/*
 * RADBASC   Implements radbas transfer functions for implemention of 
 *           neural networks within SIMULINK.
 *           Radial basis Activation Transfer Function.
 *           Returns elements of N squashed between 0 and 1
 *           using the function y=exp(-(b*n)^2).
 *
 *           See also: RADBAS, TANSIG, TANSIGC, LOGSIG, LOGSIGC.
 *
 *           Syntax:  [sys, x0] = radbasc(t,x,u,flag)
 * 
 *  Andy Grace  Nov-29th 1993, AFP 12-8-93
 *  Copyright (c) 1990-94 by The MathWorks, Inc.
 *  All Rights Reserved
 */

#define S_FUNCTION_NAME radbasc

/*
 * include math.h for the declaration of exp
 */

#include <math.h>

/*
 * need to include simstruc.h for the definition of the SimStruct and
 * its associated macro definitions.
 */

#include "simstruc.h"

/*
 * mdlInitializeSizes - initialize the sizes array
 *
 * The sizes array is used by SIMULINK to determine the S-function block's
 * characteristics (number of inputs, outputs, states, etc.).  The entries
 * below are all set to zero, with the exception of the number of sample
 * times.  Your block should have at least one sample time, even if it is
 * a purely continuous block.
 */

static void mdlInitializeSizes(S)
    SimStruct *S;
{
    ssSetNumContStates(    S, 0);                  /* number of continuous states */
    ssSetNumDiscStates(    S, 0);                  /* number of discrete states */
    ssSetNumInputs(        S, DYNAMICALLY_SIZED);  /* number of inputs */
    ssSetNumOutputs(       S, DYNAMICALLY_SIZED);  /* number of outputs */
    ssSetDirectFeedThrough(S, 1);                  /* direct feedthrough flag */
    ssSetNumSampleTimes(   S, 1);                  /* number of sample times */
    ssSetNumInputArgs(     S, 0);                  /* number of input arguments */
    ssSetNumRWork(         S, 0);                  /* number of real work vector elements */
    ssSetNumIWork(         S, 0);                  /* number of integer work vector elements */
    ssSetNumPWork(         S, 0);                  /* number of pointer work vector elements */
}

/*
 * mdlInitializeSampleTimes - initialize the sample times array
 *
 * There should always be at least one sample time for an S-function block.
 * For a purely continuous block, there should be a sample time of 0.0.
 */

static void mdlInitializeSampleTimes(S)
    SimStruct *S;
{
    ssSetSampleTimeEvent(S, 0, 0.0);
    ssSetOffsetTimeEvent(S, 0, 0.0);
}

/*
 * mdlInitializeConditions - initialize the states for the S-function
 *
 * In this function, you should initialize the continuous and discrete
 * states for your S-function block.  The initial states are placed
 * in the x0 variable.
 */

static void mdlInitializeConditions(x0, S)
    double *x0;
    SimStruct *S;
{
}

/*
 * mdlOutputs - compute the outputs of the S-function
 *
 * In this function, you compute the outputs of your S-function
 * block.  The outputs are placed in the y variable.
 */

static void mdlOutputs(y, x, u, S, tid)
    double *y, *x, *u;
    SimStruct *S;
    int tid;
{
    int nOutputs = ssGetNumOutputs(S);
    int i;
    
    for (i = 0; i < nOutputs; i++) {
	/* radbas function */
	y[i] = exp(-u[i]*u[i]);
    }
}

/*
 * mdlUpdate - perform action at major integration step
 *
 * This function is called once at the beginning of every major
 * integration step.  This is typically  where the discrete states for
 * the S-function block are updated.  This function is also
 * useful for performing any tasks that should only take place
 * once per integration step.
 */

static void mdlUpdate(x, u, S, tid)
    double *x, *u;
    SimStruct *S;
    int tid;
{
}

/*
 * mdlDerivatives - compute the derivatives of the S-function
 *
 * In this function, you compute the S-function block's derivatives.
 * The derivatives are placed in the dx variable.
 */

static void mdlDerivatives(dx, x, u, S, tid)
    double *dx, *x, *u;
    SimStruct *S;
    int tid;
{
}

/*
 * mdlTerminate - called when the simulation is terminated.
 *
 * In this function, you should perform any actions that are necessary
 * at the termination of a simulation.  For example, if memory was allocated
 * in mdlInitializeConditions, this is the place to free it.
 */

static void mdlTerminate(S)
    SimStruct *S;
{
}

#ifdef	MATLAB_MEX_FILE    /* Is this file being compiled as a MEX-file? */
#include "simulink.c"      /* MEX-file interface mechanism */
#else
#include "cg_sfun.h"       /* Code generation registration function */
#endif
