Ejemplo n.º 1
0
        public override double[] Solve()
        {
            int m = A.RowCount;
            int n = A.ColCount;

            IVector x = new SparseVector(n);

            for (int i = 0; i < n; ++i)
            {
                x[i] = 0;
            }

            IMatrix W       = null;
            IMatrix AtWAInv = null;

            for (int j = 0; j < mMaxIters; ++j)
            {
                IVector  eta    = A.Multiply(x);
                IVector  z      = new SparseVector(m);
                double[] g      = new double[m];
                double[] gprime = new double[m];

                for (int k = 0; k < m; ++k)
                {
                    g[k]      = mLinkFunc.GetInvLink(eta[k]);
                    gprime[k] = mLinkFunc.GetInvLinkDerivative(eta[k]);

                    z[k] = eta[k] + (b[k] - g[k]) / gprime[k];
                }

                W = A.Identity(m);
                for (int k = 0; k < m; ++k)
                {
                    double g_variance = GetVariance(g[k]);
                    if (g_variance == 0)
                    {
                        Environment.Exit(0);
                    }
                    W[k, k] = gprime[k] * gprime[k] / g_variance;
                }

                IVector x_old = x;

                IMatrix AtW = At.Multiply(W);

                // solve x for At * W * A * x = At * W * z
                IMatrix AtWA = AtW.Multiply(A);
                AtWAInv = QRSolver.Invert(AtWA);
                x       = AtWAInv.Multiply(AtW).Multiply(z);

                double cost = x.Minus(x_old).Norm(2);
                if (j % 10 == 0)
                {
                    Console.WriteLine("Iteration: {0}, Cost: {1}", j, cost);
                }

                if (cost < mTol)
                {
                    break;
                }
            }

            mX = new double[n];
            for (int i = 0; i < n; ++i)
            {
                mX[i] = x[i];
            }

            UpdateStatistics(AtWAInv, W);

            return(mX);
        }