1 | /* $Id: CoinModelUseful.hpp 1448 2011-06-19 15:34:41Z stefan $ */ |
2 | // Copyright (C) 2005, International Business Machines |
3 | // Corporation and others. All Rights Reserved. |
4 | // This code is licensed under the terms of the Eclipse Public License (EPL). |
5 | |
6 | #ifndef CoinModelUseful_H |
7 | #define CoinModelUseful_H |
8 | |
9 | |
10 | #include <cstdlib> |
11 | #include <cmath> |
12 | #include <cassert> |
13 | #include <cfloat> |
14 | #include <cstring> |
15 | #include <cstdio> |
16 | #include <iostream> |
17 | |
18 | |
19 | #include "CoinPragma.hpp" |
20 | |
21 | /** |
22 | This is for various structures/classes needed by CoinModel. |
23 | |
24 | CoinModelLink |
25 | CoinModelLinkedList |
26 | CoinModelHash |
27 | */ |
28 | /// for going through row or column |
29 | |
30 | class CoinModelLink { |
31 | |
32 | public: |
33 | /**@name Constructors, destructor */ |
34 | //@{ |
35 | /** Default constructor. */ |
36 | CoinModelLink(); |
37 | /** Destructor */ |
38 | ~CoinModelLink(); |
39 | //@} |
40 | |
41 | /**@name Copy method */ |
42 | //@{ |
43 | /** The copy constructor. */ |
44 | CoinModelLink(const CoinModelLink&); |
45 | /// = |
46 | CoinModelLink& operator=(const CoinModelLink&); |
47 | //@} |
48 | |
49 | /**@name Sets and gets method */ |
50 | //@{ |
51 | /// Get row |
52 | inline int row() const |
53 | { return row_;} |
54 | /// Get column |
55 | inline int column() const |
56 | { return column_;} |
57 | /// Get value |
58 | inline double value() const |
59 | { return value_;} |
60 | /// Get value |
61 | inline double element() const |
62 | { return value_;} |
63 | /// Get position |
64 | inline int position() const |
65 | { return position_;} |
66 | /// Get onRow |
67 | inline bool onRow() const |
68 | { return onRow_;} |
69 | /// Set row |
70 | inline void setRow(int row) |
71 | { row_=row;} |
72 | /// Set column |
73 | inline void setColumn(int column) |
74 | { column_=column;} |
75 | /// Set value |
76 | inline void setValue(double value) |
77 | { value_=value;} |
78 | /// Set value |
79 | inline void setElement(double value) |
80 | { value_=value;} |
81 | /// Set position |
82 | inline void setPosition(int position) |
83 | { position_=position;} |
84 | /// Set onRow |
85 | inline void setOnRow(bool onRow) |
86 | { onRow_=onRow;} |
87 | //@} |
88 | |
89 | private: |
90 | /**@name Data members */ |
91 | //@{ |
92 | /// Row |
93 | int row_; |
94 | /// Column |
95 | int column_; |
96 | /// Value as double |
97 | double value_; |
98 | /// Position in data |
99 | int position_; |
100 | /// If on row chain |
101 | bool onRow_; |
102 | //@} |
103 | }; |
104 | |
105 | /// for linked lists |
106 | // for specifying triple |
107 | typedef struct { |
108 | // top bit is nonzero if string |
109 | // rest is row |
110 | unsigned int row; |
111 | //CoinModelRowIndex row; |
112 | int column; |
113 | double value; // If string then index into strings |
114 | } CoinModelTriple; |
115 | inline int rowInTriple(const CoinModelTriple & triple) |
116 | { return triple.row&0x7fffffff;} |
117 | inline void setRowInTriple(CoinModelTriple & triple,int iRow) |
118 | { triple.row = iRow|(triple.row&0x80000000);} |
119 | inline bool stringInTriple(const CoinModelTriple & triple) |
120 | { return (triple.row&0x80000000)!=0;} |
121 | inline void setStringInTriple(CoinModelTriple & triple,bool string) |
122 | { triple.row = (string ? 0x80000000 : 0)|(triple.row&0x7fffffff);} |
123 | inline void setRowAndStringInTriple(CoinModelTriple & triple, |
124 | int iRow,bool string) |
125 | { triple.row = (string ? 0x80000000 : 0)|iRow;} |
126 | /// for names and hashing |
127 | // for hashing |
128 | typedef struct { |
129 | int index, next; |
130 | } CoinModelHashLink; |
131 | |
132 | /* Function type. */ |
133 | typedef double (*func_t) (double); |
134 | |
135 | /// For string evaluation |
136 | /* Data type for links in the chain of symbols. */ |
137 | struct symrec |
138 | { |
139 | char *name; /* name of symbol */ |
140 | int type; /* type of symbol: either VAR or FNCT */ |
141 | union |
142 | { |
143 | double var; /* value of a VAR */ |
144 | func_t fnctptr; /* value of a FNCT */ |
145 | } value; |
146 | struct symrec *next; /* link field */ |
147 | }; |
148 | |
149 | typedef struct symrec symrec; |
150 | |
151 | class CoinYacc { |
152 | private: |
153 | CoinYacc(const CoinYacc& rhs); |
154 | CoinYacc& operator=(const CoinYacc& rhs); |
155 | |
156 | public: |
157 | CoinYacc() : symtable(nullptr), symbuf(nullptr), length(0), unsetValue(0) {} |
158 | ~CoinYacc() |
159 | { |
160 | if (length) { |
161 | free(symbuf); |
162 | symbuf = nullptr; |
163 | } |
164 | symrec* s = symtable; |
165 | while (s) { |
166 | free(s->name); |
167 | symtable = s; |
168 | s = s->next; |
169 | free(symtable); |
170 | } |
171 | } |
172 | |
173 | public: |
174 | symrec * symtable; |
175 | char * symbuf; |
176 | int length; |
177 | double unsetValue; |
178 | }; |
179 | |
180 | class CoinModelHash { |
181 | |
182 | public: |
183 | /**@name Constructors, destructor */ |
184 | //@{ |
185 | /** Default constructor. */ |
186 | CoinModelHash(); |
187 | /** Destructor */ |
188 | ~CoinModelHash(); |
189 | //@} |
190 | |
191 | /**@name Copy method */ |
192 | //@{ |
193 | /** The copy constructor. */ |
194 | CoinModelHash(const CoinModelHash&); |
195 | /// = |
196 | CoinModelHash& operator=(const CoinModelHash&); |
197 | //@} |
198 | |
199 | /**@name sizing (just increases) */ |
200 | //@{ |
201 | /// Resize hash (also re-hashs) |
202 | void resize(int maxItems,bool forceReHash=false); |
203 | /// Number of items i.e. rows if just row names |
204 | inline int numberItems() const |
205 | { return numberItems_;} |
206 | /// Set number of items |
207 | void setNumberItems(int number); |
208 | /// Maximum number of items |
209 | inline int maximumItems() const |
210 | { return maximumItems_;} |
211 | /// Names |
212 | inline const char *const * names() const |
213 | { return names_;} |
214 | //@} |
215 | |
216 | /**@name hashing */ |
217 | //@{ |
218 | /// Returns index or -1 |
219 | int hash(const char * name) const; |
220 | /// Adds to hash |
221 | void addHash(int index, const char * name); |
222 | /// Deletes from hash |
223 | void deleteHash(int index); |
224 | /// Returns name at position (or NULL) |
225 | const char * name(int which) const; |
226 | /// Returns non const name at position (or NULL) |
227 | char * getName(int which) const; |
228 | /// Sets name at position (does not create) |
229 | void setName(int which,char * name ) ; |
230 | /// Validates |
231 | void validateHash() const; |
232 | private: |
233 | /// Returns a hash value |
234 | int hashValue(const char * name) const; |
235 | public: |
236 | //@} |
237 | private: |
238 | /**@name Data members */ |
239 | //@{ |
240 | /// Names |
241 | char ** names_; |
242 | /// hash |
243 | CoinModelHashLink * hash_; |
244 | /// Number of items |
245 | int numberItems_; |
246 | /// Maximum number of items |
247 | int maximumItems_; |
248 | /// Last slot looked at |
249 | int lastSlot_; |
250 | //@} |
251 | }; |
252 | /// For int,int hashing |
253 | class CoinModelHash2 { |
254 | |
255 | public: |
256 | /**@name Constructors, destructor */ |
257 | //@{ |
258 | /** Default constructor. */ |
259 | CoinModelHash2(); |
260 | /** Destructor */ |
261 | ~CoinModelHash2(); |
262 | //@} |
263 | |
264 | /**@name Copy method */ |
265 | //@{ |
266 | /** The copy constructor. */ |
267 | CoinModelHash2(const CoinModelHash2&); |
268 | /// = |
269 | CoinModelHash2& operator=(const CoinModelHash2&); |
270 | //@} |
271 | |
272 | /**@name sizing (just increases) */ |
273 | //@{ |
274 | /// Resize hash (also re-hashs) |
275 | void resize(int maxItems, const CoinModelTriple * triples,bool forceReHash=false); |
276 | /// Number of items |
277 | inline int numberItems() const |
278 | { return numberItems_;} |
279 | /// Set number of items |
280 | void setNumberItems(int number); |
281 | /// Maximum number of items |
282 | inline int maximumItems() const |
283 | { return maximumItems_;} |
284 | //@} |
285 | |
286 | /**@name hashing */ |
287 | //@{ |
288 | /// Returns index or -1 |
289 | int hash(int row, int column, const CoinModelTriple * triples) const; |
290 | /// Adds to hash |
291 | void addHash(int index, int row, int column, const CoinModelTriple * triples); |
292 | /// Deletes from hash |
293 | void deleteHash(int index, int row, int column); |
294 | private: |
295 | /// Returns a hash value |
296 | int hashValue(int row, int column) const; |
297 | public: |
298 | //@} |
299 | private: |
300 | /**@name Data members */ |
301 | //@{ |
302 | /// hash |
303 | CoinModelHashLink * hash_; |
304 | /// Number of items |
305 | int numberItems_; |
306 | /// Maximum number of items |
307 | int maximumItems_; |
308 | /// Last slot looked at |
309 | int lastSlot_; |
310 | //@} |
311 | }; |
312 | class CoinModelLinkedList { |
313 | |
314 | public: |
315 | /**@name Constructors, destructor */ |
316 | //@{ |
317 | /** Default constructor. */ |
318 | CoinModelLinkedList(); |
319 | /** Destructor */ |
320 | ~CoinModelLinkedList(); |
321 | //@} |
322 | |
323 | /**@name Copy method */ |
324 | //@{ |
325 | /** The copy constructor. */ |
326 | CoinModelLinkedList(const CoinModelLinkedList&); |
327 | /// = |
328 | CoinModelLinkedList& operator=(const CoinModelLinkedList&); |
329 | //@} |
330 | |
331 | /**@name sizing (just increases) */ |
332 | //@{ |
333 | /** Resize list - for row list maxMajor is maximum rows. |
334 | */ |
335 | void resize(int maxMajor,int maxElements); |
336 | /** Create list - for row list maxMajor is maximum rows. |
337 | type 0 row list, 1 column list |
338 | */ |
339 | void create(int maxMajor,int maxElements, |
340 | int numberMajor, int numberMinor, |
341 | int type, |
342 | int numberElements, const CoinModelTriple * triples); |
343 | /// Number of major items i.e. rows if just row links |
344 | inline int numberMajor() const |
345 | { return numberMajor_;} |
346 | /// Maximum number of major items i.e. rows if just row links |
347 | inline int maximumMajor() const |
348 | { return maximumMajor_;} |
349 | /// Number of elements |
350 | inline int numberElements() const |
351 | { return numberElements_;} |
352 | /// Maximum number of elements |
353 | inline int maximumElements() const |
354 | { return maximumElements_;} |
355 | /// First on free chain |
356 | inline int firstFree() const |
357 | { return first_[maximumMajor_];} |
358 | /// Last on free chain |
359 | inline int lastFree() const |
360 | { return last_[maximumMajor_];} |
361 | /// First on chain |
362 | inline int first(int which) const |
363 | { return first_[which];} |
364 | /// Last on chain |
365 | inline int last(int which) const |
366 | { return last_[which];} |
367 | /// Next array |
368 | inline const int * next() const |
369 | { return next_;} |
370 | /// Previous array |
371 | inline const int * previous() const |
372 | { return previous_;} |
373 | //@} |
374 | |
375 | /**@name does work */ |
376 | //@{ |
377 | /** Adds to list - easy case i.e. add row to row list |
378 | Returns where chain starts |
379 | */ |
380 | int addEasy(int majorIndex, int numberOfElements, const int * indices, |
381 | const double * elements, CoinModelTriple * triples, |
382 | CoinModelHash2 & hash); |
383 | /** Adds to list - hard case i.e. add row to column list |
384 | */ |
385 | void addHard(int minorIndex, int numberOfElements, const int * indices, |
386 | const double * elements, CoinModelTriple * triples, |
387 | CoinModelHash2 & hash); |
388 | /** Adds to list - hard case i.e. add row to column list |
389 | This is when elements have been added to other copy |
390 | */ |
391 | void addHard(int first, const CoinModelTriple * triples, |
392 | int firstFree, int lastFree,const int * nextOther); |
393 | /** Deletes from list - same case i.e. delete row from row list |
394 | */ |
395 | void deleteSame(int which, CoinModelTriple * triples, |
396 | CoinModelHash2 & hash, bool zapTriples); |
397 | /** Deletes from list - other case i.e. delete row from column list |
398 | This is when elements have been deleted from other copy |
399 | */ |
400 | void updateDeleted(int which, CoinModelTriple * triples, |
401 | CoinModelLinkedList & otherList); |
402 | /** Deletes one element from Row list |
403 | */ |
404 | void deleteRowOne(int position, CoinModelTriple * triples, |
405 | CoinModelHash2 & hash); |
406 | /** Update column list for one element when |
407 | one element deleted from row copy |
408 | */ |
409 | void updateDeletedOne(int position, const CoinModelTriple * triples); |
410 | /// Fills first,last with -1 |
411 | void fill(int first,int last); |
412 | /** Puts in free list from other list */ |
413 | void synchronize(CoinModelLinkedList & other); |
414 | /// Checks that links are consistent |
415 | void validateLinks(const CoinModelTriple * triples) const; |
416 | //@} |
417 | private: |
418 | /**@name Data members */ |
419 | //@{ |
420 | /// Previous - maximumElements long |
421 | int * previous_; |
422 | /// Next - maximumElements long |
423 | int * next_; |
424 | /// First - maximumMajor+1 long (last free element chain) |
425 | int * first_; |
426 | /// Last - maximumMajor+1 long (last free element chain) |
427 | int * last_; |
428 | /// Number of major items i.e. rows if just row links |
429 | int numberMajor_; |
430 | /// Maximum number of major items i.e. rows if just row links |
431 | int maximumMajor_; |
432 | /// Number of elements |
433 | int numberElements_; |
434 | /// Maximum number of elements |
435 | int maximumElements_; |
436 | /// 0 row list, 1 column list |
437 | int type_; |
438 | //@} |
439 | }; |
440 | |
441 | #endif |
442 | |