Changeset 16694


Ignore:
Timestamp:
03/19/19 11:02:52 (3 months ago)
Author:
gkronber
Message:

#2994: implemented remaining methods for IAlgebraicType and changed formatting

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/Interpreter.cs

    r16693 r16694  
    2727              break;
    2828            }
    29           // case OpCodes.Constant: we initialize constants in Compile. The value never changes afterwards
     29          case OpCodes.Constant: { break; }  // we initialize constants in Compile. The value never changes afterwards
    3030          case OpCodes.Add: {
    3131              instr.value.Assign(code[c].value);
     
    6767              break;
    6868            }
    69 
     69          case OpCodes.Square: {
     70              instr.value.AssignIntPower(code[c].value, 2);
     71              break;
     72            }
    7073          case OpCodes.Exp: {
    7174              instr.value.AssignExp(code[c].value);
     
    7780              break;
    7881            }
     82          default: throw new ArgumentException($"Unknown opcode {code[c].opcode}");
    7983        }
    8084      }
     
    337341      var u = code[0].value.UpperBound;
    338342      for (int i = 0; i < paramNodes.Length; ++i) {
     343        if (paramNodes[i] == null) continue;
    339344        lowerGradient[i] = l.Gradient.Elements[paramNodes[i]];
    340345        upperGradient[i] = u.Gradient.Elements[paramNodes[i]];
     
    502507      Array.Copy(data, rowIndex, arr, 0, Math.Min(arr.Length, data.Length - rowIndex));
    503508    }
    504 
    505509    public void CopyRowTo(double[,] dest, int row) {
    506510      for (int j = 0; j < arr.Length; ++j) dest[row, j] = arr[j];
     
    657661    }
    658662  }
    659 
    660663
    661664  public class AlgebraicInterval : IAlgebraicType<AlgebraicInterval> {
     
    887890    where V : IAlgebraicType<V> {
    888891    private V v;
     892    public V Value => v;
     893
    889894    private V dv;
    890 
    891     public V Value => v;
    892895    public V Derivative => dv;
    893896
    894 
    895     public Dual(V v, V dv) {
    896       this.v = v;
    897       this.dv = dv;
    898     }
    899 
    900     public Dual<V> Clone() {
    901       return new Dual<V>(v.Clone(), dv.Clone());
    902     }
     897    public Dual(V v, V dv) { this.v = v; this.dv = dv; }
    903898
    904899    public Dual<V> Zero => new Dual<V>(Value.Zero, Derivative.Zero);
    905900
    906     public Dual<V> Add(Dual<V> a) {
    907       v.Add(a.v);
    908       dv.Add(a.dv);
    909       return this;
    910     }
    911 
    912     public Dual<V> Assign(Dual<V> a) {
    913       v.Assign(a.v);
    914       dv.Assign(a.dv);
    915       return this;
    916     }
    917 
    918     public Dual<V> AssignCos(Dual<V> a) {
    919       v.AssignCos(a.v);
    920       dv.AssignNeg(dv.AssignSin(a.v));
    921       return this;
    922     }
    923 
    924     public Dual<V> Div(Dual<V> a) {
    925       Mul(a.Inv());
    926       return this;
    927     }
    928 
    929     public Dual<V> AssignExp(Dual<V> a) {
    930       v.AssignExp(a.v);
    931       dv.Assign(a.dv).Mul(v); // exp(f(x)) = exp(f(x))*f(x)'
    932       return this;
    933     }
    934 
    935     public Dual<V> AssignIntPower(Dual<V> a, int p) {
    936       v.AssignIntPower(a.v, p);
    937       dv.Assign(a.dv).Scale(p).Mul(a.v.IntPower(p - 1));
    938       return this;
    939     }
    940 
    941     public Dual<V> AssignIntRoot(Dual<V> a, int r) {
    942       v.AssignIntRoot(a.v, r);
    943       dv.Assign(a.dv).Scale(1.0 / r).Mul(a.v.IntRoot(r - 1));
    944       return this;
    945     }
    946 
    947     public Dual<V> AssignInv(Dual<V> a) {
    948       v.AssignInv(a.v);
    949       dv.AssignNeg(a.dv).Mul(v).Mul(v); // (1/f(x))' = - f(x)' / f(x)^2
    950       return this;
    951     }
    952 
    953     public Dual<V> AssignLog(Dual<V> a) {
    954       v.AssignLog(a.v);
    955       dv.Assign(a.dv).Div(a.v); // log(x)' = 1/f(x) * f(x)'
    956       return this;
    957     }
    958 
     901    public Dual<V> Assign(Dual<V> a) { v.Assign(a.v); dv.Assign(a.dv); return this; }
     902    public Dual<V> Scale(double s) { v.Scale(s); dv.Scale(s); return this; }
     903    public Dual<V> Add(Dual<V> a) { v.Add(a.v); dv.Add(a.dv); return this; }
     904    public Dual<V> Sub(Dual<V> a) { v.Sub(a.v); dv.Sub(a.dv); return this; }
     905    public Dual<V> AssignNeg(Dual<V> a) { v.AssignNeg(a.v); dv.AssignNeg(a.dv); return this; }
     906    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
     907
     908    // (a(x) * b(x))' = b(x)*a(x)' + b(x)'*a(x);
    959909    public Dual<V> Mul(Dual<V> a) {
    960       // (a(x) * b(x))' = b(x)*a(x)' + b(x)'*a(x);
    961 
    962       V t1 = default(V);
    963       t1.Assign(a.dv).Mul(v);
    964 
    965       var t2 = default(V);
    966       t2.Assign(dv).Mul(a.v);
    967 
     910      var t1 = a.dv.Clone().Mul(v);
     911      var t2 = dv.Clone().Mul(a.v);
    968912      dv.Assign(t1).Add(t2);
    969913
     
    971915      return this;
    972916    }
    973 
    974     public Dual<V> AssignNeg(Dual<V> a) {
    975       v.AssignNeg(a.v);
    976       dv.AssignNeg(a.dv);
    977       return this;
    978     }
    979 
    980     public Dual<V> Scale(double s) {
    981       v.Scale(s);
    982       dv.Scale(s);
    983       return this;
    984     }
    985 
    986     public Dual<V> AssignSin(Dual<V> a) {
    987       v.AssignSin(a.v);
    988       dv.Assign(a.dv).Mul(a.v.Clone().Cos());
    989       return this;
    990     }
    991 
    992     public Dual<V> Sub(Dual<V> a) {
    993       v.Sub(a.v);
    994       dv.Sub(a.dv);
    995       return this;
    996     }
    997 
    998     public Dual<V> AssignAbs(Dual<V> a) {
    999       v.AssignAbs(a.v);
    1000       // abs(f(x))' = f(x)*f'(x) / |f(x)|     
    1001       dv.Assign(a.dv).Mul(a.v.Clone().Sgn());
    1002       return this;
    1003     }
    1004 
    1005     public Dual<V> AssignSgn(Dual<V> a) {
    1006       throw new NotImplementedException();
    1007     }
     917    public Dual<V> Div(Dual<V> a) { Mul(a.Inv()); return this; }
     918
     919    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)'
     920    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)'
     921
     922    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; }
     923    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; }
     924
     925    public Dual<V> AssignSin(Dual<V> a) { v.AssignSin(a.v); dv.Assign(a.dv).Mul(a.v.Clone().Cos()); return this; }
     926    public Dual<V> AssignCos(Dual<V> a) { v.AssignCos(a.v); dv.AssignNeg(a.dv).Mul(a.v.Clone().Sin()); return this; }
     927
     928    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)|     
     929    public Dual<V> AssignSgn(Dual<V> a) { v.AssignSgn(a.v); dv.Assign(a.dv.Zero); return this; }
     930
     931    public Dual<V> Clone() { return new Dual<V>(v.Clone(), dv.Clone()); }
     932
    1008933  }
    1009934
     
    1019944    public SparseVector<object, V> Gradient => dv; // <key,value> partial derivative identified via the key
    1020945
    1021     private MultivariateDual(MultivariateDual<V> orig) {
    1022       this.v = orig.v.Clone();
    1023       this.dv = orig.dv.Clone();
    1024     }
     946    private MultivariateDual(MultivariateDual<V> orig) { this.v = orig.v.Clone(); this.dv = orig.dv.Clone(); }
    1025947
    1026948    /// <summary>
     
    1028950    /// </summary>
    1029951    /// <param name="v"></param>
    1030     public MultivariateDual(V v) {
    1031       this.v = v.Clone();
    1032       this.dv = new SparseVector<object, V>();
    1033     }
     952    public MultivariateDual(V v) { this.v = v.Clone(); this.dv = new SparseVector<object, V>(); }
    1034953
    1035954    /// <summary>
     
    1039958    /// <param name="keys"></param>
    1040959    /// <param name="dv"></param>
    1041     public MultivariateDual(V v, object[] keys, V[] dv) {
    1042       this.v = v.Clone();
    1043       this.dv = new SparseVector<object, V>(keys, dv);
    1044     }
     960    public MultivariateDual(V v, object[] keys, V[] dv) { this.v = v.Clone(); this.dv = new SparseVector<object, V>(keys, dv); }
    1045961
    1046962    /// <summary>
     
    1050966    /// <param name="key"></param>
    1051967    /// <param name="dv"></param>
    1052     public MultivariateDual(V v, object key, V dv) {
    1053       this.v = v.Clone();
    1054       this.dv = new SparseVector<object, V>(new[] { key }, new[] { dv });
    1055     }
     968    public MultivariateDual(V v, object key, V dv) { this.v = v.Clone(); this.dv = new SparseVector<object, V>(new[] { key }, new[] { dv }); }
    1056969
    1057970    /// <summary>
    1058     ///
     971    /// Constructor with a given value and gradient. For internal use.
    1059972    /// </summary>
    1060     /// <param name="v">not cloned</param>
    1061     /// <param name="gradient">not cloned</param>
    1062     internal MultivariateDual(V v, SparseVector<object, V> gradient) {
    1063       this.v = v;
    1064       this.dv = gradient;
    1065     }
    1066 
    1067     public MultivariateDual<V> Clone() {
    1068       return new MultivariateDual<V>(this);
    1069     }
    1070 
     973    /// <param name="v">The value (not cloned).</param>
     974    /// <param name="gradient">The gradient (not cloned).</param>
     975    internal MultivariateDual(V v, SparseVector<object, V> gradient) { this.v = v; this.dv = gradient; }
     976
     977    public MultivariateDual<V> Clone() { return new MultivariateDual<V>(this); }
    1071978
    1072979    public MultivariateDual<V> Zero => new MultivariateDual<V>(Value.Zero, Gradient.Zero);
    1073980
    1074 
    1075     public MultivariateDual<V> Add(MultivariateDual<V> a) {
    1076       v.Add(a.v);
    1077       dv.Add(a.dv);
    1078       return this;
    1079     }
    1080 
    1081     public MultivariateDual<V> Assign(MultivariateDual<V> a) {
    1082       v.Assign(a.v);
    1083       dv.Assign(a.dv);
    1084       return this;
    1085     }
    1086 
    1087     public MultivariateDual<V> AssignCos(MultivariateDual<V> a) {
    1088       throw new NotImplementedException();
    1089     }
    1090 
    1091     public MultivariateDual<V> AssignExp(MultivariateDual<V> a) {
    1092       throw new NotImplementedException();
    1093     }
    1094 
    1095     public MultivariateDual<V> AssignIntPower(MultivariateDual<V> a, int p) {
    1096       throw new NotImplementedException();
    1097     }
    1098 
    1099     public MultivariateDual<V> AssignIntRoot(MultivariateDual<V> a, int r) {
    1100       throw new NotImplementedException();
    1101     }
    1102 
    1103     public MultivariateDual<V> AssignInv(MultivariateDual<V> a) {
    1104       throw new NotImplementedException();
    1105     }
    1106 
    1107     public MultivariateDual<V> AssignLog(MultivariateDual<V> a) {
    1108       throw new NotImplementedException();
    1109     }
    1110 
    1111     public MultivariateDual<V> AssignNeg(MultivariateDual<V> a) {
    1112       throw new NotImplementedException();
    1113     }
    1114 
    1115     public MultivariateDual<V> AssignSin(MultivariateDual<V> a) {
    1116       throw new NotImplementedException();
    1117     }
    1118 
    1119     public MultivariateDual<V> Div(MultivariateDual<V> a) {
    1120       throw new NotImplementedException();
    1121     }
    1122 
     981    public MultivariateDual<V> Scale(double s) { v.Scale(s); dv.Scale(s); return this; }
     982
     983    public MultivariateDual<V> Add(MultivariateDual<V> a) { v.Add(a.v); dv.Add(a.dv); return this; }
     984    public MultivariateDual<V> Sub(MultivariateDual<V> a) { v.Sub(a.v); dv.Sub(a.dv); return this; }
     985    public MultivariateDual<V> Assign(MultivariateDual<V> a) { v.Assign(a.v); dv.Assign(a.dv); return this; }
    1123986    public MultivariateDual<V> Mul(MultivariateDual<V> a) {
    1124987      // (a(x) * b(x))' = b(x)*a(x)' + b(x)'*a(x);
    1125 
    1126988      var t1 = a.dv.Clone().Scale(v);
    1127989      var t2 = dv.Clone().Scale(a.v);
     
    1131993      return this;
    1132994    }
    1133 
    1134     public MultivariateDual<V> Scale(double s) {
    1135       v.Scale(s);
    1136       dv.Scale(s);
    1137       return this;
    1138     }
    1139 
    1140     public MultivariateDual<V> Sub(MultivariateDual<V> a) {
    1141       v.Sub(a.v);
    1142       dv.Sub(a.dv);
    1143       return this;
    1144     }
    1145 
    1146     public MultivariateDual<V> AssignAbs(MultivariateDual<V> a) {
    1147       v.AssignAbs(a.v);
    1148       // abs(f(x))' = f(x)*f'(x) / |f(x)|  doesn't work for intervals     
    1149 
    1150       dv.Assign(a.dv).Scale(a.v.Clone().Sgn());
    1151       return this;
    1152     }
    1153 
    1154     public MultivariateDual<V> AssignSgn(MultivariateDual<V> a) {
    1155       v.AssignSgn(a.v);
    1156       // sign(f(x)) = 0;
    1157       dv = a.dv.Zero;
    1158       return this;
    1159     }
     995    public MultivariateDual<V> Div(MultivariateDual<V> a) { v.Div(a.v); dv.Mul(a.dv.Inv()); return this; }
     996    public MultivariateDual<V> AssignNeg(MultivariateDual<V> a) { v.AssignNeg(a.v); dv.AssignNeg(a.dv); return this; }
     997    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
     998
     999    public MultivariateDual<V> AssignSin(MultivariateDual<V> a) { v.AssignSin(a.v); dv.Assign(a.dv).Scale(a.v.Clone().Cos()); return this; }
     1000    public MultivariateDual<V> AssignCos(MultivariateDual<V> a) { v.AssignCos(a.v); dv.AssignNeg(a.dv).Scale(a.v.Clone().Sin()); return this; }
     1001
     1002    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; }
     1003    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; }
     1004
     1005    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)'     
     1006    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)'
     1007
     1008    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     
     1009    public MultivariateDual<V> AssignSgn(MultivariateDual<V> a) { v.AssignSgn(a.v); dv = a.dv.Zero; return this; } // sign(f(x))' = 0;     
    11601010  }
    11611011}
Note: See TracChangeset for help on using the changeset viewer.