| 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 | |