COPASI API  4.16.103
COptItem.cpp
Go to the documentation of this file.
1 // Copyright (C) 2010 - 2015 by Pedro Mendes, Virginia Tech Intellectual
2 // Properties, Inc., University of Heidelberg, and The University
3 // of Manchester.
4 // All rights reserved.
5 
6 // Copyright (C) 2008 - 2009 by Pedro Mendes, Virginia Tech Intellectual
7 // Properties, Inc., EML Research, gGmbH, University of Heidelberg,
8 // and The University of Manchester.
9 // All rights reserved.
10 
11 // Copyright (C) 2005 - 2007 by Pedro Mendes, Virginia Tech Intellectual
12 // Properties, Inc. and EML Research, gGmbH.
13 // All rights reserved.
14 
15 #include <algorithm>
16 #include <limits>
17 #include <cmath>
18 #include <sstream>
19 #include <stdlib.h>
20 
21 #include "copasi.h"
22 
23 #include "COptItem.h"
24 
31 #include "utilities/utility.h"
32 
33 C_FLOAT64 NaN = std::numeric_limits< C_FLOAT64 >::quiet_NaN();
34 
36 
37 CRandom * COptItem::mpRandom = NULL;
38 
40  const std::string & name):
41  CCopasiParameterGroup(name, pParent),
42  mpParmObjectCN(NULL),
43  mpParmLowerBound(NULL),
44  mpParmUpperBound(NULL),
45  mpParmStartValue(NULL),
46  mpObject(NULL),
47  mpMethod(NULL),
48  mpObjectValue(NULL),
49  mpLowerObject(NULL),
50  mpLowerBound(NULL),
51  mLowerBound(0.0),
52  mpUpperObject(NULL),
53  mpUpperBound(NULL),
54  mUpperBound(0.0),
55  mLastStartValue(std::numeric_limits< C_FLOAT64 >::quiet_NaN())
57 
59  const CCopasiContainer * pParent):
60  CCopasiParameterGroup(src, (pParent != NULL) ? pParent : src.getObjectDataModel()),
61  mpParmObjectCN(NULL),
62  mpParmLowerBound(NULL),
63  mpParmUpperBound(NULL),
64  mpParmStartValue(NULL),
65  mpObject(NULL),
66  mpMethod(NULL),
67  mpObjectValue(NULL),
68  mpLowerObject(NULL),
69  mpLowerBound(NULL),
70  mLowerBound(0.0),
71  mpUpperObject(NULL),
72  mpUpperBound(NULL),
73  mUpperBound(0.0),
74  mLastStartValue(src.mLastStartValue)
76 
78  const CCopasiContainer * pParent):
79  CCopasiParameterGroup(group, (pParent != NULL) ? pParent : group.getObjectDataModel()),
80  mpParmObjectCN(NULL),
81  mpParmLowerBound(NULL),
82  mpParmUpperBound(NULL),
83  mpParmStartValue(NULL),
84  mpObject(NULL),
85  mpMethod(NULL),
86  mpObjectValue(NULL),
87  mpLowerObject(NULL),
88  mpLowerBound(NULL),
89  mLowerBound(0.0),
90  mpUpperObject(NULL),
91  mpUpperBound(NULL),
92  mUpperBound(0.0),
93  mLastStartValue(std::numeric_limits< C_FLOAT64 >::quiet_NaN())
95 
97 {}
98 
100 {
109 }
110 
112 {
113  const CCopasiDataModel * pDataModel = getObjectDataModel();
114  assert(pDataModel != NULL);
115 
116  const CCopasiObject * pObject = pDataModel->getDataObject(objectCN);
117 
118  if (pObject == NULL || !pObject->isValueDbl())
119  {
120  CCopasiMessage(CCopasiMessage::ERROR, MCOptimization + 1, objectCN.c_str());
121  return false;
122  }
123 
124  *mpParmObjectCN = objectCN;
125  return true;
126 }
127 
129 {return mpObject;}
130 
132 {return *mpParmObjectCN;}
133 
135 {
136  if (!mpObject && !const_cast<COptItem *>(this)->compile())
137  return "Invalid Optimization Item";
138 
139  return mpObject->getObjectDisplayName();
140 }
141 
143 {
144  if (lowerBound[0] == '-' &&
145  lowerBound[lowerBound.length() - 1] == '%' &&
146  isNumber(lowerBound.substr(1, lowerBound.length() - 2)))
147  {
148  std::stringstream LowerBound;
149  C_FLOAT64 StartValue = getStartValue();
150 
151  LowerBound << StartValue + fabs(StartValue) * strToDouble(lowerBound.c_str(), NULL) / 100.0;
152  *mpParmLowerBound = LowerBound.str();
153 
154  return true;
155  }
156  else
157  {
158  *mpParmLowerBound = lowerBound;
159  }
160 
162 }
163 
164 const std::string COptItem::getLowerBound() const
165 {return *mpParmLowerBound;}
166 
168 {
169  if (upperBound[0] == '+' &&
170  upperBound[upperBound.length() - 1] == '%' &&
171  isNumber(upperBound.substr(1, upperBound.length() - 2)))
172  {
173  std::stringstream UpperBound;
174  C_FLOAT64 StartValue = getStartValue();
175 
176  UpperBound << StartValue + fabs(StartValue) * strToDouble(upperBound.c_str(), NULL) / 100.0;
177  *mpParmUpperBound = UpperBound.str();
178 
179  return true;
180  }
181  else
182  {
183  *mpParmUpperBound = upperBound;
184  }
185 
187 }
188 
189 const std::string COptItem::getUpperBound() const
190 {return *mpParmUpperBound;}
191 
193 {
194  *mpParmStartValue = value;
195 
196  return true;
197 }
198 
200 {
201  if (!isnan(*mpParmStartValue))
202  return *mpParmStartValue;
203 
204  if (mpObjectValue == NULL)
205  {
206  const CCopasiDataModel* pDataModel = getObjectDataModel();
207  assert(pDataModel != NULL);
208  const CCopasiObject * pObject = pDataModel->getDataObject(getObjectCN());
209 
210  if (pObject != NULL &&
211  pObject->getValuePointer() != NULL)
212  return *(C_FLOAT64 *) pObject->getValuePointer();
213 
214  return NaN;
215  }
216 
217  return *mpObjectValue;
218 }
219 
221 {
222  return mLastStartValue;
223 }
224 
226 {
228 }
229 
231 {
232  C_FLOAT64 RandomValue;
233 
234  if (mpLowerBound == NULL ||
235  mpUpperBound == NULL) compile();
236 
237  if (mpLowerBound == NULL ||
238  mpUpperBound == NULL)
239  {
240  RandomValue = NaN;
241  return RandomValue;
242  }
243 
244  if (pRandom == NULL)
245  {
246  if (mpRandom == NULL)
248 
249  pRandom = mpRandom;
250  }
251 
252  C_FLOAT64 mn = *mpLowerBound;
253  C_FLOAT64 mx = *mpUpperBound;
254 
255  C_FLOAT64 la;
256 
257  try
258  {
259  // First determine the location of the interval
260  // Secondly determine whether to distribute the parameter linearly or not
261  // depending on the location and act upon it.
262  if (0.0 <= mn) // the interval [mn, mx) is in [0, inf)
263  {
264  la = log10(mx) - log10(std::max(mn, std::numeric_limits< C_FLOAT64 >::min()));
265 
266  if (la < 1.8 || !(mn > 0.0)) // linear
267  RandomValue = mn + pRandom->getRandomCC() * (mx - mn);
268  else
269  RandomValue = pow(10.0, log10(std::max(mn, std::numeric_limits< C_FLOAT64 >::min())) + la * pRandom->getRandomCC());
270  }
271  else if (mx > 0) // 0 is in the interval (mn, mx)
272  {
273  la = log10(mx) + log10(-mn);
274 
275  if (la < 3.6) // linear
276  RandomValue = mn + pRandom->getRandomCC() * (mx - mn);
277  else
278  {
279  C_FLOAT64 mean = (mx + mn) * 0.5;
280  C_FLOAT64 sigma = std::min(std::numeric_limits< C_FLOAT64 >::max(), mx - mn) / 3.0;
281 
282  do
283  {
284  RandomValue = pRandom->getRandomNormal(mean, sigma);
285  }
286  while ((RandomValue < mn) || (RandomValue > mx));
287  }
288  }
289  else // the interval (mn, mx] is in (-inf, 0]
290  {
291  // Switch lower and upper bound and change sign, i.e.,
292  // we can treat it similarly as location 1:
293  mx = - *mpLowerBound;
294  mn = - *mpUpperBound;
295 
296  la = log10(mx) - log10(std::max(mn, std::numeric_limits< C_FLOAT64 >::min()));
297 
298  if (la < 1.8 || !(mn > 0.0)) // linear
299  RandomValue = - (mn + pRandom->getRandomCC() * (mx - mn));
300  else
301  RandomValue = - pow(10.0, log10(std::max(mn, std::numeric_limits< C_FLOAT64 >::min())) + la * pRandom->getRandomCC());
302  }
303  }
304 
305  catch (...)
306  {
307  RandomValue = (mx + mn) * 0.5;
308  }
309 
310  return RandomValue;
311 }
312 
314 {return mpMethod;}
315 
316 bool COptItem::isValid() const
317 {
318  COptItem *pTmp = const_cast<COptItem *>(this);
319 
320  if (!pTmp->setObjectCN(getObjectCN())) return false;
321 
322  if (!pTmp->setLowerBound(getLowerBound())) return false;
323 
324  if (!pTmp->setUpperBound(getUpperBound())) return false;
325 
326  return true;
327 }
328 
330 {
331  COptItem tmp(group);
332 
333  return tmp.isValid();
334 }
335 
336 bool COptItem::compile(const std::vector< CCopasiContainer * > listOfContainer)
337 {
338  bool success = true;
340 
341  std::string Bound;
342 
343  mpMethod = &DoNothing;
344  mpObjectValue = &NaN;
345 
346  if ((mpObject =
347  getObjectDataModel()->ObjectFromName(listOfContainer,
348  getObjectCN())) != NULL &&
349  mpObject->isValueDbl())
351 
352  if (mpObjectValue == &NaN)
353  {
355  success = false;
356  }
357  else
358  {
361  }
362 
363  if (compileLowerBound(listOfContainer))
364  {
365  if (mpLowerObject != NULL)
366  {
368  }
369  }
370  else
371  {
373  success = false;
374  }
375 
376  if (compileUpperBound(listOfContainer))
377  {
378  if (mpUpperObject != NULL)
379  {
381  }
382  }
383  else
384  {
386  success = false;
387  }
388 
390  {
392  success = false;
393  }
394 
395  if (isnan(*mpParmStartValue))
397 
398  return success;
399 }
400 
402 {
403  if (*mpLowerBound > *mpObjectValue) return - 1;
404 
405  if (*mpObjectValue > *mpUpperBound) return 1;
406 
407  return 0;
408 }
409 
411 {
412  switch (checkConstraint())
413  {
414  case - 1:
415  return *mpLowerBound - *mpObjectValue;
416  break;
417 
418  case 1:
419  return *mpObjectValue - *mpUpperBound;
420  break;
421  }
422 
423  return 0.0;
424 }
425 
427 {
428  if (*mpLowerBound > value) return - 1;
429 
430  if (value > *mpUpperBound) return 1;
431 
432  return 0;
433 }
434 
435 bool COptItem::checkLowerBound(const C_FLOAT64 & value) const
436 {return *mpLowerBound <= value;}
437 
438 bool COptItem::checkUpperBound(const C_FLOAT64 & value) const
439 {return value <= *mpUpperBound;}
440 
442 {return mpObjectValue;}
443 
444 bool COptItem::compileLowerBound(const std::vector< CCopasiContainer * > & listOfContainer)
445 {
446  const CCopasiDataModel * pDataModel = getObjectDataModel();
447 
448  assert(pDataModel != NULL);
449 
450  mpLowerObject = NULL;
451  mpLowerBound = NULL;
452 
453  if (*mpParmLowerBound == "-inf")
454  {
457  }
458  else if (isNumber(*mpParmLowerBound))
459  {
460  mLowerBound = strToDouble(mpParmLowerBound->c_str(), NULL);
462  }
463  else if ((mpLowerObject =
464  getObjectDataModel()->ObjectFromName(listOfContainer,
465  *mpParmLowerBound)) != NULL &&
467  {
469  }
470 
471  return mpLowerBound != NULL;
472 }
473 
474 bool COptItem::compileUpperBound(const std::vector< CCopasiContainer * > & listOfContainer)
475 {
476  const CCopasiDataModel * pDataModel = getObjectDataModel();
477 
478  assert(pDataModel != NULL);
479 
480  mpUpperObject = NULL;
481  mpUpperBound = NULL;
482 
483  if (*mpParmUpperBound == "inf")
484  {
487  }
488  else if (isNumber(*mpParmUpperBound))
489  {
490  mUpperBound = strToDouble(mpParmUpperBound->c_str(), NULL);
492  }
493  else if ((mpUpperObject =
494  getObjectDataModel()->ObjectFromName(listOfContainer,
495  *mpParmUpperBound)) != NULL &&
497  {
500  }
501 
502  return mpUpperBound != NULL;
503 }
504 
505 std::ostream &operator<<(std::ostream &os, const COptItem & o)
506 {
507  if (o.mpObject == NULL && !const_cast<COptItem *>(&o)->compile())
508  return os << "Invalid Optimization Item";
509 
510  if (o.mpLowerObject)
512  else
513  os << o.getLowerBound();
514 
515  os << " <= ";
516  os << o.mpObject->getObjectDisplayName();
517  os << " <= ";
518 
519  if (o.mpUpperObject)
521  else
522  os << o.getUpperBound();
523 
524  os << "; Start Value = " << o.getStartValue();
525 
526  return os;
527 }
CCopasiDataModel * getObjectDataModel()
virtual C_INT32 checkConstraint() const
Definition: COptItem.cpp:401
CCopasiObject * getDataObject(const CCopasiObjectName &CN) const
virtual std::string getObjectDisplayName(bool regular=true, bool richtext=false) const
void clearDirectDependencies()
virtual const C_FLOAT64 * getObjectValue() const
Definition: COptItem.cpp:441
bool isNumber(const std::string &str)
Definition: utility.cpp:75
UpdateMethod * getUpdateMethod() const
UpdateMethod DoNothing
Definition: COptItem.cpp:35
const CCopasiObjectName getObjectCN() const
Definition: COptItem.cpp:131
bool checkLowerBound(const C_FLOAT64 &value) const
Definition: COptItem.cpp:435
virtual C_FLOAT64 getRandomNormal(const C_FLOAT64 &mean, const C_FLOAT64 &sd)
Definition: CRandom.cpp:292
virtual C_FLOAT64 getConstraintViolation() const
Definition: COptItem.cpp:410
const CCopasiObject * getObject() const
Definition: COptItem.cpp:128
bool setLowerBound(const CCopasiObjectName &lowerBound)
Definition: COptItem.cpp:142
const std::string getUpperBound() const
Definition: COptItem.cpp:189
const CCopasiObject * mpLowerObject
Definition: COptItem.h:303
#define MCOptimization
static CRandom * mpRandom
Definition: COptItem.h:338
const C_FLOAT64 & getLastStartValue() const
Definition: COptItem.cpp:220
bool setObjectCN(const CCopasiObjectName &objectCN)
Definition: COptItem.cpp:111
#define C_INT32
Definition: copasi.h:90
bool setUpperBound(const CCopasiObjectName &upperBound)
Definition: COptItem.cpp:167
const C_FLOAT64 * mpUpperBound
Definition: COptItem.h:323
bool compileLowerBound(const std::vector< CCopasiContainer * > &listOfContainer)
Definition: COptItem.cpp:444
CRegisteredObjectName * pCN
bool checkUpperBound(const C_FLOAT64 &value) const
Definition: COptItem.cpp:438
void addDirectDependency(const CCopasiObject *pObject)
static CRandom * createGenerator(CRandom::Type type=CRandom::mt19937, unsigned C_INT32 seed=0)
Definition: CRandom.cpp:49
virtual C_FLOAT64 getRandomCC()
Definition: CRandom.cpp:235
static const std::vector< CCopasiContainer * > EmptyList
const Value & getValue() const
virtual ~COptItem()
Definition: COptItem.cpp:96
C_FLOAT64 * mpParmStartValue
Definition: COptItem.h:283
bool setStartValue(const C_FLOAT64 &value)
Definition: COptItem.cpp:192
UpdateMethod * mpMethod
Definition: COptItem.h:293
const CCopasiObject * mpUpperObject
Definition: COptItem.h:318
Header file of class CCopasiContainer.
virtual bool compile(const std::vector< CCopasiContainer * > listOfContainer=CCopasiContainer::EmptyList)
Definition: COptItem.cpp:336
const CCopasiObject * mpObject
Definition: COptItem.h:288
virtual UpdateMethod * getUpdateMethod() const
Definition: COptItem.cpp:313
const C_FLOAT64 * mpLowerBound
Definition: COptItem.h:308
std::string * mpParmUpperBound
Definition: COptItem.h:278
std::string * mpParmLowerBound
Definition: COptItem.h:273
const C_FLOAT64 & getStartValue() const
Definition: COptItem.cpp:199
C_FLOAT64 mUpperBound
Definition: COptItem.h:328
const std::string getLowerBound() const
Definition: COptItem.cpp:164
C_FLOAT64 NaN
Definition: COptItem.cpp:33
double strToDouble(const char *str, char const **pTail)
Definition: utility.cpp:325
void initializeParameter()
Definition: COptItem.cpp:99
std::ostream & operator<<(std::ostream &os, const COptItem &o)
Definition: COptItem.cpp:505
#define C_FLOAT64
Definition: copasi.h:92
C_FLOAT64 mLastStartValue
Definition: COptItem.h:333
void rememberStartValue()
Definition: COptItem.cpp:225
bool isValueDbl() const
virtual void * getValuePointer() const
CCopasiParameter * assertParameter(const std::string &name, const CCopasiParameter::Type type, const CType &defaultValue)
C_FLOAT64 getRandomValue(CRandom *pRandom=NULL)
Definition: COptItem.cpp:230
virtual bool isValid() const
Definition: COptItem.cpp:316
const C_FLOAT64 * mpObjectValue
Definition: COptItem.h:298
std::string * mpParmObjectCN
Definition: COptItem.h:268
std::string getObjectDisplayName() const
Definition: COptItem.cpp:134
bool compileUpperBound(const std::vector< CCopasiContainer * > &listOfContainer)
Definition: COptItem.cpp:474
#define min(a, b)
Definition: f2c.h:175
C_FLOAT64 mLowerBound
Definition: COptItem.h:313
#define max(a, b)
Definition: f2c.h:176