示例#1
0
文件: triple.c 项目: BRAINSia/teem
void
tenTripleCalcSingle_d(double dst[3], int ttype, double ten[7]) {
  double eval[3];

  /* in time this can become more efficient ... */
  switch (ttype) {
  case tenTripleTypeEigenvalue:
    tenEigensolve_d(dst, NULL, ten);
    break;
  case tenTripleTypeMoment:
  case tenTripleTypeXYZ:
  case tenTripleTypeRThetaZ:
  case tenTripleTypeRThetaPhi:
  case tenTripleTypeK:
  case tenTripleTypeJ:
  case tenTripleTypeWheelParm:
    tenEigensolve_d(eval, NULL, ten);
    tenTripleConvertSingle_d(dst, ttype, eval, tenTripleTypeEigenvalue);
    break;
  case tenTripleTypeR:
    dst[0] = sqrt(_tenAnisoTen_d[tenAniso_S](ten));
    dst[1] = _tenAnisoTen_d[tenAniso_FA](ten);
    dst[2] = _tenAnisoTen_d[tenAniso_Mode](ten);
    break;
  default:
    /* what on earth? */
    ELL_3V_SET(dst, AIR_NAN, AIR_NAN, AIR_NAN);
  }
  return;
}
示例#2
0
/* unlike with the K stuff, with the R stuff I seemed to have more luck
   implementing pair-wise interpolation in terms of log and exp
*/
void
tenQGLInterpTwoEvalR(double oeval[3],
                     const double evalA[3], const double evalB[3],
                     const double tt) {
  double RThPhA[3], RThPhB[3], rlog[3], oRThPh[3];

  tenTripleConvertSingle_d(RThPhA, tenTripleTypeRThetaPhi,
                           evalA, tenTripleTypeEigenvalue);
  tenTripleConvertSingle_d(RThPhB, tenTripleTypeRThetaPhi,
                           evalB, tenTripleTypeEigenvalue);
  _tenQGL_Rlog(rlog, RThPhA, RThPhB);
  ELL_3V_SCALE(rlog, tt, rlog);
  _tenQGL_Rexp(oRThPh, RThPhA, rlog);
  tenTripleConvertSingle_d(oeval, tenTripleTypeEigenvalue,
                           oRThPh, tenTripleTypeRThetaPhi);
  return;
}
示例#3
0
文件: triple.c 项目: BRAINSia/teem
void
tenTripleConvertSingle_f(float _dst[3], int dstType,
                         const float _src[3], const int srcType) {
  double dst[3], src[3];

  ELL_3V_COPY(src, _src);
  tenTripleConvertSingle_d(dst, dstType, src, srcType);
  ELL_3V_COPY_TT(_dst, float, dst);
}
示例#4
0
void
tenQGLInterpTwoEvalK(double oeval[3],
                     const double evalA[3], const double evalB[3],
                     const double tt) {
  double RThZA[3], RThZB[3], oRThZ[3], bb;

  tenTripleConvertSingle_d(RThZA, tenTripleTypeRThetaZ,
                           evalA, tenTripleTypeEigenvalue);
  tenTripleConvertSingle_d(RThZB, tenTripleTypeRThetaZ,
                           evalB, tenTripleTypeEigenvalue);
  if (rr1 > rr0) {
    /* the bb calculation below could blow up, so we recurse
       with flipped order */
    tenQGLInterpTwoEvalK(oeval, evalB, evalA, 1-tt);
  } else {
    rr = AIR_LERP(tt, rr0, rr1);
    zz = AIR_LERP(tt, zz0, zz1);
    bb = rr0 ? (rr1/rr0 - 1) : 0;
    /* bb can't be positive, because rr1 <= rr0 enforced above, so below
       is really test for -0.001 < bb <= 0  */
    if (bb > -0.0001) {
      double dth;
      dth = th1 - th0;
      /* rr0 and rr1 are similar, use stable approximation */
      th = th0 + tt*(dth
                     + (0.5 - tt/2)*dth*bb
                     + (-1.0/12 - tt/4 + tt*tt/3)*dth*bb*bb
                     + (1.0/24 + tt/24 + tt*tt/6 - tt*tt*tt/4)*dth*bb*bb*bb);
    } else {
      /* use original formula */
      /* have to clamp value of b so that log() values don't explode */
      bb = AIR_MAX(bb, -1 + 100*FLT_EPSILON);
      th = th0 + (th1 - th0)*log(1 + bb*tt)/log(1 + bb);
    }
    tenTripleConvertSingle_d(oeval, tenTripleTypeEigenvalue,
                             oRThZ, tenTripleTypeRThetaZ);
    /*
    fprintf(stderr, "%s: (b = %g) %g %g %g <-- %g %g %g\n", "blah", bb,
            oeval[0], oeval[1], oeval[2],
            oRThZ[0], oRThZ[1], oRThZ[2]);
    */
  }
}
示例#5
0
/* normalized gradients of k or r invariants, in XYZ space,
   to help determine if path is really a loxodrome */
void
kgrads(double grad[3][3], const double eval[3]) {
  double rtz[3];

  tenTripleConvertSingle_d(rtz, tenTripleTypeRThetaZ,
                           eval, tenTripleTypeEigenvalue);

  ELL_3V_SET(grad[0], cos(rtz[1]), sin(rtz[1]), 0);
  ELL_3V_SET(grad[1], -sin(rtz[1]), cos(rtz[1]), 0);
  ELL_3V_SET(grad[2], 0, 0, 1);
}
示例#6
0
文件: ttriple.c 项目: rblake/seg3d2
int
main(int argc, char *argv[]) {
  char *me;
  hestOpt *hopt=NULL;
  airArray *mop;

  int *itype, itypeNum, ii;
  double src[3], last[3], dst[3];
  char space[] = "             ";

  me = argv[0];
  hestOptAdd(&hopt, NULL, "v1 v2 v3", airTypeDouble, 3, 3, src, NULL,
             "source triple");
  hestOptAdd(&hopt, "t", "type", airTypeEnum, 2, -1, &itype, NULL,
             "sequence of triple types to convert through",
             &itypeNum, tenTripleType);
  hestParseOrDie(hopt, argc-1, argv+1, NULL,
                 me, info, AIR_TRUE, AIR_TRUE, AIR_TRUE);
  mop = airMopNew();
  airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways);
  airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways);

  printf("%s", space + strlen(airEnumStr(tenTripleType, itype[0])));
  printf("%s", airEnumStr(tenTripleType, itype[0]));
  ell_3v_print_d(stdout, src);
  ELL_3V_COPY(last, src);
  for (ii=1; ii<itypeNum; ii++) {
    tenTripleConvertSingle_d(dst, itype[ii], src, itype[ii-1]);
    printf("%s", space + strlen(airEnumStr(tenTripleType, itype[ii])));
    printf("%s", airEnumStr(tenTripleType, itype[ii]));
    ell_3v_print_d(stdout, dst);
    ELL_3V_COPY(src, dst);
  }
  /*
  tenTripleConvert_d(dst, dstType, src, srcType);
  tenTripleConvert_d(tst, srcType, dst, dstType);
  */

  /*
  printf("%s: %s %s --> %s --> %s\n", me, 
         tenTriple->name,
         airEnumStr(tenTriple, srcType),
         airEnumStr(tenTriple, dstType),
         airEnumStr(tenTriple, srcType));
  ell_3v_print_d(stdout, src);
  ell_3v_print_d(stdout, dst);
  ell_3v_print_d(stdout, tst);
  */

  airMopOkay(mop);
  return 0;
}
示例#7
0
文件: triple.c 项目: BRAINSia/teem
int
tenTripleConvert(Nrrd *nout, int dstType,
                 const Nrrd *nin, int srcType) {
  static const char me[]="tenTripleConvert";
  size_t II, NN;
  double (*ins)(void *, size_t, double), (*lup)(const void *, size_t);

  if (!( nout && nin )) {
    biffAddf(TEN, "%s: got NULL pointer", me);
    return 1;
  }
  if ( airEnumValCheck(tenTripleType, dstType) ||
       airEnumValCheck(tenTripleType, srcType) ) {
    biffAddf(TEN, "%s: got invalid %s dst (%d) or src (%d)", me,
             tenTripleType->name, dstType, srcType);
    return 1;
  }
  if (3 != nin->axis[0].size) {
    char stmp[AIR_STRLEN_SMALL];
    biffAddf(TEN, "%s: need axis[0].size 3, not %s", me,
             airSprintSize_t(stmp, nin->axis[0].size));
    return 1;
  }
  if (nrrdTypeBlock == nin->type) {
    biffAddf(TEN, "%s: input has non-scalar %s type",
             me, airEnumStr(nrrdType, nrrdTypeBlock));
    return 1;
  }

  if (nrrdCopy(nout, nin)) {
    biffMovef(TEN, NRRD, "%s: couldn't initialize output", me);
    return 1;
  }
  lup = nrrdDLookup[nin->type];
  ins = nrrdDInsert[nout->type];
  NN = nrrdElementNumber(nin)/3;
  for (II=0; II<NN; II++) {
    double src[3], dst[3];
    src[0] = lup(nin->data, 0 + 3*II);
    src[1] = lup(nin->data, 1 + 3*II);
    src[2] = lup(nin->data, 2 + 3*II);
    tenTripleConvertSingle_d(dst, dstType, src, srcType);
    ins(nout->data, 0 + 3*II, dst[0]);
    ins(nout->data, 1 + 3*II, dst[1]);
    ins(nout->data, 2 + 3*II, dst[2]);
  }

  return 0;
}
示例#8
0
void
rgrads(double grad[3][3], const double eval[3]) {
  double rtp[3];

  tenTripleConvertSingle_d(rtp, tenTripleTypeRThetaPhi,
                           eval, tenTripleTypeEigenvalue);

  ELL_3V_SET(grad[0],
             cos(rtp[1])*sin(rtp[2]),
             sin(rtp[1])*sin(rtp[2]),
             cos(rtp[2]));
  ELL_3V_SET(grad[1], -sin(rtp[1]), cos(rtp[1]), 0);
  ELL_3V_SET(grad[2],
             cos(rtp[1])*cos(rtp[2]),
             sin(rtp[1])*cos(rtp[2]),
             -sin(rtp[2]));
}
示例#9
0
/*
** This does (non-optionally) use biff, to report convergence failures
**
** we do in fact require non-NULL tip, because it holds the buffers we need
*/
int
_tenQGLInterpNEval(double evalOut[3],
                   const double *evalIn, /* size 3 -by- NN */
                   const double *wght,   /* size NN */
                   unsigned int NN,
                   int ptype, tenInterpParm *tip) {
  static const char me[]="_tenQGLInterpNEval";
  double RTh_Out[3], elen;
  unsigned int ii, iter;
  int rttype;
  void (*llog)(double lg[3], const double RTh_A[3], const double RTh_B[3]);
  void (*lexp)(double RTh_B[3], const double RTh_A[3], const double lg[3]);

  if (!(evalOut && evalIn && tip)) {
    biffAddf(TEN, "%s: got NULL pointer", me);
    return 1;
  }
  /* convert to (R,Th,_) and initialize RTh_Out */
  if (tenInterpTypeQuatGeoLoxK == ptype) {
    rttype = tenTripleTypeRThetaZ;
    llog = _tenQGL_Klog;
    lexp = _tenQGL_Kexp;
  } else {
    rttype = tenTripleTypeRThetaPhi;
    llog = _tenQGL_Rlog;
    lexp = _tenQGL_Rexp;
  }
  ELL_3V_SET(RTh_Out, 0, 0, 0);
  for (ii=0; ii<NN; ii++) {
    double ww;
    tenTripleConvertSingle_d(tip->rtIn + 3*ii, rttype,
                             evalIn + 3*ii, tenTripleTypeEigenvalue);
    ww = wght ? wght[ii] : 1.0/NN;
    ELL_3V_SCALE_INCR(RTh_Out, ww, tip->rtIn + 3*ii);
  }

  /* compute iterated weighted mean, stored in RTh_Out */
  iter = 0;
  do {
    double logavg[3];
    /* take log of everyone */
    for (ii=0; ii<NN; ii++) {
      llog(tip->rtLog + 3*ii, RTh_Out, tip->rtIn + 3*ii);
    }
    /* average, and find length */
    ELL_3V_SET(logavg, 0, 0, 0);
    for (ii=0; ii<NN; ii++) {
      double ww;
      ww = wght ? wght[ii] : 1.0/NN;
      ELL_3V_SCALE_INCR(logavg, ww, tip->rtLog + 3*ii);
    }
    elen = ELL_3V_LEN(logavg);
    lexp(RTh_Out, RTh_Out, logavg);
    iter++;
  } while ((!tip->maxIter || iter < tip->maxIter) && elen > tip->convEps);

  if (elen > tip->convEps) {
    ELL_3V_SET(evalOut, AIR_NAN, AIR_NAN, AIR_NAN);
    biffAddf(TEN, "%s: still have error %g (> eps %g) after max %d iters", me,
             elen, tip->convEps, tip->maxIter);
    return 1;
  }

  /* finish, convert to eval */
  tenTripleConvertSingle_d(evalOut, tenTripleTypeEigenvalue,
                           RTh_Out, rttype);

  return 0;
}
示例#10
0
int
main(int argc, char *argv[]) {
  char *me;
  hestOpt *hopt=NULL;
  airArray *mop;

  double tripA[3], tripB[3], evalA[3], evalB[3],
    rt_A[3], rt_B[3], trip[3], eval[3], lasteval[3], lastxyz[3],
    logAB[3], ndist;
  int ittype, ottype, ptype, rttype;
  unsigned int NN, ii;
  tenInterpParm *tip;

  void (*interp)(double oeval[3], const double evalA[3],
                 const double evalB[3], const double tt);
  double (*qdist)(const double RTh_A[3], const double RTh_B[3]);
  void (*qlog)(double klog[3],
               const double RThZA[3], const double RThZB[3]);
  void (*qexp)(double RThZB[3], 
               const double RThZA[3], const double klog[3]);
  void (*grads)(double grad[3][3], const double eval[3]);

  me = argv[0];
  mop = airMopNew();
  tip = tenInterpParmNew();
  airMopAdd(mop, tip, (airMopper)tenInterpParmNix, airMopAlways);

  hestOptAdd(&hopt, "a", "start", airTypeDouble, 3, 3, tripA, NULL,
             "start triple of values");
  hestOptAdd(&hopt, "b", "end", airTypeDouble, 3, 3, tripB, NULL,
             "end triple of values");
  hestOptAdd(&hopt, "it", "type", airTypeEnum, 1, 1, &ittype, NULL,
             "type of given start and end triples", NULL, tenTripleType);
  hestOptAdd(&hopt, "ot", "type", airTypeEnum, 1, 1, &ottype, NULL,
             "type of triples for output", NULL, tenTripleType);
  hestOptAdd(&hopt, "p", "type", airTypeEnum, 1, 1, &ptype, NULL,
             "type of path interpolation", NULL, tenInterpType);
  hestOptAdd(&hopt, "n", "# steps", airTypeUInt, 1, 1, &NN, "100",
             "number of steps along path");

  hestOptAdd(&hopt, "v", "verbosity", airTypeInt, 1, 1,
             &(tip->verbose), "0", "verbosity");
  hestOptAdd(&hopt, "s", "stepsize", airTypeDouble, 1, 1,
             &(tip->convStep), "1", "step size in update");
  hestOptAdd(&hopt, "r", "recurse", airTypeInt, 0, 0,
             &(tip->enableRecurse), NULL,
             "enable recursive solution, when useful");
  hestOptAdd(&hopt, "mn", "minnorm", airTypeDouble, 1, 1,
             &(tip->minNorm), "0.000001",
             "minnorm of something");
  hestOptAdd(&hopt, "mi", "maxiter", airTypeUInt, 1, 1,
             &(tip->maxIter), "0",
             "if non-zero, max # iterations for computation");
  hestOptAdd(&hopt, "c", "conv", airTypeDouble, 1, 1,
             &(tip->convEps), "0.0001",
             "convergence threshold of length fraction");

  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);

  if (!( tenInterpTypeQuatGeoLoxK == ptype
         || tenInterpTypeQuatGeoLoxR == ptype )) {
    fprintf(stderr, "%s: need type %s or %s, not %s\n", me,
            airEnumStr(tenInterpType, tenInterpTypeQuatGeoLoxK),
            airEnumStr(tenInterpType, tenInterpTypeQuatGeoLoxR),
            airEnumStr(tenInterpType, ptype));
    airMopError(mop); 
    return 1;
  }

  if (tenInterpTypeQuatGeoLoxK == ptype) {
    interp = tenQGLInterpTwoEvalK;
    qdist = _tenQGL_Kdist;
    qlog = _tenQGL_Klog;
    qexp = _tenQGL_Kexp;
    grads = kgrads;
    rttype = tenTripleTypeRThetaZ;
  } else {
    interp = tenQGLInterpTwoEvalR;
    qdist = _tenQGL_Rdist;
    qlog = _tenQGL_Rlog;
    qexp = _tenQGL_Rexp;
    grads = rgrads;
    rttype = tenTripleTypeRThetaPhi;
  }

  fprintf(stderr, "%s: (%s) %f %f %f \n--%s--> %f %f %f\n", me,
          airEnumStr(tenTripleType, ittype),
          tripA[0], tripA[1], tripA[2],
          airEnumStr(tenInterpType, ptype),
          tripB[0], tripB[1], tripB[2]);

  tenTripleConvertSingle_d(evalA, tenTripleTypeEigenvalue, tripA, ittype);
  tenTripleConvertSingle_d(evalB, tenTripleTypeEigenvalue, tripB, ittype);
  tenTripleConvertSingle_d(rt_A, rttype, tripA, ittype);
  tenTripleConvertSingle_d(rt_B, rttype, tripB, ittype);

  ndist = 0;
  ELL_3V_SET(lasteval, AIR_NAN, AIR_NAN, AIR_NAN);
  ELL_3V_SET(lastxyz, AIR_NAN, AIR_NAN, AIR_NAN);
  qlog(logAB, rt_A, rt_B);
  fprintf(stderr, "%s: log = %g %g %g (%g)\n", me, 
          logAB[0], logAB[1], logAB[2], ELL_3V_LEN(logAB));
  for (ii=0; ii<NN; ii++) {
    double tt, xyz[3], dot[3], ll[3], prayRT[3], prayO[3];
    tt = AIR_AFFINE(0, ii, NN-1, 0.0, 1.0);
    interp(eval, evalA, evalB, tt);
    tenTripleConvertSingle_d(trip, ottype,
                             eval, tenTripleTypeEigenvalue);
    tenTripleConvertSingle_d(xyz, tenTripleTypeXYZ,
                             eval, tenTripleTypeEigenvalue);
    ELL_3V_SCALE(ll, tt, logAB);
    qexp(prayRT, rt_A, ll);
    tenTripleConvertSingle_d(prayO, ottype, prayRT, rttype);
    if (ii) {
      double diff[3], gr[3][3];
      ELL_3V_SUB(diff, lasteval, eval);
      ndist += ELL_3V_LEN(diff);
      ELL_3V_SUB(diff, lastxyz, xyz);
      grads(gr, eval);
      dot[0] = ELL_3V_DOT(diff, gr[0]);
      dot[1] = ELL_3V_DOT(diff, gr[1]);
      dot[2] = ELL_3V_DOT(diff, gr[2]);
    } else {
      ELL_3V_SET(dot, 0, 0, 0);
    }
    printf("%03u %g %g   %g %g    %g %g   00   %g %g %g\n", ii,
           trip[0], prayO[0], 
           trip[1], prayO[1], 
           trip[2], prayO[2],
           dot[0], dot[1], dot[2]);
    ELL_3V_COPY(lasteval, eval);
    ELL_3V_COPY(lastxyz, xyz);
  }

  fprintf(stderr, "%s: dist %g =?= %g\n", me,
          qdist(rt_A, rt_B), ndist);

  airMopOkay(mop);
  return 0;
}