コード例 #1
0
        /// <summary>
        ///   Get Jacobian matrix of the objective function.
        /// </summary>
        /// <param name = "model">Model function.</param>
        /// <param name = "pointCount">Number of data points.</param>
        /// <param name = "dataX">X-coordinates of the data points.</param>
        /// <param name = "dataY">Y-coordinates of the data points.</param>
        /// <param name = "parameters">Model function parameters.</param>
        /// <param name = "jacobian">Jacobian matrix of the objective function.</param>
        private void GetObjectiveJacobian(PowerModel model, int pointCount, Vector <double> parameters, ref Matrix <double> jacobian)
        {
            int parameterCount = parameters.Count;

            // fill rows of the Jacobian matrix
            // j-th row of a Jacobian is the gradient of model function in j-th measurement
            for (int j = 0; j < pointCount; j++)
            {
                Vector <double> gradient = new DenseVector(parameterCount);

                model.GetGradient(
                    dataX[j],
                    parameters,
                    ref gradient);

                jacobian.SetRow(j, gradient);
            }
        }
コード例 #2
0
        /// <summary>
        ///   Get value of the objective function.
        /// </summary>
        /// <param name = "model">Model function.</param>
        /// <param name = "pointCount">Number of data points.</param>
        /// <param name = "dataX">X-coordinates of the data points.</param>
        /// <param name = "dataY">Y-coordinates of the data points.</param>
        /// <param name = "parameters">Model function parameters.</param>
        /// <param name = "value">Objective function value.</param>
        private void GetObjectiveValue(PowerModel model, int pointCount, Vector <double> parameters, out double value)
        {
            value = 0.0;

            double y = 0.0;

            for (int j = 0; j < pointCount; j++)
            {
                model.GetValue(
                    dataX[j],
                    parameters,
                    out y);

                value += Math.Pow(
                    y - dataY[j],
                    2.0);
            }

            value *= 0.5;
        }
コード例 #3
0
        /// <summary>
        ///   Estimates the specified model.
        /// </summary>
        /// <param name = "model">Model function.</param>
        /// <param name = "solverOptions">Least squares solver options.</param>
        /// <param name = "pointCount">Number of data points.</param>
        /// <param name = "dataX">X-coordinates of the data points.</param>
        /// <param name = "dataY">Y-coordinates of the data points.</param>
        /// <param name = "iterations">Estimated model function parameters.</param>
        public void Estimate(PowerModel model, int pointCount, Vector <double> dataX, Vector <double> dataY, ref List <Vector <double> > iterations)
        {
            this.dataX = dataX;
            this.dataY = dataY;

            int n = guess.Count;

            Vector <double> parametersCurrent = guess;
            Vector <double> parametersNew     = new DenseVector(n);

            double valueCurrent;
            double valueNew;

            GetObjectiveValue(model, pointCount, parametersCurrent, out valueCurrent);

            while (true)
            {
                Matrix <double> jacobian = new DenseMatrix(pointCount, n);
                Vector <double> residual = new DenseVector(pointCount);

                GetObjectiveJacobian(model, pointCount, parametersCurrent, ref jacobian);

                model.GetResidualVector(pointCount, dataX, dataY, parametersCurrent, ref residual);

                Vector <double> step = jacobian.Transpose().Multiply(jacobian).Cholesky().Solve(jacobian.Transpose().Multiply(residual));

                parametersCurrent.Subtract(step, parametersNew);

                GetObjectiveValue(model, pointCount, parametersNew, out valueNew);

                iterations.Add(parametersNew);

                if (ShouldTerminate(valueCurrent, valueNew, iterations.Count, parametersCurrent, parametersNew))
                {
                    break;
                }

                parametersNew.CopyTo(parametersCurrent);
                valueCurrent = valueNew;
            }
        }