1 // $Id: parameter.h,v 1.45 2011/10/31 22:04:51 ewalkup Exp $
2 
3 /*
4   Copyright 2002  Peter Beerli, Mary Kuhner, Jon Yamato and Joseph Felsenstein
5 
6   This software is distributed free of charge for non-commercial use
7   and is copyrighted.  Of course, we do not guarantee that the software
8   works, and are not responsible for any damage you may cause or have.
9 */
10 
11 /*************************************************************************
12    The Parameter class and its helper ResultStruct are used to store
13    information about individual parameters of the force model.  For
14    example, a single Parameter object might represent the migration
15    rate from population 2 to population 1.
16 
17    Parameters contain information needed to describe a parameter in
18    input/output, and also store information about results for that
19    parameter, such as its MLE, profiles, and perhaps someday plots.
20 
21    Because everything about a parameter except its results is fixed
22    after the user-input phase, only the results have set methods
23 
24    A Parameter has an IsValidParameter() method establishing its validity.
25    No other field in an invalid Parameter should be used!  Invalid
26    Parameters are used as placeholders, for example representing the
27    non-existent "migration rate from 1 to 1".
28 
29    **
30 
31   The ParamVector class is a structure that holds a "checked out" set
32   of all Parameters.  This is done so that parts of the program which
33   need rapid, read-write access to all Parameters can get it.  One
34   creates a ParamVector to "check out" the Parameters and destroys it
35   (or lets it go out of scope) to automatically "check in" your changes.
36   It is a an error, and will throw a runtime exception, to check out
37   a second ParamVector while the first is still out.
38 
39   If you want only read access to a ParamVector, construct one with an
40   argument of "true" (meaning read-only) (and make it const to keep you
41   honest).  This ParamVector will not attempt a checkin.  It is fine to
42   have as many read-only ParamVectors as you like.  However, bear in mind
43   that if you check out a writable one and write to it, the read-only ones
44   will present a stale view (they are never updated).
45 
46   NB:  There may be invalid Parameters in a ParamVector (such as
47   the nonexistent migration rates along the diagonal).  It is a fatal
48   mistake to try to extract results, names, etc. from such a Parameter.
49 
50 Written by Mary Kuhner October 1 2001
51 ****************************************************************************/
52 
53 #ifndef PARAMETER_H
54 #define PARAMETER_H
55 
56 #include <cassert>
57 #include <vector>
58 #include <string>
59 #include <map>
60 
61 #include "plotstat.h"
62 #include "prior.h"
63 #include "constants.h"
64 #include "defaults.h"
65 #include "types.h"
66 #include "paramstat.h"
67 
68 //------------------------------------------------------------------------------------
69 
70 class ForceSummary;
71 class Random;
72 
73 //------------------------------------------------------------------------------------
74 
75 struct ResultStruct
76 {
77   private:
78     DoubleVec1d mles;                // dim: regions
79     DoubleVec1d overallmle;          // vector of one element
80     vector<ProfileStruct> profiles;        // dim: regions
81     vector<ProfileStruct> overallprofile;  // vector of one element
82 
83   public:
84 
85     // Creation and Destruction
86     // ResultStruct();                         // we accept the default
87     // ResultStruct(const ResultStruct& src);  // we accept the default
88     // ~ResultStruct();                        // we accept the default
89     // ResultStruct& operator=(const ResultStruct& src); // we accept the default
90 
91     // Getters (mostly not inline due to error checking code)
92     double GetMLE(long region) const;
GetRegionMLEsResultStruct93     DoubleVec1d GetRegionMLEs() const { return mles; };
94     double GetOverallMLE() const;
95     DoubleVec1d GetAllMLEs() const;
96 
97     const ProfileStruct& GetProfile(long region) const;
GetRegionProfilesResultStruct98     const vector<ProfileStruct>& GetRegionProfiles() const { return profiles; };
99     const ProfileStruct& GetOverallProfile() const;
100     vector<ProfileStruct> GetAllProfiles() const;
101     const ProfileLineStruct& GetProfileFor(double centile, long reg) const;
102 
103     // Setters
104     void AddMLE(double mle, long region);
105     void AddOverallMLE(double mle);
106 
AddProfileResultStruct107     void AddProfile(const ProfileStruct& profile)
108     { profiles.push_back(profile); };
AddOverallProfileResultStruct109     void AddOverallProfile(const ProfileStruct& profile)
110     { overallprofile.push_back(profile); };
111 
112 }; // ResultStruct definition
113 
114 //------------------------------------------------------------------------------------
115 
116 class Parameter
117 // EWCOMMENT -- keep an eye on how much "special case" code is added
118 // to this class. If we get a lot, then we need to think about
119 // using subclasses.  We don't do it now because we stuff these
120 // into vectors.
121 {
122   private:
123     ParamStatus m_status;               // if this is "invalid" nothing else matters
124     unsigned long m_paramvecIndex;
125     string m_shortname;
126     string m_name;
127     force_type m_force;                 // parameter knows to which force it belongs
128 
129     ResultStruct m_results;             // used to be "mutable", but no longer needed.
130     method_type m_method;               // method used to calculate this parameter
131     proftype m_profiletype;
132     double m_truevalue;                 // true value of variable
133 
134     // bayesian variables
135     Prior  m_prior;                     // a 'Prior' object (can be linear, log, ...?)
136 
137     Parameter();                        // not defined
138 
139   public:
140 
141     // Creation and destruction
142     Parameter(const ParamStatus& status,
143               unsigned long paramIndex,
144               const string sname,
145               const string lname,
146               force_type thisforce,
147               method_type meth,
148               proftype prof,
149               const UIVarsPrior & uiprior,
150               double truevalue
151               );
152 
153     //Use only to create invalid parameters.
154     Parameter(const ParamStatus& status, unsigned long paramIndex);
155 
156     // We accept default copy ctor, op=, dtor
157 
158     // Getters
GetStatus()159     ParamStatus GetStatus()   const { return m_status; };
GetParamVecIndex()160     unsigned long GetParamVecIndex()   const { return m_paramvecIndex; };
IsValidParameter()161     bool IsValidParameter()   const { return (m_status.Valid()); };
IsVariable()162     bool IsVariable()         const { return (m_status.Inferred()); };
IsForce(force_type thistag)163     bool IsForce(force_type thistag)  const { return (m_force == thistag); };
164     bool IsEasilyBayesianRearrangeable() const;
WhichForce()165     force_type WhichForce()       const { return m_force; };
GetShortName()166     string GetShortName()     const { assert (IsValidParameter()); return m_shortname; };
GetName()167     string GetName()          const { assert (IsValidParameter()); return m_name; };
168     string GetUserName()      const;
GetProfileType()169     proftype GetProfileType() const { return m_profiletype; };
IsProfiled()170     bool IsProfiled()         const { return (m_profiletype != profile_NONE); };
GetMethod()171     method_type GetMethod()   const { return m_method; };
GetTruth()172     double GetTruth()         const { return m_truevalue; };
173 
174     // The Prior interface (for Bayesian analysis)
GetPrior()175     Prior      GetPrior()         const { return m_prior; };
176 
SetShortName(string n)177     void       SetShortName(string n) { m_shortname = n; };
SetName(string n)178     void       SetName(string n) { m_name = n; };
179     std::pair<double, double> DrawFromPrior() const;
180     bool IsZeroTrueMin();
181 
182     // MLEs
GetMLE(long region)183     double GetMLE(long region) const { assert (IsValidParameter()); return m_results.GetMLE(region); };
GetRegionMLEs()184     DoubleVec1d GetRegionMLEs() const { assert (IsValidParameter()); return m_results.GetRegionMLEs(); };
GetOverallMLE()185     double GetOverallMLE() const { assert (IsValidParameter()); return m_results.GetOverallMLE(); };
GetAllMLEs()186     DoubleVec1d GetAllMLEs() const { assert (IsValidParameter()); return m_results.GetAllMLEs(); };
187 
188     // Profiles
189     vector<vector<centilepair> > GetProfiles(long region) const;
190     vector<vector<centilepair> > GetOverallProfile() const;
191     vector<centilepair> GetPriorLikes(long region) const;
192     vector<centilepair> GetOverallPriorLikes() const;
193     vector<centilepair> GetCIs(long region) const;
194     vector<centilepair> GetOverallCIs() const;
195 
196     bool CentileIsExtremeLow (double centile, long reg) const;
197     bool CentileIsExtremeHigh(double centile, long reg) const;
198     bool CentileHadWarning(double centile, long reg) const;
199 
200     // Setters
201     //   no setters for most things outside of m_results, since everything
202     //   is set in the constructor.  The m_results setters can be const
203     //   since m_results is mutable.  (The prior can be set, but in that
204     //   case the Parameter must be non-const).
205 
206     // MLEs
AddMLE(double mle,long region)207     void AddMLE(double mle, long region) { assert (IsValidParameter()); m_results.AddMLE(mle, region); };
AddOverallMLE(double mle)208     void AddOverallMLE(double mle) { assert (IsValidParameter()); m_results.AddOverallMLE(mle); };
209 
210     // Profiles
211     void AddProfile(const ProfileStruct& prof, likelihoodtype like);
212 };
213 
214 class ParamVector
215 {
216   private:
217 
218     // This class is a lock.  NO COPYING ALLOWED.  Don't define these.
219     ParamVector(const ParamVector&);              // not defined
220     ParamVector& operator=(const ParamVector&);   // not defined
221 
222     static bool s_locked;
223     bool m_readonly;
224     ForceSummary& forcesum;      // to allow check-in in destructor
225 
226     // not very private, as we hand out references....
227     vector<Parameter> parameters;
228 
229   public:
230 
231     // The constructor checks out the Parameters and the destructor checks them
232     // back in.  If you check out a read-only version, you will do yourself a
233     // favor if you also make it const (i.e. 'const ParamVector pvec(true)' )
234     ParamVector(bool rd);
235     ~ParamVector();
236 
237     // vector emulation routines
238     typedef vector<Parameter>::iterator iterator;
239     typedef vector<Parameter>::const_iterator const_iterator;
240     Parameter&     operator[](long index);
241     const Parameter&     operator[](long index) const;
size()242     unsigned long  size()  const { return parameters.size(); };
empty()243     bool           empty() const { return parameters.empty(); };
begin()244     iterator       begin()       { return parameters.begin(); };
begin()245     const_iterator begin() const { return parameters.begin(); };
end()246     iterator       end()         { return parameters.end(); };
end()247     const_iterator end()   const { return parameters.end(); };
248 
249     paramlistcondition CheckCalcProfiles() const;
250     paramlistcondition CheckCalcPProfiles() const;
251     long           NumProfiledParameters() const;
252     long           NumVariableParameters() const;
253     long           ChooseSampleParameterIndex(Random * randomSource) const;
254 };
255 
256 #endif // PARAMETER_H
257 
258 //____________________________________________________________________________________
259