Changeset 17303 for branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/VectorAutoDiffEvaluator.cs
- Timestamp:
- 10/03/19 12:30:19 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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.