📄 sparsem.cpp
字号:
// SparseMatrix.cpp : implementation file
//
#include "stdafx.h"
#include <math.h>
#define __SPARSE_DLL__
#include "Sparsem.h"
//修改2003.3.29---------------------------394
//修改2003.3.30--------------------------1916
//添加函数2003.3.31----------------------2823
//添加函数2003.4.31----------------------2836
//修改2003.4.9---------------------------2069
//===============================================================
//wl.1997
CSparseMatrix::CSparseMatrix()
// 初始化双链表和三角形表
{
List.nza = 0; // 非零元素个数
List.n = 0; // 矩阵阶数
List.row = NULL; // 元素行号
List.col = NULL; // 元素列号
List.up = NULL; // 元素的上邻元素号
List.down = NULL; // 元素的下邻元素号
List.left = NULL; // 元素的左邻元素号
List.right = NULL; // 元素的右邻元素号
List.del = NULL; // 元素删除标志: 1=删除
List.rp = NULL; // 行链指针
List.cp = NULL; // 列链指针
Table.nza = 0; // 非零元素个数
Table.n = 0; // 矩阵阶数
Table.lun = 0; // 由符号 LU 分解确定的需修正的元素个数
Table.fen = 0; // 由符号前消确定的需修正的向量元素个数
Table.val = NULL; // 矩阵及右端向量/中间解向量元素值
Table.roco = NULL; // 对角元素行列号, U 元素列号, L 元素行号
Table.urp = NULL; // U 阵行指针
Table.lcp = NULL; // L 阵列指针
Table.lup = NULL; // 由符号 LU 分解确定的需修正的元素号
Table.fep = NULL; // 前消需修正的元素号
TableC.nza = 0; // 非零元素个数
TableC.n = 0; // 矩阵阶数
TableC.lun = 0; // 由符号 LU 分解确定的需修正的元素个数
TableC.fen = 0; // 由符号前消确定的需修正的向量元素个数
TableC.vre = NULL; // 矩阵及右端向量/中间解向量元素实部值
TableC.vim = NULL; // 矩阵及右端向量/中间解向量元素虚部值
TableC.roco = NULL; // 对角元素行列号, U 元素列号, L 元素行号
TableC.urp = NULL; // U 阵行指针
TableC.lcp = NULL; // L 阵列指针
TableC.lup = NULL; // 由符号 LU 分解确定的需修正的元素号
TableC.fep = NULL; // 前消需修正的元素号
Table_T.nza = 0; // 非零元素个数
Table_T.n = 0; // 矩阵阶数
Table_T.lun = 0; // 由符号 LU 分解确定的需修正的元素个数
Table_T.fen = 0; // 由符号前消确定的需修正的向量元素个数
Table_T.val = NULL; // 矩阵及右端向量/中间解向量元素值
Table_T.roco = NULL; // 对角元素行列号, U 元素列号, L 元素行号
Table_T.urp = NULL; // U 阵行指针
Table_T.lcp = NULL; // L 阵列指针
Table_T.lup = NULL; // 由符号 LU 分解确定的需修正的元素号
Table_T.fep = NULL; // 前消需修正的元素号
NewOldR = NULL; // 新=》旧行号,新=》旧行/列号
NewOldC = NULL; // 新=》旧列号
OldNewR = NULL; // 旧=》新行号,旧=》新行/列号
OldNewC = NULL; // 旧=》新列号
x1 = NULL;
x2 = NULL; // 存储数值用
}
CSparseMatrix::~CSparseMatrix()
{
memfree();
}
//1997.3.18 增加删除函数
void CSparseMatrix::memfree()
{
if(NewOldR) delete NewOldR;
if(NewOldC) delete NewOldC;
if(OldNewR) delete OldNewR;
if(OldNewC) delete OldNewC;
if(x1) delete x1;
if(x2) delete x2;
NewOldR = NULL; // 新=》旧行号,新=》旧行/列号
NewOldC = NULL; // 新=》旧列号
OldNewR = NULL; // 旧=》新行号,旧=》新行/列号
OldNewC = NULL; // 旧=》新列号
x1 = NULL;
x2 = NULL; // 存储数值用
delete_table(Table); // 删除三角形表
delete_table(TableC); // 删除复数三角形表
delete_list(List); // 删除双链表
}
//================================================================
void CSparseMatrix::new_list(LINKED_LIST &list)
// 生成双链表结构 list, 最大阶数为 rank_max, 非零元素数为 nonzero
{
INT2 i;
list.nza = 0; // 非零元素个数
list.n = 0; // 矩阵阶数
ASSERT (maxNonzero);
list.row=new INT2[maxNonzero];
list.col=new INT2[maxNonzero];
list.up=new INT2[maxNonzero];
list.down=new INT2[maxNonzero];
list.left=new INT2[maxNonzero];
list.right=new INT2[maxNonzero];
list.del=new char[maxNonzero];
ASSERT (maxRank);
list.rp=new INT2[maxRank];
list.cp=new INT2[maxRank];
list.nza=0;
for(i=0;i<maxRank;i++)
{
list.rp[i]=0;
list.cp[i]=0;
}
for(i=0;i<maxNonzero;i++)
{
list.row[i]=0;
list.col[i]=0;
list.up[i]=0;
list.down[i]=0;
list.left[i]=0;
list.right[i]=0;
list.del[i]=0;
}
};
//=========================================================================
void CSparseMatrix::clr_list(LINKED_LIST &list)
// 清零双链表结构 list, 最大阶数为 rank_max, 非零元素数为 nonzero
{
INT2 i;
list.nza = 0; // 非零元素个数
list.n = 0; // 矩阵阶数
for(i=0;i<maxRank;i++)
{
list.rp[i]=0;
list.cp[i]=0;
}
for(i=0;i<maxNonzero;i++)
{
list.row[i]=0;
list.col[i]=0;
list.up[i]=0;
list.down[i]=0;
list.left[i]=0;
list.right[i]=0;
list.del[i]=0;
}
};
//=========================================================================
void CSparseMatrix::delete_list(LINKED_LIST &list)
// 删除双链表结构 list
{
if(list.row) delete list.row;
if(list.col) delete list.col;
if(list.up) delete list.up;
if(list.down) delete list.down;
if(list.left) delete list.left;
if(list.right) delete list.right;
if(list.del) delete list.del;
if(list.rp) delete list.rp;
if(list.cp) delete list.cp;
list.row = NULL;
list.col = NULL;
list.up = NULL;
list.down = NULL;
list.left = NULL;
list.right = NULL;
list.del = NULL;
list.rp = NULL;
list.cp = NULL;
list.nza = 0; // 非零元素个数
list.n = 0; // 矩阵阶数
};
//===============================================================================
void CSparseMatrix::new_table(INT2 rank_max,INT2 nonzero,TRIANGULAR_TABLE &table)
// 生成三角形表结构 table, 最大阶数为 rank_max, 非零元素数为 nonzero
{
INT2 i,non;
table.nza = 0; // 非零元素个数
table.n = 0; // 矩阵阶数
table.lun = 0; // 由符号 LU 分解确定的需修正的元素个数
table.fen = 0; // 由符号前消确定的需修正的向量元素个数
ASSERT (nonzero);
ASSERT (rank_max);
table.val=new double[nonzero];
table.roco=new INT2[nonzero];
table.urp=new INT2[rank_max];
table.lcp=new INT2[rank_max];
table.lup=new INT2[nonzero];
non=rank_max*5;
ASSERT (non);
table.fep=new INT2[non];
for(i=0;i<nonzero;i++) table.val[i]=0;
};
//==========================================================================
void CSparseMatrix::new_table(INT2 rank_max,INT2 nonzero,TRIANGULAR_TABLE_C &table)
// 生成复数三角形表结构 table, 最大阶数为 rank_max, 非零元素数为 nonzero
{
INT2 i,non;
table.nza = 0; // 非零元素个数
table.n = 0; // 矩阵阶数
table.lun = 0; // 由符号 LU 分解确定的需修正的元素个数
table.fen = 0; // 由符号前消确定的需修正的向量元素个数
ASSERT (nonzero);
table.vre=new double[nonzero];
table.vim=new double[nonzero];
table.roco=new INT2[nonzero];
ASSERT (rank_max);
table.urp=new INT2[rank_max];
table.lcp=new INT2[rank_max];
non=rank_max*5;
ASSERT (non);
table.lup=new INT2[non];
table.fep=new INT2[non];
for(i=0;i<nonzero;i++)
{
table.vre[i]=0;
table.vim[i]=0;
}
};
//==========================================================================
void CSparseMatrix::delete_table(TRIANGULAR_TABLE &table)
// 删除三角形表结构 table
{
if(table.val) delete table.val;
table.val = NULL;
if(table.roco) delete table.roco;
table.roco = NULL;
if(table.urp) delete table.urp;
table.urp = NULL;
if(table.lcp) delete table.lcp;
table.lcp = NULL;
if(table.lup) delete table.lup;
table.lup = NULL;
if(table.fep) delete table.fep;
table.fep = NULL;
table.nza = 0; // 非零元素个数
table.n = 0; // 矩阵阶数
table.lun = 0; // 由符号 LU 分解确定的需修正的元素个数
table.fen = 0; // 由符号前消确定的需修正的向量元素个数
};
//=========================================================================
void CSparseMatrix::delete_table(TRIANGULAR_TABLE_C &table)
// 删除复数三角形表结构 table
{
if(table.vre) delete table.vre;
table.vre = NULL;
if(table.vim) delete table.vim;
table.vim = NULL;
if(table.roco) delete table.roco;
table.roco = NULL;
if(table.urp) delete table.urp;
table.urp = NULL;
if(table.lcp) delete table.lcp;
table.lcp = NULL;
if(table.lup) delete table.lup;
table.lup = NULL;
if(table.fep) delete table.fep;
table.fep = NULL;
table.nza = 0; // 非零元素个数
table.n = 0; // 矩阵阶数
table.lun = 0; // 由符号 LU 分解确定的需修正的元素个数
table.fen = 0; // 由符号前消确定的需修正的向量元素个数
};
//==========================================================================
char CSparseMatrix::insert_row(INT2 nza, INT2 x, INT2 y, LINKED_LIST &list)
// 在双链接表 list 所描述的稀疏矩阵行链中, 插入第 nza 号元素 a[x][y]
{
INT2 k,k1,z;
k=list.rp[x];
if(k==0){ // 第 x 行还未有非零元素, a[x][y] 为其第一个元素
list.rp[x]=nza;
list.left[nza]=0;
list.right[nza]=0;
return(0);
}
for(;;){ // 搜索第 x 行非零元素
z=list.col[k]; // a[x][z] 为非零元素
if(y<z){
k1=list.left[k];
if(k1==0){ // k 为原行首, nza 在其左, 为新行首
list.left[nza]=0;
list.right[nza]=k;
list.left[k]=nza;
list.rp[x]=nza;
}
else{ // nza 在 k1 和 k 之间
list.left[nza]=k1;
list.right[nza]=k;
list.left[k]=nza;
list.right[k1]=nza;
}
return(0);
}
else if(y>z){ // nza 在 k 右
k1=list.right[k];
if(k1==0){ // k 为原行尾, nza 在其右, 为新行尾
list.right[nza]=0;
list.right[k]=nza;
list.left[nza]=k;
return(0);
}
k=k1; // 右边还有非零元素, 继续向右搜索
continue;
}
else{ // y=z, a[x][y] 已存在
return(1);
}
}
};
// =========================================================================
char CSparseMatrix::insert_col(INT2 nza, INT2 x, INT2 y, LINKED_LIST &list)
// 在双链接表 list 所描述的稀疏矩阵列链中, 插入第 nza 号元素 a[x][y]
{
INT2 k,k1,z;
k=list.cp[y];
if(k==0){ // 第 y 列还未有非零元素, a[x][y] 为其第一个元素
list.cp[y]=nza;
list.up[nza]=0;
list.down[nza]=0;
return(0);
}
for(;;){ // 搜索第 y 列非零元素
z=list.row[k]; // a[x][z] 为非零元素
if(x<z){
k1=list.up[k];
if(k1==0){ // k 为原列首, nza 在其上, 为新列首
list.up[nza]=0;
list.down[nza]=k;
list.up[k]=nza;
list.cp[y]=nza;
}
else{ // nza 在 k1 和 k 之间
list.up[nza]=k1;
list.down[nza]=k;
list.up[k]=nza;
list.down[k1]=nza;
}
return(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -