using System; using System.Diagnostics; 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 static Vector AddTo(Vector a, Vector b) { 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 static Vector Subtract(Vector a, Vector b) { 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) { if (b == Zero) return a; if (a == Zero) return -b; 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 static Vector operator -(Vector v) { if (v == Zero) return Zero; for (int i = 0; i < v.arr.Length; i++) v.arr[i] = -v.arr[i]; return v; } public static Vector operator *(double s, Vector v) { if (v == Zero) return Zero; if (s == 0.0) return Zero; 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 Vector Scale(double s) { if (this != 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] = 1.0 / v.arr[i]; return new Vector(res); } public static Vector operator /(Vector v, double s) { return v * 1.0 / s; } public static Vector Sin(Vector s) { var res = new double[s.arr.Length]; for (int i = 0; i < res.Length; i++) res[i] = Math.Sin(s.arr[i]); return new Vector(res); } public static Vector Cos(Vector s) { var res = new double[s.arr.Length]; for (int i = 0; i < res.Length; i++) res[i] = Math.Cos(s.arr[i]); return new Vector(res); } 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); } /// /// 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); } } }