Index: /branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/Interpreter.cs
===================================================================
--- /branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/Interpreter.cs	(revision 16693)
+++ /branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/Interpreter.cs	(revision 16694)
@@ -27,5 +27,5 @@
               break;
             }
-          // case OpCodes.Constant: we initialize constants in Compile. The value never changes afterwards
+          case OpCodes.Constant: { break; }  // we initialize constants in Compile. The value never changes afterwards
           case OpCodes.Add: {
               instr.value.Assign(code[c].value);
@@ -67,5 +67,8 @@
               break;
             }
-
+          case OpCodes.Square: {
+              instr.value.AssignIntPower(code[c].value, 2);
+              break;
+            }
           case OpCodes.Exp: {
               instr.value.AssignExp(code[c].value);
@@ -77,4 +80,5 @@
               break;
             }
+          default: throw new ArgumentException($"Unknown opcode {code[c].opcode}");
         }
       }
@@ -337,4 +341,5 @@
       var u = code[0].value.UpperBound;
       for (int i = 0; i < paramNodes.Length; ++i) {
+        if (paramNodes[i] == null) continue;
         lowerGradient[i] = l.Gradient.Elements[paramNodes[i]];
         upperGradient[i] = u.Gradient.Elements[paramNodes[i]];
@@ -502,5 +507,4 @@
       Array.Copy(data, rowIndex, arr, 0, Math.Min(arr.Length, data.Length - rowIndex));
     }
-
     public void CopyRowTo(double[,] dest, int row) {
       for (int j = 0; j < arr.Length; ++j) dest[row, j] = arr[j];
@@ -657,5 +661,4 @@
     }
   }
-
 
   public class AlgebraicInterval : IAlgebraicType<AlgebraicInterval> {
@@ -887,83 +890,24 @@
     where V : IAlgebraicType<V> {
     private V v;
+    public V Value => v;
+
     private V dv;
-
-    public V Value => v;
     public V Derivative => dv;
 
-
-    public Dual(V v, V dv) {
-      this.v = v;
-      this.dv = dv;
-    }
-
-    public Dual<V> Clone() {
-      return new Dual<V>(v.Clone(), dv.Clone());
-    }
+    public Dual(V v, V dv) { this.v = v; this.dv = dv; }
 
     public Dual<V> Zero => new Dual<V>(Value.Zero, Derivative.Zero);
 
-    public Dual<V> Add(Dual<V> a) {
-      v.Add(a.v);
-      dv.Add(a.dv);
-      return this;
-    }
-
-    public Dual<V> Assign(Dual<V> a) {
-      v.Assign(a.v);
-      dv.Assign(a.dv);
-      return this;
-    }
-
-    public Dual<V> AssignCos(Dual<V> a) {
-      v.AssignCos(a.v);
-      dv.AssignNeg(dv.AssignSin(a.v));
-      return this;
-    }
-
-    public Dual<V> Div(Dual<V> a) {
-      Mul(a.Inv());
-      return this;
-    }
-
-    public Dual<V> AssignExp(Dual<V> a) {
-      v.AssignExp(a.v);
-      dv.Assign(a.dv).Mul(v); // exp(f(x)) = exp(f(x))*f(x)'
-      return this;
-    }
-
-    public Dual<V> AssignIntPower(Dual<V> a, int p) {
-      v.AssignIntPower(a.v, p);
-      dv.Assign(a.dv).Scale(p).Mul(a.v.IntPower(p - 1));
-      return this;
-    }
-
-    public Dual<V> AssignIntRoot(Dual<V> a, int r) {
-      v.AssignIntRoot(a.v, r);
-      dv.Assign(a.dv).Scale(1.0 / r).Mul(a.v.IntRoot(r - 1));
-      return this;
-    }
-
-    public Dual<V> AssignInv(Dual<V> a) {
-      v.AssignInv(a.v);
-      dv.AssignNeg(a.dv).Mul(v).Mul(v); // (1/f(x))' = - f(x)' / f(x)^2
-      return this;
-    }
-
-    public Dual<V> AssignLog(Dual<V> a) {
-      v.AssignLog(a.v);
-      dv.Assign(a.dv).Div(a.v); // log(x)' = 1/f(x) * f(x)'
-      return this;
-    }
-
+    public Dual<V> Assign(Dual<V> a) { v.Assign(a.v); dv.Assign(a.dv); return this; }
+    public Dual<V> Scale(double s) { v.Scale(s); dv.Scale(s); return this; }
+    public Dual<V> Add(Dual<V> a) { v.Add(a.v); dv.Add(a.dv); return this; }
+    public Dual<V> Sub(Dual<V> a) { v.Sub(a.v); dv.Sub(a.dv); return this; }
+    public Dual<V> AssignNeg(Dual<V> a) { v.AssignNeg(a.v); dv.AssignNeg(a.dv); return this; }
+    public Dual<V> AssignInv(Dual<V> a) { v.AssignInv(a.v); dv.AssignNeg(a.dv).Mul(v).Mul(v); return this; } // (1/f(x))' = - f(x)' / f(x)^2
+
+    // (a(x) * b(x))' = b(x)*a(x)' + b(x)'*a(x);
     public Dual<V> Mul(Dual<V> a) {
-      // (a(x) * b(x))' = b(x)*a(x)' + b(x)'*a(x);
-
-      V t1 = default(V);
-      t1.Assign(a.dv).Mul(v);
-
-      var t2 = default(V);
-      t2.Assign(dv).Mul(a.v);
-
+      var t1 = a.dv.Clone().Mul(v);
+      var t2 = dv.Clone().Mul(a.v);
       dv.Assign(t1).Add(t2);
 
@@ -971,39 +915,20 @@
       return this;
     }
-
-    public Dual<V> AssignNeg(Dual<V> a) {
-      v.AssignNeg(a.v);
-      dv.AssignNeg(a.dv);
-      return this;
-    }
-
-    public Dual<V> Scale(double s) {
-      v.Scale(s);
-      dv.Scale(s);
-      return this;
-    }
-
-    public Dual<V> AssignSin(Dual<V> a) {
-      v.AssignSin(a.v);
-      dv.Assign(a.dv).Mul(a.v.Clone().Cos());
-      return this;
-    }
-
-    public Dual<V> Sub(Dual<V> a) {
-      v.Sub(a.v);
-      dv.Sub(a.dv);
-      return this;
-    }
-
-    public Dual<V> AssignAbs(Dual<V> a) {
-      v.AssignAbs(a.v);
-      // abs(f(x))' = f(x)*f'(x) / |f(x)|      
-      dv.Assign(a.dv).Mul(a.v.Clone().Sgn());
-      return this;
-    }
-
-    public Dual<V> AssignSgn(Dual<V> a) {
-      throw new NotImplementedException();
-    }
+    public Dual<V> Div(Dual<V> a) { Mul(a.Inv()); return this; }
+
+    public Dual<V> AssignExp(Dual<V> a) { v.AssignExp(a.v); dv.Assign(a.dv).Mul(v); return this; } // exp(f(x)) = exp(f(x))*f(x)'
+    public Dual<V> AssignLog(Dual<V> a) { v.AssignLog(a.v); dv.Assign(a.dv).Div(a.v); return this; }     // log(x)' = 1/f(x) * f(x)' 
+
+    public Dual<V> AssignIntPower(Dual<V> a, int p) { v.AssignIntPower(a.v, p); dv.Assign(a.dv).Scale(p).Mul(a.v.Clone().IntPower(p - 1)); return this; }
+    public Dual<V> AssignIntRoot(Dual<V> a, int r) { v.AssignIntRoot(a.v, r); dv.Assign(a.dv).Scale(1.0 / r).Mul(a.v.IntRoot(r - 1)); return this; }
+
+    public Dual<V> AssignSin(Dual<V> a) { v.AssignSin(a.v); dv.Assign(a.dv).Mul(a.v.Clone().Cos()); return this; }
+    public Dual<V> AssignCos(Dual<V> a) { v.AssignCos(a.v); dv.AssignNeg(a.dv).Mul(a.v.Clone().Sin()); return this; }
+
+    public Dual<V> AssignAbs(Dual<V> a) { v.AssignAbs(a.v); dv.Assign(a.dv).Mul(a.v.Clone().Sgn()); return this; }       // abs(f(x))' = f(x)*f'(x) / |f(x)|      
+    public Dual<V> AssignSgn(Dual<V> a) { v.AssignSgn(a.v); dv.Assign(a.dv.Zero); return this; }
+
+    public Dual<V> Clone() { return new Dual<V>(v.Clone(), dv.Clone()); }
+
   }
 
@@ -1019,8 +944,5 @@
     public SparseVector<object, V> Gradient => dv; // <key,value> partial derivative identified via the key
 
-    private MultivariateDual(MultivariateDual<V> orig) {
-      this.v = orig.v.Clone();
-      this.dv = orig.dv.Clone();
-    }
+    private MultivariateDual(MultivariateDual<V> orig) { this.v = orig.v.Clone(); this.dv = orig.dv.Clone(); }
 
     /// <summary>
@@ -1028,8 +950,5 @@
     /// </summary>
     /// <param name="v"></param>
-    public MultivariateDual(V v) {
-      this.v = v.Clone();
-      this.dv = new SparseVector<object, V>();
-    }
+    public MultivariateDual(V v) { this.v = v.Clone(); this.dv = new SparseVector<object, V>(); }
 
     /// <summary>
@@ -1039,8 +958,5 @@
     /// <param name="keys"></param>
     /// <param name="dv"></param>
-    public MultivariateDual(V v, object[] keys, V[] dv) {
-      this.v = v.Clone();
-      this.dv = new SparseVector<object, V>(keys, dv);
-    }
+    public MultivariateDual(V v, object[] keys, V[] dv) { this.v = v.Clone(); this.dv = new SparseVector<object, V>(keys, dv); }
 
     /// <summary>
@@ -1050,78 +966,24 @@
     /// <param name="key"></param>
     /// <param name="dv"></param>
-    public MultivariateDual(V v, object key, V dv) {
-      this.v = v.Clone();
-      this.dv = new SparseVector<object, V>(new[] { key }, new[] { dv });
-    }
+    public MultivariateDual(V v, object key, V dv) { this.v = v.Clone(); this.dv = new SparseVector<object, V>(new[] { key }, new[] { dv }); }
 
     /// <summary>
-    /// 
+    /// Constructor with a given value and gradient. For internal use.
     /// </summary>
-    /// <param name="v">not cloned</param>
-    /// <param name="gradient">not cloned</param>
-    internal MultivariateDual(V v, SparseVector<object, V> gradient) {
-      this.v = v;
-      this.dv = gradient;
-    }
-
-    public MultivariateDual<V> Clone() {
-      return new MultivariateDual<V>(this);
-    }
-
+    /// <param name="v">The value (not cloned).</param>
+    /// <param name="gradient">The gradient (not cloned).</param>
+    internal MultivariateDual(V v, SparseVector<object, V> gradient) { this.v = v; this.dv = gradient; }
+
+    public MultivariateDual<V> Clone() { return new MultivariateDual<V>(this); }
 
     public MultivariateDual<V> Zero => new MultivariateDual<V>(Value.Zero, Gradient.Zero);
 
-
-    public MultivariateDual<V> Add(MultivariateDual<V> a) {
-      v.Add(a.v);
-      dv.Add(a.dv);
-      return this;
-    }
-
-    public MultivariateDual<V> Assign(MultivariateDual<V> a) {
-      v.Assign(a.v);
-      dv.Assign(a.dv);
-      return this;
-    }
-
-    public MultivariateDual<V> AssignCos(MultivariateDual<V> a) {
-      throw new NotImplementedException();
-    }
-
-    public MultivariateDual<V> AssignExp(MultivariateDual<V> a) {
-      throw new NotImplementedException();
-    }
-
-    public MultivariateDual<V> AssignIntPower(MultivariateDual<V> a, int p) {
-      throw new NotImplementedException();
-    }
-
-    public MultivariateDual<V> AssignIntRoot(MultivariateDual<V> a, int r) {
-      throw new NotImplementedException();
-    }
-
-    public MultivariateDual<V> AssignInv(MultivariateDual<V> a) {
-      throw new NotImplementedException();
-    }
-
-    public MultivariateDual<V> AssignLog(MultivariateDual<V> a) {
-      throw new NotImplementedException();
-    }
-
-    public MultivariateDual<V> AssignNeg(MultivariateDual<V> a) {
-      throw new NotImplementedException();
-    }
-
-    public MultivariateDual<V> AssignSin(MultivariateDual<V> a) {
-      throw new NotImplementedException();
-    }
-
-    public MultivariateDual<V> Div(MultivariateDual<V> a) {
-      throw new NotImplementedException();
-    }
-
+    public MultivariateDual<V> Scale(double s) { v.Scale(s); dv.Scale(s); return this; }
+
+    public MultivariateDual<V> Add(MultivariateDual<V> a) { v.Add(a.v); dv.Add(a.dv); return this; }
+    public MultivariateDual<V> Sub(MultivariateDual<V> a) { v.Sub(a.v); dv.Sub(a.dv); return this; }
+    public MultivariateDual<V> Assign(MultivariateDual<V> a) { v.Assign(a.v); dv.Assign(a.dv); return this; }
     public MultivariateDual<V> Mul(MultivariateDual<V> a) {
       // (a(x) * b(x))' = b(x)*a(x)' + b(x)'*a(x);
-
       var t1 = a.dv.Clone().Scale(v);
       var t2 = dv.Clone().Scale(a.v);
@@ -1131,31 +993,19 @@
       return this;
     }
-
-    public MultivariateDual<V> Scale(double s) {
-      v.Scale(s);
-      dv.Scale(s);
-      return this;
-    }
-
-    public MultivariateDual<V> Sub(MultivariateDual<V> a) {
-      v.Sub(a.v);
-      dv.Sub(a.dv);
-      return this;
-    }
-
-    public MultivariateDual<V> AssignAbs(MultivariateDual<V> a) {
-      v.AssignAbs(a.v);
-      // abs(f(x))' = f(x)*f'(x) / |f(x)|  doesn't work for intervals      
-
-      dv.Assign(a.dv).Scale(a.v.Clone().Sgn());
-      return this;
-    }
-
-    public MultivariateDual<V> AssignSgn(MultivariateDual<V> a) {
-      v.AssignSgn(a.v);
-      // sign(f(x)) = 0;
-      dv = a.dv.Zero;
-      return this;
-    }
+    public MultivariateDual<V> Div(MultivariateDual<V> a) { v.Div(a.v); dv.Mul(a.dv.Inv()); return this; }
+    public MultivariateDual<V> AssignNeg(MultivariateDual<V> a) { v.AssignNeg(a.v); dv.AssignNeg(a.dv); return this; }
+    public MultivariateDual<V> AssignInv(MultivariateDual<V> a) { v.AssignInv(a.v); dv.AssignNeg(a.dv).Scale(v).Scale(v); return this; }   // (1/f(x))' = - f(x)' / f(x)^2
+
+    public MultivariateDual<V> AssignSin(MultivariateDual<V> a) { v.AssignSin(a.v); dv.Assign(a.dv).Scale(a.v.Clone().Cos()); return this; }
+    public MultivariateDual<V> AssignCos(MultivariateDual<V> a) { v.AssignCos(a.v); dv.AssignNeg(a.dv).Scale(a.v.Clone().Sin()); return this; }
+
+    public MultivariateDual<V> AssignIntPower(MultivariateDual<V> a, int p) { v.AssignIntPower(a.v, p); dv.Assign(a.dv).Scale(p).Scale(a.v.Clone().IntPower(p - 1)); return this; }
+    public MultivariateDual<V> AssignIntRoot(MultivariateDual<V> a, int r) { v.AssignIntRoot(a.v, r); dv.Assign(a.dv).Scale(1.0 / r).Scale(a.v.IntRoot(r - 1)); return this; }
+
+    public MultivariateDual<V> AssignExp(MultivariateDual<V> a) { v.AssignExp(a.v); dv.Assign(a.dv).Scale(v); return this; } // exp(f(x)) = exp(f(x))*f(x)'     
+    public MultivariateDual<V> AssignLog(MultivariateDual<V> a) { v.AssignLog(a.v); dv.Assign(a.dv).Scale(a.v.Clone().Inv()); return this; }     // log(x)' = 1/f(x) * f(x)' 
+
+    public MultivariateDual<V> AssignAbs(MultivariateDual<V> a) { v.AssignAbs(a.v); dv.Assign(a.dv).Scale(a.v.Clone().Sgn()); return this; }      // abs(f(x))' = f(x)*f'(x) / |f(x)|  doesn't work for intervals      
+    public MultivariateDual<V> AssignSgn(MultivariateDual<V> a) { v.AssignSgn(a.v); dv = a.dv.Zero; return this; } // sign(f(x))' = 0;     
   }
 }
