Changeset 16695
 Timestamp:
 03/19/19 13:20:46 (3 months ago)
 File:

 1 edited
Legend:
 Unmodified
 Added
 Removed

branches/2994AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/Interpreter.cs
r16694 r16695 1 1 using System; 2 2 using System.Collections.Generic; 3 using System.Diagnostics; 3 4 using System.Linq; 4 5 using HeuristicLab.Common; … … 120 121 121 122 122 public sealed class VectorEvaluator : Interpreter< DoubleVector> {123 public sealed class VectorEvaluator : Interpreter<AlgebraicDoubleVector> { 123 124 private const int BATCHSIZE = 128; 124 125 [ThreadStatic] … … 169 170 protected override void InitializeTerminalInstruction(ref Instruction instruction, ConstantTreeNode constant) { 170 171 instruction.dblVal = constant.Value; 171 instruction.value = new DoubleVector(BATCHSIZE);172 instruction.value = new AlgebraicDoubleVector(BATCHSIZE); 172 173 instruction.value.AssignConstant(instruction.dblVal); 173 174 } … … 175 176 protected override void InitializeTerminalInstruction(ref Instruction instruction, VariableTreeNode variable) { 176 177 instruction.dblVal = variable.Weight; 177 instruction.value = new DoubleVector(BATCHSIZE);178 instruction.value = new AlgebraicDoubleVector(BATCHSIZE); 178 179 if (cachedData.ContainsKey(variable.VariableName)) { 179 180 instruction.data = cachedData[variable.VariableName]; … … 185 186 186 187 protected override void InitializeInternalInstruction(ref Instruction instruction, ISymbolicExpressionTreeNode node) { 187 instruction.value = new DoubleVector(BATCHSIZE);188 instruction.value = new AlgebraicDoubleVector(BATCHSIZE); 188 189 } 189 190 … … 195 196 } 196 197 197 public sealed class VectorAutoDiffEvaluator : Interpreter<MultivariateDual< DoubleVector>> {198 public sealed class VectorAutoDiffEvaluator : Interpreter<MultivariateDual<AlgebraicDoubleVector>> { 198 199 private const int BATCHSIZE = 128; 199 200 [ThreadStatic] … … 261 262 262 263 protected override void InitializeInternalInstruction(ref Instruction instruction, ISymbolicExpressionTreeNode node) { 263 var zero = new DoubleVector(BATCHSIZE);264 instruction.value = new MultivariateDual< DoubleVector>(zero);264 var zero = new AlgebraicDoubleVector(BATCHSIZE); 265 instruction.value = new MultivariateDual<AlgebraicDoubleVector>(zero); 265 266 } 266 267 … … 269 270 if (node2paramIdx.TryGetValue(constant, out var paramIdx)) { 270 271 for (int i = 0; i < BATCHSIZE; i++) g_arr[i] = 1.0; 271 var g = new DoubleVector(g_arr);272 instruction.value = new MultivariateDual< DoubleVector>(newDoubleVector(BATCHSIZE), paramIdx, g); // only a single column for the gradient272 var g = new AlgebraicDoubleVector(g_arr); 273 instruction.value = new MultivariateDual<AlgebraicDoubleVector>(new AlgebraicDoubleVector(BATCHSIZE), paramIdx, g); // only a single column for the gradient 273 274 } else { 274 instruction.value = new MultivariateDual< DoubleVector>(newDoubleVector(BATCHSIZE));275 instruction.value = new MultivariateDual<AlgebraicDoubleVector>(new AlgebraicDoubleVector(BATCHSIZE)); 275 276 } 276 277 … … 291 292 if (node2paramIdx.ContainsKey(variable)) { 292 293 paramIdx = node2paramIdx[variable]; 293 var f = new DoubleVector(BATCHSIZE);294 var g = new DoubleVector(BATCHSIZE);295 instruction.value = new MultivariateDual< DoubleVector>(f, paramIdx, g);294 var f = new AlgebraicDoubleVector(BATCHSIZE); 295 var g = new AlgebraicDoubleVector(BATCHSIZE); 296 instruction.value = new MultivariateDual<AlgebraicDoubleVector>(f, paramIdx, g); 296 297 } else { 297 var f = new DoubleVector(BATCHSIZE);298 instruction.value = new MultivariateDual< DoubleVector>(f);298 var f = new AlgebraicDoubleVector(BATCHSIZE); 299 instruction.value = new MultivariateDual<AlgebraicDoubleVector>(f); 299 300 } 300 301 … … 397 398 398 399 public static class Algebraic { 399 public static T Abs<T>(this T a) where T : IAlgebraicType<T> { a.AssignAbs(a ); return a; }400 public static T Neg<T>(this T a) where T : IAlgebraicType<T> { a.AssignNeg(a ); return a; }401 public static T Inv<T>(this T a) where T : IAlgebraicType<T> { a.AssignInv(a ); return a; }402 public static T Log<T>(this T a) where T : IAlgebraicType<T> { a.AssignLog(a ); return a; }403 public static T Exp<T>(this T a) where T : IAlgebraicType<T> { a.AssignExp(a ); return a; }404 public static T Sin<T>(this T a) where T : IAlgebraicType<T> { a.AssignSin(a ); return a; }405 public static T Cos<T>(this T a) where T : IAlgebraicType<T> { a.AssignCos(a ); return a; }406 public static T Sgn<T>(this T a) where T : IAlgebraicType<T> { a.AssignSgn(a ); return a; }407 public static T IntPower<T>(this T a, int p) where T : IAlgebraicType<T> { a.AssignIntPower(a , p); return a; }408 public static T IntRoot<T>(this T a, int r) where T : IAlgebraicType<T> { a.AssignIntRoot(a , r); return a; }400 public static T Abs<T>(this T a) where T : IAlgebraicType<T> { a.AssignAbs(a.Clone()); return a; } 401 public static T Neg<T>(this T a) where T : IAlgebraicType<T> { a.AssignNeg(a.Clone()); return a; } 402 public static T Inv<T>(this T a) where T : IAlgebraicType<T> { a.AssignInv(a.Clone()); return a; } 403 public static T Log<T>(this T a) where T : IAlgebraicType<T> { a.AssignLog(a.Clone()); return a; } 404 public static T Exp<T>(this T a) where T : IAlgebraicType<T> { a.AssignExp(a.Clone()); return a; } 405 public static T Sin<T>(this T a) where T : IAlgebraicType<T> { a.AssignSin(a.Clone()); return a; } 406 public static T Cos<T>(this T a) where T : IAlgebraicType<T> { a.AssignCos(a.Clone()); return a; } 407 public static T Sgn<T>(this T a) where T : IAlgebraicType<T> { a.AssignSgn(a.Clone()); return a; } 408 public static T IntPower<T>(this T a, int p) where T : IAlgebraicType<T> { a.AssignIntPower(a.Clone(), p); return a; } 409 public static T IntRoot<T>(this T a, int r) where T : IAlgebraicType<T> { a.AssignIntRoot(a.Clone(), r); return a; } 409 410 410 411 public static T Max<T>(T a, T b) where T : IAlgebraicType<T> { … … 420 421 421 422 // algebraic type wrapper for a double value 423 [DebuggerDisplay("{Value}")] 422 424 public sealed class AlgebraicDouble : IAlgebraicType<AlgebraicDouble> { 423 425 public static implicit operator AlgebraicDouble(double value) { return new AlgebraicDouble(value); } … … 425 427 public double Value; 426 428 429 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 427 430 public AlgebraicDouble Zero => new AlgebraicDouble(0.0); 428 431 public AlgebraicDouble() { } … … 445 448 public AlgebraicDouble AssignSgn(AlgebraicDouble a) { Value = Math.Sign(a.Value); return this; } 446 449 public AlgebraicDouble Clone() { return new AlgebraicDouble(Value); } 450 451 public override string ToString() { 452 return Value.ToString(); 453 } 447 454 } 448 455 449 456 // a simple vector as an algebraic type 450 public class DoubleVector : IAlgebraicType<DoubleVector> { 457 [DebuggerDisplay("DoubleVector(len={Length}): {string.}")] 458 public class AlgebraicDoubleVector : IAlgebraicType<AlgebraicDoubleVector> { 451 459 private double[] arr; 452 453 454 460 public double this[int idx] { get { return arr[idx]; } set { arr[idx] = value; } } 455 456 461 public int Length => arr.Length; 457 462 458 public DoubleVector(int length) { 459 arr = new double[length]; 460 } 461 462 public DoubleVector() { } 463 public AlgebraicDoubleVector(int length) { arr = new double[length]; } 464 465 public AlgebraicDoubleVector() { } 463 466 464 467 /// <summary> … … 466 469 /// </summary> 467 470 /// <param name="arr">array is not copied</param> 468 public DoubleVector(double[] arr) { 469 this.arr = arr; 470 } 471 472 public DoubleVector Zero => new DoubleVector(new double[this.Length]); // must return vector of same length as this (therefore Zero is not static) 473 public DoubleVector Assign(DoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = a.arr[i]; } return this; } 474 public DoubleVector Add(DoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] += a.arr[i]; } return this; } 475 public DoubleVector Sub(DoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = a.arr[i]; } return this; } 476 public DoubleVector Mul(DoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] *= a.arr[i]; } return this; } 477 public DoubleVector Div(DoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] /= a.arr[i]; } return this; } 478 public DoubleVector AssignNeg(DoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = a.arr[i]; } return this; } 479 public DoubleVector AssignInv(DoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = 1.0 / a.arr[i]; } return this; } 480 public DoubleVector Scale(double s) { for (int i = 0; i < arr.Length; ++i) { arr[i] *= s; } return this; } 481 public DoubleVector AssignLog(DoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Log(a.arr[i]); } return this; } 482 public DoubleVector AssignSin(DoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Sin(a.arr[i]); } return this; } 483 public DoubleVector AssignExp(DoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Exp(a.arr[i]); } return this; } 484 public DoubleVector AssignCos(DoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Cos(a.arr[i]); } return this; } 485 public DoubleVector AssignIntPower(DoubleVector a, int p) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Pow(a.arr[i], p); } return this; } 486 public DoubleVector AssignIntRoot(DoubleVector a, int r) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Pow(a.arr[i], 1.0 / r); } return this; } 487 public DoubleVector AssignAbs(DoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Abs(a.arr[i]); } return this; } 488 public DoubleVector AssignSgn(DoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Sign(a.arr[i]); } return this; } 489 490 public DoubleVector Clone() { 491 var v = new DoubleVector(this.arr.Length); 471 public AlgebraicDoubleVector(double[] arr) { this.arr = arr; } 472 473 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 474 public AlgebraicDoubleVector Zero => new AlgebraicDoubleVector(new double[this.Length]); // must return vector of same length as this (therefore Zero is not static) 475 public AlgebraicDoubleVector Assign(AlgebraicDoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = a.arr[i]; } return this; } 476 public AlgebraicDoubleVector Add(AlgebraicDoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] += a.arr[i]; } return this; } 477 public AlgebraicDoubleVector Sub(AlgebraicDoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = a.arr[i]; } return this; } 478 public AlgebraicDoubleVector Mul(AlgebraicDoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] *= a.arr[i]; } return this; } 479 public AlgebraicDoubleVector Div(AlgebraicDoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] /= a.arr[i]; } return this; } 480 public AlgebraicDoubleVector AssignNeg(AlgebraicDoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = a.arr[i]; } return this; } 481 public AlgebraicDoubleVector AssignInv(AlgebraicDoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = 1.0 / a.arr[i]; } return this; } 482 public AlgebraicDoubleVector Scale(double s) { for (int i = 0; i < arr.Length; ++i) { arr[i] *= s; } return this; } 483 public AlgebraicDoubleVector AssignLog(AlgebraicDoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Log(a.arr[i]); } return this; } 484 public AlgebraicDoubleVector AssignSin(AlgebraicDoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Sin(a.arr[i]); } return this; } 485 public AlgebraicDoubleVector AssignExp(AlgebraicDoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Exp(a.arr[i]); } return this; } 486 public AlgebraicDoubleVector AssignCos(AlgebraicDoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Cos(a.arr[i]); } return this; } 487 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; } 488 public AlgebraicDoubleVector AssignIntRoot(AlgebraicDoubleVector a, int r) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Pow(a.arr[i], 1.0 / r); } return this; } 489 public AlgebraicDoubleVector AssignAbs(AlgebraicDoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Abs(a.arr[i]); } return this; } 490 public AlgebraicDoubleVector AssignSgn(AlgebraicDoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Sign(a.arr[i]); } return this; } 491 492 public AlgebraicDoubleVector Clone() { 493 var v = new AlgebraicDoubleVector(this.arr.Length); 492 494 Array.Copy(arr, v.arr, v.arr.Length); 493 495 return v; … … 514 516 for (int j = 0; j < len; ++j) dest[row + j, column] = arr[j]; 515 517 } 518 519 public override string ToString() { 520 return "{" + string.Join(", ", arr.Take(Math.Max(5, arr.Length))) + (arr.Length > 5 ? "..." : string.Empty) + "}"; 521 } 516 522 } 517 523 518 524 // vectors of algebraic types 519 public sealed class Vector<T> : IAlgebraicType<Vector<T>> where T : IAlgebraicType<T> {525 public sealed class AlgebraicVector<T> : IAlgebraicType<AlgebraicVector<T>> where T : IAlgebraicType<T> { 520 526 private T[] elems; 521 527 … … 524 530 public int Length => elems.Length; 525 531 526 527 private Vector() { } 528 529 public Vector(int len) { 530 elems = new T[len]; 531 } 532 private AlgebraicVector() { } 533 534 public AlgebraicVector(int len) { elems = new T[len]; } 532 535 533 536 /// <summary> … … 535 538 /// </summary> 536 539 /// <param name="elems">The array is copied (elementwise clone)</param> 537 public Vector(T[] elems) {540 public AlgebraicVector(T[] elems) { 538 541 this.elems = new T[elems.Length]; 539 542 for (int i = 0; i < elems.Length; ++i) { this.elems[i] = elems[i].Clone(); } … … 545 548 /// <param name="elems">Array is not copied!</param> 546 549 /// <returns></returns> 547 public Vector<T> FromArray(T[] elems) {548 var v = new Vector<T>();550 public AlgebraicVector<T> FromArray(T[] elems) { 551 var v = new AlgebraicVector<T>(); 549 552 v.elems = elems; 550 553 return v; … … 556 559 } 557 560 558 public Vector<T> Clone() { 559 return new Vector<T>(elems); 560 } 561 562 public Vector<T> Concat(Vector<T> other) { 561 public AlgebraicVector<T> Clone() { return new AlgebraicVector<T>(elems); } 562 563 public AlgebraicVector<T> Concat(AlgebraicVector<T> other) { 563 564 var oldLen = Length; 564 565 Array.Resize(ref this.elems, oldLen + other.Length); … … 569 570 } 570 571 571 public Vector<T> Zero => new Vector<T>(Length); 572 public Vector<T> Assign(Vector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].Assign(a.elems[i]); } return this; } 573 public Vector<T> Add(Vector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].Add(a.elems[i]); } return this; } 574 public Vector<T> Sub(Vector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].Sub(a.elems[i]); } return this; } 575 public Vector<T> Mul(Vector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].Mul(a.elems[i]); } return this; } 576 public Vector<T> Div(Vector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].Div(a.elems[i]); } return this; } 577 public Vector<T> AssignNeg(Vector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignNeg(a.elems[i]); } return this; } 578 public Vector<T> Scale(double s) { for (int i = 0; i < elems.Length; ++i) { elems[i].Scale(s); } return this; } 579 public Vector<T> Scale(T s) { for (int i = 0; i < elems.Length; ++i) { elems[i].Mul(s); } return this; } 580 public Vector<T> AssignInv(Vector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignInv(a.elems[i]); } return this; } 581 public Vector<T> AssignLog(Vector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignLog(a.elems[i]); } return this; } 582 public Vector<T> AssignExp(Vector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignExp(a.elems[i]); } return this; } 583 public Vector<T> AssignSin(Vector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignSin(a.elems[i]); } return this; } 584 public Vector<T> AssignCos(Vector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignCos(a.elems[i]); } return this; } 585 public Vector<T> AssignIntPower(Vector<T> a, int p) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignIntPower(a.elems[i], p); } return this; } 586 public Vector<T> AssignIntRoot(Vector<T> a, int r) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignIntRoot(a.elems[i], r); } return this; } 587 public Vector<T> AssignAbs(Vector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignAbs(a.elems[i]); } return this; } 588 public Vector<T> AssignSgn(Vector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignSgn(a.elems[i]); } return this; } 572 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 573 public AlgebraicVector<T> Zero => new AlgebraicVector<T>(Length); 574 public AlgebraicVector<T> Assign(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].Assign(a.elems[i]); } return this; } 575 public AlgebraicVector<T> Add(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].Add(a.elems[i]); } return this; } 576 public AlgebraicVector<T> Sub(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].Sub(a.elems[i]); } return this; } 577 public AlgebraicVector<T> Mul(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].Mul(a.elems[i]); } return this; } 578 public AlgebraicVector<T> Div(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].Div(a.elems[i]); } return this; } 579 public AlgebraicVector<T> AssignNeg(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignNeg(a.elems[i]); } return this; } 580 public AlgebraicVector<T> Scale(double s) { for (int i = 0; i < elems.Length; ++i) { elems[i].Scale(s); } return this; } 581 public AlgebraicVector<T> Scale(T s) { for (int i = 0; i < elems.Length; ++i) { elems[i].Mul(s); } return this; } 582 public AlgebraicVector<T> AssignInv(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignInv(a.elems[i]); } return this; } 583 public AlgebraicVector<T> AssignLog(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignLog(a.elems[i]); } return this; } 584 public AlgebraicVector<T> AssignExp(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignExp(a.elems[i]); } return this; } 585 public AlgebraicVector<T> AssignSin(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignSin(a.elems[i]); } return this; } 586 public AlgebraicVector<T> AssignCos(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignCos(a.elems[i]); } return this; } 587 public AlgebraicVector<T> AssignIntPower(AlgebraicVector<T> a, int p) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignIntPower(a.elems[i], p); } return this; } 588 public AlgebraicVector<T> AssignIntRoot(AlgebraicVector<T> a, int r) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignIntRoot(a.elems[i], r); } return this; } 589 public AlgebraicVector<T> AssignAbs(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignAbs(a.elems[i]); } return this; } 590 public AlgebraicVector<T> AssignSgn(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignSgn(a.elems[i]); } return this; } 589 591 } 590 592 … … 595 597 /// <typeparam name="K">Key type</typeparam> 596 598 /// <typeparam name="T">Element type</typeparam> 597 public sealed class SparseVector<K, T> : IAlgebraicType<SparseVector<K, T>> where T : IAlgebraicType<T> { 598 599 [DebuggerDisplay("SparseVector: {ToString()}")] 600 public sealed class AlgebraicSparseVector<K, T> : IAlgebraicType<AlgebraicSparseVector<K, T>> where T : IAlgebraicType<T> { 601 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 599 602 private Dictionary<K, T> elems; 600 603 public IReadOnlyDictionary<K, T> Elements => elems; 601 604 602 605 603 public SparseVector(SparseVector<K, T> original) {606 public AlgebraicSparseVector(AlgebraicSparseVector<K, T> original) { 604 607 elems = original.elems.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Clone()); 605 608 } … … 610 613 /// <param name="keys"></param> 611 614 /// <param name="values">values are cloned</param> 612 public SparseVector(K[] keys, T[] values) {615 public AlgebraicSparseVector(K[] keys, T[] values) { 613 616 if (keys.Length != values.Length) throw new ArgumentException("lengths of keys and values doesn't match in SparseVector"); 614 617 elems = new Dictionary<K, T>(keys.Length); … … 618 621 } 619 622 620 public SparseVector() {623 public AlgebraicSparseVector() { 621 624 this.elems = new Dictionary<K, T>(); 622 625 } … … 624 627 625 628 626 private void AssignTransformed(SparseVector<K, T> a, Func<T, T, T> mapAssign) { 629 // combined elements from both vectors 630 private void UnionAssign(AlgebraicSparseVector<K, T> a, Func<T, T, T> mapAssign) { 631 // elements from a 627 632 foreach (var kvp in a.elems) { 633 // this = f(a, this) 628 634 if (elems.TryGetValue(kvp.Key, out T value)) 629 635 mapAssign(kvp.Value, value); 630 636 else { 637 // this = f(a, 0) 631 638 var newValue = kvp.Value.Zero; 632 639 elems.Add(kvp.Key, newValue); … … 634 641 } 635 642 } 636 } 637 638 public SparseVector<K, T> Zero => new SparseVector<K, T>(); 639 640 public SparseVector<K, T> Scale(T s) { foreach (var kvp in elems) { kvp.Value.Mul(s); } return this; } 641 public SparseVector<K, T> Scale(double s) { foreach (var kvp in elems) { kvp.Value.Scale(s); } return this; } 642 643 public SparseVector<K, T> Assign(SparseVector<K, T> a) { AssignTransformed(a, (src, dest) => dest.Assign(src)); return this; } 644 public SparseVector<K, T> Add(SparseVector<K, T> a) { AssignTransformed(a, (src, dest) => dest.Add(src)); return this; } 645 public SparseVector<K, T> Mul(SparseVector<K, T> a) { AssignTransformed(a, (src, dest) => dest.Mul(src)); return this; } 646 public SparseVector<K, T> Sub(SparseVector<K, T> a) { AssignTransformed(a, (src, dest) => dest.Sub(src)); return this; } 647 public SparseVector<K, T> Div(SparseVector<K, T> a) { AssignTransformed(a, (src, dest) => dest.Div(src)); return this; } 648 public SparseVector<K, T> AssignInv(SparseVector<K, T> a) { AssignTransformed(a, (src, dest) => dest.AssignInv(src)); return this; } 649 public SparseVector<K, T> AssignNeg(SparseVector<K, T> a) { AssignTransformed(a, (src, dest) => dest.AssignNeg(src)); return this; } 650 public SparseVector<K, T> AssignLog(SparseVector<K, T> a) { AssignTransformed(a, (src, dest) => dest.AssignLog(src)); return this; } 651 public SparseVector<K, T> AssignExp(SparseVector<K, T> a) { AssignTransformed(a, (src, dest) => dest.AssignExp(src)); return this; } 652 public SparseVector<K, T> AssignIntPower(SparseVector<K, T> a, int p) { AssignTransformed(a, (src, dest) => dest.AssignIntPower(src, p)); return this; } 653 public SparseVector<K, T> AssignIntRoot(SparseVector<K, T> a, int r) { AssignTransformed(a, (src, dest) => dest.AssignIntRoot(src, r)); return this; } 654 public SparseVector<K, T> AssignSin(SparseVector<K, T> a) { AssignTransformed(a, (src, dest) => dest.AssignSin(src)); return this; } 655 public SparseVector<K, T> AssignCos(SparseVector<K, T> a) { AssignTransformed(a, (src, dest) => dest.AssignCos(src)); return this; } 656 public SparseVector<K, T> AssignAbs(SparseVector<K, T> a) { AssignTransformed(a, (src, dest) => dest.AssignAbs(src)); return this; } 657 public SparseVector<K, T> AssignSgn(SparseVector<K, T> a) { AssignTransformed(a, (src, dest) => dest.AssignSgn(src)); return this; } 658 659 public SparseVector<K, T> Clone() { 660 return new SparseVector<K, T>(this); 661 } 662 } 663 643 // elements from this (without a) 644 foreach (var kvp in elems) { 645 if (a.elems.ContainsKey(kvp.Key)) continue; // already processed above 646 // this = f(0, this) 647 mapAssign(kvp.Value.Zero, kvp.Value); 648 } 649 } 650 651 // keep only elements in both vectors 652 private void IntersectAssign(AlgebraicSparseVector<K, T> a, Func<T, T, T> mapAssign) { 653 List<K> keysToRemove = new List<K>(); 654 foreach (var kvp in elems) { 655 if (a.elems.TryGetValue(kvp.Key, out T value)) 656 mapAssign(value, kvp.Value); 657 else 658 keysToRemove.Add(kvp.Key); 659 } 660 foreach (var o in keysToRemove) elems.Remove(o); // > zero 661 } 662 663 // keep only elements from a 664 private void AssignFromSource(AlgebraicSparseVector<K, T> a, Func<T, T, T> mapAssign) { 665 // remove elems from this which don't occur in a 666 List<K> keysToRemove = new List<K>(); 667 foreach (var kvp in elems) { 668 if (!a.elems.ContainsKey(kvp.Key)) keysToRemove.Add(kvp.Key); 669 } 670 foreach (var o in keysToRemove) elems.Remove(o); // > zero 671 672 foreach (var kvp in a.elems) { 673 if (elems.TryGetValue(kvp.Key, out T value)) 674 mapAssign(kvp.Value, value); 675 else 676 elems.Add(kvp.Key, mapAssign(kvp.Value, kvp.Value.Zero)); 677 } 678 } 679 680 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 681 public AlgebraicSparseVector<K, T> Zero => new AlgebraicSparseVector<K, T>(); 682 683 public AlgebraicSparseVector<K, T> Scale(T s) { foreach (var kvp in elems) { kvp.Value.Mul(s); } return this; } 684 public AlgebraicSparseVector<K, T> Scale(double s) { foreach (var kvp in elems) { kvp.Value.Scale(s); } return this; } 685 686 public AlgebraicSparseVector<K, T> Assign(AlgebraicSparseVector<K, T> a) { elems.Clear(); AssignFromSource(a, (src, dest) => dest.Assign(src)); return this; } 687 public AlgebraicSparseVector<K, T> Add(AlgebraicSparseVector<K, T> a) { UnionAssign(a, (src, dest) => dest.Add(src)); return this; } 688 public AlgebraicSparseVector<K, T> Sub(AlgebraicSparseVector<K, T> a) { UnionAssign(a, (src, dest) => dest.Sub(src)); return this; } 689 public AlgebraicSparseVector<K, T> Mul(AlgebraicSparseVector<K, T> a) { IntersectAssign(a, (src, dest) => dest.Mul(src)); return this; } 690 public AlgebraicSparseVector<K, T> Div(AlgebraicSparseVector<K, T> a) { UnionAssign(a, (src, dest) => dest.Div(src)); return this; } 691 public AlgebraicSparseVector<K, T> AssignInv(AlgebraicSparseVector<K, T> a) { AssignFromSource(a, (src, dest) => dest.AssignInv(src)); return this; } 692 public AlgebraicSparseVector<K, T> AssignNeg(AlgebraicSparseVector<K, T> a) { AssignFromSource(a, (src, dest) => dest.AssignNeg(src)); return this; } 693 public AlgebraicSparseVector<K, T> AssignLog(AlgebraicSparseVector<K, T> a) { AssignFromSource(a, (src, dest) => dest.AssignLog(src)); return this; } 694 public AlgebraicSparseVector<K, T> AssignExp(AlgebraicSparseVector<K, T> a) { AssignFromSource(a, (src, dest) => dest.AssignExp(src)); return this; } 695 public AlgebraicSparseVector<K, T> AssignIntPower(AlgebraicSparseVector<K, T> a, int p) { AssignFromSource(a, (src, dest) => dest.AssignIntPower(src, p)); return this; } 696 public AlgebraicSparseVector<K, T> AssignIntRoot(AlgebraicSparseVector<K, T> a, int r) { AssignFromSource(a, (src, dest) => dest.AssignIntRoot(src, r)); return this; } 697 public AlgebraicSparseVector<K, T> AssignSin(AlgebraicSparseVector<K, T> a) { AssignFromSource(a, (src, dest) => dest.AssignSin(src)); return this; } 698 public AlgebraicSparseVector<K, T> AssignCos(AlgebraicSparseVector<K, T> a) { AssignFromSource(a, (src, dest) => dest.AssignCos(src)); return this; } 699 public AlgebraicSparseVector<K, T> AssignAbs(AlgebraicSparseVector<K, T> a) { AssignFromSource(a, (src, dest) => dest.AssignAbs(src)); return this; } 700 public AlgebraicSparseVector<K, T> AssignSgn(AlgebraicSparseVector<K, T> a) { AssignFromSource(a, (src, dest) => dest.AssignSgn(src)); return this; } 701 702 public AlgebraicSparseVector<K, T> Clone() { 703 return new AlgebraicSparseVector<K, T>(this); 704 } 705 706 public override string ToString() { 707 return "[" + string.Join(" ", elems.Select(kvp => kvp.Key + ": " + kvp.Value)) + "]"; 708 } 709 } 710 711 [DebuggerDisplay("[{low.Value}..{high.Value}]")] 664 712 public class AlgebraicInterval : IAlgebraicType<AlgebraicInterval> { 713 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 665 714 private MultivariateDual<AlgebraicDouble> low; 715 public MultivariateDual<AlgebraicDouble> LowerBound => low.Clone(); 716 717 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 666 718 private MultivariateDual<AlgebraicDouble> high; 667 668 public MultivariateDual<AlgebraicDouble> LowerBound => low.Clone();669 719 public MultivariateDual<AlgebraicDouble> UpperBound => high.Clone(); 670 720 … … 682 732 } 683 733 734 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 684 735 public AlgebraicInterval Zero => new AlgebraicInterval(0.0, 0.0); 685 736 public AlgebraicInterval Add(AlgebraicInterval a) { … … 886 937 } 887 938 888 889 939 public class Dual<V> : IAlgebraicType<Dual<V>> 890 940 where V : IAlgebraicType<V> { 941 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 891 942 private V v; 892 943 public V Value => v; 893 944 945 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 894 946 private V dv; 895 947 public V Derivative => dv; … … 897 949 public Dual(V v, V dv) { this.v = v; this.dv = dv; } 898 950 951 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 899 952 public Dual<V> Zero => new Dual<V>(Value.Zero, Derivative.Zero); 900 953 … … 937 990 /// </summary> 938 991 /// <typeparam name="V"></typeparam> 992 [DebuggerDisplay("v={Value}; dv={dv}")] 939 993 public class MultivariateDual<V> : IAlgebraicType<MultivariateDual<V>> where V : IAlgebraicType<V>, new() { 994 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 940 995 private V v; 941 996 public V Value => v; 942 997 943 private SparseVector<object, V> dv; 944 public SparseVector<object, V> Gradient => dv; // <key,value> partial derivative identified via the key 998 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 999 private AlgebraicSparseVector<object, V> dv; 1000 public AlgebraicSparseVector<object, V> Gradient => dv; // <key,value> partial derivative identified via the key 945 1001 946 1002 private MultivariateDual(MultivariateDual<V> orig) { this.v = orig.v.Clone(); this.dv = orig.dv.Clone(); } … … 950 1006 /// </summary> 951 1007 /// <param name="v"></param> 952 public MultivariateDual(V v) { this.v = v.Clone(); this.dv = new SparseVector<object, V>(); }1008 public MultivariateDual(V v) { this.v = v.Clone(); this.dv = new AlgebraicSparseVector<object, V>(); } 953 1009 954 1010 /// <summary> … … 958 1014 /// <param name="keys"></param> 959 1015 /// <param name="dv"></param> 960 public MultivariateDual(V v, object[] keys, V[] dv) { this.v = v.Clone(); this.dv = new SparseVector<object, V>(keys, dv); }1016 public MultivariateDual(V v, object[] keys, V[] dv) { this.v = v.Clone(); this.dv = new AlgebraicSparseVector<object, V>(keys, dv); } 961 1017 962 1018 /// <summary> … … 966 1022 /// <param name="key"></param> 967 1023 /// <param name="dv"></param> 968 public MultivariateDual(V v, object key, V dv) { this.v = v.Clone(); this.dv = new SparseVector<object, V>(new[] { key }, new[] { dv }); }1024 public MultivariateDual(V v, object key, V dv) { this.v = v.Clone(); this.dv = new AlgebraicSparseVector<object, V>(new[] { key }, new[] { dv }); } 969 1025 970 1026 /// <summary> … … 973 1029 /// <param name="v">The value (not cloned).</param> 974 1030 /// <param name="gradient">The gradient (not cloned).</param> 975 internal MultivariateDual(V v, SparseVector<object, V> gradient) { this.v = v; this.dv = gradient; }1031 internal MultivariateDual(V v, AlgebraicSparseVector<object, V> gradient) { this.v = v; this.dv = gradient; } 976 1032 977 1033 public MultivariateDual<V> Clone() { return new MultivariateDual<V>(this); }
Note: See TracChangeset
for help on using the changeset viewer.