/// <summary> /// Fast swap /// </summary> /// <param name="v1"></param> /// <param name="v2"></param> public static void Swap(ref WBVec v1, ref WBVec v2) { var vtemp = v1.v; v1.v = v2.v; v2.v = vtemp; }
/// <summary> /// Returns a vector each of whose elements is the maximal from the corresponding /// ones of argument vectors. Note that dimensions of the arguments must match. /// </summary> /// <param name="v1">First vector</param> /// <param name="v2">Second vector</param> /// <returns>vector v3 such that for each i = 0...dim(v1) v3[i] = max( v1[i], v2[i] )</returns> public static WBVec Max(WBVec v1, WBVec v2) { double[] av1 = v1.v; double[] av2 = v2.v; if (av1 == null) { throw new ArgumentNullException("v1"); } if (av2 == null) { throw new ArgumentNullException("v2"); } if (av1.Length != av2.Length) { throw new ArgumentException("Vector lengths do not match"); } WBVec y = WBVec.Zeros(av1.Length); for (int i = 0; i < av1.Length; i++) { y[i] = Math.Max(av1[i], av2[i]); } return(y); }
/// <summary>Constructs vector of specified length filled with zeros</summary> /// <param name="n">Length of vector</param> /// <returns>Constructed vector</returns> public static WBVec Zeros(int n) { WBVec v = new WBVec() { v = new double[n] }; return(v); }
/// <summary> /// Получить/назначть часть вектора, начиная с [fromInd-элекента и до toIndex-элемента] включительно /// </summary> /// <param name="fromInd">ОТ (начиная с StartIndex) индекс</param> /// <param name="toIndex">ДО ()</param> /// <returns></returns> public WBVec this[int fromInd, int toIndex] { get { int length = toIndex - fromInd + 1; var res = WBVec.Zeros(length); Array.Copy(this.v, fromInd - StartIndex, res.v, 0, length); return(res); } set { Array.Copy(value.v, 0, this.v, fromInd - StartIndex, toIndex - fromInd + 1); } }
/// <summary>Performs scalar multiplication of two vectors</summary> /// <param name="a">First vector</param> /// <param name="b">Second vector</param> /// <returns>Result of scalar multiplication</returns> public static WBVec operator *(WBVec a, WBVec b) { if (a.Length != b.Length) { throw new InvalidOperationException("Cannot multy vectors of different length"); } double[] res = WBVec.Zeros(a.Length); for (int i = 0; i < a.Length; i++) { res[i] = a[i] * b[i]; } return(res); }
/// <summary> /// Returns a vector whose elements are the absolute values of the given vector elements /// </summary> /// <param name="v">Vector to operate with</param> /// <returns>Vector v1 such that for each i = 0...dim(v) v1[i] = |v[i]|</returns> public WBVec Abs() { if (v == null) { return(new WBVec()); } int n = v.Length; WBVec y = WBVec.Zeros(n); for (int i = 0; i < n; i++) { y[i] = Math.Abs(v[i]); } return(y); }
/// <summary>Adds vector <paramref name="v1"/> multiplied by <paramref name="factor"/> to this object.</summary> /// <param name="v1">Vector to add</param> /// <param name="factor">Multiplication factor</param> public void MulAdd(WBVec v1, double factor) { double[] av1 = v1.v; if (av1 == null) { throw new ArgumentNullException("v1"); } if (this.Length != av1.Length) { throw new InvalidOperationException("Cannot add vectors of different length"); } for (int i = 0; i < v.Length; i++) { v[i] = v[i] + factor * av1[i]; } }
/// <summary>Copies content of one vector to another. Vectors must have same length.</summary> /// <param name="src">Source vector</param> /// <param name="dst">Vector to copy results</param> public static void Copy(WBVec src, WBVec dst) { if (src.v == null) { throw new ArgumentNullException("src"); } if (dst.v == null) { throw new ArgumentNullException("dst"); } int n = src.v.Length; if (dst.v.Length != n) { dst.v = new double[n]; } Array.Copy(src.v, dst.v, n); }
/// <summary>Performs element-wise division of two vectors</summary> /// <param name="a">Numerator vector</param> /// <param name="b">Denominator vector</param> /// <returns>Result of scalar multiplication</returns> public static WBVec operator /(WBVec a, WBVec b) { if (a.Length != b.Length) { throw new InvalidOperationException("Cannot element-wise divide vectors of different length"); } double[] res = WBVec.Zeros(a.Length); for (int i = 0; i < a.Length; i++) { if (b[i] == 0.0d) { throw new DivideByZeroException("Cannot divide by zero"); } res[i] = a[i] / b[i]; } return(res); }
/// <summary>Returns Euclidean norm of difference between two vectors. /// </summary> /// <param name="v1">First vector</param> /// <param name="v2">Second vector</param> /// <returns>Euclidean norm of vector's difference</returns> public static double GetEuclideanNorm(WBVec v1, WBVec v2) { double[] av1 = v1.v; double[] av2 = v2.v; if (av1 == null) { throw new ArgumentNullException("v1"); } if (av2 == null) { throw new ArgumentNullException("v2"); } if (av1.Length != av2.Length) { throw new ArgumentException("Vector lenghtes do not match"); } double norm = 0; for (int i = 0; i < av1.Length; i++) { norm += (av1[i] - av2[i]) * (av1[i] - av2[i]); } return(Math.Sqrt(norm)); }
/// <summary>Returns L-infinity norm of difference between two vectors. /// </summary> /// <param name="v1">First vector</param> /// <param name="v2">Second vector</param> /// <returns>L-infinity norm of vector's difference</returns> public static double GetLInfinityNorm(WBVec v1, WBVec v2) { double[] av1 = v1.v; double[] av2 = v2.v; if (av1 == null) { throw new ArgumentNullException("v1"); } if (av2 == null) { throw new ArgumentNullException("v2"); } if (av1.Length != av2.Length) { throw new ArgumentException("Vector lenghtes do not match"); } double norm = 0; for (int i = 0; i < av1.Length; i++) { norm = Math.Max(norm, Math.Abs(av1[i] - av2[i])); } return(norm); }
/// <summary>Performs linear intepolation between two vectors at specified point</summary> /// <param name="t">Point of intepolation</param> /// <param name="t0">First time point</param> /// <param name="v0">Vector at first time point</param> /// <param name="t1">Second time point</param> /// <param name="v1">Vector at second time point</param> /// <returns>Intepolated vector value at point <paramref name="t"/></returns> public static WBVec Lerp(double t, double t0, WBVec v0, double t1, WBVec v1) { return((v0 * (t1 - t) + v1 * (t - t0)) / (t1 - t0)); }