00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <iostream>
00026 #include <iomanip>
00027 #include <sstream>
00028
00029 #include "session.h"
00030 #include "util.h"
00031 #include "doublematrix.h"
00032 #include "model.h"
00033 #include "population.h"
00034 #include "statdist.h"
00035 #include "glmm.h"
00036
00037 namespace matvec {
00038 #undef DO_THREADS
00039 #ifdef SKIP_THREADS
00040 #undef DO_THREADS
00041 #endif
00042
00043 #undef DO_PMAT
00044 #define DO_LOG
00045 #undef DO_CHOL
00046
00047 #ifdef DO_CHOL
00048 #undef DO_PMAT
00049 #undef DO_LOG
00050 #endif
00051
00052 #ifdef DO_LOG
00053 #undef DO_PMAT
00054 #undef DO_CHOL
00055 #endif
00056
00057 #define DO_HINV
00058
00059 #undef DEBUG
00060
00061 #define EPSILON SESSION.epsilon
00062
00063
00064 extern void getlambda(double **lambda, const int n);
00065
00066 void GLMM::Vec2Var(const double *x)
00067
00068
00069
00070
00071 {
00072 int i,k,t1,t2,ped_done;
00073 ped_done=0;
00074 doubleMatrix *var;
00075 #ifdef DO_CHOL
00076 doubleMatrix L;
00077 #endif
00078 for (k=0,i=0; i<numterm; i++) {
00079 if (term[i].classi() == 'R' || (!ped_done && term[i].classi() == 'P')) {
00080 if(var_link[i]==i){
00081 int nt=nt_vec[i];
00082 #ifdef DO_CHOL
00083 L.resize(numtrait,numtrait);
00084 L.assign(0.0);
00085 var=&L;
00086 #else
00087 var = term[i].prior->var_matrix();
00088 #endif
00089 for (t1=0; t1<nt; t1++) {
00090 for (t2=t1; t2<nt; t2++,k++) {
00091 (*var)[t1][t2] = x[k];
00092 #ifndef DO_CHOL
00093 if ( t2>t1 ) (*var)[t2][t1] = x[k];
00094 #endif
00095 }
00096 }
00097 #ifdef DO_CHOL
00098 var= term[i].prior->var_matrix();
00099 *var=L.transpose()*L;
00100 #endif
00101 }
00102 else{
00103 int ii=var_link[i];
00104 var= term[i].prior->var_matrix();
00105 doubleMatrix *var2;
00106 var2=term[ii].prior->var_matrix();
00107 *var=*var2;
00108 }
00109 }
00110
00111 }
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 if(link_function){
00129 for(t1=0;t1<res_nvc;t1++) varcomp[t1]=x[k++];
00130 }
00131 else{
00132 for (t1=0; t1<numtrait; t1++) {
00133 for (t2=t1; t2<numtrait; t2++,k++) {
00134 residual_var[t1][t2] = x[k];
00135 if ( t2>t1 ) residual_var[t2][t1] = x[k];
00136 }
00137 }
00138 }
00139 }
00140
00141
00142 Vector<double> * GLMM::glim(int iterations,double **ke, int nr, int nc, double *mean)
00143 {
00144 int iter,i,j,k;
00145 doubleMatrix kvk;
00146 Vector<double> kpm,wrkvec;
00147 double old_like,new_like,*krow,*m,*tmpsol,kpd;
00148 double *kp,*sol;
00149 Vector<double> old_sol;
00150 Vector<double> *retval;
00151 if(!link_function) {
00152 blup("ysmp1");
00153 if(ke)
00154 {
00155 tmpsol=new double [hmmesize];
00156 krow=new double [hmmesize];
00157 }
00158 if(ke)
00159 {
00160 kpm.resize(nr);
00161 kvk.resize(nr,nr);
00162 if(mean) memcpy(kpm.begin(),mean,sizeof(double)*nr);
00163 for(i=0;i<nr;i++){
00164 for(j=0;j<nc;j++) kpm[i]-=ke[i][j]*blupsol[j];
00165 memset(krow,'\0',sizeof(double)*hmmesize);
00166 memcpy(krow,ke[i],sizeof(double)*nc);
00167 hmmec.solve(tmpsol,krow,"ysmp");
00168 for (k=0; k<nr; k++) {
00169 kp = ke[k]; sol = tmpsol;
00170 for (kpd=0.0,j=0; j<nc; j++) kpd += *kp++ * *sol++;
00171 kvk[k][i] = kpd;
00172 }
00173 }
00174 kvk.ginv1();
00175 kpm=kvk*kpm;
00176 memset(krow,'\0',sizeof(double)*hmmesize);
00177 for(i=0;i<nr;i++) {
00178 for(j=0;j<nc;j++) {
00179 krow[j]+=ke[i][j]*kpm[i];
00180 }
00181 }
00182 hmmec.solve(tmpsol,krow,"ysmp");
00183 for(i=0;i<hmmesize;i++) blupsol[i]+=tmpsol[i];
00184
00185 delete [] krow;
00186 delete [] tmpsol;
00187 }
00188
00189
00190
00191 return(&blupsol);
00192 }
00193 for(iter=0;iter< iterations;iter++) {
00194 setup_mme(&rellrhs);
00195 #ifdef DEBUG
00196 doubleMatrix LHS;
00197 LHS=mmec()->dense();
00198 std::cout << "\nRHS\n"<<rellrhs.subvec()<<"\n";
00199 std::cout << "\nLHS\n"<<LHS <<"\n";
00200 #endif
00201 blup("ysmp1");
00202
00203 if(ke && iter==0)
00204 {
00205 tmpsol=new double [hmmesize];
00206 krow=new double [hmmesize];
00207 }
00208 if(ke)
00209 {
00210 kpm.resize(nr);
00211 kvk.resize(nr,nr);
00212 if(mean) memcpy(kpm.begin(),mean,sizeof(double)*nr);
00213 for(i=0;i<nr;i++){
00214 for(j=0;j<nc;j++) kpm[i]-=ke[i][j]*blupsol[j];
00215 memset(krow,'\0',sizeof(double)*hmmesize);
00216 memcpy(krow,ke[i],sizeof(double)*nc);
00217 hmmec.solve(tmpsol,krow,"ysmp");
00218 for (k=0; k<nr; k++) {
00219 kp = ke[k]; sol = tmpsol;
00220 kpd=0.0;
00221 for (j=0; j<nc; j++) kpd += ke[k][j] * tmpsol[j];
00222 kvk[k][i] = kpd;
00223 }
00224 }
00225 kvk.ginv1();
00226 kpm=kvk*kpm;
00227 memset(krow,'\0',sizeof(double)*hmmesize);
00228 for(i=0;i<nr;i++) {
00229 for(j=0;j<nc;j++) {
00230 krow[j]+=ke[i][j]*kpm[i];
00231 }
00232 }
00233 hmmec.solve(tmpsol,krow,"ysmp");
00234 for(i=0;i<hmmesize;i++) blupsol[i]+=tmpsol[i];
00235 }
00236
00237 }
00238
00239
00240 retval=&blupsol;
00241 if(ke)
00242 {
00243 delete [] krow;
00244 delete [] tmpsol;
00245 }
00246 return retval;
00247 }
00248
00249
00250 double GLMM::contrast(const double **kpme, const unsigned nr,
00251 const unsigned nc,const double *M,const int prt_flag,double **result)
00252 {
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 if(!link_function){
00263 return(Model::contrast(kpme,nr,nc,M, prt_flag,result));
00264 }
00265 int do_varcomp=Info.num_rows();
00266 int Print_Flag=1;
00267 if(Print_Level < 0 || !prt_flag) Print_Flag=0;
00268
00269 if (!kpme) {
00270 warning("GLMM::contrast(kp): kp is null, thus it is ignored");
00271 return 0.0;
00272 }
00273 if (!get_blupsol()) throw exception("GLMM::contrast(): bad model");
00274
00275 if (nc > hmmesize) throw exception("GLMM::contrast(): size not conformable");
00276 int est=1;
00277 doubleMatrix kvk(nr,nr);
00278 doubleMatrix kvkori(nr,nr);
00279 doubleMatrix kv(nr,hmmesize);
00280 doubleMatrix kGk(nr,nr);
00281 doubleMatrix kRk(nr,nr);
00282 Vector<double> kpdiff(nr);
00283 Vector<double> kpb_m(nr);
00284 Vector<double> xy(hmmesize);
00285 Vector<double> tmpsol(hmmesize);
00286 double *sol, kpd;
00287 double log_LR;
00288 log_LR=2.*like_val;
00289 const double *kp;
00290 unsigned i,j,k;
00291 int t1,t2,ii,*ainv_ia,*ainv_ja,ainv_nrow;
00292 int ipos,jpos,je,jj,jaddr;
00293 double *ainv_a;
00294 if(LR==2) glim(10,(double **)kpme,nr,nc,(double *)M);
00295
00296 for (i=0; i<nr; i++) {
00297 if (nc < hmmesize) {
00298 memset(xy.begin(),'\0',sizeof(double)*hmmesize);
00299 memcpy(xy.begin(),kpme[i],sizeof(double)*nc);
00300 hmmec.solve(tmpsol,xy,"ysmp");
00301 }
00302 else {
00303 hmmec.solve(tmpsol.begin(),kpme[i],"ysmp");
00304 }
00305 hmmec.mv(tmpsol,xy);
00306 memcpy(kv[i],tmpsol.begin(),sizeof(double)*hmmesize);
00307 kp = kpme[i];
00308 sol = xy.begin();
00309 for (kpd=0.0,j=0; j<nc; j++) {
00310 kpd = std::max(kpd,fabs(kpme[i][j] - xy[j]));
00311 kp++;
00312 sol++;
00313 }
00314 for (j=nc; j<hmmesize; j++) {
00315 kpd = std::max(kpd,fabs(xy[j]));
00316 sol++;
00317 }
00318 kpdiff[i] = kpd;
00319 for (k=0; k<nr; k++) {
00320 kp = kpme[k]; sol = tmpsol.begin();
00321 for (kpd=0.0,j=0; j<nc; j++) kpd += kpme[k][j] * tmpsol[j];
00322 kvk[k][i] = kpd;
00323 }
00324 }
00325 for(k=1;k<nr;k++) for(i=0;i<k;i++) kvk[k][i]=kvk[i][k];
00326 kvkori=kvk;
00327 kvk = kvkori;
00328 kvk.ginv1(&k);
00329 if (k < nr) {
00330 warning("GLMM::contrast(K'): K'V{-1}K is singular. Possible reason:\n"
00331 " (1) K is non-estimable, and (2) K isn't of full column rank");
00332
00333 }
00334
00335 int nvc=TotalNvc();
00336 unsigned startaddr,nlevels,iaddr,t;
00337 Vector<double> Lambda(nvc);
00338 double addj=0.;
00339 doubleMatrix *smat;
00340 int k_vc,i_vc;
00341 doubleMatrix wmat(numtrait,numtrait);
00342 doubleMatrix rmat(numtrait,numtrait);
00343 for(k_vc=0,i_vc=0;do_varcomp && i_vc<numterm;i_vc++) {
00344 if(term[i_vc].classi() == 'P' || term[i_vc].classi() == 'R'){
00345 startaddr=term[i_vc].startaddr()+1;
00346 int nt=nt_vec[i_vc];
00347 for(t1=0;t1<nt;t1++) for(t2=t1;t2<nt;t2++,k_vc++) {
00348
00349 rmat=*(term[i_vc].prior->var_matrix());
00350 rmat.ginv1();
00351 wmat=SinMat[k_vc];
00352 kGk.assign(0.0);
00353 kRk.assign(0.0);
00354 if(term[i_vc].classi() == 'R') {
00355 nlevels=term[i_vc].nlevel();
00356 for(ii=1;ii<=nlevels;ii++) {
00357 iaddr=startaddr+(ii-1)*numtrait;
00358 kGk+=kv.submat(0,iaddr-1,nr,nt)*wmat
00359 *(kv.submat(0,iaddr-1,nr,nt)).transpose();
00360 if(t1==0 && t2==0) kRk+=kv.submat(0,iaddr-1,nr,nt)*rmat
00361 *(kv.submat(0,iaddr-1,nr,nt)).transpose();
00362 }
00363 }
00364 if(term[i_vc].classi() == 'P') {
00365 ainv();
00366 ainv_ia=hainv.ia();
00367 ainv_ja=hainv.ja();
00368 ainv_a=hainv.a();
00369 ainv_nrow=hainv.num_rows();
00370 for(ii=1;ii<=ainv_nrow;ii++) {
00371 ipos=ii;
00372 iaddr=startaddr+(ipos-1)*nt;
00373 je=ainv_ia[ii+1];
00374 for(jj=ainv_ia[ii];jj<je;jj++) {
00375 jpos=ainv_ja[jj];
00376 double offdiag;
00377 offdiag=2.;
00378 if(ipos==jpos) offdiag=1.;
00379 jaddr=startaddr+(jpos-1)*nt;
00380 kGk+=ainv_a[jj]*offdiag*
00381 kv.submat(0,iaddr-1,nr,nt)*wmat
00382 *(kv.submat(0,iaddr-1,nr,nt)).transpose();
00383 if(t1==0 && t2==0) kRk+=kv.submat(0,iaddr-1,nr,nt)*rmat
00384 *(kv.submat(0,iaddr-1,nr,nt)).transpose();
00385 }
00386 }
00387 }
00388 Lambda[k_vc]=(kvk*kGk).trace();
00389 if(t1 == 0 && t2 == 0) addj+=(kvk*kRk).trace();
00390 }
00391 }
00392 }
00393
00394
00395
00396
00397 unsigned kvc;
00398
00399 if(link_function){
00400
00401 for(kvc=0;do_varcomp && kvc<res_nvc;kvc++,k_vc++){
00402 wmat.assign(0.0);
00403 rmat.assign(0.0);
00404 for(ii=0;ii<numrec;ii++) {
00405 wmat+=observation[ii].H.transpose()*observation[ii].Resid_Sin_Mat[kvc]*
00406 observation[ii].H*observation[ii].weight;
00407 rmat+=observation[ii].rve*observation[ii].weight;
00408
00409
00410
00411
00412
00413
00414
00415 }
00416 Lambda[k_vc]=(static_cast<double>(nr) - addj)*(wmat*rmat.inv()).trace();
00417
00418 }
00419
00420
00421 }
00422 else{
00423 rmat.assign(0.0);
00424 for(ii=0;ii<numrec;ii++) {
00425 rmat+=observation[ii].rve*observation[ii].weight;
00426 }
00427 for(t1=0;t1<numtrait;t1++) for(t2=t1;t2<numtrait;t2++,k_vc++) {
00428 wmat.assign(0.0);
00429 for(ii=0;ii<numrec;ii++) {
00430 wmat+=SinMat[k_vc]*observation[ii].weight;
00431
00432 }
00433 Lambda[k_vc]=(static_cast<double>(nr) - addj)*(wmat*rmat.inv()).trace();
00434 }
00435 }
00436
00437 if(LR==2) glim();
00438 double dfe;
00439
00440
00441
00442 for (i=0; i<nr; i++) kpb_m[i] = blupsol.inner_product(kpme[i]);
00443 if (M) for (i=0; i<nr; i++) kpb_m[i] -= M[i];
00444 double quq;
00445 if(LR!=1) {
00446 quq = kvk.quadratic(kpb_m,kpb_m);
00447 }
00448 else{
00449
00450 {
00451
00452
00453
00454 glim(10,(double **)kpme,nr,nc,(double *)M);
00455 residual();
00456 quq= -like_val;
00457
00458 glim();
00459 residual();
00460 quq+=like_val;
00461 quq*=2.;
00462 }
00463 }
00464 double ssm,sse;
00465 unsigned rank_x;
00466 int degen = 0;
00467 int errcode = 0;
00468 double f_stat=0.0, prob=0.0,vart=0.0;
00469 double sigma_e = residual_var[0][0];
00470 int not_chisq = Info.num_rows();
00471 if(Asym) not_chisq=0;
00472
00473 if(not_chisq) vart=Info.ginv0().quadratic(Lambda,Lambda);
00474 if (!not_chisq || vart <= EPSILON ) {
00475 f_stat = quq;
00476
00477 prob = ChiSquare_cdf(f_stat,static_cast<double>(nr),0.0,errcode);
00478 f_stat /= static_cast<double>(nr);
00479 dfe=2000.;
00480 }
00481 else {
00482
00483 dfe=(2.0*nr*nr)/vart;
00484 if(dfe < 1.) dfe=1.;
00485 if(dfe > 2000.) {
00486 dfe=2000.;
00487 }
00488 f_stat = (quq)/nr;
00489
00490 prob = F_cdf(f_stat,static_cast<double>(nr),static_cast<double>(dfe),0.0,errcode);
00491
00492
00493 }
00494 std::string raw_data_code;
00495 double p_value,var,tcal=0.0;
00496 int W = SESSION.output_precision;
00497 std::cout.precision(W);
00498 if(Print_Level < 0) Print_Flag=0;
00499 if (Print_Flag) {
00500 std::cout << "\n RESULTS FROM CONTRAST(S)\n";
00501 std::cout << " ----------------------------------------------------------\n";
00502 std::cout << " Contrast MME_addr K_coef Raw_data_code\n";
00503 std::cout << " ---------------------------------------------\n";
00504 }
00505 for (i=0; i<nr; i++) {
00506 if (Print_Flag) {
00507 kp = kpme[i];
00508 for (j=0; j<nc; j++) {
00509 if (kp[j] == 0.0) continue;
00510 trait_effect_level(j,raw_data_code);
00511 std::cout << std::setw(4) << i+1 <<std::setw(11) << j+1 << std::setw(13) << kp[j]
00512 << " " << raw_data_code << "\n";
00513 }
00514 }
00515 kpd = kpdiff[i];
00516 if (result) {
00517 result[i][0] = kpb_m[i];
00518 result[i][3] = kpd;
00519 }
00520 var = kvkori[i][i];
00521 if (var <= 0.0) throw exception("GLMM::contrast(): you have probably found a bug!");
00522 var = std::sqrt(var);
00523
00524
00525 tcal = fabs(kpb_m[i]/var);
00526
00527 p_value = 2.0*(1.0-t_cdf(tcal,static_cast<double>(dfe),0.0));
00528
00529 if (result) {
00530 result[i][1] = var;
00531 result[i][2] = p_value;
00532 }
00533 if (!Print_Flag) continue;
00534 if (kpd > 1.0e-5) {
00535 est = 0;
00536 std::cout << " **** NON-ESTIMABLE ****\n\n";
00537 }
00538 else {
00539 if (kpd > 1.0e-10) {
00540 std::cout << " ***WARNING***: it may or mayn't be estimable\n";
00541 std::cout << " max(k'*ginv(mme)*mme - k') = " << kpd << "\n";
00542 }
00543 std::cout << " estimated value (K'b-M) = " << kpb_m[i]
00544 << " +- " << var << "\n";
00545 std::cout << " Prob(|t| > " << tcal << ") = "
00546 << p_value << " (p_value)\n";
00547 if(nr == 1 && not_chisq)
00548 std::cout << " " << dfe << " (Error degrees of freedom)\n";
00549 if (i != nr-1) std::cout << "\n";
00550 }
00551 }
00552 if (Print_Flag || Print_Summary) {
00553 std::cout << " ----------------------------------------------------------\n";
00554 if ((nr > 1 || Print_Summary) && est) {
00555 std::cout << " joint hypothesis test H: K'b = M\n";
00556 std::cout << " Prob(F > " << f_stat << ") = "
00557 << 1.0-prob << " (p_value)\n";
00558 if(not_chisq) std::cout << " " << dfe << " (Error degrees of freedom)\n";
00559 }
00560
00561 }
00562 if(Return_Stat) return f_stat;
00563 return 1.0-prob;
00564 }
00565
00566
00567
00568
00569
00570
00571
00572
00573 double GLMM::contrast(const Vector<double>& Kp,const double m)
00574 {
00575
00576
00577
00578
00579 double retval, **kpme = new double *[1];
00580 kpme[0] = Kp.begin();
00581 unsigned nc = Kp.size();
00582 double* M = (double *)NULL;
00583 if (m != 0.0) {
00584 M = new double [1];
00585 M[0] = m;
00586 }
00587 retval = contrast((const double **)kpme,1,nc,M);
00588 delete [] kpme;
00589 if (M) delete [] M;
00590 return retval;
00591 }
00592
00593 double GLMM::contrast(const doubleMatrix& Kp)
00594 {
00595
00596
00597
00598
00599 return contrast((const double **)Kp.begin(), Kp.num_rows(), Kp.num_cols());
00600 }
00601
00602 double GLMM::contrast(const doubleMatrix& Kp,const Vector<double>& M)
00603 {
00604
00605
00606
00607
00608
00609 double retval = 0.0;
00610 int nr = Kp.num_rows();
00611 unsigned nc = Kp.num_cols();
00612 if (M.size() != nr ) throw exception(" GLMM::contrast: size is incomformable");
00613 Vector<double> fullsize_M(hmmesize);
00614 Matrix<double>fullsize_Kp(nr,hmmesize);
00615 for (unsigned i=0; i<nr; i++) {
00616 memcpy(fullsize_Kp[i],Kp[i], sizeof(double)*nc);
00617 }
00618 memcpy(fullsize_M.begin(),M.begin(), sizeof(double)*nc);
00619 retval=GLMM::contrast((const double **)fullsize_Kp.begin(),nr,hmmesize,fullsize_M.begin());
00620 return retval;
00621 }
00622
00623 double GLMM::contrast(const std::string &termname,const doubleMatrix& Kp, const Vector<double>& M)
00624 {
00625 if (!(Kp.begin())) {
00626 warning("GLMM::contrast(kp): kp is null, thus it is ignored");
00627 return 0.0;
00628 }
00629
00630 double retval = 0.0;
00631 if (!get_blupsol()) throw exception("GLMM::contrastranspose(): bad model");
00632
00633 int k = term.index(termname,factor_struct);
00634 if (k < 0) {
00635 warning("GLMM::contrast(): no such term in the model");
00636 return retval;
00637 }
00638
00639 unsigned nr = Kp.num_rows();
00640 unsigned nc = Kp.num_cols();
00641 if (M.size() != nr) {
00642 warning("GLMM::contrast(): unconformable size");
00643 return retval;
00644 }
00645 unsigned i,startaddr;
00646 int nt=nt_vec[k];
00647 if (nc <= term[k].nlevel()*nt) {
00648 startaddr = term[k].startaddr();
00649 Vector<double> fullsize_M(hmmesize);
00650 Matrix<double>fullsize_Kp(nr,hmmesize);
00651 for (i=0; i<nr; i++) {
00652 memcpy(&(fullsize_Kp[i][startaddr]),Kp[i], sizeof(double)*nc);
00653 }
00654 memcpy(&(fullsize_M[startaddr]),M.begin(), sizeof(double)*nc);
00655 retval=contrast((const double **)fullsize_Kp.begin(),nr,hmmesize,fullsize_M.begin());
00656 }
00657 else {
00658 warning("GLMM::contrast(%s,Kp): too many columns in Kp",termname.c_str());
00659 }
00660 return retval;
00661 }
00662
00663 double GLMM::restricted_log_likelihood(int solve)
00664 {
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674 if(!link_function) {
00675
00676 return(Model::restricted_log_likelihood());
00677 }
00678 int Need_PEV_orig=Need_PEV;
00679 Need_PEV=0;
00680 Need_Residual=1;
00681 setup_mme(&rellrhs);
00682 double rellhood = 0.0;
00683
00684 SESSION.warning = 0;
00685 if(solve){
00686 hmmec.solve(blupsol,rellrhs,"ysmp1");
00687
00688 setup_mme(&rellrhs);
00689 }
00690 hmmec.factor();
00691
00692
00693 rellhood = hmmec.info_vec[0];
00694
00695
00696 SESSION.warning = 0;
00697
00698
00699 if(Use_Like)rellhood +=yry+like_adj;
00700
00701 if(!Use_Like)rellhood += yry - blupsol.inner_product(rellrhs);
00702 unsigned i;
00703 int done_ped;
00704 done_ped=0;
00705
00706 for (i=0; i<numterm; i++) {
00707 if (term[i].classi() == 'R'){
00708 rellhood += lng0vec[i]*term[i].nlevel();
00709
00710 }
00711 else if (term[i].classi() =='P' && !done_ped) {
00712
00713 done_ped=1;
00714
00715 rellhood += lng0vec[i]*double(popsize-numgroup);
00716
00717 rellhood -= ldet*double(nt_vec[i]);
00718
00719 }
00720 }
00721 Need_PEV=Need_PEV_orig;
00722 return (-0.5*rellhood);
00723 }
00724
00725
00726
00727
00728 double GLMM::log_likelihood(int solve)
00729 {
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740 if(!link_function) {
00741
00742 return(Model::restricted_log_likelihood());
00743 }
00744
00745 Need_Residual=1;
00746 setup_mme(&rellrhs);
00747 double rellhood = 0.0;
00748
00749 SESSION.warning = 0;
00750 if(solve){
00751 hmmec.solve(blupsol,rellrhs,"ysmp1");
00752 Need_Residual=1;
00753 setup_mme(&rellrhs);
00754 }
00755
00756
00757 rellhood=0.0;
00758
00759
00760
00761 SESSION.warning = 0;
00762
00763
00764 if(Use_Like)rellhood +=yry+like_adj;
00765
00766 if(!Use_Like)rellhood += yry - blupsol.inner_product(rellrhs);
00767 unsigned i;
00768 int done_ped;
00769 done_ped=0;
00770
00771 for (i=0; i<numterm; i++) {
00772 if (term[i].classi() == 'R'){
00773 rellhood += lng0vec[i]*term[i].nlevel();
00774
00775 }
00776 else if (term[i].classi() =='P' && !done_ped) {
00777 done_ped=1;
00778
00779 rellhood += lng0vec[i]*double(popsize-numgroup);
00780
00781 rellhood -= hainv.logdet()*double(act_numtrait);
00782
00783 }
00784 }
00785 return (-0.5*rellhood);
00786 }
00787
00788 #ifdef GLMM_QUAD
00789 extern int ysmp_solve(int n,int *iiv,int *jjv,double *aav,int *p,int *ip,int nsp,
00790 double *rsp,const double *b, double *z,double tol,int& irank,
00791 double& lgdet,int path1,int path2);
00792
00793 double GLMM::quad(double *x, double *y, double *xsol, double *ysol, int path){
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803 double xCy,ldet;
00804 int path1,path2,ir;
00805 xCy=0;
00806 if(!hmmec.perm) hmmec.factorization();
00807 path1=0;
00808 if(path & 1){
00809 path2=13;
00810 ysmp_solve(hmmec.dim,hmmec.iiv,hmmec.jjv,hmmec.aav,
00811 hmmec.perm,hmmec.iperm,hmmec.nsp,hmmec.rsp,y,ysol,
00812 EPSILON,ir,ldet,path1,path2);
00813 }
00814 if(path & 2){
00815 path2=23;
00816 ysmp_solve(hmmec.dim,hmmec.iiv,hmmec.jjv,hmmec.aav,
00817 hmmec.perm,hmmec.iperm,hmmec.nsp,hmmec.rsp,x,xsol,
00818 EPSILON,ir,ldet,path1,path2);
00819 for(int i=0;i< hmmec.dim;i++) xCy += xsol[i]*ysol[i];
00820 }
00821 return(xCy);
00822
00823 }
00824 #endif
00825
00826
00827
00828
00829
00830
00831
00832 doubleMatrix *KP( Data *D,doubleMatrix &SKM_ans,const std::string &lpl,const std::string &censor){
00833
00834
00835 doubleMatrix ret,*retpt;
00836 doubleMatrix SKM;
00837 int ny;
00838 ny=D->num_rows();
00839 doubleMatrix lpl_mat;
00840 lpl_mat.resize(ny,2);
00841 int lpl_col;
00842 if(-1 ==(lpl_col=D->field_index(lpl))) {
00843 warning("KP: Can't find lpl %s \n",lpl.c_str());
00844 return(NULL);
00845 }
00846 for(int i=0;i<ny;i++){
00847 lpl_mat[i][0]=D->datasheet[lpl_col][i].double_val();
00848 }
00849 int status_col;
00850 if(-1 ==(status_col=D->field_index(censor))) {
00851 warning("KP: Can't find status %s \n",censor.c_str());
00852 return(NULL);
00853 };
00854 for(int i=0;i<ny;i++){
00855 lpl_mat[i][1]=D->datasheet[status_col][i].double_val();
00856
00857 }
00858 lpl_mat.sortby(Matrix<double>::COLUMN,0);
00859
00860 int j;
00861 float numdead;
00862 float numcensored;
00863 float lagdead;
00864 float lagcensored;
00865 doubleMatrix skm_dead;
00866 skm_dead.resize(ny,3);
00867 j=0;
00868 lagdead=0.;
00869 lagcensored=0.;
00870 for(int i=0;i<ny;i++){
00871 if(i < ny-1 && lpl_mat[i][0] == lpl_mat[i+1][0]){
00872 if(lpl_mat[i][1]==1){
00873 lagdead++;
00874 }
00875 if(lpl_mat[i][1]==0){
00876 lagcensored++;
00877 }
00878 }
00879 else{
00880 if(lpl_mat[i][1]==1){
00881 numdead=1.+lagdead;
00882 numcensored=lagcensored;
00883 lagdead=0.;
00884 lagcensored=0.;
00885 skm_dead[j][0]=lpl_mat[i][0];
00886 skm_dead[j][1]=numdead;
00887 skm_dead[j][2]=numcensored;
00888 j++;
00889 }
00890 if(lpl_mat[i][1]==0.){
00891 numdead=lagdead;
00892 numcensored=1.+lagcensored;
00893 lagdead=0.;
00894 lagcensored=0.;
00895 skm_dead[j][0]=lpl_mat[i][0];
00896 skm_dead[j][1]=numdead;
00897 skm_dead[j][2]=numcensored;
00898 j++;
00899 }
00900 }
00901 }
00902
00903 skm_dead=skm_dead.submat(0,0,j,3);
00904
00905
00906
00907
00908 SKM.resize(j+1,3);
00909 float tot_alive;
00910 tot_alive=ny;
00911 int k;
00912 k=0;
00913 for(int i=0;i<j+1;i++){
00914 if(i == 0){
00915 SKM[k][0]=0.;
00916 SKM[k][1]=1.;
00917 k++;
00918 }
00919 if(i > 0 && skm_dead[i-1][1] != 0.){
00920 SKM[k][0]=skm_dead[i-1][0];
00921 SKM[k][1]=SKM[k-1][1]*(1.-(skm_dead[i-1][1]/tot_alive));
00922 SKM[k-1][2]=SKM[k][1]/SKM[k-1][1];
00923 SKM[k-1][2]/=SKM[k][0]-SKM[k-1][0];
00924 tot_alive=tot_alive-(skm_dead[i-1][1]+skm_dead[i-1][2]);
00925 k++;
00926 }
00927 if(i > 0 && skm_dead[i-1][1] == 0.){
00928 tot_alive=tot_alive-(skm_dead[i-1][1]+skm_dead[i-1][2]);
00929 }
00930 }
00931 SKM[k-1][2]=SKM[k-2][2];
00932
00933 SKM_ans=SKM.submat(0,0,k,3);
00934 return(&SKM_ans);
00935
00936
00937 }
00938
00939
00940
00941
00942 void GLMM::add_G_Sand(void)
00943 {
00944 for (int t=0; t<numterm; t++) {
00945 if (term[t].classi() == 'P') {
00946 add_AgSand(t);
00947 }
00948 else if (term[t].classi() == 'R') {
00949 add_IgSand(t);
00950 }
00951 }
00952 }
00953
00954 void GLMM::add_IgSand(int t)
00955 {
00956 unsigned k,i,ii,jj;
00957 int t1,t2;
00958 double **v = (double **)NULL;
00959 doubleMatrix *tmp = term[t].prior->var_matrix();
00960 if (!tmp) throw exception("Model::add_Ig(): you probably forgot to use M.variance(...)\n"
00961 " to set variance for each random effect");
00962 v = tmp->begin();
00963 Matrix<double> rv(numtrait,numtrait);
00964 for (t1=0; t1<numtrait; t1++) {
00965 for(t2=0; t2<numtrait; t2++) rv[t1][t2]=v[t1][t2];
00966 }
00967 ginverse1(rv.begin(),numtrait,lng0vec[t],1,EPSILON);
00968
00969 unsigned na = term[t].nlevel();
00970 unsigned startaddr = term[t].start + 1;
00971 for (k=0; k<na; k++) {
00972 i = startaddr + k*numtrait;
00973 for (t1=0; t1<numtrait; t1++) {
00974 ii = i + t1;
00975 for (t2=0; t2<numtrait; t2++) {
00976 jj = i + t2;
00977 if (jj>=ii) hSand.insert(ii,jj,rv[t1][t2]);
00978 }
00979 }
00980 }
00981 }
00982
00983
00984
00985 void GLMM::add_Ag(int t,int ct)
00986 {
00987 unsigned t1, t2, k, i, j, ii, jj, iii, jjj;
00988 double dii,val,value;
00989 double **var = (double **)NULL;
00990 var = corrvar[t][ct].begin();
00991 Matrix<double> rvarg(numtrait,numtrait);
00992 for (i=0; i<numtrait;i++) for (j=0; j<numtrait; j++) rvarg[i][j]= var[i][j];
00993 ginverse1(rvarg.begin(),numtrait,lng0vec[t],1,EPSILON);
00994
00995 Matrix<double> lambda(3,3);
00996 getlambda(lambda.begin(),3);
00997 unsigned startaddr = term[t].start + 1;
00998 unsigned startaddrct = term[ct].start + 1;
00999 unsigned asd[3];
01000 Individual *I;
01001 if(startaddr > startaddrct){
01002 jjj=startaddr;
01003 startaddr =startaddrct;
01004 startaddrct=jjj;
01005 }
01006 for (k=0; k<popsize; k++) {
01007 I = pop->member(k);
01008 asd[0] = I->id(); asd[1] = I->father_id(); asd[2] = I->mother_id();
01009 dii = 4.0/(2.0 - I->father_inbcoef() - I->mother_inbcoef());
01010
01011 for (i=0; i<3; i++) {
01012 if (asd[i] != 0) {
01013 ii = startaddr + (asd[i]-1)*numtrait;
01014 for (j=0; j<3; j++) {
01015 if (asd[j] != 0) {
01016 jj = startaddrct + (asd[j]-1)*numtrait;
01017 val = lambda[i][j]* dii;
01018 for (t1=0; t1<numtrait; t1++) {
01019 iii = ii + t1;
01020 for (t2=0; t2<numtrait; t2++) {
01021 jjj = jj + t2;
01022 if (jjj>=iii) {
01023 value = val*rvarg[t1][t2];
01024 hmmec.insert(iii,jjj,value);
01025 }
01026 }
01027 }
01028 }
01029 }
01030 }
01031 }
01032 }
01033 }
01034
01035
01036 void GLMM::add_AgSand(int t)
01037 {
01038 unsigned t1, t2, k, i, j, ii, jj, iii, jjj;
01039 double dii,val,value;
01040 double **var = (double **)NULL;
01041 doubleMatrix *tmp = term[t].prior->var_matrix();
01042 if (!tmp) throw exception("Model::add_Ag(): you probably forgot to use M.variance(...)\n"
01043 " to set variance for each random effect");
01044 var = tmp->begin();
01045 Matrix<double> rvarg(numtrait,numtrait);
01046 for (i=0; i<numtrait;i++) for (j=0; j<numtrait; j++) rvarg[i][j]= var[i][j];
01047 ginverse1(rvarg.begin(),numtrait,lng0vec[t],1,EPSILON);
01048
01049 Matrix<double> lambda(3,3);
01050 getlambda(lambda.begin(),3);
01051 unsigned startaddr = term[t].start + 1;
01052 unsigned asd[3];
01053 Individual *I;
01054
01055 for (k=0; k<popsize; k++) {
01056 I = pop->member(k);
01057 asd[0] = I->id(); asd[1] = I->father_id(); asd[2] = I->mother_id();
01058 dii = 4.0/(2.0 - I->father_inbcoef() - I->mother_inbcoef());
01059
01060 for (i=0; i<3; i++) {
01061 if (asd[i] != 0) {
01062 ii = startaddr + (asd[i]-1)*numtrait;
01063 for (j=0; j<3; j++) {
01064 if (asd[j] != 0) {
01065 jj = startaddr + (asd[j]-1)*numtrait;
01066 val = lambda[i][j]* dii;
01067 for (t1=0; t1<numtrait; t1++) {
01068 iii = ii + t1;
01069 for (t2=0; t2<numtrait; t2++) {
01070 jjj = jj + t2;
01071 if (jjj>=iii) {
01072 value = val*rvarg[t1][t2];
01073 hSand.insert(iii,jjj,value);
01074 }
01075 }
01076 }
01077 }
01078 }
01079 }
01080 }
01081 }
01082 }
01083
01084 doubleMatrix operator*(Vector<double> &a,Vector<double> &b)
01085 {
01086 int row,col;
01087 row=a.size();
01088 col=b.size();
01089 doubleMatrix temp(row,col);
01090 for(int i=0;i<row;i++) {
01091 for(int j=0;j<col;j++) {
01092 temp[i][j]=a[i]*b[j];
01093 }
01094 }
01095 return temp;
01096 }
01097
01098 void GLMM::covariance_old(const std::string &termname,const std::string &termname2,const doubleMatrix& v)
01099
01100
01101
01102
01103 {
01104 if (!factor_struct) throw exception("Model::variance(args): no equation(s) in the model");
01105
01106 int k = term.index(termname,factor_struct);
01107 int k2 = term.index(termname2,factor_struct);
01108 if(k2<k) {
01109 int kt=k;
01110 k=k2;
01111 k2=kt;
01112 }
01113 if ( k < 0) {
01114 warning("GLMM::covariance(): %s: not in the model",termname.c_str());
01115 type = bad_model;
01116 return;
01117 }
01118 if ( k2< 0) {
01119 warning("GLMM::covariance(): %s: not in the model",termname2.c_str());
01120 type = bad_model;
01121 return;
01122 }
01123 if (term[k].classi() != 'P') {
01124 warning("GLMM::covariance(): %s: no associated Pedigree",termname.c_str());
01125 type = bad_model;
01126 return;
01127 }
01128 if (term[k2].classi() != 'P') {
01129 warning("GLMM::covariance(): %s: no associated Pedigree",termname2.c_str());
01130 type = bad_model;
01131 return;
01132 }
01133 if(!corrmap[k]) {
01134 corrmap[k]=1;
01135 ncorr++;
01136 }
01137 if(!corrmap[k2]) {
01138 corrmap[k2]=1;
01139 ncorr++;
01140 }
01141 if (v.num_rows() == v.num_cols() && v.num_rows() == numtrait) {
01142 corrvar[k][k2]=v;
01143 }
01144 else {
01145 warning("Model::variance(): invalid variance matrix size");
01146 type = bad_model;
01147 }
01148 }
01149
01150
01151 void GLMM::build_CorrVar(void) {
01152 CorrVar.resize(act_numtrait,act_numtrait);
01153 int ipos,jpos,i,j;
01154 doubleMatrix *var;
01155 Matrix<int> posmat(numterm,act_numtrait);
01156 for(i=0,ipos=0;i<numterm;i++) {
01157 if(term[i].classi() == 'P' && corrmap[i]==0) {
01158 corrmap[i]=1;
01159 ncorr++;
01160 }
01161 if(corrmap[i]) {
01162 for(int t=0;t<numtrait;t++) {
01163 posmat[i][t]=ipos++;
01164 }
01165 }
01166 }
01167 for(i=0;i<numterm;i++) {
01168 if(corrmap[i]) {
01169 var = term[i].prior->var_matrix();
01170 for(int t1=0;t1<numtrait;t1++) {
01171 for(int t2=0;t2<numtrait;t2++) {
01172 CorrVar[posmat[i][t1]][posmat[i][t2]]=(*var)[t1][t2];
01173 }
01174 }
01175 for(j=(i+1);j<numterm;j++) {
01176 if(corrmap[j]) {
01177 var = &corrvar[i][j];
01178 for(int t1=0;t1<numtrait;t1++) {
01179 for(int t2=0;t2<numtrait;t2++) {
01180 CorrVar[posmat[i][t1]][posmat[j][t2]]=(*var)[t1][t2];
01181 CorrVar[posmat[j][t2]][posmat[i][t1]]=(*var)[t1][t2];
01182 }
01183 }
01184 }
01185 }
01186 }
01187 }
01188 }
01189
01190 void GLMM::add_G_1_old(void)
01191 {
01192 int done_ped=0;
01193 for (int t=0; t<numterm; t++) {
01194 if (term[t].classi() == 'P' && !done_ped) {
01195 done_ped=1;
01196 Model::add_Ag(t);
01197 }
01198 else if (term[t].classi() == 'R') {
01199 Model::add_Ig(t);
01200 }
01201 }
01202 }
01203
01204
01205 void GLMM::add_Ag_old(int t)
01206 {
01207 unsigned t1, t2, k, i, j, ii, jj, iii, jjj,icnt;
01208 double dii,val,value;
01209 double **var = (double **)NULL;
01210 Vector<int> tmap;
01211 build_CorrVar();
01212 tmap.resize(act_numtrait);
01213 icnt=0;
01214 for(i=t;i<numterm;i++){
01215 if(term[i].classi()=='P') {
01216 for(j=0;j<numtrait;j++,icnt++){
01217 tmap[icnt]=i;
01218 }
01219 }
01220 }
01221
01222 doubleMatrix *tmp = &CorrVar;
01223 if (!tmp) throw exception("Model::add_Ag(): you probably forgot to use M.variance(...)\n"
01224 " to set variance for each random effect");
01225 var = tmp->begin();
01226 Matrix<double> rvarg(act_numtrait,act_numtrait);
01227 for (i=0; i<act_numtrait;i++) for (j=0; j<act_numtrait; j++) rvarg[i][j]= var[i][j];
01228
01229 ginverse1(rvarg.begin(),act_numtrait,lng0vec[t],1,EPSILON);
01230
01231
01232 double f1,f2;
01233 Matrix<double> lambda(3,3);
01234 getlambda(lambda.begin(),3);
01235 unsigned startaddr = term[t].start + 1;
01236 unsigned asd[3];
01237 Individual *I;
01238 unsigned nanim=popsize-numgroup;
01239 for (k=0; k<nanim; k++) {
01240 I = pop->member(k);
01241 asd[0] = I->id(); asd[1] = I->father_id(); asd[2] = I->mother_id();
01242 f1= I->father_inbcoef() ;
01243 f2= I->mother_inbcoef();
01244 if(asd[1]> nanim) f1=-1.;
01245 if(asd[2]> nanim) f2=-1.;
01246 dii = 4.0/(2.0 -f1-f2);
01247
01248 for (i=0; i<3; i++) {
01249 if (asd[i] != 0) {
01250 ii = startaddr + (asd[i]-1)*act_numtrait;
01251 for (j=0; j<3; j++) {
01252 if (asd[j] != 0) {
01253 jj = startaddr + (asd[j]-1)*act_numtrait;
01254 val = lambda[i][j]* dii;
01255 for (t1=0; t1<act_numtrait; t1++) {
01256 iii = ii + t1;
01257 for (t2=0; t2<act_numtrait; t2++) {
01258 jjj = jj + t2;
01259 if (jjj>=iii) {
01260 value = val*rvarg[t1][t2];
01261
01262 hmmec.insert(iii,jjj,value);
01263 }
01264 }
01265 }
01266 }
01267 }
01268 }
01269 }
01270 }
01271 }
01272
01273
01274
01275 void
01276 bound_pd (double *varnew, int numtrait, doubleMatrix & P)
01277 {
01278 int i, j, k, t1, t2;
01279 doubleMatrix varbound (numtrait, numtrait);
01280 Vector<double> eig, flg;
01281 flg.resize (numtrait);
01282 for (k = 0, i = 0; i < numtrait; i++)
01283 for (j = i; j < numtrait; j++, k++)
01284 {
01285 varbound[i][j] = varnew[k];
01286 varbound[j][i] = varnew[k];
01287 }
01288 P = varbound;
01289
01290 eig = P.eigen ();
01291
01292 for (t1 = 0; t1 < numtrait; t1++)
01293 {
01294 flg[t1] = 0;
01295 if (eig[t1] < 1.e-3)
01296 {
01297 eig[t1] = .99e-3;
01298 flg[t1] = 1;
01299 }
01300 if (eig[t1] > 1.e10)
01301 {
01302 eig[t1] = 1.01e10;
01303 flg[t1] = 0;
01304 }
01305 }
01306 varbound = P * diag(eig) * P.transpose();
01307 for (t1 = 0; t1 < numtrait; t1++)
01308 {
01309 if (flg[t1])
01310 {
01311 for (t2 = 0; t2 < numtrait; t2++)
01312 {
01313 P[t1][t2] = 0;
01314 }
01315 }
01316 }
01317
01318 for (k = 0, t1 = 0; t1 < numtrait; t1++)
01319 for (t2 = t1; t2 < numtrait; t2++, k++)
01320 {
01321 varnew[k] = varbound[t1][t2];
01322
01323 }
01324 }
01325
01326 void GLMM::info(std::ostream& stream)
01327 {
01328 if (type == bad_model) {
01329 warning("Model::info(stream): model is too bad");
01330 return;
01331 }
01332 stream.precision(SESSION.output_precision);
01333 stream <<"\n some extra information in the model\n";
01334 stream << " --------------------------------------------------------\n";
01335 if (dfreml_called) {
01336 stream << "optimizor used in dfreml = " << dfreml_method <<"\n";
01337 stream <<"# of function evaluations used in dfreml = "
01338 << nfunk_in_dfreml<<"\n";
01339 stream << "maximum log restricted likelihood in dfreml = "
01340 << reml_value <<"\n";
01341 }
01342 else {
01343 ;
01344 }
01345 if(aireml_called){
01346 stream << "AI REML ";
01347 if(aireml_called < 0) stream << "failed to converge\n";
01348 else stream << "converged\n";
01349 stream << "maximum log restricted likelihood = "
01350 << restricted_log_likelihood(0) <<"\n";
01351 }
01352 const ModelTerm *T;
01353 int i,done_ped,nt;
01354 doubleMatrix *var;
01355 done_ped=0;
01356 for (i=0; i<numterm; i++) {
01357 T = &(term(i));
01358 if (T->classi() == 'R' || (T->classi() == 'P' && !done_ped)) {
01359 nt=nt_vec[i];
01360 var=T->prior->var_matrix();
01361
01362
01363
01364
01365
01366
01367 stream << " variance for "
01368 << factor_struct[T->factorindx[0]].name() << " = \n"
01369 << (*var);
01370 }
01371 }
01372 stream << " residual variance =\n" << residual_var;
01373
01374 if (data_prepared) {
01375 stream << "\n";
01376 stream << " MME dimension : " << hmmesize << "\n";
01377 stream << " non-zeros in MME: " << hmmec.nz() << "\n\n";
01378
01379 stream << " basic statistics for dependent variables\n";
01380 stream << " -----------------------------------------------------\n";
01381 stream << " trait-name n mean std\n";
01382 unsigned n;
01383 for (i=0; i<numtrait; i++) {
01384
01385 n = trait_struct[i]->nlevel();
01386 stream << " " << std::setw(16) << trait_struct[i]->name()
01387 << " " << std::setw(10) << n
01388 << " " << std::setw(12) << trait_struct[i]->mean();
01389 if (n==1) {
01390 stream << " " << std::setw(12) << "." << "\n";
01391 }
01392 else {
01393 stream<< " " << std::setw(12) << trait_struct[i]->std() << "\n";
01394 }
01395 }
01396 }
01397 stream << " --------------------------------------------------------\n";
01398 }
01399
01400
01401
01402 void GLMM::save(const std::string &fname, const int io_mode)
01403 {
01404 if (type == bad_model) {
01405 warning("Model::save(): model is too bad, nothing is saved");
01406 return;
01407 }
01408 if((numterm+ntermGdist) == 0) return;
01409 if (blupsol.size() != hmmesize + ntermGdist*popsize) return;
01410 if (!data) {
01411 warning("Model::save(): no data has been fitted");
01412 return;
01413 }
01414 std::ofstream ofs;
01415 ofs.open(fname.c_str(),(OpenModeType)io_mode);
01416 if (!ofs) throw exception("Model::save(): cann't open or already exit");
01417 ofs.setf(std::ios::unitbuf | std::ios::showpoint);
01418 ofs.precision(SESSION.output_precision);
01419 int W = SESSION.output_precision + 6;
01420 char S = ' ';
01421
01422 if (!data->in_memory()) data->input_datasheet();
01423 this->info(ofs);
01424
01425 double *ve = blupsol.begin();
01426
01427 char* tempstr;
01428 int nord, *tempval;
01429 unsigned *tempuns;
01430 unsigned i,j,t,k,ii,kk,jj,nlevel,total_numterm;
01431 char CL;
01432
01433 ofs << "\n BLUP (BLUE, Posterior_Mean) \n";
01434 ofs << " ----------------------------------------------- \n\n";
01435 total_numterm = numterm+ntermGdist;
01436 for (i=0; i<total_numterm; i++) {
01437 ofs << S << std::setw(W)<< "Term";
01438 for (t=0; t<numtrait; t++) {
01439 ofs << S << std::setw(W-2) << "Trait" << S << std::setw(2) << t+1;
01440 }
01441 ofs <<"\n";
01442
01443 ofs << S << std::setw(W) << factor_struct[term[i].factorindx[0]].name();
01444 for (t=1; t<term[i].order(); t++) {
01445 ofs << "*" << factor_struct[term[i].factorindx[t]].name();
01446 }
01447 for (t=0; t<numtrait; t++) ofs <<S <<std::setw(W)<<trait_struct[t]->name();
01448 ofs << "\n";
01449 nlevel = term[i].nlevel();
01450 k = term[i].startaddr();
01451 nord = term[i].order();
01452 if (nord == 1) {
01453 kk = factor_struct[term[i].factorindx[0]].index();
01454 CL = data->datasheet[kk].classi();
01455 switch(CL) {
01456 case 'F':
01457 for (j=0; j<nlevel; j++) {
01458 tempval = (int *)(idlist[kk]->find(j+1));
01459 ofs << S << std::setw(W) << *tempval;
01460 for (t=0; t<numtrait; t++,k++) {
01461 ofs << S << std::setw(W);
01462 if (term[i].trait[t]) {
01463 ofs << ve[k];
01464 }
01465 else {
01466 ofs << S;
01467 }
01468 }
01469 k+=(nt_vec[base_effect[i]]-numtrait);
01470 ofs << "\n";
01471 }
01472 break;
01473 case 'U':
01474 for (j=0; j<nlevel; j++) {
01475 tempstr = (char *)(idlist[kk]->find(j+1));
01476 ofs << S << std::setw(W) << tempstr;
01477 for (t=0; t<numtrait; t++,k++) {
01478 ofs << S << std::setw(W);
01479 if (term[i].trait[t]) {
01480 ofs << ve[k];
01481 }
01482 else {
01483 ofs << S;
01484 }
01485 }
01486 ofs << "\n";
01487 }
01488 break;
01489 case 'P':
01490 for (j=0; j<nlevel; j++) {
01491 ofs << S;
01492 if (pop->maxnamelen > 0) {
01493 ofs << std::setw(W) << (char *)pop->hashtable.find(j+1);
01494 }
01495 else {
01496 ofs << std::setw(W) << j+1;
01497 }
01498 for (t=0; t<numtrait; t++,k++) {
01499 ofs << S;
01500 if (term[i].trait[t]) {
01501 ofs << std::setw(W) << ve[k];
01502 }
01503 else {
01504 ofs << std::setw(W) << S;
01505 }
01506 }
01507 k+=(nt_vec[base_effect[i]]-numtrait);
01508 ofs << "\n";
01509 }
01510 break;
01511 case 'C':
01512 ofs << S << std::setw(W) << data->datasheet[kk].name();
01513 for (t=0; t<numtrait; t++,k++) {
01514 ofs << S << std::setw(W);
01515 if (term[i].trait[t]) {
01516 ofs << ve[k];
01517 }
01518 else {
01519 ofs << S;
01520 }
01521 }
01522 ofs << "\n";
01523 break;
01524 case 'I':
01525 ofs << S << std::setw(W) << "1";
01526 for (t=0; t<numtrait; t++,k++) {
01527 ofs << S << std::setw(W);
01528 if (term[i].trait[t]) {
01529 ofs << ve[k];
01530 }
01531 else {
01532 ofs << S;
01533 }
01534 }
01535 ofs << "\n";
01536 break;
01537 default:
01538 warning("Model.save(): unknown column type: %c",CL);
01539 break;
01540 }
01541 if (i+1 < total_numterm) ofs << "\n";
01542 }
01543 else {
01544 for (j=0; j<nlevel; j++) {
01545 tempuns = (unsigned *)(xact_htable[i].find(j+1));
01546 kk = factor_struct[term[i].factorindx[0]].index();
01547 CL = data->datasheet[kk].classi();
01548 jj = tempuns[0];
01549
01550 if (CL == 'F') {
01551 tempval = (int *)(idlist[kk]->find(jj));
01552 ofs << S << std::setw(W) << *tempval;
01553 }
01554 else if (CL =='U') {
01555 tempstr = (char *)(idlist[kk]->find(jj));
01556 ofs << S << std::setw(W) << tempstr;
01557 }
01558 else if ( CL =='C') {
01559 ofs << S << std::setw(W) << data->datasheet[kk].name();
01560 }
01561 else if (CL =='P') {
01562 ofs << S << std::setw(W) << (char *)pop->hashtable.find(jj);
01563 }
01564 else if (CL =='I') {
01565 ofs << S << std::setw(W) << "1";
01566 }
01567 else {
01568 warning("Model::save(): unknown column type: %c",CL);
01569 break;
01570 }
01571
01572 for (ii=1; ii<nord; ii++) {
01573 kk = factor_struct[term[i].factorindx[ii]].index();
01574 CL = data->datasheet[kk].classi();
01575 jj = tempuns[ii];
01576
01577 if (CL == 'F') {
01578 tempval = (int *)(idlist[kk]->find(jj));
01579 ofs << "*" << *tempval;
01580 }
01581 else if (CL =='U') {
01582 tempstr = (char *)(idlist[kk]->find(jj));
01583 ofs << "*" << tempstr;
01584 }
01585 else if (CL =='C' || CL =='I') {
01586 ofs << "*" << data->datasheet[kk].name();
01587 }
01588 else if (CL =='P') {
01589 ofs << "*" << (char *)pop->hashtable.find(jj);
01590 }
01591 else {
01592 warning("Model::save(): unknown column type: %c",CL);
01593 }
01594 }
01595 for (t=0; t<numtrait; t++,k++) {
01596 ofs << S << std::setw(W);
01597 if (term[i].trait[t]) ofs << ve[k];
01598 else ofs << S;
01599 }
01600
01601 k+=(nt_vec[base_effect[i]]-numtrait);
01602 ofs << "\n";
01603 }
01604 if (i+1 < total_numterm) ofs << "\n";
01605 }
01606 }
01607 ofs.close();
01608 if(!data_static) data->release_datasheet();
01609 }
01610
01611 static int squeeze(unsigned len,int *ia,int *ja,double *a)
01612
01613
01614
01615
01616
01617
01618 {
01619 unsigned lmar = 1;
01620 unsigned rmar = len;
01621 for (;;) {
01622 if (lmar >= rmar) {
01623 if (ia[lmar] == 0 && rmar == lmar) return(rmar-1);
01624 else return(rmar);
01625 }
01626 if ( ia[lmar] != 0) {
01627 lmar++;
01628 }
01629 else if (ia[rmar] == 0) {
01630 rmar--;
01631 }
01632 else {
01633 ia[lmar] = ia[rmar];
01634 ja[lmar] = ja[rmar];
01635 a[lmar] = a[rmar];
01636 lmar++;
01637 rmar--;
01638 }
01639 }
01640 }
01641
01642 static void hsort_ija(unsigned n,int *ia,int *ja,double *a)
01643
01644
01645
01646
01647
01648 {
01649 unsigned iia, jja,i,j,l,ir;
01650 double aa;
01651 if (n == 1) return;
01652 l = (n >> 1)+1;
01653 ir=n;
01654 for (;;) {
01655 if (l > 1) {
01656 l = l-1; iia = ia[l]; jja = ja[l]; aa = a[l];
01657
01658 }
01659 else {
01660 iia = ia[ir]; jja = ja[ir]; aa = a[ir];
01661 ia[ir] = ia[1]; ja[ir] = ja[1]; a[ir] = a[1];
01662 ir--;
01663 if(ir == 1) {
01664 ia[1] = iia; ja[1] = jja; a[1] = aa;
01665 return;
01666 }
01667 }
01668 i=l;
01669 j=l+l;
01670 while ( j <= ir) {
01671 if (j < ir) {
01672 if (ia[j]<ia[j+1] || (ia[j]==ia[j+1] && ja[j] < ja[j+1])) j++;
01673 }
01674 if (iia < ia[j] || (iia == ia[j] && jja < ja[j])) {
01675 ia[i] = ia[j]; ja[i] = ja[j]; a[i] = a[j];
01676 i=j;
01677 j=j+j;
01678 }
01679 else {
01680 j=ir+1;
01681 }
01682 }
01683 ia[i] = iia; ja[i] = jja; a[i] = aa;
01684 }
01685 }
01686
01687 #ifdef DO_THREADS
01688 #include "pt.h"
01689
01690 struct thread_arg {
01691 SparseMatrix *A,*Ainv;
01692 unsigned *rowdone,*order,hmmesize;
01693 int *ia,*ja,*lhs_ia,*lhs_ja;
01694 pthread_mutex_t *mdone_mutex;
01695 };
01696
01697
01698 int nextrow(int *lhs_ia,int *lhs_ja,unsigned *rowdone,pthread_mutex_t *mdone_mutex,int hmmesize, int i,unsigned *order,SparseMatrix *hInv,Vector<double> &InvCol) {
01699 int res;
01700
01701 pt_mutex_lock(mdone_mutex,"mutex lck");
01702 if(i) {
01703 for(int jj=lhs_ia[i];jj<lhs_ia[i+1];jj++) {
01704
01705 hInv->insert(order[i-1],order[lhs_ja[jj]-1],InvCol[order[lhs_ja[jj]-1]-1]);
01706 }
01707 }
01708 *rowdone=(*rowdone)+1;
01709 res=*rowdone;
01710 pt_mutex_unlock(mdone_mutex,"mutex unlck");
01711 return(res<=hmmesize ? res : -1);
01712
01713 }
01714
01715
01716 pt_addr_t thread_code(pt_arg_t *t_arg)
01717 {
01718 thread_arg *arg=(thread_arg *)t_arg->data;
01719
01720
01721 int n,p;
01722 int m;
01723 double sum;
01724 int *lhs_ia=arg->lhs_ia;
01725 int *lhs_ja=arg->lhs_ja;
01726 int *ia=arg->ia;
01727 int *ja=arg->ja;
01728 unsigned *rowdone=arg->rowdone;
01729 m=0;
01730 pthread_mutex_t *mdone_mutex=arg->mdone_mutex;
01731 unsigned *order=arg->order;
01732 SparseMatrix *hInv=arg->Ainv;
01733 SparseMatrix *hmmec=arg->A;
01734 unsigned hmmesize=arg->hmmesize;
01735 Vector<double> InvCol,wrkVec;
01736 wrkVec.resize(hmmesize);
01737 InvCol.resize(hmmesize);
01738
01739
01740 while ((m=nextrow(lhs_ia,lhs_ja,rowdone,mdone_mutex,hmmesize,m,order,hInv,InvCol))!=-1) {
01741 wrkVec(order[m-1])=1;
01742 hmmec->solvrow(InvCol.begin(),wrkVec.begin(),m);
01743 wrkVec(order[m-1])=0;
01744 }
01745 return(NULL);
01746 }
01747 #endif
01748
01749
01750 void GLMM::build_hInv()
01751 {
01752
01753 unsigned row=0;
01754 Vector<double> InvCol,wrkVec;
01755 int *lhs_ia,*lhs_ja,*lhs_sh,nz;
01756 double *lhs_a;
01757 unsigned hsize=hmmesize;
01758 InvCol.resize(hmmesize);
01759 wrkVec.resize(hmmesize);
01760 hInv.resize(hmmesize,max_nz);
01761 #ifdef DEBUG
01762 doubleMatrix LHS;
01763 LHS=hmmec.dense();
01764 std::cout << "\nbuild_hInv LHS\n"<<LHS <<"\n";
01765 #endif
01766 if (!hmmec.factor_done) hmmec.factor();
01767 unsigned int *order=hmmec.order.begin();
01768
01769 #ifdef DO_THREADS
01770 pthread_mutex_t mdone_mutex;
01771 pt_mutex_init(&mdone_mutex,"init mutex");
01772
01773 thread_arg mult_arg;
01774 mult_arg.mdone_mutex=&mdone_mutex;
01775 mult_arg.A=&hmmec;
01776 mult_arg.Ainv=&hInv;
01777 mult_arg.hmmesize=hmmesize;
01778 mult_arg.rowdone=&row;
01779 mult_arg.order=hmmec.order.begin();
01780 #endif
01781 int *ia = hmmec.iiv-1;
01782 int *ja = hmmec.jjv-1;
01783 double *a = hmmec.aav-1;
01784 unsigned nrow = 0;
01785 unsigned oldrow = 0;
01786 nz=squeeze(hmmec.hsize,ia,ja,a);
01787 for(int i=1;i<=nz;i++) {
01788 ia[i]=hmmec.inv_order[ia[i]-1];
01789 ja[i]=hmmec.inv_order[ja[i]-1];
01790 if(ja[i] < ia[i]) {
01791 int itmp=ia[i];
01792 ia[i]=ja[i];
01793 ja[i]=itmp;
01794 }
01795 }
01796 hsort_ija(nz,ia,ja,a);
01797 for (int k=1; k<=nz ; k++) {
01798 if (ia[k] != oldrow) {
01799 nrow++;
01800 ia[nrow] = k;
01801 oldrow = ia[k];
01802 }
01803 }
01804 ia[hmmec.dim+1] = nz+1;
01805
01806 lhs_ia=hmmec.ia();
01807 lhs_ja=hmmec.ja();
01808 lhs_a=hmmec.a();
01809 #ifdef DO_THREADS
01810 mult_arg.ia=ia;
01811 mult_arg.ja=ja;
01812 mult_arg.lhs_ja=lhs_ja;
01813 mult_arg.lhs_ia=lhs_ia;
01814 int NTHREADS;
01815 char *MP_NUM;
01816 NTHREADS=1;
01817 MP_NUM=getenv("MP_NUM_THREADS");
01818 if(MP_NUM) NTHREADS=atol(MP_NUM);
01819 if(NTHREADS >1) {
01820 NTHREADS--;
01821 std::cout << "Nthreads "<< NTHREADS << "\n";
01822
01823
01824
01825
01826
01827
01828
01829 }
01830 else{
01831 #endif
01832 Vector<double> solwrk,temp_rhswrk;
01833 Vector<unsigned int> temp_col,temp_row;
01834 int m,jj;
01835 #pragma omp parallel private(jj,m,wrkVec,solwrk,temp_rhswrk,InvCol,temp_col,temp_row)
01836 {
01837 #pragma omp critical
01838 {
01839 wrkVec.resize(hmmesize);
01840 InvCol.resize(hmmesize);
01841 solwrk.resize(hmmesize);
01842 temp_rhswrk.resize(hmmesize);
01843 temp_row.resize(hmmesize);
01844 temp_col.resize(hmmesize);
01845 }
01846 #pragma omp for schedule(dynamic,50) nowait
01847 for(m=1;m<=hmmesize;m++) {
01848 wrkVec(order[m-1])=1;
01849 hmmec.solvrow(InvCol.begin(),wrkVec.begin(),m,solwrk,temp_rhswrk,temp_row.begin(),temp_col.begin());
01850 wrkVec(order[m-1])=0;
01851 {
01852 for(jj=lhs_ia[m];jj<lhs_ia[m+1];jj++) {
01853
01854
01855 hInv.insert(order[m-1],order[lhs_ja[jj]-1],InvCol[lhs_ja[jj]-1]);
01856 }
01857 }
01858 }
01859 }
01860 #ifdef DO_THREADS
01861 pt_mutex_destroy(&mdone_mutex,"del mutex");
01862 }
01863 #endif
01864 }
01865
01866 doubleMatrix GLMM::getVarEstimates(const std::string &termname)
01867 {
01868
01869
01870 doubleMatrix* retval = 0;
01871 if (type == bad_model) {
01872 warning("Model::info(stream): model is too bad");
01873 return *retval;
01874 }
01875 int k = term.index(termname,factor_struct);
01876 if (k < 0) throw exception("GLMM::getVarEstimates: no such term in the model");
01877 const ModelTerm *T;
01878 T = &(term(k));
01879 if (T->classi() == 'R' || (T->classi() == 'P')) {
01880 retval=T->prior->var_matrix();
01881 }
01882 return *retval;
01883 }
01884
01885 }
01886
01887