Beispiel #1
0
        public NewtonRaphson(Parameter[] parameters, Func <double>[] functions, int numberOfDerivativePoints = 3)
        {
            _parameters = parameters;
            _functions  = functions;
            int numberOfFunctions  = _functions.Length;
            int numberOfParameters = _parameters.Length;

            _derivatives    = new Derivatives(numberOfDerivativePoints);
            _jacobian       = new Matrix(numberOfFunctions, numberOfParameters);
            _functionMatrix = new Matrix(numberOfFunctions, 1);
            _x0             = new Matrix(numberOfFunctions, 1);
        }
Beispiel #2
0
        public static Parameter[] Compute(Func <double>[] regressionFunctions, Parameter[] regressionParameters, Parameter[] observedParameters, double[,] data, int numberOfDerivativePoints)
        {
            double l0 = 100.0;
            double v  = 10.0;

            Derivatives derivatives           = new Derivatives(numberOfDerivativePoints);
            Matrix      jacobian              = new Matrix(regressionFunctions.Length * data.GetLength(0), regressionParameters.Length);
            Matrix      residuals             = new Matrix(regressionFunctions.Length * data.GetLength(0), 1);
            Matrix      regressionParameters0 = new Matrix(regressionParameters.Length, 1);

            for (int f = 0; f < 10000; f++)
            {
                int    numberOfPoints     = data.GetLength(0);
                int    numberOfParameters = regressionParameters.Length;
                int    numberOfFunctions  = regressionFunctions.Length;
                double error = 0.0;

                for (int i = 0; i < numberOfFunctions; i++)
                {
                    for (int j = 0; j < numberOfPoints; j++)
                    {
                        for (int k = 0; k < observedParameters.Length; k++)
                        {
                            observedParameters[k].Value = data[j, k];
                        }
                        double functionValue = regressionFunctions[i]();
                        double residual      = data[j, observedParameters.Length + i] - functionValue;
                        residuals[j + i * numberOfPoints, 0] = residual;
                        error += residual * residual;
                        for (int k = 0; k < numberOfParameters; k++)
                        {
                            jacobian[j + i * numberOfPoints, k] = derivatives.ComputePartialDerivative(regressionFunctions[i], regressionParameters[k], 1, functionValue);
                        }
                    }
                }
                for (int i = 0; i < numberOfParameters; i++)
                {
                    regressionParameters0[i, 0] = regressionParameters[i];
                }

                Matrix jacobianTranspose                = jacobian.Transpose();
                Matrix jacobianTransposeResiduals       = jacobianTranspose * residuals;
                Matrix jacobianTransposeJacobian        = jacobianTranspose * jacobian;
                Matrix jacobianTransposeJacobianDiagnol = new Matrix(jacobianTransposeJacobian.RowCount, jacobianTransposeJacobian.RowCount);

                for (int i = 0; i < jacobianTransposeJacobian.RowCount; i++)
                {
                    jacobianTransposeJacobianDiagnol[i, i] = jacobianTransposeJacobian[i, i];
                }

                double newResidual = error + 1.0;
                l0 /= v;

                while (newResidual > error)
                {
                    newResidual = 0.0; l0 *= v;
                    Matrix matLHS = jacobianTransposeJacobian + l0 * jacobianTransposeJacobianDiagnol;
                    var    delta  = matLHS.SolveFor(jacobianTransposeResiduals);
                    ;
                    var newRegressionParameters = regressionParameters0 + delta;
                    for (int i = 0; i < numberOfParameters; i++)
                    {
                        regressionParameters[i].Value = newRegressionParameters[i, 0];
                    }
                    for (int i = 0; i < numberOfFunctions; i++)
                    {
                        for (int j = 0; j < numberOfPoints; j++)
                        {
                            for (int k = 0; k < observedParameters.Length; k++)
                            {
                                observedParameters[k].Value = data[j, k];
                            }
                            double functionValue = regressionFunctions[i]();
                            double residual      = data[j, observedParameters.Length + i] - functionValue; newResidual += residual * residual;
                        }
                    }
                }
                l0 /= v;
            }

            return(regressionParameters);
        }