[go: up one dir, main page]

Menu

[r1123]: / trunk / src / Rdouble.cpp  Maximize  Restore  History

Download this file

197 lines (162 with data), 5.7 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#include <map>
#include <stdexcept>
#include "Rdouble.h"
using namespace std;
using namespace Constants;
namespace mesmer
{
//static variable
Rdouble* Rdouble::pendingVar;
const double Rdouble::eps = 1e-7;
Rdouble::operator double() const
{
return link ? *link * factor + addand : value;
}
Rdouble& Rdouble::operator = (const double& val)
{
prev = value ;
value = val ;
if(IsNan(val))
pendingVar =this;
return *this;
}
void Rdouble::set_range(const double valueL, const double valueU, const double valueS, const char* txt)
{
if(valueU<valueL || valueS<0)
{
cerr << "in " << txt << " The upper value should be larger than lower and the stepsize should be positive"<<endl;
return;
}
//Push on to the vector of Rdouble objects which have a range
withRange().push_back(this);
//value is NOT set
lower = valueL;
upper = valueU;
stepsize = valueS;
varname = txt;
prev = NaN;
if (get_numsteps() <= 1)
cwarn << "There is only one point for the range variable " << txt << endl;
cinfo << txt <<" was given a range with " << get_numsteps() << " steps " << endl;
}
void Rdouble::set_range_indirect
(const double valueL, const double valueU, const double valueS,const char* txt)
{
if(pendingVar)
pendingVar->set_range(valueL, valueU, valueS, txt);
else
cerr << "Indirect setting of a range " << txt
<< " without previously set variable to NaN. Range setting ignored." <<endl;
pendingVar = NULL;
}
bool Rdouble::get_range(double& lower_, double& upper_, double& stepsize_)const
{
if(IsNan(lower))
return false;
lower_ = lower;
upper_ = upper;
stepsize_= stepsize;
return true;
}
void Rdouble::set_label(const std::string& label) {
// Check to see if label already used.
labelmap::iterator itrlabel = withLabel().find(label) ;
if (itrlabel != withLabel().end()) {
cerr << "Error: Parameter label " << label << " redefined." << endl;
} else {
withLabel()[label] = this ;
}
}
// This method updates the value of a labelled variable in an XML file
// with its current Rdouble value.
void Rdouble::UpdateXMLLabelVariables() {
labelmap::iterator itrlabel = withLabel().begin() ;
for ( ;itrlabel != withLabel().end() ; itrlabel++) {
itrlabel->second->XmlWriteValue() ;
}
}
// Called after all the xml data has been read
// Look up the linked variable names
bool Rdouble::SetUpLinkedVars()
{
bool ok=true;
labelmap::iterator it;
for(it=withLabel().begin();it!=withLabel().end();++it)
{
Rdouble* depvar = it->second;
if(depvar->linkedname)
{
labelmap::iterator pos = withLabel().find(depvar->linkedname);
if(pos!=withLabel().end())
{
depvar->link = pos->second; //pointer to independent variable
cinfo << it->first << " is derived from " << depvar->linkedname << endl;
//Debug:
cinfo << it->first << " = " << *(it->second) << endl;
}
else
{
cerr << "In linking to " << it->first << ", "
<<depvar->linkedname << " could not be found" << endl;
ok = false;
}
}
}
return ok;
}
// Utility function to read parameter range.
// The parameter cnvrsnFctr applies any conversion factor that is required.
// The parameter rangeSet indicates if a range has actually been set for the rdouble variable.
// If there is a derivedFrom attribute, the cnvrsnFctr and shift parameters are ignored.
//
bool ReadRdoubleRange(const std::string& name, PersistPtr pp, Rdouble& rdouble,
bool& rangeSet, double cnvrsnFctr, double shift)
{
// Store the names of all the potential range variables in case they are referred to
// in a derivedFrom attribute of another linked variable
rdouble.set_label(name);
const char* pLowertxt = pp->XmlReadValue("lower", optional);
const char* pUppertxt = pp->XmlReadValue("upper", optional);
const char* pStepStxt = pp->XmlReadValue("stepsize", optional);
if (pLowertxt && pUppertxt){
rangeSet = true ;
double valueL(0.0), valueU(0.0), stepsize(0.0);
stringstream strLower(pLowertxt), strUpper(pUppertxt), strStepSize(pStepStxt);
strLower >> valueL;
strUpper >> valueU;
strStepSize >> stepsize;
valueL = cnvrsnFctr*valueL + shift;
valueU = cnvrsnFctr*valueU + shift;
stepsize = cnvrsnFctr*stepsize + shift;
rdouble.set_range(valueL, valueU, stepsize, name.c_str());
rdouble.store_conversion(cnvrsnFctr);
} else {
rangeSet = false ;
}
// If there is a derivedFrom attribute, a pointer to its value is put in
//
const char* pDerivedtxt = pp->XmlReadValue("me:derivedFrom", optional);
if(!pDerivedtxt)
pDerivedtxt = pp->XmlReadValue("derivedFrom", optional);
if(pDerivedtxt)
{
rdouble.set_link_params(
pDerivedtxt,
pp->XmlReadDouble("factor", optional),
pp->XmlReadDouble("addand", optional));
cinfo << name << " will be derived from " << pDerivedtxt
<< ". Check below that this has been found." << endl;
}
// Save a pointer to XML location for result update.
if(pp->XmlMoveTo("scalar")) //***DEBUG
cinfo << pp << "on property element" << endl;
rdouble.set_XMLPtr(pp) ;
return true;
}
std::istringstream& operator>>(std::istringstream& iss, Rdouble& rdouble) {
double value(0.0);
iss >> value;
rdouble = value;
return iss ;
}
}//namespace