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