00001
00020 #ifndef CORENODE_BASE_HPP
00021 #define CORENODE_BASE_HPP
00022
00023
00027 #include "flopc.hpp"
00028
00029 namespace FlopSmiEx {
00030 using namespace flopc;
00031 using namespace std;
00032
00033
00034
00036 class CoreNodeBase {
00037 protected:
00039
00047 static CoreNodeBase * p2activeNode;
00048
00050
00055 static double const * p2varValues;
00056
00057 MP_expression objFuncNode;
00058 MP_expression objFuncRec;
00059
00060 public:
00062 CoreNodeBase(CoreNodeBase *p2pred, int nodeStage = -1)
00063 : p2parent(p2pred), p2child(NULL), stage(nodeStage)
00064 {
00065 if (p2parent != NULL) {
00066 assert (p2parent->p2child == NULL && "only one child per node in Core");
00067 p2parent->p2child = this;
00068 }
00069 CoreNodeBase::p2activeNode = this;
00070 }
00071
00072 virtual ~CoreNodeBase() {}
00073
00074 CoreNodeBase * p2parent;
00075 CoreNodeBase * p2child;
00076 int stage;
00077
00079
00084
00085 vector<VariableRef const *> all_variables;
00086 vector<MP_constraint *> all_constraints;
00087 vector<int> constr_row_offsets;
00088
00089
00091 void set_var_values(double const *p2values) {
00092 p2varValues = p2values;
00093 }
00094
00096
00097 MP_expression & get_obj_func() {
00098 if (p2parent != NULL) {
00099 cerr << "Warning: get_obj_func called from a non-root node!" << endl;
00100 }
00101 make_obj_func_rec();
00102 return objFuncRec;
00103 }
00104
00105 protected:
00107
00111 class SP_variable : public MP_variable {
00112 private:
00113 CoreNodeBase * p2node;
00114 int varIndx;
00115 public:
00116 SP_variable(MP_set const &s1 = MP_set::getEmpty(),
00117 MP_set const &s2 = MP_set::getEmpty())
00118 : MP_variable(s1, s2), p2node(CoreNodeBase::p2activeNode),
00119 varIndx(static_cast<int>(p2node->all_variables.size()))
00120 {
00121 #ifndef NDEBUG
00122 cout << "Stage " << p2node->stage << ": adding SP_variable with "
00123 << s1.size() * s2.size() << " element(s), starting at col "
00124 << varIndx << endl;
00125 #endif
00126 for (int i1 = 0; i1 < s1.size(); i1++) {
00127 for (int i2 = 0; i2 < s2.size(); i2++) {
00128 p2node->all_variables.push_back(& this->operator()(i1,i2));
00129 }
00130 }
00131 }
00132
00134
00141 double value(int const i1 = 0, int const i2 = 0) const {
00142 assert (CoreNodeBase::p2varValues != NULL
00143 && "variable values must be set before they are accessed!");
00144 return CoreNodeBase::p2varValues[varIndx + f(i1, i2)];
00145 }
00146 };
00147
00149
00170 class SP_constraint : public MP_constraint {
00171 private:
00172 CoreNodeBase * p2node;
00173 int constrIndx;
00174 public:
00175 SP_constraint (MP_set const &s1 = MP_set::getEmpty())
00176 : MP_constraint(s1), p2node(CoreNodeBase::p2activeNode),
00177 constrIndx(static_cast<int>(p2node->all_constraints.size()))
00178 {
00179 #ifndef NDEBUG
00180 cout << "Stage " << p2node->stage << ": adding SP_constr. with "
00181 << s1.size() << " element(s), starting at row " << constrIndx
00182 << endl;
00183 #endif
00184 for (int i1 = 0; i1 < s1.size(); i1++) {
00185 p2node->all_constraints.push_back(this);
00186 p2node->constr_row_offsets.push_back(i1);
00187 }
00188 }
00189 };
00190
00192
00196 void make_obj_func_rec();
00197 };
00198
00199
00200 }
00201 #endif