1  PROBLEM SymbReg


2 


3  CODE <<


4  double[,] x;


5  double[] y;


6  string[] variableNames;


7  int[] rows;


8  Dictionary<string,int> nameToCol;


9 


10  double GetValue(double[,] data, string varName, int row) {


11  if(nameToCol == null) {


12  /* init mapping */


13  nameToCol = new Dictionary<string, int>();


14  for(int i=0; i<variableNames.Length; i++) {


15  nameToCol[variableNames[i]] = i;


16  }


17  }


18  return x[row, nameToCol[varName]];


19  }


20 


21  double RSquared(IEnumerable<double> xs, IEnumerable<double> ys) {


22  // calculate Pearson's correlation in one pass over xs and ys


23  double sumx = 0.0;


24  double sumy = 0.0;


25  double sumxSq = 0.0;


26  double sumySq = 0.0;


27  double sumxy = 0.0;


28  int n = 0;


29  var xEnum = xs.GetEnumerator();


30  var yEnum = ys.GetEnumerator();


31  while(xEnum.MoveNext() & yEnum.MoveNext()) {


32  sumx += xEnum.Current;


33  sumy += yEnum.Current;


34  sumxSq += xEnum.Current * xEnum.Current;


35  sumySq += yEnum.Current * yEnum.Current;


36  sumxy += xEnum.Current * yEnum.Current;


37  n++;


38  }


39  System.Diagnostics.Debug.Assert(!(xEnum.MoveNext()  yEnum.MoveNext()));


40 


41  double num;


42  double den;


43  double r = 0.0;


44  num = sumxy  ( ( sumx * sumy ) / n );


45  den = Math.Sqrt( ( sumxSq  ( sumx*sumx ) / n ) *


46  ( sumySq  ( sumy*sumy ) / n ) );


47  if(den > 0){


48  r = num / den;


49  }


50  return r*r;


51  }


52  >>


53 


54  INIT <<


55  // generate 500 case of poly10 benchmark function


56  int n = 500;


57  variableNames = new string[] {"x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10" };


58  var rand = new System.Random();


59  x = new double[n, 10];


60  y = new double[n];


61  for(int row = 0; row < n; row++) {


62  for(int col = 0; col < 10; col++) {


63  x[row, col] = rand.NextDouble() * 2.0  1.0;


64  }


65  y[row] = x[row, 0] * x[row, 1] +


66  x[row, 2] * x[row, 3] +


67  x[row, 4] * x[row, 5] +


68  x[row, 0] * x[row, 6] + x[row, 8] +


69  x[row, 2] * x[row, 5] + x[row, 9];


70  }


71 


72  rows = System.Linq.Enumerable.Range(0, n).ToArray();


73  >>


74 


75  NONTERMINALS


76  Model<<int row, out double val>>.


77  RPB<<int row, out double val>>.


78  Addition<<int row, out double val>>.


79  Subtraction<<int row, out double val>>.


80  Multiplication<<int row, out double val>>.


81  Division<<int row, out double val>>.


82 


83  TERMINALS


84  Const<<out double val>>


85  CONSTRAINTS


86  val IN RANGE <<100>> .. <<100>>


87  .


88  Var<<out string varName, out double weight>>


89  CONSTRAINTS


90  varName IN SET <<variableNames>>


91  weight IN RANGE <<100>> .. <<100>>


92  .


93 


94  RULES


95  Model<<int row, out double val>> =


96  RPB<<row, out val>> .


97 


98  RPB<<int row, out double val>> = LOCAL << string varName; double w; >>


99  Addition<<row, out val>>


100   Subtraction<<row, out val>>


101   Division<<row, out val>>


102   Multiplication<<row, out val>>


103   Var<<out varName, out w>> SEM << val = w * GetValue(x, varName, row); >>


104   Const<<out val>>


105  .


106 


107  Addition<<int row, out double val>> = LOCAL << double x1, x2; >>


108  RPB<<row, out x1>> RPB<<row, out x2>> SEM << val = x1 + x2; >>


109  .


110  Subtraction<<int row, out double val>> = LOCAL << double x1, x2; >>


111  RPB<<row, out x1>> RPB<<row, out x2>> SEM << val = x1  x2; >>


112  .


113  Division<<int row, out double val>> = LOCAL << double x1, x2; >>


114  RPB<<row, out x1>> RPB<<row, out x2>> SEM << val = x1 / x2; >>


115  .


116  Multiplication<<int row, out double val>> = LOCAL << double x1, x2; >>


117  RPB<<row, out x1>> RPB<<row, out x2>> SEM << val = x1 * x2; >>


118  .


119 


120  MAXIMIZE


121  <<


122  var predicted = rows.Select(r => {


123  double result;


124  Model(r, out result); /* we can call the root symbol directly */


125  return result;


126  });


127  return RSquared(predicted, y);


128  >>


129  END SymbReg.

