#include "Variable.h"
#include <math.h>
#include "Constraint.h"
#include "LinearSpec.h"
#ifdef DEBUG_VARIABLE
# define STRACE(x) debug_printf x
#else
# define STRACE(x) ;
#endif
int32
Variable::Index() const
{
return fLS->IndexOf(this);
}
int32
Variable::GlobalIndex() const
{
return fLS->GlobalIndexOf(this);
}
LinearSpec*
Variable::LS() const
{
return fLS;
}
double
Variable::Value() const
{
return fValue;
}
void
Variable::SetValue(double value)
{
fValue = value;
}
double
Variable::Min() const
{
return fMin;
}
void
Variable::SetMin(double min)
{
SetRange(min, fMax);
}
double
Variable::Max() const
{
return fMax;
}
void
Variable::SetMax(double max)
{
SetRange(fMin, max);
}
void
Variable::SetRange(double min, double max)
{
fMin = min;
fMax = max;
if (fIsValid)
fLS->UpdateRange(this);
}
const char*
Variable::Label()
{
return fLabel.String();
}
void
Variable::SetLabel(const char* label)
{
fLabel = label;
}
BString
Variable::ToString() const
{
BString string = "x";
string << Index() << " ";
if (fLabel) {
string << fLabel << ": ";
if (!fIsValid)
string << "(invalid)";
} else {
if (!fIsValid)
string << "(invalid," << (addr_t)this << ")";
else
string << Index() << ": ";
}
string << Value();
BString pointerString;
pointerString.SetToFormat("%p", this);
string << " (" << pointerString << ")";
return string;
}
Constraint*
Variable::IsEqual(Variable* var)
{
if (!fIsValid)
return NULL;
return fLS->AddConstraint(1.0, this, -1.0, var, kEQ, 0.0);
}
Constraint*
Variable::IsSmallerOrEqual(Variable* var)
{
if (!fIsValid)
return NULL;
return fLS->AddConstraint(1.0, this, -1.0, var, kLE, 0.0);
}
Constraint*
Variable::IsGreaterOrEqual(Variable* var)
{
if (!fIsValid)
return NULL;
return fLS->AddConstraint(-1.0, var, 1.0, this, kGE, 0.0);
}
Constraint*
Variable::IsEqual(Variable* var, double penaltyNeg, double penaltyPos)
{
if (!fIsValid)
return NULL;
return fLS->AddConstraint(1.0, this, -1.0, var, kEQ, 0.0,
penaltyNeg, penaltyPos);
}
Constraint*
Variable::IsSmallerOrEqual(Variable* var, double penaltyNeg, double penaltyPos)
{
if (!fIsValid)
return NULL;
return fLS->AddConstraint(1.0, this, -1.0, var, kLE, 0.0, penaltyNeg,
penaltyPos);
}
Constraint*
Variable::IsGreaterOrEqual(Variable* var, double penaltyNeg, double penaltyPos)
{
if (!fIsValid)
return NULL;
return fLS->AddConstraint(-1.0, var, 1.0, this, kGE, 0.0, penaltyNeg,
penaltyPos);
}
bool
Variable::IsValid()
{
return fIsValid;
}
void
Variable::Invalidate()
{
STRACE(("Variable::Invalidate() on %s\n", BString(*this).String()));
if (!fIsValid)
return;
fIsValid = false;
fLS->RemoveVariable(this, false);
}
Variable::Variable(LinearSpec* ls)
:
fLS(ls),
fValue(NAN),
fMin(-20000),
fMax(20000),
fLabel(NULL),
fIsValid(false),
fReferenceCount(0)
{
}
int32
Variable::AddReference()
{
fReferenceCount++;
return fReferenceCount;
}
int32
Variable::RemoveReference()
{
fReferenceCount--;
return fReferenceCount;
}
Variable::~Variable()
{
if (fLS)
fLS->RemoveVariable(this, false);
}