Matrix class update.

This commit is contained in:
Krad
2023-04-19 15:54:52 +08:00
parent 0d98d313a5
commit 3b7c918cf1
4 changed files with 296 additions and 50 deletions

View File

@@ -292,34 +292,67 @@ namespace Aurora {
void Matrix::printf() {
::printf("[");
for (int i = 0; i < mInfo[0]; ++i) {
int k_count = getDimSize(2)==0?1:getDimSize(2);
int j_count = getDimSize(1)==0?1:getDimSize(1);
for (int k = 0; k <k_count; ++k) {
::printf("slice %d:\r\n[",k);
for (int i = 0; i < getDimSize(0); ++i) {
::printf("[");
for (int j = 0; j < mInfo[1]; ++j) {
::printf("%f2, ",getData()[getDimSize(0)*j+i]);
for (int j = 0; j < j_count; ++j) {
::printf("%f2, ",getData()[k*getDimSize(1)*getDimSize(0)+j*getDimSize(0)+i]);
}
::printf("]\r\n");
}
::printf("]\r\n");
}
}
Matrix::MatrixSlice Matrix::operator()(int aRowIdx, int aColIdx, int s) const {
if (aRowIdx == ALL_DIM) {
return Matrix::MatrixSlice((int) (aColIdx > 0 ? getDimSize(0) : getDataSize()), 1,
getData() + getDimSize(0) * (aColIdx > 0 ? aColIdx : 0));
Matrix::MatrixSlice Matrix::operator()(int aRowIdx, int aColIdx, int aSliceIdx) const {
std::vector<int> dims = {aRowIdx, aColIdx, aSliceIdx};
std::vector<int> allDimIndex;
int mode = 0;
for (int j = 0; j < 3; ++j) {
if (dims[j]==$ && this->getDims()>j){
++mode;
allDimIndex.push_back(j);
}
}
else if (aColIdx == ALL_DIM){
return Matrix::MatrixSlice((int) (aRowIdx > 0 ? getDimSize(1) : getDataSize()), getDimSize(0),
getData() +(aRowIdx > 0 ? aRowIdx : 0));
int rowStride = 1;
int colStride = getDimSize(0);
int sliceStride = getDimSize(0)*getDimSize(1);
int strides[3] = {rowStride, colStride, sliceStride};
int rowOffset = aRowIdx == $ ? 0 : aRowIdx;
int colOffset = aColIdx == $ ? 0 : aColIdx;
int sliceOffset = aSliceIdx == $ ? 0 : aSliceIdx;
double *startPointer = getData() + (rowStride * rowOffset
+ colStride * colOffset
+ sliceStride * sliceOffset) * getValueType();
int size1 = getDimSize(allDimIndex[0]);
int stride1 = strides[allDimIndex[0]];
switch (mode) {
//matrix mode
case 2:{
int size2 = getDimSize(allDimIndex[1]);
int stride2 = strides[allDimIndex[1]];
return Matrix::MatrixSlice(size1, stride1, startPointer, getValueType(), mode, size2, stride2);
}
//vector mode & default
case 1:
{
return Matrix::MatrixSlice(size1, stride1, startPointer, getValueType(), mode);
}
//scalar mode or ALL $
case 0:
default: {
return Matrix::MatrixSlice(1 , 1, startPointer,getValueType(), mode);
}
}
return Matrix::MatrixSlice(1, 1, getData()+ getDimSize(0) * aColIdx +aRowIdx );
}
Matrix::MatrixSlice::MatrixSlice(int aSize,int aStride, double* aData, ValueType aType):
mData(aData),
mSize(aSize),
mStride(aStride),
Matrix::MatrixSlice::MatrixSlice(int aSize,int aStride, double* aData, ValueType aType, int aSliceMode,int aSize2, int aStride2):
mSliceMode(aSliceMode),mData(aData),
mSize(aSize),mSize2(aSize2),
mStride(aStride),mStride2(aStride2),
mType(aType)
{
@@ -327,26 +360,150 @@ namespace Aurora {
Matrix::MatrixSlice &Matrix::MatrixSlice::operator=(const Matrix::MatrixSlice &slice) {
if (this==&slice) return *this;
if (mSize == slice.mSize && mType == slice.mType){
if (mType== Normal)cblas_dcopy(mSize,slice.mData,slice.mStride,mData,mStride);
else cblas_zcopy(mSize,(std::complex<double>*)slice.mData,slice.mStride,(std::complex<double>*)mData,mStride);
if(!mData){
std::cerr <<"Assign value fail!Des data pointer is null!";
return *this;
}
if(!slice.mData){
std::cerr <<"Assign value fail!Src data pointer is null!";
return *this;
}
if (slice.mSliceMode!=mSliceMode) {
std::cerr <<"Assign value fail!Src slice(dims count:"<< slice.mSliceMode <<"), not match of des(dims count:"<<mSliceMode<<")!";
return *this;
}
if (slice.mSize!=mSize) {
std::cerr <<"Assign value fail!Src slice(dim 1 size:"<< slice.mSize <<"), not match of des(dim 1 size:"<<mSize<<")!";
return *this;
}
if (slice.mSize2!=mSize2) {
std::cerr <<"Assign value fail!Src slice(dim 2 size:"<< slice.mSize2 <<"), not match of des(dim 2 size:"<<mSize2<<")!";
return *this;
}
if (slice.mType!=mType) {
std::cerr <<"Assign value fail!Src slice(value type:"<< slice.mType <<"), not match of des(value type:"<<mType<<")!";
return *this;
}
switch (mSliceMode) {
case 2:{
if (mType== Normal) {
cblas_dcopy_batch_strided(mSize, slice.mData, slice.mStride, slice.mStride2, mData, mStride,
mStride2, mSize2);
}
else {
cblas_zcopy_batch_strided(mSize,(std::complex<double>*)slice.mData,slice.mStride,slice.mStride2,
(std::complex<double>*)mData,mStride,mStride2,mSize2);
}
break;
}
case 1:{
if (mType== Normal){
cblas_dcopy(mSize,slice.mData,slice.mStride,mData,mStride);
}
else {
cblas_zcopy(mSize, (std::complex<double> *) slice.mData, slice.mStride,
(std::complex<double> *) mData, mStride);
}
break;
}
case 0:
default:{
mData[0] = slice.mData[0];
if (mType != Normal)mData[1] = slice.mData[1];
}
}
return *this;
}
Matrix::MatrixSlice &Matrix::MatrixSlice::operator=(const Matrix &matrix) {
if (mSize == matrix.getDataSize() && mType == matrix.getValueType()){
if (mType== Normal)cblas_dcopy(mSize,matrix.getData(),1,mData,mStride);
else cblas_zcopy(mSize,(std::complex<double>*)matrix.getDataSize(),1,(std::complex<double>*)mData,mStride);
if(!mData){
std::cerr <<"Assign value fail!Des data pointer is null!";
return *this;
}
if(!matrix.getData()){
std::cerr <<"Assign value fail!Src data pointer is null!";
return *this;
}
if (matrix.getDims()!=mSliceMode) {
std::cerr <<"Assign value fail!Src matrix(dims count:"<< matrix.getDims() <<"), not match of des(dims count:"<<mSliceMode<<")!";
return *this;
}
if (matrix.getDimSize(0)!=mSize) {
std::cerr <<"Assign value fail!Src matrix(dim 1 size:"<< matrix.getDimSize(0)<<"), not match of des(dim 1 size:"<<mSize<<")!";
return *this;
}
if (matrix.getDimSize(1)!=mSize2) {
std::cerr <<"Assign value fail!Src slice(dim 2 size:"<< matrix.getDimSize(1) <<"), not match of des(dim 2 size:"<<mSize2<<")!";
return *this;
}
if (matrix.getValueType()!=mType) {
std::cerr <<"Assign value fail!Src slice(value type:"<< matrix.getValueType() <<"), not match of des(value type:"<<mType<<")!";
return *this;
}
switch (mSliceMode) {
case 2:{
if (mType== Normal) {
cblas_dcopy_batch_strided(mSize, matrix.getData(), 1, matrix.getDimSize(0), mData, mStride,
mStride2, mSize2);
}
else {
cblas_zcopy_batch_strided(mSize,(std::complex<double>*)matrix.getData(),1,matrix.getDimSize(0),
(std::complex<double>*)mData,mStride,mStride2,mSize2);
}
break;
}
case 1:{
if (mType== Normal){
cblas_dcopy(mSize,matrix.getData(),1,mData,mStride);
}
else {
cblas_zcopy(mSize, (std::complex<double> *) matrix.getData(),1,
(std::complex<double> *) mData, mStride);
}
break;
}
case 0:
default:{
mData[0] = matrix.getData()[0];
if (mType != Normal)mData[1] = matrix.getData()[1];
}
}
return *this;
}
Matrix Matrix::MatrixSlice::toMatrix() {
auto data = malloc(mSize ,mType == Complex);
if (mType== Normal)cblas_dcopy(mSize,mData,mStride,data,1);
else cblas_zcopy(mSize,(std::complex<double>*)mData,mStride,(std::complex<double>*)data,1);
return Matrix::New(data,mSize,0,0,mType);
auto data = (double *) mkl_malloc(mSize*(mSize2>0?mSize2:1) * sizeof(double)*mType, 64);
auto matrix = Matrix::New(data,mSize,mSize2,0,mType);
switch (mSliceMode) {
case 2:{
if (mType== Normal) {
cblas_dcopy_batch_strided(mSize, mData, mStride,
mStride2,matrix.getData(), 1, matrix.getDimSize(0), mSize2);
}
else {
cblas_zcopy_batch_strided(mSize, (std::complex<double> *) mData, mStride, mStride2,
(std::complex<double> *) matrix.getData(), 1, matrix.getDimSize(0),
mSize2);
}
break;
}
case 1:{
if (mType== Normal){
cblas_dcopy(mSize,mData,mStride,matrix.getData(),1);
}
else {
cblas_zcopy(mSize, (std::complex<double> *) mData, mStride,
(std::complex<double> *) matrix.getData(), 1);
}
break;
}
case 0:
default:{
matrix.getData()[0]= mData[0];
if (mType != Normal) matrix.getData()[1] = mData[1];
}
}
return matrix;
}
}