diff --git a/src/Numerics/LinearAlgebra/Double/Matrix.cs b/src/Numerics/LinearAlgebra/Double/Matrix.cs
new file mode 100644
index 00000000..02f2ba62
--- /dev/null
+++ b/src/Numerics/LinearAlgebra/Double/Matrix.cs
@@ -0,0 +1,340 @@
+//
+// 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");
+ }
+ }
+ }
+}
\ No newline at end of file