//R用 関数 // #include #include #include #include #include #include #include const int gl_incx=1, gl_incy=1; const double one = 1.0; const double minusOne = -1.0; const double zero = 0.0; const int intZero = 0L; int gl_lda; /* tol is used to determine the effective rank of x. if tol < 0.0 , machine eps is used for tol. */ void dqrls2(double *x, int *n, int *p, double *y, int *ny, double *tol, double *b, double *rsd, double *qty, int *k, int *jpvt, double *qraux) { double work0; double *work; double *x1; int nny = (*n)*(*ny); int np = (*n)*(*p); int lwork0, lwork; int info_dgeqp3; int info_dqrsl, job = 1110; int info_dgelsy; int ii, jj, kk; x1 = (double *) R_alloc(np, sizeof(double)); // copy x to x1 F77_CALL(dcopy)(&np, x, &gl_incx, x1, &gl_incy); // copy y to rsd F77_CALL(dcopy)(&nny, y, &gl_incx, rsd, &gl_incy); // calc LWORK lwork0 = -1; F77_CALL(dgelsy)(n, p, ny, x, n, y, n, jpvt, tol, k, &work0, &lwork0, &info_dgelsy); //Rprintf("work0 : %f\n", work0); //1Rprintf("n : %d\n", *n); // exec LM lwork = work0; work = (double *) R_alloc(lwork, sizeof(double)); F77_CALL(dgelsy)(n, p, ny, x, n, y, n, jpvt, tol, k, work, &lwork, &info_dgelsy); for( ii=0; ii<*p; ii++ ) for( jj=0; jj<*ny; jj++ ) b[ii+jj*(*p)] = y[ii+jj*(*n)]; // calc rsd F77_CALL(dgemm)("N", "N", n, ny, p, &minusOne, x1, n, b, p, &one, rsd, n); } void dqrls3(double *x, int *n, int *p, double *y, int *ny, double *tol, double *b, double *rsd, double *qty, int *k, int *jpvt, double *qraux) { double work0; double *work; double *x1; int lwork0, lwork; int INFO; int info_dgeqp3; int info_dqrsl, job = 1110; int info_dgelsy; int ii, jj, kk; int nny = (*n)*(*ny); int np = (*n)*(*p); x1 = (double *) R_alloc(np, sizeof(double)); // copy x to x1 F77_CALL(dcopy)(&np, x, &gl_incx, x1, &gl_incy); // copy y to rsd F77_CALL(dcopy)(&nny, y, &gl_incx, rsd, &gl_incy); // copy y to qty F77_CALL(dcopy)(&nny, y, &gl_incx, qty, &gl_incy); ////////////////////////////////////////////////// // calc LWORK lwork0 = -1; F77_CALL(dgelsy)(n, p, ny, x, n, y, n, jpvt, tol, k, &work0, &lwork0, &info_dgelsy); //Rprintf("work0 : %f\n", work0); //Rprintf("n : %d\n", *n); lwork = work0; work = (double *) R_alloc(lwork, sizeof(double)); //Rprintf("lwork : %d\n", lwork); const int IMAX=1, IMIN=2; int I, IASCL, IBSCL, ISMAX, ISMIN, J, LWKMIN, LWKOPT, MN, NB, NB1, NB2, NB3, NB4; double ANRM, BIGNUM, BNRM, C1, C2, S1, S2, SMAX, SMAXPR, SMIN, SMINPR, SMLNUM, WSIZE; MN = (*n)<(*p)?(*n):(*p); ISMIN = MN + 1; ISMAX = 2*MN + 1; ////////////////////////////////////////////////// // Get machine parameters SMLNUM = F77_CALL(dlamch)( "S" ) / F77_CALL(dlamch)( "P" ); BIGNUM = 1.0 / SMLNUM; F77_CALL(dlabad)( &SMLNUM, &BIGNUM ); ////////////////////////////////////////////////// // Scale A, B if max entries outside range [SMLNUM,BIGNUM] ANRM = F77_CALL(dlange)( "M", n, p, x, n, &work0 ); /* WORK (workspace) DOUBLE PRECISION array, dimension (MAX(1,LWORK)), where LWORK >= M when NORM = 'I'; otherwise, WORK is not referenced. */ IASCL = 0; if( ANRM>0.0 & ANRMBIGNUM ){ // Scale matrix norm down to BIGNUM F77_CALL(dlascl)( "G", &intZero, &intZero, &ANRM, &BIGNUM, n, p, x, n, &INFO ); IASCL = 2; } else if( ANRM==0 ){ // Matrix all zero. Return zero solution. int MAX_MN = (*n)<(*p)?(*p):(*n); F77_CALL(dlaset)( "F", &MAX_MN, ny, &zero, &zero, y, n ); *k = 0; return; } BNRM = F77_CALL(dlange)( "M", n, ny, y, n, &work0 ); IBSCL = 0; if( BNRM>0.0 & BNRMBIGNUM ){ // Scale matrix norm down to BIGNUM F77_CALL(dlascl)( "G", &intZero, &intZero, &BNRM, &BIGNUM, n, ny, y, n, &INFO ); IBSCL = 2; } ////////////////////////////////////////////////// // Compute QR factorization with column pivoting of A: lwork0 = lwork - MN; /* Rprintf("lwork0 : %d\n", lwork0); Rprintf("n : %d\n", *n); Rprintf("p : %d\n", *p); Rprintf("MN : %d\n", MN); for( ii=0; ii<(*n)*(*p); ii++ ){ Rprintf("x[ii] : %e\n", x[ii]); } Rprintf("x[0+(*n)*(2-1)] : %e\n", x[0+(*n)*(2-1)]); Rprintf("x[(2-1)+(*n)*(2-1)] : %e\n", x[(2-1)+(*n)*(2-1)]); */ //double ww[10]; //F77_CALL(dgeqp3)(n, p, x, n, jpvt, qraux, ww, &lwork0, &info_dgeqp3); F77_CALL(dgeqp3)(n, p, x, n, jpvt, qraux, &work[ MN+1-1 ], &lwork0, &info_dgeqp3); // Rprintf("info_dgeqp3 : %d\n", info_dgeqp3); // Rprintf("x[0+(*n)*(2-1)] : %e\n", x[0+(*n)*(2-1)]); // Rprintf("x[(2-1)+(*n)*(2-1)] : %e\n", x[(2-1)+(*n)*(2-1)]); //for( ii=0; ii<(*n)*(*p); ii++ ){ // Rprintf("x[ii] : %e\n", x[ii]); //} // Details of Householder rotations stored in WORK. F77_CALL(dcopy)(&MN, qraux, &gl_incx, work, &gl_incy); ////////////////////////////////////////////////// // Determine RANK using incremental condition estimation work[ ISMIN-1 ] = 1.0; work[ ISMAX-1 ] = 1.0; SMAX = fabs( x[ 0 ] ); SMIN = SMAX; if( fabs( x[0] )==0.0 ){ int MAX_MN = (*n)<(*p)?(*p):(*n); F77_CALL(dlaset)( "F", &MAX_MN, ny, &zero, &zero, y, n ); *k = 0; return; } else{ *k = 1; } while( (*k)= M when NORM = 'I'; otherwise, WORK is not referenced. */ IASCL = 0; if( ANRM>0.0 & ANRMBIGNUM ){ // Scale matrix norm down to BIGNUM F77_CALL(dlascl)( "G", &intZero, &intZero, &ANRM, &BIGNUM, n, p, x, n, &INFO ); IASCL = 2; } else if( ANRM==0 ){ // Matrix all zero. Return zero solution. int MAX_MN = (*n)<(*p)?(*p):(*n); F77_CALL(dlaset)( "F", &MAX_MN, ny, &zero, &zero, y, n ); *k = 0; return; } BNRM = F77_CALL(dlange)( "M", n, ny, y, n, &work0 ); IBSCL = 0; if( BNRM>0.0 & BNRMBIGNUM ){ // Scale matrix norm down to BIGNUM F77_CALL(dlascl)( "G", &intZero, &intZero, &BNRM, &BIGNUM, n, ny, y, n, &INFO ); IBSCL = 2; } ////////////////////////////////////////////////// // Compute QR factorization with column pivoting of A: lwork0 = lwork - MN; F77_CALL(dgeqp3)(n, p, x, n, jpvt, qraux, &work[ MN+1-1 ], &lwork0, &info_dgeqp3); //F77_CALL(dgeqrf)(n, p, x, n, qraux, &work[ MN+1-1 ], &lwork0, &info_dgeqp3); F77_CALL(dcopy)(&MN, qraux, &gl_incx, work, &gl_incy); ////////////////////////////////////////////////// // Determine RANK using incremental condition estimation work[ ISMIN-1 ] = 1.0; work[ ISMAX-1 ] = 1.0; SMAX = fabs( x[ 0 ] ); SMIN = SMAX; if( fabs( x[0] )==0.0 ){ int MAX_MN = (*n)<(*p)?(*p):(*n); F77_CALL(dlaset)( "F", &MAX_MN, ny, &zero, &zero, y, n ); *k = 0; return; } else{ *k = 1; } while( (*k)