-
Notifications
You must be signed in to change notification settings - Fork 0
/
matrix.hpp
143 lines (140 loc) · 3.4 KB
/
matrix.hpp
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
#ifndef PAGERANK_INCLUDE_MATRIX_H
#define PAGERANK_INCLUDE_MATRIX_H
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
namespace pagerank{
// Row represent a line in a matrix
template <typename T>
struct Row{
int n;
T *rdata;
Row(){
n = 0;
rdata = NULL;
}
void set_row(int n, T *rdata){
assert(n > 0);
this->n = n;
this->rdata = rdata;
}
T& operator[](int j){
assert(j >= 0 && j < n);
return rdata[j];
}
~Row(){
rdata = NULL;
}
};
template <typename T>
class Matrix{
protected:
// m rows and n cols
int m;
int n;
Row<T> *data;
public:
Matrix(){
m = n = 0;
data = NULL;
}
void initialize(int m, int n, T *_data){
// ensure parameter _m and _n are all valid
assert(m > 0 && n > 0);
this->m = m;
this->n = n;
T *buf;
assert((buf = (T*)calloc(m * n, sizeof(T))) != NULL);
if(_data){
memcpy(buf, _data, sizeof(T) * m*n);
}
// allocate memory for each row in a matrix
assert((data = new Row<T>[m]) != NULL);
for(int i = 0; i < m; ++i){
data[i].set_row(n, buf+i*n);
}
}
Matrix(int m, int n, T *_data = NULL){
initialize(m, n, _data);
}
void clear(){
if(data != NULL && data[0].rdata != NULL){
free(data[0].rdata);
}
if(data){
delete[] data;
}
data = NULL;
}
~Matrix(){
clear();
}
Row<T>& operator[](int i) const{
assert(i >= 0 && i < m);
return data[i];
}
int row_size() const{
return m;
}
int col_size() const{
return n;
}
Matrix operator*(const Matrix<T> &other){
// precondtion
assert(n == other.row_size());
// res is result to be returned
int res_col = other.col_size();
// create res to store result
Matrix<T> res(m, res_col);
for(int i = 0; i < m; ++i){
for(int j = 0; j < res_col; ++j){
res[i][j] = 0;
// matrix A, B: sum of aik * bkj, k from 1 to n
for(int k = 0; k < n; ++k){
res[i][j] += data[i][k] * other[k][j];
}
}
}
// overload operator=
return res;
}
// avoid shadow copy
void operator=(const Matrix<T> &other){
if(&other == this)return;
// this is not empty
if(this->m != 0){
clear();
}
this->m = other.row_size();
this->n = other.col_size();
// empty, don't need to copy data
if(m <= 0 || n <= 0)return;
initialize(m, n, NULL);
for(int i = 0; i < m; ++i){
for(int j = 0; j < n; ++j){
data[i][j] = other[i][j];
}
}
}
void operator+=(const Matrix<T> &other){
// allow add itself
if(m != other.row_size() || n != other.col_size())return;
assert(m > 0 && n > 0 && data != NULL);
for(int i = 0; i < m; ++i){
for(int j = 0; j < n; ++j){
data[i][j] += other[i][j];
}
}
}
void print(){
for(int i = 0; i < m; ++i){
for(int j = 0; j < n; ++j){
printf("%f ", data[i][j]);
}
printf("\n");
}
}
};
};
#endif