This repository has been archived by the owner on Mar 2, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathlinear-algebra.cpp
68 lines (51 loc) · 1.94 KB
/
linear-algebra.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
#include <cstdlib>
#include <cstring>
#include <sys/types.h>
#include "linear-algebra.h"
namespace ewald {
void matrix_vector_product(double const* A, double* X) {
double Y[] = { 0.0, 0.0, 0.0 };
for (size_t i = 0; i < 3; ++i)
for (size_t j = 0; j < 3; ++j)
Y[i] += A[3*i+j] * X[j];
memcpy(X, Y, 3 * sizeof(double));
}
void matrix_vector_product_transpose(double const* A, double* X) {
double Y[] = { 0.0, 0.0, 0.0 };
for (size_t i = 0; i < 3; ++i)
for (size_t j = 0; j < 3; ++j)
Y[i] += A[3*j+i] * X[j];
memcpy(X, Y, 3 * sizeof(double));
}
void matrix_matrix_product(double const* A, double const* B, double* C) {
memset(C, 0, 3 * 3 * sizeof(double));
for (size_t i = 0; i < 3; ++i)
for (size_t j = 0; j < 3; ++j)
for (size_t k = 0; k < 3; ++k)
C[3*i+j] += A[3*i+k] * B[3*k+j];
}
double determinant(double const* A) {
return A[3*0+0] * (A[3*1+1] * A[3*2+2] - A[3*1+2] * A[3*2+1])
- A[3*0+1] * (A[3*1+0] * A[3*2+2] - A[3*1+2] * A[3*2+0])
+ A[3*0+2] * (A[3*1+0] * A[3*2+1] - A[3*1+1] * A[3*2+0]);
}
void matrix_inverse(double const* A, double* Ainv) {
const double invdet = 1.0 / determinant(A);
memset(Ainv, 0, 3 * 3 * sizeof(double));
Ainv[3*0+0] = ( A[3*1+1]*A[3*2+2] - A[3*1+2]*A[3*2+1]) * invdet;
Ainv[3*0+1] = (-A[3*0+1]*A[3*2+2] + A[3*0+2]*A[3*2+1]) * invdet;
Ainv[3*0+2] = ( A[3*0+1]*A[3*1+2] - A[3*0+2]*A[3*1+1]) * invdet;
Ainv[3*1+0] = (-A[3*1+0]*A[3*2+2] + A[3*1+2]*A[3*2+0]) * invdet;
Ainv[3*1+1] = ( A[3*0+0]*A[3*2+2] - A[3*0+2]*A[3*2+0]) * invdet;
Ainv[3*1+2] = (-A[3*0+0]*A[3*1+2] + A[3*0+2]*A[3*1+0]) * invdet;
Ainv[3*2+0] = ( A[3*1+0]*A[3*2+1] - A[3*1+1]*A[3*2+0]) * invdet;
Ainv[3*2+1] = (-A[3*0+0]*A[3*2+1] + A[3*0+1]*A[3*2+0]) * invdet;
Ainv[3*2+2] = ( A[3*0+0]*A[3*1+1] - A[3*0+1]*A[3*1+0]) * invdet;
}
double dot_product(double const* u, double const* v) {
double result = 0.0;
for (size_t k = 0; k < 3; ++k)
result += u[k] * v[k];
return result;
}
}