-
Notifications
You must be signed in to change notification settings - Fork 0
/
amatrix.c
156 lines (141 loc) · 3.26 KB
/
amatrix.c
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
144
145
146
147
148
149
150
151
152
153
154
155
#include "amatrix.h"
#include <malloc.h>
#include <math.h>
#include <assert.h>
fp_t get_random(fp_t min, fp_t max)
{
const fp_t range = max - min;
return ((fp_t)rand() * range) / RAND_MAX + min;
}
Matrix* aligned_vector(const int size, bool randomize)
{
fp_t* v = memalign(ALIGN_BYTES, size * sizeof(fp_t));
if (v == NULL) {
printf("Error allocating memory!");
exit(-1);
}
if (randomize) {
for (int i = 0; i < size; i++) {
v[i] = get_random(-5, 5);
}
} else {
for (int i = 0; i < size; i++) {
v[i] = 0;
}
}
Matrix* m = malloc(sizeof(Matrix));
m->width = size;
m->height = 1;
m->size = size;
m->elements = v;
return m;
}
Matrix* aligned_matrix(const int rows, bool randomize)
{
Matrix* m = aligned_vector(rows * rows, randomize);
m->height = rows;
m->width = rows;
m->size = rows * rows;
return m;
}
fp_t get_abs_row_sum(const Matrix* matrix, const int row)
{
fp_t row_sum = 0;
for (int j = 0; j < matrix->width; j++) {
row_sum += fabs(matrix->elements[row * matrix->width + j]);
}
return row_sum;
}
fp_t get_max_row_sum(const Matrix* matrix)
{
fp_t max_row_sum = 0;
for (int i = 0; i < matrix->width; i++) {
const fp_t row_sum = get_abs_row_sum(matrix, i);
if (row_sum > max_row_sum) {
max_row_sum = row_sum;
}
}
return max_row_sum;
}
Matrix* make_diag_dominant(Matrix* matrix)
{
const fp_t row_sum = get_max_row_sum(matrix);
for (int i = 0; i < matrix->width; i++) {
const int index = i * matrix->width + i;
matrix->elements[index] += get_random(1.5, 2) * (row_sum - fabs(matrix->elements[index]));
}
return matrix;
}
Matrix* aligned_multiply(const Matrix* matrix, const Matrix* vector)
{
assert(matrix->width == vector->width);
Matrix* b = aligned_vector(matrix->height, false);
const int size = matrix->width;
for (int i = 0; i < size; i++) {
b->elements[i] = 0;
for (int j = 0; j < size; j++) {
b->elements[i] += matrix->elements[i * size + j] * vector->elements[j];
}
}
return b;
}
DataSet generate_dataset(const int rows)
{
DataSet dataset;
dataset.A = make_diag_dominant(aligned_matrix(rows, true));
dataset.x = aligned_vector(rows, true);
dataset.b = aligned_multiply(dataset.A, dataset.x);
return dataset;
}
fp_t matrix_diff(const Matrix* a, const Matrix* b)
{
assert(a->width == b->width);
assert(a->height == b->height);
const int size = a->width;
fp_t max_diff = 0;
fp_t curr_diff;
for (int i = 0; i < size; i++) {
curr_diff = fabs(a->elements[i] - b->elements[i]);
if (curr_diff > max_diff)
max_diff = curr_diff;
}
return max_diff;
}
fp_t array_mean(const fp_t* a, const int size)
{
fp_t mean = 0;
for (int i = 0; i < size; i++) {
mean += a[i];
}
mean /= size;
return mean;
}
fp_t array_std(const fp_t* a, const int size)
{
const fp_t mean = array_mean(a, size);
fp_t acc = 0;
for (int i = 0; i < size; i++) {
acc += pow(a[i] - mean, 2);
}
return sqrt(acc);
}
void print_matrix(const Matrix* a)
{
for (int i = 0; i < a->height; i++) {
for (int j = 0; j < a->width; j++) {
printf("%f, ", a->elements[i * a->width + j]);
}
}
printf("\n");
}
fp_t rmse(const Matrix* a, const Matrix* b)
{
assert(a->width == b->width);
assert(a->height == b->height);
fp_t res = 0;
for (int i = 0; i < a->width; i++) {
res += pow((a->elements[i] - b->elements[i]), 2);
}
res = sqrt(res);
return res;
}