// MATRIX COPY

        internal override void CopyToUnchecked(MatrixStorage <T> target, ExistingData existingData)
        {
            var diagonalTarget = target as DiagonalMatrixStorage <T>;

            if (diagonalTarget != null)
            {
                CopyToUnchecked(diagonalTarget);
                return;
            }

            var denseTarget = target as DenseColumnMajorMatrixStorage <T>;

            if (denseTarget != null)
            {
                CopyToUnchecked(denseTarget, existingData);
                return;
            }

            var sparseTarget = target as SparseCompressedRowMatrixStorage <T>;

            if (sparseTarget != null)
            {
                CopyToUnchecked(sparseTarget, existingData);
                return;
            }

            // FALL BACK

            if (existingData == ExistingData.Clear)
            {
                target.Clear();
            }

            for (int i = 0; i < Data.Length; i++)
            {
                target.At(i, i, Data[i]);
            }
        }
        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, System.Math.Max(4096 / rowCount, 32), (a, b) =>
                {
                    for (int j = a; j < b; j++)
                    {
                        int sourceIndex = sourceRowIndex + (j + sourceColumnIndex) * RowCount;
                        int targetIndex = targetRowIndex + (j + targetColumnIndex) * target.RowCount;
                        for (int 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++)
            {
                int index = sourceRowIndex + j * RowCount;
                for (int ii = targetRowIndex; ii < targetRowIndex + rowCount; ii++)
                {
                    target.At(ii, jj, f(ii, jj, Data[index++]));
                }
            }
        }
        void ValidateSubColumnRange(MatrixStorage <T> target, int columnIndex,
                                    int sourceRowIndex, int targetRowIndex, int rowCount)
        {
            if (rowCount < 1)
            {
                throw new ArgumentOutOfRangeException("rowCount", Resources.ArgumentMustBePositive);
            }

            // Verify Source

            if (sourceRowIndex >= Length || sourceRowIndex < 0)
            {
                throw new ArgumentOutOfRangeException("sourceRowIndex");
            }

            if (sourceRowIndex + rowCount > Length)
            {
                throw new ArgumentOutOfRangeException("rowCount");
            }

            // Verify Target

            if (columnIndex >= target.ColumnCount || columnIndex < 0)
            {
                throw new ArgumentOutOfRangeException("columnIndex");
            }

            if (targetRowIndex >= target.RowCount || targetRowIndex < 0)
            {
                throw new ArgumentOutOfRangeException("targetRowIndex");
            }

            if (targetRowIndex + rowCount > target.RowCount)
            {
                throw new ArgumentOutOfRangeException("rowCount");
            }
        }
        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 diagonalTarget = target as DiagonalMatrixStorage <TU>;

            if (diagonalTarget != null)
            {
                MapSubMatrixIndexedToUnchecked(diagonalTarget, f, sourceRowIndex, targetRowIndex, rowCount, sourceColumnIndex, targetColumnIndex, columnCount, zeros);
                return;
            }

            var denseTarget = target as DenseColumnMajorMatrixStorage <TU>;

            if (denseTarget != null)
            {
                MapSubMatrixIndexedToUnchecked(denseTarget, f, sourceRowIndex, targetRowIndex, rowCount, sourceColumnIndex, targetColumnIndex, columnCount, zeros, existingData);
                return;
            }

            // TODO: Proper Sparse Implementation

            // FALL BACK

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

            if (sourceRowIndex == sourceColumnIndex)
            {
                int targetRow    = targetRowIndex;
                int targetColumn = targetColumnIndex;
                for (var i = 0; i < System.Math.Min(columnCount, rowCount); i++)
                {
                    target.At(targetRow, targetColumn, f(targetRow, targetColumn, Data[sourceRowIndex + i]));
                    targetRow++;
                    targetColumn++;
                }
            }
            else if (sourceRowIndex > sourceColumnIndex && sourceColumnIndex + columnCount > sourceRowIndex)
            {
                // column by column, but skip resulting zero columns at the beginning
                int columnInit   = sourceRowIndex - sourceColumnIndex;
                int targetRow    = targetRowIndex;
                int targetColumn = targetColumnIndex + columnInit;
                for (var i = 0; i < System.Math.Min(columnCount - columnInit, rowCount); i++)
                {
                    target.At(targetRow, targetColumn, f(targetRow, targetColumn, Data[sourceRowIndex + i]));
                    targetRow++;
                    targetColumn++;
                }
            }
            else if (sourceRowIndex < sourceColumnIndex && sourceRowIndex + rowCount > sourceColumnIndex)
            {
                // row by row, but skip resulting zero rows at the beginning
                int rowInit      = sourceColumnIndex - sourceRowIndex;
                int targetRow    = targetRowIndex + rowInit;
                int targetColumn = targetColumnIndex;
                for (var i = 0; i < System.Math.Min(columnCount, rowCount - rowInit); i++)
                {
                    target.At(targetRow, targetColumn, f(targetRow, targetColumn, Data[sourceColumnIndex + i]));
                    targetRow++;
                    targetColumn++;
                }
            }
        }
        internal override Tuple <int, int, T, TOther> Find2Unchecked <TOther>(MatrixStorage <TOther> other, Func <T, TOther, bool> predicate, Zeros zeros)
        {
            var denseOther = other as DenseColumnMajorMatrixStorage <TOther>;

            if (denseOther != null)
            {
                TOther[] otherData = denseOther.Data;
                int      k         = 0;
                for (int j = 0; j < ColumnCount; j++)
                {
                    for (int i = 0; i < RowCount; i++)
                    {
                        if (predicate(i == j ? Data[i] : Zero, otherData[k]))
                        {
                            return(new Tuple <int, int, T, TOther>(i, j, i == j ? Data[i] : Zero, otherData[k]));
                        }
                        k++;
                    }
                }
                return(null);
            }

            var diagonalOther = other as DiagonalMatrixStorage <TOther>;

            if (diagonalOther != null)
            {
                TOther[] otherData = diagonalOther.Data;
                for (int i = 0; i < Data.Length; i++)
                {
                    if (predicate(Data[i], otherData[i]))
                    {
                        return(new Tuple <int, int, T, TOther>(i, i, Data[i], otherData[i]));
                    }
                }
                if (zeros == Zeros.Include && (RowCount > 1 || ColumnCount > 1))
                {
                    TOther otherZero = BuilderInstance <TOther> .Matrix.Zero;
                    if (predicate(Zero, otherZero))
                    {
                        return(new Tuple <int, int, T, TOther>(RowCount > 1 ? 1 : 0, RowCount > 1 ? 0 : 1, Zero, otherZero));
                    }
                }
                return(null);
            }

            var sparseOther = other as SparseCompressedRowMatrixStorage <TOther>;

            if (sparseOther != null)
            {
                int[]    otherRowPointers   = sparseOther.RowPointers;
                int[]    otherColumnIndices = sparseOther.ColumnIndices;
                TOther[] otherValues        = sparseOther.Values;
                TOther   otherZero          = BuilderInstance <TOther> .Matrix.Zero;
                for (int row = 0; row < RowCount; row++)
                {
                    bool diagonal   = false;
                    var  startIndex = otherRowPointers[row];
                    var  endIndex   = otherRowPointers[row + 1];
                    for (var j = startIndex; j < endIndex; j++)
                    {
                        if (otherColumnIndices[j] == row)
                        {
                            diagonal = true;
                            if (predicate(Data[row], otherValues[j]))
                            {
                                return(new Tuple <int, int, T, TOther>(row, row, Data[row], otherValues[j]));
                            }
                        }
                        else
                        {
                            if (predicate(Zero, otherValues[j]))
                            {
                                return(new Tuple <int, int, T, TOther>(row, otherColumnIndices[j], Zero, otherValues[j]));
                            }
                        }
                    }
                    if (!diagonal && row < ColumnCount)
                    {
                        if (predicate(Data[row], otherZero))
                        {
                            return(new Tuple <int, int, T, TOther>(row, row, Data[row], otherZero));
                        }
                    }
                }
                if (zeros == Zeros.Include && sparseOther.ValueCount < (RowCount * ColumnCount))
                {
                    if (predicate(Zero, otherZero))
                    {
                        int k = 0;
                        for (int row = 0; row < RowCount; row++)
                        {
                            for (int col = 0; col < ColumnCount; col++)
                            {
                                if (k < otherRowPointers[row + 1] && otherColumnIndices[k] == col)
                                {
                                    k++;
                                }
                                else if (row != col)
                                {
                                    return(new Tuple <int, int, T, TOther>(row, col, Zero, otherZero));
                                }
                            }
                        }
                    }
                }
                return(null);
            }

            // FALL BACK

            return(base.Find2Unchecked(other, predicate, zeros));
        }
        // TRANSPOSE

        internal override void TransposeToUnchecked(MatrixStorage <T> target, ExistingData existingData)
        {
            CopyToUnchecked(target, existingData);
        }
        internal override TState Fold2Unchecked <TOther, TState>(MatrixStorage <TOther> other, Func <TState, T, TOther, TState> f, TState state, Zeros zeros)
        {
            var denseOther = other as DenseColumnMajorMatrixStorage <TOther>;

            if (denseOther != null)
            {
                TOther[] otherData = denseOther.Data;
                int      k         = 0;
                for (int j = 0; j < ColumnCount; j++)
                {
                    for (int i = 0; i < RowCount; i++)
                    {
                        state = f(state, i == j ? Data[i] : Zero, otherData[k]);
                        k++;
                    }
                }
                return(state);
            }

            var diagonalOther = other as DiagonalMatrixStorage <TOther>;

            if (diagonalOther != null)
            {
                TOther[] otherData = diagonalOther.Data;
                for (int i = 0; i < Data.Length; i++)
                {
                    state = f(state, Data[i], otherData[i]);
                }

                // Do we really need to do this?
                if (zeros == Zeros.Include)
                {
                    TOther otherZero = BuilderInstance <TOther> .Matrix.Zero;
                    int    count     = RowCount * ColumnCount - Data.Length;
                    for (int i = 0; i < count; i++)
                    {
                        state = f(state, Zero, otherZero);
                    }
                }

                return(state);
            }

            var sparseOther = other as SparseCompressedRowMatrixStorage <TOther>;

            if (sparseOther != null)
            {
                int[]    otherRowPointers   = sparseOther.RowPointers;
                int[]    otherColumnIndices = sparseOther.ColumnIndices;
                TOther[] otherValues        = sparseOther.Values;
                TOther   otherZero          = BuilderInstance <TOther> .Matrix.Zero;

                if (zeros == Zeros.Include)
                {
                    int k = 0;
                    for (int row = 0; row < RowCount; row++)
                    {
                        for (int col = 0; col < ColumnCount; col++)
                        {
                            if (k < otherRowPointers[row + 1] && otherColumnIndices[k] == col)
                            {
                                state = f(state, row == col ? Data[row] : Zero, otherValues[k++]);
                            }
                            else
                            {
                                state = f(state, row == col ? Data[row] : Zero, otherZero);
                            }
                        }
                    }
                    return(state);
                }

                for (int row = 0; row < RowCount; row++)
                {
                    bool diagonal = false;

                    var startIndex = otherRowPointers[row];
                    var endIndex   = otherRowPointers[row + 1];
                    for (var j = startIndex; j < endIndex; j++)
                    {
                        if (otherColumnIndices[j] == row)
                        {
                            diagonal = true;
                            state    = f(state, Data[row], otherValues[j]);
                        }
                        else
                        {
                            state = f(state, Zero, otherValues[j]);
                        }
                    }

                    if (!diagonal && row < ColumnCount)
                    {
                        state = f(state, Data[row], otherZero);
                    }
                }

                return(state);
            }

            // FALL BACK

            return(base.Fold2Unchecked(other, f, state, zeros));
        }
Exemple #8
0
        void ValidateSubMatrixRange <TU>(MatrixStorage <TU> target,
                                         int sourceRowIndex, int targetRowIndex, int rowCount,
                                         int sourceColumnIndex, int targetColumnIndex, int columnCount)
            where TU : struct, IEquatable <TU>, IFormattable
        {
            if (rowCount < 1)
            {
                throw new ArgumentOutOfRangeException("rowCount", Resources.ArgumentMustBePositive);
            }

            if (columnCount < 1)
            {
                throw new ArgumentOutOfRangeException("columnCount", Resources.ArgumentMustBePositive);
            }

            // Verify Source

            if (sourceRowIndex >= RowCount || sourceRowIndex < 0)
            {
                throw new ArgumentOutOfRangeException("sourceRowIndex");
            }

            if (sourceColumnIndex >= ColumnCount || sourceColumnIndex < 0)
            {
                throw new ArgumentOutOfRangeException("sourceColumnIndex");
            }

            var sourceRowMax    = sourceRowIndex + rowCount;
            var sourceColumnMax = sourceColumnIndex + columnCount;

            if (sourceRowMax > RowCount)
            {
                throw new ArgumentOutOfRangeException("rowCount");
            }

            if (sourceColumnMax > ColumnCount)
            {
                throw new ArgumentOutOfRangeException("columnCount");
            }

            // Verify Target

            if (targetRowIndex >= target.RowCount || targetRowIndex < 0)
            {
                throw new ArgumentOutOfRangeException("targetRowIndex");
            }

            if (targetColumnIndex >= target.ColumnCount || targetColumnIndex < 0)
            {
                throw new ArgumentOutOfRangeException("targetColumnIndex");
            }

            var targetRowMax    = targetRowIndex + rowCount;
            var targetColumnMax = targetColumnIndex + columnCount;

            if (targetRowMax > target.RowCount)
            {
                throw new ArgumentOutOfRangeException("rowCount");
            }

            if (targetColumnMax > target.ColumnCount)
            {
                throw new ArgumentOutOfRangeException("columnCount");
            }
        }
        internal override TState Fold2Unchecked <TOther, TState>(MatrixStorage <TOther> other, Func <TState, T, TOther, TState> f, TState state, Zeros zeros)
        {
            var denseOther = other as DenseColumnMajorMatrixStorage <TOther>;

            if (denseOther != null)
            {
                TOther[] otherData = denseOther.Data;
                for (int i = 0; i < Data.Length; i++)
                {
                    state = f(state, Data[i], otherData[i]);
                }
                return(state);
            }

            var diagonalOther = other as DiagonalMatrixStorage <TOther>;

            if (diagonalOther != null)
            {
                TOther[] otherData = diagonalOther.Data;
                TOther   otherZero = BuilderInstance <TOther> .Matrix.Zero;
                int      k         = 0;
                for (int j = 0; j < ColumnCount; j++)
                {
                    for (int i = 0; i < RowCount; i++)
                    {
                        state = f(state, Data[k], i == j ? otherData[i] : otherZero);
                        k++;
                    }
                }
                return(state);
            }

            var sparseOther = other as SparseCompressedRowMatrixStorage <TOther>;

            if (sparseOther != null)
            {
                int[]    otherRowPointers   = sparseOther.RowPointers;
                int[]    otherColumnIndices = sparseOther.ColumnIndices;
                TOther[] otherValues        = sparseOther.Values;
                TOther   otherZero          = BuilderInstance <TOther> .Matrix.Zero;
                int      k = 0;
                for (int row = 0; row < RowCount; row++)
                {
                    for (int col = 0; col < ColumnCount; col++)
                    {
                        if (k < otherRowPointers[row + 1] && otherColumnIndices[k] == col)
                        {
                            state = f(state, Data[col * RowCount + row], otherValues[k++]);
                        }
                        else
                        {
                            state = f(state, Data[col * RowCount + row], otherZero);
                        }
                    }
                }
                return(state);
            }

            // FALL BACK

            return(base.Fold2Unchecked(other, f, state, zeros));
        }
        internal override Tuple <int, int, T, TOther> Find2Unchecked <TOther>(MatrixStorage <TOther> other, Func <T, TOther, bool> predicate, Zeros zeros)
        {
            var denseOther = other as DenseColumnMajorMatrixStorage <TOther>;

            if (denseOther != null)
            {
                TOther[] otherData = denseOther.Data;
                for (int i = 0; i < Data.Length; i++)
                {
                    if (predicate(Data[i], otherData[i]))
                    {
                        int row, column;
                        RowColumnAtIndex(i, out row, out column);
                        return(new Tuple <int, int, T, TOther>(row, column, Data[i], otherData[i]));
                    }
                }
                return(null);
            }

            var diagonalOther = other as DiagonalMatrixStorage <TOther>;

            if (diagonalOther != null)
            {
                TOther[] otherData = diagonalOther.Data;
                TOther   otherZero = BuilderInstance <TOther> .Matrix.Zero;
                int      k         = 0;
                for (int j = 0; j < ColumnCount; j++)
                {
                    for (int i = 0; i < RowCount; i++)
                    {
                        if (predicate(Data[k], i == j ? otherData[i] : otherZero))
                        {
                            return(new Tuple <int, int, T, TOther>(i, j, Data[k], i == j ? otherData[i] : otherZero));
                        }
                        k++;
                    }
                }
                return(null);
            }

            var sparseOther = other as SparseCompressedRowMatrixStorage <TOther>;

            if (sparseOther != null)
            {
                int[]    otherRowPointers   = sparseOther.RowPointers;
                int[]    otherColumnIndices = sparseOther.ColumnIndices;
                TOther[] otherValues        = sparseOther.Values;
                TOther   otherZero          = BuilderInstance <TOther> .Matrix.Zero;
                int      k = 0;
                for (int row = 0; row < RowCount; row++)
                {
                    for (int col = 0; col < ColumnCount; col++)
                    {
                        if (k < otherRowPointers[row + 1] && otherColumnIndices[k] == col)
                        {
                            if (predicate(Data[col * RowCount + row], otherValues[k]))
                            {
                                return(new Tuple <int, int, T, TOther>(row, col, Data[col * RowCount + row], otherValues[k]));
                            }
                            k++;
                        }
                        else
                        {
                            if (predicate(Data[col * RowCount + row], otherZero))
                            {
                                return(new Tuple <int, int, T, TOther>(row, col, Data[col * RowCount + row], otherValues[k]));
                            }
                        }
                    }
                }
                return(null);
            }

            // FALL BACK

            return(base.Find2Unchecked(other, predicate, zeros));
        }