Changeset 16695


Ignore:
Timestamp:
03/19/19 13:20:46 (3 months ago)
Author:
gkronber
Message:

#2994: renamed classes Algebraic..., added DebuggerDisplay attributes to simplify debugging. Fixed bugs in static methods for Algebraic

File:
1 edited

Legend:

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

    r16694 r16695  
    11using System;
    22using System.Collections.Generic;
     3using System.Diagnostics;
    34using System.Linq;
    45using HeuristicLab.Common;
     
    120121
    121122
    122   public sealed class VectorEvaluator : Interpreter<DoubleVector> {
     123  public sealed class VectorEvaluator : Interpreter<AlgebraicDoubleVector> {
    123124    private const int BATCHSIZE = 128;
    124125    [ThreadStatic]
     
    169170    protected override void InitializeTerminalInstruction(ref Instruction instruction, ConstantTreeNode constant) {
    170171      instruction.dblVal = constant.Value;
    171       instruction.value = new DoubleVector(BATCHSIZE);
     172      instruction.value = new AlgebraicDoubleVector(BATCHSIZE);
    172173      instruction.value.AssignConstant(instruction.dblVal);
    173174    }
     
    175176    protected override void InitializeTerminalInstruction(ref Instruction instruction, VariableTreeNode variable) {
    176177      instruction.dblVal = variable.Weight;
    177       instruction.value = new DoubleVector(BATCHSIZE);
     178      instruction.value = new AlgebraicDoubleVector(BATCHSIZE);
    178179      if (cachedData.ContainsKey(variable.VariableName)) {
    179180        instruction.data = cachedData[variable.VariableName];
     
    185186
    186187    protected override void InitializeInternalInstruction(ref Instruction instruction, ISymbolicExpressionTreeNode node) {
    187       instruction.value = new DoubleVector(BATCHSIZE);
     188      instruction.value = new AlgebraicDoubleVector(BATCHSIZE);
    188189    }
    189190
     
    195196  }
    196197
    197   public sealed class VectorAutoDiffEvaluator : Interpreter<MultivariateDual<DoubleVector>> {
     198  public sealed class VectorAutoDiffEvaluator : Interpreter<MultivariateDual<AlgebraicDoubleVector>> {
    198199    private const int BATCHSIZE = 128;
    199200    [ThreadStatic]
     
    261262
    262263    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);
    265266    }
    266267
     
    269270      if (node2paramIdx.TryGetValue(constant, out var paramIdx)) {
    270271        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>(new DoubleVector(BATCHSIZE), paramIdx, g); // only a single column for the gradient
     272        var g = new AlgebraicDoubleVector(g_arr);
     273        instruction.value = new MultivariateDual<AlgebraicDoubleVector>(new AlgebraicDoubleVector(BATCHSIZE), paramIdx, g); // only a single column for the gradient
    273274      } else {
    274         instruction.value = new MultivariateDual<DoubleVector>(new DoubleVector(BATCHSIZE));
     275        instruction.value = new MultivariateDual<AlgebraicDoubleVector>(new AlgebraicDoubleVector(BATCHSIZE));
    275276      }
    276277
     
    291292      if (node2paramIdx.ContainsKey(variable)) {
    292293        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);
    296297      } 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);
    299300      }
    300301
     
    397398
    398399  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; }
    409410
    410411    public static T Max<T>(T a, T b) where T : IAlgebraicType<T> {
     
    420421
    421422  // algebraic type wrapper for a double value
     423  [DebuggerDisplay("{Value}")]
    422424  public sealed class AlgebraicDouble : IAlgebraicType<AlgebraicDouble> {
    423425    public static implicit operator AlgebraicDouble(double value) { return new AlgebraicDouble(value); }
     
    425427    public double Value;
    426428
     429    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    427430    public AlgebraicDouble Zero => new AlgebraicDouble(0.0);
    428431    public AlgebraicDouble() { }
     
    445448    public AlgebraicDouble AssignSgn(AlgebraicDouble a) { Value = Math.Sign(a.Value); return this; }
    446449    public AlgebraicDouble Clone() { return new AlgebraicDouble(Value); }
     450
     451    public override string ToString() {
     452      return Value.ToString();
     453    }
    447454  }
    448455
    449456  // 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> {
    451459    private double[] arr;
    452 
    453 
    454460    public double this[int idx] { get { return arr[idx]; } set { arr[idx] = value; } }
    455 
    456461    public int Length => arr.Length;
    457462
    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() { }
    463466
    464467    /// <summary>
     
    466469    /// </summary>
    467470    /// <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);
    492494      Array.Copy(arr, v.arr, v.arr.Length);
    493495      return v;
     
    514516      for (int j = 0; j < len; ++j) dest[row + j, column] = arr[j];
    515517    }
     518
     519    public override string ToString() {
     520      return "{" + string.Join(", ", arr.Take(Math.Max(5, arr.Length))) + (arr.Length > 5 ? "..." : string.Empty) + "}";
     521    }
    516522  }
    517523
    518524  // 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> {
    520526    private T[] elems;
    521527
     
    524530    public int Length => elems.Length;
    525531
    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]; }
    532535
    533536    /// <summary>
     
    535538    /// </summary>
    536539    /// <param name="elems">The array is copied (element-wise clone)</param>
    537     public Vector(T[] elems) {
     540    public AlgebraicVector(T[] elems) {
    538541      this.elems = new T[elems.Length];
    539542      for (int i = 0; i < elems.Length; ++i) { this.elems[i] = elems[i].Clone(); }
     
    545548    /// <param name="elems">Array is not copied!</param>
    546549    /// <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>();
    549552      v.elems = elems;
    550553      return v;
     
    556559    }
    557560
    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) {
    563564      var oldLen = Length;
    564565      Array.Resize(ref this.elems, oldLen + other.Length);
     
    569570    }
    570571
    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; }
    589591  }
    590592
     
    595597  /// <typeparam name="K">Key type</typeparam>
    596598  /// <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)]
    599602    private Dictionary<K, T> elems;
    600603    public IReadOnlyDictionary<K, T> Elements => elems;
    601604
    602605
    603     public SparseVector(SparseVector<K, T> original) {
     606    public AlgebraicSparseVector(AlgebraicSparseVector<K, T> original) {
    604607      elems = original.elems.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Clone());
    605608    }
     
    610613    /// <param name="keys"></param>
    611614    /// <param name="values">values are cloned</param>
    612     public SparseVector(K[] keys, T[] values) {
     615    public AlgebraicSparseVector(K[] keys, T[] values) {
    613616      if (keys.Length != values.Length) throw new ArgumentException("lengths of keys and values doesn't match in SparseVector");
    614617      elems = new Dictionary<K, T>(keys.Length);
     
    618621    }
    619622
    620     public SparseVector() {
     623    public AlgebraicSparseVector() {
    621624      this.elems = new Dictionary<K, T>();
    622625    }
     
    624627
    625628
    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
    627632      foreach (var kvp in a.elems) {
     633        // this = f(a, this)
    628634        if (elems.TryGetValue(kvp.Key, out T value))
    629635          mapAssign(kvp.Value, value);
    630636        else {
     637          // this = f(a, 0)
    631638          var newValue = kvp.Value.Zero;
    632639          elems.Add(kvp.Key, newValue);
     
    634641        }
    635642      }
    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}]")]
    664712  public class AlgebraicInterval : IAlgebraicType<AlgebraicInterval> {
     713    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    665714    private MultivariateDual<AlgebraicDouble> low;
     715    public MultivariateDual<AlgebraicDouble> LowerBound => low.Clone();
     716
     717    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    666718    private MultivariateDual<AlgebraicDouble> high;
    667 
    668     public MultivariateDual<AlgebraicDouble> LowerBound => low.Clone();
    669719    public MultivariateDual<AlgebraicDouble> UpperBound => high.Clone();
    670720
     
    682732    }
    683733
     734    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    684735    public AlgebraicInterval Zero => new AlgebraicInterval(0.0, 0.0);
    685736    public AlgebraicInterval Add(AlgebraicInterval a) {
     
    886937  }
    887938
    888 
    889939  public class Dual<V> : IAlgebraicType<Dual<V>>
    890940    where V : IAlgebraicType<V> {
     941    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    891942    private V v;
    892943    public V Value => v;
    893944
     945    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    894946    private V dv;
    895947    public V Derivative => dv;
     
    897949    public Dual(V v, V dv) { this.v = v; this.dv = dv; }
    898950
     951    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    899952    public Dual<V> Zero => new Dual<V>(Value.Zero, Derivative.Zero);
    900953
     
    937990  /// </summary>
    938991  /// <typeparam name="V"></typeparam>
     992  [DebuggerDisplay("v={Value}; dv={dv}")]
    939993  public class MultivariateDual<V> : IAlgebraicType<MultivariateDual<V>> where V : IAlgebraicType<V>, new() {
     994    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    940995    private V v;
    941996    public V Value => v;
    942997
    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
    9451001
    9461002    private MultivariateDual(MultivariateDual<V> orig) { this.v = orig.v.Clone(); this.dv = orig.dv.Clone(); }
     
    9501006    /// </summary>
    9511007    /// <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>(); }
    9531009
    9541010    /// <summary>
     
    9581014    /// <param name="keys"></param>
    9591015    /// <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); }
    9611017
    9621018    /// <summary>
     
    9661022    /// <param name="key"></param>
    9671023    /// <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 }); }
    9691025
    9701026    /// <summary>
     
    9731029    /// <param name="v">The value (not cloned).</param>
    9741030    /// <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; }
    9761032
    9771033    public MultivariateDual<V> Clone() { return new MultivariateDual<V>(this); }
Note: See TracChangeset for help on using the changeset viewer.