示例#1
0
/**
In the newton function, a 1-D Newton-Raphson solver is implemented using exact solutions.  An initial guess for the solution is provided.

@param f A pointer to an instance of the FuncWrapper1D class that implements the call() function
@param x0 The inital guess for the solution
@param ftol The absolute value of the tolerance accepted for the objective function
@param maxiter Maximum number of iterations
@returns If no errors are found, the solution, otherwise the value _HUGE, the value for infinity
*/
double Newton(FuncWrapper1DWithDeriv* f, double x0, double ftol, int maxiter)
{
    double x, dx, fval=999;
    int iter=1;
    f->errstring.clear();
    x = x0;
    while (iter < 2 || std::abs(fval) > ftol)
    {
        fval = f->call(x);
        dx = -fval/f->deriv(x);

        if (!ValidNumber(fval)){
            throw ValueError("Residual function in newton returned invalid number");
        };

        x += dx;

        if (std::abs(dx/x) < 1e-11){
            return x;
        }

        if (iter>maxiter)
        {
            f->errstring= "reached maximum number of iterations";
            throw SolutionError(format("Newton reached maximum number of iterations"));
        }
        iter=iter+1;
    }
    return x;
}
示例#2
0
double _T_hp_secant(std::string Ref, double h, double p, double T_guess)
{
    double x1=0,x2=0,x3=0,y1=0,y2=0,eps=1e-8,change=999,f=999,T=300;
    int iter=1;

    while ((iter<=3 || fabs(f)>eps) && iter<100)
    {
        if (iter==1){x1=T_guess; T=x1;}
        if (iter==2){x2=T_guess+0.1; T=x2;}
        if (iter>2) {T=x2;}
            f=Props("H",'T',T,'P',p,Ref)-h;
        if (iter==1){y1=f;}
        if (iter>1)
        {
            y2=f;
            x3=x2-y2/(y2-y1)*(x2-x1);
            change=fabs(y2/(y2-y1)*(x2-x1));
            y1=y2; x1=x2; x2=x3;
        }
        iter=iter+1;
        if (iter>100)
        {
			throw SolutionError(format("iter %d: T_hp not converging with inputs(%s,%g,%g,%g) value: %0.12g\n",iter,(char*)Ref.c_str(),h,p,T_guess,f));
        }
    }
    return T;
}
示例#3
0
/**
In the secant function, a 1-D Newton-Raphson solver is implemented.  An initial guess for the solution is provided.

@param f A pointer to an instance of the FuncWrapper1D class that implements the call() function
@param x0 The inital guess for the solutionh
@param dx The initial amount that is added to x in order to build the numerical derivative
@param tol The absolute value of the tolerance accepted for the objective function
@param maxiter Maximum number of iterations
@returns If no errors are found, the solution, otherwise the value _HUGE, the value for infinity
*/
double Secant(FuncWrapper1D* f, double x0, double dx, double tol, int maxiter)
{
    #if defined(COOLPROP_DEEP_DEBUG)
    static std::vector<double> xlog, flog;
    xlog.clear(); flog.clear();
    #endif

    double x1=0,x2=0,x3=0,y1=0,y2=0,x,fval=999;
    int iter=1;
    f->errstring.clear();

    if (std::abs(dx)==0){ f->errstring="dx cannot be zero"; return _HUGE;}
    while (iter<=2 || std::abs(fval)>tol)
    {
        if (iter==1){x1=x0; x=x1;}
        if (iter==2){x2=x0+dx; x=x2;}
        if (iter>2) {x=x2;}
        
            if (f->input_not_in_range(x)){
                throw ValueError(format("Input [%g] is out of range",x));
            }

            fval = f->call(x);

            #if defined(COOLPROP_DEEP_DEBUG)
                xlog.push_back(x);
                flog.push_back(fval);
            #endif

            if (!ValidNumber(fval)){
                throw ValueError("Residual function in secant returned invalid number");
            };
        if (iter==1){y1=fval;}
        if (iter>1)
        {
            double deltax = x2-x1;
            if (std::abs(deltax)<1e-14){
                return x;
            }
            y2=fval;
            double deltay = y2-y1;
            if (iter > 2 && std::abs(deltay)<1e-14){
                return x;
            }
            x3=x2-y2/(y2-y1)*(x2-x1);
            y1=y2; x1=x2; x2=x3;

        }
        if (iter>maxiter)
        {
            f->errstring=std::string("reached maximum number of iterations");
            throw SolutionError(format("Secant reached maximum number of iterations"));
        }
        iter=iter+1;
    }
    return x3;
}
示例#4
0
/**
In the Halley's method solver, two derivatives of the input variable are needed, it yields the following method:

\f[
x_{n+1} = x_n - \frac {2 f(x_n) f'(x_n)} {2 {[f'(x_n)]}^2 - f(x_n) f''(x_n)}
\f]

http://en.wikipedia.org/wiki/Halley%27s_method

@param f A pointer to an instance of the FuncWrapper1DWithTwoDerivs class that implements the call() and two derivatives
@param x0 The inital guess for the solution
@param ftol The absolute value of the tolerance accepted for the objective function
@param maxiter Maximum number of iterations
@returns If no errors are found, the solution, otherwise the value _HUGE, the value for infinity
*/
double Halley(FuncWrapper1DWithTwoDerivs* f, double x0, double ftol, int maxiter)
{
    double x, dx, fval=999, dfdx, d2fdx2;
    int iter=1;
    f->errstring.clear();
    x = x0;
    while (iter < 2 || std::abs(fval) > ftol)
    {
        fval = f->call(x);
        dfdx = f->deriv(x);
        d2fdx2 = f->second_deriv(x);
        
        if (f->input_not_in_range(x)){
            throw ValueError(format("Input [%g] is out of range",x));
        }
        if (!ValidNumber(fval)){
            throw ValueError("Residual function in Halley returned invalid number");
        };
        if (!ValidNumber(dfdx)){
            throw ValueError("Derivative function in Halley returned invalid number");
        };
        
        dx = -(2*fval*dfdx)/(2*POW2(dfdx)-fval*d2fdx2);

        

        x += dx;

        if (std::abs(dx/x) < 10*DBL_EPSILON){
            return x;
        }

        if (iter>maxiter){
            f->errstring= "reached maximum number of iterations";
            throw SolutionError(format("Halley reached maximum number of iterations"));
        }
        iter=iter+1;
    }
    return x;
}
示例#5
0
/**
In the secant function, a 1-D Newton-Raphson solver is implemented.  An initial guess for the solution is provided.

@param f A pointer to an instance of the FuncWrapper1D class that implements the call() function
@param x0 The inital guess for the solution
@param xmax The upper bound for the solution
@param xmin The lower bound for the solution
@param dx The initial amount that is added to x in order to build the numerical derivative
@param tol The absolute value of the tolerance accepted for the objective function
@param maxiter Maximum number of iterations
@returns If no errors are found, the solution, otherwise the value _HUGE, the value for infinity
*/
double BoundedSecant(FuncWrapper1D* f, double x0, double xmin, double xmax, double dx, double tol, int maxiter)
{
    double x1=0,x2=0,x3=0,y1=0,y2=0,x,fval=999;
    int iter=1;
    f->errstring.clear();
    if (std::abs(dx)==0){ f->errstring = "dx cannot be zero"; return _HUGE;}
    while (iter<=3 || std::abs(fval)>tol)
    {
        if (iter==1){x1=x0; x=x1;}
        else if (iter==2){x2=x0+dx; x=x2;}
        else {x=x2;}
            fval=f->call(x);
        if (iter==1){y1=fval;}
        else
        {
            y2=fval;
            x3=x2-y2/(y2-y1)*(x2-x1);
            // Check bounds, go half the way to the limit if limit is exceeded
            if (x3 < xmin)
            {
                x3 = (xmin + x2)/2;
            }
            if (x3 > xmax)
            {
                x3 = (xmax + x2)/2;
            }
            y1=y2; x1=x2; x2=x3;

        }
        if (iter>maxiter){
            f->errstring = "reached maximum number of iterations";
            throw SolutionError(format("BoundedSecant reached maximum number of iterations"));
        }
        iter=iter+1;
    }
    f->errcode = 0;
    return x3;
}
示例#6
0
/**

This function implements a 1-D bounded solver using the algorithm from Brent, R. P., Algorithms for Minimization Without Derivatives.
Englewood Cliffs, NJ: Prentice-Hall, 1973. Ch. 3-4.

a and b must bound the solution of interest and f(a) and f(b) must have opposite signs.  If the function is continuous, there must be
at least one solution in the interval [a,b].

@param f A pointer to an instance of the FuncWrapper1D class that must implement the class() function
@param a The minimum bound for the solution of f=0
@param b The maximum bound for the solution of f=0
@param macheps The machine precision
@param t Tolerance (absolute)
@param maxiter Maximum numer of steps allowed.  Will throw a SolutionError if the solution cannot be found
*/
double Brent(FuncWrapper1D* f, double a, double b, double macheps, double t, int maxiter)
{
    int iter;
    f->errstring.clear();
    double fa,fb,c,fc,m,tol,d,e,p,q,s,r;
    fa = f->call(a);
    fb = f->call(b);

    // If one of the boundaries is to within tolerance, just stop
    if (std::abs(fb) < t) { return b;}
    if (!ValidNumber(fb)){
        throw ValueError(format("Brent's method f(b) is NAN for b = %g, other input was a = %g",b,a).c_str());
    }
    if (std::abs(fa) < t) { return a;}
    if (!ValidNumber(fa)){
        throw ValueError(format("Brent's method f(a) is NAN for a = %g, other input was b = %g",a,b).c_str());
    }
    if (fa*fb>0){
        throw ValueError(format("Inputs in Brent [%f,%f] do not bracket the root.  Function values are [%f,%f]",a,b,fa,fb));
    }

    c=a;
    fc=fa;
    iter=1;
    if (std::abs(fc)<std::abs(fb)){
        // Goto ext: from Brent ALGOL code
        a=b;
        b=c;
        c=a;
        fa=fb;
        fb=fc;
        fc=fa;
    }
    d=b-a;
    e=b-a;
    m=0.5*(c-b);
    tol=2*macheps*std::abs(b)+t;
    while (std::abs(m)>tol && fb!=0){
        // See if a bisection is forced
        if (std::abs(e)<tol || std::abs(fa) <= std::abs(fb)){
            m=0.5*(c-b);
            d=e=m;
        }
        else{
            s=fb/fa;
            if (a==c){
                //Linear interpolation
                p=2*m*s;
                q=1-s;
            }
            else{
                //Inverse quadratic interpolation
                q=fa/fc;
                r=fb/fc;
                m=0.5*(c-b);
                p=s*(2*m*q*(q-r)-(b-a)*(r-1));
                q=(q-1)*(r-1)*(s-1);
            }
            if (p>0){
                q=-q;
            }
            else{
                p=-p;
            }
            s=e;
            e=d;
            m=0.5*(c-b);
            if (2*p<3*m*q-std::abs(tol*q) || p<std::abs(0.5*s*q)){
                d=p/q;
            }
            else{
                m=0.5*(c-b);
                d=e=m;
            }
        }
        a=b;
        fa=fb;
        if (std::abs(d)>tol){
            b+=d;
        }
        else if (m>0){
            b+=tol;
        }
        else{
            b+=-tol;
        }
        fb=f->call(b);
        if (!ValidNumber(fb)){
            throw ValueError(format("Brent's method f(t) is NAN for t = %g",b).c_str());
        }
        if (std::abs(fb) < macheps){
            return b;
        }
        if (fb*fc>0){
            // Goto int: from Brent ALGOL code
            c=a;
            fc=fa;
            d=e=b-a;
        }
        if (std::abs(fc)<std::abs(fb)){
            // Goto ext: from Brent ALGOL code
            a=b;
            b=c;
            c=a;
            fa=fb;
            fb=fc;
            fc=fa;
        }
        m=0.5*(c-b);
        tol=2*macheps*std::abs(b)+t;
        iter+=1;
        if (!ValidNumber(a)){
            throw ValueError(format("Brent's method a is NAN").c_str());}
        if (!ValidNumber(b)){
            throw ValueError(format("Brent's method b is NAN").c_str());}
        if (!ValidNumber(c)){
            throw ValueError(format("Brent's method c is NAN").c_str());}
        if (iter>maxiter){
            throw SolutionError(format("Brent's method reached maximum number of steps of %d ", maxiter));}
        if (std::abs(fb)< 2*macheps*std::abs(b)){
            return b;
        }
    }
    return b;
}
示例#7
0
int main(int argc, char * argv[])
{
    pthread_t *tid;//number of thread
    args *arg;
    int total_processes;
    double *a, *b, *x;
    int res1, res2;
    long int t;
    int n;
    int N;
    int i;
    char * filename = 0;
    const char * name = "c.txt";
    if( argc != 3 && argc != 4 )
    {
        printf("Usage : %s <n> <total_processes> <filename>\n", argv[0]);
        return 0;
    }
    n = atoi(argv[1]);//from number to string
    total_processes = atoi (argv[2]);
    if(!n || !total_processes)
    {
        printf("Usage : %s <n> <total_processes> <filename>\n", argv[0]);
        return 0;
    }
    a = new double[n*n];
    b = new double[n];
    x = new double[n];
    tid = new pthread_t[total_processes];
    arg = new args[total_processes];
    if(argc > 3)
        filename = argv[3];

    if(filename)
    {
        res1 = read_matrix(a, n, "a.txt");
        res2 = read_vector(b, n, "b.txt");
        if(res1 || res2)
        {
            printf("cannot read from file\n");
            delete [] tid;
            delete [] arg;
            delete [] a;
            delete [] b;
            delete [] x;
            return 1;
        }
    }
    else
    {
        init_matrix(a, n);
        init_vector(b, a, n);
    }
    printf("matrix A:\n");
    print_matrix(a, n);
    printf("vector b:\n");
    print_vector(b, n);

    for (i = 0; i < total_processes; i++)
    {
        arg[i].a = a;
        arg[i].b = b;
        arg[i].n = n;
        arg[i].total_processes = total_processes;
        arg[i].num_process = i;
        arg[i].error = 0;
    }

    t = get_full_time ();
    for (i = 0; i < total_processes; i++)
    {
        if (pthread_create (tid + i, 0, &thread_method_of_reflections, arg + i))
        {
            printf ("Cannot create thread %d\n", i);
            return 2;
        }
    }
    for (i = 0; i < total_processes; i++)
        pthread_join (tid[i], 0);
    back_hod(a, b, x, n);
    t = get_full_time () - t;
    N = (n < MAX_N) ? n : MAX_N;
    printf("result : ");
    for(i = 0; i < N; i++)
        printf("%lg ", x[i]);
	printvectorfile(x,n,name);
     if(filename)
    {
        read_matrix(a, n, "a.txt");
        read_vector(b, n, "b.txt");
        printf("\nResidual = %le\nElapsed time = %Lg\n",SolutionError(n,a,b,x),(long double)t/(CLOCKS_PER_SEC));
    }
    else
    {
        init_matrix(a, n);
        init_vector(b, a, n);
        printf("\nResidual = %le\nError = %le\nElapsed time = %Lg\n",SolutionError(n,a,b,x), SolutionAccuracy(n,x),(long double)t/(CLOCKS_PER_SEC));
    }
    delete [] tid;
    delete [] arg;
    delete [] a;
    delete [] b;
    delete [] x;
    return 0;
}