source: branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/AlgebraicSparseVector.cs @ 17295

Last change on this file since 17295 was 17295, checked in by gkronber, 3 years ago

#2994: refactoring: moved types into separate files

File size: 11.0 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Diagnostics;
4using System.Linq;
5
6namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
7  /*
8  // vectors of algebraic types
9  public sealed class AlgebraicVector<T> : IAlgebraicType<AlgebraicVector<T>> where T : IAlgebraicType<T>, new() {
10    private T[] elems;
11
12    public T this[int idx] { get { return elems[idx]; } set { elems[idx] = value; } }
13
14    public int Length => elems.Length;
15
16    private AlgebraicVector() { }
17
18    public AlgebraicVector(int len) { elems = new T[len]; }
19
20    /// <summary>
21    ///
22    /// </summary>
23    /// <param name="elems">The array is copied (element-wise clone)</param>
24    public AlgebraicVector(T[] elems) {
25      this.elems = new T[elems.Length];
26      for (int i = 0; i < elems.Length; ++i) { this.elems[i] = elems[i].Clone(); }
27    }
28
29    /// <summary>
30    ///
31    /// </summary>
32    /// <param name="elems">Array is not copied!</param>
33    /// <returns></returns>
34    public AlgebraicVector<T> FromArray(T[] elems) {
35      var v = new AlgebraicVector<T>();
36      v.elems = elems;
37      return v;
38    }
39
40    public void CopyTo(T[] dest) {
41      if (dest.Length != elems.Length) throw new InvalidOperationException("arr lengths do not match in Vector<T>.Copy");
42      Array.Copy(elems, dest, dest.Length);
43    }
44
45    public AlgebraicVector<T> Clone() { return new AlgebraicVector<T>(elems); }
46
47
48    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
49    public AlgebraicVector<T> Zero => new AlgebraicVector<T>(Length);
50    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
51    public AlgebraicVector<T> One { get { var v = new AlgebraicVector<T>(Length); for (int i = 0; i < elems.Length; ++i) elems[i] = new T().One; return v; } }
52    public AlgebraicVector<T> Assign(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].Assign(a.elems[i]); } return this; }
53    public AlgebraicVector<T> Add(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].Add(a.elems[i]); } return this; }
54    public AlgebraicVector<T> Sub(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].Sub(a.elems[i]); } return this; }
55    public AlgebraicVector<T> Mul(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].Mul(a.elems[i]); } return this; }
56    public AlgebraicVector<T> Div(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].Div(a.elems[i]); } return this; }
57    public AlgebraicVector<T> AssignNeg(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignNeg(a.elems[i]); } return this; }
58    public AlgebraicVector<T> Scale(double s) { for (int i = 0; i < elems.Length; ++i) { elems[i].Scale(s); } return this; }
59    public AlgebraicVector<T> Scale(T s) { for (int i = 0; i < elems.Length; ++i) { elems[i].Mul(s); } return this; }
60    public AlgebraicVector<T> AssignInv(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignInv(a.elems[i]); } return this; }
61    public AlgebraicVector<T> AssignLog(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignLog(a.elems[i]); } return this; }
62    public AlgebraicVector<T> AssignExp(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignExp(a.elems[i]); } return this; }
63    public AlgebraicVector<T> AssignSin(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignSin(a.elems[i]); } return this; }
64    public AlgebraicVector<T> AssignCos(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignCos(a.elems[i]); } return this; }
65    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; }
66    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; }
67    public AlgebraicVector<T> AssignAbs(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignAbs(a.elems[i]); } return this; }
68    public AlgebraicVector<T> AssignSgn(AlgebraicVector<T> a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignSgn(a.elems[i]); } return this; }
69  }
70
71  */
72
73
74  /// <summary>
75  /// A sparse vector of algebraic types. Elements are accessed via a key of type K
76  /// </summary>
77  /// <typeparam name="K">Key type</typeparam>
78  /// <typeparam name="T">Element type</typeparam>
79  [DebuggerDisplay("SparseVector: {ToString()}")]
80  public sealed class AlgebraicSparseVector<K, T> : IAlgebraicType<AlgebraicSparseVector<K, T>> where T : IAlgebraicType<T> {
81    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
82    private Dictionary<K, T> elems;
83    public IReadOnlyDictionary<K, T> Elements => elems;
84
85
86    public AlgebraicSparseVector(AlgebraicSparseVector<K, T> original) {
87      elems = original.elems.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Clone());
88    }
89
90    /// <summary>
91    ///
92    /// </summary>
93    /// <param name="keys"></param>
94    /// <param name="values">values are cloned</param>
95    public AlgebraicSparseVector(K[] keys, T[] values) {
96      if (keys.Length != values.Length) throw new ArgumentException("lengths of keys and values doesn't match in SparseVector");
97      elems = new Dictionary<K, T>(keys.Length);
98      for (int i = 0; i < keys.Length; ++i) {
99        elems.Add(keys[i], values[i].Clone());
100      }
101    }
102
103    public AlgebraicSparseVector() {
104      this.elems = new Dictionary<K, T>();
105    }
106
107    // keep only elements from a
108    private void AssignFromSource(AlgebraicSparseVector<K, T> a, Func<T, T, T> mapAssign) {
109      // remove elems from this which don't occur in a
110      List<K> keysToRemove = new List<K>();
111      foreach (var kvp in elems) {
112        if (!a.elems.ContainsKey(kvp.Key)) keysToRemove.Add(kvp.Key);
113      }
114      foreach (var o in keysToRemove) elems.Remove(o); // -> zero
115
116      foreach (var kvp in a.elems) {
117        if (elems.TryGetValue(kvp.Key, out T value))
118          mapAssign(kvp.Value, value);
119        else
120          elems.Add(kvp.Key, mapAssign(kvp.Value, kvp.Value.Zero));
121      }
122    }
123
124    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
125    public AlgebraicSparseVector<K, T> Zero => new AlgebraicSparseVector<K, T>();
126    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
127    public AlgebraicSparseVector<K, T> One => throw new NotSupportedException();
128
129    public AlgebraicSparseVector<K, T> Scale(T s) { foreach (var kvp in elems) { kvp.Value.Mul(s); } return this; }
130    public AlgebraicSparseVector<K, T> Scale(double s) { foreach (var kvp in elems) { kvp.Value.Scale(s); } return this; }
131
132    public AlgebraicSparseVector<K, T> Assign(AlgebraicSparseVector<K, T> a) { elems.Clear(); AssignFromSource(a, (src, dest) => dest.Assign(src)); return this; }
133    public AlgebraicSparseVector<K, T> AssignInv(AlgebraicSparseVector<K, T> a) { AssignFromSource(a, (src, dest) => dest.AssignInv(src)); return this; }
134    public AlgebraicSparseVector<K, T> AssignNeg(AlgebraicSparseVector<K, T> a) { AssignFromSource(a, (src, dest) => dest.AssignNeg(src)); return this; }
135    public AlgebraicSparseVector<K, T> AssignLog(AlgebraicSparseVector<K, T> a) { AssignFromSource(a, (src, dest) => dest.AssignLog(src)); return this; }
136    public AlgebraicSparseVector<K, T> AssignExp(AlgebraicSparseVector<K, T> a) { AssignFromSource(a, (src, dest) => dest.AssignExp(src)); return this; }
137    public AlgebraicSparseVector<K, T> AssignIntPower(AlgebraicSparseVector<K, T> a, int p) { AssignFromSource(a, (src, dest) => dest.AssignIntPower(src, p)); return this; }
138    public AlgebraicSparseVector<K, T> AssignIntRoot(AlgebraicSparseVector<K, T> a, int r) { AssignFromSource(a, (src, dest) => dest.AssignIntRoot(src, r)); return this; }
139    public AlgebraicSparseVector<K, T> AssignSin(AlgebraicSparseVector<K, T> a) { AssignFromSource(a, (src, dest) => dest.AssignSin(src)); return this; }
140    public AlgebraicSparseVector<K, T> AssignCos(AlgebraicSparseVector<K, T> a) { AssignFromSource(a, (src, dest) => dest.AssignCos(src)); return this; }
141    public AlgebraicSparseVector<K, T> AssignTanh(AlgebraicSparseVector<K, T> a) { AssignFromSource(a, (src, dest) => dest.AssignTanh(src)); return this; }
142    public AlgebraicSparseVector<K, T> AssignAbs(AlgebraicSparseVector<K, T> a) { AssignFromSource(a, (src, dest) => dest.AssignAbs(src)); return this; }
143    public AlgebraicSparseVector<K, T> AssignSgn(AlgebraicSparseVector<K, T> a) { AssignFromSource(a, (src, dest) => dest.AssignSgn(src)); return this; }
144    public AlgebraicSparseVector<K, T> Add(AlgebraicSparseVector<K, T> a) {
145      foreach (var kvp in a.elems) {
146        if (elems.TryGetValue(kvp.Key, out T value))
147          value.Add(kvp.Value);
148        else
149          elems.Add(kvp.Key, kvp.Value.Clone()); // 0 + a
150      }
151      return this;
152    }
153
154    public AlgebraicSparseVector<K, T> Sub(AlgebraicSparseVector<K, T> a) {
155      foreach (var kvp in a.elems) {
156        if (elems.TryGetValue(kvp.Key, out T value))
157          value.Sub(kvp.Value);
158        else
159          elems.Add(kvp.Key, kvp.Value.Zero.Sub(kvp.Value)); // 0 - a
160      }
161      return this;
162    }
163
164    public AlgebraicSparseVector<K, T> Mul(AlgebraicSparseVector<K, T> a) {
165      var keys = elems.Keys.ToArray();
166      foreach (var k in keys) if (!a.elems.ContainsKey(k)) elems.Remove(k); // 0 * a => 0
167      foreach (var kvp in a.elems) {
168        if (elems.TryGetValue(kvp.Key, out T value))
169          value.Mul(kvp.Value); // this * a
170      }
171      return this;
172    }
173
174    public AlgebraicSparseVector<K, T> Div(AlgebraicSparseVector<K, T> a) {
175      return Mul(a.Clone().Inv());
176    }
177
178    public AlgebraicSparseVector<K, T> AssignMin(AlgebraicSparseVector<K, T> other) {
179      // assumes that keys without a matching key in other are zero and vice versa
180      foreach (var kvp in elems) if (!other.elems.ContainsKey(kvp.Key)) kvp.Value.AssignMin(kvp.Value.Zero); // min(v, 0)
181      foreach (var kvp in other.elems) {
182        if (elems.TryGetValue(kvp.Key, out T value))
183          value.AssignMin(kvp.Value);
184        else
185          elems.Add(kvp.Key, kvp.Value.Zero.AssignMin(kvp.Value));
186      }
187      return this;
188    }
189
190    public AlgebraicSparseVector<K, T> AssignMax(AlgebraicSparseVector<K, T> other) {
191      // assumes that keys without a matching key in other are zero and vice versa
192      foreach (var kvp in elems) if (!other.elems.ContainsKey(kvp.Key)) kvp.Value.AssignMax(kvp.Value.Zero); // max(v, 0)
193      foreach (var kvp in other.elems) {
194        if (elems.TryGetValue(kvp.Key, out T value))
195          value.AssignMax(kvp.Value);
196        else
197          elems.Add(kvp.Key, kvp.Value.Zero.AssignMax(kvp.Value));
198      }
199      return this;
200    }
201
202
203    public AlgebraicSparseVector<K, T> Clone() {
204      return new AlgebraicSparseVector<K, T>(this);
205    }
206
207    public override string ToString() {
208      return "[" + string.Join(" ", elems.Select(kvp => kvp.Key + ": " + kvp.Value)) + "]";
209    }
210  }
211}
Note: See TracBrowser for help on using the repository browser.