Index: /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/Heuristics.cs
===================================================================
--- /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/Heuristics.cs	(revision 15425)
+++ /branches/MCTS-SymbReg-2796/HeuristicLab.Algorithms.DataAnalysis/3.4/Heuristics.cs	(revision 15426)
@@ -18,4 +18,7 @@
   // We only need to identify the x y as we assume that all other terms are accounted for
   public static class Heuristics {
+    public static double CorrelationForInteraction(double[] a, double[] b, double[] c, double[] target) {
+      return 0.0;
+    }
     public static double CorrelationForInteraction(double[] a, double[] b, double[] z) {
       // 
Index: /branches/MCTS-SymbReg-2796/Tests/HeuristicLab.Algorithms.DataAnalysis-3.4/MctsSymbolicRegressionTest.cs
===================================================================
--- /branches/MCTS-SymbReg-2796/Tests/HeuristicLab.Algorithms.DataAnalysis-3.4/MctsSymbolicRegressionTest.cs	(revision 15425)
+++ /branches/MCTS-SymbReg-2796/Tests/HeuristicLab.Algorithms.DataAnalysis-3.4/MctsSymbolicRegressionTest.cs	(revision 15426)
@@ -19,5 +19,5 @@
     [TestCategory("Algorithms.DataAnalysis")]
     [TestProperty("Time", "short")]
-    public void TestHeuristics() {
+    public void TestSimple2dInteractions() {
       {
         // a, b ~ U(0, 1) should be trivial
@@ -97,8 +97,9 @@
       }
       {
+        var rand = new MersenneTwister(1234);
         // a ~ N(100, 1), b ~ N(-100, 1)
-        var nRand = new NormalDistributedRandom(new MersenneTwister(1234), 0, 1);
-        var aRand = new NormalDistributedRandom(new MersenneTwister(1234), 100, 1);
-        var bRand = new NormalDistributedRandom(new MersenneTwister(1234), -100, 1);
+        var nRand = new NormalDistributedRandom(rand, 0, 1);
+        var aRand = new NormalDistributedRandom(rand, 100, 1);
+        var bRand = new NormalDistributedRandom(rand, -100, 1);
 
         int n = 10000; // large sample so that we can use the thresholds below
@@ -115,5 +116,169 @@
         Assert.IsTrue(Heuristics.CorrelationForInteraction(b, x, z) > 0.05); // b < 0
         Assert.IsTrue(Heuristics.CorrelationForInteraction(b, y, z) > 0.05);
-        Assert.IsTrue(Heuristics.CorrelationForInteraction(x, y, z) < 0.05);
+        Assert.IsTrue(Heuristics.CorrelationForInteraction(x, y, z) < 0.05); // random variables are not correlated
+      }
+    }
+
+    [TestMethod]
+    [TestCategory("Algorithms.DataAnalysis")]
+    [TestProperty("Time", "short")]
+    public void TestGeneral2dInteractions() {
+      {
+        // we should be able to reliably detect when a product of two variables is correlated with the target variable        
+
+        // the test samples x from a two dimensional normal distribution
+        // the covariance matrix for the normal distribution is randomly sampled 
+        // this means x_1 and x_2 might be highly correlated
+        // the mean of the normal distribution is randomly sampled (most critical are probably zero-mean distributions)
+        // y is calculated as x_1*x_2
+
+        var conditionNumber = 10000;
+        for (int iter = 0; iter < 100; iter++) {
+          double m0 = 0.0; double m1 = 0.0;
+          alglib.hqrndstate randState;
+          alglib.hqrndseed(1234, 31415, out randState);
+
+          // uncomment if non-zero mean distributions should be tested
+          //alglib.hqrndnormal2(randState, out m0, out m1);
+
+          double[,] cov_ab = new double[2, 2];
+          double[,] cov_xy = new double[2, 2];
+          alglib.matgen.spdmatrixrndcond(2, conditionNumber, ref cov_ab);
+          alglib.spdmatrixcholesky(ref cov_ab, 2, true);
+
+          alglib.matgen.spdmatrixrndcond(2, conditionNumber, ref cov_xy);
+          alglib.spdmatrixcholesky(ref cov_xy, 2, true);
+
+          // generate a, b by sampling from a 2dim multivariate normal distribution
+          // generate x, y by sampling from another 2dim multivariate normal distribution
+          // a,b and x,y might be correlated but x,y are not correlated to a,b
+          int N = 1000; // large sample size to make sure the test thresholds hold
+          double[] a = new double[N];
+          double[] b = new double[N];
+          double[] x = new double[N];
+          double[] y = new double[N];
+          double[] z = new double[N];
+
+          for (int i = 0; i < N; i++) {
+            double r1, r2, r3, r4;
+            alglib.hqrndnormal2(randState, out r1, out r2);
+            alglib.hqrndnormal2(randState, out r3, out r4);
+
+            var r_ab = new double[] { r1, r2 };
+            var r_xy = new double[] { r3, r4 };
+            double[] s_ab = new double[2];
+            double[] s_xy = new double[2];
+            alglib.ablas.rmatrixmv(2, 2, cov_ab, 0, 0, 0, r_ab, 0, ref s_ab, 0);
+            alglib.ablas.rmatrixmv(2, 2, cov_xy, 0, 0, 0, r_xy, 0, ref s_xy, 0);
+
+            a[i] = s_ab[0] + m0;
+            b[i] = s_ab[1] + m1;
+            x[i] = s_xy[0] + m0; // use same mean (just for the sake of it)
+            y[i] = s_xy[1] + m1;
+
+            z[i] = a[i] * b[i];
+          }
+
+          Assert.IsTrue(Heuristics.CorrelationForInteraction(a, b, z) > 0.05);
+          Assert.IsTrue(Heuristics.CorrelationForInteraction(x, y, z) < 0.05);
+
+          /* we might see correlations when only using one of the two relevant factors.
+           * this depends on the distribution / location of a and b 
+          // for zero-mean distributions the following should all be quasi-zero
+          Assert.IsTrue(Heuristics.CorrelationForInteraction(a, x, z) < 0.05);
+          Assert.IsTrue(Heuristics.CorrelationForInteraction(b, x, z) < 0.05);
+          Assert.IsTrue(Heuristics.CorrelationForInteraction(a, y, z) < 0.05);
+          Assert.IsTrue(Heuristics.CorrelationForInteraction(b, y, z) < 0.05);
+          */
+          Console.WriteLine("a,b: {0:N3}\tx,y: {1:N3}\ta,x: {2:N3}\tb,x: {3:N3}\ta,y: {4:N3}\tb,y: {5:N3}\tcov(a,b): {6:N3}",
+            Heuristics.CorrelationForInteraction(a, b, z),
+            Heuristics.CorrelationForInteraction(x, y, z),
+            Heuristics.CorrelationForInteraction(a, x, z),
+            Heuristics.CorrelationForInteraction(b, x, z),
+            Heuristics.CorrelationForInteraction(a, y, z),
+            Heuristics.CorrelationForInteraction(b, y, z),
+            alglib.cov2(a, b)
+            );
+        }
+      }
+    }
+    [TestMethod]
+    [TestCategory("Algorithms.DataAnalysis")]
+    [TestProperty("Time", "short")]
+    public void TestGeneral3dInteractions() {
+      {
+        // same as TestGeneral2dInteractions but for terms with three variables
+
+        var conditionNumber = 100;
+        for (int iter = 0; iter < 100; iter++) {
+          double m0 = 0.0; double m1 = 0.0; double m2 = 0.0;
+          alglib.hqrndstate randState;
+          alglib.hqrndseed(1234, 31415, out randState);
+
+          // uncomment if non-zero mean distributions should be tested
+          //alglib.hqrndnormal2(randState, out m0, out m1);
+          //alglib.hqrndnormal2(randState, out m1, out m2);
+
+          double[,] cov_abc = new double[3, 3];
+          double[,] cov_xyz = new double[3, 3];
+          alglib.matgen.spdmatrixrndcond(3, conditionNumber, ref cov_abc);
+          alglib.spdmatrixcholesky(ref cov_abc, 3, true);
+
+          alglib.matgen.spdmatrixrndcond(3, conditionNumber, ref cov_xyz);
+          alglib.spdmatrixcholesky(ref cov_xyz, 3, true);
+
+          int N = 1000; // large sample size to make sure the test thresholds hold
+          double[] a = new double[N];
+          double[] b = new double[N];
+          double[] c = new double[N];
+          double[] x = new double[N];
+          double[] y = new double[N];
+          double[] z = new double[N];
+          double[] t = new double[N];
+
+          for (int i = 0; i < N; i++) {
+            double r1, r2, r3, r4, r5, r6;
+            alglib.hqrndnormal2(randState, out r1, out r2);
+            alglib.hqrndnormal2(randState, out r3, out r4);
+            alglib.hqrndnormal2(randState, out r5, out r6);
+
+            var r_abc = new double[] { r1, r2, r3 };
+            var r_xyz = new double[] { r4, r5, r6 };
+            double[] s_abc = new double[3];
+            double[] s_xyz = new double[3];
+            alglib.ablas.rmatrixmv(3, 3, cov_abc, 0, 0, 0, r_abc, 0, ref s_abc, 0);
+            alglib.ablas.rmatrixmv(3, 3, cov_xyz, 0, 0, 0, r_xyz, 0, ref s_xyz, 0);
+
+            a[i] = s_abc[0] + m0;
+            b[i] = s_abc[1] + m1;
+            c[i] = s_abc[2] + m2;
+            x[i] = s_xyz[0] + m0; // use same mean (just for the sake of it)
+            y[i] = s_xyz[1] + m1;
+            z[i] = s_xyz[2] + m2;
+
+            t[i] = a[i] * b[i] * c[i];
+          }
+
+          Assert.IsTrue(Heuristics.CorrelationForInteraction(a, b, c, z) > 0.05);
+          Assert.IsTrue(Heuristics.CorrelationForInteraction(x, y, z, z) < 0.05);
+
+          /* we might see correlations when only using one of the two relevant factors.
+           * this depends on the distribution / location of a and b 
+          // for zero-mean distributions the following should all be quasi-zero
+          Assert.IsTrue(Heuristics.CorrelationForInteraction(a, x, z) < 0.05);
+          Assert.IsTrue(Heuristics.CorrelationForInteraction(b, x, z) < 0.05);
+          Assert.IsTrue(Heuristics.CorrelationForInteraction(a, y, z) < 0.05);
+          Assert.IsTrue(Heuristics.CorrelationForInteraction(b, y, z) < 0.05);
+          */
+          Console.WriteLine("a,b: {0:N3}\tx,y: {1:N3}\ta,x: {2:N3}\tb,x: {3:N3}\ta,y: {4:N3}\tb,y: {5:N3}\tcov(a,b): {6:N3}",
+            Heuristics.CorrelationForInteraction(a, b, z),
+            Heuristics.CorrelationForInteraction(x, y, z),
+            Heuristics.CorrelationForInteraction(a, x, z),
+            Heuristics.CorrelationForInteraction(b, x, z),
+            Heuristics.CorrelationForInteraction(a, y, z),
+            Heuristics.CorrelationForInteraction(b, y, z),
+            alglib.cov2(a, b)
+            );
+        }
       }
     }
Index: /branches/MCTS-SymbReg-2796/Tests/Test.csproj
===================================================================
--- /branches/MCTS-SymbReg-2796/Tests/Test.csproj	(revision 15425)
+++ /branches/MCTS-SymbReg-2796/Tests/Test.csproj	(revision 15426)
@@ -36,4 +36,8 @@
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="ALGLIB-3.7.0, Version=3.7.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\ALGLIB-3.7.0.dll</HintPath>
+    </Reference>
     <Reference Include="HeuristicLab.Algorithms.DataAnalysis-3.4">
       <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Algorithms.DataAnalysis-3.4.dll</HintPath>
