xref: /haiku/src/libs/linprog/Variable.cpp (revision 68ea01249e1e2088933cb12f9c28d4e5c5d1c9ef)
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  */
31 int32
32 Variable::Index() const
33 {
34 	return fLS->IndexOf(this);
35 }
36 
37 
38 int32
39 Variable::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  */
50 LinearSpec*
51 Variable::LS() const
52 {
53 	return fLS;
54 }
55 
56 
57 /**
58  * Gets the value.
59  *
60  * @return the value
61  */
62 double
63 Variable::Value() const
64 {
65 	return fValue;
66 }
67 
68 
69 /**
70  * Sets the value.
71  *
72  * @param value	the value
73  */
74 void
75 Variable::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  */
86 double
87 Variable::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  */
98 void
99 Variable::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  */
110 double
111 Variable::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  */
122 void
123 Variable::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  */
135 void
136 Variable::SetRange(double min, double max)
137 {
138 	fMin = min;
139 	fMax = max;
140 	if (fIsValid)
141 		fLS->UpdateRange(this);
142 }
143 
144 
145 const char*
146 Variable::Label()
147 {
148 	return fLabel.String();
149 }
150 
151 
152 void
153 Variable::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  */
165 BString
166 Variable::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  */
194 Constraint*
195 Variable::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  */
210 Constraint*
211 Variable::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  */
226 Constraint*
227 Variable::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 
236 Constraint*
237 Variable::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 
247 Constraint*
248 Variable::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 
258 Constraint*
259 Variable::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 
269 bool
270 Variable::IsValid()
271 {
272 	return fIsValid;
273 }
274 
275 
276 void
277 Variable::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  */
292 Variable::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 
306 int32
307 Variable::AddReference()
308 {
309 	fReferenceCount++;
310 	return fReferenceCount;
311 }
312 
313 
314 int32
315 Variable::RemoveReference()
316 {
317 	fReferenceCount--;
318 	return fReferenceCount;
319 }
320 
321 
322 /**
323  * Destructor.
324  * Removes the variable from its specification.
325  */
326 Variable::~Variable()
327 {
328 	if (fLS)
329 		fLS->RemoveVariable(this, false);
330 }
331 
332