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
30class CoinModelLink {
31
32public:
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
89private:
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
107typedef 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;
115inline int rowInTriple(const CoinModelTriple & triple)
116{ return triple.row&0x7fffffff;}
117inline void setRowInTriple(CoinModelTriple & triple,int iRow)
118{ triple.row = iRow|(triple.row&0x80000000);}
119inline bool stringInTriple(const CoinModelTriple & triple)
120{ return (triple.row&0x80000000)!=0;}
121inline void setStringInTriple(CoinModelTriple & triple,bool string)
122{ triple.row = (string ? 0x80000000 : 0)|(triple.row&0x7fffffff);}
123inline void setRowAndStringInTriple(CoinModelTriple & triple,
124 int iRow,bool string)
125{ triple.row = (string ? 0x80000000 : 0)|iRow;}
126/// for names and hashing
127// for hashing
128typedef struct {
129 int index, next;
130} CoinModelHashLink;
131
132/* Function type. */
133typedef double (*func_t) (double);
134
135/// For string evaluation
136/* Data type for links in the chain of symbols. */
137struct 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
149typedef struct symrec symrec;
150
151class CoinYacc {
152private:
153 CoinYacc(const CoinYacc& rhs);
154 CoinYacc& operator=(const CoinYacc& rhs);
155
156public:
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
173public:
174 symrec * symtable;
175 char * symbuf;
176 int length;
177 double unsetValue;
178};
179
180class CoinModelHash {
181
182public:
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;
232private:
233 /// Returns a hash value
234 int hashValue(const char * name) const;
235public:
236 //@}
237private:
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
253class CoinModelHash2 {
254
255public:
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);
294private:
295 /// Returns a hash value
296 int hashValue(int row, int column) const;
297public:
298 //@}
299private:
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};
312class CoinModelLinkedList {
313
314public:
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 //@}
417private:
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