// // Math.NET Numerics, part of the Math.NET Project // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // // Copyright (c) 2009-2016 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, // copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // using System; namespace IStation.Numerics.LinearAlgebra { public abstract partial class Vector { /// /// The zero value for type T. /// public static readonly T Zero = BuilderInstance.Vector.Zero; /// /// The value of 1.0 for type T. /// public static readonly T One = BuilderInstance.Vector.One; /// /// Negates vector and save result to /// /// Target vector protected abstract void DoNegate(Vector result); /// /// Complex conjugates vector and save result to /// /// Target vector protected abstract void DoConjugate(Vector result); /// /// Adds a scalar to each element of the vector and stores the result in the result vector. /// /// The scalar to add. /// The vector to store the result of the addition. protected abstract void DoAdd(T scalar, Vector result); /// /// Adds another vector to this vector and stores the result into the result vector. /// /// The vector to add to this one. /// The vector to store the result of the addition. protected abstract void DoAdd(Vector other, Vector result); /// /// Subtracts a scalar from each element of the vector and stores the result in the result vector. /// /// The scalar to subtract. /// The vector to store the result of the subtraction. protected abstract void DoSubtract(T scalar, Vector result); /// /// Subtracts each element of the vector from a scalar and stores the result in the result vector. /// /// The scalar to subtract from. /// The vector to store the result of the subtraction. protected void DoSubtractFrom(T scalar, Vector result) { DoNegate(result); result.DoAdd(scalar, result); } /// /// Subtracts another vector to this vector and stores the result into the result vector. /// /// The vector to subtract from this one. /// The vector to store the result of the subtraction. protected abstract void DoSubtract(Vector other, Vector result); /// /// Multiplies a scalar to each element of the vector and stores the result in the result vector. /// /// The scalar to multiply. /// The vector to store the result of the multiplication. protected abstract void DoMultiply(T scalar, Vector result); /// /// Computes the dot product between this vector and another vector. /// /// The other vector. /// The sum of a[i]*b[i] for all i. protected abstract T DoDotProduct(Vector other); /// /// Computes the dot product between the conjugate of this vector and another vector. /// /// The other vector. /// The sum of conj(a[i])*b[i] for all i. protected abstract T DoConjugateDotProduct(Vector other); /// /// Computes the outer product M[i,j] = u[i]*v[j] of this and another vector and stores the result in the result matrix. /// /// The other vector /// The matrix to store the result of the product. protected void DoOuterProduct(Vector other, Matrix result) { var work = Build.Dense(Count); for (var i = 0; i < other.Count; i++) { DoMultiply(other.At(i), work); result.SetColumn(i, work); } } /// /// Divides each element of the vector by a scalar and stores the result in the result vector. /// /// The scalar denominator to use. /// The vector to store the result of the division. protected abstract void DoDivide(T divisor, Vector result); /// /// Divides a scalar by each element of the vector and stores the result in the result vector. /// /// The scalar numerator to use. /// The vector to store the result of the division. protected abstract void DoDivideByThis(T dividend, Vector result); /// /// Computes the canonical modulus, where the result has the sign of the divisor, /// for each element of the vector for the given divisor. /// /// The scalar denominator to use. /// A vector to store the results in. protected abstract void DoModulus(T divisor, Vector result); /// /// Computes the canonical modulus, where the result has the sign of the divisor, /// for the given dividend for each element of the vector. /// /// The scalar numerator to use. /// A vector to store the results in. protected abstract void DoModulusByThis(T dividend, Vector result); /// /// Computes the remainder (% operator), where the result has the sign of the dividend, /// for each element of the vector for the given divisor. /// /// The scalar denominator to use. /// A vector to store the results in. protected abstract void DoRemainder(T divisor, Vector result); /// /// Computes the remainder (% operator), where the result has the sign of the dividend, /// for the given dividend for each element of the vector. /// /// The scalar numerator to use. /// A vector to store the results in. protected abstract void DoRemainderByThis(T dividend, Vector result); /// /// Pointwise multiplies this vector with another vector and stores the result into the result vector. /// /// The vector to pointwise multiply with this one. /// The vector to store the result of the pointwise multiplication. protected abstract void DoPointwiseMultiply(Vector other, Vector result); /// /// Pointwise divide this vector with another vector and stores the result into the result vector. /// /// The pointwise denominator vector to use. /// The result of the division. protected abstract void DoPointwiseDivide(Vector divisor, Vector result); /// /// Pointwise raise this vector to an exponent and store the result into the result vector. /// /// The exponent to raise this vector values to. /// The vector to store the result of the pointwise power. protected abstract void DoPointwisePower(T exponent, Vector result); /// /// Pointwise raise this vector to an exponent vector and store the result into the result vector. /// /// The exponent vector to raise this vector values to. /// The vector to store the result of the pointwise power. protected abstract void DoPointwisePower(Vector exponent, Vector result); /// /// Pointwise canonical modulus, where the result has the sign of the divisor, /// of this vector with another vector and stores the result into the result vector. /// /// The pointwise denominator vector to use. /// The result of the modulus. protected abstract void DoPointwiseModulus(Vector divisor, Vector result); /// /// Pointwise remainder (% operator), where the result has the sign of the dividend, /// of this vector with another vector and stores the result into the result vector. /// /// The pointwise denominator vector to use. /// The result of the modulus. protected abstract void DoPointwiseRemainder(Vector divisor, Vector result); /// /// Pointwise applies the exponential function to each value and stores the result into the result vector. /// /// The vector to store the result. protected abstract void DoPointwiseExp(Vector result); /// /// Pointwise applies the natural logarithm function to each value and stores the result into the result vector. /// /// The vector to store the result. protected abstract void DoPointwiseLog(Vector result); protected abstract void DoPointwiseAbs(Vector result); protected abstract void DoPointwiseAcos(Vector result); protected abstract void DoPointwiseAsin(Vector result); protected abstract void DoPointwiseAtan(Vector result); protected abstract void DoPointwiseCeiling(Vector result); protected abstract void DoPointwiseCos(Vector result); protected abstract void DoPointwiseCosh(Vector result); protected abstract void DoPointwiseFloor(Vector result); protected abstract void DoPointwiseLog10(Vector result); protected abstract void DoPointwiseRound(Vector result); protected abstract void DoPointwiseSign(Vector result); protected abstract void DoPointwiseSin(Vector result); protected abstract void DoPointwiseSinh(Vector result); protected abstract void DoPointwiseSqrt(Vector result); protected abstract void DoPointwiseTan(Vector result); protected abstract void DoPointwiseTanh(Vector result); protected abstract void DoPointwiseAtan2(Vector other, Vector result); protected abstract void DoPointwiseAtan2(T scalar, Vector result); protected abstract void DoPointwiseMinimum(T scalar, Vector result); protected abstract void DoPointwiseMinimum(Vector other, Vector result); protected abstract void DoPointwiseMaximum(T scalar, Vector result); protected abstract void DoPointwiseMaximum(Vector other, Vector result); protected abstract void DoPointwiseAbsoluteMinimum(T scalar, Vector result); protected abstract void DoPointwiseAbsoluteMinimum(Vector other, Vector result); protected abstract void DoPointwiseAbsoluteMaximum(T scalar, Vector result); protected abstract void DoPointwiseAbsoluteMaximum(Vector other, Vector result); /// /// Adds a scalar to each element of the vector. /// /// The scalar to add. /// A copy of the vector with the scalar added. public Vector Add(T scalar) { if (scalar.Equals(Zero)) { return Clone(); } var result = Build.SameAs(this); DoAdd(scalar, result); return result; } /// /// Adds a scalar to each element of the vector and stores the result in the result vector. /// /// The scalar to add. /// The vector to store the result of the addition. /// If this vector and are not the same size. public void Add(T scalar, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } if (scalar.Equals(Zero)) { CopyTo(result); return; } DoAdd(scalar, result); } /// /// Adds another vector to this vector. /// /// The vector to add to this one. /// A new vector containing the sum of both vectors. /// If this vector and are not the same size. public Vector Add(Vector other) { if (Count != other.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(other)); } var result = Build.SameAs(this, other); DoAdd(other, result); return result; } /// /// Adds another vector to this vector and stores the result into the result vector. /// /// The vector to add to this one. /// The vector to store the result of the addition. /// If this vector and are not the same size. /// If this vector and are not the same size. public void Add(Vector other, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoAdd(other, result); } /// /// Subtracts a scalar from each element of the vector. /// /// The scalar to subtract. /// A new vector containing the subtraction of this vector and the scalar. public Vector Subtract(T scalar) { if (scalar.Equals(Zero)) { return Clone(); } var result = Build.SameAs(this); DoSubtract(scalar, result); return result; } /// /// Subtracts a scalar from each element of the vector and stores the result in the result vector. /// /// The scalar to subtract. /// The vector to store the result of the subtraction. /// If this vector and are not the same size. public void Subtract(T scalar, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } if (scalar.Equals(Zero)) { CopyTo(result); return; } DoSubtract(scalar, result); } /// /// Subtracts each element of the vector from a scalar. /// /// The scalar to subtract from. /// A new vector containing the subtraction of the scalar and this vector. public Vector SubtractFrom(T scalar) { var result = Build.SameAs(this); DoSubtractFrom(scalar, result); return result; } /// /// Subtracts each element of the vector from a scalar and stores the result in the result vector. /// /// The scalar to subtract from. /// The vector to store the result of the subtraction. /// If this vector and are not the same size. public void SubtractFrom(T scalar, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoSubtractFrom(scalar, result); } /// /// Returns a negated vector. /// /// The negated vector. /// Added as an alternative to the unary negation operator. public Vector Negate() { var retrunVector = Build.SameAs(this); DoNegate(retrunVector); return retrunVector; } /// /// Negates vector and save result to /// /// Target vector public void Negate(Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoNegate(result); } /// /// Subtracts another vector from this vector. /// /// The vector to subtract from this one. /// A new vector containing the subtraction of the two vectors. /// If this vector and are not the same size. public Vector Subtract(Vector other) { if (Count != other.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(other)); } var result = Build.SameAs(this, other); DoSubtract(other, result); return result; } /// /// Subtracts another vector to this vector and stores the result into the result vector. /// /// The vector to subtract from this one. /// The vector to store the result of the subtraction. /// If this vector and are not the same size. /// If this vector and are not the same size. public void Subtract(Vector other, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoSubtract(other, result); } /// /// Return vector with complex conjugate values of the source vector /// /// Conjugated vector public Vector Conjugate() { var retrunVector = Build.SameAs(this); DoConjugate(retrunVector); return retrunVector; } /// /// Complex conjugates vector and save result to /// /// Target vector public void Conjugate(Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoConjugate(result); } /// /// Multiplies a scalar to each element of the vector. /// /// The scalar to multiply. /// A new vector that is the multiplication of the vector and the scalar. public Vector Multiply(T scalar) { if (scalar.Equals(One)) { return Clone(); } if (scalar.Equals(Zero)) { return Build.SameAs(this); } var result = Build.SameAs(this); DoMultiply(scalar, result); return result; } /// /// Multiplies a scalar to each element of the vector and stores the result in the result vector. /// /// The scalar to multiply. /// The vector to store the result of the multiplication. /// If this vector and are not the same size. public void Multiply(T scalar, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } if (scalar.Equals(One)) { CopyTo(result); return; } if (scalar.Equals(Zero)) { result.Clear(); return; } DoMultiply(scalar, result); } /// /// Computes the dot product between this vector and another vector. /// /// The other vector. /// The sum of a[i]*b[i] for all i. /// If is not of the same size. /// public T DotProduct(Vector other) { if (Count != other.Count) throw new ArgumentException("All vectors must have the same dimensionality.", nameof(other)); return DoDotProduct(other); } /// /// Computes the dot product between the conjugate of this vector and another vector. /// /// The other vector. /// The sum of conj(a[i])*b[i] for all i. /// If is not of the same size. /// If is . /// public T ConjugateDotProduct(Vector other) { if (Count != other.Count) throw new ArgumentException("All vectors must have the same dimensionality.", nameof(other)); return DoConjugateDotProduct(other); } /// /// Divides each element of the vector by a scalar. /// /// The scalar to divide with. /// A new vector that is the division of the vector and the scalar. public Vector Divide(T scalar) { if (scalar.Equals(One)) { return Clone(); } var result = Build.SameAs(this); DoDivide(scalar, result); return result; } /// /// Divides each element of the vector by a scalar and stores the result in the result vector. /// /// The scalar to divide with. /// The vector to store the result of the division. /// If this vector and are not the same size. public void Divide(T scalar, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } if (scalar.Equals(One)) { CopyTo(result); return; } DoDivide(scalar, result); } /// /// Divides a scalar by each element of the vector. /// /// The scalar to divide. /// A new vector that is the division of the vector and the scalar. public Vector DivideByThis(T scalar) { var result = Build.SameAs(this); DoDivideByThis(scalar, result); return result; } /// /// Divides a scalar by each element of the vector and stores the result in the result vector. /// /// The scalar to divide. /// The vector to store the result of the division. /// If this vector and are not the same size. public void DivideByThis(T scalar, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoDivideByThis(scalar, result); } /// /// Computes the canonical modulus, where the result has the sign of the divisor, /// for each element of the vector for the given divisor. /// /// The scalar denominator to use. /// A vector containing the result. public Vector Modulus(T divisor) { var result = Build.SameAs(this); DoModulus(divisor, result); return result; } /// /// Computes the canonical modulus, where the result has the sign of the divisor, /// for each element of the vector for the given divisor. /// /// The scalar denominator to use. /// A vector to store the results in. public void Modulus(T divisor, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoModulus(divisor, result); } /// /// Computes the canonical modulus, where the result has the sign of the divisor, /// for the given dividend for each element of the vector. /// /// The scalar numerator to use. /// A vector containing the result. public Vector ModulusByThis(T dividend) { var result = Build.SameAs(this); DoModulusByThis(dividend, result); return result; } /// /// Computes the canonical modulus, where the result has the sign of the divisor, /// for the given dividend for each element of the vector. /// /// The scalar numerator to use. /// A vector to store the results in. public void ModulusByThis(T dividend, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoModulusByThis(dividend, result); } /// /// Computes the remainder (vector % divisor), where the result has the sign of the dividend, /// for each element of the vector for the given divisor. /// /// The scalar denominator to use. /// A vector containing the result. public Vector Remainder(T divisor) { var result = Build.SameAs(this); DoRemainder(divisor, result); return result; } /// /// Computes the remainder (vector % divisor), where the result has the sign of the dividend, /// for each element of the vector for the given divisor. /// /// The scalar denominator to use. /// A vector to store the results in. public void Remainder(T divisor, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoRemainder(divisor, result); } /// /// Computes the remainder (dividend % vector), where the result has the sign of the dividend, /// for the given dividend for each element of the vector. /// /// The scalar numerator to use. /// A vector containing the result. public Vector RemainderByThis(T dividend) { var result = Build.SameAs(this); DoRemainderByThis(dividend, result); return result; } /// /// Computes the remainder (dividend % vector), where the result has the sign of the dividend, /// for the given dividend for each element of the vector. /// /// The scalar numerator to use. /// A vector to store the results in. public void RemainderByThis(T dividend, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoRemainderByThis(dividend, result); } /// /// Pointwise multiplies this vector with another vector. /// /// The vector to pointwise multiply with this one. /// A new vector which is the pointwise multiplication of the two vectors. /// If this vector and are not the same size. public Vector PointwiseMultiply(Vector other) { if (Count != other.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(other)); } var result = Build.SameAs(this, other); DoPointwiseMultiply(other, result); return result; } /// /// Pointwise multiplies this vector with another vector and stores the result into the result vector. /// /// The vector to pointwise multiply with this one. /// The vector to store the result of the pointwise multiplication. /// If this vector and are not the same size. /// If this vector and are not the same size. public void PointwiseMultiply(Vector other, Vector result) { if (Count != other.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(other)); } if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoPointwiseMultiply(other, result); } /// /// Pointwise divide this vector with another vector. /// /// The pointwise denominator vector to use. /// A new vector which is the pointwise division of the two vectors. /// If this vector and are not the same size. public Vector PointwiseDivide(Vector divisor) { if (Count != divisor.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(divisor)); } var result = Build.SameAs(this, divisor); DoPointwiseDivide(divisor, result); return result; } /// /// Pointwise divide this vector with another vector and stores the result into the result vector. /// /// The pointwise denominator vector to use. /// The vector to store the result of the pointwise division. /// If this vector and are not the same size. /// If this vector and are not the same size. public void PointwiseDivide(Vector divisor, Vector result) { if (Count != divisor.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(divisor)); } if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoPointwiseDivide(divisor, result); } /// /// Pointwise raise this vector to an exponent. /// /// The exponent to raise this vector values to. public Vector PointwisePower(T exponent) { var result = Build.SameAs(this); DoPointwisePower(exponent, result); return result; } /// /// Pointwise raise this vector to an exponent and store the result into the result vector. /// /// The exponent to raise this vector values to. /// The matrix to store the result into. /// If this vector and are not the same size. public void PointwisePower(T exponent, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoPointwisePower(exponent, result); } /// /// Pointwise raise this vector to an exponent and store the result into the result vector. /// /// The exponent to raise this vector values to. public Vector PointwisePower(Vector exponent) { if (Count != exponent.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(exponent)); } var result = Build.SameAs(this); DoPointwisePower(exponent, result); return result; } /// /// Pointwise raise this vector to an exponent. /// /// The exponent to raise this vector values to. /// The vector to store the result into. /// If this vector and are not the same size. public void PointwisePower(Vector exponent, Vector result) { if (Count != exponent.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(exponent)); } if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoPointwisePower(exponent, result); } /// /// Pointwise canonical modulus, where the result has the sign of the divisor, /// of this vector with another vector. /// /// The pointwise denominator vector to use. /// If this vector and are not the same size. public Vector PointwiseModulus(Vector divisor) { if (Count != divisor.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(divisor)); } var result = Build.SameAs(this, divisor); DoPointwiseModulus(divisor, result); return result; } /// /// Pointwise canonical modulus, where the result has the sign of the divisor, /// of this vector with another vector and stores the result into the result vector. /// /// The pointwise denominator vector to use. /// The vector to store the result of the pointwise modulus. /// If this vector and are not the same size. /// If this vector and are not the same size. public void PointwiseModulus(Vector divisor, Vector result) { if (Count != divisor.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(divisor)); } if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoPointwiseModulus(divisor, result); } /// /// Pointwise remainder (% operator), where the result has the sign of the dividend, /// of this vector with another vector. /// /// The pointwise denominator vector to use. /// If this vector and are not the same size. public Vector PointwiseRemainder(Vector divisor) { if (Count != divisor.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(divisor)); } var result = Build.SameAs(this, divisor); DoPointwiseRemainder(divisor, result); return result; } /// /// Pointwise remainder (% operator), where the result has the sign of the dividend, /// this vector with another vector and stores the result into the result vector. /// /// The pointwise denominator vector to use. /// The vector to store the result of the pointwise remainder. /// If this vector and are not the same size. /// If this vector and are not the same size. public void PointwiseRemainder(Vector divisor, Vector result) { if (Count != divisor.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(divisor)); } if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoPointwiseRemainder(divisor, result); } /// /// Helper function to apply a unary function to a vector. The function /// f modifies the vector given to it in place. Before its /// called, a copy of the 'this' vector with the same dimension is /// first created, then passed to f. The copy is returned as the result /// /// Function which takes a vector, modifies it in place and returns void /// New instance of vector which is the result protected Vector PointwiseUnary(Action> f) { var result = Build.SameAs(this); f(result); return result; } /// /// Helper function to apply a unary function which modifies a vector /// in place. /// /// Function which takes a vector, modifies it in place and returns void /// The vector where the result is to be stored /// If this vector and are not the same size. protected void PointwiseUnary(Action> f, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } f(result); } /// /// Helper function to apply a binary function which takes a scalar and /// a vector and modifies the latter in place. A copy of the "this" /// vector is therefore first made and then passed to f together with /// the scalar argument. The copy is then returned as the result /// /// Function which takes a scalar and a vector, modifies the vector in place and returns void /// The scalar to be passed to the function /// The resulting vector protected Vector PointwiseBinary(Action> f, T other) { var result = Build.SameAs(this); f(other, result); return result; } /// /// Helper function to apply a binary function which takes a scalar and /// a vector, modifies the latter in place and returns void. /// /// Function which takes a scalar and a vector, modifies the vector in place and returns void /// The scalar to be passed to the function /// The vector where the result will be placed /// If this vector and are not the same size. protected void PointwiseBinary(Action> f, T x, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } f(x, result); } /// /// Helper function to apply a binary function which takes two vectors /// and modifies the latter in place. A copy of the "this" vector is /// first made and then passed to f together with the other vector. The /// copy is then returned as the result /// /// Function which takes two vectors, modifies the second in place and returns void /// The other vector to be passed to the function as argument. It is not modified /// The resulting vector /// If this vector and are not the same size. protected Vector PointwiseBinary(Action, Vector> f, Vector other) { if (Count != other.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(other)); } var result = Build.SameAs(this, other); f(other, result); return result; } /// /// Helper function to apply a binary function which takes two vectors /// and modifies the second one in place /// /// Function which takes two vectors, modifies the second in place and returns void /// The other vector to be passed to the function as argument. It is not modified /// The resulting vector /// If this vector and are not the same size. protected void PointwiseBinary(Action, Vector> f, Vector other, Vector result) { if (Count != other.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(other)); } if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } f(other, result); } /// /// Pointwise applies the exponent function to each value. /// public Vector PointwiseExp() { return PointwiseUnary(DoPointwiseExp); } /// /// Pointwise applies the exponent function to each value. /// /// The vector to store the result. /// If this vector and are not the same size. public void PointwiseExp(Vector result) { PointwiseUnary(DoPointwiseExp, result); } /// /// Pointwise applies the natural logarithm function to each value. /// public Vector PointwiseLog() { return PointwiseUnary(DoPointwiseLog); } /// /// Pointwise applies the natural logarithm function to each value. /// /// The vector to store the result. /// If this vector and are not the same size. public void PointwiseLog(Vector result) { PointwiseUnary(DoPointwiseLog, result); } /// /// Pointwise applies the abs function to each value /// public Vector PointwiseAbs() { return PointwiseUnary(DoPointwiseAbs); } /// /// Pointwise applies the abs function to each value /// /// The vector to store the result public void PointwiseAbs(Vector result) { PointwiseUnary(DoPointwiseAbs, result); } /// /// Pointwise applies the acos function to each value /// public Vector PointwiseAcos() { return PointwiseUnary(DoPointwiseAcos); } /// /// Pointwise applies the acos function to each value /// /// The vector to store the result public void PointwiseAcos(Vector result) { PointwiseUnary(DoPointwiseAcos, result); } /// /// Pointwise applies the asin function to each value /// public Vector PointwiseAsin() { return PointwiseUnary(DoPointwiseAsin); } /// /// Pointwise applies the asin function to each value /// /// The vector to store the result public void PointwiseAsin(Vector result) { PointwiseUnary(DoPointwiseAsin, result); } /// /// Pointwise applies the atan function to each value /// public Vector PointwiseAtan() { return PointwiseUnary(DoPointwiseAtan); } /// /// Pointwise applies the atan function to each value /// /// The vector to store the result public void PointwiseAtan(Vector result) { PointwiseUnary(DoPointwiseAtan, result); } /// /// Pointwise applies the atan2 function to each value of the current /// vector and a given other vector being the 'x' of atan2 and the /// 'this' vector being the 'y' /// /// public Vector PointwiseAtan2(Vector other) { return PointwiseBinary(DoPointwiseAtan2, other); } /// /// Pointwise applies the atan2 function to each value of the current /// vector and a given other vector being the 'x' of atan2 and the /// 'this' vector being the 'y' /// /// /// The vector to store the result public void PointwiseAtan2(Vector other, Vector result) { PointwiseBinary(DoPointwiseAtan2, other, result); } /// /// Pointwise applies the ceiling function to each value /// public Vector PointwiseCeiling() { return PointwiseUnary(DoPointwiseCeiling); } /// /// Pointwise applies the ceiling function to each value /// /// The vector to store the result public void PointwiseCeiling(Vector result) { PointwiseUnary(DoPointwiseCeiling, result); } /// /// Pointwise applies the cos function to each value /// public Vector PointwiseCos() { return PointwiseUnary(DoPointwiseCos); } /// /// Pointwise applies the cos function to each value /// /// The vector to store the result public void PointwiseCos(Vector result) { PointwiseUnary(DoPointwiseCos, result); } /// /// Pointwise applies the cosh function to each value /// public Vector PointwiseCosh() { return PointwiseUnary(DoPointwiseCosh); } /// /// Pointwise applies the cosh function to each value /// /// The vector to store the result public void PointwiseCosh(Vector result) { PointwiseUnary(DoPointwiseCosh, result); } /// /// Pointwise applies the floor function to each value /// public Vector PointwiseFloor() { return PointwiseUnary(DoPointwiseFloor); } /// /// Pointwise applies the floor function to each value /// /// The vector to store the result public void PointwiseFloor(Vector result) { PointwiseUnary(DoPointwiseFloor, result); } /// /// Pointwise applies the log10 function to each value /// public Vector PointwiseLog10() { return PointwiseUnary(DoPointwiseLog10); } /// /// Pointwise applies the log10 function to each value /// /// The vector to store the result public void PointwiseLog10(Vector result) { PointwiseUnary(DoPointwiseLog10, result); } /// /// Pointwise applies the round function to each value /// public Vector PointwiseRound() { return PointwiseUnary(DoPointwiseRound); } /// /// Pointwise applies the round function to each value /// /// The vector to store the result public void PointwiseRound(Vector result) { PointwiseUnary(DoPointwiseRound, result); } /// /// Pointwise applies the sign function to each value /// public Vector PointwiseSign() { return PointwiseUnary(DoPointwiseSign); } /// /// Pointwise applies the sign function to each value /// /// The vector to store the result public void PointwiseSign(Vector result) { PointwiseUnary(DoPointwiseSign, result); } /// /// Pointwise applies the sin function to each value /// public Vector PointwiseSin() { return PointwiseUnary(DoPointwiseSin); } /// /// Pointwise applies the sin function to each value /// /// The vector to store the result public void PointwiseSin(Vector result) { PointwiseUnary(DoPointwiseSin, result); } /// /// Pointwise applies the sinh function to each value /// public Vector PointwiseSinh() { return PointwiseUnary(DoPointwiseSinh); } /// /// Pointwise applies the sinh function to each value /// /// The vector to store the result public void PointwiseSinh(Vector result) { PointwiseUnary(DoPointwiseSinh, result); } /// /// Pointwise applies the sqrt function to each value /// public Vector PointwiseSqrt() { return PointwiseUnary(DoPointwiseSqrt); } /// /// Pointwise applies the sqrt function to each value /// /// The vector to store the result public void PointwiseSqrt(Vector result) { PointwiseUnary(DoPointwiseSqrt, result); } /// /// Pointwise applies the tan function to each value /// public Vector PointwiseTan() { return PointwiseUnary(DoPointwiseTan); } /// /// Pointwise applies the tan function to each value /// /// The vector to store the result public void PointwiseTan(Vector result) { PointwiseUnary(DoPointwiseTan, result); } /// /// Pointwise applies the tanh function to each value /// public Vector PointwiseTanh() { return PointwiseUnary(DoPointwiseTanh); } /// /// Pointwise applies the tanh function to each value /// /// The vector to store the result public void PointwiseTanh(Vector result) { PointwiseUnary(DoPointwiseTanh, result); } /// /// Computes the outer product M[i,j] = u[i]*v[j] of this and another vector. /// /// The other vector public Matrix OuterProduct(Vector other) { var matrix = Matrix.Build.SameAs(this, Count, other.Count); DoOuterProduct(other, matrix); return matrix; } /// /// Computes the outer product M[i,j] = u[i]*v[j] of this and another vector and stores the result in the result matrix. /// /// The other vector /// The matrix to store the result of the product. public void OuterProduct(Vector other, Matrix result) { if (Count != result.RowCount || other.Count != result.ColumnCount) { throw new ArgumentException("Matrix dimensions must agree.", nameof(result)); } DoOuterProduct(other, result); } public static Matrix OuterProduct(Vector u, Vector v) { return u.OuterProduct(v); } /// /// Pointwise applies the minimum with a scalar to each value. /// /// The scalar value to compare to. public Vector PointwiseMinimum(T scalar) { var result = Build.SameAs(this); DoPointwiseMinimum(scalar, result); return result; } /// /// Pointwise applies the minimum with a scalar to each value. /// /// The scalar value to compare to. /// The vector to store the result. /// If this vector and are not the same size. public void PointwiseMinimum(T scalar, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoPointwiseMinimum(scalar, result); } /// /// Pointwise applies the maximum with a scalar to each value. /// /// The scalar value to compare to. public Vector PointwiseMaximum(T scalar) { var result = Build.SameAs(this); DoPointwiseMaximum(scalar, result); return result; } /// /// Pointwise applies the maximum with a scalar to each value. /// /// The scalar value to compare to. /// The vector to store the result. /// If this vector and are not the same size. public void PointwiseMaximum(T scalar, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoPointwiseMaximum(scalar, result); } /// /// Pointwise applies the absolute minimum with a scalar to each value. /// /// The scalar value to compare to. public Vector PointwiseAbsoluteMinimum(T scalar) { var result = Build.SameAs(this); DoPointwiseAbsoluteMinimum(scalar, result); return result; } /// /// Pointwise applies the absolute minimum with a scalar to each value. /// /// The scalar value to compare to. /// The vector to store the result. /// If this vector and are not the same size. public void PointwiseAbsoluteMinimum(T scalar, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoPointwiseAbsoluteMinimum(scalar, result); } /// /// Pointwise applies the absolute maximum with a scalar to each value. /// /// The scalar value to compare to. public Vector PointwiseAbsoluteMaximum(T scalar) { var result = Build.SameAs(this); DoPointwiseAbsoluteMaximum(scalar, result); return result; } /// /// Pointwise applies the absolute maximum with a scalar to each value. /// /// The scalar value to compare to. /// The vector to store the result. /// If this vector and are not the same size. public void PointwiseAbsoluteMaximum(T scalar, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoPointwiseAbsoluteMaximum(scalar, result); } /// /// Pointwise applies the minimum with the values of another vector to each value. /// /// The vector with the values to compare to. public Vector PointwiseMinimum(Vector other) { var result = Build.SameAs(this); DoPointwiseMinimum(other, result); return result; } /// /// Pointwise applies the minimum with the values of another vector to each value. /// /// The vector with the values to compare to. /// The vector to store the result. /// If this vector and are not the same size. public void PointwiseMinimum(Vector other, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoPointwiseMinimum(other, result); } /// /// Pointwise applies the maximum with the values of another vector to each value. /// /// The vector with the values to compare to. public Vector PointwiseMaximum(Vector other) { var result = Build.SameAs(this); DoPointwiseMaximum(other, result); return result; } /// /// Pointwise applies the maximum with the values of another vector to each value. /// /// The vector with the values to compare to. /// The vector to store the result. /// If this vector and are not the same size. public void PointwiseMaximum(Vector other, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoPointwiseMaximum(other, result); } /// /// Pointwise applies the absolute minimum with the values of another vector to each value. /// /// The vector with the values to compare to. public Vector PointwiseAbsoluteMinimum(Vector other) { var result = Build.SameAs(this); DoPointwiseAbsoluteMinimum(other, result); return result; } /// /// Pointwise applies the absolute minimum with the values of another vector to each value. /// /// The vector with the values to compare to. /// The vector to store the result. /// If this vector and are not the same size. public void PointwiseAbsoluteMinimum(Vector other, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoPointwiseAbsoluteMinimum(other, result); } /// /// Pointwise applies the absolute maximum with the values of another vector to each value. /// /// The vector with the values to compare to. public Vector PointwiseAbsoluteMaximum(Vector other) { var result = Build.SameAs(this); DoPointwiseAbsoluteMaximum(other, result); return result; } /// /// Pointwise applies the absolute maximum with the values of another vector to each value. /// /// The vector with the values to compare to. /// The vector to store the result. /// If this vector and are not the same size. public void PointwiseAbsoluteMaximum(Vector other, Vector result) { if (Count != result.Count) { throw new ArgumentException("All vectors must have the same dimensionality.", nameof(result)); } DoPointwiseAbsoluteMaximum(other, result); } /// /// Calculates the L1 norm of the vector, also known as Manhattan norm. /// /// The sum of the absolute values. public abstract double L1Norm(); /// /// Calculates the L2 norm of the vector, also known as Euclidean norm. /// /// The square root of the sum of the squared values. public abstract double L2Norm(); /// /// Calculates the infinity norm of the vector. /// /// The maximum absolute value. public abstract double InfinityNorm(); /// /// Computes the p-Norm. /// /// The p value. /// Scalar ret = (sum(abs(this[i])^p))^(1/p) public abstract double Norm(double p); /// /// Normalizes this vector to a unit vector with respect to the p-norm. /// /// The p value. /// This vector normalized to a unit vector with respect to the p-norm. public abstract Vector Normalize(double p); /// /// Returns the value of the absolute minimum element. /// /// The value of the absolute minimum element. public abstract T AbsoluteMinimum(); /// /// Returns the index of the absolute minimum element. /// /// The index of absolute minimum element. public abstract int AbsoluteMinimumIndex(); /// /// Returns the value of the absolute maximum element. /// /// The value of the absolute maximum element. public abstract T AbsoluteMaximum(); /// /// Returns the index of the absolute maximum element. /// /// The index of absolute maximum element. public abstract int AbsoluteMaximumIndex(); /// /// Returns the value of maximum element. /// /// The value of maximum element. public T Maximum() { return At(MaximumIndex()); } /// /// Returns the index of the maximum element. /// /// The index of maximum element. public abstract int MaximumIndex(); /// /// Returns the value of the minimum element. /// /// The value of the minimum element. public T Minimum() { return At(MinimumIndex()); } /// /// Returns the index of the minimum element. /// /// The index of minimum element. public abstract int MinimumIndex(); /// /// Computes the sum of the vector's elements. /// /// The sum of the vector's elements. public abstract T Sum(); /// /// Computes the sum of the absolute value of the vector's elements. /// /// The sum of the absolute value of the vector's elements. public double SumMagnitudes() { return L1Norm(); } } }