Browse Source
This class provides a new indexer for obtaining or setting submatrix / vector by using System.Rangepull/859/head
committed by
GitHub
1 changed files with 175 additions and 0 deletions
@ -0,0 +1,175 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace MathNet.Numerics.LinearAlgebra |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// This class is used for slice Matrix by using System.Range.
|
||||
|
/// It is different from System.Range functions in the use of ".." syntax.
|
||||
|
/// Because the when use ".." in array,like double[],the sliced array won't contain the end index.
|
||||
|
/// However,in this Matrix<T>,it will contain the end index.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T"></typeparam>
|
||||
|
public abstract partial class Matrix<T> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Get or Set the SubMatrix by [Range,Range]
|
||||
|
/// For example:
|
||||
|
/// Matrix<double> mat = Matrix<double>.Build.Dense(10,10);
|
||||
|
/// mat[1..2,2..3];
|
||||
|
/// mat[1..2,^9..^1];
|
||||
|
/// mat[..,2..3];
|
||||
|
/// mat[1..2,2..3] = a new Matrix has the same dimension with this submatrix;
|
||||
|
/// </summary>
|
||||
|
/// <param name="rowRange">the Row Range,it must contain more than one Row</param>
|
||||
|
/// <param name="columnRange">the Column Range,it must contain more than one Column</param>
|
||||
|
/// <returns>A SubMatrix</returns>
|
||||
|
public Matrix<T> this[Range rowRange, Range columnRange] |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
int rowStartIndex = rowRange.Start.IsFromEnd ? RowCount - rowRange.Start.Value - 1 : rowRange.Start.Value; |
||||
|
int rowEndIndex = rowRange.End.IsFromEnd ? RowCount - rowRange.End.Value - 1 : rowRange.End.Value; |
||||
|
int rowCount = rowEndIndex - rowStartIndex + 1; |
||||
|
|
||||
|
if (rowCount <=1 || rowCount > RowCount) |
||||
|
{ |
||||
|
throw new ArgumentException($"The argument Row Range:{rowRange} is wrong!"); |
||||
|
} |
||||
|
|
||||
|
int columnStartIndex = columnRange.Start.IsFromEnd ? ColumnCount - columnRange.Start.Value - 1 : columnRange.Start.Value; |
||||
|
int columnEndIndex = columnRange.End.IsFromEnd ? ColumnCount - columnRange.End.Value - 1 : columnRange.End.Value; |
||||
|
int columnCount = columnEndIndex - columnStartIndex + 1; |
||||
|
|
||||
|
if (columnCount <= 1 || columnCount > ColumnCount) |
||||
|
{ |
||||
|
throw new ArgumentException($"The argument Column Range:{columnRange} is wrong!"); |
||||
|
} |
||||
|
|
||||
|
var result = Build.SameAs(this, rowCount, columnCount); |
||||
|
Storage.CopySubMatrixTo(result.Storage, rowStartIndex, 0, rowCount, columnStartIndex, 0, columnCount, ExistingData.AssumeZeros); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
set |
||||
|
{ |
||||
|
int rowStartIndex = rowRange.Start.IsFromEnd ? RowCount - rowRange.Start.Value - 1 : rowRange.Start.Value; |
||||
|
int rowEndIndex = rowRange.End.IsFromEnd ? RowCount - rowRange.End.Value - 1 : rowRange.End.Value; |
||||
|
int rowCount = rowEndIndex - rowStartIndex + 1; |
||||
|
|
||||
|
if (rowCount <= 1 || rowCount > RowCount) |
||||
|
{ |
||||
|
throw new ArgumentException($"The argument Row Range:{rowRange} is wrong!"); |
||||
|
} |
||||
|
|
||||
|
int columnStartIndex = columnRange.Start.IsFromEnd ? ColumnCount - columnRange.Start.Value - 1 : columnRange.Start.Value; |
||||
|
int columnEndIndex = columnRange.End.IsFromEnd ? ColumnCount - columnRange.End.Value - 1 : columnRange.End.Value; |
||||
|
int columnCount = columnEndIndex - columnStartIndex + 1; |
||||
|
|
||||
|
if (columnCount <= 1 || columnCount > ColumnCount) |
||||
|
{ |
||||
|
throw new ArgumentException($"The argument Column Range:{columnRange} is wrong!"); |
||||
|
} |
||||
|
|
||||
|
value.Storage.CopySubMatrixTo(Storage, 0, rowStartIndex, rowCount, 0, columnStartIndex, columnCount); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Get or Set the Column SubVector of the Matrix
|
||||
|
/// </summary>
|
||||
|
/// <param name="rowRange">the Row Range,it must contain more than one Row</param>
|
||||
|
/// <param name="columnIndex">the column index</param>
|
||||
|
/// <returns>a vector</returns>
|
||||
|
public Vector<T> this[Range rowRange, int columnIndex] |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
int rowStartIndex = rowRange.Start.IsFromEnd ? RowCount - rowRange.Start.Value - 1 : rowRange.Start.Value; |
||||
|
int rowEndIndex = rowRange.End.IsFromEnd ? RowCount - rowRange.End.Value - 1 : rowRange.End.Value; |
||||
|
int rowCount = rowEndIndex - rowStartIndex + 1; |
||||
|
|
||||
|
if (rowCount <= 1 || rowCount > RowCount) |
||||
|
{ |
||||
|
throw new ArgumentException($"The argument Row Range:{rowRange} is wrong!"); |
||||
|
} |
||||
|
|
||||
|
if ((uint)columnIndex >= (uint)ColumnCount) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(nameof(columnIndex)); |
||||
|
} |
||||
|
|
||||
|
var ret = Vector<T>.Build.SameAs(this, rowCount); |
||||
|
Storage.CopySubColumnTo(ret.Storage, columnIndex, rowStartIndex, 0, rowCount); |
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
set |
||||
|
{ |
||||
|
int rowStartIndex = rowRange.Start.IsFromEnd ? RowCount - rowRange.Start.Value - 1 : rowRange.Start.Value; |
||||
|
int rowEndIndex = rowRange.End.IsFromEnd ? RowCount - rowRange.End.Value - 1 : rowRange.End.Value; |
||||
|
int rowCount = rowEndIndex - rowStartIndex + 1; |
||||
|
|
||||
|
if (rowCount <= 1 || rowCount > RowCount) |
||||
|
{ |
||||
|
throw new ArgumentException($"The argument Row Range:{rowRange} is wrong!"); |
||||
|
} |
||||
|
|
||||
|
if ((uint)columnIndex >= (uint)ColumnCount) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(nameof(columnIndex)); |
||||
|
} |
||||
|
|
||||
|
value.Storage.CopyToSubColumn(Storage, columnIndex, 0, rowStartIndex, rowCount); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Get or Set the row SubVector of the Matrix
|
||||
|
/// </summary>
|
||||
|
/// <param name="rowIndex">the column index</param>
|
||||
|
/// <param name="columnRange">the Column Range,it must contain more than one Column</param>
|
||||
|
/// <returns>a vector</returns>
|
||||
|
public Vector<T> this[int rowIndex, Range columnRange] |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
int columnStartIndex = columnRange.Start.IsFromEnd ? ColumnCount - columnRange.Start.Value - 1 : columnRange.Start.Value; |
||||
|
int columnEndIndex = columnRange.End.IsFromEnd ? ColumnCount - columnRange.End.Value - 1 : columnRange.End.Value; |
||||
|
int columnCount = columnEndIndex - columnStartIndex + 1; |
||||
|
|
||||
|
if (columnCount <= 1 || columnCount > ColumnCount) |
||||
|
{ |
||||
|
throw new ArgumentException($"The argument Column Range:{columnRange} is wrong!"); |
||||
|
} |
||||
|
|
||||
|
if ((uint)rowIndex >= (uint)RowCount) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(nameof(rowIndex)); |
||||
|
} |
||||
|
|
||||
|
var ret = Vector<T>.Build.SameAs(this, columnCount); |
||||
|
Storage.CopySubRowTo(ret.Storage, rowIndex, columnStartIndex, 0, columnCount); |
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
set |
||||
|
{ |
||||
|
int columnStartIndex = columnRange.Start.IsFromEnd ? ColumnCount - columnRange.Start.Value - 1 : columnRange.Start.Value; |
||||
|
int columnEndIndex = columnRange.End.IsFromEnd ? ColumnCount - columnRange.End.Value - 1 : columnRange.End.Value; |
||||
|
int columnCount = columnEndIndex - columnStartIndex + 1; |
||||
|
|
||||
|
if (columnCount <= 1 || columnCount > ColumnCount) |
||||
|
{ |
||||
|
throw new ArgumentException($"The argument Column Range:{columnRange} is wrong!"); |
||||
|
} |
||||
|
|
||||
|
if ((uint)rowIndex >= (uint)RowCount) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(nameof(rowIndex)); |
||||
|
} |
||||
|
|
||||
|
value.Storage.CopyToSubRow(Storage, rowIndex, 0, columnStartIndex, columnCount); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue