About MtxVec math library: The following content applies to users of MtxVec library for Delphi pascal, C# and C++. MtxVec uses Math387 unit as a replacement of Delphis default Math unit. Always include Math387. This library has four key value types: Vector and Matrix from MtxExpr unit and VectorInt and MatrixInt from MtxExprInt unit They can be assigned like this: var a: Vector; b: Matrix; c: VectorInt; d: MatrixInt; begin a := [1,2,3,4]; b := [[1,2],[2,3]]; c := [1,2,3,4]; d := [[1,2],[2,3]]; end; They dont need a constructor in Delphi. The units MtxExpr, MtxExprInt, MtxVec, Math387, MtxVecInt, MtxVecBase, AbstractMtxVec, AbstractMtxVecInt would typically get included. Vector value type internally stores data in TVec object type and allows implicit conversion to TVec, TDenseMtxVec, TMtxVec and TMtxVecBase. Matrix value type internally stores data in TMtx object type and allows implicit conversion to TMtx, TDenseMtxVec, TMtxVec and TMtxVecBase. When declaring: var arr: TDoubleArray; av: TVec; a: Vector; Explicit typecasts: a := Vector(arr) a := Vector(av); result in a deep-copy and should be avoided when possible. Implicit conversions work without deep-copy: arr := a; av := a; Internally Vector and Matrix types can hold 4 different data types: Single, Double, TCplx (double precision complex) and TSCplx (single precision complex). The default precision used is double. The actual precision stored is saved in the property: a.FloatPrecision and this property can be: mvDouble mvSingle mvSingleComplex mvDoubleComplex This precision is assigned, when sizing the vector or matrix: a.Size(10, mvDouble); b.Size(10, 10, mvDouble); Call to size does not preserve values. Use Resize method without precision parameter to preserve values. To call size without changing precision set Length: a.Length := 10; If Size is called without parameters, default precision is used (typically mvDouble): a.Size(10); if Size is called with vector or matrix as source, the precision is used as well: a.Size(b); is same as: a.Size(b.Length, b.FloatPrecision); // a and b is vector a.Size(b.rows, b.cols, b.IntPrecision); //a and b is matrix or in case of VectorInt/TVecInt: a.Size(b.Length, b.IntPrecision); a.Size(b.rows, b.cols, b.IntPrecision); //for matrices Default precision for VectorInt/TVecInt is prInt32, which means 32bit integer. This is used in cases like this: intVec.Size(aTVec); or intVec.Size(aTVec.Length); this is both the same as: intVec.Size(aTVec.Length, prInt32); All computational methods and functions (except indexed overloads), will call Size internally and it is not neccessary to call it explicitely. Setting TVec/TMtx to complex will preserve content: a.Complex := True; and halve the length. To change or read row or col count: b.Rows := 10; b.Cols := 10; Prefer Size method over Length, Complex and Rows/Cols properties. To access individual elements, you can write: a[i] := 2; b[i,j] := 3; or: a.Values[i] := 2; b.Values[i,j] := 3; For complex numbers: a.CValues[i] := 2; b.CValues[i,j] := 3; Vector and matrix are zero-based (first element is at 0), row-major. The SetVal method accepts only one parameter: a.Size(10); a.SetVal(2.0); And sets entire vector to the same value. Matrices have rows packed. It is possible to traverse matrix elements as 1D array: aMtx.Values1D[i] aMtx.CValues1D[i] For deep copying, use the copy method: a.Copy(av); b.Copy(bm); Simple assignment of Vector or Matrix value types is without deep copy: a := b; //a and b Vectors point the same internal TVec or TMtx object You can copy (or call any other function) from matrix to vector: aVector.Sin(bMatrix); This operation also calls aVector.Size internally. Always assume for Vector/VectorInt/Matrix/MatrixInt, that implicit in-place operation is not allowed: a.Sin(a) a.Mul(a,a) Will not work. But this will: a.Sin; a.Sqr; To assign content to matrix from vector is possible, if the Length of the matrix (its size) does not need to change: bMatrix.Sin(aVector); Both Vector and Matrix support implicit conversion (without data copy) to TMtxVec type. The TMtxVec type is the abstract type accepted by all routines, which accept either parameter type. Vector and Matrix. All methods common to TVec and TMtx are defined on it. To copy to/from Delphi dynamic array use: a.CopyFromArray(DelphiDynArrayName); a.CopyToArray(DelphiDynArrayName); The Delphi array, can be 1D for vectors and matrices (TDoubleArray or TCplxArray) and optionally also 2D for matrices (T2DDoubleArray, T2DCplxArray); The array and "a" will be sized automatically during the copy operation. Most importantly, when writing expressions: a := a*b; (.* from Matlab) the "*" operator applies to per element operations. To perform linear algebra, need to call function: a := Mul(a,b); (* from Matlab) The vector is typically considered a row vector. Library assumes row-major matrices. If vector is on right side of the multiplication with matrix, it can be assumed to be a column. Division: a := Divide(a,b); is also linear algebra divison, same as a/b from Matlab. If you want to do left divide ( \ from Matlab),write: a := LDivide(A, b); Per element division uses: a := a/b; (./ from Matlab) For both matrix and vector all standard functions are defined with full support for complex numbers: a := sin(a) + cos(a) Complex number has a type named: TCplx for double precisionand TSCplx for single precision. Example: var a,b: TCplx; aStr: string; begin a := Cplx(1,2); a := sin(b)+2; aStr := CplxToStr(a); //conversion to text b := StrToCplx('2+3i'); //conversion from text TCplx and TSCplx support all standard math functions. If you need to use constants, use C_ONE or C_ZERO Both Vector and matrix types are accepted by many functions. These functions are defined concurrently as: 1.) global functions, for all cases where result is a single variable: a := sin(b); 2.) in-place methods of vector and matrix: a.Sin; 3.) not-in-place methods of vector and matrix: a.Sin(b); All vector/matrix parameters to methods need to match in length. It is not possible to pass vector length 1, if the expected param is scalar. A separate overload handles scalar parameters, if they are supported. Other functions/methods defined on Vector and where applicable also for Matrix: y.FixAngle(x), computes: y := x - y*Trunc(x/y), where Y is TWOPI a.Size(aLength, aIsComplex, aIsDouble), sets: a.Length := aLength and a.Complex := aIsComplex (double precision if aIsDouble is true) a.Size(Src, aFloatPrecision), sets: a.Length and numeric precision to match Src using aFloatPrecision a.PValues1D(Index), returns: pointer to the double value at a[Index] a.PSValues1D(Index), returns: pointer to the single value at a[Index] a.PCValues1D(Index), returns: pointer to the complex (double) value at a[Index] a.PSCValues1D(Index), returns: pointer to the complex (single) value at a[Index] a.AssignWithoutCopy(Src), computes: a becomes a reference to Src without copying a.Assign(Src), computes: a := copy of Src a.BlockInit, computes: initialize block processing on a a.BlockInit(ABlockSize), computes: initialize block processing on a with block size ABlockSize a.BlockInit(Src), computes: initialize block processing using data from Src a.BlockInit(Src, ABlockSize), computes: initialize block processing on Src with block size ABlockSize a.BlockNext, computes: advance to the next data block in a a.BlockFinish, computes: deinitialize block processing on a a.ReplaceNAN(Value), computes: replace all NANs in a with Value a.ReplaceNAN(Value, Index, Len), computes: replace NANs in a subrange with Value a.DisableSubrange, computes: prevent further subrange modifications on a a.EnableSubrange, computes: allow subrange modifications on a a.DisableSelect, computes: prevent selection changes on a a.EnableSelect, computes: allow selection changes on a a.SelectAll, computes: reset any selection in a to include all elements a.SetFullRange, computes: reset a to its full range view a.SetFullRangeLevel, computes: restore a's previous subrange view from the stack a.SetSubRange(Index, Len), computes: define a as a subvector starting at Index with length Len a.SetSubRangeLevel(Index, Len), computes: define a as a subvector (pushing the previous range to a stack) a.SetSubRange, computes: reset a to its full range (same as SetFullRange) a.SetSubIndex(BeginIndex, EndIndex), computes: a becomes a subarray from BeginIndex to EndIndex (inclusive) a.BinarySearch(X: double), computes: result = index of X in sorted a (or -1 if not found) a.BinarySearch(X: TCplx), computes: result = index of X in sorted a (complex version) a.BinarySearch(X: double; var XIndex), computes: sets XIndex to the index of X in sorted a (true if found) a.BinarySearch(X: TCplx; var XIndex), computes: sets XIndex to the index of X in sorted a (complex version, true if found) a.Sin, computes: a := sin(a) a.Sin(X), computes: a := sin(X) a.Cos, computes: a := cos(a) a.Cos(X), computes: a := cos(X) a.Tan, computes: a := tan(a) a.Tan(X), computes: a := tan(X) a.Cot, computes: a := cot(a) a.Cot(X), computes: a := cot(X) a.Sec, computes: a := sec(a) a.Sec(X), computes: a := sec(X) a.Csc, computes: a := csc(a) a.Csc(X), computes: a := csc(X) a.ArcSin, computes: a := arcsin(a) a.ArcSin(X), computes: a := arcsin(X) a.ArcCos, computes: a := arccos(a) a.ArcCos(X), computes: a := arccos(X) a.ArcTan2(Y, X), computes: a := arctan2(Y, X) a.ArcTan, computes: a := arctan(a) a.ArcTan(X), computes: a := arctan(X) a.ArcCot, computes: a := arccot(a) a.ArcCot(X), computes: a := arccot(X) a.ArcSec, computes: a := arcsec(a) a.ArcSec(X), computes: a := arcsec(X) a.ArcCsc, computes: a := arccsc(a) a.ArcCsc(X), computes: a := arccsc(X) a.Sinh, computes: a := sinh(a) a.Sinh(X), computes: a := sinh(X) a.Cosh, computes: a := cosh(a) a.Cosh(X), computes: a := cosh(X) a.Tanh, computes: a := tanh(a) a.Tanh(X), computes: a := tanh(X) a.Coth, computes: a := coth(a) a.Coth(X), computes: a := coth(X) a.Sech, computes: a := sech(a) a.Sech(X), computes: a := sech(X) a.Csch, computes: a := csch(a) a.Csch(X), computes: a := csch(X) a.Abs, computes: a := abs(a) a.Abs(X), computes: a := abs(X) a.ArcSinh, computes: a := arcsinh(a) a.ArcSinh(X), computes: a := arcsinh(X) a.ArcCosh, computes: a := arccosh(a) a.ArcCosh(X), computes: a := arccosh(X) a.ArcTanh, computes: a = arctanh(a) (inverse hyperbolic tangent applied element-wise) a.ArcTanh(X), computes: a = arctanh(X) (inverse hyperbolic tangent applied element-wise) a.ArcCoth, computes: a = arccoth(a) (inverse hyperbolic cotangent applied element-wise) a.ArcCoth(X), computes: a = arccoth(X) (inverse hyperbolic cotangent applied element-wise) a.ArcSech, computes: a = arcsech(a) (inverse hyperbolic secant applied element-wise) a.ArcSech(X), computes: a = arcsech(X) (inverse hyperbolic secant applied element-wise) a.ArcCsch, computes: a = arccsch(a) (inverse hyperbolic cosecant applied element-wise) a.ArcCsch(X), computes: a = arccsch(X) (inverse hyperbolic cosecant applied element-wise) a.Cbrt, computes: a = cube root of a (applied element-wise) a.Cbrt(X), computes: a = cube root of X (applied element-wise) a.Ceil, computes: a = ceil(a) (each element rounded towards positive infinity) a.Ceil(Src), computes: a = ceil(Src) (each element rounded towards positive infinity) a.Ln() computes: a := ln(a) a.Ln(b) computes: a := ln(b) a.Log10() computes: a := log10(a) a.Log10(b) computes: a := log10(b) a.Log2() computes: a := log2(a) a.Log2(b) computes: a := log2(b) a.Exp() computes: a := exp(a) a.Exp(b) computes: a := exp(b) a.Exp2() computes: a := 2^(a) a.Exp2(b) computes: a := 2^(b) a.Exp10() computes: a := 10^(a) a.Exp10(b) computes: a := 10^(b) a.GroupSum(Bins, Src) computes: a := group sum of Src using bin indices from Bins (BinsMax defaults to -1) a.GroupSumIteration(Bins, Src, BinsMax) computes: a := group sum of Src using bin indices from Bins with BinsMax provided a.ImagPart(b) computes: a := imaginary part of b a.IntPower(n) computes: a := a^n (each element raised to the integer exponent n) a.IntPower(b, n) computes: a := b^n (each element of b raised to the integer exponent n) a.Inv() computes: a := 1/x for each x in a a.Inv(b) computes: a := 1/x for each x in b a.Inv(b, Threshold) computes: a := 1/x for each x in b, with |x| limited by Threshold to avoid division by zero a.CartToPolar(m, p) computes: convert a from Cartesian to polar form; m := magnitude(a) and p := phase(a) a.Copy(b) computes: a := copy of b a.Copy(b, precision) computes: a := copy of b converted to the specified TMtxFloatPrecision a.Clear() computes: set a.Length = 0 and a.Complex = false a.CondDisable() computes: save current ConditionCheck and set ConditionCheck = false a.CondEnable() computes: restore ConditionCheck to its previous value a.Conj() computes: a := conjugate(a) a.CopyFromArray(Src: TCplxArray) computes: a := vector with values copied from Src; size and Complex are set accordingly a.CopyFromArray(Src: TDoubleArray) computes: a := vector with values copied from Src; a.Complex is set to false a.CopyFromArray(Src: TSingleArray) computes: a := vector with values copied from Src; a.Complex is set to false a.CopyFromArray(Src: TIntegerArray) computes: a := vector with values copied from Src; a.Complex is set to false a.CopyFromArray(Src: TSmallIntArray) computes: a := vector with values copied from Src; a.Complex is set to false a.CopyFromArray(Src: TByteArray) computes: a := vector with values copied from Src; a.Complex is set to false a.CopyToArray(Dst: TCplxArray) computes: copy a's complex values to array Dst (automatically sized) a.CopyToArray(Dst: TDoubleArray) computes: copy a's real values to array Dst (automatically sized) a.CopyToArray(Dst: TSingleArray) computes: copy a's values to array Dst as single precision (automatically sized) a.CopyToArray(Dst: TIntegerArray; Rounding) computes: convert and copy a's values to an integer array using the specified rounding a.CopyToArray(Dst: TSmallIntArray; Rounding) computes: convert and copy a's values to a small-int array using the specified rounding a.CopyToArray(Dst: TByteArray; Rounding) computes: convert and copy a's values to a byte array using the specified rounding a.CplxToReal(ReVec, ImVec) computes: split a's complex values into real parts in ReVec and imaginary parts in ImVec a.ExtendToComplex(Zeros) computes: extend a to a complex vector; if Zeros is true, set imaginary parts to 0 a.ExtendToComplex(Src, Zeros) computes: a := complex version of Src; if Zeros is true, set imaginary parts to 0 a.FixAngle() computes: adjust each element of a to lie within [ -2p, 2p ] a.Floor() computes: a := floor(a) (round each element towards negative infinity) a.Expj() computes: a := e^(j*a) (compute complex exponential assuming a is real) a.Expj(Omega) computes: a := e^(j*Omega) where Omega is a real vector a.Find(X: double) computes: return index of last occurrence of X in a, or -1 if not found a.Find(X: TCplx) computes: return index of last occurrence of complex X in a, or -1 if not found a.Frac() computes: a := fractional part of a (a - trunc(a)) a.First returns: first element in a's Values array a.Firstc returns: first element in a's CValues array a.Flip() computes: a := vector with real and imaginary parts swapped for each element in a a.FindAndGather(vec, op, complexScalar) computes: gathers all elements matching "a op b", where op is a string of a comparison operator (>, < ...) a.FindAndGather(vec, op, Scalar) computes: gathers all elements matching "a op b", where op is a string of a comparison operator (>, < ...) a.FindAndGather(vec, op, vec) computes: gathers all elements matching "a op b", where op is a string of a comparison operator (>, < ...) a.Gather(X, aTVecIntIndexes, IndexType, Increment, Offset) computes: a becomes the vector of elements gathered from X according to the specified indexes, index type, increment, and offset. a.GatherByIncr(X, Increment, Offset) computes: a becomes the vector of elements from X gathered at indices defined by the formula "Increment*i + Offset". a.GatherByIndex(X, aTVecIntIndexes) computes: a becomes the vector of elements from X gathered at the indices specified in the Indexes vector. a.GatherByMask(X, aTVecIntMask) computes: a becomes the vector of elements from X where the corresponding entry in Mask is 1. a.GatherSplit(MaskVec, NotMaskVec, Mask) computes: a becomes the original vector reconstructed from the "positive" elements in MaskVec and "negative" elements in NotMaskVec according to Mask. a.GetCol(Mtx, aCol) computes: a becomes the column vector extracted from column aCol of matrix Mtx. a.GetRow(Mtx, aRow) computes: a becomes the row vector extracted from row aRow of matrix Mtx. a.FlipConj(), computes: a := flipConj(a) a.FlipConj(b), computes: a := flipConj(b) a.InvSqrt(), computes: a := 1/sqrt(a) a.InvSqrt(b), computes: a := 1/sqrt(b) a.InvCbrt(), computes: a := 1/cbrt(a) a.InvCbrt(b), computes: a := 1/cbrt(b) a.Rem(b, c), computes: a := b - c * trunc(b/c), c is scalar a.Rem(b, y), computes: a := b - y * trunc(b/y), y is vector a.Mag(), computes: a := |a| a.Mag(b), computes: a := |b| a.Scale(c), computes: a := a * c, c is scalar a.scatter(b) computes: a := scatter(b) a.scatterByIncr(b) computes: a := scatterByIncr(b) a.scatterByIndexes(b, idx) computes: a := scatterByIndexes(b, idx) a.scatterByMask(b) computes: a := scatterByMask(b) a.SetIt(Index, A) computes: a := vector with values from array A starting at position Index a.SetIt(Index, AIndex, Len, A) computes: a[Index..Index+Len-1] := A[AIndex..AIndex+Len-1] a.SetSingle(Index, A) computes: a := vector with single-precision values from array A starting at position Index a.SetSingle(Index, AIndex, Len, A) computes: a[Index..Index+Len-1] := A[AIndex..AIndex+Len-1] (as single-precision) a.SetDouble(Index, A) computes: a := vector with double-precision values from array A starting at position Index a.SetDouble(Index, AIndex, Len, A) computes: a[Index..Index+Len-1] := A[AIndex..AIndex+Len-1] (as double-precision) a.SetInteger(Index, A) computes: a := vector with integer values from array A starting at position Index a.SetInteger(Index, AIndex, Len, A) computes: a[Index..Index+Len-1] := A[AIndex..AIndex+Len-1] (as integers) a.sqr(), computes: a := square(a) a.sqr(b), computes: a := square(b) a.sqrt(), computes: a := sqrt(a) a.sqrt(b), computes: a := sqrt(b) a.logN(10.0), computes: a := log base 10 of a a.logN(10.0, X), computes: a := log base 10 of X a.mul(3), computes: a := a * 3 a.mul(3+4i), computes: a := a * (3+4i) a.mul(X, 3), computes: a := X * 3 a.mul(X, 3+4i), computes: a := X * (3+4i) a.mulI(), computes: a := a * i a.mulI(X), computes: a := X * i a.Normalize(2,3) computes: a := (a - 2) / 3 a.Normalize(2+3i, 4-5i) computes: a := (a - (2+3i)) / (4-5i) a.Normalize(b, 2,3) computes: a := (b - 2) / 3 a.Normalize(b, 2+3i, 4-5i) computes: a := (b - (2+3i)) / (4-5i) a.Normalize(b, 2+3i, 4) computes: a := (b - (2+3i)) / 4 a.PolarToCart(b, c) computes: a := polarToCart(b, c) a.Power(1.2) computes: a := power(a, 1.2) a.Power(2+3i) computes: a := power(a, 2+3i) a.Power(1.0, b) computes: a := (1.0)^(b) (element-wise) a.Power(2+3i, b) computes: a := (2+3i)^(b) (element-wise) a.Power(b, c) computes: a := b^(c) (element-wise) a.Power(b, 1.2) computes: a := b^(1.2) (element-wise) a.PowerVec(b, c) computes: a := powerVec(b, c) (element-wise) a.PhaseSpectrum(b) computes: Phase(Src) or arctan(X.Re,X.Im) for complex vector/matrix and returns real result, b is complex and vector a.PowerSpectrum(b) computes sqr(b.re) + sqr(b.im) , b is complex and vector a.Product() computes: result = product of all real elements of a a.Productc() computes: result = product of all complex elements of a a.RandGauss() computes: a := vector of Gaussian random samples (mean = 0, stddev = 1) a.RandGauss(AMean, AStdDev) computes: a := vector of Gaussian random samples with mean = AMean and stddev = AStdDev a.RandGauss(Seed, AMean, AStdDev) computes: a := vector of Gaussian random samples with specified seed, mean = AMean, and stddev = AStdDev a.RandUniform() computes: a := vector of uniform random samples in [0, 1] a.RandUniform(aLow, aHigh) computes: a := vector of uniform random samples in [aLow, aHigh] a.RandUniform(Seed, aLow, aHigh) computes: a := vector of uniform random samples with specified seed in [aLow, aHigh] a.RealPart(b) computes: a := real part of b a.ReadValues(Stream, Precision) computes: a := vector values read from the stream using the specified precision a.RealToCplx(b, c) computes: a := complex vector constructed from real vector b and imaginary vector c a.Reset() computes: reset a's properties to their default values a.Replace(aScalar, bScalar) computes: a := vector with elements equal to aScalar (within tolerance) replaced by bScalar a.Replace(aComplexScalar, bComplexScalar) computes: a := vector with elements equal to aComplexScalar (within tolerance) replaced by bComplexScalar a.RMS() computes: result = root mean square of the elements of a a.Round(), computes: a := round(a) a.Round(b), computes: a := round(b) a.SetVal(1), computes: a := vector with all elements set to 1 a.SetVal(1+2i), computes: a := vector with all elements set to 1+2i a.SetZero(), computes: a := vector with all elements set to 0 a.Sign(), computes: a := -a a.Sgn(), computes: result := signum(a) (1 for positive, 0 for zero, -1 for negative) a.Sgn(b), computes: a := signum(b) a.SgnMul(b), computes: a := signum(b) * b a.Size(b) computes: a becomes a vector with the same size and Complex property as b a.Size(b, AComplex) computes: a becomes a vector with the same size as b, but with a.Complex set to AComplex a.SizeToArray(Dst: TCplxArray) computes: Dst is resized to hold all complex values from a a.SizeToArray(Dst: TDoubleArray) computes: Dst is resized to hold all double-precision values from a (if a.Complex is true, Dst length becomes 2*a.Length) a.SizeToArray(Dst: TSingleArray) computes: Dst is resized to hold all single-precision values from a (if a.Complex is true, Dst length becomes 2*a.Length) a.SizeToArray(Dst: TIntegerArray) computes: Dst is resized to hold all integer values from a (if a.Complex is true, Dst length becomes 2*a.Length) a.SizeToArray(Dst: TSmallIntArray) computes: Dst is resized to hold all small-integer values from a (if a.Complex is true, Dst length becomes 2*a.Length) a.SizeToArray(Dst: TByteArray) computes: Dst is resized to hold all byte values from a (if a.Complex is true, Dst length becomes 2*a.Length) a.IsEqual(b) computes: returns true if a and b have the same Length, Complex property, and matching element values a.IsEqual(b, Precision, Compare) computes: returns true if a and b are equal within the specified tolerance using the Compare method a.IsEqual(1.0) computes: returns true if every element of a equals 1.0 a.IsEqual(1+2i) computes: returns true if every element of a equals 1+2i a.IsEqual(1.0, Tol, Compare) computes: returns true if every element of a equals 1.0 within tolerance Tol using the Compare method a.IsEqual(1+2i, Tol, Compare) computes: returns true if every element of a equals 1+2i within tolerance Tol using the Compare method a.StdDev() computes: result = standard deviation of a (real values) a.StdDev(mean) computes: result = standard deviation of a using the provided mean (real values) a.StdDev(meanC) computes: result = standard deviation of a using the provided complex mean (complex values) a.MeanAndStdDev() computes: aMean := mean(a) and aStdDev := standard deviation of a (real values) a.SinCos(b, c) computes: b := sin(a) and c := cos(a) a.SinhCosh(b, c) computes: b := sinh(a) and c := cosh(a) a.Sum() computes: sum of elements in a (real sum; error if a is complex) a.Sumc() computes: sum of all elements in a (complex sum; error if a is not complex) a.ThreshBottom(scalar) replaces all values in "a" smaller than scalar with scalar. a.ThreshBottom(bVec, scalar) overwrites all values in a with values from bVec. Those which are smaller than scalar are replaced with scalar. a.ThreshTop(scalar) replaces all values in "a" bigger than scalar with scalar. a.ThreshTop(bVec, scalar) overwrites all values in a with values from bVec. Those which are bigger than scalar are replaced with scalar. a.ThreshAbsLT(Scalar) replaces all values in a whose abs value is less than Scalar with Scalar, preserves sign of replaced values. a.ThreshAbsLT(bVec, Scalar) overwrites all values in a with values from bVec whose abs value is less than Scalar with Scalar, preserves sign of replaced values, and stores result in a. a.ThreshAbsGT(Scalar) replaces all values in a whose abs value is more than Scalar with Scalar, preserves sign of replaced values. a.ThreshAbsGT(bVec, Scalar) overwrites all values in a with values from bVec and replaces them with whose abs value is more than Scalar with Scalar, preserves sign of replaced values, and stores result in a. a.ThresholdLT(LTLevel, LTValue) computes: replace values in a, if they are smaller than LTLevel with LTValue, LTValue can be complex. LTLevel only real a.ThresholdLT(bVec, LTLevel, LTValue) overwrites all values a in with values from bVec and replaces them, if they are smaller than LTLevel with LTValue, LTValue can be complex. LTLevel only real. Except for bVec, params are scalar. a.ThresholdGT(GTLevel, GTValue) computes: replaces values in a, if they are greater than GTLevel with GTValue, GTValue can be complex. GTLevel only real. a.ThresholdGT(bVec, GTLevel, GTValue) overwrites all values in a with values from bVec and replaces them, if they are greater than GTLevel with GTValue, GTValue can be complex. GTLevel only real. Except for bVec, params are scalar. a.ThresholdGT_LT(GTLevel, GTValue, LTLevel, LTValue) replaces values in a with GTValue, if they are bigger than GTLevel and with LTValue, if smaller than LTLevel. All params are scalar. a.ThresholdGT_LT(bVec, GTLevel, GTValue, LTLevel, LTValue) overwrites all values in a with values from bVec and replaces them with GTValue, if they are bigger than GTLevel and with LTValue, if smaller than LTLevel. Except for bVec, params are scalar. a.TruncAndFrac(TruncDst, FracDst) computes: TruncDst := trunc(a) and FracDst := frac(a) a.Trunc() computes: a := trunc(a) (rounds each element toward zero) a.Trunc(Src) computes: a := trunc(Src) a.SaveToFile(FileName, Append) computes: saves a's header and values to the specified file, file can be .csv, .txt or .bin a.LoadFromFile(FileName) computes: loads a's header and values from the specified file, , file can be .csv, .txt or .bin a.ReadHeader(Stream) computes: reads header information from the stream into a and returns the stored precision a.WriteHeader(Stream, Precision, Rounding) computes: writes a's header information to the stream a.WriteValues(Stream, Precision, Rounding) computes: writes a's values to the stream z.Add(RealScalar), computes: z := z + RealScalar z.Add(ComplexScalar), computes: z := z + ComplexScalar z.Add(Vec, RealScalar), computes: z := Vec + RealScalar (element-wise) z.Add(Vec, ComplexScalar), computes: z := Vec + ComplexScalar (element-wise; Complex property is set to True internally) z.Add(Vec), computes: z := z + Vec (element-wise) z.AddScaled(Vec, aScale), computes: z := z + aScale * Vec [aScale is a real number] z.AddScaled(Vec, RScale, IScale), computes: z := z + Cplx(RScale, IScale) * Vec z.AddScaled(Vec, aScale), computes: z := z + aScale * Vec [aScale is complex] z.Add(Vec1, Vec2), computes: z := Vec1 + Vec2 (element-wise) z.AddProduct(Vec1, Vec2), computes: z := z + (Vec1 .* Vec2) (element-wise product added to z) z.ConjMul(Vec), computes: z := z .* Conjugate(Vec) (element-wise multiplication with conjugate of Vec) z.ConjMul(Vec1, Vec2), computes: z := Vec1 .* Conjugate(Vec2) (element-wise) a.AddScaled(X, Y, yScale), computes: a := X + Y * yScale [X, Y are vectors; yScale is scalar] a.AddScaled(X, Y, yScale), computes: a := X + Y * yScale [X, Y are vectors; yScale is complex] a.AddScaledSqr(X, Y, yScale), computes: a := (X + Y * yScale)^2 [X, Y are vectors; yScale is scalar] - Special case: when yScale = -1, computes: a := (X - Y)^2 = X^2 - 2XY + Y^2 a.AddScaledSqr(X, Y, yScale), computes: a := (X + Y * yScale)^2 [X, Y are vectors; yScale is complex] a.SqrAddScaled(X, Y, yScale), computes: a := X^2 + Y^2 * yScale [X, Y are vectors; yScale is scalar] - Special case: when yScale = -1, computes: a := X^2 - Y^2 a.SqrAddScaled(X, Y, yScale), computes: a := X^2 + Y^2 * yScale [X, Y are vectors; yScale is complex] a.Add(X, Y, Z), computes: a := X + Y + Z [X, Y, Z are vectors] a.AddScaled(X, Y, Z, zScale), computes: a := X + Y + Z * zScale [X, Y, Z are vectors; zScale is scalar] a.AddScaled(X, Y, Z, zScale), computes: a := X + Y + Z * zScale [X, Y, Z are vectors; zScale is complex] a.AddScaled(X, Y, yScale, Z, zScale), computes: a := X + Y * yScale + Z * zScale [X, Y, Z are vectors; yScale, zScale are scalars] a.AddScaled(X, Y, yScale, Z, zScale), computes: a := X + Y * yScale + Z * zScale [X, Y, Z are vectors; yScale, zScale are complex] a.Add(X, Y, Z), computes: a := X + Y + Z [X, Y are vectors; Z is scalar] a.Add(X, Y, Z), computes: a := X + Y + Z [X, Y are vectors; Z is complex] a.AddScaledC(X, Y, yScale, Z), computes: a := X + Y * yScale + Z [X, Y are vectors; yScale, Z are scalars] a.AddScaledC(X, Y, yScale, Z), computes: a := X + Y * yScale + Z [X, Y are vectors; yScale, Z are complex] a.Sub(X, Y, Z), computes: a := X - Y - Z [X, Y, Z are vectors] a.SubScaled(X, Y, yScale, Z, zScale), computes: a := X - Y * yScale - Z * zScale [X, Y, Z are vectors; yScale, zScale are scalars] a.SubScaled(X, Y, yScale, Z, zScale), computes: a := X - Y * yScale - Z * zScale [X, Y, Z are vectors; yScale, zScale are complex] a.SubScaled(X, Y, Z, zScale), computes: a := X - Y - Z * zScale [X, Y, Z are vectors; zScale is scalar] a.SubScaled(X, Y, Z, zScale), computes: a := X - Y - Z * zScale [X, Y, Z are vectors; zScale is complex] a.Sub(X, Y, Z), computes: a := X - Y - Z [X, Y are vectors; Z is scalar] a.Sub(X, Y, Z), computes: a := X - Y - Z [X, Y are vectors; Z is complex] a.SubScaledC(X, Y, yScale, Z), computes: a := X - Y * yScale - Z [X, Y are vectors; yScale, Z are scalars] a.SubScaledC(X, Y, yScale, Z), computes: a := X - Y * yScale - Z [X, Y are vectors; yScale, Z are complex] a.MulAndDiv(X, Y, Z), computes: a := X * Y / Z [X, Y, Z are vectors] a.AddAndMul(X, Y, Z), computes: a := (X + Y) * Z [X, Y, Z are vectors] a.AddAndMul(X, Y, Z, zScale), computes: a := (X + Y) * Z * zScale [X, Y, Z are vectors; zScale is scalar] a.AddAndMul(X, Y, Z, zScale), computes: a := (X + Y) * Z * zScale [X, Y, Z are vectors; zScale is complex] a.AddAndMul(X, Y, yScale, Z, zScale), computes: a := (X + Y * yScale) * Z * zScale [X, Y, Z are vectors; yScale, zScale are scalars] a.AddAndMul(X, Y, yScale, Z, zScale), computes: a := (X + Y * yScale) * Z * zScale [X, Y, Z are vectors; yScale, zScale are complex] a.AddAndMul(X, Y, Z), computes: a := (X + Y) * Z [X, Y are vectors; Z is scalar] a.AddAndMul(X, Y, Z), computes: a := (X + Y) * Z [X, Y are vectors; Z is complex] a.AddAndMul(X, Y, yScale, Z), computes: a := (X + Y * yScale) * Z [X, Y are vectors; yScale, Z are scalars] a.AddAndMul(X, Y, yScale, Z), computes: a := (X + Y * yScale) * Z [X, Y are vectors; yScale, Z are complex] a.AddAndMul(X, Y, Z, zScale), computes: a := (X + Y) * Z * zScale [X, Z are vectors; Y, zScale are scalars] a.AddAndMul(X, Y, Z, zScale), computes: a := (X + Y) * Z * zScale [X, Z are vectors; Y, zScale are complex] a.AddAndMul(X, xScale, Y, Z), computes: a := (X * xScale + Y) * Z [X, Z are vectors; xScale, Y are scalars] a.AddAndMul(X, xScale, Y, Z), computes: a := (X * xScale + Y) * Z [X, Z are vectors; xScale, Y are complex] a.AddAndMul(X, Y, Z), computes: a := (X + Y) * Z [X, Z are vectors; Y is scalar] a.AddAndMul(X, Y, Z), computes: a := (X + Y) * Z [X, Z are vectors; Y is complex] a.AddAndMul(X, Y, Z), computes: a := (X + Y) * Z [X is vector; Y, Z are scalars] a.AddAndMul(X, Y, Z), computes: a := (X + Y) * Z [X is vector; Y, Z are complex] a.SubAndMul(X, Y, Z), computes: a := (X - Y) * Z [X, Y, Z are vectors] a.SubAndMul(X, Y, Z, zScale), computes: a := (X - Y) * Z * zScale [X, Y, Z are vectors; zScale is scalar] a.SubAndMul(X, Y, Z, zScale), computes: a := (X - Y) * Z * zScale [X, Y, Z are vectors; zScale is complex] a.SubAndMul(X, Y, yScale, Z, zScale), computes: a := (X - Y * yScale) * Z * zScale [X, Y, Z are vectors; yScale, zScale are scalars] a.SubAndMul(X, Y, yScale, Z, zScale), computes: a := (X - Y * yScale) * Z * zScale [X, Y, Z are vectors; yScale, zScale are complex] a.SubAndMul(X, Y, Z), computes: a := (X - Y) * Z [X, Y are vectors; Z is scalar] a.SubAndMul(X, Y, Z), computes: a := (X - Y) * Z [X, Y are vectors; Z is complex] a.SubAndMul(X, Y, yScale, Z), computes: a := (X - Y * yScale) * Z [X, Y are vectors; yScale, Z are scalars] a.SubAndMul(X, Y, yScale, Z), computes: a := (X - Y * yScale) * Z [X, Y are vectors; yScale, Z are complex] a.SubAndMul(X, Y, Z, zScale), computes: a := (X - Y) * Z * zScale [X, Z are vectors; Y, zScale are scalars] a.SubAndMul(X, Y, Z, zScale), computes: a := (X - Y) * Z * zScale [X, Z are vectors; Y, zScale are complex] a.SubAndMul(X, xScale, Y, Z), computes: a := (X * xScale - Y) * Z [X, Z are vectors; xScale, Y are scalars] a.SubAndMul(X, xScale, Y, Z), computes: a := (X * xScale - Y) * Z [X, Z are vectors; xScale, Y are complex] a.SubAndMul(X, Y, Z), computes: a := (X - Y) * Z [X, Z are vectors; Y is scalar] a.SubAndMul(X, Y, Z), computes: a := (X - Y) * Z [X, Z are vectors; Y is complex] a.SubAndMul(X, Y, Z), computes: a := (X - Y) * Z [X is vector; Y, Z are scalars] a.SubAndMul(X, Y, Z), computes: a := (X - Y) * Z [X is vector; Y, Z are complex] a.MulAndAdd(X, Y, Z), computes: a := X * Y + Z [X, Y, Z are vectors] a.MulAndAdd(X, Y, xyScale, Z), computes: a := X * Y * xyScale + Z [X, Y, Z are vectors; xyScale is scalar] a.MulAndAdd(X, Y, xyScale, Z), computes: a := X * Y * xyScale + Z [X, Y, Z are vectors; xyScale is complex] a.MulAndAdd(X, Y, Z, zScale), computes: a := X * Y + Z * zScale [X, Y, Z are vectors; zScale is scalar] a.MulAndAdd(X, Y, Z, zScale), computes: a := X * Y + Z * zScale [X, Y, Z are vectors; zScale is complex] a.MulAndAdd(X, Y, Z), computes: a := X * Y + Z [X, Y are vectors; Z is scalar] a.MulAndAdd(X, Y, Z), computes: a := X * Y + Z [X, Y are vectors; Z is complex] a.MulAndSub(X, Y, Z), computes: a := X * Y - Z [X, Y, Z are vectors] a.MulAndSub(X, Y, xyScale, Z), computes: a := X * Y * xyScale - Z [X, Y, Z are vectors; xyScale is scalar] a.MulAndSub(X, Y, xyScale, Z), computes: a := X * Y * xyScale - Z [X, Y, Z are vectors; xyScale is complex] a.MulAndSub(X, Y, Z, zScale), computes: a := X * Y - Z * zScale [X, Y, Z are vectors; zScale is scalar] a.MulAndSub(X, Y, Z, zScale), computes: a := X * Y - Z * zScale [X, Y, Z are vectors; zScale is complex] a.MulAndSub(X, Y, Z), computes: a := X * Y - Z [X, Y are vectors; Z is scalar] a.MulAndSub(X, Y, Z), computes: a := X * Y - Z [X, Y are vectors; Z is complex] a.DivAndAdd(X, Y, Z), computes: a := X / Y + Z [X, Y, Z are vectors] a.DivAndAdd(X, Y, xyScale, Z), computes: a := X / Y * xyScale + Z [X, Y, Z are vectors; xyScale is scalar] a.DivAndAdd(X, Y, xyScale, Z), computes: a := X / Y * xyScale + Z [X, Y, Z are vectors; xyScale is complex] a.DivAndAdd(X, Y, Z, zScale), computes: a := X / Y + Z * zScale [X, Y, Z are vectors; zScale is scalar] a.DivAndAdd(X, Y, Z, zScale), computes: a := X / Y + Z * zScale [X, Y, Z are vectors; zScale is complex] a.DivAndAdd(X, Y, Z), computes: a := X / Y + Z [X, Y are vectors; Z is scalar] a.DivAndAdd(X, Y, Z), computes: a := X / Y + Z [X, Y are vectors; Z is complex] a.DivAndSub(X, Y, Z), computes: a := X / Y - Z [X, Y, Z are vectors] a.DivAndSub(X, Y, xyScale, Z), computes: a := X / Y * xyScale - Z [X, Y, Z are vectors; xyScale is scalar] a.DivAndSub(X, Y, xyScale, Z), computes: a := X / Y * xyScale - Z [X, Y, Z are vectors; xyScale is complex] a.DivAndSub(X, Y, Z, zScale), computes: a := X / Y - Z * zScale [X, Y, Z are vectors; zScale is scalar] a.DivAndSub(X, Y, Z, zScale), computes: a := X / Y - Z * zScale [X, Y, Z are vectors; zScale is complex] a.DivAndSub(X, Y, Z), computes: a := X / Y - Z [X, Y are vectors; Z is scalar] a.DivAndSub(X, Y, Z), computes: a := X / Y - Z [X, Y are vectors; Z is complex] a.AddScaled(X, xScale, Y, yScale), computes: a := X * xScale + Y * yScale [X, Y are vectors; xScale, yScale are scalars] a.AddScaled(X, xScale, Y, yScale), computes: a := X * xScale + Y * yScale [X, Y are vectors; xScale, yScale are complex] a.AddScaledSqr(X, xScale, Y, yScale), computes: a := (X * xScale + Y * yScale)^2 [X, Y are vectors; xScale, yScale are scalars] a.AddScaledSqr(X, xScale, Y, yScale), computes: a := (X * xScale + Y * yScale)^2 [X, Y are vectors; xScale, yScale are complex] a.SqrAddScaled(X, xScale, Y, yScale), computes: a := X^2 * xScale + Y^2 * yScale [X, Y are vectors; xScale, yScale are scalars] a.SqrAddScaled(X, xScale, Y, yScale), computes: a := X^2 * xScale + Y^2 * yScale [X, Y are vectors; xScale, yScale are complex] a.AddScaled(X, xScale, Y, yScale, Z, zScale), computes: a := X * xScale + Y * yScale + Z * zScale [X, Y, Z are vectors; xScale, yScale, zScale are scalars] a.AddScaled(X, xScale, Y, yScale, Z, zScale), computes: a := X * xScale + Y * yScale + Z * zScale [X, Y, Z are vectors; xScale, yScale, zScale are complex] a.AddScaledC(X, xScale, Y, yScale, Z), computes: a := X * xScale + Y * yScale + Z [X, Y are vectors; xScale, yScale, Z are scalars] a.AddScaledC(X, xScale, Y, yScale, Z), computes: a := X * xScale + Y * yScale + Z [X, Y are vectors; xScale, yScale, Z are complex] a.SubScaled(X, xScale, Y, yScale, Z, zScale), computes: a := X * xScale - Y * yScale - Z * zScale [X, Y, Z are vectors; xScale, yScale, zScale are scalars] a.SubScaled(X, xScale, Y, yScale, Z, zScale), computes: a := X * xScale - Y * yScale - Z * zScale [X, Y, Z are vectors; xScale, yScale, zScale are complex] a.SubScaledC(X, xScale, Y, yScale, Z), computes: a := X * xScale - Y * yScale - Z [X, Y are vectors; xScale, yScale, Z are scalars] a.SubScaledC(X, xScale, Y, yScale, Z), computes: a := X * xScale - Y * yScale - Z [X, Y are vectors; xScale, yScale, Z are complex] a.Mul(X, Y, Z), computes: a := X * Y * Z [X, Y, Z are vectors] - Special case: when Z = X, computes: a := X^2 * Y a.Mul(X, Y, Z), computes: a := X * Y * Z [X, Y are vectors; Z is scalar] - Special case: when Y = X, computes: a := X^2 * Z a.Mul(X, Y, Z), computes: a := X * Y * Z [X, Y are vectors; Z is complex] - Special case: when Y = X, computes: a := X^2 * Z a.Divide(X, Y, Z), computes: a := X / (Y * Z) [X, Y, Z are vectors] - Special case: when Z = Y, computes: a := X / Y^2 a.DivideC(X, Y, Z), computes: a := X / (Y * Z) [X, Y are vectors; Z is scalar] a.DivideC(X, Y, Z), computes: a := X / (Y * Z) [X, Y are vectors; Z is complex] a.MulAndDiv(X, Y, xyScale, Z), computes: a := X * Y * xyScale / Z [X, Y, Z are vectors; xyScale is scalar] - Special case: when Y = X, computes: a := X^2 * xyScale / Z a.MulAndDiv(X, Y, xyScale, Z), computes: a := X * Y * xyScale / Z [X, Y, Z are vectors; xyScale is complex] - Special case: when Y = X, computes: a := X^2 * xyScale / Z a.MulAndDiv(X, Y, Z), computes: a := X * Y / Z [X, Y are vectors; Z is scalar] a.MulAndDiv(X, Y, Z), computes: a := X * Y / Z [X, Y are vectors; Z is complex] a.Divide(X, Y, Z), computes: a := X / (Y * Z) [X is scalar; Y, Z are vectors] a.Divide(X, Y, Z), computes: a := X / (Y * Z) [X is complex; Y, Z are vectors] a.AddAndMul(X, xScale, Y, yScale, Z, zScale), computes: a := (X * xScale + Y * yScale) * Z * zScale [X, Y, Z are vectors; xScale, yScale, zScale are scalars] - Special case: when Z = X, computes: a := (X * xScale + Y * yScale) * X * zScale = X^2 * xScale + X * Y * yScale a.AddAndMul(X, xScale, Y, yScale, Z, zScale), computes: a := (X * xScale + Y * yScale) * Z * zScale [X, Y, Z are vectors; xScale, yScale, zScale are complex] - Special case: when Z = X, computes: a := (X * xScale + Y * yScale) * X * zScale = X^2 * xScale + X * Y * yScale a.AddAndMul(X, xScale, Y, yScale, Z), computes: a := (X * xScale + Y * yScale) * Z [X, Y are vectors; xScale, yScale, Z are scalars] a.AddAndMul(X, xScale, Y, yScale, Z), computes: a := (X * xScale + Y * yScale) * Z [X, Y are vectors; xScale, yScale, Z are complex] a.AddAndMul(X, xScale, Y, Z, zScale), computes: a := (X * xScale + Y) * Z * zScale [X, Z are vectors; xScale, Y, zScale are scalars] a.AddAndMul(X, xScale, Y, Z, zScale), computes: a := (X * xScale + Y) * Z * zScale [X, Z are vectors; xScale, Y, zScale are complex] a.AddAndMul(X, xScale, Y, Z), computes: a := (X * xScale + Y) * Z [X is vector; xScale, Y, Z are scalars] a.AddAndMul(X, xScale, Y, Z), computes: a := (X * xScale + Y) * Z [X is vector; xScale, Y, Z are complex] a.SubAndMul(X, xScale, Y, yScale, Z, zScale), computes: a := (X * xScale - Y * yScale) * Z * zScale [X, Y, Z are vectors; xScale, yScale, zScale are scalars] a.SubAndMul(X, xScale, Y, yScale, Z, zScale), computes: a := (X * xScale - Y * yScale) * Z * zScale [X, Y, Z are vectors; xScale, yScale, zScale are complex] a.SubAndMul(X, xScale, Y, yScale, Z), computes: a := (X * xScale - Y * yScale) * Z [X, Y are vectors; xScale, yScale, Z are scalars] a.SubAndMul(X, xScale, Y, yScale, Z), computes: a := (X * xScale - Y * yScale) * Z [X, Y are vectors; xScale, yScale, Z are complex] a.SubAndMul(X, xScale, Y, Z, zScale), computes: a := (X * xScale - Y) * Z * zScale [X, Z are vectors; xScale, Y, zScale are scalars] a.SubAndMul(X, xScale, Y, Z, zScale), computes: a := (X * xScale - Y) * Z * zScale [X, Z are vectors; xScale, Y, zScale are complex] a.SubAndMul(X, xScale, Y, Z), computes: a := (X * xScale - Y) * Z [X is vector; xScale, Y, Z are scalars] a.SubAndMul(X, xScale, Y, Z), computes: a := (X * xScale - Y) * Z [X is vector; xScale, Y, Z are complex] a.MulAndAdd(X, Y, xyScale, Z, zScale), computes: a := X * Y * xyScale + Z * zScale [X, Y, Z are vectors; xyScale, zScale are scalars] - Special case: when Y = X, computes: a := X^2 * xyScale + Z * zScale a.MulAndAdd(X, Y, xyScale, Z, zScale), computes: a := X * Y * xyScale + Z * zScale [X, Y, Z are vectors; xyScale, zScale are complex] - Special case: when Y = X, computes: a := X^2 * xyScale + Z * zScale a.MulAndAdd(X, Y, xyScale, Z), computes: a := X * Y * xyScale + Z [X, Y are vectors; xyScale, Z are scalars] - Special case: when Y = X, computes: a := X^2 * xyScale + Z a.MulAndAdd(X, Y, xyScale, Z), computes: a := X * Y * xyScale + Z [X, Y are vectors; xyScale, Z are complex] - Special case: when Y = X, computes: a := X^2 * xyScale + Z a.MulAndAdd(X, Y, Z), computes: a := X * Y + Z [X is vector; Y, Z are scalars] a.MulAndAdd(X, Y, Z), computes: a := X * Y + Z [X is vector; Y, Z are complex] a.MulAndSub(X, Y, xyScale, Z, zScale), computes: a := X * Y * xyScale - Z * zScale [X, Y, Z are vectors; xyScale, zScale are scalars] a.MulAndSub(X, Y, xyScale, Z, zScale), computes: a := X * Y * xyScale - Z * zScale [X, Y, Z are vectors; xyScale, zScale are complex] a.MulAndSub(X, Y, xyScale, Z), computes: a := X * Y * xyScale - Z [X, Y are vectors; xyScale, Z are scalars] a.MulAndSub(X, Y, xyScale, Z), computes: a := X * Y * xyScale - Z [X, Y are vectors; xyScale, Z are complex] a.MulAndSub(X, Y, Z, zScale), computes: a := X * Y - Z * zScale [X, Z are vectors; Y, zScale are scalars] a.MulAndSub(X, Y, Z, zScale), computes: a := X * Y - Z * zScale [X, Z are vectors; Y, zScale are complex] a.DivAndAdd(X, Y, xyScale, Z, zScale), computes: a := (X / Y) * xyScale + Z * zScale [X, Y, Z are vectors; xyScale, zScale are scalars] - Special case: when Y = Z, computes: a := (X / Z) * xyScale + Z * zScale a.DivAndAdd(X, Y, xyScale, Z, zScale), computes: a := (X / Y) * xyScale + Z * zScale [X, Y, Z are vectors; xyScale, zScale are complex] - Special case: when Y = Z, computes: a := (X / Z) * xyScale + Z * zScale a.DivAndAdd(X, Y, xyScale, Z), computes: a := (X / Y) * xyScale + Z [X, Y are vectors; xyScale, Z are scalars] a.DivAndAdd(X, Y, xyScale, Z), computes: a := (X / Y) * xyScale + Z [X, Y are vectors; xyScale, Z are complex] a.DivAndSub(X, Y, xyScale, Z, zScale), computes: a := (X / Y) * xyScale - Z * zScale [X, Y, Z are vectors; xyScale, zScale are scalars] a.DivAndSub(X, Y, xyScale, Z, zScale), computes: a := (X / Y) * xyScale - Z * zScale [X, Y, Z are vectors; xyScale, zScale are complex] a.DivAndSub(X, Y, xyScale, Z), computes: a := (X / Y) * xyScale - Z [X, Y are vectors; xyScale, Z are scalars] a.DivAndSub(X, Y, xyScale, Z), computes: a := (X / Y) * xyScale - Z [X, Y are vectors; xyScale, Z are complex] a.CumProduct(Value), computes: a := [IntPower(Value, 0), IntPower(Value, 1), ..., IntPower(Value, n-1)] // Value is real a.CumProduct(Value), computes: a := [IntPower(Value, 0), IntPower(Value, 1), ..., IntPower(Value, n-1)] // Value is complex a.Divide(Vec, Threshold), computes: a = a / max(Vec, Threshold) a.Divide(Vec1, Vec2, Threshold), computes: a = Vec1 / max(Vec2, Threshold) a.Divide(Num, Den), computes: a = Num / Den a.Divide(Vec), computes: a = a / Vec a.DivideBy(RealScalar), computes: a = (RealScalar) / a a.DivideBy(ComplexScalar), computes: a = (ComplexScalar) / a a.DivideBy(RealScalar, Vec), computes: a = (RealScalar) / Vec a.DivideBy(ComplexScalar, Vec), computes: a = (ComplexScalar) / Vec prod := a.DotProd(b), computes: prod = a[0]*b[0] + a[1]*b[1] + ... + a[n-1]*b[n-1] c := a.DotProdc(b), computes: c = a[0]*b[0] + a[1]*b[1] + ... + a[n-1]*b[n-1] (for complex vectors) c := a.DotProdc(b, ConjVec), computes: c = a[0]*conjugate(b[0]) + a[1]*conjugate(b[1]) + ... + a[n-1]*conjugate(b[n-1]) k := a.Kurtosis(AMean, AStdDev), computes kurtosis m := a.Median, computes median a.Median, computes: result = median(a) a.Mul(Vec), computes: a = a * Vec a.Mul(Vec1, Vec2), computes: a = Vec1 * Vec2 a.MaxEvery(Vec), computes: a = max(a, Vec) a.MaxEvery(Vec1, Vec2), computes: a = max(Vec1, Vec2) a.MinEvery(Vec), computes: a = min(a, Vec) a.MinEvery(Vec1, Vec2), computes: a = min(Vec1, Vec2) a.Max, computes: result = max(a) a.Max(out AMax, out AIndex), computes: AMax = max(a) and AIndex = index of max element a.Maxc, computes: result = max(a) (complex) a.MaxMin(AMax, AMin), computes: AMax = max(a) and AMin = min(a) a.MaxMin(AMax, MaxIdx, AMin, MinIdx), computes: AMax = max(a), MaxIdx = index of max(a), AMin = min(a), and MinIdx = index of min(a) a.Mean, computes: result = mean(a) a.Mean(AMean), computes: AMean = mean(a) a.Meanc, computes: result = mean(a) (complex) a.Meanc(AMean), computes: AMean = mean(a) (complex) a.Min, computes: result = min(a) a.Min(AMin, AIndex), computes: AMin = min(a) and AIndex = index of min(a) a.Minc, computes: result = min(a) (complex) a.NormC(b, RelativeError), computes: if RelativeError = false, norm = max(|a[i] - b[i]|); if true, norm = max(|a[i] - b[i]|) / max(|a[i]|) a.NormC, computes: norm = max(|a[i]|) a.NormL1(b, RelativeError), computes: if RelativeError = false, norm = sum(|a[i] - b[i]|); if true, norm = sum(|a[i] - b[i]|) / sum(|a[i]|) a.NormL1, computes: norm = sum(|a[i]|) a.NormL2(b, RelativeError), computes: if RelativeError = false, norm = sqrt(sum((a[i] - b[i])^2)); if true, norm = sqrt(sum((a[i] - b[i])^2)) / sqrt(sum((a[i])^2)) a.NormL2, computes: norm = sqrt(sum((a[i])^2)) a.Offset(ValueScalar), computes: a = a + ValueScalar a.Offset(ComplexScalarScalar), computes: a = a + ComplexScalarScalar a.Range, computes: range = max(a) - min(a) a.Shift(Offset), shifts the elements in vector a by Offset a.Sub(ValueScalar), computes: a = a - ValueScalar a.Sub(ComplexScalarScalar), computes: a = a - ComplexScalarScalar a.Sub(Vec, Scalar), computes: a = Vec - Scalar a.Sub(Vec, ComplexScalarScalar), computes: a = Src - ComplexScalar a.Sub(Vec), computes: a = a - Vec a.Sub(Vec1, Vec2), computes: a = Vec1 - Vec2 a.SubFrom(Scalar), computes: a = Value - a a.SubFrom(ComplexScalarScalar), computes: a = ComplexScalarScalar - a a.SubFrom(Scalar, Vec), computes: a = Scalar - Vec a.SubFrom(ComplexScalarScalar, Vec), computes: a = ComplexScalarScalar - Vec a.SumOfSquares, computes sum of squares a.Skewness(AMean, AStdDev), computes skewness with amean and astdDev given a.AutoCorrBiased(b, Lags), computes: a = biased autocorrelation of b (using 1/n normalization) for lags 0 to Lags-1 a.AutoCorrNormal(b, Lags), computes: a = normal autocorrelation of b for lags 0 to Lags-1 a.AutoCorrUnBiased(b, Lags), computes: a = unbiased autocorrelation of b for lags 0 to Lags-1 a.Concat(Src), computes: a = concatenation of the vectors in Src a.Convolve(X, H), computes: a = convolution of X and H a.Copy(Vec1, Vec2), computes: a = concatenation of Vec1 and Vec2 a.CrossCorr(Vec1, Vec2, HiLag, LoLag), computes: a = cross-correlation of Vec1 and Vec2 for lags from LoLag to HiLag a.CumSum, computes: a = cumulative sum of a a.CumSum(Vec), computes: a = cumulative sum of Vec a.DCT, computes: a = DCT(a) a.DCT(Vec), computes: a = DCT(Vec) a.Diag(Mtx, k), computes: a = kth diagonal of Mtx a.Difference(Lag), computes: a = difference of a with lag Lag a.Difference(Vec, Lag), computes: a = difference of Vec with lag Lag a.DownSample(Src, Factor, Phase), computes: a = downsample(Src) by taking every Factor-th sample starting at offset Phase a.Equal(Vec, Tolerance), computes: result = true if |a[i] - Vec[i]| <= Tolerance for all i a.Equal(Vec, Tolerance, Compare), computes: result = true if a equals Vec using Compare with tolerance Tolerance a.FFT(ConjugateExtend), computes: a = FFT(a) a.FFT(Vec, ConjugateExtend), computes: a = FFT(Vec) a.FFTFromReal, computes: a = FFT of a (treating a as real) a.FFTFromReal(Vec), computes: a = FFT of Vec (treating Vec as real) a.Hilbert(Vec, method), computes: a = Hilbert transform of Vec a.IDCT, computes: a = inverse DCT of a a.IDCT(Vec), computes: a = inverse DCT of Vec a.IFFT(NoScale), computes: a = inverse FFT of a a.IFFT(Vec, NoScale), computes: a = inverse FFT of Vec a.IFFTToReal(NoScale), computes: a = inverse FFT (complex-to-real) of a a.IFFTToReal(Vec, NoScale), computes: a = inverse FFT (complex-to-real) of Vec a.Integrate(Init), computes: a = integration of a using initial conditions from Init a.Integrate(Vec, Init), computes: a = integration of Vec using initial conditions from Init a.Concat(Src), computes: a = concatenation of all vectors in Src a.Convolve(X, H), computes: a = convolution of X and H a.Copy(Vec1, Vec2), computes: a = concatenation of Vec1 and Vec2 a.CrossCorr(Vec1, Vec2, HiLag, LoLag a.Kron(Vec1, Vec2), computes: a := [for each element v in Vec1, concatenate the products v*Vec2] a.Norm(Vec), computes: a := [|Vec[0]|^2, |Vec[1]|^2, ...] (i.e. the power spectrum of Vec) a.PixelDownSample(Width, Y), computes: a := downsampled version of Y to Width pixels (optionally also downsampling X to NX if provided) a.PrimeNumbers(n), computes: a := list of all prime numbers less than n a.Ramp, computes: a := [0, 1, 2, 3, ...] a.Ramp(Offset, Step: double), computes: a := [Offset + k*Step] for k = 0, 1, 2, ... a.Ramp(Offset, Step: TCplx), computes: a := [Offset + k*Step] for k = 0, 1, 2, ... (complex version) a.Resize(Src, Len, ZeroIt), computes: a := resized copy of Src to length Len (if ZeroIt is true, extra elements are set to zero) a.Resize(Len, ZeroIt), computes: a := resized version of a to length Len (if ZeroIt is true, extra elements are set to zero) a.Reverse, computes: a := reverse(a) a.Reverse(Vec), computes: a := reverse(Vec) a.Rotate(Offset), computes: a := cyclically shifted version of a by Offset positions a.Rotate(Src, Offset), computes: a := cyclically shifted version of Src by Offset positions a.SetDouble(AComplex, A), computes: a := vector with values from array A; if AComplex is true, A is interpreted as interleaved real and imaginary parts a.SetInteger(AComplex, A), computes: a := vector with integer values from array A; if AComplex is true, A is interpreted as interleaved real and imaginary parts a.SetSingle(AComplex, A), computes: a := vector with single-precision values from array A; if AComplex is true, A is interpreted as interleaved real and imaginary parts a.SetIt(AComplex, A), computes: a := vector with values from array A; if AComplex is true, A is interpreted as interleaved real and imaginary parts a.SetIt(A), computes: a := vector with values from array A (real) a.SetCplx(A), computes: a := vector with complex values from array A a.SetSubIndex(Src, BeginIndex, EndIndex), computes: a becomes a subvector view of Src from BeginIndex to EndIndex a.SetSubRange(Src), computes: a becomes a subvector view of all of Src a.SetSubRange(Src, Index, Len), computes: a becomes a subvector view of Src starting at Index with length Len a.SetSubRangeLevel(Src, Index, Len), computes: a becomes a subvector view of Src starting at Index with length Len (and pushes the previous range onto a stack) a.Shift(Offset), computes: a = a shifted by Offset positions a.Shift(Src, Offset), computes: a = Src shifted by Offset positions a.SizeFromArray(Src) [TCplxArray], computes: set a.Length to length of Src and a.Complex = true a.SizeFromArray(Src) [TDoubleArray], computes: set a.Length to length of Src and a.Complex = false a.SizeFromArray(Src) [TSingleArray], computes: set a.Length to length of Src and a.Complex = false a.SizeFromArray(Src) [TIntegerArray], computes: set a.Length to length of Src and a.Complex = false a.SizeFromArray(Src) [TSmallIntArray], computes: set a.Length to length of Src and a.Complex = false a.SizeFromArray(Src) [TByteArray], computes: set a.Length to length of Src and a.Complex = false a.Size(ALength, aFloatPrecision), computes: a.Length = ALength with the specified floating-point precision (a.Complex = false) a.Size(ALength, aFloatPrecisionRef), computes: a.Length = ALength using precision from aFloatPrecisionRef (a.Complex = false) a.SortAscend, computes: a = a sorted in ascending order a.SortDescend, computes: a = a sorted in descending order a.Split(Dst), computes: split a into parts stored in the array Dst a.Split(Dst, DstSize), computes: split a into parts with sizes specified by DstSize and store them in Dst a.Split(Vec1, Offset, Vec2), computes: split a at position Offset into two vectors, with the first part in Vec1 and the second in Vec2 a.TensorProd(Mtx, Vec, MtxType, Operation), computes: a = tensor product of matrix Mtx and vector Vec (right product) a.TensorProd(Vec, Mtx, MtxType, Operation), computes: a = tensor product of vector Vec and matrix Mtx (left product) a.UpSample(Src, Factor, Phase), computes: a = upsampled version of Src by inserting (Factor - 1) zeros between samples, starting at Phase a.ZScore, computes: a = (a - mean(a)) / standard_deviation(a) a.ZScore(Src), computes: a = (Src - mean(Src)) / standard_deviation(Src) a.ValuesToStrings(dstList, Align, ReFormat, ImFormat, Headers), computes: writes the values of a to the string list dstList using the specified formatting a.ValuesToStrings(dstList, ListIndex, Index, Len, Align, ReFormat, ImFormat, Headers), computes: writes a subset of a (from Index for Len elements) to dstList starting at ListIndex with formatting a.StringsToValues(aList), computes: reads vector values from the string list aList and sets a accordingly y.AddProduct(x,z); method only, computes, y[i]:= y[i] + x[i]*z[i]; y.Mul(x); computes y := y*x; y.Mul(x,z); computes y := x*z; Most functions defined on Vector also defined for Matrix: aMatrix.Sin(bMatrix); For VectorInt and TVecInt and also for MatrixInt and TMtxInt where applicable the following is defined: a.CountInRange(LowValue, HighValue), computes: number of values where LowValue < Value[i] < HighValue [LowValue, HighValue are integers; precision is prInt32] a.DisableSubrange, prevents: calls to SetSubRange a.EnableSubrange, enables: calls to SetSubRange a.DisableSelect, prevents: calls to Select a.EnableSelect, enables: calls to Select a.First, returns: first integer element in Values array a.Last, returns: last integer element in Values array a.SizeFromArray(Src), sets: Length of vector to match Src array [Src is TCplxArray] a.SizeFromArray(Src), sets: Length of vector to match Src array [Src is TDoubleArray] a.SizeFromArray(Src), sets: Length of vector to match Src array [Src is TSingleArray] a.SizeFromArray(Src), sets: Length of vector to match Src array [Src is TIntegerArray] a.SizeFromArray(Src), sets: Length of vector to match Src array [Src is TSmallIntArray] a.SizeFromArray(Src), sets: Length of vector to match Src array [Src is Math387.TByteArray] a.SizeToArray(Dst), sizes: Dst array to match vector length [Dst is TCplxArray] a.SizeToArray(Dst), sizes: Dst array to match vector length [Dst is TDoubleArray] a.SizeToArray(Dst), sizes: Dst array to match vector length [Dst is TSingleArray] a.SizeToArray(Dst), sizes: Dst array to match vector length [Dst is TIntegerArray] a.SizeToArray(Dst), sizes: Dst array to match vector length [Dst is Math387.TWordArray] a.SizeToArray(Dst), sizes: Dst array to match vector length [Dst is TSmallIntArray] a.SizeToArray(Dst), sizes: Dst array to match vector length [Dst is Math387.TByteArray] a.SelectAll, resets: any defined selection a.SetFullRange, resets: any defined subrange a.SetFullRangeLevel, resets: last defined subrange and pops subrange stack a.SetSubIndex(BeginIndex, EndIndex), defines: subarray from BeginIndex to EndIndex [BeginIndex, EndIndex are integers] a.SetSubRange(Index, Len), defines: subarray from Index to Index+Len-1 [Index, Len are integers] a.SetSubRangeLevel(Index, Len), defines: subarray from Index to Index+Len-1 and pushes previous subranges to stack [Index, Len are integers] a.SetSubRange(Src), defines: calling vector to view same memory as Src [Src is TMtxVecInt] a.SetSubRange(Src, Index, Len), defines: subarray of Src from Index to Index+Len-1 [Src is TMtxVecInt; Index, Len are integers] a.SetSubRangeLevel(Src, Index, Len), defines: subarray of Src from Index to Index+Len-1 and pushes previous subranges to stack [Src is TMtxVecInt; Index, Len are integers] a.SetSubIndex(Src, BeginIndex, EndIndex), defines: subarray of Src from BeginIndex to EndIndex [Src is TMtxVecInt; BeginIndex, EndIndex are integers] a.SetSubRange, resets: subarray size to full size (same as SetFullRange) a.Clear, sets: vector size to zero a.CondDisable, saves: current ConditionCheck value and sets it to false a.CondEnable, restores: ConditionCheck to value before CondDisable a.Pin, pins: object memory (CLR only) a.UnPin, unpins: object memory (CLR only) a.Concat(Src), concatenates: array of TVecInt objects into calling object [Src is array of TVecInt] a.Concat(Index, Src), concatenates: array of TVecInt objects into calling object starting at Index [Index is integer; Src is array of TVecInt] a.Distinct(Src), stores: distinct values from Src into calling object [Src is TMtxVecInt] a.Abs(), computes: absolute values of all elements in-place a.Abs(Src), computes: absolute values of Src elements [Src is TMtxVecInt] a.BinaryAnd(Src1, Src2), computes: binary "and" of Src1 and Src2 elements [Src1, Src2 are TMtxVecInt] a.BinaryAnd(Src), computes: binary "and" of Src and Self elements [Src is TMtxVecInt] a.BinaryAnd(Value), computes: binary "and" of Value and Self elements [Value is integer] a.BinaryAnd(Src, Value), computes: binary "and" of Src and Value [Src is TMtxVecInt; Value is integer] a.BinaryOr(Src1, Src2), computes: binary "or" of Src1 and Src2 elements [Src1, Src2 are TMtxVecInt] a.BinaryOr(Src), computes: binary "or" of Src and Self elements [Src is TMtxVecInt] a.BinaryOr(Value), computes: binary "or" of Value and Self elements [Value is integer] a.BinaryOr(Src, Value), computes: binary "or" of Src and Value [Src is TMtxVecInt; Value is integer] a.BinaryXor(Value), computes: binary "xor" of Value and Self elements [Value is integer] a.BinaryXor(Src, Value), computes: binary "xor" of Src and Value [Src is TMtxVecInt; Value is integer] a.BinaryXor(Src1, Src2), computes: binary "xor" of Src1 and Src2 elements [Src1, Src2 are TMtxVecInt] a.BinaryXor(Src), computes: binary "xor" of Src and Self elements [Src is TMtxVecInt] a.BitShiftLeft(Bits), computes: binary shift left by Bits for all elements [Bits is integer] a.BitShiftLeft(Src, Bits), computes: binary shift left by Bits for Src elements [Src is TMtxVecInt; Bits is integer] a.BitShiftRight(Bits), computes: binary shift right by Bits for all elements (sign preserved) [Bits is integer] a.BitShiftRight(Src, Bits), computes: binary shift right by Bits for Src elements (sign preserved) [Src is TMtxVecInt; Bits is integer] a.BitShift(Bits), computes: binary shift left (positive Bits) or right (negative Bits) for all elements (sign preserved for right) [Bits is integer] a.BitShift(Src, Bits), computes: binary shift left (positive Bits) or right (negative Bits) for Src elements (sign preserved for right) [Src is TMtxVecInt; Bits is integer] a.BitPack(Src), computes: packed bit storage from Src (non-zero to 1) [Src is TVecInt; precision set to prInt32] a.BitUnpack(Src, dstPrecision), computes: unpacked bit storage from Src (bit <> 0 to 1) [Src is TVecInt; dstPrecision is TIntPrecision, default prInt32] a.BinaryNot(), computes: binary "not" of all elements in-place a.BinaryNot(Src), computes: binary "not" of Src elements [Src is TMtxVecInt] a.LogicalNot(), computes: logical "not" of all elements in-place a.LogicalNot(Src), computes: logical "not" of Src elements [Src is TMtxVecInt] a.LoadFromStream(SrcStream), reads: object from stream (CLR) [SrcStream is Stream] a.SaveToStream(DstStream), writes: object to stream (CLR) [DstStream is Stream] a.LoadFromStream(SrcStream), reads: object from stream (non-CLR) [SrcStream is TStream] a.SaveToStream(DstStream), writes: object to stream (non-CLR) [DstStream is TStream] a.CopyFromArray(Src, Rounding), copies: values from Src array with rounding [Src is TCplxArray; Rounding is TRounding] a.CopyFromArray(Src), copies: values from Src array [Src is Math387.TWordArray] a.CopyFromArray(Src, Rounding), copies: values from Src array with rounding [Src is TDoubleArray; Rounding is TRounding] a.CopyFromArray(Src, Rounding), copies: values from Src array with rounding [Src is TSingleArray; Rounding is TRounding] a.CopyFromArray(Src), copies: values from Src array [Src is TIntegerArray] a.CopyFromArray(Src), copies: values from Src array [Src is TSmallIntArray] a.CopyFromArray(Src), copies: values from Src array [Src is Math387.TByteArray] a.CopyToArray(Dst), copies: values to Dst array as double precision [Dst is TCplxArray] a.CopyToArray(Dst), copies: values to Dst array [Dst is TDoubleArray] a.CopyToArray(Dst), copies: values to Dst array as single precision [Dst is TSingleArray] a.CopyToArray(Dst), copies: values to Dst array as 4-byte signed integers [Dst is TIntegerArray] a.CopyToArray(Dst), copies: values to Dst array as 2-byte signed integers [Dst is TSmallIntArray] a.CopyToArray(Dst), copies: values to Dst array as 2-byte unsigned integers [Dst is Math387.TWordArray] a.CopyToArray(Dst), copies: values to Dst array as 1-byte unsigned integers [Dst is Math387.TByteArray] a.BinarySearch(X), returns: index of last matched element X using binary search (-1 if not found) [X is Integer; data must be sorted ascending] a.BinarySearch(X, XIndex), returns: True if X found, False with closest index in XIndex using binary search [X is Integer; XIndex is var integer; data must be sorted ascending] a.Find(X), returns: index of last matched element X (-1 if not found) [X is integer] a.FindAndSplit(a, op, b, MaskVec, NotMaskVec), splits: a into MaskVec (where a op b is True) and NotMaskVec (where False), stores mask (1 for True, 0 for False) [a, b are TMtxVec; op is string '<', '>', '>=', '<=', '=', '<>'; MaskVec, NotMaskVec are TVec] a.FindAndSplit(a, op, b, MaskVec, NotMaskVec), splits: a into MaskVec (where a op b is True) and NotMaskVec (where False), stores mask (1 for True, 0 for False) [a is TMtxVec; b is TCplx; op is string '<', '>', '>=', '<=', '=', '<>'; MaskVec, NotMaskVec are TVec] a.FindAndSplit(a, op, b, MaskVec, NotMaskVec), splits: a into MaskVec (where a op b is True) and NotMaskVec (where False), stores mask (1 for True, 0 for False) [a is TMtxVec; b is double; op is string '<', '>', '>=', '<=', '=', '<>'; MaskVec, NotMaskVec are TVec] a.FindIndexes(a, op, b), fills: indexes where a op b is True [a is TMtxVec; b is TCplx; op is string '<', '>', '>=', '<=', '=', '<>'] a.FindIndexes(a, op, b), fills: indexes where a op b is True [a is TMtxVec; b is double; op is string '<', '>', '>=', '<=', '=', '<>'] a.FindIndexes(a, op, b), fills: indexes where a op b is True [a, b are TMtxVec; op is string '<', '>', '>=', '<=', '=', '<>'] a.FindMask(a, op, b), stores: mask (1 where a op b is True, 0 where False) [a is TMtxVec; b is TCplx; op is string '<', '>', '>=', '<=', '=', '<>'] a.FindMask(a, op, b), stores: mask (1 where a op b is True, 0 where False) [a is TMtxVec; b is double; op is string '<', '>', '>=', '<=', '=', '<>'] a.FindMask(a, op, b), stores: mask (1 where a op b is True, 0 where False) [a, b are TMtxVec; op is string '<', '>', '>=', '<=', '=', '<>'] a.FindIndexes(a, op, b), fills: indexes where a op b is True [a is TMtxVecInt; b is integer; op is string '<', '>', '>=', '<=', '=', '<>'] a.FindIndexes(a, op, b), fills: indexes where a op b is True [a, b are TMtxVecInt; op is string '<', '>', '>=', '<=', '=', '<>'] a.FindIndexesAndLength(a, op, b), returns: count of indexes where a op b is True [a is TMtxVecInt; b is integer; op is string '<', '>', '>=', '<=', '=', '<>'] a.FindIndexesAndLength(a, op, b), returns: count of indexes where a op b is True [a, b are TMtxVecInt; op is string '<', '>', '>=', '<=', '=', '<>'] a.FindMask(a, op, b), stores: mask (1 where a op b is True, 0 where False) [a is TMtxVecInt; b is integer; op is string '<', '>', '>=', '<=', '=', '<>'] a.FindMask(a, op, b), stores: mask (1 where a op b is True, 0 where False) [a, b are TMtxVecInt; op is string '<', '>', '>=', '<=', '=', '<>'] a.FindAndGather(a, op, b, Indexes), fills: elements and indexes where a op b is True [a is TMtxVecInt; b is integer; op is string '<', '>', '>=', '<=', '=', '<>'; Indexes is TVecInt, optional] a.FindAndGather(a, op, b, Indexes), fills: elements and indexes where a op b is True [a, b are TMtxVecInt; op is string '<', '>', '>=', '<=', '=', '<>'; Indexes is TVecInt, optional] a.GetCol(Mtx, Col), copies: Col-th column from Mtx to calling vector [Mtx is TMtxInt; Col is integer] a.Gather(X, Indexes, IndexType, Increment, Offset), gathers: X elements into calling vector based on Indexes or Increment/Offset [X is TMtxVecInt; Indexes is TVecInt, optional; IndexType is TIndexType, default indVector; Increment, Offset are integers, default 1, 0] a.GatherByIncr(X, Increment, Offset), gathers: X elements with Increment and Offset [X is TMtxVecInt; Increment, Offset are integers, default 1, 0] a.GatherByIndex(X, Indexes), gathers: X elements specified by Indexes [X is TMtxVecInt; Indexes is TVecInt] a.GatherByMask(X, Mask, MaskNonZeroCount), gathers: X elements where Mask is non-zero [X, Mask are TMtxVecInt; MaskNonZeroCount is integer, default -1] a.ScatterByMask(Src, Mask, allow_resizing), scatters: Src elements to calling vector where Mask is non-zero [Src, Mask are TMtxVecInt; allow_resizing is boolean, default False] a.Scatter(Src, Indexes, IndexType, Increment, Offset), scatters: Src elements to calling vector based on Indexes or Increment/Offset [Src is TMtxVecInt; Indexes is TMtxVecInt, optional; IndexType is TIndexType, default indVector; Increment, Offset are integers, default 1, 0] a.ScatterByIncr(Src, Increment, Offset), scatters: Src elements with Increment and Offset [Src is TMtxVecInt; Increment, Offset are integers, default 1, 0] a.ScatterByIndexes(Src, Indexes), scatters: Src elements to indexes in Indexes [Src, Indexes are TMtxVecInt] a.Diag(Mtx, k), copies: k-th diagonal from Mtx to calling vector (k=0 main, k<0 subdiagonal, k>0 superdiagonal) [Mtx is TMtxInt; k is integer] a.GetRow(Mtx, Row), copies: Row-th row from Mtx to calling vector [Mtx is TMtxInt; Row is integer] a.Add(Src1, Src2), computes: Src1 + Src2 element-wise [Src1, Src2 are TMtxVecInt] a.Add(Src), computes: Self + Src element-wise [Src is TMtxVecInt] a.Add(Src, Value), computes: Src + Value element-wise [Src is TMtxVecInt; Value is integer] a.Add(Value), computes: Self + Value element-wise [Value is integer] a.Subtract(Src1, Src2), computes: Src1 - Src2 element-wise [Src1, Src2 are TMtxVecInt] a.Subtract(Src), computes: Self - Src element-wise [Src is TMtxVecInt] a.Subtract(Src, Value), computes: Src - Value element-wise [Src is TMtxVecInt; Value is integer] a.Subtract(Value), computes: Self - Value element-wise [Value is integer] a.SubtractFrom(Value), computes: Value - Self element-wise [Value is integer] a.SubtractFrom(Value, Src), computes: Value - Src element-wise [Value is integer; Src is TMtxVecInt] a.Multiply(Src1, Src2), computes: Src1 * Src2 element-wise [Src1, Src2 are TMtxVecInt] a.Multiply(Src), computes: Self * Src element-wise [Src is TMtxVecInt] a.Multiply(Src, Value), computes: Src * Value element-wise [Src is TMtxVecInt; Value is integer] a.Multiply(Value), computes: Self * Value element-wise [Value is integer] a.Divide(Num, Den), computes: Num / Den element-wise [Num, Den are TMtxVecInt] a.Divide(Src), computes: Self / Src element-wise [Src is TMtxVecInt] a.Divide(Src, Value), computes: Src / Value element-wise [Src is TMtxVecInt; Value is integer] a.Divide(Value), computes: Self / Value element-wise [Value is integer] a.DivideBy(Value), computes: Value / Self element-wise [Value is integer] a.DivideBy(Value, Src), computes: Value / Src element-wise [Value is integer; Src is TMtxVecInt] a.AddScaled(X, Y, yScale), computes: X + Y * yScale [X, Y are TMtxVecInt; yScale is integer] a.AddScaledSqr(X, Y, yScale), computes: (X + Y * yScale)^2 [X, Y are TMtxVecInt; yScale is integer] - Special case: when yScale = -1, computes: (X - Y)^2 = X^2 - 2XY + Y^2 a.SqrAddScaled(X, Y, yScale), computes: X^2 + Y^2 * yScale [X, Y are TMtxVecInt; yScale is integer] - Special case: when yScale = -1, computes: X^2 - Y^2 a.Add(X, Y, Z), computes: X + Y + Z [X, Y, Z are TMtxVecInt] a.AddScaled(X, Y, Z, zScale), computes: X + Y + Z * zScale [X, Y, Z are TMtxVecInt; zScale is integer] a.AddScaled(X, Y, yScale, Z, zScale), computes: X + Y * yScale + Z * zScale [X, Y, Z are TMtxVecInt; yScale, zScale are integers] a.Add(X, Y, Z), computes: X + Y + Z [X, Y are TMtxVecInt; Z is integer] a.AddScaledC(X, Y, yScale, Z), computes: X + Y * yScale + Z [X, Y are TMtxVecInt; yScale, Z are integers] a.Sub(X, Y, Z), computes: X - Y - Z [X, Y, Z are TMtxVecInt] a.SubScaled(X, Y, yScale, Z, zScale), computes: X - Y * yScale - Z * zScale [X, Y, Z are TMtxVecInt; yScale, zScale are integers] a.SubScaled(X, Y, Z, zScale), computes: X - Y - Z * zScale [X, Y, Z are TMtxVecInt; zScale is integer] a.Sub(X, Y, Z), computes: X - Y - Z [X, Y are TMtxVecInt; Z is integer] a.SubScaledC(X, Y, yScale, Z), computes: X - Y * yScale - Z [X, Y are TMtxVecInt; yScale, Z are integers] a.MulAndDiv(X, Y, Z), computes: X * Y / Z [X, Y, Z are TMtxVecInt] a.AddAndMul(X, Y, Z), computes: (X + Y) * Z [X, Y, Z are TMtxVecInt] a.AddAndMul(X, Y, Z, zScale), computes: (X + Y) * Z * zScale [X, Y, Z are TMtxVecInt; zScale is integer] a.AddAndMul(X, Y, yScale, Z, zScale), computes: (X + Y * yScale) * Z * zScale [X, Y, Z are TMtxVecInt; yScale, zScale are integers] a.AddAndMul(X, Y, Z), computes: (X + Y) * Z [X, Y are TMtxVecInt; Z is integer] a.AddAndMul(X, Y, yScale, Z), computes: (X + Y * yScale) * Z [X, Y are TMtxVecInt; yScale, Z are integers] a.AddAndMul(X, Y, Z, zScale), computes: (X + Y) * Z * zScale [X, Z are TMtxVecInt; Y, zScale are integers] a.AddAndMul(X, xScale, Y, Z), computes: (X * xScale + Y) * Z [X, Z are TMtxVecInt; xScale, Y are integers] a.AddAndMul(X, Y, Z), computes: (X + Y) * Z [X, Z are TMtxVecInt; Y is integer] a.AddAndMul(X, Y, Z), computes: (X + Y) * Z [X is TMtxVecInt; Y, Z are integers] a.SubAndMul(X, Y, Z), computes: (X - Y) * Z [X, Y, Z are TMtxVecInt] a.SubAndMul(X, Y, Z, zScale), computes: (X - Y) * Z * zScale [X, Y, Z are TMtxVecInt; zScale is integer] a.SubAndMul(X, Y, yScale, Z, zScale), computes: (X - Y * yScale) * Z * zScale [X, Y, Z are TMtxVecInt; yScale, zScale are integers] a.SubAndMul(X, Y, Z), computes: (X - Y) * Z [X, Y are TMtxVecInt; Z is integer] a.SubAndMul(X, Y, yScale, Z), computes: (X - Y * yScale) * Z [X, Y are TMtxVecInt; yScale, Z are integers] a.SubAndMul(X, Y, Z, zScale), computes: (X - Y) * Z * zScale [X, Z are TMtxVecInt; Y, zScale are integers] a.SubAndMul(X, xScale, Y, Z), computes: (X * xScale - Y) * Z [X, Z are TMtxVecInt; xScale, Y are integers] a.SubAndMul(X, Y, Z), computes: (X - Y) * Z [X, Z are TMtxVecInt; Y is integer] a.SubAndMul(X, Y, Z), computes: (X - Y) * Z [X is TMtxVecInt; Y, Z are integers] a.MulAndAdd(X, Y, Z), computes: X * Y + Z [X, Y, Z are TMtxVecInt] a.MulAndAdd(X, Y, xyScale, Z), computes: X * Y * xyScale + Z [X, Y, Z are TMtxVecInt; xyScale is integer] a.MulAndAdd(X, Y, Z, zScale), computes: X * Y + Z * zScale [X, Y, Z are TMtxVecInt; zScale is integer] a.MulAndAdd(X, Y, Z), computes: X * Y + Z [X, Y are TMtxVecInt; Z is integer] a.MulAndSub(X, Y, Z), computes: X * Y - Z [X, Y, Z are TMtxVecInt] a.MulAndSub(X, Y, xyScale, Z), computes: X * Y * xyScale - Z [X, Y, Z are TMtxVecInt; xyScale is integer] a.MulAndSub(X, Y, Z, zScale), computes: X * Y - Z * zScale [X, Y, Z are TMtxVecInt; zScale is integer] a.MulAndSub(X, Y, Z), computes: X * Y - Z [X, Y are TMtxVecInt; Z is integer] a.DivAndAdd(X, Y, Z), computes: X / Y + Z [X, Y, Z are TMtxVecInt] a.DivAndAdd(X, Y, xyScale, Z), computes: X / Y * xyScale + Z [X, Y, Z are TMtxVecInt; xyScale is integer] a.DivAndAdd(X, Y, Z, zScale), computes: X / Y + Z * zScale [X, Y, Z are TMtxVecInt; zScale is integer] a.DivAndAdd(X, Y, Z), computes: X / Y + Z [X, Y are TMtxVecInt; Z is integer] a.DivAndSub(X, Y, Z), computes: X / Y - Z [X, Y, Z are TMtxVecInt] a.DivAndSub(X, Y, xyScale, Z), computes: X / Y * xyScale - Z [X, Y, Z are TMtxVecInt; xyScale is integer] a.DivAndSub(X, Y, Z, zScale), computes: X / Y - Z * zScale [X, Y, Z are TMtxVecInt; zScale is integer] a.DivAndSub(X, Y, Z), computes: X / Y - Z [X, Y are TMtxVecInt; Z is integer] a.AddScaled(X, xScale, Y, yScale), computes: X * xScale + Y * yScale [X, Y are TMtxVecInt; xScale, yScale are integers] a.AddScaledSqr(X, xScale, Y, yScale), computes: (X * xScale + Y * yScale)^2 [X, Y are TMtxVecInt; xScale, yScale are integers] a.SqrAddScaled(X, xScale, Y, yScale), computes: X^2 * xScale + Y^2 * yScale [X, Y are TMtxVecInt; xScale, yScale are integers] a.AddScaled(X, xScale, Y, yScale, Z, zScale), computes: X * xScale + Y * yScale + Z * zScale [X, Y, Z are TMtxVecInt; xScale, yScale, zScale are integers] a.AddScaledC(X, xScale, Y, yScale, Z), computes: X * xScale + Y * yScale + Z [X, Y are TMtxVecInt; xScale, yScale, Z are integers] a.SubScaled(X, xScale, Y, yScale, Z, zScale), computes: X * xScale - Y * yScale - Z * zScale [X, Y, Z are TMtxVecInt; xScale, yScale, zScale are integers] a.SubScaledC(X, xScale, Y, yScale, Z), computes: X * xScale - Y * yScale - Z [X, Y are TMtxVecInt; xScale, yScale, Z are integers] a.Mul(X, Y, Z), computes: X * Y * Z [X, Y, Z are TMtxVecInt] - Special case: when Z = X, computes: X^2 * Y a.Mul(X, Y, Z), computes: X * Y * Z [X, Y are TMtxVecInt; Z is integer] - Special case: when Y = X, computes: X^2 * Z a.Divide(X, Y, Z), computes: X / (Y * Z) [X, Y, Z are TMtxVecInt] - Special case: when Z = Y, computes: X / Y^2 a.DivideC(X, Y, Z), computes: X / (Y * Z) [X, Y are TMtxVecInt; Z is integer] a.MulAndDiv(X, Y, xyScale, Z), computes: X * Y * xyScale / Z [X, Y, Z are TMtxVecInt; xyScale is integer] - Special case: when Y = X, computes: X^2 * xyScale / Z a.MulAndDiv(X, Y, Z), computes: X * Y / Z [X, Y are TMtxVecInt; Z is integer] a.Divide(X, Y, Z), computes: X / (Y * Z) [X is integer; Y, Z are TMtxVecInt] a.AddAndMul(X, xScale, Y, yScale, Z, zScale), computes: (X * xScale + Y * yScale) * Z * zScale [X, Y, Z are TMtxVecInt; xScale, yScale, zScale are integers] - Special case: when Z = X, computes: X^2 * xScale + X * Y * yScale a.AddAndMul(X, xScale, Y, yScale, Z), computes: (X * xScale + Y * yScale) * Z [X, Y are TMtxVecInt; xScale, yScale, Z are integers] a.AddAndMul(X, xScale, Y, Z, zScale), computes: (X * xScale + Y) * Z * zScale [X, Z are TMtxVecInt; xScale, Y, zScale are integers] a.AddAndMul(X, xScale, Y, Z), computes: (X * xScale + Y) * Z [X is TMtxVecInt; xScale, Y, Z are integers] a.SubAndMul(X, xScale, Y, yScale, Z, zScale), computes: (X * xScale - Y * yScale) * Z * zScale [X, Y, Z are TMtxVecInt; xScale, yScale, zScale are integers] a.SubAndMul(X, xScale, Y, yScale, Z), computes: (X * xScale - Y * yScale) * Z [X, Y are TMtxVecInt; xScale, yScale, Z are integers] a.SubAndMul(X, xScale, Y, Z, zScale), computes: (X * xScale - Y) * Z * zScale [X, Z are TMtxVecInt; xScale, Y, zScale are integers] a.SubAndMul(X, xScale, Y, Z), computes: (X * xScale - Y) * Z [X is TMtxVecInt; xScale, Y, Z are integers] a.MulAndAdd(X, Y, xyScale, Z, zScale), computes: X * Y * xyScale + Z * zScale [X, Y, Z are TMtxVecInt; xyScale, zScale are integers] - Special case: when Y = X, computes: X^2 * xyScale + Z * zScale a.MulAndAdd(X, Y, xyScale, Z), computes: X * Y * xyScale + Z [X, Y are TMtxVecInt; xyScale, Z are integers] - Special case: when Y = X, computes: X^2 * xyScale + Z a.MulAndAdd(X, Y, Z), computes: X * Y + Z [X is TMtxVecInt; Y, Z are integers] a.MulAndSub(X, Y, xyScale, Z, zScale), computes: X * Y * xyScale - Z * zScale [X, Y, Z are TMtxVecInt; xyScale, zScale are integers] a.MulAndSub(X, Y, xyScale, Z), computes: X * Y * xyScale - Z [X, Y are TMtxVecInt; xyScale, Z are integers] a.MulAndSub(X, Y, Z, zScale), computes: X * Y - Z * zScale [X, Z are TMtxVecInt; Y, zScale are integers] a.DivAndAdd(X, Y, xyScale, Z, zScale), computes: (X / Y) * xyScale + Z * zScale [X, Y, Z are TMtxVecInt; xyScale, zScale are integers] - Special case: when Y = Z, computes: (X / Z) * xyScale + Z * zScale a.DivAndAdd(X, Y, xyScale, Z), computes: (X / Y) * xyScale + Z [X, Y are TMtxVecInt; xyScale, Z are integers] a.DivAndSub(X, Y, xyScale, Z, zScale), computes: (X / Y) * xyScale - Z * zScale [X, Y, Z are TMtxVecInt; xyScale, zScale are integers] a.DivAndSub(X, Y, xyScale, Z), computes: (X / Y) * xyScale - Z [X, Y are TMtxVecInt; xyScale, Z are integers] a.Copy(Src), copies: Src values directly to the calling object [Src is TMtxVecInt] a.Convert(Src, DstIntPrecision), converts: Src values with precision DstIntPrecision to the calling object [Src is TMtxVecInt; DstIntPrecision is TIntPrecision] a.IsEqual(Value), compares: Value with all calling object elements [Value is integer] a.MaxEvery(Vec), computes: max(Self[i], Vec[i]) stored in Self[i] [Vec is TMtxVecInt] a.MaxEvery(Vec1, Vec2), computes: max(Vec1[i], Vec2[i]) stored in Self[i] [Vec1, Vec2 are TMtxVecInt] a.MinEvery(Vec), computes: min(Self[i], Vec[i]) stored in Self[i] [Vec is TMtxVecInt] a.MinEvery(Vec1, Vec2), computes: min(Vec1[i], Vec2[i]) stored in Self[i] [Vec1, Vec2 are TMtxVecInt] a.Max(), computes: max(Self[i]) [Self is TMtxVecInt] a.Min(), computes: min(Self[i]) [Self is TMtxVecInt] a.MaxMin(aMax, aMin), computes: aMax = max(Self[i]), aMin = min(Self[i]) [Self is TMtxVecInt; aMax, aMin are integers] a.MaxMinIdx(aMax, aMaxIdx, aMin, aMinIdx), computes: aMax = max(Self[i]), aMaxIdx = argmax(Self[i]), aMin = min(Self[i]), aMinIdx = argmin(Self[i]) [Self is TMtxVecInt; aMax, aMaxIdx, aMin, aMinIdx are integers] a.Median(MaskSize), computes: median(Self[j]) over window of size MaskSize centered at i, stored in Self[i] [MaskSize is integer] a.Resize(Src, Len, ZeroIt), resizes: calling object to Len, copies Src values, fills remaining with 0 if ZeroIt is True [Src is TVecInt; Len is integer; ZeroIt is boolean] a.Resize(Len, ZeroIt), resizes: calling object to Len, fills remaining with 0 if ZeroIt is True [Len is integer; ZeroIt is boolean] a.RandomRamp(), computes: k stored in Self[k] followed by random shuffle [k is integer index] a.RandomShuffle(), shuffles: Self[i] randomly using Fisher-Yates [Self is TMtxVecInt] a.Ramp(Offset, Step), computes: Offset + k * Step stored in Self[k] [Offset, Step are doubles] a.Rotate(Offset), shifts: Self[i] cyclically by Offset [Offset is integer] a.Rotate(Src, Offset), shifts: Src[i] cyclically by Offset, stored in Self[i] [Src is TMtxVecInt; Offset is integer] a.Reverse(), reverses: Self[i] to Self[Length-1-i] [Self is TMtxVecInt] a.Reverse(Vec), reverses: Vec[i] to Vec[Length-1-i], stored in Self[i] [Vec is TMtxVecInt] a.RemDiv(Src, Value, RemDst), computes: Src[i] / Value stored in Self[i], remainder in RemDst[i] [Src, Value, RemDst are TMtxVecInt] a.RemDiv(Src, Value, RemDst), computes: Src[i] / Value stored in Self[i], remainder in RemDst[i] [Src, RemDst are TMtxVecInt; Value is integer] a.RemDiv(Src, Value, RemDst), computes: Src / Value[i] stored in Self[i], remainder in RemDst[i] [Value, RemDst are TMtxVecInt; Src is integer] a.SetVal(Value), sets: Self[i] = Value [Value is integer] a.Shift(Offset), shifts: Self[i] by Offset, non-cyclic [Offset is integer] a.Shift(Src, Offset), shifts: Src[i] by Offset, non-cyclic, stored in Self[i] [Src is TMtxVecInt; Offset is integer] a.SetZero(), sets: Self[i] = 0 [Self is TMtxVecInt] a.SortAscend(), sorts: Self[i] in ascending order [Self is TMtxVecInt] a.SortDescend(), sorts: Self[i] in descending order [Self is TMtxVecInt] a.Sum(), computes: sum(Self[i]) [Self is TMtxVecInt] a.ThreshBottom(Value), computes: Self[i] = Value if Self[i] < Value, else Self[i] [Value is integer] a.ThreshTop(Value), computes: Self[i] = Value if Self[i] > Value, else Self[i] [Value is integer] a.ThreshAbsLT(Value), computes: Self[i] = Value if abs(Self[i]) < Value, else Self[i] [Value is integer] a.ThreshAbsGT(Value), computes: Self[i] = Value if abs(Self[i]) > Value, else Self[i] [Value is integer] a.ThresholdGT_LT(GTLevel, GTValue, LTLevel, LTValue), computes: Self[i] = GTValue if Self[i] > GTLevel, Self[i] = LTValue if Self[i] < LTLevel, else Self[i] [GTLevel, GTValue, LTLevel, LTValue are integers] a.CumSum(), computes: Self[i] = sum(Self[0] to Self[i]) [Self is TMtxVecInt] a.CumSum(Vec), computes: sum(Vec[0] to Vec[i]) stored in Self[i] [Vec is TMtxVecInt] a.Difference(Lag), computes: Self[i] - Self[i-Lag] stored in Self[i] [Lag is integer] a.Difference(Vec, Lag), computes: Vec[i] - Vec[i-Lag] stored in Self[i] [Vec is TMtxVecInt; Lag is integer] a.IntPrecision property defines internal storage precision. This can be set to: prInt32 (signed 32bit integer), prInt16 (signed 16bit integer (smallInt)) prInt8 (unsigned (!) 8 bit integer, or byte) Precision can also be specified when sizing: a.Size(10, prInt32); a.Size(10, prInt16); To access prInt32 write: a[i] or a.IValues[i] To access elements of prInt16 size: a.SValues[i] To read/write byte size elents: a.BValues[i] Additionally for VectorInt and MatrixInt a full set of overloaded operators is available: +,-, /, *, and, or, xor, not Example: var a,b,c: VectorInt; begin a := a + b xor c; end; Both logical and binary operators do the same job, operating on the entire value bit range: 32bit, 16bit or 8bit. Compound expressions are more computationally efficient, than simple expressions. When possible convert the math expression to compound expression, if the function exists in the list above. Example: a := X*xScalar + Y*yScalar + Z*zScalar; where X, Y, Z are vectors, is to be written as: a := AddScaled(X, xScalar, Y, yScalar, Z, zScalar); Additionally, to call a method is more efficient, than calling a function: a.AddScaled(X, xScalar, Y, yScalar, Z, zScalar); These are specific to Vector: AutoCorrBiased, AutoCorrNormal, AutoCorrUnBiased,Convolve, CrossCorr,Hilbert, CumSum, DCT, IDCT, Difference, DotProd, DotProdc, FFT, FFTFromReal, FFT1DFromReal, IFFTToReal, IFFT, The following functions need a matrix FFT2DFromReal, IFFT2DToReal, IFFT2D,BandedToDense, Cholesky, ConcatHorz, ConcatVert, DenseToBanded, Determinant, Determinantc, Eig, Eye, FlipHor, FlipVer, MtxInv, LowerTriangle, LQRSolve, LUSolve, MeanCols, MeanRows, MtxIntPower, MtxPower, MtxSqrt, Mul, Norm1, NormFro, NormInf, Pascl, Resize, ResizeAndTranspose, Rotate90, SVD, SumCols, SumRows, Toeplitz, Trace, UpperTriangle, VanderMonde, MulDiag, MaxCols, MinCols IFFT1D, FFT1D, FFT2D, IFFT1DToReal To convert Vector/Matrix or VectorInt/MatrixInt to strings, call ValuesToString. The destination is a TStringList object: Dst := TStringList.Create; a.ValuesToStrings(Dst); fulPrintString := Dst.Text; And the reverse: Src := TStringList.Create; a.StringsToValues(Src); To save/load from file (.csv, .txt, .bin extensions are supported): a.SaveToFile(FileName); a.LoadFromFile(FileName); all functions can also be called as methods: a.Sin(b); The "a" will be sized according to "b" and separate call to size is not needed. When using methods, the left side is usually the one which will hold result, unless the result needs more than one value to hold it. Example: a.SinCos(aSin, aCos); Left is the source and in the parameters is the result. All methods on the Vector/Matrix, which has the same names as functions, additionally support operation on indexes to address only the sub-array: a.Copy(b, bIndex, Index, Len); If there are two parameters: a.Copy(c, b, cIndex, bIndex, Index, Len); When working with sub-arrays, the right side must already be sized large enough to hold the result. About Vectorization: Here is an example of vectorization. We start with the scalar function: function MaxwellPDF(x, a: double): double; var xxaa: double; begin if (x >= 0) and (a > 0) then begin xxaa := Sqr(x/a); result := Sqrt(1.0/(PIDIV2*a))*xxaa*Exp(-0.5*xxaa); end else result := NAN; end; The parameters to the function need to be updated procedure MaxwellPDF(const x, a, result: TMtxVec); The parameters are const only to indicate that their pointers may not be overwritten, but object content can be modified. The type TMtxVec means, that either Vector or Matrix types can be passed to the routine when calling it: var xv, av, rv: Vector; xm, am, rm: Matrix; begin xv := [1,2,3,5]; av := [1,2,4,5]; MaxwellPDF(xv, av, rv); xm := [[1,2],[3,5]]; am := [[1,2],[4,5]]; MaxwellPDF(xm, am, rm); The result needs to be sized according to the source data: procedure MaxwellPDF(const x, a, result: TMtxVec); begin result.Size(x); ... end; TMtxVec is not a value based type. For local variables declare vector type. Example: procedure MaxwellPDF(const x, a, result: TMtxVec); var aLocal: Vector; begin result.Size(x); ... end; Alternatively, if localy declared types are to be TVec or TMtx objects, they need an allocation and clean-up that looks like this: var a: TVec; b: TMtx; begin CreateIt(a); CreateIt(b); try ... finally FreeIt(a); FreeIt(b); end; end; TVec/TMtx and TVecInt/TMtxInt need to be passed to separate CreateIt/FreeIt pairs. Each CreateIt/FreeIt, can accept up to 4 params. The params need to be passed to FreeIt in the same order as they were passed to CreateIt. Note that when calling methods: a.Sqr(b); There is no need to size destination object "a" sized separately. This is always done by the method. Use methods, rather than expressions for greater efficiency. User expressions only when greater readability is desired. All procedure parameters point to objects. Objects are never created inside of the procedure. They need to be allocated outside and passed as a parameter to the procedure. This means that even objects holding result need to be declared as const. Handling of if-clauses when vectorizing. First verify, if the patch up loop is really needed or if the code is already producing the required values (often NAN and INF). There are three possible approaches: 1.) Use a patch-up by explicitely using a for-loop a.) The patch-up will allow a fall-through on the main computation: function MaxwellPDF(const x, a, result: TMtxVec); var xxaa: Vector; i: integer; begin result.Size(a); xxaa.Sqr(x/a); result.Sqrt(1.0/(PIDIV2*a))*xxaa*Exp(-0.5*xxaa); for i := 0 to result.Length-1 do //patch-up loop begin if (x[i] >= 0) and (a > 0) then begin //leave unchanged end else result[i] := NAN; end; end; use explicit "for-loop" for a patch-up. It is most flexible. b.) Check if parts of the conditions in the resulting for-loop can be replaced with methods like a.ThreshTop a.ThreshBottom a.ThresholdGT a.ThresholdLT a.ThresholdGT_LT and other Thresh, Threshold variants. 2.) Use mask operations. The following methods are declared for TVecInt and VectorInt: aMask.FindMask(vecA, op, VecB) computes: gathers all elements matching "a op VecB", where op is a string of a comparison operator (>, < ...) aMask.FindMask(vecA, op, scalarB) computes: gathers all elements matching "a op scalarB", where op is a string of a comparison operator (>, < ...) aMask.FindMask(vecA, op, ComplexScalarB) computes: gathers all elements matching "a op ComplexScalarB", where op is a string of a comparison operator (>, < ...) Once we have the mask, we can gather by mask: xVec.GatherByMask(vecA, aMask); This method will store all elements from vecA, for which the mask is set, consecutively in xVec. and also scatter: vecA.ScatterByMask(xVec, aMask); This method assumes that elements in xVec to be scattered are stored consecutively. Use a for-loop to assign only specific indexes. Additional possibility is to use: aMask.FindAndSplit(vecA, op, VecB, gatheredA, gatheredNotA) computes: mask of all elements matching "a op VecB", where op is a string of a comparison operator (>, < ...). gatheredA and gatheredNotA contain elements from vecA, which match the condition. aMask.FindAndSplit(vecA, op, scalarB, gatheredA, gatheredNotA) computes: mask of all elements matching "a op scalarB", where op is a string of a comparison operator (>, < ...), gatheredA and gatheredNotA contain elements from vecA, which match the condition. aMask.FindAndSplit(vecA, op, ComplexScalarB, gatheredA, gatheredNotA) computes: mask of all elements matching "a op ComplexScalarB", where op is a string of a comparison operator (>, < ...), gatheredA and gatheredNotA contain elements from vecA, which match the condition. Example: function MaxwellPDF(const x, a, result: TMtxVec); var xxaa, xTrue, xFalse: Vector; i: integer; aMask: VectorInt; begin result.Size(a); xxaa.Sqr(x/a); result.Sqrt(1.0/(PIDIV2*a))*xxaa*Exp(-0.5*xxaa); aMask.FindAndSplit(x, '>=' 0, xTrue, xFalse); if not (a > 0) then begin xFalse.SetVal(NAN) result.ScatterByMask(xFalse, aMask); end; end; 3.) We do not use vectorized methods at all. When there are only few math operations per comparison operator, use a for-loop, but precompute all constants before entering the loop, if applicable. End Of Patch-Up topic. Using sub-ranges Vector and Matrix have SetSubRange methods. With this method we obtain a view of the data in the original vector without actually copying data. Copy operations negatively affect memory bandwidth usage and slow down the code. The SetSubRange method has two overloads. If you call: 1.) a.SetSubRange(index, Len); a will have view from a[Index ... Index + Len - 1] 2.) a.SetSubRange(b, Index, Len); a will have view from b[Index ... Index + Len - 1] b can be vector or matrix. a can be vector, but also a matrix in a special case, where a.Cols would remain the same during the sub range operation: StartingRowIndexInB := b.Cols*i; a.SetSubRange(b, StartingRowIndexInB, RowRangeCountFromB, b.Cols); results in a matrix with a.Rows equal to RowRangeCountFromB a.Cols equal to b.Cols To restore the previous view and remove the subrange call: a.SetFullRange; Example for how to apply multi-threading MtxVec: Below is an example of how to: 1.) Vectorize 2.) Block Process 3.) Multi-Thread A function. Please study this, I will give you another function to vectorize soon: // function to be threaded, without threads procedure TThreadForm.WithoutThreads(const X, Y, Z, A: TDoubleArray; const xScale, yScale: double; var xRms: double); var i: Integer; begin xRMS := 0; for i := 0 to Length(x)-1 do begin xRMS := xRMS + sqr(X[i]); a[i] := X[i]*xScale + y[i]*yScale + z[i] + x[i]*y[i]; end; xRms := sqrt(xRms/Length(x)) end; // function now threaded, using block processing, vectorized with methods instead of expressions procedure TThreadForm.BlockVectorizedThreadedWithMethods(IdxMin, IdxMax: Integer; const Context: TObjectArray; ThreadingIndex: integer); var sumSquares: double; x,y,z,a,sumOfSqr: TVec; xv,yv,zv,av: Vector; xScale, yScale: double; begin //Context can only be typecasted to TVec or TMTx x := TVec(Context[0]); y := TVec(Context[1]); z := TVec(Context[2]); a := TVec(Context[3]); xScale := TVec(Context[4])[0]; yScale := TVec(Context[4])[1]; sumOfSqr := TVec(Context[5]); sumSquares := 0; // Obtain view of data xv.SetSubRange(x, IdxMin, IdxMax - IdxMin + 1); yv.SetSubRange(y, IdxMin, IdxMax - IdxMin + 1); zv.SetSubRange(z, IdxMin, IdxMax - IdxMin + 1); av.SetSubRange(a, IdxMin, IdxMax - IdxMin + 1); // Initialize block processing on all vectors xv.BlockInit; yv.BlockInit; zv.BlockInit; av.BlockInit; // within block processing loop do not allocate any memory. Declare all vars before. // Local vars to this proced while not xv.BlockEnd do begin // Accumulate sum of squares for the current block sumSquares := sumSquares + xv.SumOfSquares; // For the current block, compute: // a = x * xScale + y * yScale + z + x*y // Using compound operations for efficiency: av.AddScaled(xv, xScale, yv, yScale, zv, 1.0); av.AddProduct(xv,yv); // Advance to the next block xv.BlockNext; yv.BlockNext; zv.BlockNext; av.BlockNext; end; sumOfSqr[ThreadingIndex] := sumSquares; xv.BlockFinish; yv.BlockFinish; zv.BlockFinish; av.BlockFinish; end; procedure TThreadForm.StartThreads; var vx, vy, vz, va, Scalars, sumOfSqr: Vector; xScale, yScale, xRms, refRms: double; vaRef1: Vector; begin Memo1.Lines.Clear; vx.Size(1000000); vx.Ramp; vy.Size(vx); vy.SetVal(1.5); vz.Size(vx); va.Size(vx); xScale := 1.2; yScale := 1.5; //Check for presence of the thread pool if not Assigned(GlobalThreads) then GlobalThreads := TMtxForLoop.Create; GlobalThreads.ThreadCount := Controller.CpuCores; StartTimer; WithoutThreads(vx, vy, vz, va, xScale, yScale, xRms); Memo1.Lines.Add('Original, not threaded time = ' + FormatSample('0.00ms',StopTimer*1000)); refRms := xRms; vaRef1.Copy(va); va.SetZero; Scalars := [xScale, yScale]; SumOfSqr.Size(GlobalThreads.ThreadCount); StartTimer; // Start the threads DoForLoop(0, vx.Length-1, BlockVectorizedThreadedWithMethods, nil, [vx, vy, vz, va, Scalars, sumOfSqr]); // Code execution will not continue until all threads have finished. xRms := sqrt(sumOfSqr.Sum/vx.Length); Memo1.Lines.Add('Block vectorized with methods and threaded = ' + FormatSample('0.00ms',StopTimer*1000)); if not Math387.Equal(xRms, refRms, 0.001) then Math387.ERaise('Not Equal'); if not vaRef1.IsEqual(va, 0.001) then Math387.ERaise('Not Equal'); end; Block processing must be done before it is possible to implement multi-threading to ensure sufficient memory bandwidth. Each CPU core has a separate Cache, but this will only be used, if the data is processed in small enough blocks (up to 1000 elements). When writing code for benchmarks, assume vector length 1000 and valid values test data. Any code will typically run mostly on valid data. Vector length of 1000 is to be used, because block processing can be used to maintain the performance obtained on 1000 long vectors on arbitrary vector length. The length of 1000 is also short enough to fit most of the local var vectors in to CPU cache. CPU Cache is 32KB or 64KB long. 1000 elements for double precision is 8kB This means that there is space for 4 vector temporary vars in CPU cache. Use Math387.StartTimer and Math387.StopTimer to measure time. An example is here: uses Math387, MtxExpr; procedure TMainForm.BenchmarkInverseGaussianPDF; const NUM_ELEMENTS = 1000; NUM_RUNS = 10000; var X, ResultVec, ScalarResult: Vector; Mu, Lambda: double; i, run: integer; ScalarTime, VectorTime: double; begin // Test parameters Mu := 1.0; Lambda := 2.0; // Initialize vectors X.Size(NUM_ELEMENTS); ResultVec.Size(NUM_ELEMENTS); ScalarResult.Size(NUM_ELEMENTS); // Fill X with test data (only from the defined regions. Functions are mostly used for defined regions.) for i := 0 to NUM_ELEMENTS - 1 do X[i] := 1.0 + (i mod 100) * 0.1; // Defined: 1.0, 1.1, ..., 10.9, repeating // Benchmark scalar version StartTimer; for run := 1 to NUM_RUNS do begin for i := 0 to NUM_ELEMENTS - 1 do ScalarResult[i] := InverseGaussianPDF(X[i], Mu, Lambda); end; ScalarTime := StopTimer; // Benchmark vectorized version StartTimer; for run := 1 to NUM_RUNS do begin InverseGaussianPDF(X, Mu, Lambda, ResultVec); end; VectorTime := StopTimer; if not ResultVec.IsEqual(ScalarResult, 1E-5) then ERaise('Problem'); //always include comparison of results with tolerance! if (ResultVec.Find(NAN) >= 0) or (ResultVec.Find(INF) >= 0) then ERaise('Undefined region computation detected!'); // Output results to Memo1 Memo1.Lines.Add('Benchmark Results (for ' + IntToStr(NUM_RUNS) + ' runs):'); Memo1.Lines.Add('Scalar Version: ' + FormatFloat('0ms', ScalarTime*1000)); Memo1.Lines.Add('Vector Version: ' + FormatFloat('0ms', VectorTime*1000)); Memo1.Lines.Add('Speedup (Scalar/Vector): ' + FormatFloat('0.00', ScalarTime / VectorTime) + 'x'); end; Special considerations for C++. 1.) When need to use Vector or Matrix, use sVector and sMatrix instead. They don't need CreateIt/FreeIt, but TVec and TMtx do. They inherit all methods and properties from Vector and Matrix, but provide some additional C++ related behaviour. 2.) Use the CreateIt/FreeIt pattern the same as in Delphi: #include #include #include #include #include TVec* a,b; CreateIt(a,b); try { // ... } __finally { FreeIt(a,b); } Prefer using TVec and TMtx with CreateIt/FreeIt over sVector and sMatrix types for local vars and procedure params. 3.) When accessing elements of sVector,Vector or Matrix, sMatrix by index use () rather than []: av.Values(i) = 0.0; av.Values(i,j) = 1.0; When accessing elements of TVec use: aVec->Values[i] And for TMtx: aMtx->Values[i][j] 4.) Prefer handling of if-clauses with a for-loop based patch-up. Do not use masks. Special considerations for C#: 1.) Use the following pattern for CreateIt/FreeIt: using Dew.Math; using Dew.Math.Units; TVec a1; TVec b1; MtxVec.CreateIt(out a1,out b1); //CreateIt overloads exist for 1 to 4 variables try { //... } finally { MtxVec.FreeIt(ref a1, ref b1); //FreeIt overloads exist for 1 to 4 variables } 2.) Never use Vector or Matrix types for local variables. Always use TVec, TVecInt, TMtx, TMtxInt with Create/FreeIt pattern when vectorizing. You can use Vector/Matrix when readability is more important than performance and explicitely requested. 3.) Prefer handling of if-clauses with a for-loop based patch-up. Do not use masks.