// File: /workspace/github_c_makefile_star2_O2/ugobas[P]tnm/nma.c
// Function: Convert_cart2torsion
int Convert_cart2torsion(struct Tors *D, struct Reference Ref,
			 struct Jacobian *J)
{
  // Formula: (LL^t)Delta_theta = JM Delta_r  with:
  // L=T_sqrt (lower diagonal matrix if obtained from Cholevsky decomposition)
  // T=JMJ^t = LL^t
  // J is the jacobian matrix dr_int_i/d_theta_a
  // M_i is the diagonal mass matrix.
  // ==> L^t Delta_theta = L^{-1} J M Delta_r = Jtilde M Delta_r
  // To solve the equation:
  // Compute x=Jtilde MDelta_r =Masswtd_Tors
  // solve x=L^t Delta_theta (by backward substitution if T_sqrt lower diagonal)
  // Return the torsional fraction,
  // sum_i m_i (J d_theta)^2/sum_i m_i Dr_i^2

  double sum=0; int i, j, a;
  if(J->Jtilde_ar==NULL)Compute_Jtilde(J);

  // Compute Masswtd_Tors_dev = Jtilde M Delta_r
  for(a=0; a<J->N_axes; a++){
    float *Jt=J->Jtilde_ar[a], *r=D->Cart, *m=Ref.mass_coord;
    sum=0; for(j=0; j<J->N_Cart; j++)sum+=m[j]*r[j]*Jt[j];
    D->MW_Tors[a]=sum;
  }
  if(J->T_sqrt_inv){
    // T_sqrt is not lower diagonal!
    for(a=0; a<J->N_axes; a++){
      sum=0;
      for(i=0; i<J->N_axes; i++)sum+=J->T_sqrt_inv[i][a]*D->MW_Tors[i];
      D->Tors[a]=sum;
    }
  }else{
    // Exploit that T_sqrt is lower diagonal
    // Backward_substitution
    // theta_i =(x_i - sum_j>i L_ji x_j)/L_ii
    for(i=J->N_axes-1; i>=0; i--){
      D->Tors[i]=D->MW_Tors[i];
      for(j=i+1; j<J->N_axes; j++)D->Tors[i]-=D->Tors[j]*J->T_sqrt[j][i];
      D->Tors[i]/=J->T_sqrt[i][i];
    }
  }
  return(0);
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x20(%rsp), %r15
cmpq $0x0, 0x18(%rsi)
jne 0x23b60
movq %r14, %rdi
callq 0x209d5
movl (%r14), %eax
movq 0x18(%r15), %rdx
xorl %esi, %esi
testl %eax, %eax
movl $0x0, %ecx
cmovgl %eax, %ecx
xorl %edi, %edi
cmpq %rcx, %rdi
je 0x23bcf
movq 0x18(%r14), %r8
movq (%r8,%rdi,8), %r8
movq 0x8(%rbx), %r9
movl 0x4(%r14), %r10d
testl %r10d, %r10d
cmovlel %esi, %r10d
xorpd %xmm0, %xmm0
xorl %r11d, %r11d
cmpq %r11, %r10
je 0x23bbc
movss (%rdx,%r11,4), %xmm1
mulss (%r9,%r11,4), %xmm1
mulss (%r8,%r11,4), %xmm1
cvtss2sd %xmm1, %xmm1
addsd %xmm1, %xmm0
incq %r11
jmp 0x23b98
cvtsd2ss %xmm0, %xmm0
movq 0x10(%rbx), %r8
movss %xmm0, (%r8,%rdi,4)
incq %rdi
jmp 0x23b75
movq 0x30(%r14), %rdx
testq %rdx, %rdx
je 0x23c20
xorl %esi, %esi
cmpq %rcx, %rsi
je 0x23c84
xorps %xmm0, %xmm0
xorl %edi, %edi
cmpq %rdi, %rax
je 0x23c0e
movq (%rdx,%rdi,8), %r8
movss (%r8,%rsi,4), %xmm1
movq 0x10(%rbx), %r8
mulss (%r8,%rdi,4), %xmm1
cvtss2sd %xmm1, %xmm1
addsd %xmm1, %xmm0
incq %rdi
jmp 0x23be8
cvtsd2ss %xmm0, %xmm0
movq 0x18(%rbx), %rdi
movss %xmm0, (%rdi,%rsi,4)
incq %rsi
jmp 0x23bda
movq %rax, %rcx
testl %ecx, %ecx
jle 0x23c84
leaq -0x1(%rcx), %rdx
movq 0x10(%rbx), %rdi
movq 0x18(%rbx), %rsi
movss (%rdi,%rdx,4), %xmm0
movss %xmm0, (%rsi,%rdx,4)
cvtss2sd %xmm0, %xmm0
cmpl %ecx, %eax
jle 0x23c69
cvtss2sd (%rsi,%rcx,4), %xmm1
movq 0x28(%r14), %rdi
movq (%rdi,%rcx,8), %rdi
mulsd (%rdi,%rdx,8), %xmm1
subsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, (%rsi,%rdx,4)
incq %rcx
jmp 0x23c3d
movq 0x28(%r14), %rcx
movq (%rcx,%rdx,8), %rcx
divsd (%rcx,%rdx,8), %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, (%rsi,%rdx,4)
movq %rdx, %rcx
jmp 0x23c23
xorl %eax, %eax
popq %rbx
popq %r14
popq %r15
retq