00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <iostream>
00023 #include "geneticdist.h"
00024 #include <cstdarg>
00025
00026
00027 namespace matvec {
00028
00029
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
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
00068
00069 GeneticDist::GeneticDist(const unsigned nc,...)
00070 {
00071 numchrom = 0;
00072 chromosome = 0;
00073 numtrait = 1;
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;
00095 numMarkerLoci = A.numMarkerLoci;
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
00135 if (strcmp(qm,"qtl")==0) {
00136 L->qtl_ml='q';
00137 L->genotypic_val_mat.resize(na,na);
00138 }
00139
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
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
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
00168
00169 void GeneticDist::genotypic_val(const unsigned c,const unsigned l,
00170 const double* v)
00171 {
00172
00173
00174
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
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
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
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
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
00313 if (strcmp(qm,"qtl")==0) {
00314 L->qtl_ml='q';
00315 L->genotypic_val_mat.resize(na,na);
00316 }
00317
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
00327
00328
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
00335 }
00336
00337 if (fabs(sumf-1.0) > 1.0e-10) throw exception("GeneticDist::locus(): allele_freq does not sum to 1.0");
00338 }
00339
00340 }