예제 #1
0
        /// <summary>
        /// Perform a SVD fit.
        /// </summary>
        /// <param name="x">The X matrix.</param>
        /// <param name="y">The Y matrix.</param>
        /// <param name="a">The A matrix.</param>
        /// <param name="funcs">The RBF functions.</param>
        /// <returns>The fit.</returns>
        public static double Svdfit(double[][] x, double[][] y, double[][] a,
                                    IRadialBasisFunction[] funcs)
        {
            int    i, j, k;
            double wmax, tmp, thresh, sum, TOL = 1e-13d;

            //Allocated memory for svd matrices
            double[][] u = EngineArray.AllocateDouble2D(x.Length, funcs.Length);
            double[][] v = EngineArray.AllocateDouble2D(funcs.Length, funcs.Length);
            var        w = new double[funcs.Length];

            //Fill input matrix with values based on fitting functions and input coordinates
            for (i = 0; i < x.Length; i++)
            {
                for (j = 0; j < funcs.Length; j++)
                {
                    u[i][j] = funcs[j].Calculate(x[i]);
                }
            }

            //Perform decomposition
            Svdcmp(u, w, v);

            //Check for w values that are close to zero and replace them with zeros such that they are ignored in backsub
            wmax = 0;
            for (j = 0; j < funcs.Length; j++)
            {
                if (w[j] > wmax)
                {
                    wmax = w[j];
                }
            }

            thresh = TOL * wmax;

            for (j = 0; j < funcs.Length; j++)
            {
                if (w[j] < thresh)
                {
                    w[j] = 0;
                }
            }

            //Perform back substitution to get result
            Svdbksb(u, w, v, y, a);

            //Calculate chi squared for the fit
            double chisq = 0;

            for (k = 0; k < y[0].Length; k++)
            {
                for (i = 0; i < y.Length; i++)
                {
                    sum = 0.0d;
                    for (j = 0; j < funcs.Length; j++)
                    {
                        sum += a[j][k] * funcs[j].Calculate(x[i]);
                    }
                    tmp    = (y[i][k] - sum);
                    chisq += tmp * tmp;
                }
            }

            return(Math.Sqrt(chisq / (y.Length * y[0].Length)));
        }