redesign matrix design
This commit is contained in:
@@ -25,10 +25,12 @@
|
||||
//
|
||||
// -----------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------
|
||||
using StgSharp.HighPerformance;
|
||||
using StgSharp.HighPerformance.Memory;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -37,21 +39,72 @@ namespace StgSharp.Mathematics.Numeric
|
||||
public unsafe partial class Matrix<T>
|
||||
{
|
||||
|
||||
private const int KernelSideLength = 4;
|
||||
|
||||
public static Matrix<T> Create(
|
||||
int columnLength,
|
||||
int rowLength,
|
||||
MatrixLayout layout,
|
||||
HybridLayerSegregatedFitAllocator allocator)
|
||||
{
|
||||
Matrix<T> matrix = new Matrix<T>();
|
||||
int tSize = sizeof(T);
|
||||
int totalSize = columnLength * rowLength * tSize;
|
||||
HybridLayerSegregatedFitAllocationHandle handle = allocator.Alloc((uint)totalSize);
|
||||
MatrixStorageHLSF<T> storage = new MatrixStorageHLSF<T>(handle);
|
||||
storage._handle = handle;
|
||||
ArgumentNullException.ThrowIfNull(allocator);
|
||||
|
||||
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(columnLength);
|
||||
|
||||
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(rowLength);
|
||||
|
||||
int kernelColumns = DivideRoundUp(columnLength, KernelSideLength);
|
||||
int kernelRows = DivideRoundUp(rowLength, KernelSideLength);
|
||||
|
||||
if (layout is MatrixLayout.UpperTriangle or MatrixLayout.LowerTriangle)
|
||||
{
|
||||
if (kernelColumns != kernelRows) {
|
||||
throw new ArgumentException("Triangular layouts require square matrices.");
|
||||
}
|
||||
}
|
||||
|
||||
long kernelCount = layout switch
|
||||
{
|
||||
MatrixLayout.DenseSquare => (long)kernelColumns * kernelRows,
|
||||
MatrixLayout.UpperTriangle => TriangularKernelCount(kernelColumns),
|
||||
MatrixLayout.LowerTriangle => TriangularKernelCount(kernelRows),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(layout))
|
||||
};
|
||||
|
||||
long requiredBytes = kernelCount * MatrixKernel<T>.Size;
|
||||
if (requiredBytes <= 0 || requiredBytes > uint.MaxValue) {
|
||||
throw new ArgumentOutOfRangeException(nameof(requiredBytes), "Requested matrix exceeds allocator capacity.");
|
||||
}
|
||||
|
||||
HybridLayerSegregatedFitAllocationHandle handle = allocator.Alloc((uint)requiredBytes);
|
||||
MatrixStorageHLSF<T> storage = new MatrixStorageHLSF<T>(allocator, handle);
|
||||
|
||||
Matrix<T> matrix = new Matrix<T>
|
||||
{
|
||||
Layout = layout,
|
||||
KernelColumnLength = kernelColumns,
|
||||
KernelRowLength = kernelRows,
|
||||
};
|
||||
|
||||
matrix._buffer = storage;
|
||||
matrix._enumeration = new MatrixMetadata(columnLength, rowLength);
|
||||
matrix._boarder = MatrixKernelBoarder.Create(layout);
|
||||
matrix._size = new MatrixSize(columnLength, rowLength, kernelColumns, kernelRows);
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static int DivideRoundUp(int value, int divisor)
|
||||
{
|
||||
return (value + (divisor - 1)) / divisor;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static long TriangularKernelCount(int order)
|
||||
{
|
||||
long n = order;
|
||||
return (n * (n + 1L)) / 2L;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user