1/* 2 * Copyright 2007-2008, Christof Lutteroth, lutteroth@cs.auckland.ac.nz 3 * Copyright 2007-2008, James Kim, jkim202@ec.auckland.ac.nz 4 * Copyright 2010, Clemens Zeidler <haiku@clemens-zeidler.de> 5 * Distributed under the terms of the MIT License. 6 */ 7 8 9#include "Variable.h" 10 11#include <math.h> 12 13#include "Constraint.h" 14#include "LinearSpec.h" 15 16// Toggle debug output 17//#define DEBUG_VARIABLE 18 19#ifdef DEBUG_VARIABLE 20# define STRACE(x) debug_printf x 21#else 22# define STRACE(x) ; 23#endif 24 25 26/** 27 * Gets index of the variable. 28 * 29 * @return the index of the variable 30 */ 31int32 32Variable::Index() const 33{ 34 return fLS->IndexOf(this); 35} 36 37 38int32 39Variable::GlobalIndex() const 40{ 41 return fLS->GlobalIndexOf(this); 42} 43 44 45/** 46 * Gets the current linear specification. 47 * 48 * @return the current linear specification 49 */ 50LinearSpec* 51Variable::LS() const 52{ 53 return fLS; 54} 55 56 57/** 58 * Gets the value. 59 * 60 * @return the value 61 */ 62double 63Variable::Value() const 64{ 65 return fValue; 66} 67 68 69/** 70 * Sets the value. 71 * 72 * @param value the value 73 */ 74void 75Variable::SetValue(double value) 76{ 77 fValue = value; 78} 79 80 81/** 82 * Gets the minimum value of the variable. 83 * 84 * @return the minimum value of variable 85 */ 86double 87Variable::Min() const 88{ 89 return fMin; 90} 91 92 93/** 94 * Sets the minimum value of the variable. 95 * 96 * @param min minimum value 97 */ 98void 99Variable::SetMin(double min) 100{ 101 SetRange(min, fMax); 102} 103 104 105/** 106 * Gets the maximum value of the variable. 107 * 108 * @return the maximum value of variable 109 */ 110double 111Variable::Max() const 112{ 113 return fMax; 114} 115 116 117/** 118 * Sets the maximum value of the variable. 119 * 120 * @param max maximum value 121 */ 122void 123Variable::SetMax(double max) 124{ 125 SetRange(fMin, max); 126} 127 128 129/** 130 * Sets the minimum and maximum values of the variable. 131 * 132 * @param min minimum value 133 * @param max maximum value 134 */ 135void 136Variable::SetRange(double min, double max) 137{ 138 fMin = min; 139 fMax = max; 140 if (fIsValid) 141 fLS->UpdateRange(this); 142} 143 144 145const char* 146Variable::Label() 147{ 148 return fLabel.String(); 149} 150 151 152void 153Variable::SetLabel(const char* label) 154{ 155 fLabel = label; 156} 157 158 159/** 160 * Returns index of the variable as String. 161 * E.g. "Var2" 162 * 163 * @return the <code>String</code> index of the variable 164 */ 165BString 166Variable::ToString() const 167{ 168 BString string = "x"; 169 string << Index() << " "; 170 if (fLabel) { 171 string << fLabel << ": "; 172 if (!fIsValid) 173 string << "(invalid)"; 174 } else { 175 if (!fIsValid) 176 string << "(invalid," << (addr_t)this << ")"; 177 else 178 string << Index() << ": "; 179 } 180 string << Value(); 181 BString pointerString; 182 pointerString.SetToFormat("%p", this); 183 string << " (" << pointerString << ")"; 184 return string; 185} 186 187 188/** 189 * Adds a constraint that sets this variable equal to the given one. 190 * 191 * @param var variable that should have the same value 192 * @return the new equality constraint 193 */ 194Constraint* 195Variable::IsEqual(Variable* var) 196{ 197 if (!fIsValid) 198 return NULL; 199 200 return fLS->AddConstraint(1.0, this, -1.0, var, kEQ, 0.0); 201} 202 203 204/** 205 * Adds a constraint that sets this variable smaller or equal to the given one. 206 * 207 * @param var variable that should have a larger or equal value 208 * @return the new constraint 209 */ 210Constraint* 211Variable::IsSmallerOrEqual(Variable* var) 212{ 213 if (!fIsValid) 214 return NULL; 215 216 return fLS->AddConstraint(1.0, this, -1.0, var, kLE, 0.0); 217} 218 219 220/** 221 * Adds a constraint that sets this variable greater or equal to the given one. 222 * 223 * @param var variable that should have a smaller or equal value 224 * @return the new constraint 225 */ 226Constraint* 227Variable::IsGreaterOrEqual(Variable* var) 228{ 229 if (!fIsValid) 230 return NULL; 231 232 return fLS->AddConstraint(-1.0, var, 1.0, this, kGE, 0.0); 233} 234 235 236Constraint* 237Variable::IsEqual(Variable* var, double penaltyNeg, double penaltyPos) 238{ 239 if (!fIsValid) 240 return NULL; 241 242 return fLS->AddConstraint(1.0, this, -1.0, var, kEQ, 0.0, 243 penaltyNeg, penaltyPos); 244} 245 246 247Constraint* 248Variable::IsSmallerOrEqual(Variable* var, double penaltyNeg, double penaltyPos) 249{ 250 if (!fIsValid) 251 return NULL; 252 253 return fLS->AddConstraint(1.0, this, -1.0, var, kLE, 0.0, penaltyNeg, 254 penaltyPos); 255} 256 257 258Constraint* 259Variable::IsGreaterOrEqual(Variable* var, double penaltyNeg, double penaltyPos) 260{ 261 if (!fIsValid) 262 return NULL; 263 264 return fLS->AddConstraint(-1.0, var, 1.0, this, kGE, 0.0, penaltyNeg, 265 penaltyPos); 266} 267 268 269bool 270Variable::IsValid() 271{ 272 return fIsValid; 273} 274 275 276void 277Variable::Invalidate() 278{ 279 STRACE(("Variable::Invalidate() on %s\n", BString(*this).String())); 280 281 if (!fIsValid) 282 return; 283 284 fIsValid = false; 285 fLS->RemoveVariable(this, false); 286} 287 288 289/** 290 * Constructor. 291 */ 292Variable::Variable(LinearSpec* ls) 293 : 294 fLS(ls), 295 fValue(NAN), 296 fMin(-20000), 297 fMax(20000), 298 fLabel(NULL), 299 fIsValid(false), 300 fReferenceCount(0) 301{ 302 303} 304 305 306int32 307Variable::AddReference() 308{ 309 fReferenceCount++; 310 return fReferenceCount; 311} 312 313 314int32 315Variable::RemoveReference() 316{ 317 fReferenceCount--; 318 return fReferenceCount; 319} 320 321 322/** 323 * Destructor. 324 * Removes the variable from its specification. 325 */ 326Variable::~Variable() 327{ 328 if (fLS) 329 fLS->RemoveVariable(this, false); 330} 331 332