Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

geneticdist.cpp

Go to the documentation of this file.
00001 //****************************************************
00002 //  April, 1993, University of Illinois
00003 // Copyright (C) 1993, 1994 Tianlin Wang
00004 /* Copyright (C) 1994-2003 Matvec Development Team. 
00005 
00006   This program is free software; you can redistribute it and/or
00007   modify it under the terms of the GNU Library General Public
00008   License as published by the Free Software Foundation; either
00009   version 2 of the License, or (at your option) any later version.
00010   
00011   This program is distributed in the hope that it will be useful,
00012   but WITHOUT ANY WARRANTY; without even the implied warranty of
00013   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014   Library General Public License for more details.
00015     
00016   You should have received a copy of the GNU Library General Public
00017   License along with this library; if not, write to the Free
00018   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00019   MA 02111-1307, USA 
00020 */
00021 
00022 #include <iostream>
00023 #include "geneticdist.h"
00024 #include <cstdarg>
00025 
00026 
00027 namespace matvec {
00028 
00029 /////////////////////////// LocusStruct class ///////////////////////
00030 
00031 void LocusStruct::copyfrom(const LocusStruct& A)
00032 {
00033    resize(A.numallele);
00034    qtl_ml = A.qtl_ml;
00035    allele_freq = A.allele_freq;
00036    genotypic_val_mat = A.genotypic_val_mat;
00037 }
00038 
00039 void LocusStruct::resize(const unsigned na)
00040 {
00041    if (numallele == na) return;
00042    numallele = na;
00043    allele_freq.resize(numallele);
00044    genotypic_val_mat.resize(numallele,numallele);
00045 }
00046 
00047 /////////////////////////// ChromStruct class ///////////////////////
00048 
00049 void ChromStruct::copyfrom(const ChromStruct& A)
00050 {
00051    if (this == &A) return;
00052    resize(A.numloci);
00053    recomb_rate_mat = A.recomb_rate_mat;
00054 }
00055 
00056 void ChromStruct::resize(const unsigned nl)
00057 {
00058    if (numloci == nl) return;
00059    numloci = nl;
00060    locus.resize(numloci);
00061    recomb_rate_mat.resize(numloci,numloci,0.5);
00062 }
00063 
00064 void ChromStruct::release(void)
00065 {locus.resize(0);numloci = 0;}
00066 
00067 /////////////////////////// GeneticDist class ///////////////////////
00068 
00069 GeneticDist::GeneticDist(const unsigned nc,...)
00070 {
00071    numchrom = 0;
00072    chromosome = 0;
00073    numtrait = 1;      // temporary value
00074    numMarkerLoci = 0;
00075    resize(nc);
00076    va_list param_pt;
00077    va_start(param_pt,nc);
00078    unsigned nl;
00079    for (unsigned i=0; i<nc; i++) {
00080       nl = va_arg(param_pt,unsigned);
00081       chromosome[i].resize(nl);
00082    }
00083    va_end(param_pt);
00084    strcpy(distname,"GeneticDist");
00085 }
00086 
00087 void GeneticDist::copyfrom(const GeneticDist& A)
00088 {
00089    if (this == &A) return;
00090    resize(A.numchrom);
00091    for (unsigned i=0; i<numchrom; i++) chromosome[i] = A.chromosome[i];
00092    strcpy(distname,A.distname);
00093 
00094    numtrait = A.numtrait;  // Occurs in old version
00095    numMarkerLoci = A.numMarkerLoci;  //LRT
00096 }
00097 
00098 void GeneticDist::nchrom(const unsigned nc)
00099 {
00100    if (numchrom == nc) return;
00101    numchrom = nc;
00102    if (chromosome) {
00103      delete [] chromosome;
00104      chromosome=0;
00105    }
00106    if(numchrom>0){
00107      chromosome = new ChromStruct[numchrom];
00108    }
00109    else {
00110      chromosome = 0;
00111    }
00112    check_ptr(chromosome);
00113 }
00114 
00115 void GeneticDist::nloci(const unsigned nl0,...)
00116 {
00117    chromosome[0].resize(nl0);
00118    va_list param_pt;
00119    va_start(param_pt,nl0);
00120    unsigned nl;
00121    for (int i=1;i<numchrom;i++) {
00122       nl = va_arg(param_pt,unsigned);
00123       chromosome[i].resize(nl);
00124    }
00125    va_end(param_pt);
00126 }
00127 
00128 void GeneticDist::locus(const unsigned c,const unsigned l,const char qm[],
00129                      const unsigned na, ...)
00130 {
00131    if (c < 1 || c>numchrom || l < 1 || l> chromosome[c-1].nloci()) throw exception("GeneticDist::locus(): bad args");
00132    LocusStruct *L = &(chromosome[c-1].locus[l-1]);
00133    
00134    //RLF modified block
00135    if (strcmp(qm,"qtl")==0) {
00136      L->qtl_ml='q';
00137      L->genotypic_val_mat.resize(na,na);
00138    }
00139    // next else if added by LRT
00140    else if(strcmp(qm,"recessiveLocus")==0) { 
00141      L->qtl_ml='r';
00142    }
00143    else {
00144      L->qtl_ml = 'm';
00145      numMarkerLoci++;
00146    }
00147    L->nallele(na);
00148    L->allele_freq.resize(na);
00149 //RLF modified block
00150    va_list param_pt;
00151    va_start(param_pt,na);
00152    double sumf = 0.0;
00153    for (int i=0;i<na; i++) sumf += L->allele_freq[i] = va_arg(param_pt,double);
00154    va_end(param_pt);
00155    if (fabs(sumf-1.0) > 1.0e-10) throw exception("GeneticDist::locus(): allele_freq does not sum to 1.0");
00156 }
00157 
00158 //RLF
00159 void GeneticDist::putColmNames(const unsigned c,const unsigned l,
00160                                 char nm1[],char nm2[])
00161 {
00162    if (c < 1 || c>numchrom || l < 1 || l> chromosome[c-1].nloci()) throw exception("GeneticDist::locus(): bad args");
00163    LocusStruct *L = &(chromosome[c-1].locus[l-1]);
00164    L->nameOfcol1 = nm1;
00165    L->nameOfcol2 = nm2;
00166 }
00167 //RLF
00168 
00169 void GeneticDist::genotypic_val(const unsigned c,const unsigned l,
00170                                 const double* v)
00171 {
00172    ///////////////////////////////////////////
00173    // requiements
00174    // v must have enough elements
00175    ///////////////////////////////////////////
00176    if (c < 1 || c>numchrom || l < 1 || l>chromosome[c-1].nloci()) throw exception("GeneticDist::genotypic_val(): bad args");
00177    unsigned i,j,k,na,cc,ll;
00178    cc = c-1; ll = l-1;
00179    na = chromosome[cc].locus[ll].nallele();
00180    double **me = chromosome[cc].locus[ll].genotypic_val_mat.begin();
00181    for (k=0,i=0; i<na; i++) for (j=0; j<=i; j++) {
00182       me[i][j] = v[k++];
00183       me[j][i] =  me[i][j];
00184    }
00185 }
00186 
00187 void GeneticDist::genotypic_val(const unsigned c,const unsigned l,
00188                                  const double v0,...)
00189 {
00190    if (c < 1 || c>numchrom || l < 1 || l>chromosome[c-1].nloci()) throw exception("GeneticDist::genotypic_val(): bad args");
00191    unsigned i,j,na,cc,ll;
00192    cc = c-1; ll = l-1;
00193    na = chromosome[cc].locus[ll].nallele();
00194    double **me = chromosome[cc].locus[ll].genotypic_val_mat.begin();
00195    me[0][0] = v0;
00196    va_list ppt;
00197    va_start(ppt,v0);
00198    for (j=1; j<na; j++) me[j][0] = me[0][j] = va_arg(ppt,double);
00199    for (i=1;i<na;i++) for (j=i;j<na;j++) me[j][i]=me[i][j]= va_arg(ppt,double);
00200    va_end(ppt);
00201 }
00202 
00203 void GeneticDist::release(void)
00204 {
00205    if (chromosome) {
00206       delete [] chromosome; chromosome = 0; numchrom = 0;
00207    }
00208 }
00209 
00210 double GeneticDist::recomb_rate(const unsigned c,const unsigned li,
00211                                  const unsigned lj)
00212 {
00213    if (c==0 || li==0) throw exception("GeneticDist::recomb_rate(): bad args");
00214    double d=0.0;
00215    unsigned k, ii=li-1;
00216    for (k=li; k<lj; k++) d += chromosome[c-1].recomb_rate_mat[ii][k];
00217    return 0.5*tanh(2.0*d);
00218 }
00219 
00220 void GeneticDist::recomb_rate(const unsigned c,const unsigned li,
00221                               const unsigned lj, const double r)
00222 {
00223    if (c <= 0) throw exception("GeneticDist.recomb_rate(): out of range");
00224    int n = chromosome[c-1].nloci();
00225    if (li<1 || li>n || lj<1 || lj>n) throw exception("GeneticDist::recomb_rate(): out of range");
00226    chromosome[c-1].recomb_rate_mat[li-1][lj-1] = r;
00227 }
00228 
00229 ///////////////////  UnknownDist class /////////////////////////////
00230 
00231 UnknownDist::UnknownDist(const Vector<double> mu, const doubleMatrix sigma)
00232 {
00233    mu_vec = mu;
00234    dim = mu_vec.size();
00235    if (sigma.psd()) {
00236       if (dim == sigma.num_rows()) {
00237          var_mat = sigma;
00238       } else {
00239           warning(" UnknownDist(u,V): u and V incompatible");
00240       }
00241    } else {
00242       warning(" UnknownDist(u,V): V must be psd ");
00243    }
00244    strcpy(distname,"Unknown");
00245 }
00246 UnknownDist::UnknownDist(const double mu, const double sigma)
00247 {
00248    resize(1);
00249    mu_vec[0] = mu;
00250    var_mat[0][0] = sigma;
00251    strcpy(distname,"Unknown");
00252 }
00253 
00254 void UnknownDist::copyfrom(const UnknownDist& A)
00255 {
00256    if (this == &A) return;
00257    dim = A.dim;
00258    mu_vec = A.mu_vec;
00259    var_mat = A.var_mat;
00260    strcpy(distname,A.distname);
00261 }
00262 
00263 void UnknownDist::resize(const unsigned n)
00264 {
00265    if (dim == n) return;
00266    dim = n;
00267    mu_vec.resize(dim);
00268    var_mat.resize(dim,dim);
00269 }
00270 
00271 //BRS
00272 void GeneticDist::put_distance(const unsigned c,const unsigned l, double dist)
00273 {
00274    if (c < 1 || c>numchrom || l < 1 || l> chromosome[c-1].nloci()) throw exception("GeneticDist::put_distance() : bad args");
00275    LocusStruct *L = &(chromosome[c-1].locus[l-1]);
00276    L->distance = dist;
00277 }
00278 double GeneticDist::get_distance(const unsigned c,const unsigned l)
00279 {
00280    if (c < 1 || c>numchrom || l < 1 || l> chromosome[c-1].nloci()) throw exception(" GeneticDist.get_distance(): bad args");
00281    LocusStruct *L = &(chromosome[c-1].locus[l-1]);
00282    return (L->distance);
00283 }
00284 
00285 void GeneticDist::multi_loci(int num_loci)
00286 {
00287 
00288    resize(1);
00289 //   cout << "in GeneticDist::multi_loci: numtrait = " << numtrait<< endl;
00290    chromosome[0].resize(num_loci);
00291 }
00292 
00293 int GeneticDist::display(void) {
00294   if (chromosome) {
00295     std::cout << "GeneticDist Object: nloci = " << chromosome[0].nloci() << std::endl;
00296              std::cout << "numtrait = " << numtrait <<  std::endl;
00297   }
00298   else {
00299     std::cout << "GeneticDist Object: nloci not initialized yet " << std::endl;
00300     std::cout << "numtrait = " << numtrait <<  std::endl;
00301   }
00302   return 1;
00303 }
00304 
00305 void GeneticDist::locus(const unsigned c,const unsigned l,const char qm[],
00306                                      const unsigned na, Vector<double> init_freqs)
00307 {
00308         //      std::cout << "V " << c << " " << l << " " << na << std::endl;
00309   if (c < 1 || c>numchrom || l < 1 || l> chromosome[c-1].nloci()) throw exception("GeneticDist::locus(): bad args");
00310   LocusStruct *L = &(chromosome[c-1].locus[l-1]);
00311   
00312   //RLF modified block
00313   if (strcmp(qm,"qtl")==0) {
00314     L->qtl_ml='q';
00315     L->genotypic_val_mat.resize(na,na);
00316   }
00317   // next else if added by LRT
00318   else if(strcmp(qm,"recessiveLocus")==0) { 
00319     L->qtl_ml='r';
00320   }
00321   else  {
00322     L->qtl_ml = 'm';
00323   }
00324   L->nallele(na);
00325   L->allele_freq.resize(na);
00326   //RLF modified block
00327   //   va_list param_pt;
00328   //   va_start(param_pt,na);
00329   double sumf = 0.0, temp=0.0;
00330   for (int i=0;i<na; i++) {
00331     temp=init_freqs[i];
00332     sumf += temp;
00333     L->allele_freq[i] = temp;
00334     //     std::cout << i << " freq " << temp << " Sumf " << sumf << std::endl;
00335   }
00336   //   va_end(param_pt);
00337   if (fabs(sumf-1.0) > 1.0e-10) throw exception("GeneticDist::locus(): allele_freq does not sum to 1.0");
00338 }
00339 //BRS
00340 } ////////////// end of namespace matvec

Generated on Thu Jun 16 17:13:41 2005 for Matvec by doxygen1.2.16