1 | using System;
|
---|
2 | using System.Collections.Generic;
|
---|
3 | using System.Diagnostics;
|
---|
4 | using System.Linq;
|
---|
5 |
|
---|
6 | namespace 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 | } |
---|