Esempio n. 1
0
    public static double[] vandermonde_coef_1d(int nd, double[] xd, double[] yd)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    VANDERMONDE_COEF_1D computes coefficients of a 1D Vandermonde interpolant.
    //
    //  Discussion:
    //
    //    We assume the interpolant has the form
    //
    //      p(x) = c1 + c2 * x + c3 * x^2 + ... + cn * x^(n-1).
    //
    //    We have n data values (x(i),y(i)) which must be interpolated:
    //
    //      p(x(i)) = c1 + c2 * x(i) + c3 * x(i)^2 + ... + cn * x(i)^(n-1) = y(i)
    //
    //    This can be cast as an NxN linear system for the polynomial
    //    coefficients:
    //
    //      [ 1 x1 x1^2 ... x1^(n-1) ] [  c1 ] = [  y1 ]
    //      [ 1 x2 x2^2 ... x2^(n-1) ] [  c2 ] = [  y2 ]
    //      [ ...................... ] [ ... ] = [ ... ]
    //      [ 1 xn xn^2 ... xn^(n-1) ] [  cn ] = [  yn ]
    //
    //    and if the x values are distinct, the system is theoretically
    //    invertible, so we can retrieve the coefficient vector c and
    //    evaluate the interpolant.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    07 October 2012
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, int ND, the number of data points.
    //
    //    Input, double XD[ND], YD[ND], the data values.
    //
    //    Output, double VANDERMONDE_COEF_1D[ND], the coefficients of the
    //    interpolating polynomial.
    //
    {
        double[] ad = vandermonde_matrix_1d(nd, xd);

        double[] cd = QRSolve.qr_solve(nd, nd, ad, yd);

        return(cd);
    }
Esempio n. 2
0
    public static double[] pwl_approx_1d(int nd, double[] xd, double[] yd, int nc, double[] xc)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    PWL_APPROX_1D determines the control values for a PWL approximant.
    //
    //  Discussion:
    //
    //    The piecewise linear approximant is defined by NC control pairs
    //    (XC(I),YC(I)) and approximates ND data pairs (XD(I),YD(I)).
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    10 October 2012
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, int ND, the number of data points.
    //    ND must be at least 1.
    //
    //    Input, double XD[ND], the data points.
    //
    //    Input, double YD[ND], the data values.
    //
    //    Input, int NC, the number of control points.
    //    NC must be at least 1.
    //
    //    Input, double XC[NC], the control points.  Set these with a
    //    command like
    //      xc = r8vec_linspace_new ( nc, xmin, xmax );
    //
    //    Output, double PWL_APPROX_1D[NC], the control values.
    //
    {
        //
        //  Define the NDxNC linear system that determines the control values.
        //
        double[] a = pwl_approx_1d_matrix(nd, xd, yd, nc, xc);
        //
        //  Solve the system.
        //
        double[] yc = QRSolve.qr_solve(nd, nc, a, yd);

        return(yc);
    }
Esempio n. 3
0
    private static void test01(int prob)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    TEST01 tests VANDERMONDE_INTERP_1D.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    07 October 2012
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        const bool debug = false;
        int        i;

        Console.WriteLine("");
        Console.WriteLine("TEST01:");
        Console.WriteLine("  Interpolate data from TEST_INTERP problem #" + prob + "");

        int nd = TestInterp.p00_data_num(prob);

        Console.WriteLine("  Number of data points = " + nd + "");

        double[] xy = TestInterp.p00_data(prob, 2, nd);

        switch (debug)
        {
        case true:
            typeMethods.r8mat_transpose_print(2, nd, xy, "  Data array:");
            break;
        }

        double[] xd = new double[nd];
        double[] yd = new double[nd];

        for (i = 0; i < nd; i++)
        {
            xd[i] = xy[0 + i * 2];
            yd[i] = xy[1 + i * 2];
        }

        //
        //  Compute Vandermonde matrix and get condition number.
        //
        double[] ad = Vandermonde.vandermonde_matrix_1d(nd, xd);

        double condition = Matrix.condition_hager(nd, ad);

        Console.WriteLine("");
        Console.WriteLine("  Condition of Vandermonde matrix is " + condition + "");
        //
        //  Solve linear system.
        //
        double[] cd = QRSolve.qr_solve(nd, nd, ad, yd);
        //
        //  #1:  Does interpolant match function at interpolation points?
        //
        int ni = nd;

        double[] xi = typeMethods.r8vec_copy_new(ni, xd);
        double[] yi = Vandermonde.vandermonde_value_1d(nd, cd, ni, xi);

        double int_error = typeMethods.r8vec_norm_affine(ni, yi, yd) / ni;

        Console.WriteLine("");
        Console.WriteLine("  L2 interpolation error averaged per interpolant node = " + int_error + "");

        //
        //  #2: Compare estimated curve length to piecewise linear (minimal) curve length.
        //  Assume data is sorted, and normalize X and Y dimensions by (XMAX-XMIN) and
        //  (YMAX-YMIN).
        //
        double xmin = typeMethods.r8vec_min(nd, xd);
        double xmax = typeMethods.r8vec_max(nd, xd);
        double ymin = typeMethods.r8vec_min(nd, yd);
        double ymax = typeMethods.r8vec_max(nd, yd);

        ni = 501;
        xi = typeMethods.r8vec_linspace_new(ni, xmin, xmax);
        yi = Vandermonde.vandermonde_value_1d(nd, cd, ni, xi);

        double ld = 0.0;

        for (i = 0; i < nd - 1; i++)
        {
            ld += Math.Sqrt(Math.Pow((xd[i + 1] - xd[i]) / (xmax - xmin), 2)
                            + Math.Pow((yd[i + 1] - yd[i]) / (ymax - ymin), 2));
        }

        double li = 0.0;

        for (i = 0; i < ni - 1; i++)
        {
            li += Math.Sqrt(Math.Pow((xi[i + 1] - xi[i]) / (xmax - xmin), 2)
                            + Math.Pow((yi[i + 1] - yi[i]) / (ymax - ymin), 2));
        }

        Console.WriteLine("");
        Console.WriteLine("  Normalized length of piecewise linear interpolant = " + ld + "");
        Console.WriteLine("  Normalized length of polynomial interpolant       = " + li + "");
    }
    public static void emweak(ref typeMethods.r8vecNormalData data, ref int seed, int method, int m, int p_max, ref double[] dtvals,
                              ref double[] xerr)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    EMWEAK tests the weak convergence of the Euler-Maruyama method.
    //
    //  Discussion:
    //
    //    The SDE is
    //
    //      dX = lambda * X dt + mu * X dW,
    //      X(0) = Xzero,
    //
    //    where
    //
    //      lambda = 2,
    //      mu = 1,
    //      Xzero = 1.
    //
    //    The discretized Brownian path over [0,1] has dt = 2^(-9).
    //
    //    The Euler-Maruyama method will use 5 different timesteps:
    //
    //      2^(p-10),  p = 1,2,3,4,5.
    //
    //    We examine weak convergence at T=1:
    //
    //      | E (X_L) - E (X(T)) |.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    25 September 2012
    //
    //  Author:
    //
    //    Original MATLAB version by Desmond Higham.
    //    C++ version by John Burkardt.
    //
    //  Reference:
    //
    //    Desmond Higham,
    //    An Algorithmic Introduction to Numerical Simulation of
    //    Stochastic Differential Equations,
    //    SIAM Review,
    //    Volume 43, Number 3, September 2001, pages 525-546
    //
    //  Parameters:
    //
    //    Input, int &SEED, a seed for the random number generator.
    //
    //    Input, int METHOD.
    //    0, use the standard Euler-Maruyama method;
    //    1, use the weak Euler-Maruyama method.
    //
    //    Input, int M, the number of simulations to perform.
    //    A typical value is M = 1000.
    //
    //    Input, int P_MAX, the number of time step sizes to use.
    //    A typical value is 5.
    //
    //    Output, double DTVALS[P_MAX], the time steps used.
    //
    //    Output, double XERR[P_MAX], the averaged absolute error in the
    //    solution estimate at the final time.
    //
    {
        int i;
        int p;
        //
        //  Problem parameters;
        //
        const double lambda = 2.0;
        const double mu     = 0.1;
        const double xzero  = 1.0;

        //
        //  Stepping parameters.
        //
        for (p = 0; p < p_max; p++)
        {
            dtvals[p] = Math.Pow(2.0, p - 9);
        }

        //
        //  Take various Euler timesteps.
        //  For stepsize dt, we will need to take L Euler steps to reach time TMAX.
        //
        double[] xtemp = new double[m];
        double[] xem   = new double[p_max];

        for (p = 0; p < p_max; p++)
        {
            int    l  = (int)Math.Pow(2, 9 - p);
            double dt = dtvals[p];

            for (i = 0; i < m; i++)
            {
                xtemp[i] = xzero;
            }

            int j;
            for (j = 0; j < l; j++)
            {
                double[] winc = typeMethods.r8vec_normal_01_new(m, ref data, ref seed);
                switch (method)
                {
                case 0:
                {
                    for (i = 0; i < m; i++)
                    {
                        winc[i] = Math.Sqrt(dt) * winc[i];
                    }

                    break;
                }

                default:
                {
                    for (i = 0; i < m; i++)
                    {
                        winc[i] = Math.Sqrt(dt) * typeMethods.r8_sign(winc[i]);
                    }

                    break;
                }
                }

                for (i = 0; i < m; i++)
                {
                    xtemp[i] = xtemp[i] + dt * lambda * xtemp[i]
                               + mu * xtemp[i] * winc[i];
                }
            }

            //
            //  Average the M results for this stepsize.
            //
            xem[p] = typeMethods.r8vec_mean(m, xtemp);
        }

        //
        //  Compute the error in the estimates for each stepsize.
        //
        for (p = 0; p < p_max; p++)
        {
            xerr[p] = Math.Abs(xem[p] - Math.Exp(lambda));
        }

        //
        //  Least squares fit of error = c * dt^q.
        //
        double[] a   = new double[p_max * 2];
        double[] rhs = new double[p_max];

        for (i = 0; i < p_max; i++)
        {
            a[i + 0 * p_max] = 1.0;
            a[i + 1 * p_max] = Math.Log(dtvals[i]);
            rhs[i]           = Math.Log(xerr[i]);
        }

        double[] sol = QRSolve.qr_solve(p_max, 2, a, rhs);

        Console.WriteLine("");
        Console.WriteLine("EMWEAK:");
        switch (method)
        {
        case 0:
            Console.WriteLine("  Using standard Euler-Maruyama method.");
            break;

        default:
            Console.WriteLine("  Using weak Euler-Maruyama method.");
            break;
        }

        Console.WriteLine("  Least squares solution to Error = c * dt ^ q");
        Console.WriteLine("  (Expecting Q to be about 1.)");
        Console.WriteLine("  Computed Q = " + sol[1] + "");

        double resid = 0.0;

        for (i = 0; i < p_max; i++)
        {
            double e = a[i + 0 * p_max] * sol[0] + a[i + 1 * p_max] * sol[1] - rhs[i];
            resid += e * e;
        }

        resid = Math.Sqrt(resid);
        Console.WriteLine("  Residual is " + resid + "");
    }
Esempio n. 5
0
    // Last two ints before fcnData are for the array index baselines.
    public static int hybrd(Func <int, double[], double[], int, int, int, fcnData> fcn,
                            int n, double[] x,
                            double[] fvec, double xtol, int maxfev, int ml, int mu, double epsfcn,
                            double[] diag, int mode, double factor, int nprint, int nfev,
                            double[] fjac, int ldfjac, double[] r, int lr, double[] qtf, double[] wa1,
                            double[] wa2, double[] wa3, double[] wa4, int fjacIndex, int rIndex, int qtfIndex, int wa1Index, int wa2Index, int wa3Index, int wa4Index)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    hybrd() finds a zero of a system of N nonlinear equations.
    //
    //  Discussion:
    //
    //    The purpose of HYBRD is to find a zero of a system of
    //    N nonlinear functions in N variables by a modification
    //    of the Powell hybrid method.
    //
    //    The user must provide FCN, which calculates the functions.
    //
    //    The jacobian is calculated by a forward-difference approximation.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    08 April 2010
    //
    //  Author:
    //
    //    Original FORTRAN77 version by Jorge More, Burt Garbow, Ken Hillstrom.
    //    C++ version by John Burkardt.
    //
    //  Reference:
    //
    //    Jorge More, Burton Garbow, Kenneth Hillstrom,
    //    User Guide for MINPACK-1,
    //    Technical Report ANL-80-74,
    //    Argonne National Laboratory, 1980.
    //
    //  Parameters:
    //
    //       fcn is the name of the user-supplied subroutine which
    //         calculates the functions. fcn must be declared
    //         in an external statement in the user calling
    //         program, and should be written as follows.
    //
    //         subroutine fcn(n,x,fvec,iflag)
    //         integer n,iflag
    //         double precision x(n),fvec(n)
    //         ----------
    //         calculate the functions at x and
    //         return this vector in fvec.
    //         ---------
    //         return
    //         end
    //
    //         the value of iflag should not be changed by fcn unless
    //         the user wants to terminate execution of hybrd.
    //         in this case set iflag to a negative integer.
    //
    //    Input, int N, the number of functions and variables.
    //
    //    Input/output, double X[N].  On input an initial estimate of the solution.
    //    On output, the final estimate of the solution.
    //
    //    Output, double FVEC[N], the functions evaluated at the output value of X.
    //
    //    Input, double XTOL, a nonnegative value.  Termination occurs when the
    //    relative error between two consecutive iterates is at most XTOL.
    //
    //    Input, int MAXFEV.  Termination occurs when the number of calls to FCN
    //    is at least MAXFEV by the end of an iteration.
    //
    //    Input, int ML, specifies the number of subdiagonals within the band of
    //    the jacobian matrix.  If the jacobian is not banded, set
    //    ml to at least n - 1.
    //
    //       mu is a nonnegative integer input variable which specifies
    //         the number of superdiagonals within the band of the
    //         jacobian matrix. if the jacobian is not banded, set
    //         mu to at least n - 1.
    //
    //       epsfcn is an input variable used in determining a suitable
    //         step length for the forward-difference approximation. this
    //         approximation assumes that the relative errors in the
    //         functions are of the order of epsfcn. if epsfcn is less
    //         than the machine precision, it is assumed that the relative
    //         errors in the functions are of the order of the machine
    //         precision.
    //
    //       diag is an array of length n. if mode = 1 (see
    //         below), diag is internally set. if mode = 2, diag
    //         must contain positive entries that serve as
    //         multiplicative scale factors for the variables.
    //
    //       mode is an integer input variable. if mode = 1, the
    //         variables will be scaled internally. if mode = 2,
    //         the scaling is specified by the input diag. other
    //         values of mode are equivalent to mode = 1.
    //
    //       factor is a positive input variable used in determining the
    //         initial step bound. this bound is set to the product of
    //         factor and the euclidean norm of diag*x if nonzero, or else
    //         to factor itself. in most cases factor should lie in the
    //         interval (.1,100.). 100. is a generally recommended value.
    //
    //       nprint is an integer input variable that enables controlled
    //         printing of iterates if it is positive. in this case,
    //         fcn is called with iflag = 0 at the beginning of the first
    //         iteration and every nprint iterations thereafter and
    //         immediately prior to return, with x and fvec available
    //         for printing. if nprint is not positive, no special calls
    //         of fcn with iflag = 0 are made.
    //
    //       info is an integer output variable. if the user has
    //         terminated execution, info is set to the (negative)
    //         value of iflag. see description of fcn. otherwise,
    //         info is set as follows.
    //
    //         info = 0   improper input parameters.
    //
    //         info = 1   relative error between two consecutive iterates
    //                    is at most xtol.
    //
    //         info = 2   number of calls to fcn has reached or exceeded
    //                    maxfev.
    //
    //         info = 3   xtol is too small. no further improvement in
    //                    the approximate solution x is possible.
    //
    //         info = 4   iteration is not making good progress, as
    //                    measured by the improvement from the last
    //                    five jacobian evaluations.
    //
    //         info = 5   iteration is not making good progress, as
    //                    measured by the improvement from the last
    //                    ten iterations.
    //
    //       nfev is an integer output variable set to the number of
    //         calls to fcn.
    //
    //       fjac is an output n by n array which contains the
    //         orthogonal matrix q produced by the qr factorization
    //         of the final approximate jacobian.
    //
    //       ldfjac is a positive integer input variable not less than n
    //         which specifies the leading dimension of the array fjac.
    //
    //       r is an output array of length lr which contains the
    //         upper triangular matrix produced by the qr factorization
    //         of the final approximate jacobian, stored rowwise.
    //
    //       lr is a positive integer input variable not less than
    //         (n*(n+1))/2.
    //
    //       qtf is an output array of length n which contains
    //         the vector (q transpose)*fvec.
    //
    //       wa1, wa2, wa3, and wa4 are work arrays of length n.
    //
    {
        double delta = 0;

        int[]        iwa = new int[1];
        int          j;
        const double p001  = 0.001;
        const double p0001 = 0.0001;
        const double p1    = 0.1;
        const double p5    = 0.5;
        double       xnorm = 0;
        //
        //  Certain loops in this function were kept closer to their original FORTRAN77
        //  format, to avoid confusing issues with the array index L.  These loops are
        //  marked "DO NOT ADJUST", although they certainly could be adjusted (carefully)
        //  once the initial translated code is tested.
        //

        //
        //  EPSMCH is the machine precision.
        //
        double epsmch = typeMethods.r8_epsilon();

        int info  = 0;
        int iflag = 0;

        nfev = 0;
        switch (n)
        {
        //
        //  Check the input parameters.
        //
        case <= 0:
            info = 0;
            return(info);
        }

        switch (xtol)
        {
        case < 0.0:
            info = 0;
            return(info);
        }

        switch (maxfev)
        {
        case <= 0:
            info = 0;
            return(info);
        }

        switch (ml)
        {
        case < 0:
            info = 0;
            return(info);
        }

        switch (mu)
        {
        case < 0:
            info = 0;
            return(info);
        }

        switch (factor)
        {
        case <= 0.0:
            info = 0;
            return(info);
        }

        if (ldfjac < n)
        {
            info = 0;
            return(info);
        }

        if (lr < n * (n + 1) / 2)
        {
            info = 0;
            return(info);
        }

        switch (mode)
        {
        case 2:
        {
            for (j = 0; j < n; j++)
            {
                switch (diag[j])
                {
                case <= 0.0:
                    info = 0;
                    return(info);
                }
            }

            break;
        }
        }

        //
        //  Evaluate the function at the starting point and calculate its norm.
        //
        iflag = 1;
        fcnData res = fcn(n, x, fvec, iflag, 0, 0);

        fvec  = res.fvec;
        iflag = res.iflag;
        nfev  = 1;
        switch (iflag)
        {
        case < 0:
            info = iflag;
            return(info);
        }

        double fnorm = Helpers.enorm(n, fvec);
        //
        //  Determine the number of calls to FCN needed to compute the jacobian matrix.
        //
        int msum = Math.Min(ml + mu + 1, n);
        //
        //  Initialize iteration counter and monitors.
        //
        int iter   = 1;
        int ncsuc  = 0;
        int ncfail = 0;
        int nslow1 = 0;
        int nslow2 = 0;

        //
        //  Beginning of the outer loop.
        //
        for (;;)
        {
            bool jeval = true;
            //
            //  Calculate the jacobian matrix.
            //
            iflag = 2;
            fdjac1(fcn, n, x, fvec, fjac, ldfjac, ref iflag, ml, mu, epsfcn, wa1, wa2, fjacIndex: fjacIndex, wa1Index: wa1Index, wa2Index: wa2Index);

            nfev += msum;
            switch (iflag)
            {
            case < 0:
                info = iflag;
                return(info);
            }

            //
            //  Compute the QR factorization of the jacobian.
            //
            int tmpi = 1;
            QRSolve.qrfac(n, n, ref fjac, ldfjac, false, ref iwa, ref tmpi, ref wa1, ref wa2, rdiagIndex: wa1Index, acnormIndex: wa2Index);
            switch (iter)
            {
            //
            //  On the first iteration and if MODE is 1, scale according
            //  to the norms of the columns of the initial jacobian.
            //
            case 1:
            {
                switch (mode)
                {
                case 1:
                {
                    for (j = 0; j < n; j++)
                    {
                        if (wa2[wa2Index + j] != 0.0)
                        {
                            diag[j] = wa2[wa2Index + j];
                        }
                        else
                        {
                            diag[j] = 1.0;
                        }
                    }

                    break;
                }
                }

                //
                //  On the first iteration, calculate the norm of the scaled X
                //  and initialize the step bound DELTA.
                //
                for (j = 0; j < n; j++)
                {
                    wa3[wa3Index + j] = diag[j] * x[j];
                }

                xnorm = Helpers.enorm(n, wa3);

                delta = xnorm switch
                {
                    0.0 => factor,
                    _ => factor * xnorm
                };

                break;
            }
            }

            //
            //  Form Q' * FVEC and store in QTF.
            //
            int i;
            for (i = 0; i < n; i++)
            {
                qtf[qtfIndex + i] = fvec[i];
            }

            double temp;
            double sum;
            for (j = 0; j < n; j++)
            {
                if (fjac[fjacIndex + j + j * ldfjac] == 0.0)
                {
                    continue;
                }

                sum = 0.0;
                for (i = j; i < n; i++)
                {
                    sum += fjac[fjacIndex + i + j * ldfjac] * qtf[qtfIndex + i];
                }

                temp = -sum / fjac[fjacIndex + j + j * ldfjac];
                for (i = j; i < n; i++)
                {
                    qtf[qtfIndex + i] += fjac[fjacIndex + i + j * ldfjac] * temp;
                }
            }

            //
            //  Copy the triangular factor of the QR factorization into R.
            //
            //  DO NOT ADJUST THIS LOOP, BECAUSE OF L.
            //
            int l;
            for (j = 1; j <= n; j++)
            {
                l = j;
                for (i = 1; i <= j - 1; i++)
                {
                    r[rIndex + (l - 1)] = fjac[fjacIndex + (i - 1) + (j - 1) * ldfjac];
                    l = l + n - i;
                }

                r[rIndex + (l - 1)] = wa1[wa1Index + (j - 1)];
                switch (wa1[wa1Index + (j - 1)])
                {
                case 0.0:
                    Console.WriteLine("  Matrix is singular.");
                    break;
                }
            }

            //
            //  Accumulate the orthogonal factor in FJAC.
            //
            QRSolve.qform(n, n, ref fjac, ldfjac, qIndex: fjacIndex);
            switch (mode)
            {
            //
            //  Rescale if necessary.
            //
            case 1:
            {
                for (j = 0; j < n; j++)
                {
                    diag[j] = Math.Max(diag[j], wa2[wa2Index + j]);
                }

                break;
            }
            }

            //
            //  Beginning of the inner loop.
            //
            for (;;)
            {
                switch (nprint)
                {
                //
                //  If requested, call FCN to enable printing of iterates.
                //
                case > 0:
                {
                    switch ((iter - 1) % nprint)
                    {
                    case 0:
                    {
                        iflag = 0;
                        fcn(n, x, fvec, iflag, 0, 0);
                        switch (iflag)
                        {
                        case < 0:
                            info = iflag;
                            return(info);
                        }

                        break;
                    }
                    }

                    break;
                }
                }

                //
                //  Determine the direction P.
                //
                dogleg(n, r, lr, diag, qtf, delta, ref wa1, wa2, wa3, rIndex: rIndex, qtbIndex: qtfIndex, xIndex: wa1Index, wa1Index: wa2Index, wa2Index: wa3Index);
                //
                //  Store the direction P and X + P.  Calculate the norm of P.
                //
                for (j = 0; j < n; j++)
                {
                    wa1[wa1Index + j] = -wa1[j];
                    wa2[wa2Index + j] = x[j] + wa1[j];
                    wa3[wa3Index + j] = diag[j] * wa1[wa1Index + j];
                }

                double pnorm = Helpers.enorm(n, wa3);
                delta = iter switch
                {
                    //
                    //  On the first iteration, adjust the initial step bound.
                    //
                    1 => Math.Min(delta, pnorm),
                    _ => delta
                };

                //
                //  Evaluate the function at X + P and calculate its norm.
                //
                iflag = 1;
                fcn(n, wa2, wa4, iflag, wa2Index, wa4Index);
                nfev += 1;
                switch (iflag)
                {
                case < 0:
                    info = iflag;
                    return(info);
                }

                double fnorm1 = Helpers.enorm(n, wa4);
                //
                //  Compute the scaled actual reduction.
                //
                double actred;
                if (fnorm1 < fnorm)
                {
                    actred = 1.0 - fnorm1 / fnorm * (fnorm1 / fnorm);
                }
                else
                {
                    actred = -1.0;
                }

                //
                //  Compute the scaled predicted reduction.
                //
                //  DO NOT ADJUST THIS LOOP, BECAUSE OF L.
                //
                l = 1;
                for (i = 1; i <= n; i++)
                {
                    sum = 0.0;
                    for (j = i; j <= n; j++)
                    {
                        sum += r[rIndex + (l - 1)] * wa1[wa1Index + (j - 1)];
                        l   += 1;
                    }

                    wa3[i - 1] = qtf[i - 1] + sum;
                }

                temp = Helpers.enorm(n, wa3);

                double prered;
                if (temp < fnorm)
                {
                    prered = 1.0 - temp / fnorm * (temp / fnorm);
                }
                else
                {
                    prered = 0.0;
                }

                double ratio = prered switch
                {
                    //
                    //  Compute the ratio of the actual to the predicted reduction.
                    //
                    > 0.0 => actred / prered,
                    _ => 0.0
                };

                switch (ratio)
                {
                //
                //  Update the step bound.
                //
                case < p1:
                    ncsuc   = 0;
                    ncfail += 1;
                    delta   = p5 * delta;
                    break;

                default:
                {
                    ncfail = 0;
                    ncsuc += 1;
                    if (p5 <= ratio || 1 < ncsuc)
                    {
                        delta = Math.Max(delta, pnorm / p5);
                    }

                    delta = Math.Abs(ratio - 1.0) switch
                    {
                        <= p1 => pnorm / p5,
                        _ => delta
                    };

                    break;
                }
                }
Esempio n. 6
0
    public static double[] vandermonde_approx_1d_coef(int n, int m, double[] x, double[] y)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    VANDERMONDE_APPROX_1D_COEF computes a 1D polynomial approximant.
    //
    //  Discussion:
    //
    //    We assume the approximating function has the form
    //
    //      p(x) = c0 + c1 * x + c2 * x^2 + ... + cm * x^m.
    //
    //    We have n data values (x(i),y(i)) which must be approximated:
    //
    //      p(x(i)) = c0 + c1 * x(i) + c2 * x(i)^2 + ... + cm * x(i)^m = y(i)
    //
    //    This can be cast as an Nx(M+1) linear system for the polynomial
    //    coefficients:
    //
    //      [ 1 x1 x1^2 ... x1^m ] [  c0 ] = [  y1 ]
    //      [ 1 x2 x2^2 ... x2^m ] [  c1 ] = [  y2 ]
    //      [ .................. ] [ ... ] = [ ... ]
    //      [ 1 xn xn^2 ... xn^m ] [  cm ] = [  yn ]
    //
    //    In the typical case, N is greater than M+1 (we have more data and equations
    //    than degrees of freedom) and so a least squares solution is appropriate,
    //    in which case the computed polynomial will be a least squares approximant
    //    to the data.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    10 October 2012
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, int N, the number of data points.
    //
    //    Input, int M, the degree of the polynomial.
    //
    //    Input, double X[N], Y[N], the data values.
    //
    //    Output, double VANDERMONDE_APPROX_1D_COEF[M+1], the coefficients of
    //    the approximating polynomial.  C(0) is the constant term, and C(M)
    //    multiplies X^M.
    //
    {
        double[] a = VandermondeMatrix.vandermonde_approx_1d_matrix(n, m, x);

        double[] c = QRSolve.qr_solve(n, m + 1, a, y);

        return(c);
    }
Esempio n. 7
0
    public static double[] vandermonde_approx_2d_coef(int n, int m, double[] x, double[] y,
                                                      double[] z)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    VANDERMONDE_APPROX_2D_COEF computes a 2D polynomial approximant.
    //
    //  Discussion:
    //
    //    We assume the approximating function has the form of a polynomial
    //    in X and Y of total degree M.
    //
    //      p(x,y) = c00
    //             + c10 * x                + c01 *  y
    //             + c20 * x^2   + c11 * xy + c02 * y^2
    //             + ...
    //             + cm0 * x^(m) + ...      + c0m * y^m.
    //
    //    If we let T(K) = the K-th triangular number
    //            = sum ( 1 <= I <= K ) I
    //    then the number of coefficients in the above polynomial is T(M+1).
    //
    //    We have n data locations (x(i),y(i)) and values z(i) to approximate:
    //
    //      p(x(i),y(i)) = z(i)
    //
    //    This can be cast as an NxT(M+1) linear system for the polynomial
    //    coefficients:
    //
    //      [ 1 x1 y1  x1^2 ... y1^m ] [ c00 ] = [  z1 ]
    //      [ 1 x2 y2  x2^2 ... y2^m ] [ c10 ] = [  z2 ]
    //      [ 1 x3 y3  x3^2 ... y3^m ] [ c01 ] = [  z3 ]
    //      [ ...................... ] [ ... ] = [ ... ]
    //      [ 1 xn yn  xn^2 ... yn^m ] [ c0m ] = [  zn ]
    //
    //    In the typical case, N is greater than T(M+1) (we have more data and
    //    equations than degrees of freedom) and so a least squares solution is
    //    appropriate, in which case the computed polynomial will be a least squares
    //    approximant to the data.
    //
    //    The polynomial defined by the T(M+1) coefficients C could be evaluated
    //    at the Nx2-vector x by the command
    //
    //      pval = r8poly_value_2d ( m, c, n, x )
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    12 October 2012
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, int N, the number of data points.
    //
    //    Input, int M, the maximum degree of the polynomial.
    //
    //    Input, double X[N], Y[N] the data locations.
    //
    //    Input, double Z[N], the data values.
    //
    //    Output, double VANDERMONDE_APPROX_2D_COEF[T(M+1)], the
    //    coefficients of the approximating polynomial.
    //
    {
        int tm = typeMethods.triangle_num(m + 1);

        double[] a = VandermondeMatrix.vandermonde_approx_2d_matrix(n, m, tm, x, y);

        double[] c = QRSolve.qr_solve(n, tm, a, z);

        return(c);
    }
Esempio n. 8
0
    public static double[] chebyshev_coef_1d(int nd, double[] xd, double[] yd, ref double xmin,
                                             ref double xmax)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    CHEBYSHEV_COEF_1D determines the Chebyshev interpolant coefficients.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    28 September 2012
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, int ND, the number of data points.
    //    ND must be at least 1.
    //
    //    Input, double XD[ND], the data locations.
    //
    //    Input, double YD[ND], the data values.
    //
    //    Output, double &XMIN, &XMAX, the interpolation interval.
    //
    //    Output, double CHEBYSHEV_COEF_1D[ND], the Chebyshev coefficients.
    //
    {
        double[] c;
        int      i;
        int      j;

        switch (nd)
        {
        case 1:
            xmin = xd[0];
            xmax = xd[0];
            c    = new double[nd];
            c[0] = 1.0;
            return(c);
        }

        xmin = typeMethods.r8vec_min(nd, xd);
        xmax = typeMethods.r8vec_max(nd, xd);
        //
        //  Map XD to [-1,+1].
        //
        double[] x = new double[nd];
        for (i = 0; i < nd; i++)
        {
            x[i] = (2.0 * xd[i] - xmin - xmax) / (xmax - xmin);
        }

        //
        //  Form the Chebyshev Vandermonde matrix.
        //
        double[] a = new double[nd * nd];
        for (j = 0; j < nd; j++)
        {
            for (i = 0; i < nd; i++)
            {
                a[i + j * nd] = Math.Cos(Math.Acos(x[i]) * j);
            }
        }

        //
        //  Solve for the expansion coefficients.
        //
        c = QRSolve.qr_solve(nd, nd, a, yd);

        return(c);
    }
Esempio n. 9
0
    private static void test01(int prob, int m)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    TEST01 tests VANDERMONDE_APPROX_1D_MATRIX.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    10 October 2012
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, int PROB, the problem number.
    //
    //    Input, int M, the polynomial degree.
    //
    {
        const bool debug = false;
        int        i;

        Console.WriteLine("");
        Console.WriteLine("TEST01:");
        Console.WriteLine("  Approximate data from TEST_INTERP problem #" + prob + "");

        int nd = TestInterp.p00_data_num(prob);

        Console.WriteLine("  Number of data points = " + nd + "");

        double[] xy = TestInterp.p00_data(prob, 2, nd);

        switch (debug)
        {
        case true:
            typeMethods.r8mat_transpose_print(2, nd, xy, "  Data array:");
            break;
        }

        double[] xd = new double[nd];
        double[] yd = new double[nd];
        for (i = 0; i < nd; i++)
        {
            xd[i] = xy[0 + i * 2];
            yd[i] = xy[1 + i * 2];
        }

        //
        //  Compute the Vandermonde matrix.
        //
        Console.WriteLine("  Using polynomial approximant of degree " + m + "");

        double[] a = VandermondeMatrix.vandermonde_approx_1d_matrix(nd, m, xd);
        //
        //  Solve linear system.
        //
        double[] c = QRSolve.qr_solve(nd, m + 1, a, yd);
        //
        //  #1:  Does approximant match function at data points?
        //
        int ni = nd;

        double[] xi = typeMethods.r8vec_copy_new(ni, xd);
        double[] yi = Polynomial.r8poly_values(m, c, ni, xi);

        double app_error = typeMethods.r8vec_norm_affine(ni, yi, yd) / ni;

        Console.WriteLine("");
        Console.WriteLine("  L2 data approximation error = " + app_error + "");

        //
        //  #2: Compare estimated curve length to piecewise linear (minimal) curve length.
        //  Assume data is sorted, and normalize X and Y dimensions by (XMAX-XMIN) and
        //  (YMAX-YMIN).
        //
        double xmin = typeMethods.r8vec_min(nd, xd);
        double xmax = typeMethods.r8vec_max(nd, xd);
        double ymin = typeMethods.r8vec_min(nd, yd);
        double ymax = typeMethods.r8vec_max(nd, yd);

        ni = 501;
        xi = typeMethods.r8vec_linspace_new(ni, xmin, xmax);

        yi = Polynomial.r8poly_values(m, c, ni, xi);

        double ld = 0.0;

        for (i = 0; i < nd - 1; i++)
        {
            ld += Math.Sqrt(Math.Pow((xd[i + 1] - xd[i]) / (xmax - xmin), 2)
                            + Math.Pow((yd[i + 1] - yd[i]) / (ymax - ymin), 2));
        }

        double li = 0.0;

        for (i = 0; i < ni - 1; i++)
        {
            li += Math.Sqrt(Math.Pow((xi[i + 1] - xi[i]) / (xmax - xmin), 2)
                            + Math.Pow((yi[i + 1] - yi[i]) / (ymax - ymin), 2));
        }

        Console.WriteLine("");
        Console.WriteLine("  Normalized length of piecewise linear interpolant = " + ld + "");
        Console.WriteLine("  Normalized length of polynomial interpolant       = " + li + "");
    }
Esempio n. 10
0
    public static void milstrong(ref typeMethods.r8vecNormalData data, ref int seed, int p_max, ref double[] dtvals, ref double[] xerr)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    MILSTRONG tests the strong convergence of the Milstein method.
    //
    //  Discussion:
    //
    //    This function solves the stochastic differential equation
    //
    //      dX = sigma * X * ( k - X ) dt + beta * X dW,
    //      X(0) = Xzero,
    //
    //    where
    //
    //       sigma = 2,
    //       k = 1,
    //       beta = 1,
    //       Xzero = 0.5.
    //
    //    The discretized Brownian path over [0,1] has dt = 2^(-11).
    //
    //    The Milstein method uses timesteps 128*dt, 64*dt, 32*dt, 16*dt
    //    (also dt for reference).
    //
    //    We examine strong convergence at T=1:
    //
    //      E | X_L - X(T) |.
    //
    //    The code is vectorized: all paths computed simultaneously.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    28 September 2012
    //
    //  Author:
    //
    //    Original MATLAB version by Desmond Higham.
    //    C++ version by John Burkardt.
    //
    //  Reference:
    //
    //    Desmond Higham,
    //    An Algorithmic Introduction to Numerical Simulation of
    //    Stochastic Differential Equations,
    //    SIAM Review,
    //    Volume 43, Number 3, September 2001, pages 525-546.
    //
    //  Parameters:
    //
    //    Input/output, int &SEED, a seed for the random
    //    number generator.
    //
    //    Input, int P_MAX, the number of time step sizes to use.
    //    A typical value is 4.
    //
    //    Output, double DTVALS[P_MAX], the time steps used.
    //
    //    Output, double XERR[P_MAX], the averaged absolute error in the
    //    solution estimate at the final time.
    //
    {
        int i;
        int j;
        int p;
        //
        //  Set problem parameters.
        //
        const double sigma = 2.0;
        const double k     = 1.0;
        const double beta  = 0.25;
        const double xzero = 0.5;
        //
        //  Set stepping parameters.
        //
        const double tmax = 1.0;
        int          n    = (int)Math.Pow(2, 11);
        double       dt   = tmax / n;
        //
        //  Number of paths sampled.
        //
        const int m = 500;

        //
        //  Define the increments dW.
        //
        double[] dw = typeMethods.r8mat_normal_01_new(m, n, ref data, ref seed);
        for (j = 0; j < n; j++)
        {
            for (i = 0; i < m; i++)
            {
                dw[i + j * m] = Math.Sqrt(dt) * dw[i + j * m];
            }
        }

        //
        //  Estimate the reference solution at time T M times.
        //
        double[] xref = new double[m];

        for (i = 0; i < m; i++)
        {
            xref[i] = xzero;
        }

        for (j = 0; j < n; j++)
        {
            for (i = 0; i < m; i++)
            {
                xref[i] = xref[i]
                          + dt * sigma * xref[i] * (k - xref[i])
                          + beta * xref[i] * dw[i + j * m]
                          + 0.5 * beta * beta * xref[i] * (dw[i + j * m] * dw[i + j * m] - dt);
            }
        }

        //
        //  Now compute M Milstein approximations at each of 4 timesteps,
        //  and record the average errors.
        //
        for (p = 0; p < p_max; p++)
        {
            dtvals[p] = dt * 8.0 * Math.Pow(2.0, p + 1);
        }

        for (p = 0; p < p_max; p++)
        {
            xerr[p] = 0.0;
        }

        double[] xtemp = new double[m];
        for (p = 0; p < p_max; p++)
        {
            int    r   = 8 * (int)Math.Pow(2, p + 1);
            double dtp = dtvals[p];
            int    l   = n / r;
            for (i = 0; i < m; i++)
            {
                xtemp[i] = xzero;
            }

            for (j = 0; j < l; j++)
            {
                for (i = 0; i < m; i++)
                {
                    double winc = 0.0;
                    int    i2;
                    for (i2 = r * j; i2 < r * (j + 1); i2++)
                    {
                        winc += dw[i + i2 * m];
                    }

                    xtemp[i] = xtemp[i]
                               + dtp * sigma * xtemp[i] * (k - xtemp[i])
                               + beta * xtemp[i] * winc
                               + 0.5 * beta * beta * xtemp[i] * (winc * winc - dtp);
                }
            }

            xerr[p] = 0.0;
            for (i = 0; i < m; i++)
            {
                xerr[p] += Math.Abs(xtemp[i] - xref[i]);
            }

            xerr[p] /= m;
        }

        //
        //  Least squares fit of error = C * dt^q
        //
        double[] a   = new double[p_max * 2];
        double[] rhs = new double[p_max];
        for (p = 0; p < p_max; p++)
        {
            a[p + 0 * p_max] = 1.0;
            a[p + 1 * p_max] = Math.Log(dtvals[p]);
            rhs[p]           = Math.Log(xerr[p]);
        }

        double[] sol = QRSolve.qr_solve(p_max, 2, a, rhs);

        Console.WriteLine("");
        Console.WriteLine("MILSTEIN:");
        Console.WriteLine("  Least squares solution to Error = c * dt ^ q");
        Console.WriteLine("  Expecting Q to be about 1.");
        Console.WriteLine("  Computed Q = " + sol[1] + "");

        double resid = 0.0;

        for (i = 0; i < p_max; i++)
        {
            double e = a[i + 0 * p_max] * sol[0] + a[i + 1 * p_max] * sol[1] - rhs[i];
            resid += e * e;
        }

        resid = Math.Sqrt(resid);
        Console.WriteLine("  Residual is " + resid + "");
    }
Esempio n. 11
0
    private static void qform_test()
    //****************************************************************************80
    //
    //  Purpose:
    //
    //    QFORM_TEST tests QFORM.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    02 January 2018
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        int       i;
        int       j;
        int       k;
        const int lda = 5;
        const int m   = 5;
        const int n   = 7;

        Console.WriteLine("");
        Console.WriteLine("QFORM_TEST:");
        Console.WriteLine("  QFORM constructs the Q factor explicitly");
        Console.WriteLine("  after the use of QRFAC.");
        //
        //  Set the matrix A.
        //
        double[] a = new double[m * n];

        int seed = 123456789;

        for (j = 0; j < n; j++)
        {
            for (i = 0; i < m; i++)
            {
                a[i + j * m] = UniformRNG.r8_uniform_01(ref seed);
            }
        }

        typeMethods.r8mat_print(m, n, a, "  Matrix A:");
        //
        //  Compute the QR factors.
        //
        const bool pivot = false;

        int[] ipivot = new int[n];
        int   lipvt  = n;

        double[] rdiag  = new double[n];
        double[] acnorm = new double[n];

        QRSolve.qrfac(m, n, ref a, lda, pivot, ref ipivot, ref lipvt, ref rdiag, ref acnorm);
        //
        //  Extract the R factor.
        //
        double[] r = new double[m * n];
        for (j = 0; j < n; j++)
        {
            for (i = 0; i < m; i++)
            {
                r[i + j * m] = 0.0;
            }
        }

        for (k = 0; k < Math.Min(m, n); k++)
        {
            r[k + k * m] = rdiag[k];
        }

        for (j = 0; j < n; j++)
        {
            for (i = 0; i < Math.Min(j, m); i++)
            {
                r[i + j * m] = a[i + j * m];
            }
        }

        typeMethods.r8mat_print(m, n, r, "  Matrix R:");
        //
        //  Call QRFORM to form the Q factor.
        //
        double[] q = new double[m * m];
        for (j = 0; j < m; j++)
        {
            for (i = 0; i < m; i++)
            {
                q[i + j * m] = 0.0;
            }
        }

        for (j = 0; j < Math.Min(m, n); j++)
        {
            for (i = 0; i < m; i++)
            {
                q[i + j * m] = a[i + j * m];
            }
        }

        QRSolve.qform(m, n, ref q, m);

        typeMethods.r8mat_print(m, m, q, "  Matrix Q:");
        //
        //  Compute Q*R.
        //
        double[] a2 = typeMethods.r8mat_mm_new(m, m, n, q, r);
        //
        //  Compare Q*R to A.
        //
        typeMethods.r8mat_print(m, n, a2, "  Matrix A2 = Q * R:");
    }
Esempio n. 12
0
    public static void line_fekete_chebyshev(int m, double a, double b, int n, double[] x,
                                             ref int nf, ref double[] xf, ref double[] wf)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    LINE_FEKETE_CHEBYSHEV: approximate Fekete points in an interval [A,B].
    //
    //  Discussion:
    //
    //    We use the Chebyshev basis.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    13 April 2014
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Reference:
    //
    //    Len Bos, Norm Levenberg,
    //    On the calculation of approximate Fekete points: the univariate case,
    //    Electronic Transactions on Numerical Analysis,
    //    Volume 30, pages 377-397, 2008.
    //
    //  Parameters:
    //
    //    Input, int M, the number of basis polynomials.
    //
    //    Input, double A, B, the endpoints of the interval.
    //
    //    Input, int N, the number of sample points.
    //    M <= N.
    //
    //    Input, double X(N), the coordinates of the sample points.
    //
    //    Output, int &NF, the number of Fekete points.
    //    If the computation is successful, NF = M.
    //
    //    Output, double XF(NF), the coordinates of the Fekete points.
    //
    //    Output, double WF(NF), the weights of the Fekete points.
    //
    {
        int i;
        int j;

        if (n < m)
        {
            Console.WriteLine("");
            Console.WriteLine("LINE_FEKETE_CHEBYSHEV - Fatal error!");
            Console.WriteLine("  N < M.");
            return;
        }

        //
        //  Compute the Chebyshev-Vandermonde matrix.
        //
        double[] v = VandermondeMatrix.cheby_van1(m, a, b, n, x);
        //
        //  MOM(I) = Integral ( A <= x <= B ) Tab(A,B,I;x) dx
        //
        double[] mom = new double[m];

        mom[0] = Math.PI * (b - a) / 2.0;
        for (i = 1; i < m; i++)
        {
            mom[i] = 0.0;
        }

        //
        //  Solve the system for the weights W.
        //
        double[] w = QRSolve.qr_solve(m, n, v, mom);
        //
        //  Extract the data associated with the nonzero weights.
        //
        nf = 0;
        for (j = 0; j < n; j++)
        {
            if (w[j] == 0.0)
            {
                continue;
            }

            if (nf >= m)
            {
                continue;
            }

            xf[nf] = x[j];
            wf[nf] = w[j];
            nf    += 1;
        }
    }
Esempio n. 13
0
    public static void line_fekete_monomial(int m, double a, double b, int n, double[] x,
                                            ref int nf, ref double[] xf, ref double[] wf)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    LINE_FEKETE_MONOMIAL: approximate Fekete points in an interval [A,B].
    //
    //  Discussion:
    //
    //    We use the uniform weight and the monomial basis:
    //
    //      P(j) = x^(j-1)
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    13 April 2014
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Reference:
    //
    //    Alvise Sommariva, Marco Vianello,
    //    Computing approximate Fekete points by QR factorizations of Vandermonde
    //    matrices,
    //    Computers and Mathematics with Applications,
    //    Volume 57, 2009, pages 1324-1336.
    //
    //  Parameters:
    //
    //    Input, int M, the number of basis polynomials.
    //
    //    Input, double A, B, the endpoints of the interval.
    //
    //    Input, int N, the number of sample points.
    //    M <= N.
    //
    //    Input, double X(N), the coordinates of the sample points.
    //
    //    Output, int &NF, the number of Fekete points.
    //    If the computation is successful, NF = M.
    //
    //    Output, double XF(NF), the coordinates of the Fekete points.
    //
    //    Output, double WF(NF), the weights of the Fekete points.
    //
    {
        int j;

        if (n < m)
        {
            Console.WriteLine("");
            Console.WriteLine("LINE_FEKETE_MONOMIAL - Fatal error!");
            Console.WriteLine("  N < M.");
            return;
        }

        //
        //  Form the moments.
        //
        double[] mom = Monomial.line_monomial_moments(a, b, m);
        //
        //  Form the rectangular Vandermonde matrix V for the polynomial basis.
        //
        double[] v = new double[m * n];
        for (j = 0; j < n; j++)
        {
            v[0 + j * m] = 1.0;
            int i;
            for (i = 1; i < m; i++)
            {
                v[i + j * m] = v[i - 1 + j * m] * x[j];
            }
        }

        //
        //  Solve the system for the weights W.
        //
        double[] w = QRSolve.qr_solve(m, n, v, mom);
        //
        //  Extract the data associated with the nonzero weights.
        //
        nf = 0;
        for (j = 0; j < n; j++)
        {
            if (w[j] == 0.0)
            {
                continue;
            }

            if (nf >= m)
            {
                continue;
            }

            xf[nf] = x[j];
            wf[nf] = w[j];
            nf    += 1;
        }
    }
Esempio n. 14
0
    public static double[] lagrange_approx_1d(int m, int nd, double[] xd, double[] yd,
                                              int ni, double[] xi)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    LAGRANGE_APPROX_1D evaluates the Lagrange approximant of degree M.
    //
    //  Discussion:
    //
    //    The Lagrange approximant L(M,ND,XD,YD)(X) is a polynomial of
    //    degree M which approximates the data (XD(I),YD(I)) for I = 1 to ND.
    //
    //    We can represent any polynomial of degree M+1 as the sum of the Lagrange
    //    basis functions at the M+1 Chebyshev points.
    //
    //      L(M)(X) = sum ( 1 <= I <= M+1 ) C(I) LB(M,XC)(X)
    //
    //    Given our data, we can seek the M+1 unknown coefficients C which minimize
    //    the norm of || L(M)(XD(1:ND)) - YD(1:ND) ||.
    //
    //    Given the coefficients, we can then evaluate the polynomial at the
    //    points XI.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    09 October 2012
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, int M, the polynomial degree.
    //
    //    Input, int ND, the number of data points.
    //    ND must be at least 1.
    //
    //    Input, double XD[ND], the data points.
    //
    //    Input, double YD[ND], the data values.
    //
    //    Input, int NI, the number of interpolation points.
    //
    //    Input, double XI[NI], the interpolation points.
    //
    //    Output, double LAGRANGE_APPROX_1D[NI], the interpolated values.
    //
    {
        int nc = m + 1;
        //
        //  Evaluate the Chebyshev points.
        //
        const double a = -1.0;
        const double b = +1.0;

        double[] xc = typeMethods.r8vec_cheby_extreme_new(nc, a, b);
        //
        //  Evaluate the Lagrange basis functions for the Chebyshev points
        //  at the data points.
        //
        double[] ld = lagrange_basis_1d(nc, xc, nd, xd);
        //
        //  The value of the Lagrange approximant at each data point should
        //  approximate the data value: LD * YC = YD, where YC are the unknown
        //  coefficients.
        //
        double[] yc = QRSolve.qr_solve(nd, nc, ld, yd);
        //
        //  Now we want to evaluate the Lagrange approximant at the "interpolant
        //  points": LI * YC = YI
        //
        double[] li = lagrange_basis_1d(nc, xc, ni, xi);

        double[] yi = typeMethods.r8mat_mv_new(ni, nc, li, yc);

        return(yi);
    }
Esempio n. 15
0
    private static void test02(int prob)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    TEST02 tests VANDERMONDE_INTERP_1D_MATRIX.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    02 June 2013
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, int PROB, the problem index.
    //
    {
        List <string> command_unit = new();
        List <string> data_unit    = new();
        int           i;
        List <string> interp_unit = new();
        int           j;

        Console.WriteLine("");
        Console.WriteLine("TEST02:");
        Console.WriteLine("  VANDERMONDE_INTERP_1D_MATRIX sets the Vandermonde linear system");
        Console.WriteLine("  for the interpolating polynomial.");
        Console.WriteLine("  Interpolate data from TEST_INTERP problem #" + prob + "");

        int nd = TestInterp.p00_data_num(prob);

        Console.WriteLine("  Number of data points = " + nd + "");

        double[] xy = TestInterp.p00_data(prob, 2, nd);

        typeMethods.r8mat_transpose_print(2, nd, xy, "  Data array:");

        double[] xd = new double[nd];
        double[] yd = new double[nd];

        for (i = 0; i < nd; i++)
        {
            xd[i] = xy[0 + 2 * i];
            yd[i] = xy[1 + 2 * i];
        }

        //
        //  Compute Vandermonde matrix and get condition number.
        //
        double[] ad = Vandermonde.vandermonde_matrix_1d(nd, xd);
        //
        //  Solve linear system.
        //
        double[] cd = QRSolve.qr_solve(nd, nd, ad, yd);
        //
        //  Create data file.
        //
        string data_filename = "data" + prob + ".txt";

        for (j = 0; j < nd; j++)
        {
            data_unit.Add("  " + xd[j]
                          + "  " + yd[j] + "");
        }

        File.WriteAllLines(data_filename, data_unit);
        Console.WriteLine("");
        Console.WriteLine("  Created graphics data file \"" + data_filename + "\".");
        //
        //  Create interp file.
        //
        int    ni   = 501;
        double xmin = typeMethods.r8vec_min(nd, xd);
        double xmax = typeMethods.r8vec_max(nd, xd);

        double[] xi = typeMethods.r8vec_linspace_new(ni, xmin, xmax);
        double[] yi = Vandermonde.vandermonde_value_1d(nd, cd, ni, xi);

        string interp_filename = "interp" + prob + ".txt";

        for (j = 0; j < ni; j++)
        {
            interp_unit.Add("  " + xi[j]
                            + "  " + yi[j] + "");
        }

        File.WriteAllLines(interp_filename, interp_unit);
        Console.WriteLine("  Created graphics interp file \"" + interp_filename + "\".");
        //
        //  Plot the data and the interpolant.
        //
        string command_filename = "commands" + prob + ".txt";

        string output_filename = "plot" + prob + ".png";

        command_unit.Add("# " + command_filename + "");
        command_unit.Add("#");
        command_unit.Add("# Usage:");
        command_unit.Add("#  gnuplot < " + command_filename + "");
        command_unit.Add("#");
        command_unit.Add("set term png");
        command_unit.Add("set output '" + output_filename + "'");
        command_unit.Add("set xlabel '<---X--->'");
        command_unit.Add("set ylabel '<---Y--->'");
        command_unit.Add("set title 'Data versus Vandermonde polynomial interpolant'");
        command_unit.Add("set grid");
        command_unit.Add("set style data lines");
        command_unit.Add("plot '" + data_filename
                         + "' using 1:2 with points pt 7 ps 2 lc rgb 'blue',\\");
        command_unit.Add("     '" + interp_filename
                         + "' using 1:2 lw 3 linecolor rgb 'red'");

        File.WriteAllLines(command_filename, command_unit);
        Console.WriteLine("  Created graphics command file \"" + command_filename + "\".");
    }
Esempio n. 16
0
    private static void qr_solve_test()

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    QR_SOLVE_TEST tests QR_SOLVE.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    21 April 2012
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        int prob;

        Console.WriteLine("");
        Console.WriteLine("QR_SOLVE_TEST");
        Console.WriteLine("  QR_SOLVE is a function with a simple interface which");
        Console.WriteLine("  solves a linear system A*x = b in the least squares sense.");
        Console.WriteLine("  Compare a tabulated solution X1 to the QR_SOLVE result X2.");

        int prob_num = ProbabilityFunctions.p00_prob_num();

        Console.WriteLine("");
        Console.WriteLine("  Number of problems = " + prob_num + "");
        Console.WriteLine("");
        Console.WriteLine("  Index     M     N     ||B||         ||X1 - X2||   ||X1||       ||X2||        ||R1||        ||R2||");
        Console.WriteLine("");

        for (prob = 1; prob <= prob_num; prob++)
        {
            //
            //  Get problem size.
            //
            int m = ProbabilityFunctions.p00_m(prob);
            int n = ProbabilityFunctions.p00_n(prob);
            //
            //  Retrieve problem data.
            //
            double[] a  = ProbabilityFunctions.p00_a(prob, m, n);
            double[] b  = ProbabilityFunctions.p00_b(prob, m);
            double[] x1 = ProbabilityFunctions.p00_x(prob, n);

            double   b_norm  = typeMethods.r8vec_norm(m, b);
            double   x1_norm = typeMethods.r8vec_norm(n, x1);
            double[] r1      = typeMethods.r8mat_mv_new(m, n, a, x1);
            int      i;
            for (i = 0; i < m; i++)
            {
                r1[i] -= b[i];
            }

            double r1_norm = typeMethods.r8vec_norm(m, r1);
            //
            //  Use QR_SOLVE on the problem.
            //
            double[] x2 = QRSolve.qr_solve(m, n, a, b);

            double   x2_norm = typeMethods.r8vec_norm(n, x2);
            double[] r2      = typeMethods.r8mat_mv_new(m, n, a, x2);
            for (i = 0; i < m; i++)
            {
                r2[i] -= b[i];
            }

            double r2_norm = typeMethods.r8vec_norm(m, r2);
            //
            //  Compare tabulated and computed solutions.
            //
            double x_diff_norm = typeMethods.r8vec_norm_affine(n, x1, x2);
            //
            //  Report results for this problem.
            //
            Console.WriteLine("  " + prob.ToString(CultureInfo.InvariantCulture).PadLeft(5)
                              + "  " + m.ToString(CultureInfo.InvariantCulture).PadLeft(4)
                              + "  " + n.ToString(CultureInfo.InvariantCulture).PadLeft(4)
                              + "  " + b_norm.ToString(CultureInfo.InvariantCulture).PadLeft(12)
                              + "  " + x_diff_norm.ToString(CultureInfo.InvariantCulture).PadLeft(12)
                              + "  " + x1_norm.ToString(CultureInfo.InvariantCulture).PadLeft(12)
                              + "  " + x2_norm.ToString(CultureInfo.InvariantCulture).PadLeft(12)
                              + "  " + r1_norm.ToString(CultureInfo.InvariantCulture).PadLeft(12)
                              + "  " + r2_norm.ToString(CultureInfo.InvariantCulture).PadLeft(12) + "");
        }
    }
    public static void emstrong(ref typeMethods.r8vecNormalData data, ref int seed, int m, int n, int p_max, ref double[] dtvals,
                                ref double[] xerr)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    EMSTRONG tests the strong convergence of the EM method.
    //
    //  Discussion:
    //
    //    The SDE is
    //
    //      dX = lambda * X dt + mu * X dW,
    //      X(0) = Xzero,
    //
    //    where
    //
    //      lambda = 2,
    //      mu = 1,
    //      Xzero = 1.
    //
    //    The discretized Brownian path over [0,1] has dt = 2^(-9).
    //
    //    The Euler-Maruyama method uses 5 different timesteps:
    //      16*dt, 8*dt, 4*dt, 2*dt, dt.
    //
    //    We are interested in examining strong convergence at T=1,
    //    that is
    //
    //      E | X_L - X(T) |.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    28 September 2012
    //
    //  Author:
    //
    //    Original Matlab version by Desmond Higham.
    //    C++ version by John Burkardt.
    //
    //  Reference:
    //
    //    Desmond Higham,
    //    An Algorithmic Introduction to Numerical Simulation of
    //    Stochastic Differential Equations,
    //    SIAM Review,
    //    Volume 43, Number 3, September 2001, pages 525-546.
    //
    //  Parameters:
    //
    //    Input/output, int &SEED, a seed for the random
    //    number generator.
    //
    //    Input, int M, the number of simulations to perform.
    //    A typical value is M = 1000.
    //
    //    Input, int N, the number of time steps to take.
    //    A typical value is N = 512.
    //
    //    Input, int P_MAX, the number of time step sizes to use.
    //    A typical value is 5.
    //
    //    Output, double DTVALS[P_MAX], the time steps used.
    //
    //    Output, double XERR[P_MAX], the averaged absolute error in the
    //    solution estimate at the final time.
    //
    {
        int i;
        int p;
        int s;
        //
        //  Set problem parameters.
        //
        const double lambda = 2.0;
        const double mu     = 1.0;
        const double xzero  = 1.0;
        //
        //  Set stepping parameters.
        //
        const double tmax = 1.0;
        double       dt   = tmax / n;

        for (p = 0; p < p_max; p++)
        {
            dtvals[p] = dt * Math.Pow(2.0, p);
        }

        //
        //  Sample over discrete Brownian paths.
        //
        for (p = 0; p < p_max; p++)
        {
            xerr[p] = 0.0;
        }

        for (s = 0; s < m; s++)
        {
            //
            //  Define the increments dW.
            //
            double[] dw = typeMethods.r8vec_normal_01_new(n, ref data, ref seed);

            int j;
            for (j = 0; j < n; j++)
            {
                dw[j] = Math.Sqrt(dt) * dw[j];
            }

            //
            //  Sum the increments to get the Brownian path.
            //
            double[] w = new double[n + 1];
            w[0] = 0.0;
            for (j = 1; j <= n; j++)
            {
                w[j] = w[j - 1] + dw[j - 1];
            }

            //
            //  Determine the true solution.
            //
            double xtrue = xzero * Math.Exp(lambda - 0.5 * mu * mu + mu * w[n]);
            //
            //  Use the Euler-Maruyama method with 5 different time steps dt2 = r * dt
            //  to estimate the solution value at time TMAX.
            //
            for (p = 0; p < p_max; p++)
            {
                double dt2   = dtvals[p];
                int    r     = (int)Math.Pow(2, p);
                int    l     = n / r;
                double xtemp = xzero;
                for (j = 0; j < l; j++)
                {
                    double winc = 0.0;
                    int    k;
                    for (k = r * j; k < r * (j + 1); k++)
                    {
                        winc += dw[k];
                    }

                    xtemp = xtemp + dt2 * lambda * xtemp + mu * xtemp * winc;
                }

                xerr[p] += Math.Abs(xtemp - xtrue);
            }
        }

        for (p = 0; p < p_max; p++)
        {
            xerr[p] /= m;
        }

        //
        //  Least squares fit of error = c * dt^q.
        //
        double[] a   = new double[p_max * 2];
        double[] rhs = new double[p_max];

        for (i = 0; i < p_max; i++)
        {
            a[i + 0 * p_max] = 1.0;
            a[i + 1 * p_max] = Math.Log(dtvals[i]);
            rhs[i]           = Math.Log(xerr[i]);
        }

        double[] sol = QRSolve.qr_solve(p_max, 2, a, rhs);

        Console.WriteLine("");
        Console.WriteLine("EMSTRONG:");
        Console.WriteLine("  Least squares solution to Error = c * dt ^ q");
        Console.WriteLine("  (Expecting Q to be about 1/2.)");
        Console.WriteLine("  Computed Q = " + sol[1] + "");

        double resid = 0.0;

        for (i = 0; i < p_max; i++)
        {
            double e = a[i + 0 * p_max] * sol[0] + a[i + 1 * p_max] * sol[1] - rhs[i];
            resid += e * e;
        }

        resid = Math.Sqrt(resid);
        Console.WriteLine("  Residual is " + resid + "");
    }
Esempio n. 18
0
    private static void dqrls_test()

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    DQRLS_TEST tests DQRLS.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    21 April 2012
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        double[] b =
        {
            1.0, 2.3, 4.6, 3.1, 1.2
        }

        ;
        int       i;
        int       kr = 0;
        const int m  = 5;
        const int n  = 3;

        double[] a     = new double[m * n];
        int[]    jpvt  = new int[n];
        double[] qraux = new double[n];
        double[] x     = new double[n];
        //
        //  Set up least-squares problem
        //  quadratic model, equally-spaced points
        //
        Console.WriteLine("");
        Console.WriteLine("DQRLS_TEST");
        Console.WriteLine("  DQRLS solves a linear system A*x = b in the least squares sense.");

        for (i = 0; i < m; i++)
        {
            a[i + 0 * m] = 1.0;
            int j;
            for (j = 1; j < n; j++)
            {
                a[i + j * m] = a[i + (j - 1) * m] * (i + 1);
            }
        }

        double tol = 1.0E-06;

        typeMethods.r8mat_print(m, n, a, "  Coefficient matrix A:");

        typeMethods.r8vec_print(m, b, "  Right hand side b:");
        //
        //  Solve least-squares problem
        //
        int itask = 1;
        int ind   = QRSolve.dqrls(ref a, m, m, n, tol, ref kr, b, ref x, ref b, jpvt, qraux, itask);

        //
        //  Print results
        //
        Console.WriteLine("");
        Console.WriteLine("  Error code = " + ind + "");
        Console.WriteLine("  Estimated matrix rank = " + kr + "");

        typeMethods.r8vec_print(n, x, "  Least squares solution x:");

        typeMethods.r8vec_print(m, b, "  Residuals A*x-b");
    }
Esempio n. 19
0
    private static void test01(int prob, int grd, int m)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    VANDERMONDE_APPROX_2D_TEST01 tests VANDERMONDE_APPROX_2D_MATRIX.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    11 October 2012
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, int PROB, the problem number.
    //
    //    Input, int GRD, the grid number.
    //    (Can't use GRID as the name because that's also a plotting function.)
    //
    //    Input, int M, the total polynomial degree.
    //
    {
        Console.WriteLine("");
        Console.WriteLine("TEST01:");
        Console.WriteLine("  Approximate data from TEST_INTERP_2D problem #" + prob + "");
        Console.WriteLine("  Use grid from TEST_INTERP_2D with index #" + grd + "");
        Console.WriteLine("  Using polynomial approximant of total degree " + m + "");

        int nd = Data_2D.g00_size(grd);

        Console.WriteLine("  Number of data points = " + nd + "");

        double[] xd = new double[nd];
        double[] yd = new double[nd];
        Data_2D.g00_xy(grd, nd, ref xd, ref yd);

        double[] zd = new double[nd];
        Data_2D.f00_f0(prob, nd, xd, yd, ref zd);

        switch (nd)
        {
        case < 10:
            typeMethods.r8vec3_print(nd, xd, yd, zd, "  X, Y, Z data:");
            break;
        }

        //
        //  Compute the Vandermonde matrix.
        //
        int tm = typeMethods.triangle_num(m + 1);

        double[] a = VandermondeMatrix.vandermonde_approx_2d_matrix(nd, m, tm, xd, yd);
        //
        //  Solve linear system.
        //
        double[] c = QRSolve.qr_solve(nd, tm, a, zd);
        //
        //  #1:  Does approximant match function at data points?
        //
        int ni = nd;

        double[] xi = typeMethods.r8vec_copy_new(ni, xd);
        double[] yi = typeMethods.r8vec_copy_new(ni, yd);
        double[] zi = Polynomial.r8poly_values_2d(m, c, ni, xi, yi);

        double app_error = typeMethods.r8vec_norm_affine(ni, zi, zd) / ni;

        Console.WriteLine("");
        Console.WriteLine("  L2 data approximation error = " + app_error + "");
    }
Esempio n. 20
0
    private static void test01(int prob, int m)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    TEST01 tests VANDERMONDE_INTERP_2D_MATRIX.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    07 October 2012
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, int PROB, the problem number.
    //
    //    Input, int M, the degree of interpolation.
    //
    {
        const bool debug = false;

        Console.WriteLine("");
        Console.WriteLine("TEST01:");
        Console.WriteLine("  Interpolate data from TEST_INTERP_2D problem #" + prob + "");
        Console.WriteLine("  Create an interpolant of total degree " + m + "");
        int tmp1 = typeMethods.triangle_num(m + 1);

        Console.WriteLine("  Number of data values needed is " + tmp1 + "");

        int seed = 123456789;

        double[] xd = UniformRNG.r8vec_uniform_01_new(tmp1, ref seed);
        double[] yd = UniformRNG.r8vec_uniform_01_new(tmp1, ref seed);
        double[] zd = new double[tmp1];
        Data_2D.f00_f0(prob, tmp1, xd, yd, ref zd);

        switch (debug)
        {
        case true:
            typeMethods.r8vec3_print(tmp1, xd, yd, zd, "  X, Y, Z data:");
            break;
        }

        //
        //  Compute the Vandermonde matrix.
        //
        double[] a = Vandermonde.vandermonde_interp_2d_matrix(tmp1, m, xd, yd);
        //
        //  Solve linear system.
        //
        double[] c = QRSolve.qr_solve(tmp1, tmp1, a, zd);
        //
        //  #1:  Does interpolant match function at data points?
        //
        int ni = tmp1;

        double[] xi = typeMethods.r8vec_copy_new(ni, xd);
        double[] yi = typeMethods.r8vec_copy_new(ni, yd);
        double[] zi = Polynomial.r8poly_values_2d(m, c, ni, xi, yi);

        double app_error = typeMethods.r8vec_norm_affine(ni, zi, zd) / ni;

        Console.WriteLine("");
        Console.WriteLine("  L2 data interpolation error = " + app_error + "");
    }