43 float r_eigen_values[3],
44 float r_eigen_vectors[3][3])
48 if ((m3[0][1] != m3[1][0]) || (m3[0][2] != m3[2][0]) || (m3[1][2] != m3[2][1])) {
54 3, (
const float *)m3, r_eigen_values, (
float *)r_eigen_vectors);
65 void BLI_svd_m3(
const float m3[3][3],
float r_U[3][3],
float r_S[3],
float r_V[3][3])
83 const float *
a,
const float *b,
const float *
c,
const float *d,
float *r_x,
const int count)
90 double *c1 = (
double *)
MEM_mallocN(bytes * 2,
"tridiagonal_c1d1");
91 double *d1 = c1 +
count;
98 double c_prev, d_prev, x_prev;
102 c1[0] = c_prev = ((
double)
c[0]) / b[0];
103 d1[0] = d_prev = ((
double)d[0]) / b[0];
105 for (i = 1; i <
count; i++) {
106 double denum = b[i] -
a[i] * c_prev;
108 c1[i] = c_prev =
c[i] / denum;
109 d1[i] = d_prev = (d[i] -
a[i] * d_prev) / denum;
115 r_x[--i] = ((
float)x_prev);
118 x_prev = d1[i] - c1[i] * x_prev;
119 r_x[i] = ((
float)x_prev);
134 const float *
a,
const float *b,
const float *
c,
const float *d,
float *r_x,
const int count)
142 r_x[0] = d[0] / (
a[0] + b[0] +
c[0]);
149 float a2[2] = {0,
a[1] +
c[1]};
150 float c2[2] = {
a[0] +
c[0], 0};
156 float a0 =
a[0], cN =
c[
count - 1];
158 if (a0 == 0.0f && cN == 0.0f) {
162 size_t bytes =
sizeof(
float) * (
unsigned)
count;
163 float *tmp = (
float *)
MEM_mallocN(bytes * 2,
"tridiagonal_ex");
164 float *b2 = tmp +
count;
171 memcpy(b2, b, bytes);
175 memset(tmp, 0, bytes);
185 float coeff = (r_x[0] + r_x[
count - 1]) / (1.0f + tmp[0] + tmp[
count - 1]);
187 for (
int i = 0; i <
count; i++) {
188 r_x[i] -= coeff * tmp[i];
219 const float x_init[3],
222 float fdelta[3], fdeltav, next_fdeltav;
223 float jacobian[3][3], step[3],
x[3], x_next[3];
229 func_delta(userdata,
x, fdelta);
233 printf(
"START (%g, %g, %g) %g %g\n",
x[0],
x[1],
x[2], fdeltav,
epsilon);
236 for (
int i = 0; i == 0 || (i < max_iterations && fdeltav >
epsilon); i++) {
238 func_jacobian(userdata,
x, jacobian);
248 if (func_correction) {
250 printf(
"%3d * (%g, %g, %g)\n", i, x_next[0], x_next[1], x_next[2]);
253 if (!func_correction(userdata,
x, step, x_next)) {
258 func_delta(userdata, x_next, fdelta);
262 printf(
"%3d ? (%g, %g, %g) %g\n", i, x_next[0], x_next[1], x_next[2], next_fdeltav);
266 while (next_fdeltav > fdeltav && next_fdeltav >
epsilon) {
267 float g0 =
sqrtf(fdeltav), g1 =
sqrtf(next_fdeltav);
268 float g01 = -g0 /
len_v3(step);
269 float det = 2.0f * (g1 - g0 - g01);
270 float l = (det == 0.0f) ? 0.1f : -g01 / det;
276 func_delta(userdata, x_next, fdelta);
280 printf(
"%3d . (%g, %g, %g) %g\n", i, x_next[0], x_next[1], x_next[2], next_fdeltav);
285 fdeltav = next_fdeltav;
288 bool success = (fdeltav <=
epsilon);
291 printf(
"%s (%g, %g, %g) %g\n", success ?
"OK " :
"FAIL",
x[0],
x[1],
x[2], fdeltav);
typedef float(TangentPoint)[2]
bool invert_m3(float R[3][3])
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
bool(* Newton3D_CorrectionFunc)(void *userdata, const float x[3], float step[3], float x_next[3])
void(* Newton3D_JacobianFunc)(void *userdata, const float x[3], float r_jacobian[3][3])
void(* Newton3D_DeltaFunc)(void *userdata, const float x[3], float r_delta[3])
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
Strict compiler flags for areas of code we want to ensure don't do conversions without us knowing abo...
typedef double(DMatrix)[4][4]
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMLoop * l
bool EIG_self_adjoint_eigen_solve(const int size, const float *matrix, float *r_eigen_values, float *r_eigen_vectors)
void(* MEM_freeN)(void *vmemh)
void *(* MEM_mallocN)(size_t len, const char *str)
bool BLI_newton3d_solve(Newton3D_DeltaFunc func_delta, Newton3D_JacobianFunc func_jacobian, Newton3D_CorrectionFunc func_correction, void *userdata, float epsilon, int max_iterations, bool trace, const float x_init[3], float result[3])
Solve a generic f(x) = 0 equation using Newton's method.
void BLI_svd_m3(const float m3[3][3], float r_U[3][3], float r_S[3], float r_V[3][3])
Compute the SVD (Singular Values Decomposition) of given 3D matrix (m3 = USV*).
bool BLI_tridiagonal_solve(const float *a, const float *b, const float *c, const float *d, float *r_x, const int count)
Solve a tridiagonal system of equations:
bool BLI_tridiagonal_solve_cyclic(const float *a, const float *b, const float *c, const float *d, float *r_x, const int count)
Solve a possibly cyclic tridiagonal system using the Sherman-Morrison formula.
bool BLI_eigen_solve_selfadjoint_m3(const float m3[3][3], float r_eigen_values[3], float r_eigen_vectors[3][3])
Compute the eigen values and/or vectors of given 3D symmetric (aka adjoint) matrix.
void EIG_svd_square_matrix(const int size, const float *matrix, float *r_U, float *r_S, float *r_V)