// // Math.NET Numerics, part of the Math.NET Project // http://mathnet.opensourcedotnet.info // Copyright (c) 2009 Math.NET // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, // copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // namespace MathNet.Numerics.LinearAlgebra.Double { using System; using System.Text; using MathNet.Numerics.Properties; /// /// A matrix class. /// [Serializable] public abstract class Matrix : IFormattable, ICloneable, IEquatable { /// /// Initializes a new instance of the class. /// /// /// The number of rows. /// /// /// The number of columns. /// protected Matrix(int rows, int columns) { RowCount = rows; ColumnCount = columns; } /// /// Initializes a new instance of the class. /// /// /// The order of the matrix. /// protected Matrix(int order) { RowCount = order; ColumnCount = order; } /// /// Gets the number of columns. /// /// The number of columns. public virtual int ColumnCount { get; private set; } /// /// Gets the number of rows. /// /// The number of rows. public virtual int RowCount { get; private set; } /// /// Gets or sets the value at the given row and column. /// /// /// The row of the element. /// /// /// The column of the element. /// /// The double value to get or set. /// This method is ranged checked. and /// to get and set values without range checking. public virtual double this[int row, int column] { get { RangeCheck(row, column); return At(row, column); } set { RangeCheck(row, column); At(row, column, value); } } /// /// Retrieves the requested element without range checking. /// /// /// The row of the element. /// /// /// The column of the element. /// /// /// The requested element. /// public abstract double At(int row, int column); /// /// Sets the value of the given element. /// /// /// The row of the element. /// /// /// The column of the element. /// /// /// The value to set the element to. /// public abstract void At(int row, int column, double value); /// /// Creates a clone of this instance. /// /// /// A clone of the instance. /// public virtual Matrix Clone() { var result = CreateMatrix(RowCount, ColumnCount); CopyTo(result); return result; } /// /// Copies the elements of this matrix to the given matrix. /// /// /// The matrix to copy values into. /// /// /// If target is . /// /// /// If this and the target matrix do not have the same dimensions.. /// public virtual void CopyTo(Matrix target) { if (target == null) { throw new ArgumentNullException("target"); } if (ReferenceEquals(this, target)) { return; } if (RowCount != target.RowCount || ColumnCount != target.ColumnCount) { throw new ArgumentException("target", Resources.ArgumentMatrixSameDimensions); } throw new NotImplementedException(); /* foreach (KeyValuePair column in GetColumnEnumerator()) { foreach (KeyValuePair element in column.Value.GetIndexedEnumerator()) { target.ValueAt(element.Key, column.Key, element.Value); } }*/ } /// /// Creates a Matrix for the given number of rows and columns. /// /// /// The number of rows. /// /// /// The number of columns. /// /// /// A Matrix with the given dimensions. /// /// /// Creates a matrix of the same matrix type as the current matrix. /// public abstract Matrix CreateMatrix(int numberOfRows, int numberOfColumns); /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString() { return this.ToString(null, null); } #region Implemented Interfaces #region ICloneable /// /// Creates a new object that is a copy of the current instance. /// /// /// A new object that is a copy of this instance. /// object ICloneable.Clone() { return Clone(); } #endregion #region IEquatable /// /// Indicates whether the current object is equal to another object of the same type. /// /// /// An object to compare with this object. /// /// /// true if the current object is equal to the parameter; otherwise, false. /// public bool Equals(Matrix other) { // Reject equality when the argument is null or has a different shape. if (other == null) { return false; } if (ColumnCount != other.ColumnCount || RowCount != other.RowCount) { return false; } // Accept if the argument is the same object as this. if (ReferenceEquals(this, other)) { return true; } // If all else fails, perform element wise comparison. for (var row = 0; row < RowCount; row++) { for (var column = 0; column < ColumnCount; column++) { if (At(row, column) != other.At(row, column)) { return false; } } } return true; } #endregion #region IFormattable /// /// Returns a that represents this instance. /// /// /// The format to use. /// /// /// The format provider to use. /// /// /// A that represents this instance. /// public string ToString(string format, IFormatProvider formatProvider) { var stringBuilder = new StringBuilder(); for (var row = 0; row < RowCount; row++) { for (var column = 0; column < ColumnCount; column++) { stringBuilder.Append(At(row, column).ToString(format, formatProvider)); if (column != ColumnCount - 1) { stringBuilder.Append(","); } } if (row != RowCount - 1) { stringBuilder.Append(Environment.NewLine); } } return stringBuilder.ToString(); } #endregion #endregion /// /// Ranges the check. /// /// /// The row of the element. /// /// /// The column of the element. /// private void RangeCheck(int row, int column) { if (row < 0 || row >= RowCount) { throw new ArgumentOutOfRangeException("row"); } if (column < 0 || column >= ColumnCount) { throw new ArgumentOutOfRangeException("column"); } } } }