column() публичный Метод

public column ( int c ) : Vector
c int
Результат Vector
Пример #1
0
        public override Vector evolve(double t0, Vector x0, double dt, Vector dw)
        {
            /* predictor-corrector step to reduce discretization errors.
             *
             * Short - but slow - solution would be
             *
             * Array rnd_0     = stdDeviation(t0, x0, dt)*dw;
             * Array drift_0   = discretization_->drift(*this, t0, x0, dt);
             *
             * return apply(x0, ( drift_0 + discretization_
             *      ->drift(*this,t0,apply(x0, drift_0 + rnd_0),dt) )*0.5 + rnd_0);
             *
             * The following implementation does the same but is faster.
             */

            int    m   = nextIndexReset(t0);
            double sdt = Math.Sqrt(dt);

            Vector f          = new Vector(x0);
            Matrix diff       = lfmParam_.diffusion(t0, x0);
            Matrix covariance = lfmParam_.covariance(t0, x0);

            for (int k = m; k < size_; ++k)
            {
                double y = accrualPeriod_[k] * x0[k];
                m1[k] = y / (1 + y);

                double d = 0;
                m1.GetRange(m, k + 1 - m).ForEach(
                    (ii, vv) => d += vv *
                                     covariance.column(k).GetRange(m, covariance.rows() - m)[ii]);
                d = (d - 0.5 * covariance[k, k]) * dt;

                double r = 0;
                diff.row(k).ForEach((kk, vv) => r += vv * dw[kk]);
                r *= sdt;

                double x = y * Math.Exp(d + r);
                m2[k] = x / (1 + x);

                double inner_product = 0;
                m2.GetRange(m, k + 1 - m).ForEach(
                    (ii, vv) => inner_product += vv *
                                                 covariance.column(k).GetRange(m, covariance.rows() - m)[ii]);
                f[k] = x0[k] * Math.Exp(0.5 * (d + (inner_product - 0.5 * covariance[k, k]) * dt) + r);
            }

            return(f);
        }
Пример #2
0
        public override Vector evolve(double t0, Vector x0, double dt, Vector dw)
        {
            // predictor-corrector step to reduce discretization errors.

            int    m   = nextIndexReset(t0);
            double sdt = Math.Sqrt(dt);

            Vector f          = new Vector(x0);
            Matrix diff       = lfmParam_.diffusion(t0, x0);
            Matrix covariance = lfmParam_.covariance(t0, x0);

            for (int k = m; k < size_; ++k)
            {
                double y = accrualPeriod_[k] * x0[k];
                m1[k] = y / (1 + y);

                double d = 0;
                m1.GetRange(m, k + 1 - m).ForEach(
                    (ii, vv) => d += vv *
                                     covariance.column(k).GetRange(m, covariance.rows() - m)[ii]);
                d = (d - 0.5 * covariance[k, k]) * dt;

                double r = 0;
                diff.row(k).ForEach((kk, vv) => r += vv * dw[kk]);
                r *= sdt;

                double x = y * Math.Exp(d + r);
                m2[k] = x / (1 + x);

                double inner_product = 0;
                m2.GetRange(m, k + 1 - m).ForEach(
                    (ii, vv) => inner_product += vv *
                                                 covariance.column(k).GetRange(m, covariance.rows() - m)[ii]);
                f[k] = x0[k] * Math.Exp(0.5 * (d + (inner_product - 0.5 * covariance[k, k]) * dt) + r);
            }

            return(f);
        }
Пример #3
0
        public override Vector drift(double t, Vector x)
        {
            Vector f          = new Vector(size_, 0.0);
            Matrix covariance = lfmParam_.covariance(t, x);
            int    m          = nextIndexReset(t);

            for (int k = m; k < size_; ++k)
            {
                m1[k] = accrualPeriod_[k] * x[k] / (1 + accrualPeriod_[k] * x[k]);
                double inner_product = 0;
                m1.GetRange(m, k + 1 - m).ForEach(
                    (ii, vv) => inner_product += vv *
                                                 covariance.column(k).GetRange(m, covariance.rows() - m)[ii]);

                f[k] = inner_product - 0.5 * covariance[k, k];
            }
            return(f);
        }
Пример #4
0
        public TqrEigenDecomposition(Vector diag, Vector sub, EigenVectorCalculation calc = EigenVectorCalculation.WithEigenVector,
                                     ShiftStrategy strategy = ShiftStrategy.CloseEigenValue)
        {
            iter_ = 0;
            d_    = new Vector(diag);

            int row = calc == EigenVectorCalculation.WithEigenVector ? d_.size() :
                      calc == EigenVectorCalculation.WithoutEigenVector ? 0 : 1;

            ev_ = new Matrix(row, d_.size(), 0.0);

            int n = diag.size();

            Utils.QL_REQUIRE(n == sub.size() + 1, () => "Wrong dimensions");

            Vector e = new Vector(sub);

            int i;

            for (i = 0; i < ev_.rows(); ++i)
            {
                ev_[i, i] = 1.0;
            }

            for (int k = n - 1; k >= 1; --k)
            {
                while (!offDiagIsZero(k, e))
                {
                    int l = k;
                    while (--l > 0 && !offDiagIsZero(l, e))
                    {
                        ;
                    }
                    iter_++;

                    double q = d_[l];
                    if (strategy != ShiftStrategy.NoShift)
                    {
                        // calculated eigenvalue of 2x2 sub matrix of
                        // [ d_[k-1] e_[k] ]
                        // [  e_[k]  d_[k] ]
                        // which is closer to d_[k+1].
                        // FLOATING_POINT_EXCEPTION
                        double t1 = Math.Sqrt(
                            0.25 * (d_[k] * d_[k] + d_[k - 1] * d_[k - 1])
                            - 0.5 * d_[k - 1] * d_[k] + e[k] * e[k]);
                        double t2 = 0.5 * (d_[k] + d_[k - 1]);

                        double lambda = (Math.Abs(t2 + t1 - d_[k]) < Math.Abs(t2 - t1 - d_[k]))?
                                        t2 + t1 : t2 - t1;

                        if (strategy == ShiftStrategy.CloseEigenValue)
                        {
                            q -= lambda;
                        }
                        else
                        {
                            q -= ((k == n - 1)? 1.25 : 1.0) * lambda;
                        }
                    }

                    // the QR transformation
                    double sine   = 1.0;
                    double cosine = 1.0;
                    double u      = 0.0;

                    bool recoverUnderflow = false;
                    for (i = l + 1; i <= k && !recoverUnderflow; ++i)
                    {
                        double h = cosine * e[i];
                        double p = sine * e[i];

                        e[i - 1] = Math.Sqrt(p * p + q * q);
                        if (e[i - 1] != 0.0)
                        {
                            sine   = p / e[i - 1];
                            cosine = q / e[i - 1];

                            double g = d_[i - 1] - u;
                            double t = (d_[i] - g) * sine + 2 * cosine * h;

                            u         = sine * t;
                            d_[i - 1] = g + u;
                            q         = cosine * t - h;

                            for (int j = 0; j < ev_.rows(); ++j)
                            {
                                double tmp = ev_[j, i - 1];
                                ev_[j, i - 1] = sine * ev_[j, i] + cosine * tmp;
                                ev_[j, i]     = cosine * ev_[j, i] - sine * tmp;
                            }
                        }
                        else
                        {
                            // recover from underflow
                            d_[i - 1]       -= u;
                            e[l]             = 0.0;
                            recoverUnderflow = true;
                        }
                    }

                    if (!recoverUnderflow)
                    {
                        d_[k] -= u;
                        e[k]   = q;
                        e[l]   = 0.0;
                    }
                }
            }

            // sort (eigenvalues, eigenvectors),
            // code taken from symmetricSchureDecomposition.cpp
            List <KeyValuePair <double, List <double> > > temp = new List <KeyValuePair <double, List <double> > >(n);
            List <double> eigenVector = new List <double>(ev_.rows());

            for (i = 0; i < n; i++)
            {
                if (ev_.rows() > 0)
                {
                    //std::copy(ev_.column_begin(i),ev_.column_end(i), eigenVector.begin());
                    eigenVector = ev_.column(i);
                }

                temp[i] = new KeyValuePair <double, List <double> >(d_[i], eigenVector);
            }

            //std::sort(temp.begin(), temp.end(), std::greater<std::pair<Real, std::vector<Real> > >());
            temp.Sort();

            // first element is positive
            for (i = 0; i < n; i++)
            {
                d_[i] = temp[i].Key;
                double sign = 1.0;
                if (ev_.rows() > 0 && temp[i].Value[0] < 0.0)
                {
                    sign = -1.0;
                }
                for (int j = 0; j < ev_.rows(); ++j)
                {
                    ev_[j, i] = sign * temp[i].Value[j];
                }
            }
        }
        /*! \pre s must be symmetric */
        public SymmetricSchurDecomposition(Matrix s) {
            diagonal_ = new Vector(s.rows());
            eigenVectors_ = new Matrix(s.rows(), s.columns(), 0.0);

            if (!(s.rows() > 0 && s.columns() > 0)) 
                throw new ApplicationException( "null matrix given");
            if (s.rows()!=s.columns()) 
                throw new ApplicationException( "input matrix must be square");

            int size = s.rows();
            for (int q=0; q<size; q++) {
                diagonal_[q] = s[q,q];
                eigenVectors_[q,q] = 1.0;
            }
            Matrix ss = new Matrix(s);

            Vector tmpDiag = new Vector(diagonal_);
            Vector tmpAccumulate = new Vector(size, 0.0);
            double threshold, epsPrec = 1e-15;
            bool keeplooping = true;
            int maxIterations = 100, ite = 1;
            do {
                //main loop
                double sum = 0;
                for (int a=0; a<size-1; a++) {
                    for (int b=a+1; b<size; b++) {
                        sum += Math.Abs(ss[a,b]);
                    }
                }

                if (sum==0) {
                    keeplooping = false;
                } else {
                    /* To speed up computation a threshold is introduced to
                       make sure it is worthy to perform the Jacobi rotation
                    */
                    if (ite<5) threshold = 0.2*sum/(size*size);
                    else       threshold = 0.0;

                    int j, k, l;
                    for (j=0; j<size-1; j++) {
                        for (k=j+1; k<size; k++) {
                            double sine, rho, cosin, heig, tang, beta;
                            double smll = Math.Abs(ss[j,k]);
                            if(ite> 5 &&
                               smll<epsPrec*Math.Abs(diagonal_[j]) &&
                               smll<epsPrec*Math.Abs(diagonal_[k])) {
                                    ss[j,k] = 0;
                            } else if (Math.Abs(ss[j,k])>threshold) {
                                heig = diagonal_[k]-diagonal_[j];
                                if (smll<epsPrec*Math.Abs(heig)) {
                                    tang = ss[j,k]/heig;
                                } else {
                                    beta = 0.5*heig/ss[j,k];
                                    tang = 1.0/(Math.Abs(beta)+
                                        Math.Sqrt(1+beta*beta));
                                    if (beta<0)
                                        tang = -tang;
                                }
                                cosin = 1/Math.Sqrt(1+tang*tang);
                                sine = tang*cosin;
                                rho = sine/(1+cosin);
                                heig = tang*ss[j,k];
                                tmpAccumulate[j] -= heig;
                                tmpAccumulate[k] += heig;
                                diagonal_[j] -= heig;
                                diagonal_[k] += heig;
                                ss[j,k] = 0.0;
                                for (l=0; l+1<=j; l++)
                                    jacobiRotate_(ss, rho, sine, l, j, l, k);
                                for (l=j+1; l<=k-1; l++)
                                    jacobiRotate_(ss, rho, sine, j, l, l, k);
                                for (l=k+1; l<size; l++)
                                    jacobiRotate_(ss, rho, sine, j, l, k, l);
                                for (l=0;   l<size; l++)
                                    jacobiRotate_(eigenVectors_,
                                                      rho, sine, l, j, l, k);
                            }
                        }
                    }
                    for (k=0; k<size; k++) {
                        tmpDiag[k] += tmpAccumulate[k];
                        diagonal_[k] = tmpDiag[k];
                        tmpAccumulate[k] = 0.0;
                    }
                }
            } while (++ite<=maxIterations && keeplooping);

            if(!(ite<=maxIterations))
                throw new ApplicationException("Too many iterations (" + maxIterations + ") reached");


            // sort (eigenvalues, eigenvectors)
            List<KeyValuePair<double, Vector>> temp = new InitializedList<KeyValuePair<double, Vector>>(size);
            int row, col;
            for (col=0; col<size; col++) {
                Vector eigenVector = new Vector(size);
                eigenVectors_.column(col).ForEach((ii, xx) => eigenVector[ii] = xx);
                temp[col] = new KeyValuePair<double,Vector>(diagonal_[col], eigenVector);
            }
            // sort descending: std::greater
            temp.Sort((x, y) => y.Key.CompareTo(x.Key));
            double maxEv = temp[0].Key;
            for (col=0; col<size; col++) {
                // check for round-off errors
                diagonal_[col] = (Math.Abs(temp[col].Key/maxEv)<1e-16 ? 0.0 : temp[col].Key);
                double sign = 1.0;
                if (temp[col].Value[0]<0.0)
                    sign = -1.0;
                for (row=0; row<size; row++) {
                    eigenVectors_[row,col] = sign * temp[col].Value[row];
                }
            }
        }
Пример #6
0
      public TqrEigenDecomposition(Vector diag, Vector sub, EigenVectorCalculation calc = EigenVectorCalculation.WithEigenVector,
                            ShiftStrategy strategy = ShiftStrategy.CloseEigenValue)
      {
         iter_ = 0;
         d_ = new Vector(diag);
         
         int row = calc == EigenVectorCalculation.WithEigenVector ? d_.size() :
            calc == EigenVectorCalculation.WithoutEigenVector ? 0 : 1;

         ev_ = new Matrix(row, d_.size(), 0.0);
         
         int n = diag.size();

         Utils.QL_REQUIRE( n == sub.size() + 1, () => "Wrong dimensions" );

         Vector e = new Vector(sub);

         int i;
         for (i=0; i < ev_.rows(); ++i) 
         {
            ev_[i,i] = 1.0;
         }

         for (int k=n-1; k >=1; --k) 
         {
            while (!offDiagIsZero(k, e)) 
            {
                int l = k;
                while (--l > 0 && !offDiagIsZero(l,e));
                iter_++;

                double q = d_[l];
                if (strategy != ShiftStrategy.NoShift) 
                {
                    // calculated eigenvalue of 2x2 sub matrix of
                    // [ d_[k-1] e_[k] ]
                    // [  e_[k]  d_[k] ]
                    // which is closer to d_[k+1].
                    // FLOATING_POINT_EXCEPTION
                    double t1 = Math.Sqrt(
                                          0.25*(d_[k]*d_[k] + d_[k-1]*d_[k-1])
                                          - 0.5*d_[k-1]*d_[k] + e[k]*e[k]);
                    double t2 = 0.5*(d_[k]+d_[k-1]);

                    double lambda = (Math.Abs(t2+t1 - d_[k]) < Math.Abs(t2-t1 - d_[k]))?
                                     t2+t1 : t2-t1;

                    if (strategy == ShiftStrategy.CloseEigenValue) 
                    {
                        q-=lambda;
                    } 
                    else 
                    {
                        q-=((k==n-1)? 1.25 : 1.0)*lambda;
                    }
                }

                // the QR transformation
                double sine = 1.0;
                double cosine = 1.0;
                double u = 0.0;

                bool recoverUnderflow = false;
                for (i=l+1; i <= k && !recoverUnderflow; ++i) 
                {
                    double h = cosine*e[i];
                    double p = sine*e[i];

                    e[i-1] = Math.Sqrt(p*p+q*q);
                    if (e[i-1] != 0.0) {
                        sine = p/e[i-1];
                        cosine = q/e[i-1];

                        double g = d_[i-1]-u;
                        double t = (d_[i]-g)*sine+2*cosine*h;

                        u = sine*t;
                        d_[i-1] = g + u;
                        q = cosine*t - h;

                        for (int j=0; j < ev_.rows(); ++j) 
                        {
                            double tmp = ev_[j,i-1];
                            ev_[j,i-1] = sine*ev_[j,i] + cosine*tmp;
                            ev_[j,i] = cosine*ev_[j,i] - sine*tmp;
                        }
                    } 
                    else 
                    {
                        // recover from underflow
                        d_[i-1] -= u;
                        e[l] = 0.0;
                        recoverUnderflow = true;
                    }
                }

                if (!recoverUnderflow) {
                    d_[k] -= u;
                    e[k] = q;
                    e[l] = 0.0;
                }
            }
        }

        // sort (eigenvalues, eigenvectors),
        // code taken from symmetricSchureDecomposition.cpp
        List<KeyValuePair<double, List<double> > > temp = new List<KeyValuePair<double,List<double>>>(n);
        List<double> eigenVector = new List<double>(ev_.rows());
        for (i=0; i<n; i++) 
        {
            if (ev_.rows() > 0)
                //std::copy(ev_.column_begin(i),ev_.column_end(i), eigenVector.begin());
                eigenVector = ev_.column(i) ;

            temp[i] = new KeyValuePair<double,List<double>>(d_[i], eigenVector);
        }
       
        //std::sort(temp.begin(), temp.end(), std::greater<std::pair<Real, std::vector<Real> > >());
        temp.Sort();

        // first element is positive
        for (i=0; i<n; i++) {
            d_[i] = temp[i].Key;
            double sign = 1.0;
            if (ev_.rows() > 0 && temp[i].Value[0]<0.0)
                sign = -1.0;
            for (int j=0; j<ev_.rows(); ++j) {
                ev_[j,i] = sign * temp[i].Value[j];
            }
        }

      }
        /*! \pre s must be symmetric */
        public SymmetricSchurDecomposition(Matrix s)
        {
            diagonal_     = new Vector(s.rows());
            eigenVectors_ = new Matrix(s.rows(), s.columns(), 0.0);

            if (!(s.rows() > 0 && s.columns() > 0))
            {
                throw new ApplicationException("null matrix given");
            }
            if (s.rows() != s.columns())
            {
                throw new ApplicationException("input matrix must be square");
            }

            int size = s.rows();

            for (int q = 0; q < size; q++)
            {
                diagonal_[q]        = s[q, q];
                eigenVectors_[q, q] = 1.0;
            }
            Matrix ss = new Matrix(s);

            Vector tmpDiag = new Vector(diagonal_);
            Vector tmpAccumulate = new Vector(size, 0.0);
            double threshold, epsPrec = 1e-15;
            bool   keeplooping = true;
            int    maxIterations = 100, ite = 1;

            do
            {
                //main loop
                double sum = 0;
                for (int a = 0; a < size - 1; a++)
                {
                    for (int b = a + 1; b < size; b++)
                    {
                        sum += Math.Abs(ss[a, b]);
                    }
                }

                if (sum == 0)
                {
                    keeplooping = false;
                }
                else
                {
                    /* To speed up computation a threshold is introduced to
                     * make sure it is worthy to perform the Jacobi rotation
                     */
                    if (ite < 5)
                    {
                        threshold = 0.2 * sum / (size * size);
                    }
                    else
                    {
                        threshold = 0.0;
                    }

                    int j, k, l;
                    for (j = 0; j < size - 1; j++)
                    {
                        for (k = j + 1; k < size; k++)
                        {
                            double sine, rho, cosin, heig, tang, beta;
                            double smll = Math.Abs(ss[j, k]);
                            if (ite > 5 &&
                                smll < epsPrec * Math.Abs(diagonal_[j]) &&
                                smll < epsPrec * Math.Abs(diagonal_[k]))
                            {
                                ss[j, k] = 0;
                            }
                            else if (Math.Abs(ss[j, k]) > threshold)
                            {
                                heig = diagonal_[k] - diagonal_[j];
                                if (smll < epsPrec * Math.Abs(heig))
                                {
                                    tang = ss[j, k] / heig;
                                }
                                else
                                {
                                    beta = 0.5 * heig / ss[j, k];
                                    tang = 1.0 / (Math.Abs(beta) +
                                                  Math.Sqrt(1 + beta * beta));
                                    if (beta < 0)
                                    {
                                        tang = -tang;
                                    }
                                }
                                cosin             = 1 / Math.Sqrt(1 + tang * tang);
                                sine              = tang * cosin;
                                rho               = sine / (1 + cosin);
                                heig              = tang * ss[j, k];
                                tmpAccumulate[j] -= heig;
                                tmpAccumulate[k] += heig;
                                diagonal_[j]     -= heig;
                                diagonal_[k]     += heig;
                                ss[j, k]          = 0.0;
                                for (l = 0; l + 1 <= j; l++)
                                {
                                    jacobiRotate_(ss, rho, sine, l, j, l, k);
                                }
                                for (l = j + 1; l <= k - 1; l++)
                                {
                                    jacobiRotate_(ss, rho, sine, j, l, l, k);
                                }
                                for (l = k + 1; l < size; l++)
                                {
                                    jacobiRotate_(ss, rho, sine, j, l, k, l);
                                }
                                for (l = 0; l < size; l++)
                                {
                                    jacobiRotate_(eigenVectors_,
                                                  rho, sine, l, j, l, k);
                                }
                            }
                        }
                    }
                    for (k = 0; k < size; k++)
                    {
                        tmpDiag[k]      += tmpAccumulate[k];
                        diagonal_[k]     = tmpDiag[k];
                        tmpAccumulate[k] = 0.0;
                    }
                }
            } while (++ite <= maxIterations && keeplooping);

            if (!(ite <= maxIterations))
            {
                throw new ApplicationException("Too many iterations (" + maxIterations + ") reached");
            }


            // sort (eigenvalues, eigenvectors)
            List <KeyValuePair <double, Vector> > temp = new InitializedList <KeyValuePair <double, Vector> >(size);
            int row, col;

            for (col = 0; col < size; col++)
            {
                Vector eigenVector = new Vector(size);
                eigenVectors_.column(col).ForEach((ii, xx) => eigenVector[ii] = xx);
                temp[col] = new KeyValuePair <double, Vector>(diagonal_[col], eigenVector);
            }
            // sort descending: std::greater
            temp.Sort((x, y) => y.Key.CompareTo(x.Key));
            double maxEv = temp[0].Key;

            for (col = 0; col < size; col++)
            {
                // check for round-off errors
                diagonal_[col] = (Math.Abs(temp[col].Key / maxEv) < 1e-16 ? 0.0 : temp[col].Key);
                double sign = 1.0;
                if (temp[col].Value[0] < 0.0)
                {
                    sign = -1.0;
                }
                for (row = 0; row < size; row++)
                {
                    eigenVectors_[row, col] = sign * temp[col].Value[row];
                }
            }
        }