bool TShapeB1::evaluate_with_hess( const MsqMatrix<3,3>& T,
                                   double& result,
                                   MsqMatrix<3,3>& deriv_wrt_T,
                                   MsqMatrix<3,3> second_wrt_T[6],
                                   MsqError& err )
{
  double d = det(T);
  if (invalid_determinant(d)) {
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
  
  double id = 1.0/d;
  double norm = Frobenius(T);
  double den = 1.0/(3 * MSQ_SQRT_THREE * d);
  double norm_cube = norm*norm*norm;
  result = norm_cube * den - 1.0;
  MsqMatrix<3,3> adjt = transpose_adj(T);
  deriv_wrt_T = T;
  deriv_wrt_T *= 3 * norm * den;
  deriv_wrt_T -= norm_cube * den * id * transpose_adj(T);
 
  set_scaled_outer_product( second_wrt_T, 3 * den / norm, T );
  pluseq_scaled_I( second_wrt_T, 3 * norm * den );
  pluseq_scaled_2nd_deriv_of_det( second_wrt_T, -den * norm_cube * id, T );
  pluseq_scaled_outer_product( second_wrt_T, 2 * den * norm_cube * id * id , adjt );
  pluseq_scaled_sum_outer_product( second_wrt_T, -3 * norm * den * id, T, adjt );

  return true;
}
Ejemplo n.º 2
0
bool TShape3DB2::evaluate_with_hess( const MsqMatrix<3,3>& T,
                                     double& result,
                                     MsqMatrix<3,3>& wrt_T,
                                     MsqMatrix<3,3> second[6],
                                     MsqError& err )
{
  double f = sqr_Frobenius(T);
  double g = sqr_Frobenius(adj(T));
  double d = det(T);
  if (invalid_determinant(d)) {
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
  const double den = 1.0/(9*d*d);
  result = f*g*den- 1;
  
  MsqMatrix<3,3> dg = 2 * (f * T - T * transpose(T) * T);
  MsqMatrix<3,3> df = 2 * T;
  MsqMatrix<3,3> dtau = transpose_adj(T);
  
  wrt_T = g*df + f*dg - 2*f*g/d * transpose_adj(T);
  wrt_T *= den;
  
  set_scaled_2nd_deriv_norm_sqr_adj( second, den*f, T );
  pluseq_scaled_I( second, 2*den*g );
  pluseq_scaled_sum_outer_product( second, den, dg, df );
  pluseq_scaled_sum_outer_product( second, -2*den*g/d, df, dtau );
  pluseq_scaled_sum_outer_product( second, -2*den*f/d, dg, dtau );
  pluseq_scaled_outer_product( second, 6*den*f*g/(d*d), dtau );
  pluseq_scaled_2nd_deriv_of_det( second, -2*den*f*g/d, T );
  
  return true;
}
Ejemplo n.º 3
0
bool InvTransBarrier2D::evaluate( const MsqMatrix<2,2>& A, 
                                  const MsqMatrix<2,2>& W, 
                                  double& result, MsqError& err )
{
  double da = det(A);
  double dw = det(W);
  if (invalid_determinant(da) || invalid_determinant(dw))
    return false;
  MsqMatrix<2,2> Ap = transpose_adj(A);
  Ap *= 1.0/da;
  MsqMatrix<2,2> Wp = transpose_adj(W);
  Wp *= 1.0/dw;
  bool rval = metricPtr->evaluate( Ap, Wp, result, err );
  return !MSQ_CHKERR(err) && rval;
}
Ejemplo n.º 4
0
/** \f$ \frac{\partial^2 \mu}{\partial T^2} 
      = \frac{1}{\tau} I_4 
      - \frac{1}{\tau^2} \left( T \otimes \frac{\partial \tau}{\partial T} 
                          + \frac{\partial \tau}{\partial T} \otimes T \right) 
      + \frac{|T|^2}{\tau^3} \left( \frac{\partial \tau}{\partial T} \otimes
                               \frac{\partial \tau}{\partial T} \right) 
      - \frac{|T|^2}{2 \tau^3} \frac{\partial^2 \tau}{\partial T^2} \f$
  */
bool Target2DShapeBarrier::evaluate_with_hess( const MsqMatrix<2,2>& A,
                                               const MsqMatrix<2,2>& W,
                                               double& result,
                                               MsqMatrix<2,2>& deriv_wrt_A,
                                               MsqMatrix<2,2> second_wrt_A[3],
                                               MsqError& err )
{
  const MsqMatrix<2,2> Winv = inverse(W);
  const MsqMatrix<2,2> T = A * Winv;
  const double d = det(T);
  if (invalid_determinant(d)) { // barrier
    result = 0.0;
    return false;
  }
    
  double inv_d = 1.0/d;
  double f1 = sqr_Frobenius(T) * inv_d;
  result = 0.5 * f1;
  const MsqMatrix<2,2> adjt = transpose_adj(T);
  deriv_wrt_A = T;
  deriv_wrt_A -= result * adjt;
  deriv_wrt_A *= inv_d;
  deriv_wrt_A = deriv_wrt_A * transpose(Winv);
  
  set_scaled_outer_product( second_wrt_A, f1 * inv_d * inv_d, adjt );
  pluseq_scaled_sum_outer_product( second_wrt_A, -inv_d*inv_d, T, adjt );
  pluseq_scaled_I( second_wrt_A, inv_d );
  pluseq_scaled_2nd_deriv_of_det( second_wrt_A, -result * inv_d );
  second_deriv_wrt_product_factor( second_wrt_A, Winv );

  result -= 1.0;
  return true;
}
Ejemplo n.º 5
0
bool TShapeOrientB2::evaluate_with_grad( const MsqMatrix<2,2>& T, 
                                         double& result, 
                                         MsqMatrix<2,2>& deriv_wrt_T,
                                         MsqError& err )
{
  double tau = det(T);
  if (TMetric::invalid_determinant(tau)) {
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
  const double b = 0.5/tau;

  const double tr = trace(T);
  const double f = 0.5 * fabs(tr);
  result = sqr_Frobenius( T ) - f * tr;
  
  deriv_wrt_T = T;
  pluseq_scaled_I( deriv_wrt_T, -f );
  deriv_wrt_T *= 2*tau;
  deriv_wrt_T -= result * transpose_adj(T);
  
  result *= b;
  deriv_wrt_T *= b/tau;
  
  return true;
}
Ejemplo n.º 6
0
bool TShapeSizeB3::evaluate_with_hess( const MsqMatrix<2,2>& T,
                                                     double& result,
                                                     MsqMatrix<2,2>& deriv_wrt_T,
                                                     MsqMatrix<2,2> second_wrt_T[3],
                                                     MsqError& err )
{
  const double tau = det(T);
  if (invalid_determinant(tau)) { // barrier
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
  
  result = sqr_Frobenius(T) - 2.0 * std::log(tau) - 2;

  const MsqMatrix<2,2> adjt = transpose_adj(T);
  const double it = 1/tau;
  deriv_wrt_T = T;
  deriv_wrt_T -= it * adjt;
  deriv_wrt_T *= 2;
  
  set_scaled_outer_product( second_wrt_T, 2*it*it, adjt );
  pluseq_scaled_2nd_deriv_of_det( second_wrt_T, -2*it );
  pluseq_scaled_I( second_wrt_T, 2.0 );

  return true;
}
Ejemplo n.º 7
0
bool TShapeSizeB1::evaluate_with_grad( const MsqMatrix<3,3>& T,
                                       double& result,
                                       MsqMatrix<3,3>& deriv_wrt_T,
                                       MsqError& )
{
  const double tau = det(T);
  if (invalid_determinant(tau)) { // barrier
    result = 0.0;
    return false;
  }
  
  const MsqMatrix<3,3> adjt = transpose_adj(T);
  const double nT = sqr_Frobenius(T);
  const double nadj = sqr_Frobenius(adjt);
  const double f = 1/(tau*tau);
  result = nT + f*nadj - 6;
  
  deriv_wrt_T = T;
  deriv_wrt_T *= (1+f*nT);
  deriv_wrt_T -= f * T * transpose(T) * T;
  deriv_wrt_T -= f/tau * nadj * adjt;
  deriv_wrt_T *= 2;

  return true;
}
Ejemplo n.º 8
0
bool TShapeSizeB1::evaluate_with_hess( const MsqMatrix<3,3>& T,
                                       double& result,
                                       MsqMatrix<3,3>& deriv_wrt_T,
                                       MsqMatrix<3,3> second_wrt_T[6],
                                       MsqError& err )
{
  const double tau = det(T);
  if (invalid_determinant(tau)) { // barrier
    result = 0.0;
    return false;
  }
  
  const MsqMatrix<3,3> adjt = transpose_adj(T);
  const double nT = sqr_Frobenius(T);
  const double nadj = sqr_Frobenius(adjt);
  const double f = 1/(tau*tau);
  result = nT + f*nadj - 6;
  
  //! \f$ \frac{\partial}{\partial T} |adj T|^2 \f$
  const MsqMatrix<3,3> dNadj_dT = 2 * (nT * T - T * transpose(T) * T);
  deriv_wrt_T = T;
  deriv_wrt_T -= f/tau * nadj * adjt;
  deriv_wrt_T *= 2;
  deriv_wrt_T += f * dNadj_dT;
 
    // calculate negative of 2nd wrt T of (|adj T|^2 / tau^2) (sec 3.2.2)
  set_scaled_2nd_deriv_norm_sqr_adj( second_wrt_T,    f,            T );
  pluseq_scaled_2nd_deriv_of_det(    second_wrt_T, -2*f*f*nadj*tau, T );
  pluseq_scaled_outer_product(       second_wrt_T,  6*f*f*nadj,     adjt );
  pluseq_scaled_sum_outer_product(   second_wrt_T, -2*f*f     *tau, adjt, dNadj_dT );
    // calculate 2nd wrt T of this metric
  pluseq_scaled_I( second_wrt_T, 2.0 );

  return true;
}
Ejemplo n.º 9
0
bool TShapeSizeB1::evaluate_with_hess( const MsqMatrix<2,2>& T,
                                       double& result,
                                       MsqMatrix<2,2>& deriv_wrt_T,
                                       MsqMatrix<2,2> second_wrt_T[3],
                                       MsqError& err )
{
  const double tau = det(T);
  if (invalid_determinant(tau)) { // barrier
    result = 0.0;
    return false;
  }
  
  const MsqMatrix<2,2> adjt = transpose_adj(T);
  const double nT = sqr_Frobenius(T);
  const double f = 1/(tau*tau);
  result = (1 + f) * nT - 4;
  
  deriv_wrt_T = T;
  deriv_wrt_T *= 2 + 2*f;
  deriv_wrt_T -= 2 * f/tau * nT * adjt;

  set_scaled_sum_outer_product( second_wrt_T, -4*f/tau, T, adjt );
  pluseq_scaled_I( second_wrt_T, 2 + 2*f );
  pluseq_scaled_outer_product( second_wrt_T, 6*nT*f*f, adjt );
  pluseq_scaled_2nd_deriv_of_det( second_wrt_T, -2*nT*f/tau );

  return true;
}
Ejemplo n.º 10
0
bool Target3DShape::evaluate_with_hess( const MsqMatrix<3,3>& A, 
                                        const MsqMatrix<3,3>& W, 
                                        double& result, 
                                        MsqMatrix<3,3>& deriv_wrt_A,
                                        MsqMatrix<3,3> second_wrt_A[6],
                                        MsqError& err )
{
  MsqMatrix<3,3> Winv = inverse(W);
  MsqMatrix<3,3> T = A * Winv;
  double f = Frobenius(T);
  double d = det(T);
  result = f*f*f - 3*MSQ_SQRT_THREE*d;

  deriv_wrt_A = T;
  deriv_wrt_A *= f;
  deriv_wrt_A -= MSQ_SQRT_THREE*transpose_adj(T);
  deriv_wrt_A *= 3;
  deriv_wrt_A = deriv_wrt_A * transpose(Winv);
  
  set_scaled_2nd_deriv_of_det( second_wrt_A, -3 * MSQ_SQRT_THREE, T );
  pluseq_scaled_outer_product( second_wrt_A, 3.0/f, T );
  pluseq_scaled_I( second_wrt_A, 3.0*f );
  second_deriv_wrt_product_factor( second_wrt_A, Winv );
  return true;
}
bool Target2DShapeOrientBarrier::evaluate_with_grad( const MsqMatrix<2,2>& A,
                                                     const MsqMatrix<2,2>& W,
                                                     double& result,
                                                     MsqMatrix<2,2>& deriv,
                                                     MsqError& err )
{
  const MsqMatrix<2,2> Winv = inverse(W);
  const MsqMatrix<2,2> T = A * Winv;
  const double norm = Frobenius(T);
  const double invroot = 1.0/MSQ_SQRT_TWO;
  const double tau = det(T);
  if (invalid_determinant(tau)) { // barrier
    result = 0.0;
    return false;
  }
  const double inv_tau = 1.0/tau;
  const double invnorm = 1.0/norm;
  
  result = 0.5*inv_tau*(norm - invroot * trace(T));

  deriv = invnorm * T;
  deriv(0,0) -= invroot;
  deriv(1,1) -= invroot;
  deriv *= 0.5;
  deriv -= result * transpose_adj(T);
  deriv *= inv_tau;
  deriv = deriv * transpose(Winv);
  return true;
}
Ejemplo n.º 12
0
bool TShapeOrientB1::evaluate_with_hess( const MsqMatrix<2,2>& T,
                                         double& result,
                                         MsqMatrix<2,2>& deriv_wrt_T,
                                         MsqMatrix<2,2> second_wrt_T[3],
                                         MsqError& err )
{
  const double norm = Frobenius(T);
  const double invroot = 1.0/MSQ_SQRT_TWO;
  const double tau = det(T);
  if (TMetric::invalid_determinant(tau)) { // barrier
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
  const double inv_tau = 1.0/tau;
  const double invnorm = 1.0/norm;
  
  const double f = norm - invroot * trace(T);
  result = 0.5 * inv_tau * f;

  const MsqMatrix<2,2> adjt = transpose_adj(T);
  deriv_wrt_T = invnorm * T;
  pluseq_scaled_I( deriv_wrt_T, -invroot );
  deriv_wrt_T *= 0.5;
  deriv_wrt_T -= result * adjt;
  deriv_wrt_T *= inv_tau;
  
  const double a = 0.5 * inv_tau * invnorm;
  set_scaled_outer_product( second_wrt_T, -a*invnorm*invnorm, T );
  pluseq_scaled_I( second_wrt_T, a );
  pluseq_scaled_outer_product( second_wrt_T, f*inv_tau*inv_tau*inv_tau, adjt );
  pluseq_scaled_2nd_deriv_of_det( second_wrt_T, -0.5*f*inv_tau*inv_tau, T );
  pluseq_scaled_sum_outer_product( second_wrt_T, -0.5*inv_tau*inv_tau*invnorm, T, adjt );
  pluseq_scaled_sum_outer_product_I( second_wrt_T, 0.5*inv_tau*inv_tau*invroot, adjt );
  return true;
}
Ejemplo n.º 13
0
bool TShapeSize3DB2::evaluate_with_grad( const MsqMatrix<3,3>& T,
                                         double& result,
                                         MsqMatrix<3,3>& deriv_wrt_T,
                                         MsqError& err )
{
  const double tau = det(T);
  if (invalid_determinant(tau)) { // barrier
    result = 0.0;
    return false;
  }
  
  const double f = sqr_Frobenius(T);
  const double g = sqr_Frobenius(adj(T));
  result = (f + g)/(6 * tau);
  
  deriv_wrt_T = -transpose(T) * T;
  deriv_wrt_T(0,0) += 1+f;
  deriv_wrt_T(1,1) += 1+f;
  deriv_wrt_T(2,2) += 1+f;
  deriv_wrt_T = T * deriv_wrt_T;
  deriv_wrt_T -= 3*result * transpose_adj(T);
  deriv_wrt_T *= 1.0/(3*tau);
  
  result -= 1.0;
  return true;
}
bool Target3DShapeOrientBarrierAlt1::evaluate_with_grad( const MsqMatrix<3,3>& A, 
                                                        const MsqMatrix<3,3>& W, 
                                                        double& result, 
                                                        MsqMatrix<3,3>& deriv_wrt_A,
                                                        MsqError& err )
{
  MsqMatrix<3,3> Winv = inverse(W);
  MsqMatrix<3,3> T = A * Winv;
  double tau = det(T);
  if (invalid_determinant(tau)) {
    result = 0.0;
    return false;
  }
  const double b = 0.5/tau;

  const double tr = trace(T);
  const double f = MSQ_ONE_THIRD * fabs(tr);
  result = sqr_Frobenius( T ) - f * tr;
  
  deriv_wrt_A = T;
  deriv_wrt_A(0,0) -= f;
  deriv_wrt_A(1,1) -= f;
  deriv_wrt_A(2,2) -= f;
  deriv_wrt_A *= 2*tau;
  deriv_wrt_A -= result * transpose_adj(T);
  
  result *= b;
  deriv_wrt_A *= b/tau;
  
  deriv_wrt_A = deriv_wrt_A * transpose(Winv);
  return true;
}
Ejemplo n.º 15
0
bool TShapeSize2DNB2::evaluate_with_grad( const MsqMatrix<2,2>& T, 
                                          double& result, 
                                          MsqMatrix<2,2>& deriv_wrt_T,
                                          MsqError& err )
{
  double frob_sqr = sqr_Frobenius(T);
  double psi = sqrt( frob_sqr + 2.0*det(T) );

  double a = 1e-12;
  while (!Mesquite::divide(frob_sqr+2,2*psi,result)) {
    MsqMatrix<2,2> Tdelta(T);
    Tdelta(0,0) += a;
    Tdelta(1,1) += a;
    a *= 2.0;
    frob_sqr = sqr_Frobenius(Tdelta);
    psi = sqrt( frob_sqr + 2.0*det(Tdelta) );
    if (psi > 1e-50) 
      result = (frob_sqr+2) / 2*psi;
  }
  
  //MsqMatrix<2,2> d_psi = 1.0/psi * (T + transpose_adj(T));
  //deriv_wrt_T = (1.0/psi) * (T - result * d_psi);
  if (psi > 1e-50) 
  {
    const double f = result/(psi*psi);
    deriv_wrt_T = transpose_adj(T);
    deriv_wrt_T *= -f;
    deriv_wrt_T += (1.0/psi - f) * T;
  }
  
  result -= 1.0;
  
  return true;
}
Ejemplo n.º 16
0
bool InverseMeanRatio2D::evaluate_with_grad( const MsqMatrix<2,2>& A,
                                             const MsqMatrix<2,2>& W,
                                             double& result,
                                             MsqMatrix<2,2>& deriv_wrt_A,
                                             MsqError& err )
{
  const MsqMatrix<2,2> Winv = inverse(W);
  const MsqMatrix<2,2> T = A * Winv;
  const double d = det( T );
  if (invalid_determinant(d)) {
    result = 0.0;
    deriv_wrt_A = MsqMatrix<2,2>(0.0);
    return false;
  }
  else {
    result = sqr_Frobenius(T) / (2 * d);
    deriv_wrt_A = transpose_adj(T);
    deriv_wrt_A *= -result;
    deriv_wrt_A += T;
    deriv_wrt_A *= 1.0/d;
    deriv_wrt_A = deriv_wrt_A * transpose(Winv);
    result -= 1.0;
    return true;
  }
}
Ejemplo n.º 17
0
template <unsigned DIM> static inline
bool hess( const MsqMatrix<DIM,DIM>& T, 
           double& result, 
           MsqMatrix<DIM,DIM>& deriv, 
           MsqMatrix<DIM,DIM>* second )
{
  const double norm = Frobenius(T);
  const double invroot = 1.0/DimConst<DIM>::sqrt();
  const double tau = det(T);
  if (TMetric::invalid_determinant(tau)) { // barrier
    result = 0.0;
    return false;
  }
  const double inv_tau = 1.0/tau;
  const double invnorm = 1.0/norm;
  
  const double f = norm - invroot * trace(T);
  result = 0.5 * inv_tau * f;

  const MsqMatrix<DIM,DIM> adjt = transpose_adj(T);
  deriv = invnorm * T;
  pluseq_scaled_I( deriv, -invroot );
  deriv *= 0.5;
  deriv -= result * adjt;
  deriv *= inv_tau;
  
  const double a = 0.5 * inv_tau * invnorm;
  set_scaled_outer_product( second, -a*invnorm*invnorm, T );
  pluseq_scaled_I( second, a );
  pluseq_scaled_outer_product( second, f*inv_tau*inv_tau*inv_tau, adjt );
  pluseq_scaled_2nd_deriv_of_det( second, -0.5*f*inv_tau*inv_tau, T );
  pluseq_scaled_sum_outer_product( second, -0.5*inv_tau*inv_tau*invnorm, T, adjt );
  pluseq_scaled_sum_outer_product_I( second, 0.5*inv_tau*inv_tau*invroot, adjt );
  return true;
}
Ejemplo n.º 18
0
bool Target2DUntangle::evaluate_with_hess( const MsqMatrix<2,2>& A,
                                           const MsqMatrix<2,2>& W,
                                           double& result,
                                           MsqMatrix<2,2>& deriv_wrt_A,
                                           MsqMatrix<2,2> second_wrt_A[3],
                                           MsqError& err )
{
  const MsqMatrix<2,2> Winv = inverse(W);
  const MsqMatrix<2,2> T = A * Winv;
  double tau = det(T);
  if (tau < mGamma) {
    double d = tau - mGamma;
    result = 16 * d*d*d*d;
    const MsqMatrix<2,2> adjt = transpose_adj(T);
    deriv_wrt_A = 64 * d*d*d * adjt;
    deriv_wrt_A = deriv_wrt_A * transpose(Winv);
    set_scaled_outer_product( second_wrt_A, 192*d*d, adjt );
    pluseq_scaled_2nd_deriv_of_det( second_wrt_A, 64*d*d*d );
    second_deriv_wrt_product_factor( second_wrt_A, Winv );
  }
  else {
    result = 0.0;
    second_wrt_A[0] = second_wrt_A[1] = second_wrt_A[2] = deriv_wrt_A = MsqMatrix<2,2>(0.0);
  }
  return true;
}
Ejemplo n.º 19
0
bool TShapeSizeOrientB1::evaluate_with_hess( const MsqMatrix<2,2>& T,
                                             double& result,
                                             MsqMatrix<2,2>& deriv_wrt_T,
                                             MsqMatrix<2,2> second_wrt_T[3],
                                             MsqError& err )
{
  const double d = det(T);
  if (TMetric::invalid_determinant(d)) { // barrier
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
  
  deriv_wrt_T = T;
  pluseq_scaled_I( deriv_wrt_T, -1.0 );
  double inv_d = 1.0/d;
  result = 0.5 * sqr_Frobenius(deriv_wrt_T) * inv_d;
  
  MsqMatrix<2,2> adjt = transpose_adj(T);
  set_scaled_outer_product( second_wrt_T, 2*result*inv_d*inv_d, adjt );
  pluseq_scaled_sum_outer_product( second_wrt_T, -inv_d*inv_d, deriv_wrt_T, adjt );
  pluseq_scaled_2nd_deriv_of_det( second_wrt_T, -result * inv_d, T );
  pluseq_scaled_I( second_wrt_T, inv_d );
  
  deriv_wrt_T -= result * adjt;
  deriv_wrt_T *= inv_d;

  return true;
}
bool Target3DShapeSizeBarrierAlt1::evaluate_with_grad( const MsqMatrix<3,3>& A,
                                                       const MsqMatrix<3,3>& W,
                                                       double& result,
                                                       MsqMatrix<3,3>& deriv_wrt_A,
                                                       MsqError& err )
{
  const MsqMatrix<3,3> Winv = inverse(W);
  const MsqMatrix<3,3> T = A * Winv;
  const double tau = det(T);
  if (invalid_determinant(tau)) { // barrier
    result = 0.0;
    return false;
  }
  
  const double f = sqr_Frobenius(T);
  const double g = sqr_Frobenius(adj(T));
  result = (f + g)/(6 * tau);
  
  deriv_wrt_A = -transpose(T) * T;
  deriv_wrt_A(0,0) += 1+f;
  deriv_wrt_A(1,1) += 1+f;
  deriv_wrt_A(2,2) += 1+f;
  deriv_wrt_A = T * deriv_wrt_A;
  deriv_wrt_A -= 3*result * transpose_adj(T);
  deriv_wrt_A *= 1.0/(3*tau);
  deriv_wrt_A = deriv_wrt_A * transpose(Winv);
  
  result -= 1.0;
  return true;
}
bool TShapeSize2DB2::evaluate_with_hess( const MsqMatrix<2,2>& T, 
                                         double& result, 
                                         MsqMatrix<2,2>& deriv_wrt_T,
                                         MsqMatrix<2,2> second[3],
                                         MsqError& err )
{
  const double d = det(T);
  if (invalid_determinant(d)) { // barrier
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
  const double frob_sqr = sqr_Frobenius(T);
  const double psi = sqrt( frob_sqr + 2.0*det(T) );
  const double v = frob_sqr - 2.0 * psi + 2.0;
  result = v / (2*d);

    // deriv of V wrt T
  MsqMatrix<2,2> adjt = transpose_adj(T);
  MsqMatrix<2,2> v_wrt_T(T);
  if (psi > 1e-50) 
  {
    v_wrt_T *= (1.0 - 1.0/psi);
    v_wrt_T -= 1.0/psi * adjt;
    v_wrt_T *= 2;
  }
  else
  {
    std::cout << "Warning: Division by zero avoided in TShapeSize2DB2::evaluate_with_hess()" << std::endl;
  }  
  
    // deriv of mu wrt T
  deriv_wrt_T = v_wrt_T;
  deriv_wrt_T *= 0.5/d;
  deriv_wrt_T -= v / (2*d*d) * adjt;
  
    // second of V wrt T 
  const double s = T(0,1) - T(1,0);
  const double tr = trace(T);
  const double f = -2.0/(psi*psi*psi);
  second[0](0,0) = second[1](0,1) = second[2](1,1) =  f*s*s;
  second[0](0,1) = second[0](1,0) = second[1](1,1) = -f*s*tr;
  second[1](0,0) = second[2](0,1) = second[2](1,0) =  f*s*tr;
  second[0](1,1) = second[2](0,0) = -(second[1](1,0) = -f*tr*tr);
  pluseq_scaled_I( second, 2 );
  
    // second of mu wrt T 
  const double x = 1.0/(2*d);
  second[0] *= x;
  second[1] *= x;
  second[2] *= x;
  pluseq_scaled_2nd_deriv_of_det( second, v/(-2*d*d) );
  pluseq_scaled_outer_product( second, v/(d*d*d), adjt );
  pluseq_scaled_sum_outer_product( second, -1/(2*d*d), v_wrt_T, adjt );
  
  return true;
}
Ejemplo n.º 22
0
template <unsigned DIM> static inline
bool grad( const MsqMatrix<DIM,DIM>& T, 
           double& result, 
           MsqMatrix<DIM,DIM>& deriv )
{
  double d1 = det(T) - 1;
  result = d1*d1;
  deriv = 2 * d1 * transpose_adj(T);
  return true;  
}
Ejemplo n.º 23
0
bool InverseMeanRatio2D::evaluate_with_hess( const MsqMatrix<2,2>& A,
                                             const MsqMatrix<2,2>& W,
                                             double& result,
                                             MsqMatrix<2,2>& dA,
                                             MsqMatrix<2,2> d2A[3],
                                             MsqError& err )
{
  const MsqMatrix<2,2> Winv = inverse(W);
  const MsqMatrix<2,2> T = A * Winv;
  const double d = det( T );
  if (invalid_determinant(d)) {
    result = 0.0;
    dA = d2A[0] = d2A[1] = d2A[2] = MsqMatrix<2,2>(0.0);
    return false;
  }
  else {
    const double inv_det = 1.0/d;
    result = sqr_Frobenius(T) * 0.5 * inv_det;
    
    const MsqMatrix<2,2> AT = transpose_adj(T);
    dA = AT;
    dA *= -result;
    dA += T;
    dA *= inv_det;
    dA = dA * transpose(Winv);
    
    const double p3 = -result * inv_det;
    const double p1 = -2.0 * p3 * inv_det;
    const double p2 = -inv_det * inv_det;
    const MsqMatrix<2,2> AT_T_op_00 = outer( AT.row(0), T.row(0));
    const MsqMatrix<2,2> AT_T_op_11 = outer( AT.row(1), T.row(1));
    d2A[0] = p1 * outer( AT.row(0), AT.row(0))
           + p2 * (AT_T_op_00 + transpose(AT_T_op_00));
    d2A[1] = p1 * outer( AT.row(0), AT.row(1)) 
           + p2 * (outer( AT.row(0), T.row(1))
	     + outer( T.row(0), AT.row(1) ));
    d2A[2] = p1 * outer( AT.row(1), AT.row(1)) 
           + p2 * (AT_T_op_11 + transpose(AT_T_op_11));

    d2A[0](0,0) += inv_det;
    d2A[0](1,1) += inv_det;
    d2A[1](0,1) += p3;
    d2A[1](1,0) -= p3;
    d2A[2](0,0) += inv_det;
    d2A[2](1,1) += inv_det;
    
    d2A[0] = Winv * d2A[0] * transpose(Winv);
    d2A[1] = Winv * d2A[1] * transpose(Winv);
    d2A[2] = Winv * d2A[2] * transpose(Winv);
    
    result -= 1.0;
    return true;
  }
}
Ejemplo n.º 24
0
bool InvTransBarrier::evaluate( const MsqMatrix<2,2>& T, 
                                double& result, MsqError& err )
{
  double tau = det(T);
  if (invalid_determinant(tau))
    return false;
  MsqMatrix<2,2> Tp = transpose_adj(T);
  Tp *= 1.0/tau;
  bool rval = metricPtr->evaluate( Tp, result, err );
  return !MSQ_CHKERR(err) && rval;
}
Ejemplo n.º 25
0
template <unsigned DIM> static inline
bool hess( const MsqMatrix<DIM,DIM>& T, 
           double& result, 
           MsqMatrix<DIM,DIM>& deriv, 
           MsqMatrix<DIM,DIM>* second )
{
  double d1 = det(T) - 1;
  result = d1*d1;
  const MsqMatrix<DIM,DIM> adjt = transpose_adj(T);
  deriv = 2 * d1 * adjt;
  set_scaled_outer_product( second, 2, adjt );
  pluseq_scaled_2nd_deriv_of_det( second, 2 * d1, T );
  return true;  
}
bool Target3DShapeOrientBarrierAlt1::evaluate_with_Hess( const MsqMatrix<3,3>& A, 
                                                        const MsqMatrix<3,3>& W, 
                                                        double& result, 
                                                        MsqMatrix<3,3>& deriv_wrt_A,
                                                        MsqMatrix<3,3> second_wrt_A[6],
                                                        MsqError& err )
{
  MsqMatrix<3,3> Winv = inverse(W);
  MsqMatrix<3,3> T = A * Winv;
  double tau = det(T);
  if (invalid_determinant(tau)) {
    result = 0.0;
    return false;
  }
  const double b = 0.5/tau;

    // calculate non-barrier value (ShapeOrientAlt1)
  const double tr = trace(T);
  const double f = MSQ_ONE_THIRD * fabs(tr);
  result = sqr_Frobenius( T ) - f * tr;
  
    // calculate non-barrier first derivatives
  deriv_wrt_A = T;
  deriv_wrt_A(0,0) -= f;
  deriv_wrt_A(1,1) -= f;
  deriv_wrt_A(2,2) -= f;
  deriv_wrt_A *= 2;
  
    // calculate barrier second derivs
  const MsqMatrix<3,3> adjt = transpose_adj(T);
  set_scaled_sum_outer_product( second_wrt_A, -b/tau, deriv_wrt_A, adjt );
  pluseq_scaled_outer_product( second_wrt_A, result/(tau*tau*tau), adjt );
  pluseq_scaled_2nd_deriv_of_det( second_wrt_A, -result * b / tau, T );
    // calculate non-barrier barrier portion of second derivs
  pluseq_scaled_I( second_wrt_A, 1/tau );
  pluseq_scaled_outer_product_I_I( second_wrt_A, MSQ_ONE_THIRD/tau * (tr < 0 ? 1 : -1) );
  
    // calculate barrier derivs from non-barrier
  deriv_wrt_A *= tau;
  deriv_wrt_A -= result * adjt;
  deriv_wrt_A *= b/tau;
  
    // barrier value from non-barrier
  result *= b;
  
    // convert from derivs wrt T to derivs wrt A
  deriv_wrt_A = deriv_wrt_A * transpose(Winv);
  second_deriv_wrt_product_factor( second_wrt_A, Winv );
  return true;
}
Ejemplo n.º 27
0
bool TSizeB1::evaluate_with_grad( const MsqMatrix<2,2>& T,
                                  double& result,
                                  MsqMatrix<2,2>& deriv_wrt_T,
                                  MsqError& err )
{
  double d = det(T);
  if (TMetric::invalid_determinant(d)) {
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
  result = d + 1.0/d - 2.0;
  deriv_wrt_T = (1 - 1/(d*d)) * transpose_adj(T);
  return true;  
}
Ejemplo n.º 28
0
bool TShapeSizeB1::evaluate( const MsqMatrix<3,3>& T, 
                             double& result, 
                             MsqError&  )
{
  const double tau = det(T);
  if (invalid_determinant(tau)) { // barrier
    result = 0.0;
    return false;
  }
  
  const double nT = sqr_Frobenius(T);
  const double nadj = sqr_Frobenius(transpose_adj(T));
  const double f = 1/(tau*tau);
  result = nT + f*nadj - 6;
  return true;
}
bool Target3DShapeSizeBarrierAlt1::evaluate_with_hess( const MsqMatrix<3,3>& A,
                                                       const MsqMatrix<3,3>& W,
                                                       double& result,
                                                       MsqMatrix<3,3>& wrt_A,
                                                       MsqMatrix<3,3> second[6],
                                                       MsqError& err )
{
  const MsqMatrix<3,3> Winv = inverse(W);
  const MsqMatrix<3,3> T = A * Winv;
  const double tau = det(T);
  if (invalid_determinant(tau)) { // barrier
    result = 0.0;
    return false;
  }
  
  const double f = sqr_Frobenius(T);
  const double g = sqr_Frobenius(adj(T));
  result = (f + g)/(6 * tau);
  
  MsqMatrix<3,3> dtau = transpose_adj(T);
  MsqMatrix<3,3> dg = -transpose(T) * T;
  dg(0,0) += f;
  dg(1,1) += f;
  dg(2,2) += f;
  dg = T * dg;
  dg *= 2;
  
  wrt_A = T;
  wrt_A += 0.5*dg;
  wrt_A *= 1.0/3.0;
  wrt_A -= result * dtau;
  wrt_A *= 1.0/tau;
  wrt_A = wrt_A * transpose(Winv);
  
  set_scaled_2nd_deriv_norm_sqr_adj( second, 1.0/6.0, T );
  pluseq_scaled_I( second, 1.0/3.0 );
  pluseq_scaled_sum_outer_product( second, -1./3./tau, T, dtau );
  pluseq_scaled_sum_outer_product( second, -1./6./tau, dg, dtau );
  pluseq_scaled_outer_product( second, 2*result/tau, dtau );
  pluseq_scaled_2nd_deriv_of_det( second, -result, T );
  hess_scale( second, 1.0/tau );
  second_deriv_wrt_product_factor( second, Winv );
  
  result -= 1.0;
  return true;
}
Ejemplo n.º 30
0
bool TShapeSizeB3::evaluate_with_grad( const MsqMatrix<2,2>& T,
                                                     double& result,
                                                     MsqMatrix<2,2>& deriv_wrt_T,
                                                     MsqError& err )
{
  const double tau = det(T);
  if (invalid_determinant(tau)) { // barrier
    MSQ_SETERR(err)( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
    return false;
  }
  
  result = sqr_Frobenius(T) - 2.0 * std::log(tau) - 2;
  deriv_wrt_T = T;
  deriv_wrt_T -= 1/tau * transpose_adj(T);
  deriv_wrt_T *= 2;
  
  return true;
}