-
Notifications
You must be signed in to change notification settings - Fork 30
/
matrix.c
100 lines (84 loc) · 2.41 KB
/
matrix.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
/**
* @file matrix.c
* @author hutusi ([email protected])
* @brief Refer to matrix.h
* @date 2019-07-20
*
* @copyright Copyright (c) 2019, hutusi.com
*
*/
#include "matrix.h"
#include "def.h"
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
Matrix *matrix_new(unsigned int num_dimensions, ...)
{
Matrix *matrix = (Matrix *)malloc(sizeof(Matrix));
matrix->dimensions =
(unsigned int *)malloc(sizeof(unsigned int) * num_dimensions);
matrix->num_dimensions = num_dimensions;
/** todo: ensure matrix->num_data should not greater than MAX_UINT! */
matrix->num_data = 1;
va_list vl;
va_start(vl, num_dimensions);
for (int i = 0; i < num_dimensions; ++i) {
matrix->dimensions[i] = va_arg(vl, unsigned int);
matrix->num_data *= matrix->dimensions[i];
}
va_end(vl);
matrix->offsets =
(unsigned int *)malloc(sizeof(unsigned int) * num_dimensions);
unsigned int offsets = 1; // the last dimension offset * 1
for (int i = num_dimensions - 1; i >= 0; --i) {
matrix->offsets[i] = offsets;
offsets *= matrix->dimensions[i];
}
matrix->data =
(MatrixValue *)malloc(sizeof(MatrixValue) * matrix->num_data);
if (matrix->data == NULL) {
free(matrix->dimensions);
free(matrix->offsets);
free(matrix);
return NULL;
}
return matrix;
}
void matrix_free(Matrix *matrix)
{
free(matrix->dimensions);
free(matrix->offsets);
free(matrix->data);
free(matrix);
}
void matrix_reset(Matrix *matrix)
{
memset(matrix->data, 0, matrix->num_data * sizeof(MatrixValue));
}
void matrix_set(Matrix *matrix,
MatrixValue value,
unsigned int num_dimensions,
...)
{
unsigned int offset = 0;
va_list vl;
va_start(vl, num_dimensions);
for (int i = 0; i < num_dimensions; ++i) {
unsigned demension_index = va_arg(vl, unsigned int);
offset += demension_index * matrix->offsets[i];
}
va_end(vl);
matrix->data[offset] = value;
}
MatrixValue matrix_get(const Matrix *matrix, unsigned int num_dimensions, ...)
{
unsigned int offset = 0;
va_list vl;
va_start(vl, num_dimensions);
for (int i = 0; i < num_dimensions; ++i) {
unsigned demension_index = va_arg(vl, unsigned int);
offset += demension_index * matrix->offsets[i];
}
va_end(vl);
return matrix->data[offset];
}