/* ** watch out for false advertising! */ void _coilKind7TensorFilterSelf(coil_t *delta, coil_t **iv3, double spacing[3], double parm[COIL_PARMS_NUM]) { coil_t hess[7], rspX, rspY, rspZ, parm0; float eval[3], evec[9], tens[7], lin; rspX = AIR_CAST(coil_t, 1.0/spacing[0]); rspY = AIR_CAST(coil_t, 1.0/spacing[1]); rspZ = AIR_CAST(coil_t, 1.0/spacing[2]); TENS(tens, iv3); tenEigensolve_f(eval, evec, tens); lin = (eval[0] - eval[1])/(eval[0] - eval[2] + 0.000001f); TEN_T3V_OUTER(tens, evec + 3*0); delta[0] = 0; parm0 = AIR_CAST(coil_t, parm[0]); HESS(hess, iv3, 1, rspX, rspY, rspZ); delta[1] = lin*parm0*tens[0]*TEN_T_DOT(hess, tens); HESS(hess, iv3, 2, rspX, rspY, rspZ); delta[2] = lin*parm0*tens[0]*TEN_T_DOT(hess, tens); HESS(hess, iv3, 3, rspX, rspY, rspZ); delta[3] = lin*parm0*tens[0]*TEN_T_DOT(hess, tens); HESS(hess, iv3, 4, rspX, rspY, rspZ); delta[4] = lin*parm0*tens[0]*TEN_T_DOT(hess, tens); HESS(hess, iv3, 5, rspX, rspY, rspZ); delta[5] = lin*parm0*tens[0]*TEN_T_DOT(hess, tens); HESS(hess, iv3, 6, rspX, rspY, rspZ); delta[6] = lin*parm0*tens[0]*TEN_T_DOT(hess, tens); }
void _coilKind7TensorFilterFinish(coil_t *delta, coil_t **iv3, double spacing[3], double parm[COIL_PARMS_NUM]) { coil_t rspX, rspY, rspZ, rspsqX, rspsqY, rspsqZ; double eval[3], evec[9], tens[7], tengrad[21], grad[3], LL, KK, cnd, dmu1[7], dmu2[7], dskw[7], phi3[7]; rspX = AIR_CAST(coil_t, 1.0/spacing[0]); rspsqX = rspX*rspX; rspY = AIR_CAST(coil_t, 1.0/spacing[1]); rspsqY = rspY*rspY; rspZ = AIR_CAST(coil_t, 1.0/spacing[2]); rspsqZ = rspZ*rspZ; TENS(tens, iv3); TENGRAD(tengrad, iv3, rspX, rspY, rspZ); tenEigensolve_d(eval, evec, tens); tenInvariantGradientsK_d(dmu1, dmu2, dskw, tens, 0.000001); tenRotationTangents_d(NULL, NULL, phi3, evec); /* \midhat{\nabla} \mu_1 ----------------- */ ELL_3V_SET(grad, TEN_T_DOT(dmu1, tengrad + 0*7), TEN_T_DOT(dmu1, tengrad + 1*7), TEN_T_DOT(dmu1, tengrad + 2*7)); LL = ELL_3V_DOT(grad,grad); KK = parm[1]*parm[1]; cnd = _COIL_CONDUCT(LL, KK); /* \midhat{\nabla} \mu_2 ----------------- */ ELL_3V_SET(grad, TEN_T_DOT(dmu2, tengrad + 0*7), TEN_T_DOT(dmu2, tengrad + 1*7), TEN_T_DOT(dmu2, tengrad + 2*7)); LL = ELL_3V_DOT(grad,grad); KK = parm[2]*parm[2]; cnd *= _COIL_CONDUCT(LL, KK); /* \midhat{\nabla} \skw and twist! ----------------- */ ELL_3V_SET(grad, TEN_T_DOT(dskw, tengrad + 0*7), TEN_T_DOT(dskw, tengrad + 1*7), TEN_T_DOT(dskw, tengrad + 2*7)); LL = ELL_3V_DOT(grad,grad); ELL_3V_SET(grad, TEN_T_DOT(phi3, tengrad + 0*7), TEN_T_DOT(phi3, tengrad + 1*7), TEN_T_DOT(phi3, tengrad + 2*7)); LL += ELL_3V_DOT(grad,grad); KK = AIR_CAST(coil_t, parm[3]*parm[3]); cnd *= _COIL_CONDUCT(LL, KK); delta[0]= 0.0f; delta[1]= AIR_CAST(coil_t, parm[0]*cnd*LAPL(iv3, 1, rspsqX, rspsqY, rspsqZ)); delta[2]= AIR_CAST(coil_t, parm[0]*cnd*LAPL(iv3, 2, rspsqX, rspsqY, rspsqZ)); delta[3]= AIR_CAST(coil_t, parm[0]*cnd*LAPL(iv3, 3, rspsqX, rspsqY, rspsqZ)); delta[4]= AIR_CAST(coil_t, parm[0]*cnd*LAPL(iv3, 4, rspsqX, rspsqY, rspsqZ)); delta[5]= AIR_CAST(coil_t, parm[0]*cnd*LAPL(iv3, 5, rspsqX, rspsqY, rspsqZ)); delta[6]= AIR_CAST(coil_t, parm[0]*cnd*LAPL(iv3, 6, rspsqX, rspsqY, rspsqZ)); }
void _tenGageAnswer (gageContext *ctx, gagePerVolume *pvl) { /* char me[]="_tenGageAnswer"; */ gage_t epsilon=1.0E-10f; gage_t *tenAns, *evalAns, *evecAns, *vecTmp=NULL, *gradDtA=NULL, *gradDtB=NULL, *gradDtC=NULL, *gradDtD=NULL, *gradDtE=NULL, *gradDtF=NULL, gradDdXYZ[21]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, *gradCbS=NULL, *gradCbB=NULL, *gradCbQ=NULL, *gradCbR=NULL; gage_t tmp0, tmp1, magTmp=0, gradCbA[3]={0,0,0}, gradCbC[3]={0,0,0}, dtA=0, dtB=0, dtC=0, dtD=0, dtE=0, dtF=0, cbQQQ=0, cbQ=0, cbR=0, cbA=0, cbB=0, cbC=0, cbS=0; #if !GAGE_TYPE_FLOAT int ci; float evalAnsF[3], aniso[TEN_ANISO_MAX+1]; #endif tenAns = pvl->directAnswer[tenGageTensor]; evalAns = pvl->directAnswer[tenGageEval]; evecAns = pvl->directAnswer[tenGageEvec]; if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageTensor)) { /* done if doV */ tenAns[0] = AIR_CLAMP(0.0f, tenAns[0], 1.0f); dtA = tenAns[1]; dtB = tenAns[2]; dtC = tenAns[3]; dtD = tenAns[4]; dtE = tenAns[5]; dtF = tenAns[6]; if (ctx->verbose) { fprintf(stderr, "tensor = (%g) %g %g %g %g %g %g\n", tenAns[0], dtA, dtB, dtC, dtD, dtE, dtF); } } /* done if doV if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageConfidence)) { } */ if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageTrace)) { cbA = -(pvl->directAnswer[tenGageTrace][0] = dtA + dtD + dtF); } if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageB)) { cbB = pvl->directAnswer[tenGageB][0] = dtA*dtD + dtA*dtF + dtD*dtF - dtB*dtB - dtC*dtC - dtE*dtE; } if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageDet)) { cbC = -(pvl->directAnswer[tenGageDet][0] = 2.0f*dtB*dtC*dtE + dtA*dtD*dtF - dtC*dtC*dtD - dtA*dtE*dtE - dtB*dtB*dtF); } if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageS)) { cbS = (pvl->directAnswer[tenGageS][0] = dtA*dtA + dtD*dtD + dtF*dtF + 2.0f*dtB*dtB + 2.0f*dtC*dtC + 2.0f*dtE*dtE); } if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageQ)) { cbQ = pvl->directAnswer[tenGageQ][0] = (cbS - cbB)/9.0f; } if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageFA)) { pvl->directAnswer[tenGageFA][0] = AIR_CAST(gage_t, 3*sqrt(cbQ/(epsilon + cbS))); } if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageR)) { cbR = pvl->directAnswer[tenGageR][0] = (5.0f*cbA*cbB - 27.0f*cbC - 2.0f*cbA*cbS)/54.0f; } if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageTheta)) { cbQQQ = cbQ*cbQ*cbQ; tmp0 = AIR_CAST(gage_t, cbR/(epsilon + sqrt(cbQQQ))); tmp0 = AIR_CLAMP(-1.0f, tmp0, 1.0f); pvl->directAnswer[tenGageTheta][0] = AIR_CAST(gage_t, acos(tmp0)/AIR_PI); } if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageEvec)) { /* we do the longer process to get eigenvectors, and in the process we always find the eigenvalues, whether or not they were asked for */ #if GAGE_TYPE_FLOAT tenEigensolve_f(evalAns, evecAns, tenAns); #else tenEigensolve_d(evalAns, evecAns, tenAns); #endif } else if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageEval)) { /* else eigenvectors are NOT needed, but eigenvalues ARE needed */ #if GAGE_TYPE_FLOAT tenEigensolve_f(evalAns, NULL, tenAns); #else tenEigensolve_d(evalAns, NULL, tenAns); #endif } if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageTensorGrad)) { /* done if doD1 */ /* still have to set up pointer variables that item answers below will rely on as short-cuts */ vecTmp = pvl->directAnswer[tenGageTensorGrad]; gradDtA = vecTmp + 1*3; gradDtB = vecTmp + 2*3; gradDtC = vecTmp + 3*3; gradDtD = vecTmp + 4*3; gradDtE = vecTmp + 5*3; gradDtF = vecTmp + 6*3; TEN_T_SET(gradDdXYZ + 0*7, tenAns[0], gradDtA[0], gradDtB[0], gradDtC[0], gradDtD[0], gradDtE[0], gradDtF[0]); TEN_T_SET(gradDdXYZ + 1*7, tenAns[0], gradDtA[1], gradDtB[1], gradDtC[1], gradDtD[1], gradDtE[1], gradDtF[1]); TEN_T_SET(gradDdXYZ + 2*7, tenAns[0], gradDtA[2], gradDtB[2], gradDtC[2], gradDtD[2], gradDtE[2], gradDtF[2]); } if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageTensorGradMag)) { vecTmp = pvl->directAnswer[tenGageTensorGradMag]; vecTmp[0] = AIR_CAST(gage_t, sqrt(TEN_T_DOT(gradDdXYZ + 0*7, gradDdXYZ + 0*7))); vecTmp[1] = AIR_CAST(gage_t, sqrt(TEN_T_DOT(gradDdXYZ + 1*7, gradDdXYZ + 1*7))); vecTmp[2] = AIR_CAST(gage_t, sqrt(TEN_T_DOT(gradDdXYZ + 2*7, gradDdXYZ + 2*7))); } if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageTensorGradMag)) { pvl->directAnswer[tenGageTensorGradMagMag][0] = AIR_CAST(gage_t, ELL_3V_LEN(vecTmp)); } /* --- Trace --- */ if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageTraceGradVec)) { vecTmp = pvl->directAnswer[tenGageTraceGradVec]; ELL_3V_ADD3(vecTmp, gradDtA, gradDtD, gradDtF); ELL_3V_SCALE(gradCbA, -1, vecTmp); } if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageTraceGradMag)) { magTmp = pvl->directAnswer[tenGageTraceGradMag][0] = AIR_CAST(gage_t, ELL_3V_LEN(vecTmp)); } if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageTraceNormal)) { ELL_3V_SCALE(pvl->directAnswer[tenGageTraceNormal], 1.0f/(epsilon + magTmp), vecTmp); } /* --- B --- */ if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageBGradVec)) { gradCbB = vecTmp = pvl->directAnswer[tenGageBGradVec]; ELL_3V_SCALE_ADD6(vecTmp, dtD + dtF, gradDtA, -2.0f*dtB, gradDtB, -2.0f*dtC, gradDtC, dtA + dtF, gradDtD, -2.0f*dtE, gradDtE, dtA + dtD, gradDtF); } if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageBGradMag)) { magTmp = pvl->directAnswer[tenGageBGradMag][0] = AIR_CAST(gage_t, ELL_3V_LEN(vecTmp)); } if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageBNormal)) { ELL_3V_SCALE(pvl->directAnswer[tenGageBNormal], 1.0f/(epsilon + magTmp), vecTmp); } /* --- Det --- */ if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageDetGradVec)) { vecTmp = pvl->directAnswer[tenGageDetGradVec]; ELL_3V_SCALE_ADD6(vecTmp, dtD*dtF - dtE*dtE, gradDtA, 2.0f*(dtC*dtE - dtB*dtF), gradDtB, 2.0f*(dtB*dtE - dtC*dtD), gradDtC, dtA*dtF - dtC*dtC, gradDtD, 2.0f*(dtB*dtC - dtA*dtE), gradDtE, dtA*dtD - dtB*dtB, gradDtF); ELL_3V_SCALE(gradCbC, -1, vecTmp); } if (GAGE_QUERY_ITEM_TEST(pvl->query, tenGageDetGradMag)) { magTmp = pvl->directAnswer[tenGageDetGradMag][0] = AIR_CAST(float, ELL_3V_LEN(vecTmp)); }