Пример #1
0
Eigen::VectorXd GLMMBelief::evaluateDerivative(const Eigen::VectorXd& x,
					       const Parameters& parameters)
{
  setTheta(parameters.GLMMTheta);
  setBeta(parameters.GLMMBeta);
  auto family = parameters.GLMMFamily;
  auto linearPredictor = computeLinearPredictor(x);
  return LambdatThetaZt_ * family.evaluateDerivative(linearPredictor, response_, weights_).matrix();
}
Пример #2
0
//==============================================================================
void Spline::getWaypointDerivative(
    std::size_t _index, int _derivative, Eigen::VectorXd& _tangentVector) const
{
  if (_index < getNumWaypoints())
  {
    double waypointTime = getWaypointTime(_index);
    evaluateDerivative(waypointTime, _derivative, _tangentVector);
  }
  else
  {
    throw std::domain_error("Waypoint index is out of bounds.");
  }
}
Пример #3
0
void SkCurveMeasure::getPosTanTime(SkScalar targetLength, SkPoint* pos,
                                   SkVector* tan, SkScalar* time) {
    SkScalar t = getTime(targetLength);

    if (time) {
        *time = t;
    }
    if (pos) {
        *pos = evaluate(fPts, fSegType, t);
    }
    if (tan) {
        *tan = evaluateDerivative(fPts, fSegType, t);
    }
}
Пример #4
0
SkScalar SkCurveMeasure::getTime(SkScalar targetLength) {
    if (targetLength == 0.0f) {
        return 0.0f;
    }

    SkScalar currentLength = getLength();

    if (SkScalarNearlyEqual(targetLength, currentLength)) {
        return 1.0f;
    }

    // initial estimate of t is percentage of total length
    SkScalar currentT = targetLength / currentLength;
    SkScalar prevT = -1.0f;
    SkScalar newT;

    SkScalar minT = 0.0f;
    SkScalar maxT = 1.0f;

    int iterations = 0;
    while (iterations < kNewtonIters + kBisectIters) {
        currentLength = fIntegrator.computeLength(currentT);
        SkScalar lengthDiff = currentLength - targetLength;

        // Update root bounds.
        // If lengthDiff is positive, we have overshot the target, so
        // we know the current t is an upper bound, and similarly
        // for the lower bound.
        if (lengthDiff > 0.0f) {
            if (currentT < maxT) {
                maxT = currentT;
            }
        } else {
            if (currentT > minT) {
                minT = currentT;
            }
        }

        // We have a tolerance on both the absolute value of the difference and
        // on the t value
        // because we may not have enough precision in the t to get close enough
        // in the length.
        if ((std::abs(lengthDiff) < kTolerance) ||
            (std::abs(prevT - currentT) < kTolerance)) {
            break;
        }

        prevT = currentT;
        if (iterations < kNewtonIters) {
            // This is just newton's formula.
            SkScalar dt = evaluateDerivative(fPts, fSegType, currentT).length();
            newT = currentT - (lengthDiff / dt);

            // If newT is out of bounds, bisect inside newton.
            if ((newT < 0.0f) || (newT > 1.0f)) {
                newT = (minT + maxT) * 0.5f;
            }
        } else if (iterations < kNewtonIters + kBisectIters) {
            if (lengthDiff > 0.0f) {
                maxT = currentT;
            } else {
                minT = currentT;
            }
            // TODO(hstern) do a lerp here instead of a bisection
            newT = (minT + maxT) * 0.5f;
        } else {
            SkDEBUGF(("%.7f %.7f didn't get close enough after bisection.\n",
                      currentT, currentLength));
            break;
        }
        currentT = newT;

        SkASSERT(minT <= maxT);

        iterations++;
    }

    // debug. is there an SKDEBUG or something for ifdefs?
    fIters = iterations;

    return currentT;
}