Minsky
schema1.cc
Go to the documentation of this file.
1 /*
2  @copyright Steve Keen 2012
3  @author Russell Standish
4  This file is part of Minsky.
5 
6  Minsky is free software: you can redistribute it and/or modify it
7  under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Minsky is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with Minsky. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "cairoItems.h"
21 #include "schema1.h"
22 #include "schemaHelper.h"
23 #include "factory.h"
24 #include "str.h"
25 #include "minsky_epilogue.h"
26 using namespace ecolab;
27 
28 namespace schema1
29 {
30  const int Minsky::version;
31 
32  namespace
33  {
34  struct IsOrphan
35  {
36  set<int> ids;
37  void insert(int id) {ids.insert(id);}
38  bool operator()(const Variable& v) const {
39  return ids.contains(v.id);
40  }
41  bool operator()(const shared_ptr<Layout>& l) const {
42  return l && ids.contains(l->id);
43  }
44  };
45  }
46 
47  void Minsky::removeIntVarOrphans()
48  {
49  set<string> intNames;
50  for (vector<Operation>::const_iterator o=model.operations.begin();
51  o!=model.operations.end(); ++o)
53  intNames.insert(o->name);
54 
55  IsOrphan isOrphan;
56  for (vector<Variable>::const_iterator v=model.variables.begin();
57  v!=model.variables.end(); ++v)
58  // an orphaned variable is an integral variable not attached to an integral and without
59  if (v->type==minsky::VariableType::integral && intNames.contains(v->name)==0)
60  isOrphan.insert(v->id);
61 
62  model.variables.erase
63  (remove_if(model.variables.begin(), model.variables.end(), isOrphan),
64  model.variables.end());
65  layout.erase
66  (remove_if(layout.begin(), layout.end(), isOrphan), layout.end());
67  }
68 
69  Minsky::Minsky(const schema0::Minsky& m)
70  {
71  // uniquify all IDs
72  int nextId=0;
73  map<int,int> newPortIds;
74  map<int,int> newOpIds;
75  map<int,int> newVarIds;
76 
77  for (auto& i: m.ports)
78  newPortIds[i.first]=nextId++;
79  for (auto& i: m.wires)
80  {
81  model.wires.emplace_back(nextId, newPortIds[i.second.from], newPortIds[i.second.to]);
82  layout.emplace_back(new WireLayout(nextId++, i.second));
83  }
84  for (auto v: m.variables) //NOLINT - index var mutated in loop body
85  {
86  newVarIds[v.first]=nextId;
87  v.second.m_outPort=newPortIds[v.second.m_outPort];
88  if (v.second.m_inPort>=0)
89  v.second.m_inPort=newPortIds[v.second.m_inPort];
90  // values init field overrides that of the variable's
91  auto value=m.variables.values.find(v.second.name);
92  if (value!=m.variables.values.end())
93  v.second.init=value->second.init;
94  model.variables.emplace_back(nextId, v.second);
95  layout.emplace_back(new ItemLayout(nextId++, v.second));
96  }
97  for (auto i: m.operations)
98  {
99  newOpIds[i.first]=nextId;
100  for (auto& j: i.second.m_ports)
101  j=newPortIds[j];
102  if (i.second.intVar>-1) i.second.intVar=newVarIds[i.second.intVar];
103  model.operations.emplace_back(nextId, i.second);
104  layout.emplace_back(new ItemLayout(nextId++, i.second));
105  }
106 
107  for (auto i: m.plots.plots)
108  {
109  for (auto& j: i.second.ports)
110  j=newPortIds[j];
111  // insert another 6 ports for axis ranges that weren't there in schema 0
112  // move first 4 ports (x ports) to end, and add anothe 4 x ports
113  i.second.ports=(pcoord(6)+nextId)<<
114  i.second.ports[pcoord(8)+4]<<
115  i.second.ports[pcoord(4)]<<
116  (pcoord(4)+nextId+6);
117  nextId+=10;
118  model.plots.emplace_back(nextId, i.second);
119  layout.emplace_back(new PlotLayout(nextId++, i.second));
120  }
121 
122  for (auto g: m.groupItems)
123  {
124  for (auto& i: g.second.operations)
125  i=newOpIds[i];
126  for (auto& i: g.second.variables)
127  i=newVarIds[i];
128  for (auto& j: g.second.m_ports)
129  j=newPortIds[j];
130  // wires not used in new schema, no need to renumber
131  model.groups.emplace_back(nextId, g.second);
132  layout.emplace_back(new GroupLayout(nextId++, g.second));
133  }
134 
135  for (auto g: m.godleyItems)
136  {
137  // need to renumber ports in variables
138  for (auto& v: g.second.flowVars)
139  v.m_inPort=newPortIds[v.m_inPort];
140  for (auto& v: g.second.stockVars)
141  v.m_outPort=newPortIds[v.m_outPort];
142  model.godleys.emplace_back(nextId, g.second);
143  layout.emplace_back(new PositionLayout(nextId++, g.second.x, g.second.y));
144  }
145 
146  model.rungeKutta.stepMin=m.stepMin;
147  model.rungeKutta.stepMax=m.stepMax;
148  model.rungeKutta.nSteps=m.nSteps;
149  model.rungeKutta.epsAbs=m.epsAbs;
150  model.rungeKutta.epsRel=m.epsRel;
151  removeIntVarOrphans();
152  }
153 
154 }
155 
156 namespace classdesc
157 {
158  template<> Factory<schema1::Item,string>::Factory() {}
159  template<> Factory<schema1::Layout,string>::Factory()
160  {enumerateRegisterLayout(*this);}
161 }
162 
163 namespace schema1
164 {
165  using classdesc::Factory;
166 
167  struct ItemFactory: public Factory<schema1::Item,string>
168  {
170  using Factory<schema1::Item,string>::registerType;
171  // define our own registerType that avoids calling type()
172  template <class T> void registerType()
173  {registerType<T>(classdesc::typeName<T>());}
174  };
175 
177  Factory<schema1::Layout,string> factoryForLayout;
178 
179 }
180 
represent objects whose layouts just have a position (ports, plots, godleyIcons)
Definition: schema1.h:214
bool operator()(const shared_ptr< Layout > &l) const
Definition: schema1.cc:41
int nSteps
number of steps per GUI update
Definition: schema0.h:228
GroupIcons groupItems
Definition: schema0.h:219
VariableValues values
map of ports to variables
Definition: schema0.h:122
void enumerateRegisterItems(F &f)
utilities to call registerType for these class heirarchies, for different factory types ...
double epsAbs
absolute error
Definition: schema0.h:229
Factory< schema1::Layout, string > factoryForLayout
Definition: schema1.cc:177
represents layouts of objects like variables and operators
Definition: schema1.h:268
represents layouts of wires
Definition: schema1.h:257
group layouts also have a width & height
Definition: schema1.h:281
double stepMin
Runge-Kutta parameters.
Definition: schema0.h:226
double epsRel
relative error
Definition: schema0.h:230
ItemFactory itemFactory
Definition: schema1.cc:176
double stepMax
maximum step size
Definition: schema0.h:227
Operations operations
Definition: schema0.h:215
void enumerateRegisterLayout(Factory &f)
VariableManager variables
Definition: schema0.h:216
bool operator()(const Variable &v) const
Definition: schema1.cc:38
GodleyItems godleyItems
Definition: schema0.h:212