Exemplo n.º 1
0
Arquivo: lr.cpp Projeto: guyrt/WFUBMC
/*
 * Compute p-val using Wald test.
 * 
 * @param betas A vector of beta values
 * @param invInf Inverse of corresponding information matrix.
 * 
 * @return chiSq The test statistic
 * @return p-value.
 */
double LogisticRegression::getStats(const vector<double> &betas, const vector<vector<double> > invInf, double &chiS){
    
    if(betas.size() != invInf.size())
        return 2.0;
    
    int sz = betas.size()-1;
    
    // Make vector and matrix.
    alglib::real_1d_array vBetas;
    alglib::real_1d_array vTemp;
    alglib::real_1d_array singleNum;
    alglib::real_2d_array vInvInf;
    
    vBetas.setlength(sz+1);
    vTemp.setlength(sz+1);
    singleNum.setlength(1);
    vInvInf.setlength(sz+1, sz+1);
    
    for(unsigned int i=0;i < betas.size();i++){
        vBetas(i) = betas.at(i);
        for(unsigned int j=0;j < betas.size() ; j++){
            vInvInf(i,j) = invInf.at(i).at(j);
        }
    }
    
    alglib::matinvreport report;
    alglib::ae_int_t reportInfo;
    rmatrixinverse(vInvInf, reportInfo, report);
    if(reportInfo != 1) return 2.0;
    
    // Check condition number.
    if (report.r1 < condition_number_limit){
        throw ConditionNumberEx(1.0/report.r1);
    }
    
    // betas' * vInvInf * betas  (vInvInf has been inverted)
    matrixvectormultiply(vInvInf,0,sz,0,sz,false,
                        vBetas,0,sz,1.0,vTemp,0,sz,0.0);
    
    alglib::real_2d_array vBetasTemp;
    vBetasTemp.setlength(sz+1,1);
    for(int i=0;i<=sz;i++)
        vBetasTemp(i,0) = vBetas(i);
    
    matrixvectormultiply(vBetasTemp,0,sz,0,0,true,
                        vTemp,0,sz,1.0,singleNum,0,0,0.0);
    
    chiS = singleNum(0);
    
    try{
        return Statistics::chi2prob(chiS, betas.size());
    }catch(StatsException){
        chiS = -1;
        return 2.0;
    }
    
}
Exemplo n.º 2
0
void internalschurdecomposition(ap::real_2d_array& h,
     int n,
     int tneeded,
     int zneeded,
     ap::real_1d_array& wr,
     ap::real_1d_array& wi,
     ap::real_2d_array& z,
     int& info)
{
    ap::real_1d_array work;
    int i;
    int i1;
    int i2;
    int ierr;
    int ii;
    int itemp;
    int itn;
    int its;
    int j;
    int k;
    int l;
    int maxb;
    int nr;
    int ns;
    int nv;
    double absw;
    double ovfl;
    double smlnum;
    double tau;
    double temp;
    double tst1;
    double ulp;
    double unfl;
    ap::real_2d_array s;
    ap::real_1d_array v;
    ap::real_1d_array vv;
    ap::real_1d_array workc1;
    ap::real_1d_array works1;
    ap::real_1d_array workv3;
    ap::real_1d_array tmpwr;
    ap::real_1d_array tmpwi;
    bool initz;
    bool wantt;
    bool wantz;
    double cnst;
    bool failflag;
    int p1;
    int p2;
    int p3;
    int p4;
    double vt;

    
    //
    // Set the order of the multi-shift QR algorithm to be used.
    // If you want to tune algorithm, change this values
    //
    ns = 12;
    maxb = 50;
    
    //
    // Now 2 < NS <= MAXB < NH.
    //
    maxb = ap::maxint(3, maxb);
    ns = ap::minint(maxb, ns);
    
    //
    // Initialize
    //
    cnst = 1.5;
    work.setbounds(1, ap::maxint(n, 1));
    s.setbounds(1, ns, 1, ns);
    v.setbounds(1, ns+1);
    vv.setbounds(1, ns+1);
    wr.setbounds(1, ap::maxint(n, 1));
    wi.setbounds(1, ap::maxint(n, 1));
    workc1.setbounds(1, 1);
    works1.setbounds(1, 1);
    workv3.setbounds(1, 3);
    tmpwr.setbounds(1, ap::maxint(n, 1));
    tmpwi.setbounds(1, ap::maxint(n, 1));
    ap::ap_error::make_assertion(n>=0, "InternalSchurDecomposition: incorrect N!");
    ap::ap_error::make_assertion(tneeded==0||tneeded==1, "InternalSchurDecomposition: incorrect TNeeded!");
    ap::ap_error::make_assertion(zneeded==0||zneeded==1||zneeded==2, "InternalSchurDecomposition: incorrect ZNeeded!");
    wantt = tneeded==1;
    initz = zneeded==2;
    wantz = zneeded!=0;
    info = 0;
    
    //
    // Initialize Z, if necessary
    //
    if( initz )
    {
        z.setbounds(1, n, 1, n);
        for(i = 1; i <= n; i++)
        {
            for(j = 1; j <= n; j++)
            {
                if( i==j )
                {
                    z(i,j) = 1;
                }
                else
                {
                    z(i,j) = 0;
                }
            }
        }
    }
    
    //
    // Quick return if possible
    //
    if( n==0 )
    {
        return;
    }
    if( n==1 )
    {
        wr(1) = h(1,1);
        wi(1) = 0;
        return;
    }
    
    //
    // Set rows and columns 1 to N to zero below the first
    // subdiagonal.
    //
    for(j = 1; j <= n-2; j++)
    {
        for(i = j+2; i <= n; i++)
        {
            h(i,j) = 0;
        }
    }
    
    //
    // Test if N is sufficiently small
    //
    if( ns<=2||ns>n||maxb>=n )
    {
        
        //
        // Use the standard double-shift algorithm
        //
        internalauxschur(wantt, wantz, n, 1, n, h, wr, wi, 1, n, z, work, workv3, workc1, works1, info);
        
        //
        // fill entries under diagonal blocks of T with zeros
        //
        if( wantt )
        {
            j = 1;
            while(j<=n)
            {
                if( wi(j)==0 )
                {
                    for(i = j+1; i <= n; i++)
                    {
                        h(i,j) = 0;
                    }
                    j = j+1;
                }
                else
                {
                    for(i = j+2; i <= n; i++)
                    {
                        h(i,j) = 0;
                        h(i,j+1) = 0;
                    }
                    j = j+2;
                }
            }
        }
        return;
    }
    unfl = ap::minrealnumber;
    ovfl = 1/unfl;
    ulp = 2*ap::machineepsilon;
    smlnum = unfl*(n/ulp);
    
    //
    // I1 and I2 are the indices of the first row and last column of H
    // to which transformations must be applied. If eigenvalues only are
    // being computed, I1 and I2 are set inside the main loop.
    //
    if( wantt )
    {
        i1 = 1;
        i2 = n;
    }
    
    //
    // ITN is the total number of multiple-shift QR iterations allowed.
    //
    itn = 30*n;
    
    //
    // The main loop begins here. I is the loop index and decreases from
    // IHI to ILO in steps of at most MAXB. Each iteration of the loop
    // works with the active submatrix in rows and columns L to I.
    // Eigenvalues I+1 to IHI have already converged. Either L = ILO or
    // H(L,L-1) is negligible so that the matrix splits.
    //
    i = n;
    while(true)
    {
        l = 1;
        if( i<1 )
        {
            
            //
            // fill entries under diagonal blocks of T with zeros
            //
            if( wantt )
            {
                j = 1;
                while(j<=n)
                {
                    if( wi(j)==0 )
                    {
                        for(i = j+1; i <= n; i++)
                        {
                            h(i,j) = 0;
                        }
                        j = j+1;
                    }
                    else
                    {
                        for(i = j+2; i <= n; i++)
                        {
                            h(i,j) = 0;
                            h(i,j+1) = 0;
                        }
                        j = j+2;
                    }
                }
            }
            
            //
            // Exit
            //
            return;
        }
        
        //
        // Perform multiple-shift QR iterations on rows and columns ILO to I
        // until a submatrix of order at most MAXB splits off at the bottom
        // because a subdiagonal element has become negligible.
        //
        failflag = true;
        for(its = 0; its <= itn; its++)
        {
            
            //
            // Look for a single small subdiagonal element.
            //
            for(k = i; k >= l+1; k--)
            {
                tst1 = fabs(h(k-1,k-1))+fabs(h(k,k));
                if( tst1==0 )
                {
                    tst1 = upperhessenberg1norm(h, l, i, l, i, work);
                }
                if( fabs(h(k,k-1))<=ap::maxreal(ulp*tst1, smlnum) )
                {
                    break;
                }
            }
            l = k;
            if( l>1 )
            {
                
                //
                // H(L,L-1) is negligible.
                //
                h(l,l-1) = 0;
            }
            
            //
            // Exit from loop if a submatrix of order <= MAXB has split off.
            //
            if( l>=i-maxb+1 )
            {
                failflag = false;
                break;
            }
            
            //
            // Now the active submatrix is in rows and columns L to I. If
            // eigenvalues only are being computed, only the active submatrix
            // need be transformed.
            //
            if( !wantt )
            {
                i1 = l;
                i2 = i;
            }
            if( its==20||its==30 )
            {
                
                //
                // Exceptional shifts.
                //
                for(ii = i-ns+1; ii <= i; ii++)
                {
                    wr(ii) = cnst*(fabs(h(ii,ii-1))+fabs(h(ii,ii)));
                    wi(ii) = 0;
                }
            }
            else
            {
                
                //
                // Use eigenvalues of trailing submatrix of order NS as shifts.
                //
                copymatrix(h, i-ns+1, i, i-ns+1, i, s, 1, ns, 1, ns);
                internalauxschur(false, false, ns, 1, ns, s, tmpwr, tmpwi, 1, ns, z, work, workv3, workc1, works1, ierr);
                for(p1 = 1; p1 <= ns; p1++)
                {
                    wr(i-ns+p1) = tmpwr(p1);
                    wi(i-ns+p1) = tmpwi(p1);
                }
                if( ierr>0 )
                {
                    
                    //
                    // If DLAHQR failed to compute all NS eigenvalues, use the
                    // unconverged diagonal elements as the remaining shifts.
                    //
                    for(ii = 1; ii <= ierr; ii++)
                    {
                        wr(i-ns+ii) = s(ii,ii);
                        wi(i-ns+ii) = 0;
                    }
                }
            }
            
            //
            // Form the first column of (G-w(1)) (G-w(2)) . . . (G-w(ns))
            // where G is the Hessenberg submatrix H(L:I,L:I) and w is
            // the vector of shifts (stored in WR and WI). The result is
            // stored in the local array V.
            //
            v(1) = 1;
            for(ii = 2; ii <= ns+1; ii++)
            {
                v(ii) = 0;
            }
            nv = 1;
            for(j = i-ns+1; j <= i; j++)
            {
                if( wi(j)>=0 )
                {
                    if( wi(j)==0 )
                    {
                        
                        //
                        // real shift
                        //
                        p1 = nv+1;
                        ap::vmove(&vv(1), &v(1), ap::vlen(1,p1));
                        matrixvectormultiply(h, l, l+nv, l, l+nv-1, false, vv, 1, nv, 1.0, v, 1, nv+1, -wr(j));
                        nv = nv+1;
                    }
                    else
                    {
                        if( wi(j)>0 )
                        {
                            
                            //
                            // complex conjugate pair of shifts
                            //
                            p1 = nv+1;
                            ap::vmove(&vv(1), &v(1), ap::vlen(1,p1));
                            matrixvectormultiply(h, l, l+nv, l, l+nv-1, false, v, 1, nv, 1.0, vv, 1, nv+1, -2*wr(j));
                            itemp = vectoridxabsmax(vv, 1, nv+1);
                            temp = 1/ap::maxreal(fabs(vv(itemp)), smlnum);
                            p1 = nv+1;
                            ap::vmul(&vv(1), ap::vlen(1,p1), temp);
                            absw = pythag2(wr(j), wi(j));
                            temp = temp*absw*absw;
                            matrixvectormultiply(h, l, l+nv+1, l, l+nv, false, vv, 1, nv+1, 1.0, v, 1, nv+2, temp);
                            nv = nv+2;
                        }
                    }
                    
                    //
                    // Scale V(1:NV) so that max(abs(V(i))) = 1. If V is zero,
                    // reset it to the unit vector.
                    //
                    itemp = vectoridxabsmax(v, 1, nv);
                    temp = fabs(v(itemp));
                    if( temp==0 )
                    {
                        v(1) = 1;
                        for(ii = 2; ii <= nv; ii++)
                        {
                            v(ii) = 0;
                        }
                    }
                    else
                    {
                        temp = ap::maxreal(temp, smlnum);
                        vt = 1/temp;
                        ap::vmul(&v(1), ap::vlen(1,nv), vt);
                    }
                }
            }
            
            //
            // Multiple-shift QR step
            //
            for(k = l; k <= i-1; k++)
            {
                
                //
                // The first iteration of this loop determines a reflection G
                // from the vector V and applies it from left and right to H,
                // thus creating a nonzero bulge below the subdiagonal.
                //
                // Each subsequent iteration determines a reflection G to
                // restore the Hessenberg form in the (K-1)th column, and thus
                // chases the bulge one step toward the bottom of the active
                // submatrix. NR is the order of G.
                //
                nr = ap::minint(ns+1, i-k+1);
                if( k>l )
                {
                    p1 = k-1;
                    p2 = k+nr-1;
                    ap::vmove(v.getvector(1, nr), h.getcolumn(p1, k, p2));
                }
                generatereflection(v, nr, tau);
                if( k>l )
                {
                    h(k,k-1) = v(1);
                    for(ii = k+1; ii <= i; ii++)
                    {
                        h(ii,k-1) = 0;
                    }
                }
                v(1) = 1;
                
                //
                // Apply G from the left to transform the rows of the matrix in
                // columns K to I2.
                //
                applyreflectionfromtheleft(h, tau, v, k, k+nr-1, k, i2, work);
                
                //
                // Apply G from the right to transform the columns of the
                // matrix in rows I1 to min(K+NR,I).
                //
                applyreflectionfromtheright(h, tau, v, i1, ap::minint(k+nr, i), k, k+nr-1, work);
                if( wantz )
                {
                    
                    //
                    // Accumulate transformations in the matrix Z
                    //
                    applyreflectionfromtheright(z, tau, v, 1, n, k, k+nr-1, work);
                }
            }
        }
        
        //
        // Failure to converge in remaining number of iterations
        //
        if( failflag )
        {
            info = i;
            return;
        }
        
        //
        // A submatrix of order <= MAXB in rows and columns L to I has split
        // off. Use the double-shift QR algorithm to handle it.
        //
        internalauxschur(wantt, wantz, n, l, i, h, wr, wi, 1, n, z, work, workv3, workc1, works1, info);
        if( info>0 )
        {
            return;
        }
        
        //
        // Decrement number of remaining iterations, and return to start of
        // the main loop with a new value of I.
        //
        itn = itn-its;
        i = l-1;
    }
}
Exemplo n.º 3
0
bool generalizedsymmetricdefiniteevdreduce(ap::real_2d_array& a,
        int n,
        bool isuppera,
        const ap::real_2d_array& b,
        bool isupperb,
        int problemtype,
        ap::real_2d_array& r,
        bool& isupperr)
{
    bool result;
    ap::real_2d_array t;
    ap::real_1d_array w1;
    ap::real_1d_array w2;
    ap::real_1d_array w3;
    int i;
    int j;
    double v;

    ap::ap_error::make_assertion(n>0, "GeneralizedSymmetricDefiniteEVDReduce: N<=0!");
    ap::ap_error::make_assertion(problemtype==1||problemtype==2||problemtype==3, "GeneralizedSymmetricDefiniteEVDReduce: incorrect ProblemType!");
    result = true;

    //
    // Problem 1:  A*x = lambda*B*x
    //
    // Reducing to:
    //     C*y = lambda*y
    //     C = L^(-1) * A * L^(-T)
    //     x = L^(-T) * y
    //
    if( problemtype==1 )
    {

        //
        // Factorize B in T: B = LL'
        //
        t.setbounds(1, n, 1, n);
        if( isupperb )
        {
            for(i = 1; i <= n; i++)
            {
                ap::vmove(t.getcolumn(i, i, n), b.getrow(i, i, n));
            }
        }
        else
        {
            for(i = 1; i <= n; i++)
            {
                ap::vmove(&t(i, 1), &b(i, 1), ap::vlen(1,i));
            }
        }
        if( !choleskydecomposition(t, n, false) )
        {
            result = false;
            return result;
        }

        //
        // Invert L in T
        //
        if( !invtriangular(t, n, false, false) )
        {
            result = false;
            return result;
        }

        //
        // Build L^(-1) * A * L^(-T) in R
        //
        w1.setbounds(1, n);
        w2.setbounds(1, n);
        r.setbounds(1, n, 1, n);
        for(j = 1; j <= n; j++)
        {

            //
            // Form w2 = A * l'(j) (here l'(j) is j-th column of L^(-T))
            //
            ap::vmove(&w1(1), &t(j, 1), ap::vlen(1,j));
            symmetricmatrixvectormultiply(a, isuppera, 1, j, w1, 1.0, w2);
            if( isuppera )
            {
                matrixvectormultiply(a, 1, j, j+1, n, true, w1, 1, j, 1.0, w2, j+1, n, 0.0);
            }
            else
            {
                matrixvectormultiply(a, j+1, n, 1, j, false, w1, 1, j, 1.0, w2, j+1, n, 0.0);
            }

            //
            // Form l(i)*w2 (here l(i) is i-th row of L^(-1))
            //
            for(i = 1; i <= n; i++)
            {
                v = ap::vdotproduct(&t(i, 1), &w2(1), ap::vlen(1,i));
                r(i,j) = v;
            }
        }

        //
        // Copy R to A
        //
        for(i = 1; i <= n; i++)
        {
            ap::vmove(&a(i, 1), &r(i, 1), ap::vlen(1,n));
        }

        //
        // Copy L^(-1) from T to R and transpose
        //
        isupperr = true;
        for(i = 1; i <= n; i++)
        {
            for(j = 1; j <= i-1; j++)
            {
                r(i,j) = 0;
            }
        }
        for(i = 1; i <= n; i++)
        {
            ap::vmove(r.getrow(i, i, n), t.getcolumn(i, i, n));
        }
        return result;
    }

    //
    // Problem 2:  A*B*x = lambda*x
    // or
    // problem 3:  B*A*x = lambda*x
    //
    // Reducing to:
    //     C*y = lambda*y
    //     C = U * A * U'
    //     B = U'* U
    //
    if( problemtype==2||problemtype==3 )
    {

        //
        // Factorize B in T: B = U'*U
        //
        t.setbounds(1, n, 1, n);
        if( isupperb )
        {
            for(i = 1; i <= n; i++)
            {
                ap::vmove(&t(i, i), &b(i, i), ap::vlen(i,n));
            }
        }
        else
        {
            for(i = 1; i <= n; i++)
            {
                ap::vmove(t.getrow(i, i, n), b.getcolumn(i, i, n));
            }
        }
        if( !choleskydecomposition(t, n, true) )
        {
            result = false;
            return result;
        }

        //
        // Build U * A * U' in R
        //
        w1.setbounds(1, n);
        w2.setbounds(1, n);
        w3.setbounds(1, n);
        r.setbounds(1, n, 1, n);
        for(j = 1; j <= n; j++)
        {

            //
            // Form w2 = A * u'(j) (here u'(j) is j-th column of U')
            //
            ap::vmove(&w1(1), &t(j, j), ap::vlen(1,n-j+1));
            symmetricmatrixvectormultiply(a, isuppera, j, n, w1, 1.0, w3);
            ap::vmove(&w2(j), &w3(1), ap::vlen(j,n));
            ap::vmove(&w1(j), &t(j, j), ap::vlen(j,n));
            if( isuppera )
            {
                matrixvectormultiply(a, 1, j-1, j, n, false, w1, j, n, 1.0, w2, 1, j-1, 0.0);
            }
            else
            {
                matrixvectormultiply(a, j, n, 1, j-1, true, w1, j, n, 1.0, w2, 1, j-1, 0.0);
            }

            //
            // Form u(i)*w2 (here u(i) is i-th row of U)
            //
            for(i = 1; i <= n; i++)
            {
                v = ap::vdotproduct(&t(i, i), &w2(i), ap::vlen(i,n));
                r(i,j) = v;
            }
        }

        //
        // Copy R to A
        //
        for(i = 1; i <= n; i++)
        {
            ap::vmove(&a(i, 1), &r(i, 1), ap::vlen(1,n));
        }
        if( problemtype==2 )
        {

            //
            // Invert U in T
            //
            if( !invtriangular(t, n, true, false) )
            {
                result = false;
                return result;
            }

            //
            // Copy U^-1 from T to R
            //
            isupperr = true;
            for(i = 1; i <= n; i++)
            {
                for(j = 1; j <= i-1; j++)
                {
                    r(i,j) = 0;
                }
            }
            for(i = 1; i <= n; i++)
            {
                ap::vmove(&r(i, i), &t(i, i), ap::vlen(i,n));
            }
        }
        else
        {

            //
            // Copy U from T to R and transpose
            //
            isupperr = false;
            for(i = 1; i <= n; i++)
            {
                for(j = i+1; j <= n; j++)
                {
                    r(i,j) = 0;
                }
            }
            for(i = 1; i <= n; i++)
            {
                ap::vmove(r.getcolumn(i, i, n), t.getrow(i, i, n));
            }
        }
    }
    return result;
}
Exemplo n.º 4
0
/**
 * Compute the ordinary least squares estimation of the solution to a linear regression
 * 
 * @param data The regression input.  Each inner vector should be a single variable (so column maj order)
 * @param response The response variable.
 * @return betas The estimate of regression coefficients
 */
vector<double> LinearRegression::leastSquares(const vector<vector<double> > &data, const vector<double> &response){
	
	int sz = data.size();
	if(sz < 0) throw LinearRegressionException();
	
	int indivSz = response.size();
	
	vector<double> betas;
	
	alglib::real_1d_array vecResp;
	alglib::real_1d_array vecBetas;
	alglib::real_2d_array vecData;
	alglib::real_2d_array tempSquare;
	alglib::real_1d_array tempWork;
	
	vecResp.setlength(indivSz);
	vecBetas.setlength(sz);
	vecData.setlength(indivSz,sz);
	tempSquare.setlength(sz,sz);
	tempWork.setlength(indivSz+1);
	
	// Transfer into the matrices.
	for(unsigned int i=0;i<data.size();i++){
		for(unsigned int j=0;j < data.at(0).size();j++){
			vecData(j,i) = data.at(i).at(j);
		}
	}
	for(unsigned int i=0;i<response.size();i++)
		vecResp(i) = response.at(i);
	
	
	/// X'*X
	matrixmatrixmultiply(vecData,0,indivSz-1,0,sz-1,true,
						vecData,0,indivSz-1,0,sz-1,false,1.0,
						tempSquare,0,sz-1,0,sz-1,0.0,tempWork);
	
	alglib::matinvreport report;

	alglib::ae_int_t reportInfo ;
	rmatrixinverse(tempSquare, reportInfo, report);
	
	if(reportInfo != 1){
		throw LinearRegressionException();
	}
	if (report.r1 > LINEAR_REGRESSION_CONDITION_NUMBER_LIMIT){
		throw ConditionNumberEx(1.0/report.r1);
	}
		
	/// X'*beta
	matrixvectormultiply(vecData,0,indivSz-1,0,sz-1,true,
						vecResp,0,indivSz-1,1.0,
						tempWork,0,sz-1,0.0);
						
	/// tempSquare * tempWork
	matrixvectormultiply(tempSquare,0,sz-1,0,sz-1,false,
						tempWork,0,sz-1,1.0,
						vecBetas,0,sz-1,0.0);
	
	for(int i=0;i<sz;i++)
		betas.push_back(vecBetas(i));
	
	return betas;
}
Exemplo n.º 5
0
bool GetScore(ap::template_2d_array<float,true>& Responses, 
              ap::template_1d_array<unsigned short int, true>& Code,
              parameters tMUD,
              ap::template_1d_array<short int,true>& trialnr,
              ap::template_1d_array<double,true>& windowlen, 
              int numchannels,
              int NumberOfSequences,
              int NumberOfChoices,
              int mode,
              ap::real_2d_array &pscore)

{
///////////////////////////////////////////////////////////////////////
// Section: Define variables
int row_Responses, col_Responses, row_MUD, col_MUD,
  dslen, count, max, NumberOfEpochs, numVariables;

bool flag = true;

ap::real_2d_array Responses_double;
ap::template_2d_array<float, true> Responses_copy;
ap::real_2d_array DATA;
ap::real_2d_array tmp_MUD;
ap::real_1d_array score;
ap::real_1d_array weights;

vector<short int> trial;
//vector<short int> trial_copy;
vector<int> range;
vector<int> code_indx;
vector<short int>::iterator it;

///////////////////////////////////////////////////////////////////////
// Section: Get Dimmensions 
row_Responses = Responses.gethighbound(1)+1;
col_Responses = Responses.gethighbound(0)+1;
row_MUD = tMUD.MUD.gethighbound(1)+1;
col_MUD = tMUD.MUD.gethighbound(0)+1;

///////////////////////////////////////////////////////////////////////
// Section: Extract from the signal only the channels containing the "in" variables
numVariables = static_cast<int>( col_Responses/static_cast<double>( numchannels ) );
Responses_copy.setbounds(0, row_Responses-1, 0, numVariables*(tMUD.channels.gethighbound(1)+1)-1);
Responses_double.setbounds(0, row_Responses-1, 0, numVariables*(tMUD.channels.gethighbound(1)+1)-1);

for (int i=0; i<row_Responses; i++)
{
  for (int j=0; j<tMUD.channels.gethighbound(1)+1; j++)
  {
    ap::vmove(Responses_copy.getrow(i, j*numVariables, ((j+1)*numVariables)-1), 
              Responses.getrow(i, static_cast<int>(tMUD.channels(j)-1)*numVariables, 
                                  static_cast<int>(tMUD.channels(j)*numVariables)-1));
  }
}

for (int i=0; i<row_Responses; i++)
{
    for (int j=0; j<numVariables*(tMUD.channels.gethighbound(1)+1); j++) 
      Responses_double(i,j) = static_cast<double>( Responses_copy(i,j) );
}

for (int i=0; i<row_Responses; i++)
   trial.push_back(trialnr(i)); 

///////////////////////////////////////////////////////////////////////
// Section: Downsampling the MUD  
dslen = ap::iceil((row_MUD-1)/tMUD.DF)+1;
tmp_MUD.setbounds(0, dslen, 0, col_MUD-1);
for (int j=0; j<col_MUD; j++)
{
  for (int i=0; i<dslen; i++)
  {
    if (j==0)
      tmp_MUD(i,0) = tMUD.MUD(i*tMUD.DF, 0)-1;

    if (j==1)
    {
      tmp_MUD(i,1) = tMUD.MUD(i*tMUD.DF, 1) - windowlen(0);
      tmp_MUD(i,1) = ap::ifloor(tmp_MUD(i,1)/tMUD.DF)+1;
      tmp_MUD(i,1) = tmp_MUD(i,1) + (tmp_MUD(i,0)*numVariables);
    }
    if (j==2)
      tmp_MUD(i,2) = tMUD.MUD(i*tMUD.DF, 2);
  }
}
///////////////////////////////////////////////////////////////////////
// Section: Computing the score 
DATA.setbounds(0, row_Responses-1, 0, dslen-1);
score.setbounds(0, row_Responses-1);
weights.setbounds(0, dslen-1);

double valor;
for (int i=0; i<dslen; i++)
{
  valor = tmp_MUD(i,1); 
  ap::vmove(DATA.getcolumn(i, 0, row_Responses-1), Responses_double.getcolumn(static_cast<int>( tmp_MUD(i,1) ), 0, row_Responses-1));
  valor = DATA(0,i); 
  weights(i) = tmp_MUD(i,2);
}

matrixvectormultiply(DATA, 0, row_Responses-1, 0, dslen-1, FALSE, weights, 0, dslen-1, 1, score, 0, row_Responses-1, 0);


///////////////////////////////////////////////////////////////////////
// Section: Make sure that the epochs are not outside of the boundaries 
#if 0 // jm Mar 18, 2011
trial_copy = trial;
it = unique(trial_copy.begin(), trial_copy.end());
trial_copy.resize(it-trial_copy.begin());

max = *max_element(trial_copy.begin(), trial_copy.end());
#else // jm
max = *max_element(trial.begin(), trial.end());
#endif // jm

count = 0;
for (size_t i=0; i<trial.size(); i++)
{
  if (trial[i] == max)
    count++;
}

if (count == NumberOfSequences*NumberOfChoices)
  NumberOfEpochs = *max_element(trial.begin(), trial.end());
else
  NumberOfEpochs = *max_element(trial.begin(), trial.end())-1;

///////////////////////////////////////////////////////////////////////
// Section: Create a matrix with the scores for each sequence 
pscore.setbounds(0, NumberOfChoices-1, 0, (NumberOfEpochs*NumberOfSequences)-1);
for (int i=0; i<NumberOfEpochs; i++)
{
  for (size_t j=0; j<trial.size(); j++)
  {
    if (trial[j] == i+1)
      range.push_back(static_cast<int>(j));
  }
  if ((range.size() != 0) && (range.size() == NumberOfSequences*NumberOfChoices))
  {
    for (int k=0; k<NumberOfChoices; k++)
    {
      for (size_t j=0; j<range.size(); j++)
      {
        if (Code(range[j]) == k+1)
          code_indx.push_back(range[j]);
      }
      for (size_t j=0; j<code_indx.size(); j++)
      {
        if (code_indx.size() == NumberOfSequences)
          pscore(k,static_cast<int>((i*NumberOfSequences)+j)) = score(code_indx[j]);
      }
      code_indx.clear();
    }
	flag = true;
  }
  else
  {
	  flag = false;
	  break;
  }
  range.clear(); 
}
return flag;
}
Exemplo n.º 6
0
bool testblas(bool silent)
{
    bool result;
    int pass;
    int passcount;
    int n;
    int i;
    int i1;
    int i2;
    int j;
    int j1;
    int j2;
    int l;
    int k;
    int r;
    int i3;
    int j3;
    int col1;
    int col2;
    int row1;
    int row2;
    ap::real_1d_array x1;
    ap::real_1d_array x2;
    ap::real_2d_array a;
    ap::real_2d_array b;
    ap::real_2d_array c1;
    ap::real_2d_array c2;
    double err;
    double e1;
    double e2;
    double e3;
    double v;
    double scl1;
    double scl2;
    double scl3;
    bool was1;
    bool was2;
    bool trans1;
    bool trans2;
    double threshold;
    bool n2errors;
    bool hsnerrors;
    bool amaxerrors;
    bool mverrors;
    bool iterrors;
    bool cterrors;
    bool mmerrors;
    bool waserrors;

    n2errors = false;
    amaxerrors = false;
    hsnerrors = false;
    mverrors = false;
    iterrors = false;
    cterrors = false;
    mmerrors = false;
    waserrors = false;
    threshold = 10000*ap::machineepsilon;
    
    //
    // Test Norm2
    //
    passcount = 1000;
    e1 = 0;
    e2 = 0;
    e3 = 0;
    scl2 = 0.5*ap::maxrealnumber;
    scl3 = 2*ap::minrealnumber;
    for(pass = 1; pass <= passcount; pass++)
    {
        n = 1+ap::randominteger(1000);
        i1 = ap::randominteger(10);
        i2 = n+i1-1;
        x1.setbounds(i1, i2);
        x2.setbounds(i1, i2);
        for(i = i1; i <= i2; i++)
        {
            x1(i) = 2*ap::randomreal()-1;
        }
        v = 0;
        for(i = i1; i <= i2; i++)
        {
            v = v+ap::sqr(x1(i));
        }
        v = sqrt(v);
        e1 = ap::maxreal(e1, fabs(v-vectornorm2(x1, i1, i2)));
        for(i = i1; i <= i2; i++)
        {
            x2(i) = scl2*x1(i);
        }
        e2 = ap::maxreal(e2, fabs(v*scl2-vectornorm2(x2, i1, i2)));
        for(i = i1; i <= i2; i++)
        {
            x2(i) = scl3*x1(i);
        }
        e3 = ap::maxreal(e3, fabs(v*scl3-vectornorm2(x2, i1, i2)));
    }
    e2 = e2/scl2;
    e3 = e3/scl3;
    n2errors = ap::fp_greater_eq(e1,threshold)||ap::fp_greater_eq(e2,threshold)||ap::fp_greater_eq(e3,threshold);
    
    //
    // Testing VectorAbsMax, Column/Row AbsMax
    //
    x1.setbounds(1, 5);
    x1(1) = 2.0;
    x1(2) = 0.2;
    x1(3) = -1.3;
    x1(4) = 0.7;
    x1(5) = -3.0;
    amaxerrors = vectoridxabsmax(x1, 1, 5)!=5||vectoridxabsmax(x1, 1, 4)!=1||vectoridxabsmax(x1, 2, 4)!=3;
    n = 30;
    x1.setbounds(1, n);
    a.setbounds(1, n, 1, n);
    for(i = 1; i <= n; i++)
    {
        for(j = 1; j <= n; j++)
        {
            a(i,j) = 2*ap::randomreal()-1;
        }
    }
    was1 = false;
    was2 = false;
    for(pass = 1; pass <= 1000; pass++)
    {
        j = 1+ap::randominteger(n);
        i1 = 1+ap::randominteger(n);
        i2 = i1+ap::randominteger(n+1-i1);
        ap::vmove(x1.getvector(i1, i2), a.getcolumn(j, i1, i2));
        if( vectoridxabsmax(x1, i1, i2)!=columnidxabsmax(a, i1, i2, j) )
        {
            was1 = true;
        }
        i = 1+ap::randominteger(n);
        j1 = 1+ap::randominteger(n);
        j2 = j1+ap::randominteger(n+1-j1);
        ap::vmove(&x1(j1), &a(i, j1), ap::vlen(j1,j2));
        if( vectoridxabsmax(x1, j1, j2)!=rowidxabsmax(a, j1, j2, i) )
        {
            was2 = true;
        }
    }
    amaxerrors = amaxerrors||was1||was2;
    
    //
    // Testing upper Hessenberg 1-norm
    //
    a.setbounds(1, 3, 1, 3);
    x1.setbounds(1, 3);
    a(1,1) = 2;
    a(1,2) = 3;
    a(1,3) = 1;
    a(2,1) = 4;
    a(2,2) = -5;
    a(2,3) = 8;
    a(3,1) = 99;
    a(3,2) = 3;
    a(3,3) = 1;
    hsnerrors = ap::fp_greater(fabs(upperhessenberg1norm(a, 1, 3, 1, 3, x1)-11),threshold);
    
    //
    // Testing MatrixVectorMultiply
    //
    a.setbounds(2, 3, 3, 5);
    x1.setbounds(1, 3);
    x2.setbounds(1, 2);
    a(2,3) = 2;
    a(2,4) = -1;
    a(2,5) = -1;
    a(3,3) = 1;
    a(3,4) = -2;
    a(3,5) = 2;
    x1(1) = 1;
    x1(2) = 2;
    x1(3) = 1;
    x2(1) = -1;
    x2(2) = -1;
    matrixvectormultiply(a, 2, 3, 3, 5, false, x1, 1, 3, 1.0, x2, 1, 2, 1.0);
    matrixvectormultiply(a, 2, 3, 3, 5, true, x2, 1, 2, 1.0, x1, 1, 3, 1.0);
    e1 = fabs(x1(1)+5)+fabs(x1(2)-8)+fabs(x1(3)+1)+fabs(x2(1)+2)+fabs(x2(2)+2);
    x1(1) = 1;
    x1(2) = 2;
    x1(3) = 1;
    x2(1) = -1;
    x2(2) = -1;
    matrixvectormultiply(a, 2, 3, 3, 5, false, x1, 1, 3, 1.0, x2, 1, 2, 0.0);
    matrixvectormultiply(a, 2, 3, 3, 5, true, x2, 1, 2, 1.0, x1, 1, 3, 0.0);
    e2 = fabs(x1(1)+3)+fabs(x1(2)-3)+fabs(x1(3)+1)+fabs(x2(1)+1)+fabs(x2(2)+1);
    mverrors = ap::fp_greater_eq(e1+e2,threshold);
    
    //
    // testing inplace transpose
    //
    n = 10;
    a.setbounds(1, n, 1, n);
    b.setbounds(1, n, 1, n);
    x1.setbounds(1, n-1);
    for(i = 1; i <= n; i++)
    {
        for(j = 1; j <= n; j++)
        {
            a(i,j) = ap::randomreal();
        }
    }
    passcount = 10000;
    was1 = false;
    for(pass = 1; pass <= passcount; pass++)
    {
        i1 = 1+ap::randominteger(n);
        i2 = i1+ap::randominteger(n-i1+1);
        j1 = 1+ap::randominteger(n-(i2-i1));
        j2 = j1+(i2-i1);
        copymatrix(a, i1, i2, j1, j2, b, i1, i2, j1, j2);
        inplacetranspose(b, i1, i2, j1, j2, x1);
        for(i = i1; i <= i2; i++)
        {
            for(j = j1; j <= j2; j++)
            {
                if( ap::fp_neq(a(i,j),b(i1+(j-j1),j1+(i-i1))) )
                {
                    was1 = true;
                }
            }
        }
    }
    iterrors = was1;
    
    //
    // testing copy and transpose
    //
    n = 10;
    a.setbounds(1, n, 1, n);
    b.setbounds(1, n, 1, n);
    for(i = 1; i <= n; i++)
    {
        for(j = 1; j <= n; j++)
        {
            a(i,j) = ap::randomreal();
        }
    }
    passcount = 10000;
    was1 = false;
    for(pass = 1; pass <= passcount; pass++)
    {
        i1 = 1+ap::randominteger(n);
        i2 = i1+ap::randominteger(n-i1+1);
        j1 = 1+ap::randominteger(n);
        j2 = j1+ap::randominteger(n-j1+1);
        copyandtranspose(a, i1, i2, j1, j2, b, j1, j2, i1, i2);
        for(i = i1; i <= i2; i++)
        {
            for(j = j1; j <= j2; j++)
            {
                if( ap::fp_neq(a(i,j),b(j,i)) )
                {
                    was1 = true;
                }
            }
        }
    }
    cterrors = was1;
    
    //
    // Testing MatrixMatrixMultiply
    //
    n = 10;
    a.setbounds(1, 2*n, 1, 2*n);
    b.setbounds(1, 2*n, 1, 2*n);
    c1.setbounds(1, 2*n, 1, 2*n);
    c2.setbounds(1, 2*n, 1, 2*n);
    x1.setbounds(1, n);
    x2.setbounds(1, n);
    for(i = 1; i <= 2*n; i++)
    {
        for(j = 1; j <= 2*n; j++)
        {
            a(i,j) = ap::randomreal();
            b(i,j) = ap::randomreal();
        }
    }
    passcount = 1000;
    was1 = false;
    for(pass = 1; pass <= passcount; pass++)
    {
        for(i = 1; i <= 2*n; i++)
        {
            for(j = 1; j <= 2*n; j++)
            {
                c1(i,j) = 2.1*i+3.1*j;
                c2(i,j) = c1(i,j);
            }
        }
        l = 1+ap::randominteger(n);
        k = 1+ap::randominteger(n);
        r = 1+ap::randominteger(n);
        i1 = 1+ap::randominteger(n);
        j1 = 1+ap::randominteger(n);
        i2 = 1+ap::randominteger(n);
        j2 = 1+ap::randominteger(n);
        i3 = 1+ap::randominteger(n);
        j3 = 1+ap::randominteger(n);
        trans1 = ap::fp_greater(ap::randomreal(),0.5);
        trans2 = ap::fp_greater(ap::randomreal(),0.5);
        if( trans1 )
        {
            col1 = l;
            row1 = k;
        }
        else
        {
            col1 = k;
            row1 = l;
        }
        if( trans2 )
        {
            col2 = k;
            row2 = r;
        }
        else
        {
            col2 = r;
            row2 = k;
        }
        scl1 = ap::randomreal();
        scl2 = ap::randomreal();
        matrixmatrixmultiply(a, i1, i1+row1-1, j1, j1+col1-1, trans1, b, i2, i2+row2-1, j2, j2+col2-1, trans2, scl1, c1, i3, i3+l-1, j3, j3+r-1, scl2, x1);
        naivematrixmatrixmultiply(a, i1, i1+row1-1, j1, j1+col1-1, trans1, b, i2, i2+row2-1, j2, j2+col2-1, trans2, scl1, c2, i3, i3+l-1, j3, j3+r-1, scl2);
        err = 0;
        for(i = 1; i <= l; i++)
        {
            for(j = 1; j <= r; j++)
            {
                err = ap::maxreal(err, fabs(c1(i3+i-1,j3+j-1)-c2(i3+i-1,j3+j-1)));
            }
        }
        if( ap::fp_greater(err,threshold) )
        {
            was1 = true;
            break;
        }
    }
    mmerrors = was1;
    
    //
    // report
    //
    waserrors = n2errors||amaxerrors||hsnerrors||mverrors||iterrors||cterrors||mmerrors;
    if( !silent )
    {
        printf("TESTING BLAS\n");
        printf("VectorNorm2:                             ");
        if( n2errors )
        {
            printf("FAILED\n");
        }
        else
        {
            printf("OK\n");
        }
        printf("AbsMax (vector/row/column):              ");
        if( amaxerrors )
        {
            printf("FAILED\n");
        }
        else
        {
            printf("OK\n");
        }
        printf("UpperHessenberg1Norm:                    ");
        if( hsnerrors )
        {
            printf("FAILED\n");
        }
        else
        {
            printf("OK\n");
        }
        printf("MatrixVectorMultiply:                    ");
        if( mverrors )
        {
            printf("FAILED\n");
        }
        else
        {
            printf("OK\n");
        }
        printf("InplaceTranspose:                        ");
        if( iterrors )
        {
            printf("FAILED\n");
        }
        else
        {
            printf("OK\n");
        }
        printf("CopyAndTranspose:                        ");
        if( cterrors )
        {
            printf("FAILED\n");
        }
        else
        {
            printf("OK\n");
        }
        printf("MatrixMatrixMultiply:                    ");
        if( mmerrors )
        {
            printf("FAILED\n");
        }
        else
        {
            printf("OK\n");
        }
        if( waserrors )
        {
            printf("TEST FAILED\n");
        }
        else
        {
            printf("TEST PASSED\n");
        }
        printf("\n\n");
    }
    result = !waserrors;
    return result;
}
Exemplo n.º 7
0
/*************************************************************************
Weighted constained linear least squares fitting.

This  is  variation  of LSFitLinearW(), which searchs for min|A*x=b| given
that  K  additional  constaints  C*x=bc are satisfied. It reduces original
task to modified one: min|B*y-d| WITHOUT constraints,  then LSFitLinearW()
is called.

INPUT PARAMETERS:
    Y       -   array[0..N-1] Function values in  N  points.
    W       -   array[0..N-1]  Weights  corresponding to function  values.
                Each summand in square  sum  of  approximation  deviations
                from  given  values  is  multiplied  by  the   square   of
                corresponding weight.
    FMatrix -   a table of basis functions values, array[0..N-1, 0..M-1].
                FMatrix[I,J] - value of J-th basis function in I-th point.
    CMatrix -   a table of constaints, array[0..K-1,0..M].
                I-th row of CMatrix corresponds to I-th linear constraint:
                CMatrix[I,0]*C[0] + ... + CMatrix[I,M-1]*C[M-1] = CMatrix[I,M]
    N       -   number of points used. N>=1.
    M       -   number of basis functions, M>=1.
    K       -   number of constraints, 0 <= K < M
                K=0 corresponds to absence of constraints.

OUTPUT PARAMETERS:
    Info    -   error code:
                * -4    internal SVD decomposition subroutine failed (very
                        rare and for degenerate systems only)
                * -3    either   too   many  constraints  (M   or   more),
                        degenerate  constraints   (some   constraints  are
                        repetead twice) or inconsistent  constraints  were
                        specified.
                * -1    incorrect N/M/K were specified
                *  1    task is solved
    C       -   decomposition coefficients, array[0..M-1]
    Rep     -   fitting report. Following fields are set:
                * RMSError          rms error on the (X,Y).
                * AvgError          average error on the (X,Y).
                * AvgRelError       average relative error on the non-zero Y
                * MaxError          maximum error
                                    NON-WEIGHTED ERRORS ARE CALCULATED

IMPORTANT:
    this subroitine doesn't calculate task's condition number for K<>0.

SEE ALSO
    LSFitLinear
    LSFitLinearC
    LSFitLinearWC

  -- ALGLIB --
     Copyright 07.09.2009 by Bochkanov Sergey
*************************************************************************/
void lsfitlinearwc(ap::real_1d_array y,
     const ap::real_1d_array& w,
     const ap::real_2d_array& fmatrix,
     ap::real_2d_array cmatrix,
     int n,
     int m,
     int k,
     int& info,
     ap::real_1d_array& c,
     lsfitreport& rep)
{
    int i;
    int j;
    ap::real_1d_array tau;
    ap::real_2d_array q;
    ap::real_2d_array f2;
    ap::real_1d_array tmp;
    ap::real_1d_array c0;
    double v;

    if( n<1||m<1||k<0 )
    {
        info = -1;
        return;
    }
    if( k>=m )
    {
        info = -3;
        return;
    }
    
    //
    // Solve
    //
    if( k==0 )
    {
        
        //
        // no constraints
        //
        lsfitlinearinternal(y, w, fmatrix, n, m, info, c, rep);
    }
    else
    {
        
        //
        // First, find general form solution of constraints system:
        // * factorize C = L*Q
        // * unpack Q
        // * fill upper part of C with zeros (for RCond)
        //
        // We got C=C0+Q2'*y where Q2 is lower M-K rows of Q.
        //
        rmatrixlq(cmatrix, k, m, tau);
        rmatrixlqunpackq(cmatrix, k, m, tau, m, q);
        for(i = 0; i <= k-1; i++)
        {
            for(j = i+1; j <= m-1; j++)
            {
                cmatrix(i,j) = 0.0;
            }
        }
        if( ap::fp_less(rmatrixlurcondinf(cmatrix, k),1000*ap::machineepsilon) )
        {
            info = -3;
            return;
        }
        tmp.setlength(k);
        for(i = 0; i <= k-1; i++)
        {
            if( i>0 )
            {
                v = ap::vdotproduct(&cmatrix(i, 0), 1, &tmp(0), 1, ap::vlen(0,i-1));
            }
            else
            {
                v = 0;
            }
            tmp(i) = (cmatrix(i,m)-v)/cmatrix(i,i);
        }
        c0.setlength(m);
        for(i = 0; i <= m-1; i++)
        {
            c0(i) = 0;
        }
        for(i = 0; i <= k-1; i++)
        {
            v = tmp(i);
            ap::vadd(&c0(0), 1, &q(i, 0), 1, ap::vlen(0,m-1), v);
        }
        
        //
        // Second, prepare modified matrix F2 = F*Q2' and solve modified task
        //
        tmp.setlength(ap::maxint(n, m)+1);
        f2.setlength(n, m-k);
        matrixvectormultiply(fmatrix, 0, n-1, 0, m-1, false, c0, 0, m-1, -1.0, y, 0, n-1, 1.0);
        matrixmatrixmultiply(fmatrix, 0, n-1, 0, m-1, false, q, k, m-1, 0, m-1, true, 1.0, f2, 0, n-1, 0, m-k-1, 0.0, tmp);
        lsfitlinearinternal(y, w, f2, n, m-k, info, tmp, rep);
        rep.taskrcond = -1;
        if( info<=0 )
        {
            return;
        }
        
        //
        // then, convert back to original answer: C = C0 + Q2'*Y0
        //
        c.setlength(m);
        ap::vmove(&c(0), 1, &c0(0), 1, ap::vlen(0,m-1));
        matrixvectormultiply(q, k, m-1, 0, m-1, true, tmp, 0, m-k-1, 1.0, c, 0, m-1, 1.0);
    }
}
Exemplo n.º 8
0
Arquivo: lr.cpp Projeto: guyrt/WFUBMC
// Perform exact (and slower) NR test using the exact fisher information matrix.
vector<double> LogisticRegression::newtonRaphson(const vector<vector<double> > &data, const vector<double> &response, vector<vector<double> > &invInfMatrix, double startVal)
{

    vector<double> betas;
    
    // Variables used in the computation:
    alglib::real_1d_array tempBetas;
    alglib::real_2d_array tempData;
    alglib::real_2d_array tempDataTrans;
    alglib::real_1d_array oldExpY;
    alglib::real_2d_array hessian; // holds data' * w * data.  Returned in last input param.
    alglib::real_1d_array expY;
    alglib::real_1d_array W; // holds diagonal of the w matrix above.
    alglib::real_1d_array adjy;
    
    alglib::real_1d_array work;
    
    double stop_var = 1e-10;

    int iter = 0;
    int maxIter = 200;
    
    int numVars = data.size();
    if(numVars < 1){
        throw NewtonRaphsonFailureEx();
    }
    
    int numSamples = data.at(0).size();
    if(numSamples < 1){
        throw NewtonRaphsonFailureEx();
    }
    
    tempBetas.setlength(numVars);
    tempData.setlength(numSamples,numVars);
    tempDataTrans.setlength(numVars, numSamples);
    oldExpY.setlength(numSamples);
    expY.setlength(numSamples);
    hessian.setlength(numVars, numVars);
    adjy.setlength(numSamples);
    W.setlength(numSamples);
    
    work.setlength(numVars);
    
    for(int i=0;i < numVars; i++){
        for(int j=0;j < numSamples; j++){
            tempData(j,i) = data.at(i).at(j);
        }
        tempBetas(i) = startVal;
    }
    for(int i=0;i < numSamples;i++){
        oldExpY(i) = -1;
        adjy(i) = 0; // makes valgrind happier.
    }

    // End initial setup.
    // In each iteration, create a hessian and a first derivative.
    while(iter < maxIter){
        
        //adjy <- data * tempBetas (get new y guess)
        matrixvectormultiply(tempData, 0, numSamples-1,0,numVars-1,false, 
                            tempBetas, 0, numVars-1, 1.0, 
                            adjy, 0, numSamples-1, 0.0);
        
        // adjy = 1 / (1 + exp(-adjy))  
        for(int i=0;i < numSamples; i++){
            expY(i) = 1 / (1 + exp(-adjy(i)));
        }
        
        // build deriv.
        for(int i=0;i < numSamples; i++){
            W(i) = expY(i) * (1 - expY(i));
        }
        
        // adjy = adjy + (y-expy) ./ deriv
        for(int i=0;i<numSamples;i++){
            adjy(i) = adjy(i) + (response.at(i) - expY(i)) / W(i);
        }
        
        // build data' * w * data
        // set to hessian.  
        // Also doing secondary computation (see inside)
        for(int i=0; i < numVars; i++){
            for(int j=0; j < numVars; j++)
                hessian(i,j) = 0.0;
        }
        
        for(int indiv=0; indiv < numSamples; ++indiv){
            for(int i = 0; i < numVars; i++){
                for(int j = 0; j < numVars; j++){
                    hessian(i,j) += W(indiv) * tempData(indiv, j) * tempData(indiv, i);
                }
                
                // NOTE: as a speedup, I'm also computing X' * W
                tempDataTrans(i, indiv) = W(indiv) * tempData(indiv, i);
                
            }
        }
        
        alglib::matinvreport report;
        alglib::ae_int_t reportInfo;
        rmatrixinverse(hessian, reportInfo, report);
        if(reportInfo != 1 ){
            throw SingularMatrixEx();
        }
        
        // Check condition number.
        if (report.r1 < condition_number_limit){
            throw ConditionNumberEx(1.0/report.r1);
        }
        
        // work <- X'W * adjy
        matrixvectormultiply(tempDataTrans,0,numVars-1,0,numSamples-1,false,
                            adjy,0,numSamples-1,1,
                            work,0,numVars-1,0.0);
        // tempBetas <= invHessian * work
        matrixvectormultiply(hessian,0,numVars-1,0,numVars-1,false,
                            work,0,numVars-1,1.0,
                            tempBetas,0,numVars-1,0.0);
        
        
        #if DEBUG_NR
            cout << "Betas ";
            for(int i=0;i < numVars;i++) cout << tempBetas(i) << "  " ;
            cout << endl;
        #endif
        
        double stop = 0.0;
        // Could be computed as a 1-norm.
        // This should be done as a sum of abs diff.
        for(int i=0;i < numSamples;i++){
            stop += abs(expY(i) - oldExpY(i));
        }

        if (stop < numSamples*stop_var){
            break;
        }
        
        oldExpY = expY;
        
        iter++;
    }
    
    if(iter == maxIter){
        
        throw NewtonRaphsonIterationEx();
    }
    
    betas.clear();
    for(int i=0;i<numVars;i++){
        betas.push_back(tempBetas(i));
    }

    for(int i=0;i<numVars;i++){
        for(int j=0;j<numVars;j++){
            invInfMatrix.at(i).at(j) = hessian(i,j);
        }
    }
    
    //dumpMatrix(invInfMatrix);
    
    return betas;
    
}
Exemplo n.º 9
0
Arquivo: lr.cpp Projeto: guyrt/WFUBMC
/*
 * @depricated
 * 
 * NR implementation by RTG.
 *
 * Note on matrix vector multiplication:
 *  void matrixmatrixmultiply(const alglib::real_2d_array& a,
 *    int ai1,
 *    int ai2,
 *    int aj1,
 *    int aj2,
 *    bool transa,
 *    const alglib::real_2d_array& b,
 *    int bi1,
 *    int bi2,
 *    int bj1,
 *    int bj2,
 *    bool transb,
 *    double alpha,
 *    alglib::real_2d_array& c,
 *    int ci1,
 *    int ci2,
 *    int cj1,
 *    int cj2,
 *    double beta,
 *    alglib::real_1d_array& work);
 * 
 * transa is true if transposed.
 * Operation is: c = A * alpha * b + beta * C
 * 
 *  
 * @input const vector<vector<double>>  data holds explantory variables.  each inner vector is a variable.
 * @input const vector<double>          response holds response variable.
 * @input       vector<double>          Place to return the information matrix inverse.  Column major order.
 *                                      Expects correct size.
 */
vector<double> LogisticRegression::newtonRaphsonFast(const vector<vector<double> > &data, const vector<double> &response
                                                    , vector<vector<double> > &invInfMatrix, double startVal)
{
    
    
    vector<double> betas;
    
    
    // Variables used in the computation:
    alglib::real_1d_array tempBetas;
    alglib::real_2d_array tempData;
    alglib::real_1d_array oldExpY;
    alglib::real_2d_array tempDeriv; // holds data' * w * data.  Returned in last input param.
    alglib::real_1d_array expY;
    
    alglib::real_1d_array adjy;
    
    
    double stop_var = 1e-10;

    int iter = 0;
    int maxIter = 200;
    
    int numVars = data.size();
    if(numVars < 1){
        throw NewtonRaphsonFailureEx();
    }
    
    int numSamples = data.at(0).size();
    if(numSamples < 1){
        throw NewtonRaphsonFailureEx();
    }
    
    tempBetas.setlength(numVars);
    tempData.setlength(numSamples,numVars);
    oldExpY.setlength(numSamples);
    expY.setlength(numSamples);
    tempDeriv.setlength(numVars,numVars);
    adjy.setlength(numSamples);
    
    for(int i=0;i < numVars; i++){
        for(int j=0;j < numSamples; j++){
            tempData(j,i) = data.at(i).at(j);
        }
        tempBetas(i) = startVal;
    }
    for(int i=0;i < numSamples;i++){
        oldExpY(i) = -1;
        adjy(i) = 0; // makes valgrind happier.
    }

    while(iter < maxIter){
    
        //data * tempBetas
        matrixvectormultiply(tempData, 0, numSamples-1,0,numVars-1,false, 
                            tempBetas, 0, numVars-1, 1.0, 
                            adjy, 0, numSamples-1, 0.0);
        
        for(int i=0;i < numSamples; i++){
            expY(i) = 1 / (1 + exp(-adjy(i)));
        }
        
        // build deriv.
        double deriv = -100000;
        for(int i=0;i < numSamples; i++){
            if(expY(i) * (1 - expY(i)) > deriv)
                deriv = expY(i) * (1 - expY(i));
        }
        if(stop_var * 0.001 > deriv) deriv = stop_var * 0.001;
        
        // adjy = adjy + (y-expy) ./ deriv
        for(int i=0;i<numSamples;i++){
            adjy(i) = adjy(i) + (response.at(i) - expY(i)) / deriv;
        }
        
        // build data' * w * data
        alglib::real_1d_array work;
        work.setlength(numSamples); // This temporary workspace must be one larger than the longest
                                    // row or column that will be seen.  Otherwise, the program
                                    // crashes or - worse! - corrupts data.
        matrixmatrixmultiply(tempData,0,numSamples-1,0,numVars-1,true,
                            tempData,0,numSamples-1,0,numVars-1,false,deriv,
                            tempDeriv,0,numVars-1,0,numVars-1,0.0,work);

        #if DEBUG_NR
            cout << "A' * w * A " << endl;
            cout << tempDeriv(0,0) << " " << tempDeriv(0,1) << endl;
            cout << tempDeriv(1,0) << " " << tempDeriv(1,1) << endl;
            cout << endl;
        #endif
        
        alglib::matinvreport report;
        alglib::ae_int_t reportInfo;
        rmatrixinverse(tempDeriv, reportInfo, report);
        
        if( reportInfo != 1 ){
            throw SingularMatrixEx();
        }

        #if DEBUG_NR
            cout << "inv(A' * w * A) " << endl;
            cout << tempDeriv(0,0) << " " << tempDeriv(0,1) << endl;
            cout << tempDeriv(1,0) << " " << tempDeriv(1,1) << endl;
            cout << endl;
        #endif

        matrixvectormultiply(tempData,0,numSamples-1,0,numVars-1,true,
                            adjy,0,numSamples-1,deriv,
                            work,0,numVars-1,0.0);
        matrixvectormultiply(tempDeriv,0,numVars-1,0,numVars-1,false,
                            work,0,numVars-1,1.0,
                            tempBetas,0,numVars-1,0.0);
        
        #if DEBUG_NR
            cout << "Betas ";
            for(int i=0;i < numVars;i++) cout << tempBetas(i) << "  " ;
            cout << endl;
        #endif
        
        double stop = 0.0;
        for(int i=0;i < numSamples;i++){
            stop += abs(expY(i) - oldExpY(i));
        }
    
        if (stop < numSamples*stop_var){
            break;
        }
        
        oldExpY = expY;
        
        iter++;
    }
    
    if(iter == maxIter){
        throw NewtonRaphsonIterationEx();
    }
    
    betas.clear();
    for(int i=0;i<numVars;i++){
        betas.push_back(tempBetas(i));
    }

    for(int i=0;i<numVars;i++){
        for(int j=0;j<numVars;j++){
            invInfMatrix.at(i).at(j) = tempDeriv(i,j);
        }
    }
    
    return betas;
}