示例#1
0
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;
}
示例#2
0
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]);
    }
}
示例#3
0
	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);
	}
示例#4
0
 //! @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];
 }
示例#5
0
文件: main.cpp 项目: CCJY/coliru
 ~ScopeGuard()
 {
     if (mActive)
     {
         mFunction();
     }
 }
示例#6
0
	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);
	}
示例#7
0
            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);
            }
示例#8
0
void Method::invoke(Object* const obj) {
	if (!obj->isInstanceOf(this->getDeclaringClass())) {
		throw MethodNotFound();
	}
	objectContext.push(obj);
	mFunction(obj);
	objectContext.pop();
}
示例#9
0
    //! @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;
    }
示例#10
0
 void forCaches(TFunction&& mFunction)
 {
     Utils::forTuple(
         [&mFunction](auto& mX)
         {
             mFunction(mX);
         },
         signatureCache);
 }
示例#11
0
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;
}
示例#12
0
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;
}
示例#13
0
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;
    }
示例#15
0
 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;
     }
 }
示例#16
0
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;
}
示例#17
0
void Cue::loopStart()
{
	if( mFunction )
		mFunction();
}
示例#18
0
 inline void run()
 {
   mFunction(mArg);
 }
示例#19
0
void CCCallLambda::update(float time) {
    
    CCActionInstant::update(time);
    
    mFunction();
}
示例#20
0
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);
		}
	}
}
示例#21
0
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);
		}
	}
}
示例#22
0
			// Call function
			void call(Parameter arg) const
			{
				mFunction(arg);
			}
示例#23
0
template <typename F> B (F p1) : mFunction (p1) { mFunction (); }
示例#24
0
 virtual bool call(const TSingleArg<ArgType1>& args)
 {
    mFunction(args.mArg1);
    return true;
 }
示例#25
0
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;
}
示例#26
0
 constexpr decltype(auto) forArgs(
     TFunction&& mFunction, Ts&&... mArgs)
 {
     return (void)std::initializer_list<int>{
         (mFunction(ECS_FWD(mArgs)), 0)...};
 }
示例#27
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;
}