Esempio n. 1
0
 /// <summary>
 /// Returns the indices of the diagonal entries in the sparse matrix storage.
 /// </summary>
 /// <param name="storage"></param>
 /// <param name="throwOnMissingDiag"></param>
 /// <returns>Indices of the diagonal entries.</returns>
 public static int[] FindDiagonalIndices <T>(this SparseCompressedRowMatrixStorage <T> storage,
                                             bool throwOnMissingDiag = false)
     where T : struct, IEquatable <T>, IFormattable
 {
     return(Helper.FindDiagonalIndices(storage.RowCount, storage.RowPointers,
                                       storage.ColumnIndices, throwOnMissingDiag));
 }
        public static SparseCompressedRowMatrixStorage <T> OfColumnArrays(T[][] data)
        {
            var storage       = new SparseCompressedRowMatrixStorage <T>(data[0].Length, data.Length);
            var rowPointers   = storage.RowPointers;
            var columnIndices = new List <int>();
            var values        = new List <T>();

            for (int row = 0; row < storage.RowCount; row++)
            {
                rowPointers[row] = values.Count;
                for (int col = 0; col < storage.ColumnCount; col++)
                {
                    T x = data[col][row];
                    if (!Zero.Equals(x))
                    {
                        values.Add(x);
                        columnIndices.Add(col);
                    }
                }
            }

            rowPointers[storage.RowCount] = values.Count;
            storage.ColumnIndices         = columnIndices.ToArray();
            storage.Values = values.ToArray();
            return(storage);
        }
Esempio n. 3
0
        /// <summary>
        /// Permutes the columns of a matrix in CSR format, B = A * P, where P represents
        /// a permutation matrix.
        /// </summary>
        /// <param name="storage">Input storage.</param>
        /// <param name="target">Target storage.</param>
        /// <param name="perm">Permutation array of length ColumnCount.</param>
        /// <param name="copy">Copy matrix values (not needed if used 'in place').</param>
        /// <param name="sorted">Ensure that column indices will be sorted.</param>
        /// <remarks>
        /// The permutation matrix P maps column j into column perm(j), i.e.,
        /// on return a(i,j) in the original matrix becomes a(i,perm(j)) in the
        /// output matrix.
        ///
        /// Notes:
        ///
        /// 1. This routine is in place: aj, bj can be the same.
        /// 2. If the matrix is initially sorted (by increasing column number)
        ///    then bx, bi, bj may not be on return.
        /// </remarks>
        public static void PermuteColumns <T>(this SparseCompressedRowMatrixStorage <T> storage,
                                              SparseCompressedRowMatrixStorage <T> target, int[] perm, bool copy = false,
                                              bool sorted = true)
            where T : struct, IEquatable <T>, IFormattable
        {
            int n = storage.RowCount;

            var ax = storage.Values;
            var ap = storage.RowPointers;
            var ai = storage.ColumnIndices;

            var bx = target.Values;
            var bp = target.RowPointers;
            var bi = target.ColumnIndices;

            int i, nnz = ap[n];

            for (i = 0; i < nnz; i++)
            {
                bi[i] = perm[ai[i]];
            }

            if (copy)
            {
                Array.Copy(ax, bx, nnz);
                Array.Copy(ap, bp, n);
            }

            if (sorted)
            {
                Helper.SortIndices(storage.RowCount, bx, bp, bi);
            }
        }
        public static SparseCompressedRowMatrixStorage <T> OfArray(T[,] array)
        {
            var storage       = new SparseCompressedRowMatrixStorage <T>(array.GetLength(0), array.GetLength(1));
            var rowPointers   = storage.RowPointers;
            var columnIndices = new List <int>();
            var values        = new List <T>();

            for (int row = 0; row < storage.RowCount; row++)
            {
                rowPointers[row] = values.Count;
                for (int col = 0; col < storage.ColumnCount; col++)
                {
                    if (!Zero.Equals(array[row, col]))
                    {
                        values.Add(array[row, col]);
                        columnIndices.Add(col);
                    }
                }
            }

            rowPointers[storage.RowCount] = values.Count;
            storage.ColumnIndices         = columnIndices.ToArray();
            storage.Values = values.ToArray();
            return(storage);
        }
        public static SparseCompressedRowMatrixStorage <T> OfRowMajorEnumerable(int rows, int columns, IEnumerable <T> data)
        {
            var storage       = new SparseCompressedRowMatrixStorage <T>(rows, columns);
            var rowPointers   = storage.RowPointers;
            var columnIndices = new List <int>();
            var values        = new List <T>();

            using (var iterator = data.GetEnumerator())
            {
                for (int row = 0; row < rows; row++)
                {
                    rowPointers[row] = values.Count;
                    for (int col = 0; col < columns; col++)
                    {
                        iterator.MoveNext();
                        if (!Zero.Equals(iterator.Current))
                        {
                            values.Add(iterator.Current);
                            columnIndices.Add(col);
                        }
                    }
                }
            }

            rowPointers[rows]     = values.Count;
            storage.ColumnIndices = columnIndices.ToArray();
            storage.Values        = values.ToArray();
            return(storage);
        }
Esempio n. 6
0
        /// <summary>
        /// Extract row from storage.
        /// </summary>
        /// <param name="storage"></param>
        /// <param name="rowIndex">The row index to extract.</param>
        /// <param name="target">Dense array.</param>
        /// <returns>The requested row.</returns>
        public static void GetRow <T>(this SparseCompressedRowMatrixStorage <T> storage,
                                      int rowIndex, T[] target, ExistingData existingData = ExistingData.Clear)
            where T : struct, IEquatable <T>, IFormattable
        {
            if (target.Length != storage.ColumnCount)
            {
                throw new Exception();
            }

            if (existingData == ExistingData.Clear)
            {
                Array.Clear(target, 0, target.Length);
            }

            var ap = storage.RowPointers;
            var ai = storage.ColumnIndices;
            var ax = storage.Values;

            int rowEnd = ap[rowIndex + 1];

            for (int k = ap[rowIndex]; k < rowEnd; k++)
            {
                target[ai[k]] = ax[k];
            }
        }
        public static SparseCompressedRowMatrixStorage <T> OfColumnMajorList(int rows, int columns, IList <T> data)
        {
            if (rows * columns != data.Count)
            {
                throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
            }

            var storage       = new SparseCompressedRowMatrixStorage <T>(rows, columns);
            var rowPointers   = storage.RowPointers;
            var columnIndices = new List <int>();
            var values        = new List <T>();

            for (int row = 0; row < rows; row++)
            {
                rowPointers[row] = values.Count;
                for (int col = 0; col < columns; col++)
                {
                    var item = data[row + (col * rows)];
                    if (!Zero.Equals(item))
                    {
                        values.Add(item);
                        columnIndices.Add(col);
                    }
                }
            }

            rowPointers[rows]     = values.Count;
            storage.ColumnIndices = columnIndices.ToArray();
            storage.Values        = values.ToArray();
            return(storage);
        }
        // INITIALIZATION

        public static SparseCompressedRowMatrixStorage <T> OfMatrix(MatrixStorage <T> matrix)
        {
            var storage = new SparseCompressedRowMatrixStorage <T>(matrix.RowCount, matrix.ColumnCount);

            matrix.CopyToUnchecked(storage, skipClearing: true);
            return(storage);
        }
        public static SparseCompressedRowMatrixStorage <T> OfInit(int rows, int columns, Func <int, int, T> init)
        {
            var storage       = new SparseCompressedRowMatrixStorage <T>(rows, columns);
            var rowPointers   = storage.RowPointers;
            var columnIndices = new List <int>();
            var values        = new List <T>();

            for (int row = 0; row < rows; row++)
            {
                rowPointers[row] = values.Count;
                for (int col = 0; col < columns; col++)
                {
                    var x = init(row, col);
                    if (!Zero.Equals(x))
                    {
                        values.Add(x);
                        columnIndices.Add(col);
                    }
                }
            }

            rowPointers[rows]     = values.Count;
            storage.ColumnIndices = columnIndices.ToArray();
            storage.Values        = values.ToArray();
            return(storage);
        }
        public static SparseCompressedRowMatrixStorage <T> OfColumnVectors(VectorStorage <T>[] data)
        {
            var storage       = new SparseCompressedRowMatrixStorage <T>(data[0].Length, data.Length);
            var rowPointers   = storage.RowPointers;
            var columnIndices = new List <int>();
            var values        = new List <T>();

            // TODO PERF: Optimize for sparse and dense cases
            for (int row = 0; row < storage.RowCount; row++)
            {
                rowPointers[row] = values.Count;
                for (int col = 0; col < storage.ColumnCount; col++)
                {
                    var x = data[col].At(row);
                    if (!Zero.Equals(x))
                    {
                        values.Add(x);
                        columnIndices.Add(col);
                    }
                }
            }

            rowPointers[storage.RowCount] = values.Count;
            storage.ColumnIndices         = columnIndices.ToArray();
            storage.Values = values.ToArray();
            return(storage);
        }
        public static SparseCompressedRowMatrixStorage <T> OfColumnEnumerables(int rows, int columns, IEnumerable <IEnumerable <T> > data)
        {
            var trows = new List <Tuple <int, T> > [rows];

            using (var columnIterator = data.GetEnumerator())
            {
                for (int column = 0; column < columns; column++)
                {
                    if (!columnIterator.MoveNext())
                    {
                        throw new ArgumentOutOfRangeException("data", string.Format(Resources.ArgumentArrayWrongLength, columns));
                    }
                    using (var rowIterator = columnIterator.Current.GetEnumerator())
                    {
                        for (int row = 0; row < rows; row++)
                        {
                            if (!rowIterator.MoveNext())
                            {
                                throw new ArgumentOutOfRangeException("data", string.Format(Resources.ArgumentArrayWrongLength, rows));
                            }
                            if (!Zero.Equals(rowIterator.Current))
                            {
                                var trow = trows[row] ?? (trows[row] = new List <Tuple <int, T> >());
                                trow.Add(new Tuple <int, T>(column, rowIterator.Current));
                            }
                        }
                    }
                }
            }

            var storage       = new SparseCompressedRowMatrixStorage <T>(rows, columns);
            var rowPointers   = storage.RowPointers;
            var columnIndices = new List <int>();
            var values        = new List <T>();

            int index = 0;

            for (int row = 0; row < rows; row++)
            {
                rowPointers[row] = index;
                var trow = trows[row];
                if (trow != null)
                {
                    trow.Sort();
                    foreach (var item in trow)
                    {
                        values.Add(item.Item2);
                        columnIndices.Add(item.Item1);
                        index++;
                    }
                }
            }

            rowPointers[rows]     = values.Count;
            storage.ColumnIndices = columnIndices.ToArray();
            storage.Values        = values.ToArray();
            return(storage);
        }
Esempio n. 12
0
        void CopyToUnchecked(SparseCompressedRowMatrixStorage <T> target, ExistingData existingData)
        {
            if (existingData == ExistingData.Clear)
            {
                target.Clear();
            }

            for (int i = 0; i < Data.Length; i++)
            {
                target.At(i, i, Data[i]);
            }
        }
Esempio n. 13
0
        void CopyToUnchecked(SparseCompressedRowMatrixStorage <T> target, bool skipClearing)
        {
            if (!skipClearing)
            {
                target.Clear();
            }

            for (int i = 0; i < Data.Length; i++)
            {
                target.At(i, i, Data[i]);
            }
        }
        void CopyToUnchecked(SparseCompressedRowMatrixStorage <T> target)
        {
            target.Values        = new T[ValueCount];
            target.ColumnIndices = new int[ValueCount];

            if (ValueCount != 0)
            {
                Array.Copy(Values, target.Values, ValueCount);
                Buffer.BlockCopy(ColumnIndices, 0, target.ColumnIndices, 0, ValueCount * Constants.SizeOfInt);
                Buffer.BlockCopy(RowPointers, 0, target.RowPointers, 0, (RowCount + 1) * Constants.SizeOfInt);
            }
        }
        public static SparseCompressedRowMatrixStorage <T> OfRowEnumerables <TRow>(int rows, int columns, IEnumerable <TRow> data)
        // NOTE: flexible typing to 'backport' generic covariance.
            where TRow : IEnumerable <T>
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            var storage       = new SparseCompressedRowMatrixStorage <T>(rows, columns);
            var rowPointers   = storage.RowPointers;
            var columnIndices = new List <int>();
            var values        = new List <T>();

            using (var rowIterator = data.GetEnumerator())
            {
                for (int row = 0; row < rows; row++)
                {
                    if (!rowIterator.MoveNext())
                    {
                        throw new ArgumentOutOfRangeException("data", string.Format(Resources.ArgumentArrayWrongLength, rows));
                    }
                    rowPointers[row] = values.Count;
                    using (var columnIterator = rowIterator.Current.GetEnumerator())
                    {
                        for (int col = 0; col < columns; col++)
                        {
                            if (!columnIterator.MoveNext())
                            {
                                throw new ArgumentOutOfRangeException("data", string.Format(Resources.ArgumentArrayWrongLength, columns));
                            }
                            if (!Zero.Equals(columnIterator.Current))
                            {
                                values.Add(columnIterator.Current);
                                columnIndices.Add(col);
                            }
                        }
                        if (columnIterator.MoveNext())
                        {
                            throw new ArgumentOutOfRangeException("data", string.Format(Resources.ArgumentArrayWrongLength, columns));
                        }
                    }
                }
                if (rowIterator.MoveNext())
                {
                    throw new ArgumentOutOfRangeException("data", string.Format(Resources.ArgumentArrayWrongLength, rows));
                }
            }
            storage.ColumnIndices = columnIndices.ToArray();
            storage.Values        = values.ToArray();
            storage.ValueCount    = values.Count;
            return(storage);
        }
        public static SparseCompressedRowMatrixStorage <T> OfRowEnumerables(int rows, int columns, IEnumerable <IEnumerable <T> > data)
        {
            var storage       = new SparseCompressedRowMatrixStorage <T>(rows, columns);
            var rowPointers   = storage.RowPointers;
            var columnIndices = new List <int>();
            var values        = new List <T>();

            using (var rowIterator = data.GetEnumerator())
            {
                for (int row = 0; row < rows; row++)
                {
                    if (!rowIterator.MoveNext())
                    {
                        throw new ArgumentOutOfRangeException("data", string.Format(Resources.ArgumentArrayWrongLength, rows));
                    }
                    rowPointers[row] = values.Count;
                    using (var columnIterator = rowIterator.Current.GetEnumerator())
                    {
                        for (int col = 0; col < columns; col++)
                        {
                            if (!columnIterator.MoveNext())
                            {
                                throw new ArgumentOutOfRangeException("data", string.Format(Resources.ArgumentArrayWrongLength, columns));
                            }
                            if (!Zero.Equals(columnIterator.Current))
                            {
                                values.Add(columnIterator.Current);
                                columnIndices.Add(col);
                            }
                        }
                        if (columnIterator.MoveNext())
                        {
                            throw new ArgumentOutOfRangeException("data", string.Format(Resources.ArgumentArrayWrongLength, columns));
                        }
                    }
                }
                if (rowIterator.MoveNext())
                {
                    throw new ArgumentOutOfRangeException("data", string.Format(Resources.ArgumentArrayWrongLength, rows));
                }
            }

            rowPointers[rows]     = values.Count;
            storage.ColumnIndices = columnIndices.ToArray();
            storage.Values        = values.ToArray();
            return(storage);
        }
        void CopySubMatrixTo(SparseCompressedRowMatrixStorage <T> target,
                             int sourceRowIndex, int targetRowIndex, int rowCount,
                             int sourceColumnIndex, int targetColumnIndex, int columnCount,
                             bool skipClearing)
        {
            if (target == null)
            {
                throw new ArgumentNullException("target");
            }

            ValidateSubMatrixRange(target,
                                   sourceRowIndex, targetRowIndex, rowCount,
                                   sourceColumnIndex, targetColumnIndex, columnCount);

            if (!skipClearing)
            {
                target.Clear(targetRowIndex, rowCount, targetColumnIndex, columnCount);
            }

            if (sourceRowIndex == sourceColumnIndex)
            {
                for (var i = 0; i < Math.Min(columnCount, rowCount); i++)
                {
                    target.At(i + targetRowIndex, i + targetColumnIndex, Data[sourceRowIndex + i]);
                }
            }
            else if (sourceRowIndex > sourceColumnIndex && sourceColumnIndex + columnCount > sourceRowIndex)
            {
                // column by column, but skip resulting zero columns at the beginning
                int columnInit = sourceRowIndex - sourceColumnIndex;
                for (var i = 0; i < Math.Min(columnCount - columnInit, rowCount); i++)
                {
                    target.At(i + targetRowIndex, columnInit + i + targetColumnIndex, Data[sourceRowIndex + i]);
                }
            }
            else if (sourceRowIndex < sourceColumnIndex && sourceRowIndex + rowCount > sourceColumnIndex)
            {
                // row by row, but skip resulting zero rows at the beginning
                int rowInit = sourceColumnIndex - sourceRowIndex;
                for (var i = 0; i < Math.Min(columnCount, rowCount - rowInit); i++)
                {
                    target.At(rowInit + i + targetRowIndex, i + targetColumnIndex, Data[sourceColumnIndex + i]);
                }
            }

            // else: all zero, nop
        }
        public static SparseCompressedRowMatrixStorage <T> OfIndexedEnumerable(int rows, int columns, IEnumerable <Tuple <int, int, T> > data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            var trows = new List <Tuple <int, T> > [rows];

            foreach (var item in data)
            {
                if (!Zero.Equals(item.Item3))
                {
                    var row = trows[item.Item1] ?? (trows[item.Item1] = new List <Tuple <int, T> >());
                    row.Add(new Tuple <int, T>(item.Item2, item.Item3));
                }
            }

            var storage       = new SparseCompressedRowMatrixStorage <T>(rows, columns);
            var rowPointers   = storage.RowPointers;
            var columnIndices = new List <int>();
            var values        = new List <T>();

            int index = 0;

            for (int row = 0; row < rows; row++)
            {
                rowPointers[row] = index;
                var trow = trows[row];
                if (trow != null)
                {
                    trow.Sort();
                    foreach (var item in trow)
                    {
                        values.Add(item.Item2);
                        columnIndices.Add(item.Item1);
                        index++;
                    }
                }
            }

            storage.ColumnIndices = columnIndices.ToArray();
            storage.Values        = values.ToArray();
            storage.ValueCount    = values.Count;
            return(storage);
        }
Esempio n. 19
0
        /// <summary>
        /// Permute the rows of a matrix in CSR format, B = P * A, where P represents
        /// a permutation matrix.
        /// </summary>
        /// <param name="storage">Input storage.</param>
        /// <param name="target">Target storage.</param>
        /// <param name="perm">Permutation array of length RowCount.</param>
        /// <param name="sorted">Ensure that column indices will be sorted.</param>
        /// <remarks>
        /// The permutation P is defined through the array perm: for each j,
        /// perm(j) represents the destination row number of row number j:
        ///
        /// a(i,j) in the original matrix becomes a(perm(i),j) in the output matrix.
        /// </remarks>
        public static void PermuteRows <T>(this SparseCompressedRowMatrixStorage <T> storage,
                                           SparseCompressedRowMatrixStorage <T> target, int[] perm, bool sorted = true)
            where T : struct, IEquatable <T>, IFormattable
        {
            int k, n = storage.RowCount;

            var ax = storage.Values;
            var ap = storage.RowPointers;
            var ai = storage.ColumnIndices;

            var bx = target.Values;
            var bp = target.RowPointers;
            var bi = target.ColumnIndices;

            // Determine pointers for output matix.
            for (int i = 0; i < n; i++)
            {
                k         = perm[i];
                bp[k + 1] = ap[i + 1] - ap[i];
            }

            // Get pointers from lengths
            bp[0] = 0;
            for (int i = 0; i < n; i++)
            {
                bp[i + 1] += bp[i];
            }

            // Copying
            for (int i = 0; i < n; i++)
            {
                // Old row = i, new row = perm(i), k = new pointer
                k = bp[perm[i]];
                for (int j = ap[i]; j < ap[i + 1]; j++)
                {
                    bi[k] = ai[j];
                    bx[k] = ax[j];
                    k     = k + 1;
                }
            }

            if (sorted)
            {
                Helper.SortIndices(storage.RowCount, bx, bp, bi);
            }
        }
Esempio n. 20
0
        /// <summary>
        /// Drops entries from a sparse matrix.
        /// </summary>
        /// <param name="storage">The sparse storage.</param>
        /// <param name="func">Drop element a_{i,j} if func(i, j, aij) is false.</param>
        /// <param name="sorted">Ensure that column indices will be sorted.</param>
        /// <returns>New number of entries in A.</returns>
        public static int Keep <T>(this SparseCompressedRowMatrixStorage <T> storage,
                                   Func <int, int, T, bool> func, bool sorted = true)
            where T : struct, IEquatable <T>, IFormattable
        {
            int rowCount = storage.RowCount;

            var ax = storage.Values;
            var ap = storage.RowPointers;
            var ai = storage.ColumnIndices;

            int i, j, nz = 0;

            for (i = 0; i < rowCount; i++)
            {
                j = ap[i];

                // Record new location of row i.
                ap[i] = nz;

                for (; j < ap[i + 1]; j++)
                {
                    if (func(i, ai[j], ax[j]))
                    {
                        // Keep A(i,j).
                        ax[nz] = ax[j];
                        ai[nz] = ai[j];
                        nz++;
                    }
                }
            }

            // Record new nonzero count.
            ap[rowCount] = nz;

            if (sorted)
            {
                Helper.SortIndices(storage.RowCount, ax, ap, ai);
            }

            // Remove extra space.
            Array.Resize(ref storage.Values, nz);
            Array.Resize(ref storage.ColumnIndices, nz);

            return(nz);
        }
        void CopyTo(SparseCompressedRowMatrixStorage <T> target, bool skipClearing)
        {
            if (target == null)
            {
                throw new ArgumentNullException("target");
            }

            if (RowCount != target.RowCount || ColumnCount != target.ColumnCount)
            {
                var message = string.Format(Resources.ArgumentMatrixDimensions2, RowCount + "x" + ColumnCount, target.RowCount + "x" + target.ColumnCount);
                throw new ArgumentException(message, "target");
            }

            if (!skipClearing)
            {
                target.Clear();
            }

            for (int i = 0; i < Data.Length; i++)
            {
                target.At(i, i, Data[i]);
            }
        }
Esempio n. 22
0
        public static SparseCompressedRowMatrixStorage <T> OfDiagonalInit(int rows, int columns, Func <int, T> init)
        {
            var storage       = new SparseCompressedRowMatrixStorage <T>(rows, columns);
            var rowPointers   = storage.RowPointers;
            var columnIndices = new List <int>();
            var values        = new List <T>();

            for (int i = 0; i < Math.Min(rows, columns); i++)
            {
                rowPointers[i] = values.Count;
                var x = init(i);
                if (!Zero.Equals(x))
                {
                    values.Add(x);
                    columnIndices.Add(i);
                }
            }

            storage.ColumnIndices = columnIndices.ToArray();
            storage.Values        = values.ToArray();
            storage.ValueCount    = values.Count;
            return(storage);
        }
        void TransposeToUnchecked(SparseCompressedRowMatrixStorage<T> target)
        {
            var rowPointers = target.RowPointers;
            var columnIndices = new List<int>();
            var values = new List<T>();

            for (int j = 0; j < ColumnCount; j++)
            {
                rowPointers[j] = values.Count;
                var index = j * RowCount;
                for (int i = 0; i < RowCount; i++)
                {
                    if (!Zero.Equals(Data[index + i]))
                    {
                        values.Add(Data[index + i]);
                        columnIndices.Add(i);
                    }
                }
            }

            rowPointers[ColumnCount] = values.Count;
            target.ColumnIndices = columnIndices.ToArray();
            target.Values = values.ToArray();
        }
        void CopyTo(SparseCompressedRowMatrixStorage <T> target)
        {
            if (ReferenceEquals(this, target))
            {
                return;
            }

            if (RowCount != target.RowCount || ColumnCount != target.ColumnCount)
            {
                var message = string.Format(Resources.ArgumentMatrixDimensions2, RowCount + "x" + ColumnCount, target.RowCount + "x" + target.ColumnCount);
                throw new ArgumentException(message, "target");
            }

            target.ValueCount    = ValueCount;
            target.Values        = new T[ValueCount];
            target.ColumnIndices = new int[ValueCount];

            if (ValueCount != 0)
            {
                Array.Copy(Values, target.Values, ValueCount);
                Buffer.BlockCopy(ColumnIndices, 0, target.ColumnIndices, 0, ValueCount * Constants.SizeOfInt);
                Buffer.BlockCopy(RowPointers, 0, target.RowPointers, 0, RowCount * Constants.SizeOfInt);
            }
        }
Esempio n. 25
0
        /// <summary>
        /// Extract rows from given storage.
        /// </summary>
        /// <param name="storage"></param>
        /// <param name="rowIndices">The rows to extract.</param>
        /// <param name="target">The target storage (will be resized, if needed).</param>
        /// <returns>The requested sub-matrix.</returns>
        public static void GetRows <T>(this SparseCompressedRowMatrixStorage <T> storage,
                                       int[] rowIndices, SparseCompressedRowMatrixStorage <T> target)
            where T : struct, IEquatable <T>, IFormattable
        {
            var ap = storage.RowPointers;
            var ai = storage.ColumnIndices;
            var ax = storage.Values;

            int count = rowIndices.Length;

            if (target.RowCount != count || storage.ColumnCount != target.ColumnCount)
            {
                throw new Exception();
            }

            int i, needed = 0;

            // Compute space needed.
            for (int k = 0; k < count; k++)
            {
                i = rowIndices[k];

                needed += ap[i + 1] - ap[i];
            }

            var cp = target.RowPointers;
            var ci = target.ColumnIndices;
            var cx = target.Values;

            // We assume that cx and ci have the same length.
            int nz = cx.Length;

            if (nz < needed)
            {
                // Resize workspace.
                Array.Resize(ref ci, needed);
                Array.Resize(ref cx, needed);
            }

            nz = 0;

            for (int k = 0; k < count; k++)
            {
                i = rowIndices[k];

                int rowEnd = ap[i + 1];

                cp[k] = nz;

                // Copy row.
                for (int j = ap[i]; j < rowEnd; j++)
                {
                    cx[nz] = ax[j];
                    ci[nz] = ai[j];

                    nz = nz + 1;
                }
            }

            cp[count] = nz;

            target.ColumnIndices = ci;
            target.Values        = cx;
        }
        void CopySubMatrixToUnchecked(SparseCompressedRowMatrixStorage <T> target,
                                      int sourceRowIndex, int targetRowIndex, int rowCount,
                                      int sourceColumnIndex, int targetColumnIndex, int columnCount,
                                      bool skipClearing)
        {
            var rowOffset    = targetRowIndex - sourceRowIndex;
            var columnOffset = targetColumnIndex - sourceColumnIndex;

            // special case for empty target - much faster
            if (target.ValueCount == 0)
            {
                // note: ValueCount is maximum resulting ValueCount (just using max to avoid internal copying)
                // resulting arrays will likely be smaller - unless all values fit in the chosen range.
                var values        = new List <T>(ValueCount);
                var columnIndices = new List <int>(ValueCount);
                var rowPointers   = target.RowPointers;

                for (int i = sourceRowIndex, row = 0; i < sourceRowIndex + rowCount; i++, row++)
                {
                    rowPointers[i + rowOffset] = values.Count;

                    var startIndex = RowPointers[i];
                    var endIndex   = RowPointers[i + 1];

                    // note: we might be able to replace this loop with Array.Copy (perf)
                    for (int j = startIndex; j < endIndex; j++)
                    {
                        // check if the column index is in the range
                        if ((ColumnIndices[j] >= sourceColumnIndex) && (ColumnIndices[j] < sourceColumnIndex + columnCount))
                        {
                            values.Add(Values[j]);
                            columnIndices.Add(ColumnIndices[j] + columnOffset);
                        }
                    }
                }

                for (int i = targetRowIndex + rowCount; i < rowPointers.Length; i++)
                {
                    rowPointers[i] = values.Count;
                }

                target.RowPointers[target.RowCount] = values.Count;
                target.Values        = values.ToArray();
                target.ColumnIndices = columnIndices.ToArray();

                return;
            }

            if (!skipClearing)
            {
                target.Clear(targetRowIndex, rowCount, targetColumnIndex, columnCount);
            }

            // NOTE: potential for more efficient implementation
            for (int i = sourceRowIndex, row = 0; i < sourceRowIndex + rowCount; i++, row++)
            {
                var startIndex = RowPointers[i];
                var endIndex   = RowPointers[i + 1];

                for (int j = startIndex; j < endIndex; j++)
                {
                    // check if the column index is in the range
                    if ((ColumnIndices[j] >= sourceColumnIndex) && (ColumnIndices[j] < sourceColumnIndex + columnCount))
                    {
                        var column = ColumnIndices[j] - sourceColumnIndex;
                        target.At(targetRowIndex + row, targetColumnIndex + column, Values[j]);
                    }
                }
            }
        }
Esempio n. 27
0
        /// <summary>
        /// Replaces the rows of the storage with the given rows.
        /// </summary>
        /// <param name="storage"></param>
        /// <param name="rowIndices">The indices of the rows to replace.</param>
        /// <param name="source">The storage containing the rows to copy.</param>
        public static void SetRows <T>(this SparseCompressedRowMatrixStorage <T> storage,
                                       int[] rowIndices, SparseCompressedRowMatrixStorage <T> source)
            where T : struct, IEquatable <T>, IFormattable
        {
            var ap = storage.RowPointers;
            var ai = storage.ColumnIndices;
            var ax = storage.Values;

            int i, n = ap.Length;
            int rowCount = rowIndices.Length;

            int valueCount = 0;

            // Count the number of nonzeros in given rows of input matrix.
            for (int k = 0; k < rowCount; k++)
            {
                i = rowIndices[k];

                valueCount += ap[i + 1] - ap[i];
            }

            int nz   = storage.ValueCount;
            int size = nz + (source.ValueCount - valueCount);

            // Check if the matrix storage has to be resized.
            if (ai.Length < size)
            {
                Array.Resize(ref ai, size);
                Array.Resize(ref ax, size);

                storage.ColumnIndices = ai;
                storage.Values        = ax;
            }

            size = ai.Length;

            var cp = source.RowPointers;
            var ci = source.ColumnIndices;
            var cx = source.Values;

            int count, length, rowStart, rowEnd;

            // Replace the rows.
            for (int k = 0; k < rowCount; k++)
            {
                i = rowIndices[k];

                rowStart = ap[i];
                rowEnd   = ap[i + 1];

                // Length of the row to insert.
                length = cp[k + 1] - cp[k];

                // Number of elements to shift.
                count = nz - rowEnd;

                // Copy all data behind the current block.
                Array.Copy(ai, rowEnd, ai, rowStart + length, count);
                Array.Copy(ax, rowEnd, ax, rowStart + length, count);

                // Replace row.
                Array.Copy(ci, cp[k], ai, rowStart, length);
                Array.Copy(cx, cp[k], ax, rowStart, length);

                // The difference of the row lengths.
                count = length - (rowEnd - rowStart);

                // Fix row pointers.
                for (int j = i + 1; j < n; j++)
                {
                    ap[j] += count;
                }

                nz += count;
            }
        }
Esempio n. 28
0
        /// <summary>
        /// Extract columns from given storage.
        /// </summary>
        /// <param name="storage"></param>
        /// <param name="columnIndices">The columns to extract.</param>
        /// <param name="target">The target storage (will be resized, if needed).</param>
        /// <returns>The requested sub-matrix.</returns>
        public static void GetColumns <T>(this SparseCompressedRowMatrixStorage <T> storage,
                                          int[] columnIndices, SparseCompressedRowMatrixStorage <T> target)
            where T : struct, IEquatable <T>, IFormattable
        {
            var ap = storage.RowPointers;
            var ai = storage.ColumnIndices;
            var ax = storage.Values;

            int count    = columnIndices.Length;
            int rowCount = storage.RowCount;

            if (target.ColumnCount != count || rowCount != target.RowCount)
            {
                throw new Exception();
            }

            int i, j, nz, needed = 0;

            var columnCounts = new int[storage.ColumnCount];

            nz = storage.ValueCount;

            // Count columns.
            for (i = 0; i < nz; i++)
            {
                columnCounts[ai[i]]++;
            }

            // Compute space needed.
            for (int k = 0; k < count; k++)
            {
                needed += columnCounts[columnIndices[k]];
            }

            var cp = target.RowPointers;
            var ci = target.ColumnIndices;
            var cx = target.Values;

            // We assume that cx and ci have the same length.
            nz = cx.Length;

            if (nz < needed)
            {
                // Resize workspace.
                Array.Resize(ref ci, needed);
                Array.Resize(ref cx, needed);
            }

            int column, rowStart, rowEnd;

            nz = 0;

            for (int k = 0; k < rowCount; k++)
            {
                rowStart = ap[k];
                rowEnd   = ap[k + 1];

                cp[k] = nz;

                // Look for columns in current row.
                for (j = 0; j < count; j++)
                {
                    column = columnIndices[j];

                    i = Array.BinarySearch(ai, rowStart, rowEnd - rowStart, column);

                    if (i >= 0)
                    {
                        ci[nz] = j;
                        cx[nz] = ax[i];

                        nz = nz + 1;
                    }
                }
            }

            cp[rowCount] = nz;

            target.ColumnIndices = ci;
            target.Values        = cx;
        }