_TEN_PARM_ALLOC _TEN_PARM_RAND _TEN_PARM_STEP _TEN_PARM_DIST _TEN_PARM_COPY static int parmConvert(double *parmDst, const double *parmSrc, const tenModel *modelSrc) { int ret; if (modelSrc == tenModelBall) { TEN_T_SET(parmDst, parmSrc[0], parmSrc[1], 0, 0, parmSrc[1], 0, parmSrc[1]); ret = 0; } else if (modelSrc == tenModel1Stick) { double ten[7]; TEN_T3V_OUTER(ten, parmSrc + 2); TEN_T_SCALE(parmDst, parmSrc[1], ten); parmDst[0] = parmSrc[0]; ret = 0; } else if (modelSrc == tenModelBall1Stick) { double stick[7], ball[7], diff, frac; diff = parmSrc[1]; frac = parmSrc[2]; TEN_T3V_OUTER(stick, parmSrc + 3); TEN_T_SCALE(stick, diff, stick); TEN_T_SET(ball, 1, diff, 0, 0, diff, 0, diff); TEN_T_LERP(parmDst, frac, ball, stick); parmDst[0] = parmSrc[0]; ret = 1; } else if (modelSrc == tenModel1Cylinder) { double stick[7], ball[7], len, rad; len = parmSrc[1]; rad = parmSrc[2]; TEN_T3V_OUTER(stick, parmSrc + 3); TEN_T_SCALE(stick, len-rad, stick); TEN_T_SET(ball, 1, rad, 0, 0, rad, 0, rad); TEN_T_ADD(parmDst, ball, stick); parmDst[0] = parmSrc[0]; ret = 0; } else if (modelSrc == tenModel1Tensor2) { parmCopy(parmDst, parmSrc); ret = 0; } else { unsigned int ii; for (ii=0; ii<PARM_NUM; ii++) { parmDst[ii] = AIR_NAN; } ret = 2; } return ret; }
int main(int argc, const char *argv[]) { const char *me; hestOpt *hopt=NULL; airArray *mop; double _tt[6], tt[7], ss, pp[3], qq[4], rot[9], mat1[9], mat2[9], tmp, evalA[3], evecA[9], evalB[3], evecB[9]; int roots; mop = airMopNew(); me = argv[0]; hestOptAdd(&hopt, NULL, "m00 m01 m02 m11 m12 m22", airTypeDouble, 6, 6, _tt, NULL, "symmtric matrix coeffs"); hestOptAdd(&hopt, "p", "vec", airTypeDouble, 3, 3, pp, "0 0 0", "rotation as P vector"); hestOptAdd(&hopt, "s", "scl", airTypeDouble, 1, 1, &ss, "1.0", "scaling"); hestParseOrDie(hopt, argc-1, argv+1, NULL, me, info, AIR_TRUE, AIR_TRUE, AIR_TRUE); airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways); airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways); ELL_6V_COPY(tt + 1, _tt); tt[0] = 1.0; TEN_T_SCALE(tt, ss, tt); ELL_4V_SET(qq, 1, pp[0], pp[1], pp[2]); ELL_4V_NORM(qq, qq, tmp); ell_q_to_3m_d(rot, qq); printf("%s: rot\n", me); printf(" %g %g %g\n", rot[0], rot[1], rot[2]); printf(" %g %g %g\n", rot[3], rot[4], rot[5]); printf(" %g %g %g\n", rot[6], rot[7], rot[8]); TEN_T2M(mat1, tt); ell_3m_mul_d(mat2, rot, mat1); ELL_3M_TRANSPOSE_IP(rot, tmp); ell_3m_mul_d(mat1, mat2, rot); TEN_M2T(tt, mat1); printf("input matrix = \n %g %g %g\n %g %g\n %g\n", tt[1], tt[2], tt[3], tt[4], tt[5], tt[6]); printf("================== tenEigensolve_d ==================\n"); roots = tenEigensolve_d(evalA, evecA, tt); printf("%s roots\n", airEnumStr(ell_cubic_root, roots)); testeigen(tt, evalA, evecA); printf("================== new eigensolve ==================\n"); roots = evals(evalB, tt[1], tt[2], tt[3], tt[4], tt[5], tt[6]); printf("%s roots: %g %g %g\n", airEnumStr(ell_cubic_root, roots), evalB[0], evalB[1], evalB[2]); roots = evals_evecs(evalB, evecB, tt[1], tt[2], tt[3], tt[4], tt[5], tt[6]); printf("%s roots\n", airEnumStr(ell_cubic_root, roots)); testeigen(tt, evalB, evecB); airMopOkay(mop); return 0; }
static int csimDo(double tm[7], double tcov[21], double rm[3], double rv[3], Nrrd *ntbuff, tenEstimateContext *tec, double *dwibuff, double sigma, double bvalue, double B0, unsigned int NN, int randrot, double _tenOrig[7]) { char me[]="csimDo", err[BIFF_STRLEN]; double *tbuff; unsigned int II, taa, tbb, cc; if (!(ntbuff && ntbuff->data && 2 == ntbuff->dim && 7 == ntbuff->axis[0].size && NN == ntbuff->axis[1].size)) { sprintf(err, "%s: ntbuff not allocated for 2-by-%u array of %s", me, NN, airEnumStr(nrrdType, nrrdTypeDouble)); biffAdd(TEN, err); return 1; } /* find all tensors from simulated DWIs */ tbuff = AIR_CAST(double *, ntbuff->data); for (II=0; II<NN; II++) { double tenOrig[7], rotf[9], rotb[9], matA[9], matB[9], qq[4], tmp; ELL_3M_IDENTITY_SET(rotf); /* sssh warnings */ ELL_3M_IDENTITY_SET(rotb); /* sssh warnings */ if (randrot) { if (1) { double eval[3], evec[9], eps, ma[9], mb[9], rf[9], rb[9]; tenEigensolve_d(eval, evec, _tenOrig); airNormalRand(&eps, NULL); ell_aa_to_3m_d(rf, 0*eps/20, evec + 0); TEN_T_SCALE_INCR(_tenOrig, 0*eps/30, _tenOrig); TEN_T2M(ma, _tenOrig); ELL_3M_TRANSPOSE(rb, rf); ELL_3M_MUL(mb, ma, rf); ELL_3M_MUL(ma, rb, mb); TEN_M2T(_tenOrig, ma); } TEN_T2M(matA, _tenOrig); airNormalRand(qq+0, qq+1); airNormalRand(qq+2, qq+3); ELL_4V_NORM(qq, qq, tmp); ell_q_to_3m_d(rotf, qq); ELL_3M_TRANSPOSE(rotb, rotf); ELL_3M_MUL(matB, matA, rotf); ELL_3M_MUL(matA, rotb, matB); TEN_M2T(tenOrig, matA); } else { TEN_T_COPY(tenOrig, _tenOrig); } if (tenEstimate1TensorSimulateSingle_d(tec, dwibuff, sigma, bvalue, B0, tenOrig) || tenEstimate1TensorSingle_d(tec, tbuff, dwibuff)) { sprintf(err, "%s: trouble on exp %u/%u", me, II, NN); biffAdd(TEN, err); return 1; } if (randrot) { TEN_T2M(matA, tbuff); ELL_3M_MUL(matB, matA, rotb); ELL_3M_MUL(matA, rotf, matB); TEN_M2T(tbuff, matA); } /* else we leave tbuff as it is */ /* if (_tenOrig[0] > 0.5) { double tdiff[7]; TEN_T_SUB(tdiff, _tenOrig, tbuff); fprintf(stderr, "!%s: %g\n" " (%g) %g,%g,%g %g,%g %g\n" " (%g) %g,%g,%g %g,%g %g\n", me, TEN_T_NORM(tdiff), _tenOrig[0], _tenOrig[1], _tenOrig[2], _tenOrig[3], _tenOrig[4], _tenOrig[5], _tenOrig[6], tbuff[0], tbuff[1], tbuff[2], tbuff[3], tbuff[4], tbuff[5], tbuff[6]); } */ tbuff += 7; } /* find mean tensor, and mean R_i */ tbuff = AIR_CAST(double *, ntbuff->data); TEN_T_SET(tm, 0, 0, 0, 0, 0, 0, 0); ELL_3V_SET(rm, 0, 0, 0); for (II=0; II<NN; II++) { TEN_T_INCR(tm, tbuff); rm[0] += sqrt(_tenAnisoTen_d[tenAniso_S](tbuff)); rm[1] += _tenAnisoTen_d[tenAniso_FA](tbuff); rm[2] += _tenAnisoTen_d[tenAniso_Mode](tbuff); tbuff += 7; } rm[0] /= NN; rm[1] /= NN; rm[2] /= NN; TEN_T_SCALE(tm, 1.0/NN, tm); /* accumulate covariance tensor, and R_i variances */ for (cc=0; cc<21; cc++) { tcov[cc] = 0; } ELL_3V_SET(rv, 0, 0, 0); tbuff = AIR_CAST(double *, ntbuff->data); for (II=0; II<NN; II++) { double r[3]; r[0] = sqrt(_tenAnisoTen_d[tenAniso_S](tbuff)); r[1] = _tenAnisoTen_d[tenAniso_FA](tbuff); r[2] = _tenAnisoTen_d[tenAniso_Mode](tbuff); cc = 0; rv[0] += (r[0] - rm[0])*(r[0] - rm[0])/(NN-1); rv[1] += (r[1] - rm[1])*(r[1] - rm[1])/(NN-1); rv[2] += (r[2] - rm[2])*(r[2] - rm[2])/(NN-1); for (taa=0; taa<6; taa++) { for (tbb=taa; tbb<6; tbb++) { tcov[cc] += (10000*(tbuff[taa+1]-tm[taa+1]) *10000*(tbuff[tbb+1]-tm[tbb+1])/(NN-1)); cc++; } } tbuff += 7; } return 0; }