// // Math.NET Numerics, part of the Math.NET Project // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // // Copyright (c) 2009-2015 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; using IStation.Numerics.LinearAlgebra.Storage; using IStation.Numerics.Threading; namespace IStation.Numerics.LinearAlgebra.Double { /// /// double version of the class. /// [Serializable] public abstract class Vector : Vector { /// /// Initializes a new instance of the Vector class. /// protected Vector(VectorStorage storage) : base(storage) { } /// /// Set all values whose absolute value is smaller than the threshold to zero. /// public override void CoerceZero(double threshold) { MapInplace(x => Math.Abs(x) < threshold ? 0d : x, Zeros.AllowSkip); } /// /// Conjugates vector and save result to /// /// Target vector protected sealed override void DoConjugate(Vector result) { if (ReferenceEquals(this, result)) { return; } CopyTo(result); } /// /// Negates vector and saves result to /// /// Target vector protected override void DoNegate(Vector result) { Map(x => -x, result, Zeros.AllowSkip); } /// /// 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 override void DoAdd(double scalar, Vector result) { Map(x => x + scalar, result, Zeros.Include); } /// /// 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 override void DoAdd(Vector other, Vector result) { Map2((x, y) => x + y, other, result, Zeros.AllowSkip); } /// /// 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 override void DoSubtract(double scalar, Vector result) { Map(x => x - scalar, result, Zeros.Include); } /// /// 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 override void DoSubtract(Vector other, Vector result) { Map2((x, y) => x - y, other, result, Zeros.AllowSkip); } /// /// 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 override void DoMultiply(double scalar, Vector result) { Map(x => x*scalar, result, Zeros.AllowSkip); } /// /// 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. /// protected override void DoDivide(double divisor, Vector result) { Map(x => x/divisor, result, divisor == 0.0 ? Zeros.Include : Zeros.AllowSkip); } /// /// 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. protected override void DoDivideByThis(double dividend, Vector result) { Map(x => dividend/x, result, Zeros.Include); } /// /// 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 override void DoPointwiseMultiply(Vector other, Vector result) { Map2((x, y) => x*y, other, result, Zeros.AllowSkip); } /// /// Pointwise divide this vector with another vector and stores the result into the result vector. /// /// The vector to pointwise divide this one by. /// The vector to store the result of the pointwise division. protected override void DoPointwiseDivide(Vector divisor, Vector result) { Map2((x, y) => x/y, divisor, result, Zeros.Include); } /// /// 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 override void DoPointwisePower(double exponent, Vector result) { Map(x => Math.Pow(x, exponent), result, exponent > 0.0 ? Zeros.AllowSkip : Zeros.Include); } /// /// 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 override void DoPointwisePower(Vector exponent, Vector result) { Map2(Math.Pow, exponent, result, Zeros.Include); } /// /// 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 override void DoPointwiseModulus(Vector divisor, Vector result) { Map2(Euclid.Modulus, divisor, result, Zeros.Include); } /// /// 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 override void DoPointwiseRemainder(Vector divisor, Vector result) { Map2(Euclid.Remainder, divisor, result, Zeros.Include); } /// /// Pointwise applies the exponential function to each value and stores the result into the result vector. /// /// The vector to store the result. protected override void DoPointwiseExp(Vector result) { Map(Math.Exp, result, Zeros.Include); } /// /// Pointwise applies the natural logarithm function to each value and stores the result into the result vector. /// /// The vector to store the result. protected override void DoPointwiseLog(Vector result) { Map(Math.Log, result, Zeros.Include); } protected override void DoPointwiseAbs(Vector result) { Map(Math.Abs, result, Zeros.AllowSkip); } protected override void DoPointwiseAcos(Vector result) { Map(Math.Acos, result, Zeros.Include); } protected override void DoPointwiseAsin(Vector result) { Map(Math.Asin, result, Zeros.AllowSkip); } protected override void DoPointwiseAtan(Vector result) { Map(Math.Atan, result, Zeros.AllowSkip); } protected override void DoPointwiseAtan2(Vector other, Vector result) { Map2(Math.Atan2, other, result, Zeros.Include); } protected override void DoPointwiseAtan2(double scalar, Vector result) { Map(x => Math.Atan2(x, scalar), result, Zeros.Include); } protected override void DoPointwiseCeiling(Vector result) { Map(Math.Ceiling, result, Zeros.AllowSkip); } protected override void DoPointwiseCos(Vector result) { Map(Math.Cos, result, Zeros.Include); } protected override void DoPointwiseCosh(Vector result) { Map(Math.Cosh, result, Zeros.Include); } protected override void DoPointwiseFloor(Vector result) { Map(Math.Floor, result, Zeros.AllowSkip); } protected override void DoPointwiseLog10(Vector result) { Map(Math.Log10, result, Zeros.Include); } protected override void DoPointwiseRound(Vector result) { Map(Math.Round, result, Zeros.AllowSkip); } protected override void DoPointwiseSign(Vector result) { Map(x => (double)Math.Sign(x), result, Zeros.AllowSkip); } protected override void DoPointwiseSin(Vector result) { Map(Math.Sin, result, Zeros.AllowSkip); } protected override void DoPointwiseSinh(Vector result) { Map(Math.Sinh, result, Zeros.AllowSkip); } protected override void DoPointwiseSqrt(Vector result) { Map(Math.Sqrt, result, Zeros.AllowSkip); } protected override void DoPointwiseTan(Vector result) { Map(Math.Tan, result, Zeros.AllowSkip); } protected override void DoPointwiseTanh(Vector result) { Map(Math.Tanh, result, Zeros.AllowSkip); } /// /// Computes the dot product between this vector and another vector. /// /// The other vector. /// The sum of a[i]*b[i] for all i. protected override double DoDotProduct(Vector other) { var dot = 0.0; for (var i = 0; i < Count; i++) { dot += At(i) * other.At(i); } return dot; } /// /// 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 sealed override double DoConjugateDotProduct(Vector other) { return DoDotProduct(other); } /// /// 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 override void DoModulus(double divisor, Vector result) { Map(x => Euclid.Modulus(x, divisor), result, Zeros.Include); } /// /// 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 override void DoModulusByThis(double dividend, Vector result) { Map(x => Euclid.Modulus(dividend, x), result, Zeros.Include); } /// /// 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 override void DoRemainder(double divisor, Vector result) { Map(x => Euclid.Remainder(x, divisor), result, Zeros.Include); } /// /// 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 override void DoRemainderByThis(double dividend, Vector result) { Map(x => Euclid.Remainder(dividend, x), result, Zeros.Include); } protected override void DoPointwiseMinimum(double scalar, Vector result) { Map(x => Math.Min(scalar, x), result, scalar >= 0d ? Zeros.AllowSkip : Zeros.Include); } protected override void DoPointwiseMaximum(double scalar, Vector result) { Map(x => Math.Max(scalar, x), result, scalar <= 0d ? Zeros.AllowSkip : Zeros.Include); } protected override void DoPointwiseAbsoluteMinimum(double scalar, Vector result) { double absolute = Math.Abs(scalar); Map(x => Math.Min(absolute, Math.Abs(x)), result, Zeros.AllowSkip); } protected override void DoPointwiseAbsoluteMaximum(double scalar, Vector result) { double absolute = Math.Abs(scalar); Map(x => Math.Max(absolute, Math.Abs(x)), result, Zeros.Include); } protected override void DoPointwiseMinimum(Vector other, Vector result) { Map2(Math.Min, other, result, Zeros.AllowSkip); } protected override void DoPointwiseMaximum(Vector other, Vector result) { Map2(Math.Max, other, result, Zeros.AllowSkip); } protected override void DoPointwiseAbsoluteMinimum(Vector other, Vector result) { Map2((x, y) => Math.Min(Math.Abs(x), Math.Abs(y)), other, result, Zeros.AllowSkip); } protected override void DoPointwiseAbsoluteMaximum(Vector other, Vector result) { Map2((x, y) => Math.Max(Math.Abs(x), Math.Abs(y)), other, result, Zeros.AllowSkip); } /// /// Returns the value of the absolute minimum element. /// /// The value of the absolute minimum element. public override double AbsoluteMinimum() { return Math.Abs(At(AbsoluteMinimumIndex())); } /// /// Returns the index of the absolute minimum element. /// /// The index of absolute minimum element. public override int AbsoluteMinimumIndex() { var index = 0; var min = Math.Abs(At(index)); for (var i = 1; i < Count; i++) { var test = Math.Abs(At(i)); if (test < min) { index = i; min = test; } } return index; } /// /// Returns the value of the absolute maximum element. /// /// The value of the absolute maximum element. public override double AbsoluteMaximum() { return Math.Abs(At(AbsoluteMaximumIndex())); } /// /// Returns the index of the absolute maximum element. /// /// The index of absolute maximum element. public override int AbsoluteMaximumIndex() { var index = 0; var max = Math.Abs(At(index)); for (var i = 1; i < Count; i++) { var test = Math.Abs(At(i)); if (test > max) { index = i; max = test; } } return index; } /// /// Computes the sum of the vector's elements. /// /// The sum of the vector's elements. public override double Sum() { var sum = 0.0; for (var i = 0; i < Count; i++) { sum += At(i); } return sum; } /// /// Calculates the L1 norm of the vector, also known as Manhattan norm. /// /// The sum of the absolute values. public override double L1Norm() { var sum = 0.0; for (var i = 0; i < Count; i++) { sum += Math.Abs(At(i)); } return sum; } /// /// Calculates the L2 norm of the vector, also known as Euclidean norm. /// /// The square root of the sum of the squared values. public override double L2Norm() { return Math.Sqrt(DoDotProduct(this)); } /// /// Calculates the infinity norm of the vector. /// /// The maximum absolute value. public override double InfinityNorm() { return CommonParallel.Aggregate(0, Count, i => Math.Abs(At(i)), Math.Max, 0d); } /// /// Computes the p-Norm. /// /// /// The p value. /// /// /// Scalar ret = ( ∑|At(i)|^p )^(1/p) /// public override double Norm(double p) { if (p < 0d) throw new ArgumentOutOfRangeException(nameof(p)); if (p == 1d) return L1Norm(); if (p == 2d) return L2Norm(); if (double.IsPositiveInfinity(p)) return InfinityNorm(); var sum = 0d; for (var index = 0; index < Count; index++) { sum += Math.Pow(Math.Abs(At(index)), p); } return Math.Pow(sum, 1.0/p); } /// /// Returns the index of the maximum element. /// /// The index of maximum element. public override int MaximumIndex() { var index = 0; var max = At(index); for (var i = 1; i < Count; i++) { var test = At(i); if (test > max) { index = i; max = test; } } return index; } /// /// Returns the index of the minimum element. /// /// The index of minimum element. public override int MinimumIndex() { var index = 0; var min = At(index); for (var i = 1; i < Count; i++) { var test = At(i); if (test < min) { index = i; min = test; } } return index; } /// /// 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 override Vector Normalize(double p) { if (p < 0d) { throw new ArgumentOutOfRangeException(nameof(p)); } double norm = Norm(p); var clone = Clone(); if (norm == 0d) { return clone; } clone.Multiply(1d / norm, clone); return clone; } } }