Exemplo n.º 1
0
 /// <summary>
 /// Calculates the infinity norm of the vector.
 /// </summary>
 /// <returns>The maximum absolute value.</returns>
 public override double InfinityNorm()
 {
     return(CommonParallel.Aggregate(0, _storage.ValueCount, i => Math.Abs(_storage.Values[i]), Math.Max, 0d));
 }
Exemplo n.º 2
0
 /// <summary>
 /// Calculates the infinity norm of the vector.
 /// </summary>
 /// <returns>The maximum absolute value.</returns>
 public override double InfinityNorm()
 {
     return(CommonParallel.Aggregate(0, _storage.ValueCount, i => _storage.Values[i].Magnitude, Math.Max, 0f));
 }
Exemplo n.º 3
0
 /// <summary>
 /// Calculates the infinity norm of the vector.
 /// </summary>
 /// <returns>The maximum absolute value.</returns>
 public override double InfinityNorm()
 {
     return(CommonParallel.Aggregate(0, Count, i => Math.Abs(At(i)), Math.Max, 0d));
 }
Exemplo n.º 4
0
 /// <summary>
 /// Calculates the infinity norm of the vector.
 /// </summary>
 /// <returns>The maximum absolute value.</returns>
 public override double InfinityNorm()
 {
     return(CommonParallel.Aggregate(_values, (i, v) => Math.Abs(v), Math.Max, 0f));
 }
Exemplo n.º 5
0
 /// <summary>
 /// Calculates the infinity norm of the vector.
 /// </summary>
 /// <returns>The maximum absolute value.</returns>
 public override double InfinityNorm()
 {
     return(CommonParallel.Aggregate(_values, (i, v) => v.Magnitude, Math.Max, 0d));
 }
Exemplo n.º 6
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.Clear(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]);
                    }
                }
            }
        }
Exemplo n.º 7
0
        internal override void MapIndexedToUnchecked <TU>(VectorStorage <TU> target, Func <int, T, TU> f, Zeros zeros, ExistingData existingData)
        {
            if (target is SparseVectorStorage <TU> sparseTarget)
            {
                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;
            }

            if (target is DenseVectorStorage <TU> denseTarget)
            {
                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);
        }
        /// <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);
            }
        }
Exemplo n.º 9
0
 /// <summary>
 /// Calculates the infinity norm of the vector.
 /// </summary>
 /// <returns>The square root of the sum of the squared values.</returns>
 public override double InfinityNorm()
 {
     return(CommonParallel.Aggregate(0, Count, i => At(i).Magnitude, Math.Max, 0f));
 }
        /// <summary>
        ///     Multiplies two matrices and updates another with the result. <c>c = alpha*op(a)*op(b) + beta*c</c>
        /// </summary>
        /// <param name="transposeA">How to transpose the <paramref name="a matrix.</param>
        /// <param name="transposeB">How to transpose the <paramref name="b matrix.</param>
        /// <param name="alpha">The value to scale <paramref name="a matrix.</param>
        /// <param name="a">The a matrix.</param>
        /// <param name="rowsA">The number of rows in the <paramref name="a matrix.</param>
        /// <param name="columnsA">The number of columns in the <paramref name="a matrix.</param>
        /// <param name="b">The b matrix</param>
        /// <param name="rowsB">The number of rows in the <paramref name="b matrix.</param>
        /// <param name="columnsB">The number of columns in the <paramref name="b matrix.</param>
        /// <param name="beta">The value to scale the <paramref name="c matrix.</param>
        /// <param name="c">The c matrix.</param>
        public virtual 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(nameof(a));
            }

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

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

            if (transposeA != Transpose.DontTranspose)
            {
                var swap = rowsA;
                rowsA    = columnsA;
                columnsA = swap;
            }

            if (transposeB != Transpose.DontTranspose)
            {
                var swap = rowsB;
                rowsB    = columnsB;
                columnsB = swap;
            }

            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 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 (var i = 0; i < columnDataB.Length; i++)
            {
                var column = new double[rowsB];
                GetColumn(transposeB, i, rowsB, columnsB, b, column);
                columnDataB[i] = column;
            }

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

            if (shouldNotParallelize)
            {
                var row = new double[columnsA];
                for (var i = 0; i < rowsA; i++)
                {
                    GetRow(transposeA, i, rowsA, columnsA, a, row);
                    for (var j = 0; j < columnsB; j++)
                    {
                        var    col = columnDataB[j];
                        double sum = 0;
                        for (var 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) =>
                {
                    var row = new double[columnsA];
                    for (var i = u; i < v; i++)
                    {
                        GetRow(transposeA, i, rowsA, columnsA, a, row);
                        for (var j = 0; j < columnsB; j++)
                        {
                            var column = columnDataB[j];
                            double sum = 0;
                            for (var ii = 0; ii < row.Length; ii++)
                            {
                                sum += row[ii] * column[ii];
                            }

                            c[j * rowsA + i] += alpha * sum;
                        }
                    }
                });
            }
        }
        /// <summary>
        ///     Multiples two matrices. <c>result = x * y</c>
        /// </summary>
        /// <param name="x">The x matrix.</param>
        /// <param name="rowsX">The number of rows in the x matrix.</param>
        /// <param name="columnsX">The number of columns in the x matrix.</param>
        /// <param name="y">The y matrix.</param>
        /// <param name="rowsY">The number of rows in the y matrix.</param>
        /// <param name="columnsY">The number of columns in the y matrix.</param>
        /// <param name="result">Where to store the result of the multiplication.</param>
        /// <remarks>
        ///     This is a simplified version of the BLAS GEMM routine with alpha
        ///     set to 1.0 and beta set to 0.0, and x and y are not transposed.
        /// </remarks>
        public virtual void MatrixMultiply(double[] x, int rowsX, int columnsX, double[] y, int rowsY, int columnsY,
                                           double[] result)
        {
            if (x == null)
            {
                throw new ArgumentNullException(nameof(x));
            }

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

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

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

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

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

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

            // handle degenerate cases
            Array.Clear(result, 0, result.Length);

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

            for (var i = 0; i < columnDataB.Length; i++)
            {
                var column = new double[rowsY];
                GetColumn(Transpose.DontTranspose, i, rowsY, columnsY, y, column);
                columnDataB[i] = column;
            }

            var shouldNotParallelize = rowsX + columnsY + columnsX < Control.ParallelizeOrder ||
                                       Control.MaxDegreeOfParallelism < 2;

            if (shouldNotParallelize)
            {
                var row = new double[columnsX];
                for (var i = 0; i < rowsX; i++)
                {
                    GetRow(Transpose.DontTranspose, i, rowsX, columnsX, x, row);
                    for (var j = 0; j < columnsY; j++)
                    {
                        var    col = columnDataB[j];
                        double sum = 0;
                        for (var ii = 0; ii < row.Length; ii++)
                        {
                            sum += row[ii] * col[ii];
                        }

                        result[j * rowsX + i] += 1.0 * sum;
                    }
                }
            }
            else
            {
                CommonParallel.For(0, rowsX, 1, (u, v) =>
                {
                    var row = new double[columnsX];
                    for (var i = u; i < v; i++)
                    {
                        GetRow(Transpose.DontTranspose, i, rowsX, columnsX, x, row);
                        for (var j = 0; j < columnsY; j++)
                        {
                            var column = columnDataB[j];
                            double sum = 0;
                            for (var ii = 0; ii < row.Length; ii++)
                            {
                                sum += row[ii] * column[ii];
                            }

                            result[j * rowsX + i] += 1.0 * sum;
                        }
                    }
                });
            }
        }
Exemplo n.º 12
0
        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;
                        }
                    }
                });
            }
        }
Exemplo n.º 13
0
        static void CacheObliviousMatrixMultiply(double[] matrixA, int shiftArow, int shiftAcol, double[] matrixB, int shiftBrow, int shiftBcol, double[] result, int shiftCrow, int shiftCcol, int m, int n, int k, int constM, int constN, int constK, int level)
        {
            if (m + n <= Control.ParallelizeOrder)
            {
                fixed(double *resultPtr = &result[0])
                fixed(double *aPtr = &matrixA[0])
                fixed(double *bPtr = &matrixB[0])
                {
                    double *a = aPtr + shiftArow;
                    double *c = resultPtr + shiftCrow;

                    for (var m1 = 0; m1 < m; m1++)
                    {
                        for (var n1 = 0; n1 < n; ++n1)
                        {
                            double *b   = bPtr + (n1 + shiftBcol) * constK + shiftBrow;
                            double  sum = 0;
                            for (var k1 = 0; k1 < k; ++k1)
                            {
                                sum += a[((k1 + shiftAcol) * constM)] * b[k1];
                            }

                            c[((n1 + shiftCcol) * constM)] += sum;
                        }
                        a++;
                        c++;
                    }
                }

                return;
            }

            // divide and conquer
            int m2 = m / 2, n2 = n / 2, k2 = k / 2;

            level++;
            if (level <= 2)
            {
                CommonParallel.Invoke(
                    () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k2, constM, constN, constK, level),
                    () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k2, constM, constN, constK, level),
                    () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k2, constM, constN, constK, level),
                    () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k2, constM, constN, constK, level));

                CommonParallel.Invoke(
                    () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k - k2, constM, constN, constK, level),
                    () => CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k - k2, constM, constN, constK, level),
                    () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k - k2, constM, constN, constK, level),
                    () => CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k - k2, constM, constN, constK, level));
            }
            else
            {
                CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k2, constM, constN, constK, level);
                CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k2, constM, constN, constK, level);

                CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow, shiftCcol, m2, n2, k - k2, constM, constN, constK, level);
                CacheObliviousMatrixMultiply(matrixA, shiftArow, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow, shiftCcol + n2, m2, n - n2, k - k2, constM, constN, constK, level);

                CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k2, constM, constN, constK, level);
                CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol, matrixB, shiftBrow, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k2, constM, constN, constK, level);

                CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol, result, shiftCrow + m2, shiftCcol, m - m2, n2, k - k2, constM, constN, constK, level);
                CacheObliviousMatrixMultiply(matrixA, shiftArow + m2, shiftAcol + k2, matrixB, shiftBrow + k2, shiftBcol + n2, result, shiftCrow + m2, shiftCcol + n2, m - m2, n - n2, k - k2, constM, constN, constK, level);
            }
        }
Exemplo n.º 14
0
        /// <summary>
        /// Learns a model that can map the given inputs to the given outputs.
        /// </summary>
        /// <param name="trainer">The learning algorithm.</param>
        /// <param name="numberOfClasses">The number of classes.</param>
        /// <param name="x">The input vectors <paramref name="x"/>.</param>
        /// <param name="y">The expected binary output <paramref name="y"/>.</param>
        /// <param name="weights">The <c>weight</c> of importance for each input vector (if supported by the learning algorithm).</param>
        /// <param name="cancellationToken">The cancellationToken token used to notify the machine that the operation should be canceled.</param>
        /// <exception cref="ArgumentNullException">
        /// <para><paramref name="trainer"/> is <b>null</b>.</para>
        /// <para>-or-</para>
        /// <para><paramref name="x"/> is <b>null</b>.</para>
        /// <para>-or-</para>
        /// <para><paramref name="y"/> is <b>null</b>.</para>
        /// </exception>
        /// <exception cref="ArgumentException">
        /// <para><paramref name="numberOfClasses"/> is less than 2.</para>
        /// <para>-or-</para>
        /// <para>The number of elements in <paramref name="y"/> does not match the number of elements in <paramref name="x"/>.</para>
        /// <para>-or-</para>
        /// <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>
        /// <returns>
        /// The <see cref="OneVsAllSupportVectorMachine"/> learned by this method.
        /// A model that has learned how to produce <paramref name="y"/> given <paramref name="x"/>.
        /// </returns>
        public static OneVsAllSupportVectorMachine Learn(
            ISupportVectorMachineLearning trainer,
            int numberOfClasses,
            IList <float[]> x,
            IList <int> y,
            IList <float> weights,
            CancellationToken cancellationToken)
        {
            if (trainer == null)
            {
                throw new ArgumentNullException(nameof(trainer));
            }

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

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

            if (numberOfClasses < 2)
            {
                throw new ArgumentException("The machine must have at least two classes.", nameof(numberOfClasses));
            }

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

            // create the machines
            SupportVectorMachine[] machines = new SupportVectorMachine[numberOfClasses];

            // train each machine
            int sampleCount = x.Count;

            CommonParallel.For(
                0,
                machines.Length,
                (a, b) =>
            {
                for (int i = a; i < b; i++)
                {
                    bool[] expected = new bool[sampleCount];
                    for (int j = 0; j < sampleCount; j++)
                    {
                        expected[j] = y[j] == i;
                    }

                    machines[i] = SupportVectorMachine.Learn(trainer, x, expected, weights, cancellationToken);
                }
            },
                new ParallelOptions()
            {
                CancellationToken = cancellationToken,
            });

            return(new OneVsAllSupportVectorMachine(machines));
        }