00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "numeric/funcobj.hxx"
00029 #include "numeric/exception.hxx"
00030 #include <vector>
00031 #include <string>
00032 #include <sstream>
00033
00034 using ::std::vector;
00035 using ::std::string;
00036
00037 namespace scsolver { namespace numeric {
00038
00039 const char* VarSizeException::what() const throw()
00040 {
00041 return "variable size exception";
00042 }
00043
00048 class BaseFuncSingleObjImpl : public SingleVarFuncObj
00049 {
00050 public:
00051 BaseFuncSingleObjImpl(BaseFuncObj& rParent, size_t varIndex) :
00052 m_rParent(rParent),
00053 m_varIndex(varIndex)
00054 {
00055 if (varIndex >= m_rParent.getVarCount())
00056 throw VarSizeException();
00057 }
00058
00059 virtual ~BaseFuncSingleObjImpl()
00060 {
00061 }
00062
00063 virtual void setVar(double var)
00064 {
00065 m_rParent.setVar(m_varIndex, var);
00066 }
00067
00068 virtual double getVar() const
00069 {
00070 return m_rParent.getVar(m_varIndex);
00071 }
00072
00073 virtual double eval() const
00074 {
00075 return m_rParent.eval();
00076 }
00077
00078 virtual const string getFuncString() const
00079 {
00080 return m_rParent.getFuncString();
00081 }
00082
00083 private:
00084 BaseFuncObj& m_rParent;
00085 size_t m_varIndex;
00086 };
00087
00088
00089
00099 class BaseFuncRatioObjImpl : public SingleVarFuncObj
00100 {
00101 public:
00102 BaseFuncRatioObjImpl(BaseFuncObj& rParent, const vector<double>& ratios) :
00103 m_rParent(rParent),
00104 m_ratios(ratios),
00105 m_varIndex(0)
00106 {
00107 size_t varCount = m_rParent.getVarCount();
00108 if (ratios.size() != varCount || varCount == 0)
00109 throw VarSizeException();
00110
00111
00112
00113 bool varIndexFound = false;
00114 for (size_t i = 0; i < varCount; ++i)
00115 {
00116 double absRatio = m_ratios[i] > 0 ? m_ratios[i] : -m_ratios[i];
00117 if (absRatio > 3.89e-15)
00118 {
00119 m_varIndex = i;
00120 varIndexFound = true;
00121 break;
00122 }
00123 }
00124
00125 if (!varIndexFound)
00126 throw Exception("BaseFuncRatioObjImpl::BaseFuncratioObjImpl: variable index not found");
00127
00128 m_oldVar = rParent.getVar(m_varIndex);
00129 }
00130
00131 virtual ~BaseFuncRatioObjImpl()
00132 {
00133 }
00134
00135 virtual void setVar(double var)
00136 {
00137 m_rParent.setVar(m_varIndex, var);
00138 double delta = var - m_oldVar;
00139
00140 size_t n = m_ratios.size();
00141 double baseRatio = m_ratios.at(m_varIndex);
00142 for (size_t i = 0; i < n; ++i)
00143 {
00144 if (i == m_varIndex)
00145 continue;
00146
00147 double ratio = m_ratios[i]/baseRatio;
00148 double origVal = m_rParent.getVar(i) + delta*ratio;
00149 m_rParent.setVar(i, origVal);
00150 }
00151
00152 m_oldVar = var;
00153 }
00154
00155 virtual double getVar() const
00156 {
00157 return m_rParent.getVar(0);
00158 }
00159
00160 virtual double eval() const
00161 {
00162 return m_rParent.eval();
00163 }
00164
00165 virtual const string getFuncString() const
00166 {
00167 string funcStr = m_rParent.getFuncString();
00168 if (m_ratios.empty())
00169 return funcStr;
00170
00171 ::std::ostringstream os;
00172 os << funcStr << " : locked ratio (";
00173 size_t n = m_ratios.size();
00174 for (size_t i = 0; i < n; ++i)
00175 {
00176 if (i > 0)
00177 os << ", ";
00178 os << m_ratios.at(i);
00179 }
00180 os << ")";
00181 return os.str();
00182 }
00183
00184 private:
00185 BaseFuncObj& m_rParent;
00186 vector<double> m_ratios;
00187 size_t m_varIndex;
00188 double m_oldVar;
00189 };
00190
00191
00192
00193
00194 BaseFuncObj::BaseFuncObj() :
00195 m_pSVFuncObj(NULL)
00196 {
00197 }
00198
00199 BaseFuncObj::BaseFuncObj(size_t varCount) :
00200 m_vars(varCount),
00201 m_pSVFuncObj(NULL)
00202 {
00203 }
00204
00205 BaseFuncObj::BaseFuncObj(const BaseFuncObj& r) :
00206 m_vars(r.m_vars),
00207 m_pSVFuncObj(NULL)
00208
00209 {
00210 }
00211
00212 BaseFuncObj::~BaseFuncObj()
00213 {
00214 }
00215
00216 const vector<double>& BaseFuncObj::getVars() const
00217 {
00218 return m_vars;
00219 }
00220
00221 double BaseFuncObj::getVar(size_t index) const
00222 {
00223 return m_vars.at(index);
00224 }
00225
00226 SingleVarFuncObj& BaseFuncObj::getSingleVarFuncObj(size_t varIndex)
00227 {
00228 m_pSVFuncObj.reset(new BaseFuncSingleObjImpl(*this, varIndex));
00229 return *m_pSVFuncObj;
00230 }
00231
00232 SingleVarFuncObj& BaseFuncObj::getSingleVarFuncObjByRatio(const vector<double>& ratios)
00233 {
00234 m_pSVFuncObj.reset(new BaseFuncRatioObjImpl(*this, ratios));
00235 return *m_pSVFuncObj;
00236 }
00237
00238 void BaseFuncObj::setVar(size_t index, double var) const
00239 {
00240 if (index >= m_vars.size())
00241 return;
00242
00243 m_vars[index] = var;
00244 }
00245
00246 void BaseFuncObj::setVars(const vector<double> &vars) const
00247 {
00248 vector<double> tmp(vars);
00249 m_vars.swap(tmp);
00250 }
00251
00252 size_t BaseFuncObj::getVarCount() const
00253 {
00254 return m_vars.size();
00255 }
00256
00257 double BaseFuncObj::operator ()(const vector<double>& vars) const
00258 {
00259 setVars(vars);
00260 return eval();
00261 }
00262
00263
00264
00265 SingleVarFuncObj::SingleVarFuncObj()
00266 {
00267 }
00268
00269 SingleVarFuncObj::~SingleVarFuncObj()
00270 {
00271 }
00272
00273 double SingleVarFuncObj::operator()(double var)
00274 {
00275 setVar(var);
00276 return eval();
00277 }
00278
00279 }}