26 float r_eigen_values[3],
27 float r_eigen_vectors[3][3])
31 if ((m3[0][1] != m3[1][0]) || (m3[0][2] != m3[2][0]) || (m3[1][2] != m3[2][1])) {
37 3, (
const float *)m3, r_eigen_values, (
float *)r_eigen_vectors);
40void BLI_svd_m3(
const float m3[3][3],
float r_U[3][3],
float r_S[3],
float r_V[3][3])
48 const float *a,
const float *
b,
const float *c,
const float *d,
float *r_x,
const int count)
58 double *d1 = c1 +
count;
61 double c_prev, d_prev, x_prev;
65 c1[0] = c_prev = double(c[0]) /
b[0];
66 d1[0] = d_prev = double(d[0]) /
b[0];
69 double denum =
b[
i] - a[
i] * c_prev;
71 c1[
i] = c_prev = c[
i] / denum;
72 d1[
i] = d_prev = (d[
i] - a[
i] * d_prev) / denum;
81 x_prev = d1[
i] - c1[
i] * x_prev;
87 return isfinite(x_prev);
91 const float *a,
const float *
b,
const float *c,
const float *d,
float *r_x,
const int count)
99 r_x[0] = d[0] / (a[0] +
b[0] + c[0]);
101 return isfinite(r_x[0]);
106 const float a2[2] = {0, a[1] + c[1]};
107 const float c2[2] = {a[0] + c[0], 0};
113 float a0 = a[0], cN = c[
count - 1];
115 if (a0 == 0.0f && cN == 0.0f) {
124 float *b2 = tmp +
count;
127 memcpy(b2,
b, bytes);
131 memset(tmp, 0, bytes);
141 float coeff = (r_x[0] + r_x[
count - 1]) / (1.0f + tmp[0] + tmp[
count - 1]);
144 r_x[
i] -= coeff * tmp[
i];
160 const float x_init[3],
163 float fdelta[3], fdeltav, next_fdeltav;
164 float jacobian[3][3],
step[3],
x[3], x_next[3];
170 func_delta(userdata,
x, fdelta);
174 printf(
"START (%g, %g, %g) %g %g\n",
x[0],
x[1],
x[2], fdeltav, epsilon);
179 func_jacobian(userdata,
x, jacobian);
189 if (func_correction) {
191 printf(
"%3d * (%g, %g, %g)\n",
i, x_next[0], x_next[1], x_next[2]);
194 if (!func_correction(userdata,
x,
step, x_next)) {
199 func_delta(userdata, x_next, fdelta);
203 printf(
"%3d ? (%g, %g, %g) %g\n",
i, x_next[0], x_next[1], x_next[2], next_fdeltav);
207 while (next_fdeltav > fdeltav && next_fdeltav > epsilon) {
208 float g0 =
sqrtf(fdeltav), g1 =
sqrtf(next_fdeltav);
210 float det = 2.0f * (g1 - g0 - g01);
211 float l = (det == 0.0f) ? 0.1f : -g01 / det;
217 func_delta(userdata, x_next, fdelta);
221 printf(
"%3d . (%g, %g, %g) %g\n",
i, x_next[0], x_next[1], x_next[2], next_fdeltav);
226 fdeltav = next_fdeltav;
229 bool success = (fdeltav <= epsilon);
232 printf(
"%s (%g, %g, %g) %g\n", success ?
"OK " :
"FAIL",
x[0],
x[1],
x[2], fdeltav);
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
bool invert_m3(float mat[3][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
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)
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
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)