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(); }
//============================================================================== 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."); } }
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); } }
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; }