You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
451 lines
8.5 KiB
451 lines
8.5 KiB
#include <iostream>
|
|
#include <fstream>
|
|
#include <iomanip>
|
|
#include "matconv.h"
|
|
#include "sparmat.h"
|
|
|
|
using namespace std;
|
|
|
|
matlist::matlist()
|
|
{
|
|
col = -1;
|
|
next = 0;
|
|
}
|
|
|
|
void matlist::print()
|
|
{
|
|
cout << "col = " << col;
|
|
}
|
|
|
|
list2::list2()
|
|
{
|
|
next = 0;
|
|
matListPtr = 0;
|
|
}
|
|
|
|
matconv::matconv()
|
|
{
|
|
dim = 0;
|
|
NZ = 0;
|
|
newMem = 0;
|
|
matDiag = 0;
|
|
type = SYMMETRIC;
|
|
|
|
allocPos = new list2;
|
|
tmpList2 = allocPos;
|
|
}
|
|
|
|
matconv::~matconv()
|
|
{
|
|
deleteMemory();
|
|
}
|
|
|
|
void matconv::deleteMemory()
|
|
{
|
|
list2* nextPtr = NULL;
|
|
tmpList2 = allocPos;
|
|
|
|
while (tmpList2->next != 0) {
|
|
delete [] tmpList2->matListPtr;
|
|
nextPtr = tmpList2->next;
|
|
delete tmpList2;
|
|
tmpList2 = nextPtr;
|
|
}
|
|
delete tmpList2;
|
|
delete [] matDiag;
|
|
}
|
|
|
|
void matconv::setDim(int n)
|
|
{
|
|
int i;
|
|
|
|
dim = n;
|
|
NZ = n;
|
|
matDiag = new matlist[n];
|
|
for (i = 0; i < dim; i++) {
|
|
matDiag[i].col = i;
|
|
if (i != (dim - 1)) matDiag[i].next = &(matDiag[i + 1]);
|
|
}
|
|
}
|
|
|
|
void matconv::setNsDim(int n)
|
|
{
|
|
int i;
|
|
|
|
dim = n;
|
|
matDiag = new matlist[n];
|
|
for (i = 0; i < dim; i ++) {
|
|
matDiag[i].col = -1;
|
|
matDiag[i].next = 0;
|
|
}
|
|
|
|
type = NON_SYMMETRIC;
|
|
}
|
|
|
|
void matconv::init(int n)
|
|
{
|
|
int i;
|
|
|
|
dim = n;
|
|
NZ = n;
|
|
matDiag = new matlist[n];
|
|
|
|
if (type != NON_SYMMETRIC) {
|
|
for (i = 0; i < dim; i ++) {
|
|
matDiag[i].col = i;
|
|
matDiag[i].next = 0;
|
|
}
|
|
} else {
|
|
for (i = 0; i < dim; i ++) {
|
|
matDiag[i].col = 0;
|
|
matDiag[i].next = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void matconv::addentry(int r, int c)
|
|
{
|
|
matlist *pEntry, *cEntry;
|
|
|
|
// only store the upper half of the matrix
|
|
if (r < 0 || c < 0) return;
|
|
if (c < r) return;
|
|
if (r == c) return;
|
|
if (r == (dim - 1)) return;
|
|
|
|
pEntry = &(matDiag[r]);
|
|
cEntry = pEntry->next;
|
|
while (cEntry != &(matDiag[r + 1])) {
|
|
if (cEntry->col > c) {
|
|
if (newMem == 0) blockMemory(dim);
|
|
pEntry->next = newMem;
|
|
newMem = newMem->next;
|
|
pEntry = pEntry->next;
|
|
pEntry->col = c;
|
|
pEntry->next = cEntry;
|
|
NZ++;
|
|
return;
|
|
}
|
|
if (cEntry->col == c) return;
|
|
|
|
pEntry = cEntry;
|
|
cEntry = cEntry->next;
|
|
}
|
|
|
|
if (newMem == 0) blockMemory(dim);
|
|
pEntry->next = newMem;
|
|
newMem = newMem->next;
|
|
pEntry = pEntry->next;
|
|
pEntry->col = c;
|
|
pEntry->next = cEntry;
|
|
NZ++;
|
|
}
|
|
|
|
void matconv::addNsEntry(int r, int c)
|
|
{
|
|
matlist *pEntry, *cEntry;
|
|
|
|
// only store the upper half of the matrix
|
|
if (r < 0 || c < 0) return;
|
|
|
|
pEntry = &(matDiag[r]);
|
|
cEntry = pEntry->next;
|
|
while (cEntry != 0) {
|
|
if (cEntry->col > c) {
|
|
if (newMem == 0) blockMemory(dim);
|
|
pEntry->next = newMem;
|
|
newMem = newMem->next;
|
|
pEntry = pEntry->next;
|
|
pEntry->col = c;
|
|
pEntry->next = cEntry;
|
|
NZ ++;
|
|
return;
|
|
}
|
|
if (cEntry->col == c) return;
|
|
|
|
pEntry = cEntry;
|
|
cEntry = cEntry->next;
|
|
}
|
|
|
|
if (newMem == 0) blockMemory(dim);
|
|
pEntry->next = newMem;
|
|
newMem = newMem->next;
|
|
pEntry = pEntry->next;
|
|
pEntry->col = c;
|
|
pEntry->next = cEntry;
|
|
NZ ++;
|
|
}
|
|
|
|
void matconv::blockMemory(int n)
|
|
{
|
|
int i;
|
|
matlist *bMem;
|
|
|
|
bMem = new matlist[n];
|
|
for (i = 0; i < n; i++) {
|
|
if (i != (n - 1)) bMem[i].next = &(bMem[i + 1]);
|
|
}
|
|
|
|
newMem = &(bMem[0]);
|
|
|
|
// added to keep track of the positions we add memery,
|
|
// in order to delete it correctly at the end
|
|
tmpList2->matListPtr = newMem;
|
|
tmpList2->next = new list2;
|
|
tmpList2 = tmpList2->next;
|
|
}
|
|
|
|
void matconv::conversion(sparMat *A)
|
|
{
|
|
int i, counter;
|
|
matlist *cEntry;
|
|
|
|
A->sparInit(dim, NZ);
|
|
|
|
counter = 0;
|
|
for (i = 0; i < (dim - 1); i++) {
|
|
A->setJA(counter, i);
|
|
A->setIA(i, counter);
|
|
counter++;
|
|
|
|
cEntry = matDiag[i].next;
|
|
while (cEntry != &(matDiag[i + 1])) {
|
|
A->setJA(counter, cEntry->col);
|
|
counter++;
|
|
|
|
cEntry = cEntry->next;
|
|
}
|
|
}
|
|
A->setJA(counter, dim - 1);
|
|
A->setIA(dim - 1, counter);
|
|
counter++;
|
|
A->setIA(dim, counter);
|
|
// cout << " NZ = " << NZ << ", COUNTER = " << counter << endl;
|
|
}
|
|
|
|
void matconv::blockAddEntry(int n, int *map)
|
|
{
|
|
int i, j, row, col;
|
|
|
|
for (i = 0; i < n; i++) {
|
|
row = map[i];
|
|
if (row < 0) continue;
|
|
if (row >= dim) {
|
|
cout << "ERROR: ID " << row << " is greater than " << dim
|
|
<< endl;
|
|
}
|
|
|
|
for (j = 0; j < n; j++) {
|
|
col = map[j];
|
|
if (col < 0) continue;
|
|
|
|
addentry(row, col);
|
|
}
|
|
}
|
|
}
|
|
|
|
void matconv::blockAddEntry(int n, int *rowMap, int *colMap)
|
|
{
|
|
int i, j, row, col;
|
|
|
|
for (i = 0; i < n; i++) {
|
|
row = rowMap[i];
|
|
if (row < 0) continue;
|
|
if (row >= dim) {
|
|
cout << "ERROR: ID " << row << " is greater than " << dim
|
|
<< endl;
|
|
}
|
|
|
|
for (j = 0; j < n; j++) {
|
|
col = colMap[j];
|
|
if (col < 0) continue;
|
|
|
|
addentry(row, col);
|
|
}
|
|
}
|
|
}
|
|
|
|
void matconv::blockAddEntry(int rowDim, int colDim, int *rowMap, int *colMap)
|
|
{
|
|
int i, j, row, col;
|
|
|
|
for (i = 0; i < rowDim; i ++) {
|
|
row = rowMap[i];
|
|
if (row < 0) continue;
|
|
if (row >= dim) {
|
|
cout << "ERROR: ID " << row << " is greater than " << dim << endl;
|
|
}
|
|
for (j = 0; j < colDim; j ++) {
|
|
col = colMap[j];
|
|
if (col < 0) continue;
|
|
|
|
if (type == NON_SYMMETRIC) addNsEntry(row, col);
|
|
else addentry(row, col);
|
|
}
|
|
}
|
|
}
|
|
|
|
void matconv::freeMemory(matlist *entry)
|
|
{
|
|
entry->col = -100;
|
|
entry->next = newMem;
|
|
newMem = entry;
|
|
}
|
|
|
|
void matconv::print()
|
|
{
|
|
int i;
|
|
matlist *curPtr;
|
|
cout << "MATCONV" << endl;
|
|
cout << "dim=" << dim << endl;
|
|
cout << "NZ=" << NZ << endl;
|
|
for (i = 0; i < dim; i++) {
|
|
cout << "matDiag[" << i << "]" << endl;
|
|
matDiag[i].print();
|
|
curPtr = &(matDiag[i]);
|
|
while(curPtr->next !=0) {
|
|
curPtr = curPtr->next;
|
|
curPtr->print();
|
|
}
|
|
}
|
|
}
|
|
|
|
void matconv::setDimNonSymm(int n)
|
|
{
|
|
int i;
|
|
|
|
dim = n;
|
|
NZ = n;
|
|
|
|
// matDiag = new matlist[n+1];
|
|
// for (i = 0; i < dim+1; i ++) {
|
|
// matDiag[i].col = 0;
|
|
// if (i != (dim - 1)) matDiag[i].next = &(matDiag[i + 1]);
|
|
// }
|
|
|
|
matDiag = new matlist[n+1];
|
|
for (i = 0; i < dim+1; i ++) {
|
|
matDiag[i].col = 0;
|
|
matDiag[i].next = 0;//&(matDiag[i + 1]);
|
|
}
|
|
}
|
|
|
|
void matconv::addentryNonSymm(int r, int c)
|
|
{
|
|
matlist *pEntry, *cEntry;
|
|
|
|
// store entire matrix
|
|
if (r < 0 || c < 0) return;
|
|
// if (c == 0) return;
|
|
// if (c < r) return;
|
|
// if (r == c) return;
|
|
// if (r == (dim - 1)) return;
|
|
|
|
pEntry = &(matDiag[r]);
|
|
cEntry = pEntry->next;
|
|
// while (cEntry != &(matDiag[r + 1])) {
|
|
while (cEntry != 0) {
|
|
if (cEntry->col > c) {
|
|
if (newMem == 0) blockMemory(dim);
|
|
pEntry->next = newMem;
|
|
newMem = newMem->next;
|
|
pEntry = pEntry->next;
|
|
pEntry->col = c;
|
|
pEntry->next = cEntry;
|
|
NZ ++;
|
|
return;
|
|
}
|
|
if (cEntry->col == c) return;
|
|
|
|
pEntry = cEntry;
|
|
cEntry = cEntry->next;
|
|
}
|
|
|
|
if (newMem == 0) blockMemory(dim);
|
|
pEntry->next = newMem;
|
|
newMem = newMem->next;
|
|
pEntry = pEntry->next;
|
|
pEntry->col = c;
|
|
pEntry->next = cEntry;
|
|
NZ ++;
|
|
}
|
|
|
|
void matconv::blockAddEntryNonSymm(int rowDim, int colDim,
|
|
int *rowMap, int *colMap)
|
|
{
|
|
int i, j, row, col;
|
|
|
|
for (i = 0; i < rowDim; i ++) {
|
|
row = rowMap[i];
|
|
if (row < 0) continue;
|
|
if (row >= dim) {
|
|
cout << "ERROR: ID " << row << " is greater than " << dim << endl;
|
|
}
|
|
for (j = 0; j < colDim; j ++) {
|
|
col = colMap[j];
|
|
if (col < 0) continue;
|
|
|
|
addentryNonSymm(row, col);
|
|
}
|
|
}
|
|
}
|
|
|
|
void matconv::conversionNonSymm(sparMat *A)
|
|
{
|
|
int i, counter;
|
|
matlist *cEntry;
|
|
|
|
// A->sparInit(dim, NZ);
|
|
A->sparInitNonSymm(dim, NZ);
|
|
|
|
counter = 0;
|
|
// for (i = 0; i < (dim - 1); i ++) {
|
|
for (i = 0; i < dim; i ++) {
|
|
A->setJA(counter, i);
|
|
A->setIA(i, counter);
|
|
counter ++;
|
|
cEntry = matDiag[i].next;
|
|
// while (cEntry != &(matDiag[i + 1])) {
|
|
while (cEntry != 0) {
|
|
A->setJA(counter, cEntry->col);
|
|
counter ++;
|
|
|
|
cEntry = cEntry->next;
|
|
}
|
|
}
|
|
// A->setJA(counter, dim - 1);
|
|
// A->setIA(dim - 1, counter);
|
|
// counter ++;
|
|
A->setIA(dim, counter);
|
|
// cout << " NZ = " << NZ << ", COUNTER = " << counter << endl;
|
|
}
|
|
|
|
void matconv::conversion(sparMat *A, int rowDim, int colDim)
|
|
{
|
|
int i, counter;
|
|
matlist *cEntry;
|
|
|
|
A->sparINIT(rowDim, colDim, NZ);
|
|
counter = 0;
|
|
for (i = 0; i < (dim); i ++) {
|
|
A->setIA(i, counter);
|
|
|
|
if (matDiag[i].next == 0) continue;
|
|
|
|
cEntry = matDiag[i].next;
|
|
while (cEntry->col >= 0) {
|
|
A->setJA(counter, cEntry->col);
|
|
counter ++;
|
|
|
|
if (cEntry->next == 0) break;
|
|
cEntry = cEntry->next;
|
|
}
|
|
}
|
|
if (NZ != counter) {
|
|
cout << "Error in non-symmetric conversion" << endl;
|
|
cout << " NZ = " << NZ << ", COUNTER = " << counter << endl;
|
|
exit(1);
|
|
}
|
|
cout << " NZ = " << NZ << ", COUNTER = " << counter << endl;
|
|
A->setIA(dim, counter);
|
|
}
|
|
|