/*
 * MakeAC.c
 *
 *  Created on: 2009/02/16
 *      Author: H.Shouno
 *  This is a wrapper program for make_ac() in Neocog.c by Prof.Fukushima.
 *
 */

#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include "mex.h"
#include "neocog_proto.h"

void mexFunction( int nlhs, mxArray *lhs[], int nrhs, const mxArray *rhs[] );

/*
 * Input & Output Arguments
 */

#define AC_OUT		lhs[0] // output Gaussian filter matrix
#define AC_SIZE_IN	rhs[0] // Size of C coefficient marix 
#define AC_IN		rhs[1] // connection radius (in diameter)
#define AO_IN		rhs[2] // radius of connect. ac, Ac[L]
#define GAMMA_IN	rhs[3] // Spatial decay of excitation (optional, default: 0.7)
#define GAMMA_O_IN	rhs[4] // Spatial decay of inhibition (optional, default: 0.12)
#define GAMMA_P_IN	rhs[5] // Spatial decay of inhibition (optional, default: 0.8)
#define CO_IN		rhs[6] // Value at the center coC[l] (optional, default: 4.0)
#define PN_IN		rhs[7] // ratio of negative to positive components (optional, default: 1.0)

/*
	double	Aco[]	= {        3.4,  3.4,  4.4,  0.0};	// radius of on center in connect. ac, Ac[L]
	double	Ac[]	= {        9.4,  7.4, Aco[2],0.0};	// radius of connect. ac, Ac[L]

	double	gamC[]	= {        0.7,  0.7,  0.7,  1.0};	// make_ac(ac): spatial decay of exc. center at x=Ao,  gamC[L]
	double	gamCo[]	= {        0.12, 0.12, 0.12, 0.0};	// make_ac(ac): spatial decay of inh. connect. at x=Ao
	double	gamCp[]	= {        0.8,  0.8,  0.8,  0.0};	// make_ac(ac): spatial decay of inh. connect. at x=A
	double	coC[]	= {        4.0,  4.0,  4.0,  1.0};	// make_ac(ac): value at the center,  coC[L]
	double	pnC[]	= {        1.0,  1.0,  1.0,  0.0};	// make_ac(ac): ratio of negative to positive components
*/

//
// available expressions...
// D = MakeAC( SIZE, dia1, dia2 );
// D = MakeAC( SIZE, dia1, dia2, gamma, gammao, gammap, coc, pnc );
//

#define DEFAULT_GAMMA    0.7  // Spatial decay of Excitatory connection
#define DEFAULT_GAMMA_CO 0.12 // Spatial decay of Inhibitory connection at X = Ao
#define DEFAULT_GAMMA_CP 0.8  // Spatial decay of Inhibitory connection at x = A
#define DEFAULT_COC      4.0  // Value at the center
#define DEFAULT_PNC      1.0  // Ratio of Negative/Positive components: 0.0 is ballanced.

//
// Gateway function
//
void mexFunction( int nlhs, mxArray *lhs[], int nrhs, const mxArray *rhs[] )
{
	int na, i;
	double *coefp;
	double **c;
	double a, ao, gamma, gamco, gamcp, coc, pnc;

	if( nrhs < 3 )		mexErrMsgTxt( "MakeAC() requires input parameter(s): MakeAC( SIZE, off-diameter, on-diameter, ... )" );
	if( nlhs < 1 )		mexErrMsgTxt( "MakeAC() requires ouput parameter(s): D = MakeAC( ... )" );

	// right side
	na = (int)mxGetScalar( AC_SIZE_IN );
	a = mxGetScalar( AC_IN );
	ao = mxGetScalar( AO_IN );
	if( nrhs >= 4 )		gamma = mxGetScalar( GAMMA_IN );
	else			gamma = DEFAULT_GAMMA;  
	if( nrhs >= 5 )		gamco = mxGetScalar( GAMMA_O_IN );
	else			gamco = DEFAULT_GAMMA_CO;
	if( nrhs >= 6 )		gamcp = mxGetScalar( GAMMA_P_IN );
	else			gamcp = DEFAULT_GAMMA_CP;
	if( nrhs >= 7 )		coc   = mxGetScalar( CO_IN );
	else			coc   = DEFAULT_COC;
	if( nrhs >= 8 )		pnc   = mxGetScalar( PN_IN );
	else			pnc   = DEFAULT_PNC;

	if( na < 0 )		mexErrMsgTxt( "Size is illegal." );
	AC_OUT = mxCreateDoubleMatrix( na, na, mxREAL );
	coefp = (double*)mxGetPr( AC_OUT );

	c = (double**)mxCalloc( sizeof(double*), na );
	c[0] = coefp;
	for( i = 1 ; i < na ; i++ )		c[i] = c[i-1] + na;

	make_ac( c, na, a, ao, gamma, gamco, gamcp, coc, pnc );

	return;
}
