2
// File: MixedSubstitutionModelSet.cpp
3
// Created by: Laurent Guéguen
4
// Created on: mercredi 25 mai 2011, à 22h 12
8
Copyright or <A9> or Copr. CNRS, (November 16, 2004)
10
This software is a computer program whose purpose is to provide classes
11
for phylogenetic data analysis.
13
This software is governed by the CeCILL license under French law and
14
abiding by the rules of distribution of free software. You can use,
15
modify and/ or redistribute the software under the terms of the CeCILL
16
license as circulated by CEA, CNRS and INRIA at the following URL
17
"http://www.cecill.info".
19
As a counterpart to the access to the source code and rights to copy,
20
modify and redistribute granted by the license, users are provided only
21
with a limited warranty and the software's author, the holder of the
22
economic rights, and the successive licensors have only limited
25
In this respect, the user's attention is drawn to the risks associated
26
with loading, using, modifying and/or developing or reproducing the
27
software by the user in light of its specific status of free software,
28
that may mean that it is complicated to manipulate, and that also
29
therefore means that it is reserved for developers and experienced
30
professionals having in-depth computer knowledge. Users are therefore
31
encouraged to load and test the software's suitability as regards their
32
requirements in conditions enabling the security of their systems and/or
33
data to be ensured and, more generally, to use and operate it in the
34
same conditions as regards security.
36
The fact that you are presently reading this means that you have had
37
knowledge of the CeCILL license and that you accept its terms.
40
#include "MixedSubstitutionModelSet.h"
41
#include "MixedSubstitutionModel.h"
42
#include "MixtureOfASubstitutionModel.h"
47
MixedSubstitutionModelSet::MixedSubstitutionModelSet(const MixedSubstitutionModelSet& set) :
48
SubstitutionModelSet(set), vpHyperNodes_()
50
for (unsigned int i=0;i<set.vpHyperNodes_.size();i++)
51
vpHyperNodes_.push_back(new HyperNode(*set.vpHyperNodes_[i]));
54
MixedSubstitutionModelSet::MixedSubstitutionModelSet(const SubstitutionModelSet& set) :
55
SubstitutionModelSet(set), vpHyperNodes_()
59
MixedSubstitutionModelSet::~MixedSubstitutionModelSet()
61
for (unsigned int i=0;i<vpHyperNodes_.size();i++)
62
delete vpHyperNodes_[i];
65
void MixedSubstitutionModelSet::clear()
67
SubstitutionModelSet::clear();
68
for (unsigned int i=0;i<vpHyperNodes_.size();i++)
69
delete vpHyperNodes_[i];
72
MixedSubstitutionModelSet& MixedSubstitutionModelSet::operator=(const MixedSubstitutionModelSet& set)
74
SubstitutionModelSet::operator=(set);
75
for (unsigned int i=0;i<vpHyperNodes_.size();i++)
76
if (vpHyperNodes_[i]!=NULL)
77
delete vpHyperNodes_[i];
78
vpHyperNodes_.clear();
80
for (unsigned int i=0;i<set.vpHyperNodes_.size();i++)
81
vpHyperNodes_.push_back(new HyperNode(*set.vpHyperNodes_[i]));
86
void MixedSubstitutionModelSet::addEmptyHyperNode()
88
vpHyperNodes_.push_back(new HyperNode(this));
91
void MixedSubstitutionModelSet::addHyperNode(const HyperNode& hn)
93
vpHyperNodes_.push_back(new HyperNode(hn));
96
bool MixedSubstitutionModelSet::complete()
98
MixedSubstitutionModelSet::HyperNode nhn(this);
100
for ( i=0;i<vpHyperNodes_.size();i++)
101
nhn+=*vpHyperNodes_[i];
103
unsigned int nbm=getNumberOfModels();
105
const MixedSubstitutionModel* pSM=dynamic_cast<const MixedSubstitutionModel*>(getModel(i));
107
if (nhn.getNode(i).size()!=pSM->getNumberOfModels())
116
for ( i=0;i<nbm;i++){
117
const MixedSubstitutionModel* pSM=dynamic_cast<const MixedSubstitutionModel*>(getModel(i));
119
const MixedSubstitutionModelSet::HyperNode::Node& nd=nhn.getNode(i);
120
int snd=(int)nd.size();
121
int vs=(int)pSM->getNumberOfModels();
126
while ((k<snd) && (nd[k]<j))
128
if ((k>=snd) || (nd[k]>j))
132
addToHyperNode(i,an);
139
void MixedSubstitutionModelSet::addToHyperNode(int nM, const Vint& vnS, int nH)
141
if (nH>=(int)vpHyperNodes_.size())
142
throw BadIntegerException("Bad HyperNode number",nH);
144
nH=vpHyperNodes_.size()-1;
146
if (nM<0 || nM>=(int)getNumberOfModels())
147
throw BadIntegerException("Bad Mixed Model number",nM);
149
vpHyperNodes_[nH]->addToModel(nM,vnS);
152
bool MixedSubstitutionModelSet::hasExclusivePaths() const
154
HyperNode tthn(this);
156
unsigned int nhn=getNumberOfHyperNodes();
157
for (unsigned int i=0;i<nhn;i++){
158
if (tthn.intersects(getHyperNode(i)))
161
tthn+=getHyperNode(i);
167
void MixedSubstitutionModelSet::fireParameterChanged(const ParameterList& parameters)
169
SubstitutionModelSet::fireParameterChanged(parameters);
171
// should be restricted only when probability related parameters are changed
172
computeHyperNodesProbabilities();
176
void MixedSubstitutionModelSet::computeHyperNodesProbabilities()
178
unsigned int nbm=getNumberOfModels();
180
// Looking for the first Mixed model
184
MixedSubstitutionModel* pfSM=0;
185
for (fmM=0;fmM<nbm;fmM++){
186
pfSM=dynamic_cast<MixedSubstitutionModel*>(getModel(fmM));
193
// Compute the probabilities of the hypernodes from the first mixed
196
unsigned int nbh=getNumberOfHyperNodes();
199
for (unsigned int nh=0;nh<nbh;nh++){
200
MixedSubstitutionModelSet::HyperNode& h=getHyperNode(nh);
201
const MixedSubstitutionModelSet::HyperNode::Node& fnd=h.getNode(fmM);
204
for (unsigned int i=0;i<fnd.size();i++)
205
fprob+=pfSM->getNProbability(fnd[i]);
206
h.setProbability(fprob);
209
// Sets the new probabilities & rates of the mixmodels
211
for (unsigned int iM=fmM+1;iM<nbm;iM++){
212
pfSM=dynamic_cast<MixedSubstitutionModel*>(getModel(iM));
214
for (unsigned int nh=0;nh<nbh;nh++){
215
MixedSubstitutionModelSet::HyperNode& h=getHyperNode(nh);
216
const MixedSubstitutionModelSet::HyperNode::Node& fnd=h.getNode(iM);
218
for (unsigned int j=0;j<fnd.size();j++)
219
prob+=pfSM->getNProbability(fnd[j]);
221
// sets the real probabilities
222
for (unsigned int j=0;j<fnd.size();j++)
223
pfSM->setNProbability(fnd[j],h.getProbability()*pfSM->getNProbability(fnd[j])/prob);
226
// normalizes Vrates with the real probabilities
228
pfSM->normalizeVRates();
230
// sets the conditional probabilities
232
for (unsigned int nh=0;nh<nbh;nh++){
233
MixedSubstitutionModelSet::HyperNode& h=getHyperNode(nh);
234
const MixedSubstitutionModelSet::HyperNode::Node& fnd=h.getNode(iM);
235
for (unsigned int j=0;j<fnd.size();j++)
236
pfSM->setNProbability(fnd[j],pfSM->getNProbability(fnd[j])/h.getProbability());
242
double MixedSubstitutionModelSet::getHyperNodeProbability(const HyperNode& hn) const
244
unsigned int nbm=getNumberOfModels();
247
for (unsigned int fmM=0;fmM<nbm;fmM++){
249
const MixedSubstitutionModelSet::HyperNode::Node& fnd=hn.getNode(fmM);
250
const MixedSubstitutionModel* pfSM=dynamic_cast<const MixedSubstitutionModel*>(getModel(fmM));
254
for (unsigned int i=0;i<fnd.size();i++)
255
x+=pfSM->getNProbability(fnd[i]);
264
/**********************************************************/
265
/*************** HYPERNODE ********************************/
266
/***********************************************************/
269
MixedSubstitutionModelSet::HyperNode::HyperNode(const MixedSubstitutionModelSet *pMSMS): vNumbers_(pMSMS->getNumberOfModels()), vUnused_(), proba_(1)
271
for (unsigned int i=0;i<pMSMS->getNumberOfModels();i++){
272
const MixedSubstitutionModel* pSM=dynamic_cast<const MixedSubstitutionModel*>(pMSMS->getModel(i));
274
vUnused_.push_back(i);
278
MixedSubstitutionModelSet::HyperNode::HyperNode(const HyperNode& hn): vNumbers_(hn.vNumbers_), vUnused_(hn.vUnused_), proba_(hn.proba_)
282
MixedSubstitutionModelSet::HyperNode& MixedSubstitutionModelSet::HyperNode::operator=(const MixedSubstitutionModelSet::HyperNode& hn)
285
vNumbers_.resize(hn.vNumbers_.size());
286
for (unsigned int i=0;i<hn.vNumbers_.size();i++)
287
vNumbers_[i]=hn.vNumbers_[i];
289
vUnused_.resize(hn.vUnused_.size());
290
for (unsigned int i=0;i<hn.vUnused_.size();i++)
291
vUnused_[i]=hn.vUnused_[i];
298
void MixedSubstitutionModelSet::HyperNode::addToModel(int nM, const Vint& vnS)
300
if ((nM<0) || (nM>=(int)vNumbers_.size()))
301
throw BadIntegerException("Bad Mixed model Number",nM);
303
vNumbers_[nM].insertN(vnS);
306
void MixedSubstitutionModelSet::HyperNode::setModel(int nM, const Vint& vnS)
308
if ((nM<0) || (nM>=(int)vNumbers_.size()))
309
throw BadIntegerException("Bad Mixed model Number",nM);
314
bool MixedSubstitutionModelSet::HyperNode::isComplete() const
317
int vUs=(int)vUnused_.size();
318
for (int i=0;i<(int)vNumbers_.size();i++){
322
if ((k==vUs) && vNumbers_[i].size()==0)
328
bool MixedSubstitutionModelSet::HyperNode::operator<=(const HyperNode& hn) const
330
for (unsigned int i=0;i<vNumbers_.size();i++){
331
if (!( vNumbers_[i]<=hn.vNumbers_[i]))
338
bool MixedSubstitutionModelSet::HyperNode::intersects(const HyperNode& hn) const
340
for (unsigned int i=0;i<vNumbers_.size();i++)
341
if (vNumbers_[i].intersects(hn.vNumbers_[i]))
347
bool MixedSubstitutionModelSet::HyperNode::operator>=(const HyperNode& hn) const
352
MixedSubstitutionModelSet::HyperNode& MixedSubstitutionModelSet::HyperNode::operator+=(const HyperNode& hn)
354
for (unsigned int i=0;i<vNumbers_.size();i++)
355
vNumbers_[i]+=hn.vNumbers_[i];
360
/**********************************************************/
361
/******************** NODE ********************************/
362
/***********************************************************/
364
void MixedSubstitutionModelSet::HyperNode::Node::insertN(const Vint& vn)
366
vector<int>::iterator it;
367
vector<int>::const_iterator it2;
369
for (it2=vn.begin();it2!=vn.end();it2++){
370
for (it=vNumb_.begin();it!=vNumb_.end();it++)
373
if (it==vNumb_.end())
374
vNumb_.push_back(*it2);
376
vNumb_.insert(it,*it2);
380
MixedSubstitutionModelSet::HyperNode::Node& MixedSubstitutionModelSet::HyperNode::Node::operator+=(const Node& n)
387
bool MixedSubstitutionModelSet::HyperNode::Node::operator<=(const Node& n) const
389
vector<int>::const_iterator it(vNumb_.begin());
390
vector<int>::const_iterator it2(n.vNumb_.begin());
392
for (;it!=vNumb_.end();it++){
393
while (it2!=n.vNumb_.end() && (*it2<*it))
395
if (it2==n.vNumb_.end() || (*it2>*it))
402
bool MixedSubstitutionModelSet::HyperNode::Node::operator>=(const Node& n) const
407
bool MixedSubstitutionModelSet::HyperNode::Node::intersects(const Node& n) const
409
vector<int>::const_iterator it(vNumb_.begin());
410
vector<int>::const_iterator it2(n.vNumb_.begin());
412
for (;it!=vNumb_.end();it++){
413
while (it2!=n.vNumb_.end() && (*it2<*it))
416
if (it2==n.vNumb_.end())