forked from fritzo/jenn3d
-
Notifications
You must be signed in to change notification settings - Fork 0
/
linalg.h
194 lines (164 loc) · 5.06 KB
/
linalg.h
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/*
This file is part of Jenn.
Copyright 2001-2007 Fritz Obermeyer.
Jenn is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Jenn is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Jenn; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef JENN_LINALG_H
#define JENN_LINALG_H
#include <cmath>
#include <complex>
#include <vector>
#include <cstdlib>
typedef std::complex<float> complex;
#include "definitions.h"
#ifndef M_PI
#define M_PI 3.1415926535897
#endif
namespace std {
std::ostream& operator<< (std::ostream& os, const std::vector<int>& v);
} // namespace std
namespace LinAlg
{
const Logging::Logger logger("linalg", Logging::INFO);
}
//[ linear algebra shite ]----------------------------------
/* conventions:
[x, y, z, w] - first two are screen space,
- thrid is out-of-screen vector
- fourth is the center (hidden) dimension
*/
struct Vect
{
float data[4];
float& operator[] (int i) { return data[i]; }
float operator[] (int i) const { return data[i]; }
//void operator= (float x) { data[3] = data[2] = data[1] = data[0] = x; }
void operator+= (const Vect& v)
{ for (int i=0; i<4; ++i) data[i] += v[i]; }
void operator*= (float c)
{ for (int i=0; i<4; ++i) data[i] *= c; }
};
inline Vect const_vect (float x)
{
Vect result;
for (int i=0; i<4; ++i) result[i] = x;
return result;
}
struct Mat
{
Vect data[4];
Vect& operator[] (int i) { return data[i]; }
Vect operator[] (int i) const { return data[i]; }
};
inline float g_sqrt (float num) { return num>0 ? sqrt(num) : 0; }
inline float sqr (float num) { return num*num; }
inline float inner (const Vect &a, const Vect &b) //inner product
{
return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3];
}
inline float inner3 (const Vect &a, const Vect &b) //inner product
{
return a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
}
inline void cross3 (const Vect &a, const Vect &b, Vect &c)
{
c[0] = a[1]*b[2] - a[2]*b[1];
c[1] = a[2]*b[0] - a[0]*b[2];
c[2] = a[0]*b[1] - a[1]*b[0];
}
void cross4 (const Vect &a, const Vect &b, const Vect &c, Vect &d);
inline float norm (const Vect &a)
{
return sqrt(sqr(a[0]) + sqr(a[1]) + sqr(a[2]) + sqr(a[3]));
}
inline float r3_norm(const Vect &a)
{
return sqrt(sqr(a[0]) + sqr(a[1]) + sqr(a[2]));
}
inline float r3_dist_sqr(const Vect &a, const Vect &b)
{
return sqr(a[0]-b[0]) + sqr(a[1]-b[1]) + sqr(a[2]-b[2]);
}
inline float r4_dist (const Vect& a, const Vect& b)
{
return sqrt( sqr(a[0]-b[0])
+ sqr(a[1]-b[1])
+ sqr(a[2]-b[2])
+ sqr(a[3]-b[3]) );
}
inline void normalize (Vect &a)
{
const float norm = sqrt(sqr(a[0]) + sqr(a[1]) + sqr(a[2]) + sqr(a[3]));
a[0] /= norm;
a[1] /= norm;
a[2] /= norm;
a[3] /= norm;
}
inline bool normalize3(Vect &a)
{//returns true if normalizable
const float norm = sqrtf(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]);
if (norm <= 0) return false;
a[0] /= norm;
a[1] /= norm;
a[2] /= norm;
return true;
}
inline void vect_iadd (Vect &a, const Vect &b)
{//a += b
for (int i=0; i<4; ++i) a[i] += b[i];
}
inline void vect_scale (Vect&a, float s, const Vect& b)
{//a = s * b
for (int i=0; i<4; ++i) { a[i] = b[i] * s; }
}
inline void vect_isadd (Vect&a, float s, const Vect& b)
{//a *= s * b
for (int i=0; i<4; ++i) { a[i] += b[i] * s; }
}
void make_ortho (Mat &M);
void make_asym (Mat &M);
void mat_iscale (Mat &a, float t);
void mat_iadd (Mat &a, const Mat &b);
void mat_isub (Mat &a, const Mat &b);
void mat3_iadd (Mat &a, const Mat &b);
void mat_mult (const Mat &a, const Mat &b, Mat &c);
void mat_trans (const Mat &a, Mat &b);
void mat_conj (const Mat &a, const Mat &b, Mat &c);
void mat_copy (const Mat &a, Mat &b);
void vect_mult (const Mat &a, const Vect &b, Vect &c);
void vect_imul (const Mat &a, Vect &b);
void mat_zero (Mat &a);
void mat_identity (Mat &a);
void mat_inverse (const Mat &a, Mat &b);
void mat_rot (int i, int j, float theta, Mat &a);
void print_matrix (const Mat &a);
float rand_gauss ();
void rand_asym_mat (Mat &a, float sigma=1.0f);
inline float random_unif ()
{
#ifndef CYGWIN_HACKS
return drand48();
#else
return static_cast<float>(rand()) / RAND_MAX;
#endif
}
//[ geometry stuff ]----------
void build_geom (const int *coxeter_utriang,
const std::vector<std::vector<int> >& vertex_coset,
const std::vector<std::vector<int> >& gens,
const std::vector<std::vector<int> >& v_cogens,
const Vect& weights,
std::vector<Mat>& gen_reps,
Vect &origin);
complex hopf_phase (Vect &e);
#endif