-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathInverseLinkNumberMatrix.cpp
143 lines (135 loc) · 5.62 KB
/
InverseLinkNumberMatrix.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
(c) 2012 Fengtao Fan
*/
#include "InverseLinkNumberMatrix.h"
#include <fstream>
void InverseLinkNumberMatrix::add_rows(const int dst_row, const int src_row, const int multiplier,
std::vector<std::list<std::pair<int, int> > > &mat) {
// elements in each row list are ordered by the colomn number
std::list<std::pair<int, int> >::iterator srcIter = mat[src_row].begin();
std::list<std::pair<int, int> >::iterator dstIter = mat[dst_row].begin();
// scan both list by the increasing order of columns
while (srcIter != mat[src_row].end() && dstIter != mat[dst_row].end()) {
if (srcIter->first < dstIter->first) {
// insert a new element with value of srcIter->second * muliplier
mat[dst_row].insert(dstIter, std::pair<int, int>(srcIter->first, srcIter->second * multiplier));
srcIter++;
} else {
if (srcIter->first > dstIter->first) {
dstIter++;
} else {// both equal
dstIter->second = dstIter->second + srcIter->second * multiplier;
if (dstIter->second == 0) {// remove it from dst row
dstIter = mat[dst_row].erase(
dstIter); // dstIter now points to the element after the erasted element
}
srcIter++;
}
}
}
if (dstIter == mat[dst_row].end() &&
srcIter != mat[src_row].end()) {// add all elements starting srcIter to dst rows
do {
mat[dst_row].push_back(std::pair<int, int>(srcIter->first, srcIter->second * multiplier));
srcIter++;
} while (srcIter != mat[src_row].end());
}
//
return;
}
void InverseLinkNumberMatrix::ComputeInverseMatrix() {
ComputeInverseMatrix(n, org_mat);
}
void InverseLinkNumberMatrix::ComputeInverseMatrix(const int halfDim,
std::vector<std::list<std::pair<int, int> > > &inOrgMat) {
/*
* * * 1 * *
* * * 0 1 *
* * * 0 0 1
1 0 0 0 0 0
* 1 0 0 0 0
* * 1 0 0 0
The submatrix M(n:2n, 1:n) and M(1:n, n:2n) are triangular matrix
*/
// initialize inverse matrix as identity matrix
inv_mat.resize(2 * halfDim);
for (int row = 0; row < 2 * halfDim; row++) {
inv_mat[row].push_back(std::pair<int, int>(row, 1));
}
//
for (int i = halfDim; i < 2 * halfDim; i++) {
const int pivot_value = inOrgMat[i].front().second; // pivot_value == 1 or -1
for (int row = 0; row < 2 * halfDim; row++) {
if (row != i) {
std::list<std::pair<int, int> >::iterator listIter = inOrgMat[row].begin();
int multiplier = 0;
for (; listIter != inOrgMat[row].end(); listIter++) {
if (listIter->first == inOrgMat[i].front().first) {
break;
}
}
//
if (listIter != inOrgMat[row].end()) {
multiplier = -(pivot_value * listIter->second);
//
add_rows(row, i, multiplier, inOrgMat);
add_rows(row, i, multiplier, inv_mat);
}
}
}
}
//
for (int i = halfDim - 1; i >= 0; i--) {
const int pivot_value = inOrgMat[i].front().second;
for (int row = 0; row < halfDim; row++) {
if (row != i) {
std::list<std::pair<int, int> >::iterator listIter = inOrgMat[row].begin();
int multiplier = 0;
for (; listIter != inOrgMat[row].end(); listIter++) {
if (listIter->first == inOrgMat[i].front().first) {
break;
}
}
//
if (listIter != inOrgMat[row].end()) {
multiplier = -(pivot_value * listIter->second);
//
add_rows(row, i, multiplier, inOrgMat);
add_rows(row, i, multiplier, inv_mat);
}
}
}
}
}
void InverseLinkNumberMatrix::PrintMatrix(std::vector<std::list<std::pair<int, int> > > &mat) {
const int dim = (int) mat.size();
std::cout << "M=zeros(" << dim << "," << dim << ");" << std::endl;
for (int i = 0; i < dim; i++) {
//std::cout << "Vert Loop " << i << " link against " << std::endl;
for (std::list<std::pair<int, int> >::iterator listIter = mat[i].begin();
listIter != mat[i].end(); listIter++) {
std::cout << "M(" << i + 1 << "," << listIter->first + 1 << ")=" << listIter->second << ";";
}
std::cout << std::endl;
}
return;
}
void InverseLinkNumberMatrix::PrintMatrix(const char *pFileName, std::vector<std::list<std::pair<int, int> > > &mat) {
std::ofstream ofile;
ofile.open(pFileName, std::ifstream::out);
if (ofile.is_open()) {
const int dim = (int) mat.size();
ofile << "M=zeros(" << dim << "," << dim << ");" << std::endl;
for (int i = 0; i < dim; i++) {
//std::cout << "Vert Loop " << i << " link against " << std::endl;
for (std::list<std::pair<int, int> >::iterator listIter = mat[i].begin();
listIter != mat[i].end(); listIter++) {
ofile << "M(" << i + 1 << "," << listIter->first + 1 << ")=" << listIter->second << ";";
}
ofile << std::endl;
}
//
ofile.close();
}
return;
}