using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; namespace HeuristicLab.Problems.DataAnalysis.Symbolic { /* // vectors of algebraic types public sealed class AlgebraicVector : IAlgebraicType> where T : IAlgebraicType, new() { private T[] elems; public T this[int idx] { get { return elems[idx]; } set { elems[idx] = value; } } public int Length => elems.Length; private AlgebraicVector() { } public AlgebraicVector(int len) { elems = new T[len]; } /// /// /// /// The array is copied (element-wise clone) public AlgebraicVector(T[] elems) { this.elems = new T[elems.Length]; for (int i = 0; i < elems.Length; ++i) { this.elems[i] = elems[i].Clone(); } } /// /// /// /// Array is not copied! /// public AlgebraicVector FromArray(T[] elems) { var v = new AlgebraicVector(); v.elems = elems; return v; } public void CopyTo(T[] dest) { if (dest.Length != elems.Length) throw new InvalidOperationException("arr lengths do not match in Vector.Copy"); Array.Copy(elems, dest, dest.Length); } public AlgebraicVector Clone() { return new AlgebraicVector(elems); } [DebuggerBrowsable(DebuggerBrowsableState.Never)] public AlgebraicVector Zero => new AlgebraicVector(Length); [DebuggerBrowsable(DebuggerBrowsableState.Never)] public AlgebraicVector One { get { var v = new AlgebraicVector(Length); for (int i = 0; i < elems.Length; ++i) elems[i] = new T().One; return v; } } public AlgebraicVector Assign(AlgebraicVector a) { for (int i = 0; i < elems.Length; ++i) { elems[i].Assign(a.elems[i]); } return this; } public AlgebraicVector Add(AlgebraicVector a) { for (int i = 0; i < elems.Length; ++i) { elems[i].Add(a.elems[i]); } return this; } public AlgebraicVector Sub(AlgebraicVector a) { for (int i = 0; i < elems.Length; ++i) { elems[i].Sub(a.elems[i]); } return this; } public AlgebraicVector Mul(AlgebraicVector a) { for (int i = 0; i < elems.Length; ++i) { elems[i].Mul(a.elems[i]); } return this; } public AlgebraicVector Div(AlgebraicVector a) { for (int i = 0; i < elems.Length; ++i) { elems[i].Div(a.elems[i]); } return this; } public AlgebraicVector AssignNeg(AlgebraicVector a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignNeg(a.elems[i]); } return this; } public AlgebraicVector Scale(double s) { for (int i = 0; i < elems.Length; ++i) { elems[i].Scale(s); } return this; } public AlgebraicVector Scale(T s) { for (int i = 0; i < elems.Length; ++i) { elems[i].Mul(s); } return this; } public AlgebraicVector AssignInv(AlgebraicVector a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignInv(a.elems[i]); } return this; } public AlgebraicVector AssignLog(AlgebraicVector a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignLog(a.elems[i]); } return this; } public AlgebraicVector AssignExp(AlgebraicVector a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignExp(a.elems[i]); } return this; } public AlgebraicVector AssignSin(AlgebraicVector a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignSin(a.elems[i]); } return this; } public AlgebraicVector AssignCos(AlgebraicVector a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignCos(a.elems[i]); } return this; } public AlgebraicVector AssignIntPower(AlgebraicVector a, int p) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignIntPower(a.elems[i], p); } return this; } public AlgebraicVector AssignIntRoot(AlgebraicVector a, int r) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignIntRoot(a.elems[i], r); } return this; } public AlgebraicVector AssignAbs(AlgebraicVector a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignAbs(a.elems[i]); } return this; } public AlgebraicVector AssignSgn(AlgebraicVector a) { for (int i = 0; i < elems.Length; ++i) { elems[i].AssignSgn(a.elems[i]); } return this; } } */ /// /// A sparse vector of algebraic types. Elements are accessed via a key of type K /// /// Key type /// Element type [DebuggerDisplay("SparseVector: {ToString()}")] public sealed class AlgebraicSparseVector : IAlgebraicType> where T : IAlgebraicType { [DebuggerBrowsable(DebuggerBrowsableState.Never)] private Dictionary elems; public IReadOnlyDictionary Elements => elems; public AlgebraicSparseVector(AlgebraicSparseVector original) { elems = original.elems.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Clone()); } /// /// /// /// /// values are cloned public AlgebraicSparseVector(K[] keys, T[] values) { if (keys.Length != values.Length) throw new ArgumentException("lengths of keys and values doesn't match in SparseVector"); elems = new Dictionary(keys.Length); for (int i = 0; i < keys.Length; ++i) { elems.Add(keys[i], values[i].Clone()); } } public AlgebraicSparseVector() { this.elems = new Dictionary(); } // keep only elements from a private void AssignFromSource(AlgebraicSparseVector a, Func mapAssign) { // remove elems from this which don't occur in a List keysToRemove = new List(); foreach (var kvp in elems) { if (!a.elems.ContainsKey(kvp.Key)) keysToRemove.Add(kvp.Key); } foreach (var o in keysToRemove) elems.Remove(o); // -> zero foreach (var kvp in a.elems) { if (elems.TryGetValue(kvp.Key, out T value)) mapAssign(kvp.Value, value); else elems.Add(kvp.Key, mapAssign(kvp.Value, kvp.Value.Zero)); } } [DebuggerBrowsable(DebuggerBrowsableState.Never)] public AlgebraicSparseVector Zero => new AlgebraicSparseVector(); [DebuggerBrowsable(DebuggerBrowsableState.Never)] public AlgebraicSparseVector One => throw new NotSupportedException(); public AlgebraicSparseVector Scale(T s) { foreach (var kvp in elems) { kvp.Value.Mul(s); } return this; } public AlgebraicSparseVector Scale(double s) { foreach (var kvp in elems) { kvp.Value.Scale(s); } return this; } public AlgebraicSparseVector Assign(AlgebraicSparseVector a) { elems.Clear(); AssignFromSource(a, (src, dest) => dest.Assign(src)); return this; } public AlgebraicSparseVector AssignInv(AlgebraicSparseVector a) { AssignFromSource(a, (src, dest) => dest.AssignInv(src)); return this; } public AlgebraicSparseVector AssignNeg(AlgebraicSparseVector a) { AssignFromSource(a, (src, dest) => dest.AssignNeg(src)); return this; } public AlgebraicSparseVector AssignLog(AlgebraicSparseVector a) { AssignFromSource(a, (src, dest) => dest.AssignLog(src)); return this; } public AlgebraicSparseVector AssignExp(AlgebraicSparseVector a) { AssignFromSource(a, (src, dest) => dest.AssignExp(src)); return this; } public AlgebraicSparseVector AssignIntPower(AlgebraicSparseVector a, int p) { AssignFromSource(a, (src, dest) => dest.AssignIntPower(src, p)); return this; } public AlgebraicSparseVector AssignIntRoot(AlgebraicSparseVector a, int r) { AssignFromSource(a, (src, dest) => dest.AssignIntRoot(src, r)); return this; } public AlgebraicSparseVector AssignSin(AlgebraicSparseVector a) { AssignFromSource(a, (src, dest) => dest.AssignSin(src)); return this; } public AlgebraicSparseVector AssignCos(AlgebraicSparseVector a) { AssignFromSource(a, (src, dest) => dest.AssignCos(src)); return this; } public AlgebraicSparseVector AssignTanh(AlgebraicSparseVector a) { AssignFromSource(a, (src, dest) => dest.AssignTanh(src)); return this; } public AlgebraicSparseVector AssignAbs(AlgebraicSparseVector a) { AssignFromSource(a, (src, dest) => dest.AssignAbs(src)); return this; } public AlgebraicSparseVector AssignSgn(AlgebraicSparseVector a) { AssignFromSource(a, (src, dest) => dest.AssignSgn(src)); return this; } public AlgebraicSparseVector Add(AlgebraicSparseVector a) { foreach (var kvp in a.elems) { if (elems.TryGetValue(kvp.Key, out T value)) value.Add(kvp.Value); else elems.Add(kvp.Key, kvp.Value.Clone()); // 0 + a } return this; } public AlgebraicSparseVector Sub(AlgebraicSparseVector a) { foreach (var kvp in a.elems) { if (elems.TryGetValue(kvp.Key, out T value)) value.Sub(kvp.Value); else elems.Add(kvp.Key, kvp.Value.Zero.Sub(kvp.Value)); // 0 - a } return this; } public AlgebraicSparseVector Mul(AlgebraicSparseVector a) { var keys = elems.Keys.ToArray(); foreach (var k in keys) if (!a.elems.ContainsKey(k)) elems.Remove(k); // 0 * a => 0 foreach (var kvp in a.elems) { if (elems.TryGetValue(kvp.Key, out T value)) value.Mul(kvp.Value); // this * a } return this; } public AlgebraicSparseVector Div(AlgebraicSparseVector a) { return Mul(a.Clone().Inv()); } public AlgebraicSparseVector AssignMin(AlgebraicSparseVector other) { // assumes that keys without a matching key in other are zero and vice versa foreach (var kvp in elems) if (!other.elems.ContainsKey(kvp.Key)) kvp.Value.AssignMin(kvp.Value.Zero); // min(v, 0) foreach (var kvp in other.elems) { if (elems.TryGetValue(kvp.Key, out T value)) value.AssignMin(kvp.Value); else elems.Add(kvp.Key, kvp.Value.Zero.AssignMin(kvp.Value)); } return this; } public AlgebraicSparseVector AssignMax(AlgebraicSparseVector other) { // assumes that keys without a matching key in other are zero and vice versa foreach (var kvp in elems) if (!other.elems.ContainsKey(kvp.Key)) kvp.Value.AssignMax(kvp.Value.Zero); // max(v, 0) foreach (var kvp in other.elems) { if (elems.TryGetValue(kvp.Key, out T value)) value.AssignMax(kvp.Value); else elems.Add(kvp.Key, kvp.Value.Zero.AssignMax(kvp.Value)); } return this; } public AlgebraicSparseVector Clone() { return new AlgebraicSparseVector(this); } public override string ToString() { return "[" + string.Join(" ", elems.Select(kvp => kvp.Key + ": " + kvp.Value)) + "]"; } } }