public sealed override object Clone()
        {
            var implementorClone =
                new DenseDoubleMatrixImplementor(
                    this.numberOfRows,
                    this.numberOfColumns);

            this.storage.CopyTo(implementorClone.storage, 0);

            return(implementorClone);
        }
        internal sealed override MatrixImplementor <double> this[string rowIndexes, IndexCollection columnIndexes]
        {
            get
            {
                // Check if any column index is outside the range defined by matrix dimensions
                if (columnIndexes.maxIndex >= this.numberOfColumns)
                {
                    throw new ArgumentOutOfRangeException(
                              nameof(columnIndexes),
                              ImplementationServices.GetResourceString(
                                  "STR_EXCEPT_TAB_INDEX_EXCEEDS_DIMS"));
                }

                int thisNumberOfRows = this.numberOfRows;

                int[]    columns       = columnIndexes.indexes;
                int      rowsLength    = thisNumberOfRows;
                int      columnsLength = columns.Length;
                var      subMatrix     = new DenseDoubleMatrixImplementor(rowsLength, columnsLength);
                double[] subStorage    = subMatrix.storage;

                double[] thisStorage = this.storage;

                int offset, index = 0;

                for (int j = 0; j < columnsLength; j++)
                {
                    offset = thisNumberOfRows * columns[j];
                    for (int i = 0; i < rowsLength; i++, index++)
                    {
                        subStorage[index] = thisStorage[i + offset];
                    }
                }

                return(subMatrix);
            }
            set
            {
                // Check if any column index is outside the range defined by matrix dimensions
                if (columnIndexes.maxIndex >= this.numberOfColumns)
                {
                    throw new ArgumentOutOfRangeException(
                              nameof(columnIndexes),
                              ImplementationServices.GetResourceString(
                                  "STR_EXCEPT_TAB_INDEX_EXCEEDS_DIMS"));
                }

                int thisNumberOfRows = this.numberOfRows;

                // Test for mismatched matrix dimensions
                ImplementationServices.ThrowOnMismatchedMatrixDimensions(thisNumberOfRows, columnIndexes.Count, value);

                MatrixImplementor <double> sourceImplementor;

                // if the source is this, clone the data before writing
                if (object.ReferenceEquals(this, value))
                {
                    sourceImplementor = (MatrixImplementor <double>)value.Clone();
                }
                else
                {
                    sourceImplementor = value;
                }

                int   offset;
                int[] columns = columnIndexes.indexes;

                switch (sourceImplementor.StorageScheme)
                {
                case StorageScheme.CompressedRow:
                {
                    var source       = (SparseCsr3DoubleMatrixImplementor)sourceImplementor;
                    var sourceValues = source.values;

                    for (int j = 0; j < columns.Length; j++)
                    {
                        offset = thisNumberOfRows * columns[j];
                        for (int i = 0; i < thisNumberOfRows; i++)
                        {
                            if (source.TryGetPosition(i, j, out int index))
                            {
                                this.storage[i + offset] = sourceValues[index];
                            }
                        }
                    }
                }
                break;

                case StorageScheme.Dense:
                {
                    var      source        = (DenseDoubleMatrixImplementor)sourceImplementor;
                    double[] sourceStorage = source.storage;
                    int      index         = 0;
                    for (int j = 0; j < columns.Length; j++)
                    {
                        offset = thisNumberOfRows * columns[j];
                        for (int i = 0; i < thisNumberOfRows; i++, index++)
                        {
                            this.storage[i + offset] = sourceStorage[index];
                        }
                    }
                }
                break;
                }
            }
        }
        internal sealed override MatrixImplementor <double> this[int rowIndex, string columnIndexes]
        {
            get
            {
                // Check if any row index is outside the range defined by matrix dimensions
                if (rowIndex < 0 || this.numberOfRows <= rowIndex)
                {
                    throw new ArgumentOutOfRangeException(
                              nameof(rowIndex),
                              ImplementationServices.GetResourceString(
                                  "STR_EXCEPT_TAB_INDEX_EXCEEDS_DIMS"));
                }

                int thisNumberOfRows = this.numberOfRows;

                int      columnsLength = this.numberOfColumns;
                var      subMatrix     = new DenseDoubleMatrixImplementor(1, columnsLength);
                double[] subStorage    = subMatrix.storage;

                double[] thisStorage = this.storage;

                int offset;

                for (int j = 0; j < columnsLength; j++)
                {
                    offset        = thisNumberOfRows * j;
                    subStorage[j] = thisStorage[rowIndex + offset];
                }

                return(subMatrix);
            }
            set
            {
                // Check if any row index is outside the range defined by matrix dimensions
                if (rowIndex < 0 || this.numberOfRows <= rowIndex)
                {
                    throw new ArgumentOutOfRangeException(
                              nameof(rowIndex),
                              ImplementationServices.GetResourceString(
                                  "STR_EXCEPT_TAB_INDEX_EXCEEDS_DIMS"));
                }

                // Test for mismatched matrix dimensions
                ImplementationServices.ThrowOnMismatchedMatrixDimensions(
                    1, this.numberOfColumns, value);

                MatrixImplementor <double> sourceImplementor;

                // if the source is this, clone the data before writing
                if (object.ReferenceEquals(this, value))
                {
                    sourceImplementor = (MatrixImplementor <double>)value.Clone();
                }
                else
                {
                    sourceImplementor = value;
                }

                int thisNumberOfRows = this.numberOfRows;

                int offset;
                int columnsLength = this.numberOfColumns;

                switch (sourceImplementor.StorageScheme)
                {
                case StorageScheme.CompressedRow:
                {
                    var source = (SparseCsr3DoubleMatrixImplementor)sourceImplementor;

                    for (int j = 0; j < columnsLength; j++)
                    {
                        offset = thisNumberOfRows * j;
                        this.storage[rowIndex + offset] = source.GetValue(j);
                    }
                }
                break;

                case StorageScheme.Dense:
                {
                    var      source        = (DenseDoubleMatrixImplementor)sourceImplementor;
                    double[] sourceStorage = source.storage;

                    for (int j = 0; j < columnsLength; j++)
                    {
                        offset = thisNumberOfRows * j;
                        this.storage[rowIndex + offset] = sourceStorage[j];
                    }
                }
                break;
                }
            }
        }
        internal sealed override MatrixImplementor <double> this[string rowIndexes, string columnIndexes]
        {
            get
            {
                int thisNumberOfRows = this.numberOfRows;

                int      rowsLength    = thisNumberOfRows;
                int      columnsLength = this.numberOfColumns;
                var      subMatrix     = new DenseDoubleMatrixImplementor(rowsLength, columnsLength);
                double[] subStorage    = subMatrix.storage;

                double[] thisStorage = this.storage;

                int offset, index = 0;

                for (int j = 0; j < columnsLength; j++)
                {
                    offset = thisNumberOfRows * j;
                    for (int i = 0; i < rowsLength; i++, index++)
                    {
                        subStorage[index] = thisStorage[i + offset];
                    }
                }

                return(subMatrix);
            }
            set
            {
                // Test for mismatched matrix dimensions
                ImplementationServices.ThrowOnMismatchedMatrixDimensions(this.numberOfRows, this.numberOfColumns, value);

                // if the source is this, nothing has to be done
                if (object.ReferenceEquals(this, value))
                {
                    return;
                }

                MatrixImplementor <double> sourceImplementor = value;

                int offset;

                int thisNumberOfRows = this.numberOfRows;
                int rowsLength       = thisNumberOfRows;
                int columnsLength    = this.numberOfColumns;

                switch (sourceImplementor.StorageScheme)
                {
                case StorageScheme.CompressedRow:
                {
                    var source       = (SparseCsr3DoubleMatrixImplementor)sourceImplementor;
                    var sourceValues = source.values;

                    for (int j = 0; j < columnsLength; j++)
                    {
                        offset = thisNumberOfRows * j;
                        for (int i = 0; i < rowsLength; i++)
                        {
                            if (source.TryGetPosition(i, j, out int index))
                            {
                                this.storage[i + offset] = sourceValues[index];
                            }
                        }
                    }
                }
                break;

                case StorageScheme.Dense:
                {
                    var      source        = (DenseDoubleMatrixImplementor)sourceImplementor;
                    double[] sourceStorage = source.storage;
                    int      index         = 0;
                    for (int j = 0; j < columnsLength; j++)
                    {
                        offset = thisNumberOfRows * j;
                        for (int i = 0; i < rowsLength; i++, index++)
                        {
                            this.storage[i + offset] = sourceStorage[index];
                        }
                    }
                }
                break;
                }
            }
        }
Exemplo n.º 5
0
        ///<inheritdoc/>
        public override MatrixImplementor <double> Read(
            ref Utf8JsonReader reader,
            Type typeToConvert,
            JsonSerializerOptions options)
        {
            if (reader.TokenType != JsonTokenType.StartObject)
            {
                throw new JsonException();
            }

            #region StorageScheme

            reader.Read();
            if (reader.TokenType != JsonTokenType.PropertyName)
            {
                throw new JsonException();
            }

            string propertyName = reader.GetString();
            if (propertyName != "StorageScheme")
            {
                throw new JsonException();
            }

            reader.Read();
            if (reader.TokenType != JsonTokenType.Number)
            {
                throw new JsonException();
            }

            StorageScheme storageScheme = (StorageScheme)reader.GetInt32();

            #endregion

            #region NumberOfRows

            reader.Read();
            if (reader.TokenType != JsonTokenType.PropertyName)
            {
                throw new JsonException();
            }

            propertyName = reader.GetString();
            if (propertyName != "NumberOfRows")
            {
                throw new JsonException();
            }

            reader.Read();
            if (reader.TokenType != JsonTokenType.Number)
            {
                throw new JsonException();
            }

            int numberOfRows = reader.GetInt32();

            #endregion

            #region NumberOfColumns

            reader.Read();
            if (reader.TokenType != JsonTokenType.PropertyName)
            {
                throw new JsonException();
            }

            propertyName = reader.GetString();
            if (propertyName != "NumberOfColumns")
            {
                throw new JsonException();
            }

            reader.Read();
            if (reader.TokenType != JsonTokenType.Number)
            {
                throw new JsonException();
            }

            int numberOfColumns = reader.GetInt32();

            #endregion

            MatrixImplementor <double> matrixImplementor;

            switch (storageScheme)
            {
            case StorageScheme.Dense:
            {
                matrixImplementor =
                    new DenseDoubleMatrixImplementor(
                        numberOfRows,
                        numberOfColumns);

                #region Storage

                reader.Read();
                if (reader.TokenType != JsonTokenType.PropertyName)
                {
                    throw new JsonException();
                }

                propertyName = reader.GetString();
                if (propertyName != "Storage")
                {
                    throw new JsonException();
                }

                reader.Read();
                if (reader.TokenType != JsonTokenType.StartArray)
                {
                    throw new JsonException();
                }

                for (int i = 0; i < matrixImplementor.Count; i++)
                {
                    reader.Read();
                    if (reader.TokenType != JsonTokenType.Number)
                    {
                        throw new JsonException();
                    }

                    matrixImplementor[i] = reader.GetDouble();
                }

                reader.Read();
                if (reader.TokenType != JsonTokenType.EndArray)
                {
                    throw new JsonException();
                }

                #endregion
            }
            break;

            case StorageScheme.CompressedRow:
            {
                #region Capacity

                reader.Read();
                if (reader.TokenType != JsonTokenType.PropertyName)
                {
                    throw new JsonException();
                }

                propertyName = reader.GetString();
                if (propertyName != "Capacity")
                {
                    throw new JsonException();
                }

                reader.Read();
                if (reader.TokenType != JsonTokenType.Number)
                {
                    throw new JsonException();
                }

                int capacity = reader.GetInt32();

                #endregion

                var sparseMatrixImplementor =
                    new SparseCsr3DoubleMatrixImplementor(
                        numberOfRows,
                        numberOfColumns,
                        capacity);

                #region Values

                reader.Read();
                if (reader.TokenType != JsonTokenType.PropertyName)
                {
                    throw new JsonException();
                }

                propertyName = reader.GetString();
                if (propertyName != "Values")
                {
                    throw new JsonException();
                }

                reader.Read();
                if (reader.TokenType != JsonTokenType.StartArray)
                {
                    throw new JsonException();
                }

                for (int i = 0; i < capacity; i++)
                {
                    reader.Read();
                    if (reader.TokenType != JsonTokenType.Number)
                    {
                        throw new JsonException();
                    }

                    sparseMatrixImplementor.values[i] = reader.GetDouble();
                }

                reader.Read();
                if (reader.TokenType != JsonTokenType.EndArray)
                {
                    throw new JsonException();
                }

                #endregion

                #region Columns

                reader.Read();
                if (reader.TokenType != JsonTokenType.PropertyName)
                {
                    throw new JsonException();
                }

                propertyName = reader.GetString();
                if (propertyName != "Columns")
                {
                    throw new JsonException();
                }

                reader.Read();
                if (reader.TokenType != JsonTokenType.StartArray)
                {
                    throw new JsonException();
                }

                for (int i = 0; i < capacity; i++)
                {
                    reader.Read();
                    if (reader.TokenType != JsonTokenType.Number)
                    {
                        throw new JsonException();
                    }

                    sparseMatrixImplementor.columns[i] = reader.GetInt32();
                }

                reader.Read();
                if (reader.TokenType != JsonTokenType.EndArray)
                {
                    throw new JsonException();
                }

                #endregion

                #region RowIndex

                reader.Read();
                if (reader.TokenType != JsonTokenType.PropertyName)
                {
                    throw new JsonException();
                }

                propertyName = reader.GetString();
                if (propertyName != "RowIndex")
                {
                    throw new JsonException();
                }

                reader.Read();
                if (reader.TokenType != JsonTokenType.StartArray)
                {
                    throw new JsonException();
                }

                for (int i = 0; i < numberOfRows + 1; i++)
                {
                    reader.Read();
                    if (reader.TokenType != JsonTokenType.Number)
                    {
                        throw new JsonException();
                    }

                    sparseMatrixImplementor.rowIndex[i] = reader.GetInt32();
                }

                reader.Read();
                if (reader.TokenType != JsonTokenType.EndArray)
                {
                    throw new JsonException();
                }

                #endregion

                matrixImplementor = sparseMatrixImplementor;
            }
            break;

            default:
                throw new JsonException();
            }

            reader.Read();
            if (reader.TokenType == JsonTokenType.EndObject)
            {
                return(matrixImplementor);
            }

            throw new JsonException();
        }