[Pomp-commits] r394 - pkg/src

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Sat Oct 23 16:50:42 CEST 2010


Author: kingaa
Date: 2010-10-23 16:50:42 +0200 (Sat, 23 Oct 2010)
New Revision: 394

Modified:
   pkg/src/pomp_mat.h
   pkg/src/synth_lik.c
Log:
- fix bug to do with pivoting in 'synth_lik.c'


Modified: pkg/src/pomp_mat.h
===================================================================
--- pkg/src/pomp_mat.h	2010-10-21 12:51:21 UTC (rev 393)
+++ pkg/src/pomp_mat.h	2010-10-23 14:50:42 UTC (rev 394)
@@ -6,18 +6,10 @@
 
 static R_INLINE void pomp_backsolve (double *a, int m, int n, double *x, int incx, 
 				     char *uplo, char *transpose, char *unit) {
-  // Level 2 BLAS triangular-matrix solver
-  // DTRSV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
+  // Level 2 BLAS triangular-matrix solver DTRSV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
   F77_NAME(dtrsv)(uplo,transpose,unit,&n,a,&m,x,&incx);
 }
 
-static R_INLINE void pomp_qr_x_inv_r (double *a, int m, int n, double *b, int ldb) {
-  // Level 3 BLAS triangular-matrix solver
-  // DTRSM(SIDE,UPLO,TRANS,DIAG,M,N,ALPHA,A,LDA,B,LDB)
-  double alpha = 1.0;
-  F77_NAME(dtrsm)("Right","Upper","No transpose","Non-unit",&m,&n,&alpha,a,&m,b,&ldb);
-}
-
 static R_INLINE void pomp_qr (double *a, int m, int n, int *pivot, double *tau) {
   int info, j, lwork = -1;
   double work1;

Modified: pkg/src/synth_lik.c
===================================================================
--- pkg/src/synth_lik.c	2010-10-21 12:51:21 UTC (rev 393)
+++ pkg/src/synth_lik.c	2010-10-23 14:50:42 UTC (rev 394)
@@ -15,11 +15,12 @@
   int nrow = dim[0];
   int ncol = dim[1];
   double alpha = 2.0, beta = 1.25;
-  double x, xx, *yp, wbar;
-  double w[nrow], tau[ncol];
-  int pivot[nrow];
-  double *y1, *y2;
-  double d, d0, rss, half_log_det;
+  double w[nrow], tau[ncol], work[ncol];
+  int pivot[ncol];
+  int info = 0, ione = 1;
+  double one = 1.0;
+  double *y1, *y2, *yp;
+  double x, xx, wbar, d, d0, rss, half_log_det;
   int i, j, k;
 
   half_log_det = ncol*M_LN_SQRT_2PI;
@@ -27,22 +28,25 @@
   y1 = (double *) R_alloc(nrow*ncol,sizeof(double));
   y2 = (double *) R_alloc(nrow*ncol,sizeof(double));
 
-  // compute column means, center each column, compute preconditioner
+  // compute column means, center each column, precondition
   memcpy(y1,y,nrow*ncol*sizeof(double));
   for (yp = y1, j = 0; j < ncol; j++, yp += nrow) {
     for (xx = 0, i = 0; i < nrow; i++) xx += yp[i];
     xx /= nrow;
     for (i = 0; i < nrow; i++) yp[i] -= xx; // center the column
     for (xx = 0, i = 0; i < nrow; i++) xx += yp[i]*yp[i];
-    x = sqrt(xx/nrow);		   // column SD
+    x = sqrt(xx/(nrow-1));		   // column SD
     for (i = 0; i < nrow; i++) yp[i] /= x; // precondition
   }
 
   // do first QR decomposition & backsolve
-
   memcpy(y2,y1,nrow*ncol*sizeof(double));
-  pomp_qr(y2,nrow,ncol,pivot,tau); // Q*R = Y*inv(diag(d))
-  pomp_qr_x_inv_r(y2,nrow,ncol,y1,nrow); // y1 <- y1 %*% inv(R)
+  {
+    // LAPACK QR decomposition without pivoting DGEQR2(M,N,A,LDA,TAU,WORK,INFO)
+    F77_NAME(dgeqr2)(&nrow,&ncol,y2,&nrow,tau,work,&info);
+    // Level-3 BLAS triangular matrix solver DTRSM(SIDE,UPLO,TRANS,DIAG,M,N,ALPHA,A,LDA,B,LDB)
+    F77_NAME(dtrsm)("Right","Upper","No transpose","Non-unit",&nrow,&ncol,&one,y2,&nrow,y1,&nrow);
+  }
 
   // create Campbell weight vector
   d0 = sqrt(ncol)+alpha/sqrt(2.0);
@@ -51,7 +55,7 @@
       x = y1[i+nrow*j];
       xx += x*x;
     }
-    d = sqrt((nrow-1)*xx);	// Mahalonobis distance of row i
+    d = sqrt((nrow-1)*xx); // Mahalonobis distance of row i
     if (d > d0) {
       x = d-d0;
       xx = exp(-0.5*x*x/beta)*d0/d;
@@ -62,7 +66,7 @@
     wbar += xx*xx;
   }
   wbar = sqrt(wbar-1);
-
+  
   // compute weighted column means, center each column, precondition
   memcpy(y1,y,nrow*ncol*sizeof(double));
   for (yp = y1, j = 0; j < ncol; j++, yp += nrow) {
@@ -77,23 +81,22 @@
       xx += yp[i]*yp[i];
       yp[i] /= wbar; 
     }
-    x = sqrt(xx/(nrow-1)); // column SD
-    for (i = 0; i < nrow; i++) yp[i] *= (w[i]/x); // precondition & weight
-    ydat[j] /= x;
-    half_log_det += log(x); // sum up logs(diag(D))
+    d = sqrt(xx/(nrow-1)); // column SD
+    for (i = 0; i < nrow; i++) yp[i] *= (w[i]/d); // precondition & weight
+    ydat[j] /= d;
+    half_log_det += log(d); // sum up logs(diag(D))
   }
 
   // do second QR decomposition & backsolve
   pomp_qr(y1,nrow,ncol,pivot,tau); // Q*R = diag(w)*Y*inv(diag(d))
-  pomp_backsolve(y1,nrow,ncol,ydat,1,"Upper","Transpose","Non-unit"); // ydat <- ydat*inv(R)
+  for (j = 0; j < ncol; j++) tau[j] = ydat[pivot[j]]; // unpivot
+  pomp_backsolve(y1,nrow,ncol,tau,1,"Upper","Transpose","Non-unit");
 
   // compute residual sum of squares and add up logs of diag(R)
-  xx = 0;
   for (yp = y1, rss = 0, i = nrow+1, j = 0; j < ncol; j++, yp += i) { // yp marches along the diagonal of R
-    x = ydat[j];
+    x = tau[j];
     rss += x*x;
     half_log_det += log(fabs(*yp)); // log(diag(R))
-    xx += log(fabs(*yp));
   }
 
   *loglik = -0.5*rss-half_log_det;



More information about the pomp-commits mailing list