- Timestamp:
- 10/03/19 12:30:19 (5 years ago)
- Location:
- branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4
- Files:
-
- 1 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
r17297 r17303 182 182 <Compile Include="Interpreter\VectorAutoDiffEvaluator.cs" /> 183 183 <Compile Include="Interpreter\VectorEvaluator.cs" /> 184 <Compile Include="Interpreter\VectorOfAlgebraic.cs" /> 184 185 <Compile Include="Selectors\DiversitySelector.cs" /> 185 186 <Compile Include="SymbolicDataAnalysisExpressionTreeAverageSimilarityCalculator.cs" /> -
branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/Algebraic.cs
r17295 r17303 12 12 public static T IntRoot<T>(this T a, int r) where T : IAlgebraicType<T> { a.AssignIntRoot(a.Clone(), r); return a; } 13 13 14 internal static T Min<T>(T a, T b) where T : IAlgebraicType<T> { return a.Clone().AssignMin(b); }15 internal static T Max<T>(T a, T b) where T : IAlgebraicType<T> { return a.Clone().AssignMax(b); }16 17 14 // public static T Max<T>(T a, T b) where T : IAlgebraicType<T> { 18 15 // // ((a + b) + abs(b - a)) / 2 -
branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/AlgebraicDouble.cs
r17298 r17303 5 5 // algebraic type wrapper for a double value 6 6 [DebuggerDisplay("{Value}")] 7 public sealed class AlgebraicDouble : I AlgebraicType<AlgebraicDouble> {7 public sealed class AlgebraicDouble : IComparableAlgebraicType<AlgebraicDouble> { 8 8 public static implicit operator AlgebraicDouble(double value) { return new AlgebraicDouble(value); } 9 9 public static implicit operator double(AlgebraicDouble value) { return value.Value; } … … 35 35 public AlgebraicDouble AssignIntPower(AlgebraicDouble a, int p) { Value = Math.Pow(a.Value, p); return this; } 36 36 public AlgebraicDouble AssignIntRoot(AlgebraicDouble a, int r) { Value = IntRoot(a.Value, r); return this; } 37 public AlgebraicDouble AssignMin(AlgebraicDouble other) { Value = Math.Min(Value, other.Value); return this; }38 public AlgebraicDouble AssignMax(AlgebraicDouble other) { Value = Math.Max(Value, other.Value); return this; }37 //public AlgebraicDouble AssignMin(AlgebraicDouble other) { Value = Math.Min(Value, other.Value); return this; } 38 //public AlgebraicDouble AssignMax(AlgebraicDouble other) { Value = Math.Max(Value, other.Value); return this; } 39 39 public AlgebraicDouble AssignAbs(AlgebraicDouble a) { Value = Math.Abs(a.Value); return this; } 40 40 public AlgebraicDouble AssignSgn(AlgebraicDouble a) { Value = double.IsNaN(a.Value) ? double.NaN : Math.Sign(a.Value); return this; } … … 51 51 return Value.ToString(); 52 52 } 53 54 public int CompareTo(AlgebraicDouble other) { 55 return Value.CompareTo(other.Value); 56 } 53 57 } 54 58 } -
branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/AlgebraicDoubleVector.cs
r17298 r17303 6 6 // a simple vector as an algebraic type 7 7 [DebuggerDisplay("DoubleVector(len={Length}): {string.}")] 8 [Obsolete("Use VectorOfAlgebraic instead")] 8 9 public class AlgebraicDoubleVector : IAlgebraicType<AlgebraicDoubleVector> { 9 10 private double[] arr; … … 40 41 public AlgebraicDoubleVector AssignIntPower(AlgebraicDoubleVector a, int p) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Pow(a.arr[i], p); } return this; } 41 42 public AlgebraicDoubleVector AssignIntRoot(AlgebraicDoubleVector a, int r) { for (int i = 0; i < arr.Length; ++i) { arr[i] = IntRoot(a.arr[i], r); } return this; } 42 public AlgebraicDoubleVector AssignMin(AlgebraicDoubleVector other) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Min(arr[i], other.arr[i]); } return this; }43 public AlgebraicDoubleVector AssignMax(AlgebraicDoubleVector other) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Max(arr[i], other.arr[i]); } return this; }43 //public AlgebraicDoubleVector AssignMin(AlgebraicDoubleVector other) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Min(arr[i], other.arr[i]); } return this; } 44 //public AlgebraicDoubleVector AssignMax(AlgebraicDoubleVector other) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Max(arr[i], other.arr[i]); } return this; } 44 45 public AlgebraicDoubleVector AssignAbs(AlgebraicDoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Abs(a.arr[i]); } return this; } 45 46 public AlgebraicDoubleVector AssignSgn(AlgebraicDoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Sign(a.arr[i]); } return this; } -
branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/AlgebraicInterval.cs
r17295 r17303 47 47 var v4 = high.Clone().Mul(a.high); 48 48 49 low = Min(Min(v1, v2), Min(v3, v4)); 50 high = Max(Max(v1, v2), Max(v3, v4)); 51 52 return this; 53 } 54 55 56 private static MultivariateDual<AlgebraicDouble> Min(MultivariateDual<AlgebraicDouble> a, MultivariateDual<AlgebraicDouble> b) { 57 return a.Value < b.Value ? a : b; 58 } 59 private static MultivariateDual<AlgebraicDouble> Max(MultivariateDual<AlgebraicDouble> a, MultivariateDual<AlgebraicDouble> b) { 60 return a.Value > b.Value ? a : b; 49 AssignLowAndHigh(v1, v2, v3, v4); 50 51 return this; 61 52 } 62 53 … … 133 124 if (a.Contains(0.0)) { 134 125 low = new MultivariateDual<AlgebraicDouble>(0.0); 135 high = a.low.IntPower(p).AssignMax(a.high.IntPower(p)); 136 } else { 137 var lowPower = a.low.IntPower(p); 138 var highPower = a.high.IntPower(p); 139 low = lowPower.AssignMin(highPower); 140 high = lowPower.AssignMax(highPower); 126 AssignMax(high, a.low.IntPower(p), a.high.IntPower(p)); 127 } else { 128 AssignLowAndHigh(a.low.IntPower(p), a.high.IntPower(p)); 141 129 } 142 130 } else { … … 148 136 var lowPower = a.low.IntPower(p); 149 137 var highPower = a.high.IntPower(p); 150 low = lowPower.AssignMin(highPower);151 high = lowPower.AssignMax(highPower);138 AssignMin(low, lowPower, highPower); 139 AssignMax(high, lowPower, highPower); 152 140 } 153 141 } … … 217 205 218 206 // assume low and high are in the same quadrant 219 low = Algebraic.Min(a.LowerBound.Clone().Sin(), a.UpperBound.Clone().Sin()); 220 high = Algebraic.Max(a.LowerBound.Clone().Sin(), a.UpperBound.Clone().Sin()); 207 AssignLowAndHigh(a.LowerBound.Clone().Sin(), a.UpperBound.Clone().Sin()); // AssignLowAndHigh determines the lower and higher value 221 208 222 209 // override min and max if necessary … … 260 247 public AlgebraicInterval AssignAbs(AlgebraicInterval a) { 261 248 if (a.Contains(0.0)) { 249 low.Assign(new MultivariateDual<AlgebraicDouble>(0.0)); // lost gradient for lower bound 250 AssignMax(high, a.low.Clone().Abs(), a.high.Clone().Abs()); 251 } else { 262 252 var abslow = a.low.Clone().Abs(); 263 253 var abshigh = a.high.Clone().Abs(); 264 a.high.Assign(Algebraic.Max(abslow, abshigh)); 265 a.low.Assign(new MultivariateDual<AlgebraicDouble>(0.0)); // lost gradient for lower bound 266 } else { 267 var abslow = a.low.Clone().Abs(); 268 var abshigh = a.high.Clone().Abs(); 269 a.low.Assign(Algebraic.Min(abslow, abshigh)); 270 a.high.Assign(Algebraic.Max(abslow, abshigh)); 254 AssignLowAndHigh(abslow, abshigh); 271 255 } 272 256 return this; … … 279 263 } 280 264 281 public AlgebraicInterval AssignMin(AlgebraicInterval other) { 282 low.AssignMin(other.low); 283 high.AssignMin(other.high); 284 return this; 285 } 286 287 public AlgebraicInterval AssignMax(AlgebraicInterval other) { 288 low.AssignMax(other.low); 289 high.AssignMax(other.high); 290 return this; 291 } 265 266 #region helper 267 private void AssignMin(MultivariateDual<AlgebraicDouble> dest, MultivariateDual<AlgebraicDouble> a, MultivariateDual<AlgebraicDouble> b) { 268 if (a.Value.CompareTo(b.Value) <= 0) { 269 dest.Assign(a); 270 } else { 271 dest.Assign(b); 272 } 273 } 274 private void AssignMax(MultivariateDual<AlgebraicDouble> dest, MultivariateDual<AlgebraicDouble> a, MultivariateDual<AlgebraicDouble> b) { 275 if (a.Value.CompareTo(b.Value) <= 0) { 276 dest.Assign(b); 277 } else { 278 dest.Assign(a); 279 } 280 } 281 282 // determines the smaller and larger value and sets low and high accordingly 283 private void AssignLowAndHigh(MultivariateDual<AlgebraicDouble> a, MultivariateDual<AlgebraicDouble> b) { 284 // we must make sure that low and high are different objects when a == b 285 if (a.Value.CompareTo(b.Value) == 0) { 286 low.Assign(a); 287 high.Assign(b); 288 } else { 289 AssignMin(low, a, b); 290 AssignMax(high, a, b); 291 } 292 } 293 private void AssignLowAndHigh(params MultivariateDual<AlgebraicDouble>[] xs) { 294 if (xs.Length <= 2) throw new ArgumentException("need at least 3 arguments"); 295 AssignLowAndHigh(xs[0], xs[1]); 296 for(int i=2;i<xs.Length;i++) { 297 // we must make sure that low and high are different objects when a == b 298 if (low.Value.CompareTo(xs[i].Value) > 0) low.Assign(xs[i]); 299 if (high.Value.CompareTo(xs[i].Value) < 0) high.Assign(xs[i]); 300 } 301 } 302 #endregion 303 292 304 } 293 305 } -
branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/AlgebraicSparseVector.cs
r17298 r17303 109 109 } 110 110 111 public AlgebraicSparseVector<K, T> AssignMin(AlgebraicSparseVector<K, T> other) {112 // assumes that keys without a matching key in other are zero and vice versa113 foreach (var kvp in elems) if (!other.elems.ContainsKey(kvp.Key)) kvp.Value.AssignMin(kvp.Value.Zero); // min(v, 0)114 foreach (var kvp in other.elems) {115 if (elems.TryGetValue(kvp.Key, out T value))116 value.AssignMin(kvp.Value);117 else118 elems.Add(kvp.Key, kvp.Value.Zero.AssignMin(kvp.Value));119 }120 return this;121 }122 123 public AlgebraicSparseVector<K, T> AssignMax(AlgebraicSparseVector<K, T> other) {124 // assumes that keys without a matching key in other are zero and vice versa125 foreach (var kvp in elems) if (!other.elems.ContainsKey(kvp.Key)) kvp.Value.AssignMax(kvp.Value.Zero); // max(v, 0)126 foreach (var kvp in other.elems) {127 if (elems.TryGetValue(kvp.Key, out T value))128 value.AssignMax(kvp.Value);129 else130 elems.Add(kvp.Key, kvp.Value.Zero.AssignMax(kvp.Value));131 }132 return this;133 }134 135 136 111 public AlgebraicSparseVector<K, T> Clone() { 137 112 return new AlgebraicSparseVector<K, T>(this); -
branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/Dual.cs
r17295 r17303 4 4 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 5 5 public class Dual<V> : IAlgebraicType<Dual<V>> 6 where V : I AlgebraicType<V> {6 where V : IComparableAlgebraicType<V> { 7 7 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 8 8 private V v; … … 54 54 55 55 public Dual<V> AssignMin(Dual<V> other) { 56 throw new NotImplementedException(); 56 if(v.CompareTo(other.v) > 0) { 57 v.Assign(other.v); 58 dv.Assign(other.dv); 59 } 60 return this; 57 61 } 58 62 59 63 public Dual<V> AssignMax(Dual<V> other) { 60 throw new NotImplementedException(); 64 if (v.CompareTo(other.v) <= 0) { 65 v.Assign(other.v); 66 dv.Assign(other.dv); 67 } 68 return this; 61 69 } 62 70 } -
branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IAlgebraicType.cs
r17295 r17303 1 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 1 using System; 2 3 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 2 4 public interface IAlgebraicType<T> { 3 5 T Zero { get; } // Zero and One must create new objects … … 21 23 T AssignIntRoot(T a, int r); 22 24 T AssignSgn(T a); // set this to sign(a) 23 T AssignMin(T other); // set this min(this, other)24 T AssignMax(T other); // set this max(this, other)25 //T AssignMin(T other); // set this min(this, other) 26 //T AssignMax(T other); // set this max(this, other) 25 27 T Clone(); 26 28 } 29 30 public interface IComparableAlgebraicType<T> : IAlgebraicType<T>, IComparable<T> { 31 32 } 27 33 } -
branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/MultivariateDual.cs
r17297 r17303 17 17 public AlgebraicSparseVector<object, V> Gradient => dv; // <key,value> partial derivative identified via the key 18 18 19 19 20 private MultivariateDual(MultivariateDual<V> orig) { this.v = orig.v.Clone(); this.dv = orig.dv.Clone(); } 21 22 /// <summary> 23 /// Constructor which sets value and derivative to zero 24 /// </summary> 25 public MultivariateDual() { 26 v = new V(); // assumed to be zero 27 dv = new AlgebraicSparseVector<object, V>(); 28 } 20 29 21 30 /// <summary> … … 83 92 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 84 93 public MultivariateDual<V> AssignSgn(MultivariateDual<V> a) { v.AssignSgn(a.v); dv = a.dv.Zero; return this; } // sign(f(x))' = 0; 85 86 public MultivariateDual<V> AssignMin(MultivariateDual<V> other) {87 throw new NotImplementedException();88 }89 90 public MultivariateDual<V> AssignMax(MultivariateDual<V> other) {91 throw new NotImplementedException();92 }93 94 } 94 95 } -
branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/VectorAutoDiffEvaluator.cs
r17296 r17303 5 5 6 6 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 7 public sealed class VectorAutoDiffEvaluator : InterpreterBase< MultivariateDual<AlgebraicDoubleVector>> {7 public sealed class VectorAutoDiffEvaluator : InterpreterBase<VectorOfAlgebraic<MultivariateDual<AlgebraicDouble>>> { 8 8 private const int BATCHSIZE = 128; 9 9 [ThreadStatic] … … 57 57 for (rowIndex = 0; rowIndex < roundedTotal; rowIndex += BATCHSIZE) { 58 58 Evaluate(code); 59 code[0].value.Value.CopyTo(fi, rowIndex, BATCHSIZE);60 59 61 // TRANSPOSE into JAC 62 var g = code[0].value.Gradient; 63 for (int j = 0; j < nParams; ++j) { 64 if (g.Elements.TryGetValue(j, out AlgebraicDoubleVector v)) { 65 v.CopyColumnTo(jac, j, rowIndex, BATCHSIZE); 66 } else { 67 for (int r = 0; r < BATCHSIZE; r++) jac[rowIndex + r, j] = 0.0; 60 // code[0].value.Value.CopyTo(fi, rowIndex, BATCHSIZE); 61 var v = code[0].value; 62 for (int k = 0; k < BATCHSIZE; k++) { 63 fi[rowIndex + k] = v[k].Value.Value; 64 65 // copy gradient to Jacobian 66 var g = v[k].Gradient; 67 for (int j = 0; j < nParams; ++j) { 68 if (g.Elements.TryGetValue(j, out AlgebraicDouble gj)) { 69 jac[rowIndex + k, j] = gj.Value; 70 } else { 71 jac[rowIndex + k, j] = 0.0; 72 } 68 73 } 69 74 } … … 72 77 if (remainingRows > 0) { 73 78 Evaluate(code); 74 code[0].value.Value.CopyTo(fi, roundedTotal, remainingRows); 79 // code[0].value.Value.CopyTo(fi, roundedTotal, remainingRows); 80 var v = code[0].value; 81 for (int k = 0; k < remainingRows; k++) { 82 fi[roundedTotal + k] = v[k].Value.Value; 75 83 76 var g = code[0].value.Gradient; 77 for (int j = 0; j < nParams; ++j) 78 if (g.Elements.TryGetValue(j, out AlgebraicDoubleVector v)) { 79 v.CopyColumnTo(jac, j, roundedTotal, remainingRows); 80 } else { 81 for (int r = 0; r < remainingRows; r++) jac[roundedTotal + r, j] = 0.0; 84 var g = v[k].Gradient; 85 for (int j = 0; j < nParams; ++j) { 86 if (g.Elements.TryGetValue(j, out AlgebraicDouble gj)) { 87 jac[roundedTotal + k, j] = gj.Value; 88 } else { 89 jac[roundedTotal + k, j] = 0.0; 90 } 82 91 } 92 } 83 93 } 84 94 } 85 95 86 96 protected override void InitializeInternalInstruction(ref Instruction instruction, ISymbolicExpressionTreeNode node) { 87 var zero = new AlgebraicDoubleVector(BATCHSIZE); 88 instruction.value = new MultivariateDual<AlgebraicDoubleVector>(zero); 97 instruction.value = new VectorOfAlgebraic<MultivariateDual<AlgebraicDouble>>(BATCHSIZE).Zero; // XXX zero needed? 89 98 } 90 99 91 100 protected override void InitializeTerminalInstruction(ref Instruction instruction, ConstantTreeNode constant) { 92 var g_arr = new double[BATCHSIZE];93 101 if (node2paramIdx.TryGetValue(constant, out var paramIdx)) { 94 for (int i = 0; i < BATCHSIZE; i++) g_arr[i] = 1.0; 95 var g = new AlgebraicDoubleVector(g_arr); 96 instruction.value = new MultivariateDual<AlgebraicDoubleVector>(new AlgebraicDoubleVector(BATCHSIZE), paramIdx, g); // only a single column for the gradient 102 instruction.value = new VectorOfAlgebraic<MultivariateDual<AlgebraicDouble>>(BATCHSIZE); 103 for (int k = 0; k < BATCHSIZE; k++) { 104 instruction.value[k] = new MultivariateDual<AlgebraicDouble>(constant.Value, paramIdx, 1.0); // gradient is 1.0 for all elements 105 } 97 106 } else { 98 instruction.value = new MultivariateDual<AlgebraicDoubleVector>(new AlgebraicDoubleVector(BATCHSIZE)); 107 instruction.value = new VectorOfAlgebraic<MultivariateDual<AlgebraicDouble>>(BATCHSIZE); 108 for (int k = 0; k < BATCHSIZE; k++) { 109 instruction.value[k] = new MultivariateDual<AlgebraicDouble>(constant.Value); // zero gradient 110 } 99 111 } 100 112 101 instruction.dblVal = constant.Value; 102 instruction.value.Value.AssignConstant(instruction.dblVal); 113 instruction.dblVal = constant.Value; // also store the parameter value in the instruction (not absolutely necessary, will not be used) 103 114 } 104 115 … … 115 126 if (node2paramIdx.ContainsKey(variable)) { 116 127 paramIdx = node2paramIdx[variable]; 117 var f = new AlgebraicDoubleVector(BATCHSIZE); 118 var g = new AlgebraicDoubleVector(BATCHSIZE); 119 instruction.value = new MultivariateDual<AlgebraicDoubleVector>(f, paramIdx, g); 128 instruction.value = new VectorOfAlgebraic<MultivariateDual<AlgebraicDouble>>(BATCHSIZE); 129 for(int k=0;k<BATCHSIZE;k++) { 130 instruction.value[k] = new MultivariateDual<AlgebraicDouble>(0.0, paramIdx, 0.0); // values are set in LoadVariable() 131 } 120 132 } else { 121 133 var f = new AlgebraicDoubleVector(BATCHSIZE); 122 instruction.value = new MultivariateDual<AlgebraicDoubleVector>(f); 134 instruction.value = new VectorOfAlgebraic<MultivariateDual<AlgebraicDouble>>(BATCHSIZE); 135 for (int k = 0; k < BATCHSIZE; k++) { 136 instruction.value[k] = new MultivariateDual<AlgebraicDouble>(0.0); // values are set in LoadVariable() 137 } 123 138 } 124 139 125 instruction.dblVal = variable.Weight; 140 instruction.dblVal = variable.Weight; 126 141 instruction.data = new object[] { data, paramIdx }; 127 142 } … … 131 146 var data = (double[])((object[])a.data)[0]; 132 147 133 for (int i = rowIndex; i < rows.Length && i - rowIndex < BATCHSIZE; i++) a.value.Value[i - rowIndex] = data[rows[i]]; 134 a.value.Scale(a.dblVal); 148 for (int i = rowIndex; i < rows.Length && i - rowIndex < BATCHSIZE; i++) { 149 a.value[i - rowIndex].Value.Assign(a.dblVal * data[rows[i]]); 150 } 135 151 136 152 if (paramIdx >= 0) { 137 153 // update gradient with variable values 138 var g = a.value.Gradient.Elements[paramIdx];139 154 for (int i = rowIndex; i < rows.Length && i - rowIndex < BATCHSIZE; i++) { 140 g[i - rowIndex] = data[rows[i]];155 a.value[i - rowIndex].Gradient.Elements[paramIdx].Assign(data[rows[i]]); 141 156 } 142 157 }
Note: See TracChangeset
for help on using the changeset viewer.