示例#1
0
        /// <summary>
        /// Fills the array <see cref="_x"/> with <see cref="LongLag"/> new unsigned random numbers.
        /// </summary>
        /// <remarks>
        /// Generated random numbers are 32-bit unsigned integers greater than or equal to 0
        /// and less than or equal to <see cref="Int32.MaxValue"/>.
        /// </remarks>
        private void Fill()
        {
            CommonParallel.For(
                0,
                Control.NumberOfParallelWorkerThreads,
                index =>
            {
                // Two loops to avoid costly modulo operations
                for (var j = index; j < ShortLag; j = j + Control.NumberOfParallelWorkerThreads)
                {
                    _x[j] += _x[j + (LongLag - ShortLag)];
                }

                for (var j = ShortLag + index; j < LongLag; j = j + Control.NumberOfParallelWorkerThreads)
                {
                    _x[j] += _x[j - ShortLag - index];
                }
            });
            _i = 0;
        }
示例#2
0
 private static void LRNKernel(int[] axes, int[] strides, float[] xw, float[] yw, int kernelSize)
 {
     CommonParallel.For(
         0,
         axes[0],
         (a, b) =>
     {
         for (; a < b; a++)
         {
             NativeMethods.LRNKernel(
                 xw,
                 yw,
                 kernelSize,
                 a,
                 axes,
                 strides);
         }
     },
         new ParallelOptions());
 }
        public Vector <double> ParallelLoop4096()
        {
            var z = _b;

            for (int i = 0; i < _rounds; i++)
            {
                var aa = ((DenseVectorStorage <double>)_a.Storage).Data;
                var az = ((DenseVectorStorage <double>)z.Storage).Data;
                var ar = new Double[aa.Length];
                CommonParallel.For(0, ar.Length, 4096, (u, v) =>
                {
                    for (int k = u; k < v; k++)
                    {
                        ar[k] = aa[k] + az[k];
                    }
                });
                z = Vector <double> .Build.Dense(ar);
            }
            return(z);
        }
示例#4
0
        static void SamplesUnchecked(System.Random rnd, double[] values, int freedom)
        {
            var standard = new double[values.Length * freedom];

            Normal.SamplesUnchecked(rnd, standard, 0.0, 1.0);
            CommonParallel.For(0, values.Length, 4096, (a, b) =>
            {
                for (int i = a; i < b; i++)
                {
                    int k      = i * freedom;
                    double sum = 0;
                    for (int j = 0; j < freedom; j++)
                    {
                        sum += standard[k + j] * standard[k + j];
                    }

                    values[i] = Math.Sqrt(sum);
                }
            });
        }
        /// <summary>
        /// Returns a negated vector.
        /// </summary>
        /// <returns>The negated vector.</returns>
        /// <remarks>Added as an alternative to the unary negation operator.</remarks>
        public override Vector <Complex> Negate()
        {
            var result = new SparseVector(Count)
            {
                _nonZeroValues  = new Complex[NonZerosCount],
                _nonZeroIndices = new int[NonZerosCount],
                NonZerosCount   = NonZerosCount
            };

            if (NonZerosCount != 0)
            {
                CommonParallel.For(
                    0,
                    NonZerosCount,
                    index => result._nonZeroValues[index] = -_nonZeroValues[index]);
                Buffer.BlockCopy(_nonZeroIndices, 0, result._nonZeroIndices, 0, NonZerosCount * Constants.SizeOfInt);
            }

            return(result);
        }
        /// <summary>
        /// Create a piecewise log-linear interpolation from a set of (x,y) value pairs, sorted ascending by x.
        /// </summary>
        public new static LogLinearInterpolation Interpolate(double[] x, double[] y)
        {
            if (x.Length != y.Length)
            {
                throw new ArgumentException("ArgumentVectorsSameLength");
            }
            if (x.Length < 1)
            {
                throw new ArgumentException(string.Format("ArrayTooSmall"), nameof(x));
            }
            var logy = new double[y.Length];

            CommonParallel.For(0, y.Length, 4096, (a, b) =>
            {
                for (int i = a; i < b; i++)
                {
                    logy[i] = -Math.Log(y[i]);
                }
            });
            return(new LogLinearInterpolation(x, logy));
        }
示例#7
0
        /// <summary>
        /// Radix-2 generic FFT for power-of-two sample vectors (Parallel Version).
        /// </summary>
        /// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
        /// <param name="exponentSign">Fourier series exponent sign.</param>
        /// <exception cref="ArgumentException"/>
        internal static void Radix2Parallel(Complex[] samples, int exponentSign)
        {
            if (!samples.Length.IsPowerOfTwo())
            {
                throw new ArgumentException(Resources.ArgumentPowerOfTwo);
            }

            Radix2Reorder(samples);
            for (var levelSize = 1; levelSize < samples.Length; levelSize *= 2)
            {
                var size = levelSize;

                CommonParallel.For(0, size, (u, v) =>
                {
                    for (int i = u; i < v; i++)
                    {
                        Radix2Step(samples, exponentSign, size, i);
                    }
                });
            }
        }
示例#8
0
        internal override void MapIndexedToUnchecked <TU>(VectorStorage <TU> target, Func <int, T, TU> f, Zeros zeros, ExistingData existingData)
        {
            if (target is DenseVectorStorage <TU> denseTarget)
            {
                CommonParallel.For(0, Data.Length, 4096, (a, b) =>
                {
                    for (int i = a; i < b; i++)
                    {
                        denseTarget.Data[i] = f(i, Data[i]);
                    }
                });
                return;
            }

            // FALL BACK

            for (int i = 0; i < Length; i++)
            {
                target.At(i, f(i, Data[i]));
            }
        }
        /// <summary>
        /// Divides a scalar by each element of the matrix and stores the result in the result matrix.
        /// </summary>
        /// <param name="dividend">The scalar to add.</param>
        /// <param name="result">The matrix to store the result of the division.</param>
        protected override void DoDivideByThis(Complex dividend, Matrix <Complex> result)
        {
            if (result is DiagonalMatrix diagResult)
            {
                var resultData = diagResult._data;
                CommonParallel.For(0, _data.Length, 4096, (a, b) =>
                {
                    for (int i = a; i < b; i++)
                    {
                        resultData[i] = dividend / _data[i];
                    }
                });
                return;
            }

            result.Clear();
            for (int i = 0; i < _data.Length; i++)
            {
                result.At(i, i, dividend / _data[i]);
            }
        }
示例#10
0
        /// <summary>
        /// Computes the modulus for each element of the matrix.
        /// </summary>
        /// <param name="divisor">The divisor to use.</param>
        /// <param name="result">Matrix to store the results in.</param>
        protected override void DoModulus(float divisor, Matrix <float> result)
        {
            var denseResult = result as DenseMatrix;

            if (denseResult == null)
            {
                base.DoModulus(divisor, result);
            }
            else
            {
                if (!ReferenceEquals(this, result))
                {
                    CopyTo(result);
                }

                CommonParallel.For(
                    0,
                    Data.Length,
                    index => denseResult.Data[index] %= divisor);
            }
        }
示例#11
0
        /// <summary>
        /// Subtracts another vector to this vector and stores the result into the result vector.
        /// </summary>
        /// <param name="other">The vector to subtract from this one.</param>
        /// <param name="result">The vector to store the result of the subtraction.</param>
        /// <exception cref="ArgumentNullException">If the other vector is <see langword="null"/>.</exception>
        /// <exception cref="ArgumentNullException">If the result vector is <see langword="null"/>.</exception>
        /// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception>
        /// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception>
        public override void Subtract(Vector <Complex> other, Vector <Complex> result)
        {
            if (result == null)
            {
                throw new ArgumentNullException("result");
            }

            if (Count != other.Count)
            {
                throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
            }

            if (Count != result.Count)
            {
                throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
            }

            if (ReferenceEquals(this, result) || ReferenceEquals(other, result))
            {
                var tmp = Subtract(other);
                tmp.CopyTo(result);
            }
            else
            {
                var rdense = result as DenseVector;
                var odense = other as DenseVector;
                if (rdense != null && odense != null)
                {
                    CopyTo(result);
                    Control.LinearAlgebraProvider.AddVectorToScaledVector(rdense.Data, -Complex.One, odense.Data);
                }
                else
                {
                    CommonParallel.For(
                        0,
                        Data.Length,
                        index => result[index] = Data[index] - other[index]);
                }
            }
        }
示例#12
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SparseVector"/> class with a given size
        /// and each element set to the given value;
        /// </summary>
        /// <param name="size">
        /// the size of the vector.
        /// </param>
        /// <param name="value">
        /// the value to set each element to.
        /// </param>
        /// <exception cref="ArgumentException">
        /// If <paramref name="size"/> is less than one.
        /// </exception>
        public SparseVector(int size, Complex32 value) : this(size)
        {
            if (value == Complex32.Zero)
            {
                // Skip adding values
                return;
            }

            // We already know that this vector is "full", let's allocate all needed memory
            _nonZeroValues  = new Complex32[size];
            _nonZeroIndices = new int[size];
            NonZerosCount   = size;

            CommonParallel.For(
                0,
                Count,
                index =>
            {
                _nonZeroValues[index]  = value;
                _nonZeroIndices[index] = index;
            });
        }
        /// <param name="x">Sample points (N+1), sorted ascending</param>
        /// <param name="y">Sample values (N or N+1) at the corresponding points; intercept, zero order coefficients</param>
        public override void Initialize(double[] x, double[] y)
        {
            if (x.Length != y.Length)
            {
                throw new ArgumentException("ArgumentVectorsSameLength");
            }
            if (x.Length < 1)
            {
                throw new ArgumentException(string.Format("ArrayTooSmall"), nameof(x));
            }
            X = x;
            var logy = new double[y.Length];

            CommonParallel.For(0, y.Length, 4096, (a, b) =>
            {
                for (int i = a; i < b; i++)
                {
                    logy[i] = -Math.Log(y[i]);
                }
            });
            Y = logy;
        }
示例#14
0
        /// <summary>
        /// Conjugates vector and save result to <paramref name="target"/>
        /// </summary>
        /// <param name="target">Target vector</param>
        public override void Conjugate(Vector <Complex32> target)
        {
            if (target == null)
            {
                throw new ArgumentNullException("target");
            }

            if (Count != target.Count)
            {
                throw new ArgumentException(Resources.ArgumentVectorsSameLength, "target");
            }

            if (ReferenceEquals(this, target))
            {
                var tmp = CreateVector(Count);
                Conjugate(tmp);
                tmp.CopyTo(target);
            }

            var otherVector = target as SparseVector;

            if (otherVector == null)
            {
                base.Conjugate(target);
            }
            else
            {
                // Lets copy only needed data. Portion of needed data is determined by NonZerosCount value
                otherVector._nonZeroValues  = new Complex32[NonZerosCount];
                otherVector._nonZeroIndices = new int[NonZerosCount];
                otherVector.NonZerosCount   = NonZerosCount;

                if (NonZerosCount != 0)
                {
                    CommonParallel.For(0, NonZerosCount, index => otherVector._nonZeroValues[index] = _nonZeroValues[index].Conjugate());
                    Buffer.BlockCopy(_nonZeroIndices, 0, otherVector._nonZeroIndices, 0, NonZerosCount * Constants.SizeOfInt);
                }
            }
        }
示例#15
0
        /// <summary>
        /// Create a linear spline interpolation from an unsorted set of (x,y) value pairs.
        /// WARNING: Works in-place and can thus causes the data array to be reordered and modified.
        /// </summary>
        public static TransformedInterpolation InterpolateInplace(
            Func <double, double> transform,
            Func <double, double> transformInverse,
            double[] x,
            double[] y)
        {
            if (x.Length != y.Length)
            {
                throw new ArgumentException("All vectors must have the same dimensionality.");
            }

            Sorting.Sort(x, y);
            CommonParallel.For(0, y.Length, 4096, (a, b) =>
            {
                for (int i = a; i < b; i++)
                {
                    y[i] = transformInverse(y[i]);
                }
            });

            return(new TransformedInterpolation(LinearSpline.InterpolateSorted(x, y), transform));
        }
        internal override void MapSubMatrixIndexedToUnchecked <TU>(MatrixStorage <TU> target, Func <int, int, T, TU> f,
                                                                   int sourceRowIndex, int targetRowIndex, int rowCount,
                                                                   int sourceColumnIndex, int targetColumnIndex, int columnCount,
                                                                   Zeros zeros, ExistingData existingData)
        {
            var denseTarget = target as DenseColumnMajorMatrixStorage <TU>;

            if (denseTarget != null)
            {
                CommonParallel.For(0, columnCount, Math.Max(4096 / rowCount, 32), (a, b) =>
                {
                    for (var j = a; j < b; j++)
                    {
                        var sourceIndex = sourceRowIndex + (j + sourceColumnIndex) * RowCount;
                        var targetIndex = targetRowIndex + (j + targetColumnIndex) * target.RowCount;
                        for (var i = 0; i < rowCount; i++)
                        {
                            denseTarget.Data[targetIndex++] = f(targetRowIndex + i, targetColumnIndex + j,
                                                                Data[sourceIndex++]);
                        }
                    }
                });
                return;
            }

            // TODO: Proper Sparse Implementation

            // FALL BACK

            for (int j = sourceColumnIndex, jj = targetColumnIndex; j < sourceColumnIndex + columnCount; j++, jj++)
            {
                var index = sourceRowIndex + j * RowCount;
                for (var ii = targetRowIndex; ii < targetRowIndex + rowCount; ii++)
                {
                    target.At(ii, jj, f(ii, jj, Data[index++]));
                }
            }
        }
示例#17
0
        /// <summary>
        /// Computes the modulus for each element of the matrix.
        /// </summary>
        /// <param name="divisor">The divisor to use.</param>
        /// <param name="result">Matrix to store the results in.</param>
        protected override void DoModulus(double divisor, Matrix<double> result)
        {
            var denseResult = result as DenseMatrix;
            if (denseResult == null)
            {
                base.DoModulus(divisor, result);
                return;
            }

            if (!ReferenceEquals(this, result))
            {
                CopyTo(result);
            }

            CommonParallel.For(0, _values.Length, (a, b) =>
                {
                    var v = denseResult._values;
                    for (int i = a; i < b; i++)
                    {
                        v[i] %= divisor;
                    }
                });
        }
示例#18
0
        static void SamplesUnchecked(System.Random rnd, int[] values, double lambda, double nu, double z)
        {
            var uniform = rnd.NextDoubles(values.Length);

            CommonParallel.For(0, values.Length, 4096, (a, b) =>
            {
                for (int i = a; i < b; i++)
                {
                    var u   = uniform[i];
                    var p   = 1.0 / z;
                    var cdf = p;
                    var k   = 0;
                    while (u > cdf)
                    {
                        k++;
                        p    = p * lambda / Math.Pow(k, nu);
                        cdf += p;
                    }

                    values[i] = k;
                }
            });
        }
示例#19
0
        /// <summary>
        /// Divides a scalar by each element of the matrix and stores the result in the result matrix.
        /// </summary>
        /// <param name="dividend">The scalar to add.</param>
        /// <param name="result">The matrix to store the result of the division.</param>
        protected override void DoDivideByThis(float dividend, Matrix <float> result)
        {
            var diagResult = result as DiagonalMatrix;

            if (diagResult != null)
            {
                var resultData = diagResult._data;
                CommonParallel.For(0, _data.Length, 4096, (a, b) =>
                {
                    for (int i = a; i < b; i++)
                    {
                        resultData[i] = dividend / _data[i];
                    }
                });
                return;
            }

            result.Clear();
            for (int i = 0; i < _data.Length; i++)
            {
                result.At(i, i, dividend / _data[i]);
            }
        }
示例#20
0
        // FUNCTIONAL COMBINATORS

        internal override void MapToUnchecked <TU>(VectorStorage <TU> target, Func <T, TU> f, Zeros zeros, ExistingData existingData)
        {
            var denseTarget = target as DenseVectorStorage <TU>;

            if (denseTarget != null)
            {
                CommonParallel.For(0, Data.Length, 4096, (a, b) =>
                {
                    for (int i = a; i < b; i++)
                    {
                        denseTarget.Data[i] = f(Data[i]);
                    }
                });
                return;
            }

            // FALL BACK

            for (int i = 0; i < Length; i++)
            {
                target.At(i, f(Data[i]));
            }
        }
示例#21
0
        /// <summary>
        /// Create a linear spline interpolation from a set of (x,y) value pairs, sorted ascendingly by x.
        /// </summary>
        public static TransformedInterpolation InterpolateSorted(
            Func <double, double> transform,
            Func <double, double> transformInverse,
            double[] x,
            double[] y)
        {
            if (x.Length != y.Length)
            {
                throw new ArgumentException(Resource.ArgumentVectorsSameLength);
            }

            var yhat = new double[y.Length];

            CommonParallel.For(0, y.Length, 4096, (a, b) =>
            {
                for (int i = a; i < b; i++)
                {
                    yhat[i] = transformInverse(y[i]);
                }
            });

            return(new TransformedInterpolation(LinearSpline.InterpolateSorted(x, yhat), transform));
        }
        /// <summary>
        /// Naive generic DFT, useful e.g. to verify faster algorithms.
        /// </summary>
        /// <param name="samples">Time-space sample vector.</param>
        /// <param name="exponentSign">Fourier series exponent sign.</param>
        /// <returns>Corresponding frequency-space vector.</returns>
        static void Naive(Complex32[] samples, int exponentSign)
        {
            var w0       = exponentSign * Constants.Pi2 / samples.Length;
            var spectrum = new Complex32[samples.Length];

            CommonParallel.For(0, samples.Length, (u, v) =>
            {
                for (int i = u; i < v; i++)
                {
                    var wk  = w0 * i;
                    var sum = Complex32.Zero;
                    for (var n = 0; n < samples.Length; n++)
                    {
                        var w = n * wk;
                        sum  += samples[n] * new Complex32((float)Math.Cos(w), (float)Math.Sin(w));
                    }

                    spectrum[i] = sum;
                }
            });

            spectrum.Copy(samples);
        }
示例#23
0
        /// <summary>
        /// Naive generic DFT, useful e.g. to verify faster algorithms.
        /// </summary>
        /// <param name="samples">Time-space sample vector.</param>
        /// <param name="exponentSign">Fourier series exponent sign.</param>
        /// <returns>Corresponding frequency-space vector.</returns>
        internal static Complex[] Naive(Complex[] samples, int exponentSign)
        {
            var w0       = exponentSign * Constants.Pi2 / samples.Length;
            var spectrum = new Complex[samples.Length];

            CommonParallel.For(0, samples.Length, (u, v) =>
            {
                for (int i = u; i < v; i++)
                {
                    var wk  = w0 * i;
                    var sum = Complex.Zero;
                    for (var n = 0; n < samples.Length; n++)
                    {
                        var w = n * wk;
                        sum  += samples[n] * new Complex(Math.Cos(w), Math.Sin(w));
                    }

                    spectrum[i] = sum;
                }
            });

            return(spectrum);
        }
示例#24
0
        /// <summary>
        /// Naive generic DHT, useful e.g. to verify faster algorithms.
        /// </summary>
        /// <param name="samples">Time-space sample vector.</param>
        /// <returns>Corresponding frequency-space vector.</returns>
        internal static double[] Naive(double[] samples)
        {
            var w0       = Constants.Pi2 / samples.Length;
            var spectrum = new double[samples.Length];

            CommonParallel.For(0, samples.Length, (u, v) =>
            {
                for (int i = u; i < v; i++)
                {
                    var wk  = w0 * i;
                    var sum = 0.0;
                    for (var n = 0; n < samples.Length; n++)
                    {
                        var w = n * wk;
                        sum  += samples[n] * Constants.Sqrt2 * Math.Cos(w - Constants.PiOver4);
                    }

                    spectrum[i] = sum;
                }
            });

            return(spectrum);
        }
示例#25
0
        public float[] Assign(int startingIndex, int count, IList <IVector <float> > x, float[] result, CancellationToken cancellationToken)
        {
            if (result == null)
            {
                result = new float[x.Count];
            }

            CommonParallel.For(
                0,
                x.Count,
                (a, b) =>
            {
                for (int i = a; i < b; i++)
                {
                    this.Assign(startingIndex, count, x[i], out result[i]);
                }
            },
                new ParallelOptions()
            {
                CancellationToken = cancellationToken,
            });

            return(result);
        }
示例#26
0
        void MapSubMatrixIndexedToUnchecked <TU>(DenseColumnMajorMatrixStorage <TU> target, Func <int, int, T, TU> f,
                                                 int sourceRowIndex, int targetRowIndex, int rowCount,
                                                 int sourceColumnIndex, int targetColumnIndex, int columnCount,
                                                 Zeros zeros, ExistingData existingData)
            where TU : struct, IEquatable <TU>, IFormattable
        {
            var processZeros = zeros == Zeros.Include || !Zero.Equals(f(0, 1, Zero));

            if (existingData == ExistingData.Clear && !processZeros)
            {
                target.ClearUnchecked(targetRowIndex, rowCount, targetColumnIndex, columnCount);
            }

            if (processZeros)
            {
                CommonParallel.For(0, columnCount, Math.Max(4096 / rowCount, 32), (a, b) =>
                {
                    int sourceColumn = sourceColumnIndex + a;
                    int targetColumn = targetColumnIndex + a;
                    for (int j = a; j < b; j++)
                    {
                        int targetIndex = targetRowIndex + (j + targetColumnIndex) * target.RowCount;
                        int sourceRow   = sourceRowIndex;
                        int targetRow   = targetRowIndex;
                        for (int i = 0; i < rowCount; i++)
                        {
                            target.Data[targetIndex++] = f(targetRow++, targetColumn, sourceRow++ == sourceColumn ? Data[sourceColumn] : Zero);
                        }
                        sourceColumn++;
                        targetColumn++;
                    }
                });
            }
            else
            {
                if (sourceRowIndex > sourceColumnIndex && sourceColumnIndex + columnCount > sourceRowIndex)
                {
                    // column by column, but skip resulting zero columns at the beginning

                    int columnInit = sourceRowIndex - sourceColumnIndex;
                    int offset     = (columnInit + targetColumnIndex) * target.RowCount + targetRowIndex;
                    int step       = target.RowCount + 1;
                    int count      = Math.Min(columnCount - columnInit, rowCount);

                    for (int k = 0, j = offset; k < count; j += step, k++)
                    {
                        target.Data[j] = f(targetRowIndex + k, targetColumnIndex + columnInit + k, Data[sourceRowIndex + k]);
                    }
                }
                else if (sourceRowIndex < sourceColumnIndex && sourceRowIndex + rowCount > sourceColumnIndex)
                {
                    // row by row, but skip resulting zero rows at the beginning

                    int rowInit = sourceColumnIndex - sourceRowIndex;
                    int offset  = targetColumnIndex * target.RowCount + rowInit + targetRowIndex;
                    int step    = target.RowCount + 1;
                    int count   = Math.Min(columnCount, rowCount - rowInit);

                    for (int k = 0, j = offset; k < count; j += step, k++)
                    {
                        target.Data[j] = f(targetRowIndex + rowInit + k, targetColumnIndex + k, Data[sourceColumnIndex + k]);
                    }
                }
                else
                {
                    int offset = targetColumnIndex * target.RowCount + targetRowIndex;
                    int step   = target.RowCount + 1;
                    var count  = Math.Min(columnCount, rowCount);

                    for (int k = 0, j = offset; k < count; j += step, k++)
                    {
                        target.Data[j] = f(targetRowIndex + k, targetColumnIndex + k, Data[sourceRowIndex + k]);
                    }
                }
            }
        }
        /// <summary>
        ///     Solves A*X=B for X using a previously QR factored matrix.
        /// </summary>
        /// <param name="q">
        ///     The Q matrix obtained by calling <seecreQRFactor( double[], int, int, double[], double[]).</param>
        /// <param name="r">
        ///     The R matrix obtained by calling <seecreQRFactor( double[], int, int, double[], double[]). </param>
        /// <param name="rowsA">The number of rows in the A matrix.</param>
        /// <param name="columnsA">The number of columns in the A matrix.</param>
        /// <param name="tau">
        ///     Contains additional information on Q. Only used for the native solver
        ///     and can be <c>null</c> for the managed provider.
        /// </param>
        /// <param name="b">The B matrix.</param>
        /// <param name="columnsB">The number of columns of B.</param>
        /// <param name="x">On exit, the solution matrix.</param>
        /// <param name="method">The type of QR factorization to perform. <seealsocreQRMethod</param>
        /// <remarks>Rows must be greater or equal to columns.</remarks>
        public virtual void QRSolveFactored(double[] q, double[] r, int rowsA, int columnsA, double[] tau, double[] b,
                                            int columnsB, double[] x, QRMethod method = QRMethod.Full)
        {
            if (r == null)
            {
                throw new ArgumentNullException(nameof(r));
            }

            if (q == null)
            {
                throw new ArgumentNullException(nameof(q));
            }

            if (b == null)
            {
                throw new ArgumentNullException(nameof(q));
            }

            if (x == null)
            {
                throw new ArgumentNullException(nameof(q));
            }

            if (rowsA < columnsA)
            {
                //throw new ArgumentException(Resources.RowsLessThanColumns);
            }

            int rowsQ, columnsQ, rowsR, columnsR;

            if (method == QRMethod.Full)
            {
                rowsQ    = columnsQ = rowsR = rowsA;
                columnsR = columnsA;
            }
            else
            {
                rowsQ    = rowsA;
                columnsQ = rowsR = columnsR = columnsA;
            }

            if (r.Length != rowsR * columnsR)
            {
                //throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, rowsR*columnsR), nameof(r));
            }

            if (q.Length != rowsQ * columnsQ)
            {
                //throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, rowsQ*columnsQ), nameof(q));
            }

            if (b.Length != rowsA * columnsB)
            {
                //throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, rowsA*columnsB), nameof(b));
            }

            if (x.Length != columnsA * columnsB)
            {
                //throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, columnsA*columnsB), nameof(x));
            }

            var sol = new double[b.Length];

            // Copy B matrix to "sol", so B data will not be changed
            Buffer.BlockCopy(b, 0, sol, 0, b.Length * Constants.SizeOfDouble);

            // Compute Y = transpose(Q)*B
            var column = new double[rowsA];

            for (var j = 0; j < columnsB; j++)
            {
                var jm = j * rowsA;
                Array.Copy(sol, jm, column, 0, rowsA);
                CommonParallel.For(0, columnsA, (u, v) =>
                {
                    for (var i = u; i < v; i++)
                    {
                        var im = i * rowsA;

                        var sum = 0.0;
                        for (var k = 0; k < rowsA; k++)
                        {
                            sum += q[im + k] * column[k];
                        }

                        sol[jm + i] = sum;
                    }
                });
            }

            // Solve R*X = Y;
            for (var k = columnsA - 1; k >= 0; k--)
            {
                var km = k * rowsR;
                for (var j = 0; j < columnsB; j++)
                {
                    sol[j * rowsA + k] /= r[km + k];
                }

                for (var i = 0; i < k; i++)
                {
                    for (var j = 0; j < columnsB; j++)
                    {
                        var jm = j * rowsA;
                        sol[jm + i] -= sol[jm + k] * r[km + i];
                    }
                }
            }

            // Fill result matrix
            for (var col = 0; col < columnsB; col++)
            {
                Array.Copy(sol, col * rowsA, x, col * columnsA, columnsR);
            }
        }
        public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, double alpha, double[] a, int rowsA, int columnsA, double[] b, int rowsB, int columnsB, double beta, double[] c)
        {
            if (a == null)
            {
                throw new ArgumentNullException("a");
            }

            if (b == null)
            {
                throw new ArgumentNullException("b");
            }

            if (c == null)
            {
                throw new ArgumentNullException("c");
            }

            if (transposeA != Transpose.DontTranspose)
            {
                Swap(ref rowsA, ref columnsA);
            }

            if (transposeB != Transpose.DontTranspose)
            {
                Swap(ref rowsB, ref columnsB);
            }

            if (columnsA != rowsB)
            {
                throw new ArgumentOutOfRangeException(String.Format("columnsA ({0}) != rowsB ({1})", columnsA, rowsB));
            }

            if (rowsA * columnsA != a.Length)
            {
                throw new ArgumentOutOfRangeException(String.Format("rowsA ({0}) * columnsA ({1}) != a.Length ({2})", rowsA, columnsA, a.Length));
            }

            if (rowsB * columnsB != b.Length)
            {
                throw new ArgumentOutOfRangeException(String.Format("rowsB ({0}) * columnsB ({1}) != b.Length ({2})", rowsB, columnsB, b.Length));
            }

            if (rowsA * columnsB != c.Length)
            {
                throw new ArgumentOutOfRangeException(String.Format("rowsA ({0}) * columnsB ({1}) != c.Length ({2})", rowsA, columnsB, c.Length));
            }

            // handle the degenerate cases
            if (beta == 0.0)
            {
                Array.Clear(c, 0, c.Length);
            }
            else if (beta != 1.0)
            {
                ScaleArray(beta, c, c);
            }

            if (alpha == 0.0)
            {
                return;
            }

            // Extract column arrays
            var columnDataB = new double[columnsB][];

            for (int i = 0; i < columnDataB.Length; i++)
            {
                columnDataB[i] = GetColumn(transposeB, i, rowsB, columnsB, b);
            }

            var shouldNotParallelize = rowsA + columnsB + columnsA < Control.ParallelizeOrder || Control.MaxDegreeOfParallelism < 2;

            if (shouldNotParallelize)
            {
                for (int i = 0; i < rowsA; i++)
                {
                    var row = GetRow(transposeA, i, rowsA, columnsA, a);
                    for (int j = 0; j < columnsB; j++)
                    {
                        var    col = columnDataB[j];
                        double sum = 0;
                        for (int ii = 0; ii < row.Length; ii++)
                        {
                            sum += row[ii] * col[ii];
                        }

                        c[j * rowsA + i] += alpha * sum;
                    }
                }
            }
            else
            {
                CommonParallel.For(0, rowsA, 1, (u, v) =>
                {
                    for (int i = u; i < v; i++)
                    {
                        // for each row in a
                        var row = GetRow(transposeA, i, rowsA, columnsA, a);
                        for (int j = 0; j < columnsB; j++)
                        {
                            var column = columnDataB[j];
                            double sum = 0;
                            for (int ii = 0; ii < row.Length; ii++)
                            {
                                sum += row[ii] * column[ii];
                            }

                            c[j * rowsA + i] += alpha * sum;
                        }
                    }
                });
            }
        }
示例#29
0
        internal override void MapIndexedToUnchecked <TU>(VectorStorage <TU> target, Func <int, T, TU> f, Zeros zeros, ExistingData existingData)
        {
            var sparseTarget = target as SparseVectorStorage <TU>;

            if (sparseTarget != null)
            {
                var indices = new List <int>();
                var values  = new List <TU>();
                if (zeros == Zeros.Include || !Zero.Equals(f(0, Zero)))
                {
                    int k = 0;
                    for (int i = 0; i < Length; i++)
                    {
                        var item = k < ValueCount && (Indices[k]) == i?f(i, Values[k++]) : f(i, Zero);

                        if (!Zero.Equals(item))
                        {
                            values.Add(item);
                            indices.Add(i);
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < ValueCount; i++)
                    {
                        var item = f(Indices[i], Values[i]);
                        if (!Zero.Equals(item))
                        {
                            values.Add(item);
                            indices.Add(Indices[i]);
                        }
                    }
                }
                sparseTarget.Indices    = indices.ToArray();
                sparseTarget.Values     = values.ToArray();
                sparseTarget.ValueCount = values.Count;
                return;
            }

            var denseTarget = target as DenseVectorStorage <TU>;

            if (denseTarget != null)
            {
                if (existingData == ExistingData.Clear)
                {
                    denseTarget.Clear();
                }

                if (zeros == Zeros.Include || !Zero.Equals(f(0, Zero)))
                {
                    int k = 0;
                    for (int i = 0; i < Length; i++)
                    {
                        denseTarget.Data[i] = k < ValueCount && (Indices[k]) == i
                            ? f(i, Values[k++])
                            : f(i, Zero);
                    }
                }
                else
                {
                    CommonParallel.For(0, ValueCount, 4096, (a, b) =>
                    {
                        for (int i = a; i < b; i++)
                        {
                            denseTarget.Data[Indices[i]] = f(Indices[i], Values[i]);
                        }
                    });
                }
                return;
            }

            // FALL BACK

            base.MapIndexedToUnchecked(target, f, zeros, existingData);
        }
示例#30
0
文件: KMeans.cs 项目: arnavdas88/dnn
        /// <summary>
        /// Learns a <see cref="KMeans"/> model that can map the given inputs to the desired outputs.
        /// </summary>
        /// <param name="k">The number of clusters.</param>
        /// <param name="seeding">The cluster initialization algorithm.</param>
        /// <param name="maxiter">The maximum number of iterations.</param>
        /// <param name="distance">The distance function.</param>
        /// <param name="x">The data points <paramref name="x"/> to clusterize.</param>
        /// <param name="weights">The <c>weight</c> of importance for each data point.</param>
        /// <param name="cancellationToken">The cancellationToken token used to notify the classifier that the operation should be canceled.</param>
        /// <returns>
        /// The <see cref="KMeans"/> clusterizer learned by this method.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <para><paramref name="x"/> is <b>null</b>.</para>
        /// <para>-or-</para>
        /// <para><paramref name="distance"/> is <b>null</b>.</para>
        /// </exception>
        /// <exception cref="ArgumentException">
        /// <para><paramref name="weights"/> is not <b>null</b> and the number of elements in <paramref name="weights"/> does not match the number of elements in <paramref name="x"/>.</para>
        /// </exception>
        public static KMeans Learn(
            int k,
            KMeansSeeding seeding,
            int maxiter,
            IVectorDistance <float, IVector <float>, float> distance,
            IList <IVector <float> > x,
            IList <float> weights,
            CancellationToken cancellationToken)
        {
            if (x == null)
            {
                throw new ArgumentNullException(nameof(x));
            }

            if (weights != null && weights.Count != x.Count)
            {
                throw new ArgumentException("The number of weights must match the number of input vectors.", nameof(weights));
            }

            int sampleCount = x.Count;
            int dimension   = x[0].Length;

            KMeansClusterCollection clusters = new KMeansClusterCollection(k, dimension, distance);

            switch (seeding)
            {
            case KMeansSeeding.KMeansPlusPlus:
                clusters.KMeansPlusPlusSeeding(x, weights, cancellationToken);
                break;

            default:
                clusters.RandomSeeding(x, weights, cancellationToken);
                break;
            }

            float[] counts = new float[k];
            float[] means  = new float[k * dimension];
            object  sync   = new object();

            for (int iter = 0; iter < maxiter; iter++)
            {
                cancellationToken.ThrowIfCancellationRequested();

                // reset means and counts
                if (iter > 0)
                {
                    Vectors.Set(counts.Length, 0.0f, counts, 0);
                    Vectors.Set(means.Length, 0.0f, means, 0);
                }

                // assign vectors to new clusters
                CommonParallel.For(
                    0,
                    sampleCount,
                    (a, b) =>
                {
                    float[] lcounts = new float[counts.Length];
                    float[] lmeans  = new float[means.Length];

                    for (int i = a; i < b; i++)
                    {
                        int index    = clusters.Assign(x[i]);
                        float weight = weights?[i] ?? 1.0f;

                        lcounts[index] += weight;
                        x[i].AddProductC(weight, lmeans, index * dimension);
                    }

                    lock (sync)
                    {
                        Mathematics.Add(lcounts.Length, lcounts, 0, counts, 0);
                        Mathematics.Add(lmeans.Length, lmeans, 0, means, 0);
                    }
                },
                    new ParallelOptions());

                // calculate new centroids
                for (int i = 0, off = 0; i < k; i++, off += dimension)
                {
                    if (counts[i] != 0)
                    {
                        Mathematics.DivC(dimension, means, off, counts[i], clusters[i].Centroid, 0);
                    }
                }
            }

            return(new KMeans(clusters)
            {
                Seeding = seeding,
            });
        }