void Minimize1<Real>::GetMinimum (Real t0, Real t1, Real tInitial, Real& tMin, Real& fMin) { assertion(t0 <= tInitial && tInitial <= t1, "Invalid initial t value\n"); mTMin = Math<Real>::MAX_REAL; mFMin = Math<Real>::MAX_REAL; Real f0 = mFunction(t0, mUserData); if (f0 < mFMin) { mTMin = t0; mFMin = f0; } Real fInitial = mFunction(tInitial, mUserData); if (fInitial < mFMin) { mTMin = tInitial; mFMin = fInitial; } Real f1 = mFunction(t1, mUserData); if (f1 < mFMin) { mTMin = t1; mFMin = f1; } GetMinimum(t0, f0, tInitial, fInitial, t1, f1, mMaxLevel); tMin = mTMin; fMin = mFMin; }
void OdeRungeKutta4<Real>::Update (Real tIn, Real* xIn, Real& tOut, Real* xOut) { // first step mFunction(tIn, xIn, mUserData, mTemp1); int i; for (i = 0; i < mDim; ++i) { mXTemp[i] = xIn[i] + mHalfStep*mTemp1[i]; } // second step Real halfT = tIn + mHalfStep; mFunction(halfT, mXTemp, mUserData, mTemp2); for (i = 0; i < mDim; ++i) { mXTemp[i] = xIn[i] + mHalfStep*mTemp2[i]; } // third step mFunction(halfT, mXTemp, mUserData, mTemp3); for (i = 0; i < mDim; ++i) { mXTemp[i] = xIn[i] + mStep*mTemp3[i]; } // fourth step tOut = tIn + mStep; mFunction(tOut, mXTemp, mUserData, mTemp4); for (i = 0; i < mDim; ++i) { xOut[i] = xIn[i] + mSixthStep*(mTemp1[i] + ((Real)2)*(mTemp2[i] + mTemp3[i]) + mTemp4[i]); } }
virtual HTMLEventStatus Event(HTMLElement *pElement, HTMLEvent *pEvent, WEBC_CHAR *pParam = 0) { HTMLEventStatus result = HTML_EVENT_STATUS_CONTINUE; if (mFunction) { HTMLDocument *pDoc; HTMLBrowser *pBrowser; pDoc = (pElement)? pElement->GetDocument() : 0; pBrowser = (pDoc)? pDoc->GetBrowser() : 0; char *param = webc_arg_to_char(pParam); if (!param) { param = nphoney; } result = mFunction((HBROWSER_HANDLE)pBrowser, (HDOC_HANDLE)pDoc, (HELEMENT_HANDLE)pElement, pEvent, param); if (param != nphoney) { webc_arg_done(param); } } return (result); }
//! @brief returns the value of the function for the given arguments. //! Repeated calls of Get() with the same arguments will return the memoized //! result. //! @param v ... argument //! @return reference to the 'memoized' result const TResult& Get(const TNaturalCoords& v) const { size_t id = TIdHash()(v); if (mCache[id] == nullptr) mCache[id] = std::make_unique<TResult>(mFunction(v)); return *mCache[id]; }
~ScopeGuard() { if (mActive) { mFunction(); } }
virtual HTMLEventStatus Event(HTMLElement *pElement, HTMLEvent *pEvent, WEBC_CHAR *pParam = 0) { HTMLEventStatus result = HTML_EVENT_STATUS_CONTINUE; if (mFunction) { HTMLDocument *pDoc; HTMLBrowser *pBrowser; wcCtx _Ctx; char nphoney[4]; pDoc = (pElement)? pElement->GetDocument() : 0; pBrowser = (pDoc)? pDoc->GetBrowser() : 0; wcCtxtInit(&_Ctx, (wcBROW) pBrowser, (wcDOC) pDoc); char *param = webc_arg_to_char(pParam); if (!param) param = &nphoney[0]; result = mFunction(&_Ctx, (wcEL)pElement, pEvent, param); wcCtxtRelease(&_Ctx); if (param != &nphoney[0]) webc_arg_done(param); } return (result); }
void forCache(TFunction&& mFunction) { auto& c(getCache<TSignature>()); auto iEnd(&(c.v[c.size])); for(auto iBegin(&(c.v[0])); iBegin != iEnd; ++iBegin) mFunction(*iBegin); }
void Method::invoke(Object* const obj) { if (!obj->isInstanceOf(this->getDeclaringClass())) { throw MethodNotFound(); } objectContext.push(obj); mFunction(obj); objectContext.pop(); }
//! @brief returns the value of the function for the given arguments. //! Repeated calls of Get() with the same arguments will return the memoized //! result. //! @param v ... argument //! @return reference to the 'memoized' result const TResult& Get(const TNaturalCoords& v) const { auto it = mCache.find(v); if (it != mCache.end()) return it->second; auto emplace_result = mCache.emplace(v, mFunction(v)); return emplace_result.first->second; }
void forCaches(TFunction&& mFunction) { Utils::forTuple( [&mFunction](auto& mX) { mFunction(mX); }, signatureCache); }
void OdeEuler<Real>::Update (Real tIn, Real* xIn, Real& tOut, Real* xOut) { mFunction(tIn, xIn, mUserData, mFValue); for (int i = 0; i < mDim; ++i) { xOut[i] = xIn[i] + mStep*mFValue[i]; } tOut = tIn + mStep; }
Real* OdeEuler<Real>::step() { Real h = mStepSize; Real t = mCurrentStep; mFunction(t, mLastValue, mFunctionResult); for (INT i = 0; i < mDimension; ++i) mLastValue[i] = mLastValue[i] + h * mFunctionResult[i]; mCurrentStep += mStepSize; return mLastValue; }
Real* OdeRungeKutta4<Real>::step() { Real h = mStepSize; Real t = mCurrentStep; Real half_h = h / 2.0f; Real k1, k2, k3, k4, yi; for (INT i = 0; i < mDimension; ++i) { yi = mLastValue[i]; k1 = h * mFunction(t, yi, i); k2 = h * mFunction(t + half_h, yi + k1 / 2.0f, i); k3 = h * mFunction(t + half_h, yi + k2 / 2.0f, i); k4 = h * mFunction(t + h, yi + k3, i); mLastValue[i] = yi + (1 / 6.0f) * (k1 + 2.0f * k2 + 2.0f * k3 + k4); } mCurrentStep += h; return mLastValue; }
Solver& BisectionSolver::solve() { mNumFunctionCalls = 0; // Simple Bisection Algorithm double xLow = mLow; double xHigh = mHigh; double xCenter = 0.0; double fLow = mFunction(xLow); double fHigh = mFunction(xHigh); double fCenter = 0.0; if (fLow * fHigh > 0.0) throw NoRootException {__FILE__, __LINE__, "f(low) * f(high) > 0."}; int maxIter = static_cast<int>(std::log2((xHigh - xLow)/ mTol)) + 1; for (int iter = 0; iter < maxIter; ++iter) { xCenter = 0.5 * (xLow + xHigh); fCenter = mFunction(xCenter); if (fCenter * fHigh > 0.0) { xHigh = xCenter; fHigh = fCenter; } else { xLow = xCenter; fLow = fCenter; } } mRootPoint = {xCenter}; return *this; }
void CThreadPool::CMember::ThreadProc() { mParent->OnStartup(this); while (mThreadContinue) { mParent->OnIdle(this); mSemaphore.Wait(mParent->GetTimeOut()*1000); if (mFunction) { mFunction(mArgument); mArgument = NULL; mFunction = NULL; } else if (mParent->OnDestory(this)) mThreadContinue = false; } }
void OdeImplicitEuler<Real>::Update (Real tIn, Real* xIn, Real& tOut, Real* xOut) { mFunction(tIn, xIn, mUserData, mF); mDerFunction(tIn, xIn, mUserData, mDF); GMatrix<Real> DG = mIdentity - mStep*mDF; GMatrix<Real> DGInverse(mDim, mDim); bool invertible = LinearSystem<Real>().Inverse(DG, DGInverse); if (invertible) { mF = DGInverse*mF; for (int i = 0; i < mDim; ++i) { xOut[i] = xIn[i] + mStep*mF[i]; } } else { memcpy(xOut, xIn, mDim*sizeof(Real)); } tOut = tIn + mStep; }
void Cue::loopStart() { if( mFunction ) mFunction(); }
inline void run() { mFunction(mArg); }
void CCCallLambda::update(float time) { CCActionInstant::update(time); mFunction(); }
void Minimize1<Real>::GetBracketedMinimum (Real t0, Real f0, Real tm, Real fm, Real t1, Real f1, int level) { for (int i = 0; i < mMaxBracket; ++i) { // Update minimum value. if (fm < mFMin) { mTMin = tm; mFMin = fm; } // Test for convergence. const Real epsilon = (Real)1e-08; const Real tolerance = (Real)1e-04; if (Math<Real>::FAbs(t1-t0) <= ((Real)2)*tolerance* Math<Real>::FAbs(tm) + epsilon ) { break; } // Compute vertex of interpolating parabola. Real dt0 = t0 - tm; Real dt1 = t1 - tm; Real df0 = f0 - fm; Real df1 = f1 - fm; Real tmp0 = dt0*df1; Real tmp1 = dt1*df0; Real denom = tmp1 - tmp0; if (Math<Real>::FAbs(denom) < epsilon) { return; } Real tv = tm + ((Real)0.5)*(dt1*tmp1 - dt0*tmp0)/denom; assertion(t0 <= tv && tv <= t1, "Vertex not in interval\n"); Real fv = mFunction(tv, mUserData); if (fv < mFMin) { mTMin = tv; mFMin = fv; } if (tv < tm) { if (fv < fm) { t1 = tm; f1 = fm; tm = tv; fm = fv; } else { t0 = tv; f0 = fv; } } else if (tv > tm) { if (fv < fm) { t0 = tm; f0 = fm; tm = tv; fm = fv; } else { t1 = tv; f1 = fv; } } else { // The vertex of parabola is already at middle sample point. GetMinimum(t0, f0, tm, fm, level); GetMinimum(tm, fm, t1, f1, level); } } }
void Minimize1<Real>::GetMinimum (Real t0, Real f0, Real t1, Real f1, int level) { if (level-- == 0) { return; } Real tm = ((Real)0.5)*(t0 + t1); Real fm = mFunction(tm, mUserData); if (fm < mFMin) { mTMin = tm; mFMin = fm; } if (f0 - ((Real)2)*fm + f1 > (Real)0) { // The quadratic fit has positive second derivative at the midpoint. if (f1 > f0) { if (fm >= f0) { // Increasing, repeat on [t0,tm]. GetMinimum(t0, f0, tm, fm, level); } else { // Not monotonic, have a bracket. GetBracketedMinimum(t0, f0, tm, fm, t1, f1, level); } } else if (f1 < f0) { if (fm >= f1) { // Decreasing, repeat on [tm,t1]. GetMinimum(tm, fm, t1, f1, level); } else { // Not monotonic, have a bracket. GetBracketedMinimum(t0, f0, tm, fm, t1, f1, level); } } else { // Constant, repeat on [t0,tm] and [tm,t1]. GetMinimum(t0, f0, tm, fm, level); GetMinimum(tm, fm, t1, f1, level); } } else { // The quadratic fit has nonpositive second derivative at the // midpoint. if (f1 > f0) { // Repeat on [t0,tm]. GetMinimum(t0, f0, tm, fm, level); } else if (f1 < f0) { // Repeat on [tm,t1]. GetMinimum(tm, fm, t1, f1, level); } else { // Repeat on [t0,tm] and [tm,t1]. GetMinimum(t0, f0, tm, fm, level); GetMinimum(tm, fm, t1, f1, level); } } }
// Call function void call(Parameter arg) const { mFunction(arg); }
template <typename F> B (F p1) : mFunction (p1) { mFunction (); }
virtual bool call(const TSingleArg<ArgType1>& args) { mFunction(args.mArg1); return true; }
void MinimizeN<Real>::GetMinimum (const Real* t0, const Real* t1, const Real* tInitial, Real* tMin, Real& fMin) { // For 1D function callback. mMinimizer.SetUserData(this); // The initial guess. size_t numBytes = mDimensions*sizeof(Real); mFCurr = mFunction(tInitial, mUserData); memcpy(mTSave, tInitial, numBytes); memcpy(mTCurr, tInitial, numBytes); // Initialize the direction set to the standard Euclidean basis. size_t numBasisBytes = numBytes*(mDimensions + 1); memset(mDirectionStorage, 0, numBasisBytes); int i; for (i = 0; i < mDimensions; ++i) { mDirection[i][i] = (Real)1; } Real ell0, ell1, ellMin; for (int iter = 0; iter < mMaxIterations; iter++) { // Find minimum in each direction and update current location. for (i = 0; i < mDimensions; ++i) { mDCurr = mDirection[i]; ComputeDomain(t0, t1, ell0, ell1); mMinimizer.GetMinimum(ell0, ell1, (Real)0, ellMin, mFCurr); for (int j = 0; j < mDimensions; ++j) { mTCurr[j] += ellMin*mDCurr[j]; } } // Estimate a unit-length conjugate direction. Real length = (Real)0; for (i = 0; i < mDimensions; ++i) { mDConj[i] = mTCurr[i] - mTSave[i]; length += mDConj[i]*mDConj[i]; } const Real epsilon = (Real)1e-06; length = Math<Real>::Sqrt(length); if (length < epsilon) { // New position did not change significantly from old one. // Should there be a better convergence criterion here? break; } Real invlength = ((Real)1)/length; for (i = 0; i < mDimensions; ++i) { mDConj[i] *= invlength; } // Minimize in conjugate direction. mDCurr = mDConj; ComputeDomain(t0, t1, ell0, ell1); mMinimizer.GetMinimum(ell0, ell1, (Real)0, ellMin, mFCurr); for (i = 0; i < mDimensions; ++i) { mTCurr[i] += ellMin*mDCurr[i]; } // Cycle the directions and add conjugate direction to set. mDConj = mDirection[0]; for (i = 0; i < mDimensions; ++i) { mDirection[i] = mDirection[i+1]; } // Set parameters for next pass. memcpy(mTSave, mTCurr, numBytes); } memcpy(tMin, mTCurr, numBytes); fMin = mFCurr; }
constexpr decltype(auto) forArgs( TFunction&& mFunction, Ts&&... mArgs) { return (void)std::initializer_list<int>{ (mFunction(ECS_FWD(mArgs)), 0)...}; }
bool BrentsMethod<Real>::GetRoot (Real x0, Real x1, Real& xRoot, Real& fRoot) { if (x1 <= x0) { // The interval is invalid. return false; } Real f0 = mFunction(x0, mUserData); if (mNegFTolerance <= f0 && f0 <= mPosFTolerance) { // This endpoint is an approximate root that satisfies the function // tolerance. xRoot = x0; fRoot = f0; return true; } Real f1 = mFunction(x1, mUserData); if (mNegFTolerance <= f1 && f1 <= mPosFTolerance) { // This endpoint is an approximate root that satisfies the function // tolerance. xRoot = x1; fRoot = f1; return true; } if (f0*f1 >= (Real)0) { // The input interval must bound a root. return false; } if (fabs(f0) < fabs(f1)) { // Swap x0 and x1 so that |f(x1)| <= |f(x0)|. The number x1 is // considered to be the best estimate of the root. Real save = x0; x0 = x1; x1 = save; save = f0; f0 = f1; f1 = save; } // Initialize values for the root search. Real x2 = x0, x3 = x0, f2 = f0; bool prevBisected = true; // The root search. for (int i = 0; i < mMaxIterations; ++i) { Real fDiff01 = f0 - f1, fDiff02 = f0 - f2, fDiff12 = f1 - f2; Real invFDiff01 = ((Real)1)/fDiff01; Real s; if (fDiff02 != (Real)0 && fDiff12 != (Real)0) { // Use inverse quadratic interpolation. Real infFDiff02 = ((Real)1)/fDiff02; Real invFDiff12 = ((Real)1)/fDiff12; s = x0*f1*f2*invFDiff01*infFDiff02 - x1*f0*f2*invFDiff01*invFDiff12 + x2*f0*f1*infFDiff02*invFDiff12; } else { // Use inverse linear interpolation (secant method). s = (x1*f0 - x0*f1)*invFDiff01; } // Compute values need in the accept-or-reject tests. Real xDiffSAvr = s - ((Real)0.75)*x0 - ((Real)0.25)*x1; Real xDiffS1 = s - x1; Real absXDiffS1 = fabs(xDiffS1); Real absXDiff12 = fabs(x1 - x2); Real absXDiff23 = fabs(x2 - x3); bool currBisected = false; if (xDiffSAvr*xDiffS1 > (Real)0) { // The value s is not between 0.75*x0+0.25*x1 and x1. NOTE: The // algorithm sometimes has x0 < x1 but sometimes x1 < x0, so the // betweenness test does not use simple comparisons. currBisected = true; } else if (prevBisected) { // The first of Brent's tests to determine whether to accept the // interpolated s-value. currBisected = (absXDiffS1 >= ((Real)0.5)*absXDiff12) || (absXDiff12 <= mStepXTolerance); } else { // The second of Brent's tests to determine whether to accept the // interpolated s-value. currBisected = (absXDiffS1 >= ((Real)0.5)*absXDiff23) || (absXDiff23 <= mStepXTolerance); } if (currBisected) { // One of the additional tests failed, so reject the interpolated // s-value and use bisection instead. s = ((Real)0.5)*(x0 + x1); prevBisected = true; } else { prevBisected = false; } // Evaluate the function at the new estimate and test for convergence. Real fs = mFunction(s, mUserData); if (mNegFTolerance <= fs && fs <= mPosFTolerance) { xRoot = s; fRoot = fs; return true; } // Update the subinterval to include the new estimate as an endpoint. x3 = x2; x2 = x1; f2 = f1; if (f0*fs < (Real)0) { x1 = s; f1 = fs; } else { x0 = s; f0 = fs; } // Allow the algorithm to terminate when the subinterval is // sufficiently small. if (fabs(x1 - x0) <= mConvXTolerance) { xRoot = x1; fRoot = f1; return true; } // A loop invariant is that x1 is the root estimate, f(x0)*f(x1) < 0, // and |f(x1)| <= |f(x0)|. if (fabs(f0) < fabs(f1)) { Real save = x0; x0 = x1; x1 = save; save = f0; f0 = f1; f1 = save; } } return true; }