#ifndef GledCore_SVars_H
#define GledCore_SVars_H
#include <TMath.h>
template<typename T>
class SMinMaxVar
{
protected:
T mVal, mMin, mMax;
T valminmax(T v) const
{
return v > mMax ? mMax : (v < mMin ? mMin : v);
}
public:
SMinMaxVar()
: mVal(0), mMin(0), mMax(1)
{}
SMinMaxVar(T val, T min, T max) :
mVal(val), mMin(min), mMax(max)
{}
operator T() const { return mVal; }
T operator=(T v) { return Set(v); }
T Get() const { return mVal; }
T Set(T v)
{
mVal = valminmax(v);
return mVal;
}
T Delta(T d)
{
T ov = mVal;
mVal = valminmax(mVal + d);
return mVal - ov;
}
T GetMin() const { return mMin; }
T GetMax() const { return mMax; }
void SetMin(T min) { mMin = min; }
void SetMax(T max) { mMax = max; }
void SetMinMax(T min, T max) { mMin = min; mMax = max; }
void Print() const
{
printf("%f [%f, %f]\n", mVal, mMin, mMax);
}
ClassDefNV(SMinMaxVar, 1);
};
typedef SMinMaxVar<Float_t> SMinMaxVarF;
typedef SMinMaxVar<Double_t> SMinMaxVarD;
template<typename T>
class SInertVar : public SMinMaxVar<T>
{
typedef SMinMaxVar<T> MMV;
protected:
T mDeltaInc, mDeltaDec;
T deltaminmax(T d) const
{
if (d > 0)
{
T lim = MMV::mVal >= 0 ? mDeltaInc : mDeltaDec;
return d > lim ? lim : d;
} else {
T lim = MMV::mVal <= 0 ? -mDeltaInc : -mDeltaDec;
return d < lim ? lim : d;
}
}
T deltaminmax(T d, T dt) const
{
if (d > 0)
{
T lim = MMV::mVal >= 0 ? mDeltaInc*dt : mDeltaDec*dt;
return d > lim ? lim : d;
} else {
T lim = MMV::mVal <= 0 ? -mDeltaInc*dt : -mDeltaDec*dt;
return d < lim ? lim : d;
}
}
T deltamaxpos(T dt) const
{
return MMV::mVal >= 0 ? mDeltaInc*dt : mDeltaDec*dt;
}
T deltamaxneg(T dt) const
{
return MMV::mVal <= 0 ? -mDeltaInc*dt : -mDeltaDec*dt;
}
public:
SInertVar()
: MMV(), mDeltaInc(1), mDeltaDec(-1)
{}
SInertVar(T val, T min, T max, T delta) :
MMV(val, min, max), mDeltaInc(delta), mDeltaDec(-delta)
{}
SInertVar(T val, T min, T max, T delta_i, T delta_d) :
MMV(val, min, max), mDeltaInc(delta_i), mDeltaDec(delta_d)
{}
T operator=(T v) { return Set(v); }
T Set(T v)
{
T d = deltaminmax(v - MMV::mVal);
return MMV::Set(MMV::mVal + d);
}
T Delta(T d)
{
d = deltaminmax(d);
return MMV::Delta(d);
}
T Delta(T d, T dt)
{
d = deltaminmax(d, dt);
return MMV::Delta(d);
}
T DeltaMaxPositive(T dt)
{
return MMV::Delta(deltamaxpos(dt));
}
T DeltaMaxNegative(T dt)
{
return MMV::Delta(deltamaxneg(dt));
}
T DeltaMax(Int_t sign, T dt)
{
if (sign > 0) return DeltaMaxPositive(dt);
else if (sign < 0) return DeltaMaxNegative(dt);
else return 0;
}
T GetDeltaInc() const { return mDeltaInc; }
void SetDeltaInc(T d) { mDeltaInc = d; }
T GetDeltaDec() const { return mDeltaDec; }
void SetDeltaDec(T d) { mDeltaDec = d; }
void SetMinMaxDelta(T min, T max, T delta_i, T delta_d)
{ SetMinMax(min, max); mDeltaInc = delta_i; mDeltaDec = delta_d; }
void Print() const
{
printf("%f [%f, %f; %f, %f]\n", MMV::mVal, MMV::mMin, MMV::mMax, mDeltaInc, mDeltaDec);
}
ClassDefNV(SInertVar, 1);
};
typedef SInertVar<Float_t> SInertVarF;
typedef SInertVar<Double_t> SInertVarD;
template<typename T>
class SDesireVar : public SInertVar<T>
{
typedef SMinMaxVar<T> MMV;
typedef SInertVar<T> IV;
protected:
T mStdDesireDelta;
mutable T mDesire;
mutable Bool_t bDesireSatisfied;
public:
SDesireVar() :
IV(), mStdDesireDelta(1), mDesire(0), bDesireSatisfied(true)
{}
SDesireVar(T val, T min, T max, T delta) :
IV(val, min, max, delta),
mStdDesireDelta(delta),
mDesire(val), bDesireSatisfied(true)
{}
SDesireVar(T val, T min, T max, T delta_i, T delta_d) :
IV(val, min, max, delta_i, delta_d),
mStdDesireDelta(TMath::Max(delta_i, delta_d)),
mDesire(val), bDesireSatisfied(true)
{}
T operator=(T v) { return Set(v); }
T Set(T v)
{
bDesireSatisfied = false;
T d = deltaminmax(v - MMV::mVal);
return MMV::Set(MMV::mVal + d);
}
T Delta(T d)
{
bDesireSatisfied = false;
d = deltaminmax(d);
return MMV::Delta(d);
}
T Delta(T d, T dt)
{
bDesireSatisfied = false;
d = deltaminmax(d, dt);
return MMV::Delta(d);
}
T GetStdDesireDelta() const { return mStdDesireDelta; }
void SetStdDesireDelta(T sdd) { mStdDesireDelta = sdd; }
T GetDesire() const { return mDesire; }
void SetDesire(T d) const { bDesireSatisfied = false; mDesire = valminmax(d); }
void DesireToValue() const { bDesireSatisfied = true; mDesire = MMV::mVal; }
T DeltaDesire(T d) const
{
bDesireSatisfied = false;
mDesire = valminmax(mDesire + d);
return mDesire;
}
T DeltaDesireMax(Int_t ifac, T dt) const
{
if (ifac) return DeltaDesire(ifac*mStdDesireDelta*dt);
else return 0;
}
Bool_t IsDesireSatisfied() const { return bDesireSatisfied; }
Bool_t IsAboveDesire() const { return MMV::mVal > mDesire; }
Bool_t IsBelowDesire() const { return MMV::mVal < mDesire; }
void SetMinMaxDeltaDesire(T min, T max, T delta_i, T delta_d, T desire)
{
SetMinMaxDelta(min, max, delta_i, delta_d);
SetDesire(desire);
}
void TimeTick(T dt)
{
if (bDesireSatisfied)
return;
if (MMV::mVal < mDesire)
{
DeltaMaxPositive(dt);
if (MMV::mVal > mDesire)
{
MMV::mVal = mDesire;
bDesireSatisfied = true;
}
}
else if (MMV::mVal > mDesire)
{
DeltaMaxNegative(dt);
if (MMV::mVal < mDesire)
{
MMV::mVal = mDesire;
bDesireSatisfied = true;
}
}
else
{
bDesireSatisfied = true;
}
}
void Print() const
{
printf("%f -> %f [%f, %f; %f, %f]\n", MMV::mVal, mDesire,
MMV::mMin, MMV::mMax, IV::mDeltaInc, IV::mDeltaDec);
}
ClassDefNV(SDesireVar, 1);
};
typedef SDesireVar<Float_t> SDesireVarF;
typedef SDesireVar<Double_t> SDesireVarD;
template<typename T>
class SExpDesireVar : public SDesireVar<T>
{
typedef SMinMaxVar<T> MMV;
typedef SInertVar<T> IV;
typedef SDesireVar<T> DV;
protected:
T mOmega;
UChar_t mExpMode;
public:
SExpDesireVar()
: DV(), mOmega(0), mExpMode(0)
{}
SExpDesireVar(T val, T min, T max, T delta) :
DV(val, min, max, delta), mOmega(0), mExpMode(0)
{}
SExpDesireVar(T val, T min, T max, T delta, T omega, T mode) :
DV(val, min, max, delta), mOmega(omega), mExpMode(mode)
{}
ClassDefNV(SExpDesireVar, 1);
};
typedef SExpDesireVar<Float_t> SExpDesireVarF;
typedef SExpDesireVar<Double_t> SExpDesireVarD;
#endif