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);
}
}
}