#![allow(
dead_code,
mutable_transmutes,
non_camel_case_types,
non_snake_case,
non_upper_case_globals,
unused_assignments,
unused_mut,
clippy::all
)]
use crate::math::Vec3;
pub struct SVD {
rows: usize,
u: [[f64; 3]; 12],
v: [[f64; 3]; 3],
d: [f64; 3],
}
impl SVD {
pub fn new(mat: &[[f64; 3]]) -> Self {
let rows = mat.len();
let mut u: [[f64; 3]; 12] = [[0.; 3]; 12];
let mut v: [[f64; 3]; 3] = [[0.; 3]; 3];
let mut d: [f64; 3] = [0.; 3];
unsafe {
computeSVD(
mat.as_ptr(),
u.as_mut_ptr(),
v.as_mut_ptr(),
d.as_mut_ptr(),
rows,
)
};
Self { rows, u, v, d }
}
pub fn diagonal(&mut self) -> &mut [f64] {
&mut self.d
}
pub fn solve(mut self, vec: &[f64]) -> Vec3 {
let mut point = [0.0; 3];
let mut v = vec.to_vec();
if self.d[2 as usize as usize] < 0.1f64 {
self.d[2 as usize as usize] = 0.0f64
}
if self.d[1 as usize as usize] < 0.1f64 {
self.d[1 as usize as usize] = 0.0f64
}
if self.d[0 as usize as usize] < 0.1f64 {
self.d[0 as usize as usize] = 0.0f64
}
unsafe {
solveSVD(
self.u.as_mut_ptr(),
self.v.as_mut_ptr(),
self.d.as_mut_ptr(),
v.as_mut_ptr(),
point.as_mut_ptr(),
self.rows,
)
};
Vec3::new(point[0] as f32, point[1] as f32, point[2] as f32)
}
}
#[no_mangle]
unsafe extern "C" fn evaluateSVD(
mat: *const [f64; 3],
mut vec: *mut f64,
mut rows: usize,
mut point: *mut f64,
) {
let mut u: [[f64; 3]; 12] = [[0.; 3]; 12];
let mut v: [[f64; 3]; 3] = [[0.; 3]; 3];
let mut d: [f64; 3] = [0.; 3];
computeSVD(mat, u.as_mut_ptr(), v.as_mut_ptr(), d.as_mut_ptr(), rows);
if d[2 as usize as usize] < 0.1f64 {
d[2 as usize as usize] = 0.0f64
}
if d[1 as usize as usize] < 0.1f64 {
d[1 as usize as usize] = 0.0f64
}
if d[0 as usize as usize] < 0.1f64 {
d[0 as usize as usize] = 0.0f64
}
let mut x: [f64; 3] = [0.; 3];
solveSVD(
u.as_mut_ptr(),
v.as_mut_ptr(),
d.as_mut_ptr(),
vec,
x.as_mut_ptr(),
rows,
);
*point.offset(0) = x[0];
*point.offset(1) = x[1];
*point.offset(2) = x[2];
}
unsafe extern "C" fn computeSVD(
mat: *const [f64; 3],
mut u: *mut [f64; 3],
mut v: *mut [f64; 3],
mut d: *mut f64,
mut rows: usize,
) {
for i in 0..rows {
*u.offset(i as isize) = *mat.offset(i as isize);
}
let mut tau_u: *mut f64 = d;
let mut tau_v: [f64; 2] = [0.; 2];
factorize(u, tau_u, tau_v.as_mut_ptr(), rows);
unpack(u, v, tau_u, tau_v.as_mut_ptr(), rows);
diagonalize(u, v, tau_u, tau_v.as_mut_ptr(), rows);
singularize(u, v, tau_u, rows);
}
unsafe extern "C" fn factorize(
mut mat: *mut [f64; 3],
mut tau_u: *mut f64,
mut tau_v: *mut f64,
mut rows: usize,
) {
let mut y: usize = 0;
let mut i: usize = 0 as usize;
while i < 3 as usize {
let mut ptrs: [*mut f64; 12] = [0 as *mut f64; 12];
let mut num_ptrs: usize = rows - i;
let mut q: usize = 0 as usize;
while q < num_ptrs {
ptrs[q as usize] = &mut *(*mat.offset((q + i) as isize))
.as_mut_ptr()
.offset(i as isize) as *mut f64;
q += 1
}
let mut tau: f64 = factorize_hh(ptrs.as_mut_ptr(), num_ptrs);
*tau_u.offset(i as isize) = tau;
if (i + 1 as usize) < 3 as usize {
if tau != 0.0f64 {
let mut x: usize = i + 1 as usize;
while x < 3 as usize {
let mut wx: f64 = (*mat.offset(i as isize))[x as usize];
y = i + 1 as usize;
while y < rows {
wx += (*mat.offset(y as isize))[x as usize] * *ptrs[(y - i) as usize];
y += 1
}
let mut tau_wx: f64 = tau * wx;
(*mat.offset(i as isize))[x as usize] -= tau_wx;
y = i + 1 as usize;
while y < rows {
(*mat.offset(y as isize))[x as usize] -= tau_wx * *ptrs[(y - i) as usize];
y += 1
}
x += 1
}
}
ptrs[0 as usize as usize] = &mut *(*mat.offset(i as isize))
.as_mut_ptr()
.offset((i + 1 as usize) as isize)
as *mut f64; if i == 0 as usize {
ptrs[1 as usize as usize] = &mut *(*mat.offset(i as isize))
.as_mut_ptr()
.offset((i + 2 as usize) as isize)
as *mut f64;
num_ptrs = 2 as usize
} else {
num_ptrs = 1 as usize
}
tau = factorize_hh(ptrs.as_mut_ptr(), num_ptrs);
*tau_v.offset(i as isize) = tau;
if tau != 0.0f64 {
y = i + 1 as usize;
while y < rows {
let mut wy: f64 = (*mat.offset(y as isize))[(i + 1 as usize) as usize];
if i == 0 as usize {
wy += (*mat.offset(y as isize))[(i + 2 as usize) as usize]
* *ptrs[1 as usize as usize]
}
let mut tau_wy: f64 = tau * wy;
(*mat.offset(y as isize))[(i + 1 as usize) as usize] -= tau_wy;
if i == 0 as usize {
(*mat.offset(y as isize))[(i + 2 as usize) as usize] -=
tau_wy * *ptrs[1 as usize as usize]
}
y += 1
}
}
}
i += 1
}
}
unsafe extern "C" fn factorize_hh(mut ptrs: *mut *mut f64, mut n: usize) -> f64 {
let mut tau: f64 = 0.0f64;
if n > 1 as usize {
let mut xnorm: f64 = 0.;
if n == 2 as usize {
xnorm = (**ptrs.offset(1 as usize as isize)).abs()
} else {
let mut scl: f64 = 0.0f64;
let mut ssq: f64 = 1.0f64;
let mut i: usize = 1 as usize;
while i < n {
let mut x: f64 = (**ptrs.offset(i as isize)).abs();
if x != 0.0f64 {
if scl < x {
ssq = 1.0f64 + ssq * (scl / x) * (scl / x);
scl = x
} else {
ssq += x / scl * (x / scl)
}
}
i += 1
}
xnorm = scl * (ssq).sqrt()
}
if xnorm != 0.0f64 {
let mut alpha: f64 = **ptrs.offset(0 as usize as isize);
let mut beta: f64 = (alpha * alpha + xnorm * xnorm).sqrt();
if alpha >= 0.0f64 {
beta = -beta
}
tau = (beta - alpha) / beta;
let mut scl_0: f64 = 1.0f64 / (alpha - beta);
**ptrs.offset(0 as usize as isize) = beta;
let mut i_0: usize = 1 as usize;
while i_0 < n {
**ptrs.offset(i_0 as isize) *= scl_0;
i_0 += 1
}
}
}
return tau;
}
unsafe extern "C" fn unpack(
mut u: *mut [f64; 3],
mut v: *mut [f64; 3],
mut tau_u: *mut f64,
mut tau_v: *mut f64,
mut rows: usize,
) {
let mut i: usize = 0;
let mut y: usize = 0;
let ref mut fresh0 = (*v.offset(2 as usize as isize))[2 as usize as usize];
*fresh0 = 1.0f64;
let ref mut fresh1 = (*v.offset(1 as usize as isize))[1 as usize as usize];
*fresh1 = *fresh0;
(*v.offset(0 as usize as isize))[0 as usize as usize] = *fresh1;
let ref mut fresh2 = (*v.offset(2 as usize as isize))[1 as usize as usize];
*fresh2 = 0.0f64;
let ref mut fresh3 = (*v.offset(2 as usize as isize))[0 as usize as usize];
*fresh3 = *fresh2;
let ref mut fresh4 = (*v.offset(1 as usize as isize))[2 as usize as usize];
*fresh4 = *fresh3;
let ref mut fresh5 = (*v.offset(1 as usize as isize))[0 as usize as usize];
*fresh5 = *fresh4;
let ref mut fresh6 = (*v.offset(0 as usize as isize))[2 as usize as usize];
*fresh6 = *fresh5;
(*v.offset(0 as usize as isize))[1 as usize as usize] = *fresh6;
for i in (0..=1).rev() {
let mut tau: f64 = *tau_v.offset(i as isize);
if tau != 0.0f64 {
let mut x: usize = i + 1 as usize;
while x < 3 as usize {
let mut wx: f64 = (*v.offset((i + 1 as usize) as isize))[x as usize];
y = i + 1 as usize + 1 as usize;
while y < 3 as usize {
wx += (*v.offset(y as isize))[x as usize] * (*u.offset(i as isize))[y as usize];
y += 1
}
let mut tau_wx: f64 = tau * wx;
(*v.offset((i + 1 as usize) as isize))[x as usize] -= tau_wx;
y = i + 1 as usize + 1 as usize;
while y < 3 as usize {
(*v.offset(y as isize))[x as usize] -=
tau_wx * (*u.offset(i as isize))[y as usize];
y += 1
}
x += 1
}
}
}
i = 0 as usize;
while i < 2 as usize {
*tau_v.offset(i as isize) = (*u.offset(i as isize))[(i + 1 as usize) as usize];
i += 1
}
for i in (0..=2).rev() {
let mut tau_0: f64 = *tau_u.offset(i as isize);
*tau_u.offset(i as isize) = (*u.offset(i as isize))[i as usize];
if tau_0 == 0.0f64 {
(*u.offset(i as isize))[i as usize] = 1.0f64;
if i < 2 as usize {
(*u.offset(i as isize))[2 as usize as usize] = 0.0f64;
if i < 1 as usize {
(*u.offset(i as isize))[1 as usize as usize] = 0.0f64
}
}
y = i + 1 as usize;
while y < rows {
(*u.offset(y as isize))[i as usize] = 0.0f64;
y += 1
}
} else {
let mut x_0: usize = i + 1 as usize;
while x_0 < 3 as usize {
let mut wx_0: f64 = 0.0f64;
y = i + 1 as usize;
while y < rows {
wx_0 +=
(*u.offset(y as isize))[x_0 as usize] * (*u.offset(y as isize))[i as usize];
y += 1
}
let mut tau_wx_0: f64 = tau_0 * wx_0;
(*u.offset(i as isize))[x_0 as usize] = -tau_wx_0;
y = i + 1 as usize;
while y < rows {
(*u.offset(y as isize))[x_0 as usize] -=
tau_wx_0 * (*u.offset(y as isize))[i as usize];
y += 1
}
x_0 += 1
}
y = i + 1 as usize;
while y < rows {
(*u.offset(y as isize))[i as usize] = (*u.offset(y as isize))[i as usize] * -tau_0;
y += 1
}
(*u.offset(i as isize))[i as usize] = 1.0f64 - tau_0
}
}
}
unsafe extern "C" fn diagonalize(
mut u: *mut [f64; 3],
mut v: *mut [f64; 3],
mut tau_u: *mut f64,
mut tau_v: *mut f64,
mut rows: usize,
) {
let mut i: usize = 0;
let mut j: usize = 0;
chop(tau_u, tau_v, 3 as usize);
let mut b: usize = 3 as usize - 1 as usize;
while b > 0 as usize {
if *tau_v.offset((b - 1 as usize) as isize) == 0.0f64 {
b -= 1
} else {
let mut a: usize = b - 1 as usize;
while a > 0 as usize && *tau_v.offset((a - 1 as usize) as isize) != 0.0f64 {
a -= 1
}
let mut n: usize = b - a + 1 as usize;
let mut u1: [[f64; 3]; 12] = [[0.; 3]; 12];
let mut v1: [[f64; 3]; 3] = [[0.; 3]; 3];
j = a;
while j <= b {
i = 0 as usize;
while i < rows {
u1[i as usize][(j - a) as usize] = (*u.offset(i as isize))[j as usize];
i += 1
}
i = 0 as usize;
while i < 3 as usize {
v1[i as usize][(j - a) as usize] = (*v.offset(i as isize))[j as usize];
i += 1
}
j += 1
}
qrstep(
u1.as_mut_ptr(),
v1.as_mut_ptr(),
&mut *tau_u.offset(a as isize),
&mut *tau_v.offset(a as isize),
rows,
n,
);
j = a;
while j <= b {
i = 0 as usize;
while i < rows {
(*u.offset(i as isize))[j as usize] = u1[i as usize][(j - a) as usize];
i += 1
}
i = 0 as usize;
while i < 3 as usize {
(*v.offset(i as isize))[j as usize] = v1[i as usize][(j - a) as usize];
i += 1
}
j += 1
}
chop(
&mut *tau_u.offset(a as isize),
&mut *tau_v.offset(a as isize),
n,
);
}
}
}
unsafe extern "C" fn chop(mut a: *mut f64, mut b: *mut f64, mut n: usize) {
let mut ai: f64 = *a.offset(0 as usize as isize);
let mut i: usize = 0 as usize;
while i < n - 1 as usize {
let mut bi: f64 = *b.offset(i as isize);
let mut ai1: f64 = *a.offset((i + 1 as usize) as isize);
if bi.abs() < 1e-5f64 * (ai.abs() + ai1.abs()) {
*b.offset(i as isize) = 0.0f64
}
ai = ai1;
i += 1
}
}
unsafe extern "C" fn qrstep(
mut u: *mut [f64; 3],
mut v: *mut [f64; 3],
mut tau_u: *mut f64,
mut tau_v: *mut f64,
mut rows: usize,
mut cols: usize,
) {
let mut i: usize = 0;
if cols == 2 as usize {
qrstep_cols2(u, v, tau_u, tau_v, rows);
return;
}
if cols == 1 as usize {
let mut bomb: *mut std::os::raw::c_char = 0 as *mut std::os::raw::c_char;
*bomb = 0 as usize as std::os::raw::c_char
}
i = 0 as usize;
while i < cols - 1 as usize {
if *tau_u.offset(i as isize) == 0.0f64 {
qrstep_middle(u, tau_u, tau_v, rows, cols, i);
return;
}
i += 1
}
if *tau_u.offset((cols - 1 as usize) as isize) == 0.0f64 {
qrstep_end(v, tau_u, tau_v);
return;
}
let mut mu: f64 = qrstep_eigenvalue(tau_u, tau_v);
let mut y: f64 = *tau_u.offset(0 as usize as isize) * *tau_u.offset(0 as usize as isize) - mu;
let mut z: f64 = *tau_u.offset(0 as usize as isize) * *tau_v.offset(0 as usize as isize);
let mut ak: f64 = 0.0f64;
let mut bk: f64 = 0.0f64;
let mut zk: f64 = 0.;
let mut ap: f64 = *tau_u.offset(0 as usize as isize);
let mut bp: f64 = *tau_v.offset(0 as usize as isize);
let mut aq: f64 = *tau_u.offset(1 as usize as isize);
let mut k: usize = 0 as usize;
while k < cols - 1 as usize {
let mut c: f64 = 0.;
let mut s: f64 = 0.;
computeGivens(y, z, &mut c, &mut s);
i = 0 as usize;
while i < 3 as usize {
let mut vip: f64 = (*v.offset(i as isize))[k as usize];
let mut viq: f64 = (*v.offset(i as isize))[(k + 1 as usize) as usize];
(*v.offset(i as isize))[k as usize] = vip * c - viq * s;
(*v.offset(i as isize))[(k + 1 as usize) as usize] = vip * s + viq * c;
i += 1
}
let mut bk1: f64 = bk * c - z * s;
let mut ap1: f64 = ap * c - bp * s;
let mut bp1: f64 = ap * s + bp * c;
let mut zp1: f64 = aq * -s;
let mut aq1: f64 = aq * c;
if k > 0 as usize {
*tau_v.offset((k - 1 as usize) as isize) = bk1
}
ak = ap1;
bk = bp1;
zk = zp1;
ap = aq1;
if k < cols - 2 as usize {
bp = *tau_v.offset((k + 1 as usize) as isize)
} else {
bp = 0.0f64
}
y = ak;
z = zk;
computeGivens(y, z, &mut c, &mut s);
i = 0 as usize;
while i < rows {
let mut uip: f64 = (*u.offset(i as isize))[k as usize];
let mut uiq: f64 = (*u.offset(i as isize))[(k + 1 as usize) as usize];
(*u.offset(i as isize))[k as usize] = uip * c - uiq * s;
(*u.offset(i as isize))[(k + 1 as usize) as usize] = uip * s + uiq * c;
i += 1
}
let mut ak1: f64 = ak * c - zk * s;
bk1 = bk * c - ap * s;
let mut zk1: f64 = bp * -s;
ap1 = bk * s + ap * c;
bp1 = bp * c;
*tau_u.offset(k as isize) = ak1;
ak = ak1;
bk = bk1;
zk = zk1;
ap = ap1;
bp = bp1;
if k < cols - 2 as usize {
aq = *tau_u.offset((k + 2 as usize) as isize)
} else {
aq = 0.0f64
}
y = bk;
z = zk;
k += 1
}
*tau_v.offset((cols - 2 as usize) as isize) = bk;
*tau_u.offset((cols - 1 as usize) as isize) = ap;
}
unsafe extern "C" fn qrstep_middle(
mut u: *mut [f64; 3],
mut tau_u: *mut f64,
mut tau_v: *mut f64,
mut rows: usize,
mut cols: usize,
mut col: usize,
) {
let mut x: f64 = *tau_v.offset(col as isize);
let mut y: f64 = *tau_u.offset((col + 1 as usize) as isize);
let mut j: usize = col;
while j < cols - 1 as usize {
let mut c: f64 = 0.;
let mut s: f64 = 0.;
computeGivens(y, -x, &mut c, &mut s);
let mut i: usize = 0 as usize;
while i < rows {
let mut uip: f64 = (*u.offset(i as isize))[col as usize];
let mut uiq: f64 = (*u.offset(i as isize))[(j + 1 as usize) as usize];
(*u.offset(i as isize))[col as usize] = uip * c - uiq * s;
(*u.offset(i as isize))[(j + 1 as usize) as usize] = uip * s + uiq * c;
i += 1
}
*tau_u.offset((j + 1 as usize) as isize) = x * s + y * c;
if j == col {
*tau_v.offset(j as isize) = x * c - y * s
}
if j < cols - 2 as usize {
let mut z: f64 = *tau_v.offset((j + 1 as usize) as isize);
*tau_v.offset((j + 1 as usize) as isize) *= c;
x = z * -s;
y = *tau_u.offset((j + 2 as usize) as isize)
}
j += 1
}
}
unsafe extern "C" fn qrstep_end(mut v: *mut [f64; 3], mut tau_u: *mut f64, mut tau_v: *mut f64) {
let mut x: f64 = *tau_u.offset(1 as usize as isize);
let mut y: f64 = *tau_v.offset(1 as usize as isize);
for k in (0..=1).rev() {
let mut c: f64 = 0.;
let mut s: f64 = 0.;
computeGivens(x, y, &mut c, &mut s);
let mut i: usize = 0 as usize;
while i < 3 as usize {
let mut vip: f64 = (*v.offset(i as isize))[k as usize];
let mut viq: f64 = (*v.offset(i as isize))[2 as usize as usize];
(*v.offset(i as isize))[k as usize] = vip * c - viq * s;
(*v.offset(i as isize))[2 as usize as usize] = vip * s + viq * c;
i += 1
}
*tau_u.offset(k as isize) = x * c - y * s;
if k == 1 as usize {
*tau_v.offset(k as isize) = x * s + y * c
}
if k > 0 as usize {
let mut z: f64 = *tau_v.offset((k - 1 as usize) as isize);
*tau_v.offset((k - 1 as usize) as isize) *= c;
x = *tau_u.offset((k - 1 as usize) as isize);
y = z * s
}
}
}
unsafe extern "C" fn qrstep_eigenvalue(mut tau_u: *mut f64, mut tau_v: *mut f64) -> f64 {
let mut ta: f64 = *tau_u.offset(1 as usize as isize) * *tau_u.offset(1 as usize as isize)
+ *tau_v.offset(0 as usize as isize) * *tau_v.offset(0 as usize as isize);
let mut tb: f64 = *tau_u.offset(2 as usize as isize) * *tau_u.offset(2 as usize as isize)
+ *tau_v.offset(1 as usize as isize) * *tau_v.offset(1 as usize as isize);
let mut tab: f64 = *tau_u.offset(1 as usize as isize) * *tau_v.offset(1 as usize as isize);
let mut dt: f64 = (ta - tb) / 2.0f64;
let mut mu: f64 = 0.;
if dt >= 0.0f64 {
mu = tb - tab * tab / (dt + (dt * dt + tab * tab).sqrt())
} else {
mu = tb + tab * tab / ((dt * dt + tab * tab).sqrt() - dt)
}
return mu;
}
unsafe extern "C" fn qrstep_cols2(
mut u: *mut [f64; 3],
mut v: *mut [f64; 3],
mut tau_u: *mut f64,
mut tau_v: *mut f64,
mut rows: usize,
) {
let mut i: usize = 0;
let mut tmp: f64 = 0.;
if *tau_u.offset(0 as usize as isize) == 0.0f64 {
let mut c: f64 = 0.;
let mut s: f64 = 0.;
computeGivens(
*tau_v.offset(0 as usize as isize),
*tau_u.offset(1 as usize as isize),
&mut c,
&mut s,
);
*tau_u.offset(0 as usize as isize) =
*tau_v.offset(0 as usize as isize) * c - *tau_u.offset(1 as usize as isize) * s;
*tau_v.offset(0 as usize as isize) =
*tau_v.offset(0 as usize as isize) * s + *tau_u.offset(1 as usize as isize) * c;
*tau_u.offset(1 as usize as isize) = 0.0f64;
i = 0 as usize;
while i < rows {
let mut uip: f64 = (*u.offset(i as isize))[0 as usize as usize];
let mut uiq: f64 = (*u.offset(i as isize))[1 as usize as usize];
(*u.offset(i as isize))[0 as usize as usize] = uip * c - uiq * s;
(*u.offset(i as isize))[1 as usize as usize] = uip * s + uiq * c;
i += 1
}
i = 0 as usize;
while i < 3 as usize {
tmp = (*v.offset(i as isize))[0 as usize as usize];
(*v.offset(i as isize))[0 as usize as usize] =
(*v.offset(i as isize))[1 as usize as usize];
(*v.offset(i as isize))[1 as usize as usize] = tmp;
i += 1
}
} else if *tau_u.offset(1 as usize as isize) == 0.0f64 {
let mut c_0: f64 = 0.;
let mut s_0: f64 = 0.;
computeGivens(
*tau_u.offset(0 as usize as isize),
*tau_v.offset(0 as usize as isize),
&mut c_0,
&mut s_0,
);
*tau_u.offset(0 as usize as isize) =
*tau_u.offset(0 as usize as isize) * c_0 - *tau_v.offset(0 as usize as isize) * s_0;
*tau_v.offset(0 as usize as isize) = 0.0f64;
i = 0 as usize;
while i < 3 as usize {
let mut vip: f64 = (*v.offset(i as isize))[0 as usize as usize];
let mut viq: f64 = (*v.offset(i as isize))[1 as usize as usize];
(*v.offset(i as isize))[0 as usize as usize] = vip * c_0 - viq * s_0;
(*v.offset(i as isize))[1 as usize as usize] = vip * s_0 + viq * c_0;
i += 1
}
} else {
let mut c_1: f64 = 0.;
let mut s_1: f64 = 0.;
computeSchur(
*tau_u.offset(0 as usize as isize),
*tau_v.offset(0 as usize as isize),
*tau_u.offset(1 as usize as isize),
&mut c_1,
&mut s_1,
);
let mut a11: f64 =
*tau_u.offset(0 as usize as isize) * c_1 - *tau_v.offset(0 as usize as isize) * s_1;
let mut a21: f64 = -*tau_u.offset(1 as usize as isize) * s_1;
let mut a12: f64 =
*tau_u.offset(0 as usize as isize) * s_1 + *tau_v.offset(0 as usize as isize) * c_1;
let mut a22: f64 = *tau_u.offset(1 as usize as isize) * c_1;
i = 0 as usize;
while i < 3 as usize {
let mut vip_0: f64 = (*v.offset(i as isize))[0 as usize as usize];
let mut viq_0: f64 = (*v.offset(i as isize))[1 as usize as usize];
(*v.offset(i as isize))[0 as usize as usize] = vip_0 * c_1 - viq_0 * s_1;
(*v.offset(i as isize))[1 as usize as usize] = vip_0 * s_1 + viq_0 * c_1;
i += 1
}
if a11 * a11 + a21 * a21 < a12 * a12 + a22 * a22 {
tmp = a11;
a11 = a12;
a12 = tmp;
tmp = a21;
a21 = a22;
a22 = tmp;
i = 0 as usize;
while i < 3 as usize {
tmp = (*v.offset(i as isize))[0 as usize as usize];
(*v.offset(i as isize))[0 as usize as usize] =
(*v.offset(i as isize))[1 as usize as usize];
(*v.offset(i as isize))[1 as usize as usize] = tmp;
i += 1
}
}
computeGivens(a11, a21, &mut c_1, &mut s_1);
*tau_u.offset(0 as usize as isize) = a11 * c_1 - a21 * s_1;
*tau_v.offset(0 as usize as isize) = a12 * c_1 - a22 * s_1;
*tau_u.offset(1 as usize as isize) = a12 * s_1 + a22 * c_1;
i = 0 as usize;
while i < rows {
let mut uip_0: f64 = (*u.offset(i as isize))[0 as usize as usize];
let mut uiq_0: f64 = (*u.offset(i as isize))[1 as usize as usize];
(*u.offset(i as isize))[0 as usize as usize] = uip_0 * c_1 - uiq_0 * s_1;
(*u.offset(i as isize))[1 as usize as usize] = uip_0 * s_1 + uiq_0 * c_1;
i += 1
}
};
}
unsafe extern "C" fn computeGivens(mut a: f64, mut b: f64, mut c: *mut f64, mut s: *mut f64) {
if b == 0.0f64 {
*c = 1.0f64;
*s = 0.0f64
} else if b.abs() > a.abs() {
let mut t: f64 = -a / b;
let mut s1: f64 = 1.0f64 / (1 as usize as f64 + t * t).sqrt();
*s = s1;
*c = s1 * t
} else {
let mut t_0: f64 = -b / a;
let mut c1: f64 = 1.0f64 / (1 as usize as f64 + t_0 * t_0).sqrt();
*c = c1;
*s = c1 * t_0
};
}
unsafe extern "C" fn computeSchur(
mut a1: f64,
mut a2: f64,
mut a3: f64,
mut c: *mut f64,
mut s: *mut f64,
) {
let mut apq: f64 = a1 * a2 * 2.0f64;
if apq == 0.0f64 {
*c = 1.0f64;
*s = 0.0f64
} else {
let mut t: f64 = 0.;
let mut tau: f64 = (a2 * a2 + (a3 + a1) * (a3 - a1)) / apq;
if tau >= 0.0f64 {
t = 1.0f64 / (tau + (1.0f64 + tau * tau).sqrt())
} else {
t = -1.0f64 / ((1.0f64 + tau * tau).sqrt() - tau)
}
*c = 1.0f64 / (1.0f64 + t * t).sqrt();
*s = t * *c
};
}
unsafe extern "C" fn singularize(
mut u: *mut [f64; 3],
mut v: *mut [f64; 3],
mut d: *mut f64,
mut rows: usize,
) {
let mut i: usize = 0;
let mut j: usize = 0;
let mut y: usize = 0;
j = 0 as usize;
while j < 3 as usize {
if *d.offset(j as isize) < 0.0f64 {
i = 0 as usize;
while i < 3 as usize {
(*v.offset(i as isize))[j as usize] = -(*v.offset(i as isize))[j as usize];
i += 1
}
*d.offset(j as isize) = -*d.offset(j as isize)
}
j += 1
}
i = 0 as usize;
while i < 3 as usize {
let mut d_max: f64 = *d.offset(i as isize);
let mut i_max: usize = i;
j = i + 1 as usize;
while j < 3 as usize {
if *d.offset(j as isize) > d_max {
d_max = *d.offset(j as isize);
i_max = j
}
j += 1
}
if i_max != i {
let mut tmp: f64 = *d.offset(i as isize);
*d.offset(i as isize) = *d.offset(i_max as isize);
*d.offset(i_max as isize) = tmp;
y = 0 as usize;
while y < rows {
tmp = (*u.offset(y as isize))[i as usize];
(*u.offset(y as isize))[i as usize] = (*u.offset(y as isize))[i_max as usize];
(*u.offset(y as isize))[i_max as usize] = tmp;
y += 1
}
y = 0 as usize;
while y < 3 as usize {
tmp = (*v.offset(y as isize))[i as usize];
(*v.offset(y as isize))[i as usize] = (*v.offset(y as isize))[i_max as usize];
(*v.offset(y as isize))[i_max as usize] = tmp;
y += 1
}
}
i += 1
}
}
unsafe extern "C" fn solveSVD(
mut u: *mut [f64; 3],
mut v: *mut [f64; 3],
mut d: *mut f64,
mut b: *mut f64,
mut x: *mut f64,
mut rows: usize,
) {
let mut i: usize = 0;
let mut j: usize = 0;
let mut w: [f64; 3] = [0.; 3];
i = 0 as usize;
while i < rows {
if *b.offset(i as isize) != 0.0f64 {
j = 0 as usize;
while j < 3 as usize {
w[j as usize] += *b.offset(i as isize) * (*u.offset(i as isize))[j as usize];
j += 1
}
}
i += 1
}
i = 0 as usize;
while i < 3 as usize {
if *d.offset(i as isize) != 0.0f64 {
w[i as usize] /= *d.offset(i as isize)
}
i += 1
}
i = 0 as usize;
while i < 3 as usize {
let mut tmp: f64 = 0.0f64;
j = 0 as usize;
while j < 3 as usize {
tmp += w[j as usize] * (*v.offset(i as isize))[j as usize];
j += 1
}
*x.offset(i as isize) = tmp;
i += 1
}
}