#include #include #include #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); }