using System; using System.Diagnostics; using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; namespace HeuristicLab.Problems.DynamicalSystemsModelling { public class Vector { public readonly static Vector Zero = new Vector(new double[0]); public static Vector operator +(Vector a, Vector b) { if (a == Zero) return b; if (b == Zero) return a; Trace.Assert(a.arr.Length == b.arr.Length); var res = new double[a.arr.Length]; for (int i = 0; i < res.Length; i++) res[i] = a.arr[i] + b.arr[i]; return new Vector(res); } public Vector Add(Vector b) { var a = this; if (b == Zero) return a; if (a == Zero) { var vArr = new double[b.Length]; b.CopyTo(vArr); return new Vector(vArr); } else { Trace.Assert(a.arr.Length == b.arr.Length); for (int i = 0; i < a.arr.Length; i++) a.arr[i] += b.arr[i]; return a; } } public Vector Subtract(Vector b) { var a = this; if (b == Zero) return a; if (a == Zero) { var vArr = new double[b.Length]; a = new Vector(vArr); } Trace.Assert(a.arr.Length == b.arr.Length); for (int i = 0; i < a.arr.Length; i++) a.arr[i] -= b.arr[i]; return a; } // public static Vector operator -(Vector a, Vector b) { // return Subtract(a, b); // } // public static Vector operator -(Vector v) { // return v.Scale(-1.0); // } //public static Vector operator *(double s, Vector v) { // return v.Scale(s); //} public Vector Scale(double s) { if (this == Zero) return Zero; for (int i = 0; i < arr.Length; i++) { arr[i] *= s; } return this; } // public static Vector operator *(Vector v, double s) { // return s * v; // } public static Vector operator *(Vector u, Vector v) { if (v == Zero) return Zero; if (u == Zero) return Zero; var res = new double[v.arr.Length]; for (int i = 0; i < res.Length; i++) res[i] = u.arr[i] * v.arr[i]; return new Vector(res); } public static Vector operator /(double s, Vector v) { if (s == 0.0) return Zero; if (v == Zero) throw new ArgumentException("Division by zero vector"); var res = new double[v.arr.Length]; for (int i = 0; i < res.Length; i++) res[i] = s / v.arr[i]; return new Vector(res); } // public static Vector operator /(Vector v, double s) { // return v.Scale(1.0 / s); // } public Vector Sin() { for (int i = 0; i < arr.Length; i++) arr[i] = Math.Sin(arr[i]); return this; } public Vector Cos() { for (int i = 0; i < arr.Length; i++) arr[i] = Math.Cos(arr[i]); return this; } public double this[int idx] { get { if (this == Vector.Zero) return 0.0; else return arr[idx]; } set { if (this == Vector.Zero) throw new InvalidOperationException(); else arr[idx] = value; } } public int Length { get { if (this == Vector.Zero) throw new InvalidOperationException(); else return arr.Length; } } private readonly double[] arr; // backing array; /// /// /// /// Is not cloned! public Vector(double[] v) { this.arr = v; } public void CopyTo(double[] target) { Trace.Assert(arr.Length <= target.Length); Array.Copy(arr, target, arr.Length); } public void CopyTo(double[,] target, int rowIdx) { if (target == null) return; if (this == Zero) { for (int j = 0; j < target.GetLength(1); j++) target[rowIdx, j] = 0.0; } else { for (int j = 0; j < target.GetLength(1); j++) target[rowIdx, j] = arr[j]; } } /// /// Creates a new vector /// /// is cloned /// public static Vector CreateNew(double[] a) { var arr = new double[a.Length]; Array.Copy(a, arr, arr.Length); return new Vector(arr); } /// /// Creates a new vector /// /// is cloned /// public static Vector CreateNew(Vector v) { if (v == Zero) return Zero; var arr = new double[v.arr.Length]; Array.Copy(v.arr, arr, arr.Length); return new Vector(arr); } internal static Vector CreateIndicator(int length, int idx) { var gArr = new double[length]; // backing array gArr[idx] = 1.0; return new Vector(gArr); } internal static Vector CreateFromMatrixRow(double[,] jac, int rowIdx) { var arr = new double[jac.GetLength(1)]; for (int i = 0; i < arr.Length; i++) arr[i] = jac[rowIdx, i]; return new Vector(arr); } } }