rbf-dda
0 Views
0 Downloads
0 Favorites
rbf-dda
// mt4 implementation of rbf-dda as described in:
// http://citeseer.ist.psu.edu/cache/papers/cs/6810/http:zSzzSzhttp.cs.berkeley.eduzSz~bertholdzSzFTPzSzberthold.neuroc98.pdf/berthold98constructive.pdf

#define MAX_I 1000  // Max number of samples
#define MAX_E 10    // Max number of dimensions in input
#define M_PI 3.141592653589793

int init()
  {
  TestSpiral();
  return(0);
  }

int deinit()
  {
  return(0);
  }

int start()
  {
  return(0);
  }

// Warning ! this version works with only two classes: -1 and +1
void DDALearn(int Nbi, int Nbe, double Spi[MAX_I][MAX_E], int CSpi[MAX_I], double tm, double tp,
			  int& Nbm, double& Mum[MAX_I][MAX_E], double& Sigm[MAX_I], double& Am[MAX_I],
			  int& Nbp, double& Mup[MAX_I][MAX_E], double& Sigp[MAX_I], double& Ap[MAX_I])
{
int i, j, k, nj, iter;
double ltm, a, x, mnj, minx;

ltm = MathLog(tm);
Nbm = 0;
Nbp = 0;
iter = 1;
while (iter == 1)
  {
  iter = 0;
  for (i=0;i<Nbi;i++)
    {
	 if (CSpi[i] == 1)
	   {
	   minx = 1000000000.0;

// Shrink
      for (j=0;j<Nbm;j++)
	     {
		  a = 0.0;
        for (k=0;k<Nbe;k++)
		    {
		    x = Spi[i][k]-Mum[j][k];
		    a += (x*x);
		    }
		  x = MathSqrt(-a/ltm);
		  if (x < Sigm[j])
		    Sigm[j] = x;
		  if (x < minx)
		    minx = x;
		  }

// Search for a valid prototype
	  nj = -1;
	  mnj = tp;
      for (j=0;j<Nbp;j++)
	    {
		a = 0.0;
        for (k=0;k<Nbe;k++)
		  {
		  x = Spi[i][k]-Mup[j][k];
		  a += (x*x);
		  }
		x = MathExp(-a/(Sigp[j]*Sigp[j]));
		if (x >= mnj)
		  {
		  mnj = x;
		  nj = j;
		  }
	    }

// New prototype
	  if (nj == -1)
	    {
	    Ap[Nbp] = 1.0;
       for (k=0;k<Nbe;k++)
		  Mup[Nbp][k] = Spi[i][k];
		Sigp[Nbp] = minx;  // may be 1e10
		Nbp++;
		iter = 1;
	    }
	    else
	    Ap[nj]++;
	  }

	if (CSpi[i] == -1)
	  {
	  minx = 1000000000.0;

// Shrink
      for (j=0;j<Nbp;j++)
	    {
		a = 0.0;
        for (k=0;k<Nbe;k++)
		  {
		  x = Spi[i][k]-Mup[j][k];
		  a += (x*x);
		  }
		x = MathSqrt(-a/ltm);
		if (x < Sigp[j])
		  Sigp[j] = x;
		if (x < minx)
		  minx = x;
		}

// Search for a valid prototype
	  nj = -1;
	  mnj = tp;
     for (j=0;j<Nbm;j++)
	    {
		 a = 0.0;
       for (k=0;k<Nbe;k++)
		  {
		  x = Spi[i][k]-Mum[j][k];
		  a += (x*x);
		  }
		x = MathExp(-a/(Sigm[j]*Sigm[j]));
		if (x >= mnj)
		  {
		  mnj = x;
		  nj = j;
		  }
	    }

// New prototype
	  if (nj == -1)
	    {
	    Am[Nbm] = 1.0;
        for (k=0;k<Nbe;k++)
		  Mum[Nbm][k] = Spi[i][k];
		Sigm[Nbm] = minx;  // may be 1e10
		Nbm++;
		iter = 1;
	    }
	    else
	    Am[nj]++;
	  }
    }

  if (iter == 1)
	Print("Nm = ", Nbm, " Np = ", Nbp);
  }

x = 0.0;
for (j=0;j<Nbm;j++)
  x += Am[j];
for (j=0;j<Nbm;j++)
  Am[j] /= x;

x = 0.0;
for (j=0;j<Nbp;j++)
  x += Ap[j];
for (j=0;j<Nbp;j++)
  Ap[j] /= x;
}

void DDAclass(int Nbi, int Nbe, double Spi[MAX_I][MAX_E], double tm,
			  int Nbm, double Mum[MAX_I][MAX_E], double Sigm[MAX_I], double Am[MAX_I],
			  int Nbp, double Mup[MAX_I][MAX_E], double Sigp[MAX_I], double Ap[MAX_I],
			  double& om[MAX_I], double& op[MAX_I])
{
int i, j, k;
double a, x;

for (i=0;i<Nbi;i++)
  {
  om[i] = 0.0;
  for (j=0;j<Nbm;j++)
    {
	a = 0.0;
    for (k=0;k<Nbe;k++)
      {
	  x = Spi[i][k]-Mum[j][k];
	  a += x*x;
	  }
	x = MathExp(-a/(Sigm[j]*Sigm[j]));
	om[i] += x*Am[j];
    }

  op[i] = 0.0;
  for (j=0;j<Nbp;j++)
    {
	a = 0.0;
    for (k=0;k<Nbe;k++)
      {
	  x = Spi[i][k]-Mup[j][k];
	  a += x*x;
	  }
	x = MathExp(-a/(Sigp[j]*Sigp[j]));
	op[i] += x*Ap[j];
    }

  x = op[i] + om[i] + tm;
  op[i] /= x;
  om[i] /= x;
  }
}

void DDAStep(int Nbe, double tm, double tp,
			 int Nbi1, double Spi1[MAX_I][MAX_E], int CSpi1[MAX_I],
			 int Nbi2, double Spi2[MAX_I][MAX_E],
			 double& om[MAX_I], double& op[MAX_I])
{
static int Nbm, Nbp;
static double Mum[MAX_I][MAX_E], Sigm[MAX_I], Am[MAX_I];
static double Mup[MAX_I][MAX_E], Sigp[MAX_I], Ap[MAX_I];

DDALearn(Nbi1, Nbe, Spi1, CSpi1, tm, tp, Nbm, Mum, Sigm, Am, Nbp, Mup, Sigp, Ap);
DDAclass(Nbi2, Nbe, Spi2, tm, Nbm, Mum, Sigm, Am, Nbp, Mup, Sigp, Ap, om, op);
}

void TestSpiral()
{
int i;
double ri, spi1[98][2], spi2[98][2];
static double Spi[MAX_I][MAX_E];
static int CSpi[MAX_I];
int Nbi, Nbe;
static double Mum[MAX_I][MAX_E], Sigm[MAX_I], Am[MAX_I];
static double Mup[MAX_I][MAX_E], Sigp[MAX_I], Ap[MAX_I];
static double om[MAX_I], op[MAX_I];
double tm, tp;

Nbi = 98;
Nbe = 2;
for (i=0;i<Nbi;i++)
  {
  ri = ((140.0-i)/140.0);
  ri = ri*ri*ri;
  spi1[i][0] = ri*MathSin(i*M_PI/16.0);
  spi1[i][1] = ri*MathCos(i*M_PI/16.0);
  spi2[i][0] = -ri*MathSin(i*M_PI/16.0);
  spi2[i][1] = -ri*MathCos(i*M_PI/16.0);
  }

for (i=0;i<Nbi;i++)
  {
  ri = ((140.0-i)/140.0);
  ri = ri*ri*ri;
  Spi[2*i][0] = spi1[i][0];
  Spi[2*i][1] = spi1[i][1];
  CSpi[2*i] = 1;
  Spi[2*i+1][0] = spi2[i][0];
  Spi[2*i+1][1] = spi2[i][1];
  CSpi[2*i+1] = -1;
  }

tm = 0.2;
tp = 0.4;
// Test: learning samples and test samples are the same
DDAStep(Nbe, tm, tp, 2*Nbi, Spi, CSpi, 2*Nbi, Spi, om, op);

for (i=0;i<2*Nbi;i++)
  {
  Print(i, " ", CSpi[i], " ", op[i] - om[i]);
  }

}

Comments