-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMatrix.cpp
119 lines (97 loc) · 2.99 KB
/
Matrix.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
#include "Matrix.hpp"
using namespace std;
// Class ExplicitMatrix
ExplicitMatrix::ExplicitMatrix(uint size) : stateNb(size)
{
coefficients.resize(size);
for (auto & row : coefficients)
row.resize(size);
clear(0);
};
ExplicitMatrix::ExplicitMatrix(const ExplicitMatrix& mat)
{
stateNb = mat.stateNb;
coefficients.resize(stateNb);
for (auto & row : coefficients)
row.resize(stateNb);
for (int i=0;i<stateNb;i++)
for(int j=0;j<stateNb;j++)
coefficients[i][j]=mat.coefficients[i][j];
}
void ExplicitMatrix::print(std::ostream& os) const
{
for (int i = 0; i < stateNb; i++)
{
for (int j = 0; j < stateNb; j++)
os << (int) coefficients[i][j] << " ";
os << endl;
}
}
void ExplicitMatrix::clear(unsigned char a) {
for(int i = 0; i < stateNb; i++)
for(int j = 0; j < stateNb; j++)
coefficients[i][j] = a;
}
// Constructor
Matrix::Matrix() : _hash(0)
{
};
//Random matrix
ExplicitMatrix * ExplicitMatrix::random(uint stateNb)
{
ExplicitMatrix * pe = new ExplicitMatrix(stateNb);
ExplicitMatrix & e = *pe;
auto seed = rand();
for (uint i = 0; i < Vector::GetStateNb(); i++)
{
int sel = (stateNb * rand() / RAND_MAX);
e.coefficients[i][sel] = 2;
for (uint j = 0; j < stateNb; j++)
if (j != sel)
e.coefficients[i][j] = (rand() > seed) ? 2 : 0;
}
return pe;
}
std::ostream& operator<< (std::ostream& os, const Matrix & mat){ mat.print(os); return os; };
// The set of known vectors
std::unordered_set<Vector> Matrix::vectors;
// The zero vector
const Vector * Matrix::zero_vector = NULL;
// Construct a vector obtained by multiplying the line vec by all columns of mat
const Vector * Matrix::sub_prod(const Vector * vec, const Vector ** mat){
if (vec == Matrix::zero_vector) return Matrix::zero_vector;
size_t * new_vec = (size_t *) malloc( Vector::GetBitSize() * sizeof(size_t));
memset(new_vec, 0, (size_t)(Vector::GetBitSize() * sizeof(size_t)));
for (int j = Vector::GetStateNb() - 1; j >= 0; j--)
{
bool ok = false;
if (mat[j] != Matrix::zero_vector) {
for (uint i = 0; i < Vector::GetBitSize(); i++)
{
ok = ((vec->bits[i]) & (mat[j]->bits[i])) != 0;
if (ok) break;
}
}
//update the coef with the result
//this is the part of the coef being updated
size_t * coef = new_vec + (j / (8 * sizeof(size_t)));
*coef <<= 1;
if(ok) (*coef)++;
}
/* old patch
if (!(*new_vec))
return Matrix::zero_vector;
*/
auto it = vectors.emplace(new_vec, Vector::GetStateNb()).first;
free(new_vec); new_vec = NULL;
//cout << "Final result "; (*it).print(); cout << endl;
return &(*it);
}
// Create a new vector, keep only coordinates of v that are true in tab
const Vector * Matrix::purge(const Vector *varg, const Vector * tab){
size_t * new_vec = (size_t *)malloc(Vector::GetBitSize() * sizeof(size_t));
for (uint i = 0; i < Vector::GetBitSize(); i++)
new_vec[i] = ((varg->bits[i]) & (tab->bits[i]));
auto it = vectors.emplace(new_vec, false).first;
return &(*it);
}