Rev 2175 | Rev 2824 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 2 | fmk | 1 | /* ****************************************************************** ** |
| 2 | ** OpenSees - Open System for Earthquake Engineering Simulation ** |
||
| 3 | ** Pacific Earthquake Engineering Research Center ** |
||
| 4 | ** ** |
||
| 5 | ** ** |
||
| 6 | ** (C) Copyright 1999, The Regents of the University of California ** |
||
| 7 | ** All Rights Reserved. ** |
||
| 8 | ** ** |
||
| 9 | ** Commercial use of this program without express permission of the ** |
||
| 10 | ** University of California, Berkeley, is strictly prohibited. See ** |
||
| 11 | ** file 'COPYRIGHT' in main directory for information on usage and ** |
||
| 12 | ** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** |
||
| 13 | ** ** |
||
| 14 | ** Developed by: ** |
||
| 15 | ** Frank McKenna (fmckenna@ce.berkeley.edu) ** |
||
| 16 | ** Gregory L. Fenves (fenves@ce.berkeley.edu) ** |
||
| 17 | ** Filip C. Filippou (filippou@ce.berkeley.edu) ** |
||
| 18 | ** ** |
||
| 19 | ** ****************************************************************** */ |
||
| 20 | |||
| 2418 | fmk | 21 | // $Revision: 1.11 $ |
| 22 | // $Date: 2006-05-26 18:19:16 $ |
||
| 2 | fmk | 23 | // $Source: /usr/local/cvs/OpenSees/SRC/matrix/ID.cpp,v $ |
| 24 | |||
| 25 | |||
| 26 | // Written: fmk |
||
| 27 | // Revision: A |
||
| 28 | // |
||
| 29 | // Description: This file contains the class implementation for ID. |
||
| 30 | // |
||
| 31 | // What: "@(#) ID.C, revA" |
||
| 32 | |||
| 33 | #include "ID.h" |
||
| 34 | #include <stdlib.h> |
||
| 35 | |||
| 36 | |||
| 37 | int ID::ID_NOT_VALID_ENTRY = 0; |
||
| 38 | |||
| 39 | // ID(): |
||
| 40 | // Standard constructor, sets size = 0; |
||
| 41 | |||
| 42 | ID::ID() |
||
| 947 | mhscott | 43 | :sz(0), data(0), arraySize(0), fromFree(0) |
| 2 | fmk | 44 | { |
| 45 | |||
| 46 | } |
||
| 47 | |||
| 48 | |||
| 49 | // ID(int size): |
||
| 50 | // Constructor used to allocate a ID of size size. |
||
| 51 | |||
| 52 | ID::ID(int size) |
||
| 947 | mhscott | 53 | :sz(size), data(0), arraySize(size), fromFree(0) |
| 2 | fmk | 54 | { |
| 55 | |||
| 56 | #ifdef _G3DEBUG |
||
| 57 | if (sz <= 0) { |
||
| 1276 | fmk | 58 | opserr << "ID::ID(int) - size " << size << " specified <= 0\n"; |
| 2 | fmk | 59 | sz = 1; |
| 60 | arraySize = 1; |
||
| 61 | } |
||
| 62 | #endif |
||
| 63 | |||
| 64 | // create the space for the data & check space was available |
||
| 1745 | fmk | 65 | // data = (int *)malloc(size*sizeof(int)); |
| 66 | data = new int[size]; |
||
| 2 | fmk | 67 | if (data == 0) { |
| 1271 | fmk | 68 | opserr << "ID::ID(int): ran out of memory with size " << size << endln; |
| 2 | fmk | 69 | exit(-1); |
| 70 | } |
||
| 71 | |||
| 72 | // zero the data |
||
| 73 | for (int i=0; i<size; i++) |
||
| 74 | data[i] = 0; |
||
| 75 | } |
||
| 76 | |||
| 77 | |||
| 78 | // ID(int size): |
||
| 79 | // Constructor used to allocate a ID of size size. |
||
| 80 | |||
| 81 | ID::ID(int size, int arraySz) |
||
| 947 | mhscott | 82 | :sz(size), data(0), arraySize(arraySz), fromFree(0) |
| 2 | fmk | 83 | { |
| 84 | #ifdef _G3DEBUG |
||
| 85 | if (sz < 0) { |
||
| 1276 | fmk | 86 | opserr << "ID::ID(size, arraySize) - size " << size << " specified < 0\n"; |
| 2 | fmk | 87 | sz = 0; |
| 88 | } |
||
| 89 | if (arraySz <= 0) { |
||
| 1276 | fmk | 90 | opserr << "ID::ID(size, arraySize) - arraySize " << arraySz << " specified < 0\n"; |
| 2 | fmk | 91 | if (sz != 0) |
| 92 | arraySz = sz; |
||
| 93 | else |
||
| 94 | arraySz = 1; |
||
| 95 | } |
||
| 96 | if (arraySz < sz) { |
||
| 1276 | fmk | 97 | opserr << "ID::ID(size, arraySize) - arraySize " << arraySz << " specified < " << size << endln; |
| 2 | fmk | 98 | arraySz = sz; |
| 99 | } |
||
| 100 | #endif |
||
| 101 | |||
| 102 | // create the space |
||
| 1745 | fmk | 103 | // data = (int *)malloc(arraySize*sizeof(int)); |
| 104 | data = new int[arraySize]; |
||
| 2 | fmk | 105 | if (data == 0) { |
| 1271 | fmk | 106 | opserr << "ID::ID(int, int): ran out of memory with arraySize: " << arraySize << endln; |
| 2 | fmk | 107 | exit(-1); |
| 108 | } |
||
| 109 | |||
| 110 | // zero the data |
||
| 111 | for (int i=0; i<arraySize; i++) |
||
| 112 | data[i] = 0; |
||
| 113 | } |
||
| 114 | |||
| 1745 | fmk | 115 | ID::ID(int *d, int size, bool cleanIt) |
| 947 | mhscott | 116 | :sz(size), data(d), arraySize(size), fromFree(1) |
| 117 | { |
||
| 1271 | fmk | 118 | if (d == 0) { // OOPS must have been other constructor we wanted |
| 119 | sz = 0; |
||
| 120 | data = 0; |
||
| 121 | arraySize = size; |
||
| 122 | fromFree = 0; |
||
| 2 | fmk | 123 | |
| 1271 | fmk | 124 | // create the space |
| 125 | if (arraySize != 0) { |
||
| 126 | data = (int *)malloc(arraySize*sizeof(int)); |
||
| 127 | if (data == 0) { |
||
| 128 | opserr << "ID::ID(int, int): ran out of memory with arraySize " << arraySize << endln; |
||
| 129 | exit(-1); |
||
| 130 | } |
||
| 131 | } |
||
| 132 | |||
| 133 | // zero the data |
||
| 134 | for (int i=0; i<arraySize; i++) |
||
| 135 | data[i] = 0; |
||
| 136 | } |
||
| 1745 | fmk | 137 | |
| 138 | if (cleanIt == true) |
||
| 139 | fromFree = 0; |
||
| 947 | mhscott | 140 | } |
| 2 | fmk | 141 | |
| 142 | // ID(const ID&): |
||
| 143 | // Constructor to init a ID from another. |
||
| 144 | |||
| 145 | ID::ID(const ID &other) |
||
| 947 | mhscott | 146 | :sz(other.sz), data(0), arraySize(other.arraySize), fromFree(0) |
| 2 | fmk | 147 | { |
| 148 | // create the space |
||
| 1745 | fmk | 149 | // data = (int *)malloc(arraySize*sizeof(int)); |
| 150 | data = new int[arraySize]; |
||
| 2 | fmk | 151 | if (data == 0) { |
| 1271 | fmk | 152 | opserr << "ID::ID(ID): ran out of memory with arraySize " << arraySize << endln, |
| 2 | fmk | 153 | exit(-1); |
| 154 | } |
||
| 155 | |||
| 156 | // copy the data |
||
| 157 | for (int i=0; i<sz; i++) |
||
| 158 | data[i] = other.data[i]; |
||
| 159 | } |
||
| 160 | |||
| 161 | |||
| 162 | |||
| 163 | // ~ID(): |
||
| 164 | // destructor, deletes the [] data |
||
| 165 | |||
| 166 | ID::~ID() |
||
| 167 | { |
||
| 947 | mhscott | 168 | if (data != 0 && fromFree == 0) |
| 1745 | fmk | 169 | // free((void *)data); |
| 170 | delete [] data; |
||
| 2 | fmk | 171 | } |
| 172 | |||
| 1137 | fmk | 173 | int |
| 1745 | fmk | 174 | ID::setData(int *newData, int size, bool cleanIt){ |
| 2160 | fmk | 175 | |
| 1137 | fmk | 176 | if (data != 0 && fromFree == 0) |
| 1745 | fmk | 177 | // free((void *)data); |
| 178 | delete [] data; |
||
| 2 | fmk | 179 | |
| 1137 | fmk | 180 | sz = size; |
| 181 | data = newData; |
||
| 1745 | fmk | 182 | |
| 183 | if (cleanIt == false) |
||
| 184 | fromFree = 1; |
||
| 185 | else |
||
| 186 | fromFree = 0; |
||
| 1137 | fmk | 187 | |
| 188 | if (sz <= 0) { |
||
| 1271 | fmk | 189 | opserr << "ID::ID(int *, size) - size " << size << " specified <= 0\n"; |
| 1137 | fmk | 190 | sz = 0; |
| 191 | } |
||
| 192 | |||
| 193 | return 0; |
||
| 194 | } |
||
| 195 | |||
| 196 | |||
| 2 | fmk | 197 | void |
| 198 | ID::Zero(void) |
||
| 199 | { |
||
| 200 | for (int i=0; i<sz; i++) |
||
| 201 | data[i] =0; |
||
| 202 | } |
||
| 203 | |||
| 204 | int |
||
| 205 | ID::getLocation(int value) const |
||
| 206 | { |
||
| 207 | // search through ID for the value |
||
| 208 | for (int i=0; i<sz; i++) |
||
| 209 | if (data[i] == value) |
||
| 210 | return i; |
||
| 211 | |||
| 212 | // if we get here the value is not in the array |
||
| 213 | return -1; |
||
| 214 | } |
||
| 215 | |||
| 2152 | fmk | 216 | |
| 2 | fmk | 217 | int |
| 2152 | fmk | 218 | ID::getLocationOrdered(int value) const |
| 219 | { |
||
| 220 | int middle = 0; |
||
| 221 | int left = 0; |
||
| 222 | int right = sz-1; |
||
| 223 | if (sz != 0) { |
||
| 224 | while (left <= right) { |
||
| 225 | middle = (left + right)/2; |
||
| 226 | double dataMiddle = data[middle]; |
||
| 227 | if (value == dataMiddle) |
||
| 228 | return middle; // already there |
||
| 229 | else if (value > dataMiddle) |
||
| 230 | left = middle + 1; |
||
| 231 | else |
||
| 232 | right = middle-1; |
||
| 233 | } |
||
| 234 | } |
||
| 235 | |||
| 236 | // if we get here the value is not in the array |
||
| 237 | return -1; |
||
| 238 | } |
||
| 239 | |||
| 240 | |||
| 241 | int |
||
| 2 | fmk | 242 | ID::removeValue(int value) |
| 243 | { |
||
| 244 | int place = -1; |
||
| 245 | for (int i=0; i<sz; i++) |
||
| 246 | if (data[i] == value) { |
||
| 247 | place = i; |
||
| 248 | // copy the rest of the components down one in ID |
||
| 249 | for (int j=i; j<sz-1; j++) |
||
| 250 | data[j] = data[j+1]; |
||
| 251 | sz--; |
||
| 252 | } |
||
| 253 | return place; |
||
| 254 | } |
||
| 255 | |||
| 256 | |||
| 257 | int & |
||
| 258 | ID::operator[](int x) |
||
| 259 | { |
||
| 260 | #ifdef _G3DEBUG |
||
| 261 | // check if it is inside range [0,sz-1] |
||
| 262 | if (x < 0) { |
||
| 1276 | fmk | 263 | opserr << "ID::[] - location " << x << " < 0\n"; |
| 2 | fmk | 264 | return ID_NOT_VALID_ENTRY; |
| 265 | } |
||
| 266 | #endif |
||
| 267 | |||
| 268 | // see if quick return |
||
| 269 | if (x < sz) |
||
| 270 | return data[x]; |
||
| 1271 | fmk | 271 | |
| 2 | fmk | 272 | /* |
| 273 | * otherwise we have to enlarge the order of the ID |
||
| 274 | */ |
||
| 275 | |||
| 276 | // see if we can just enlarge the array |
||
| 277 | // without having to go get more space |
||
| 278 | |||
| 279 | if (x < arraySize) { |
||
| 280 | for (int i=sz; i<x; i++) |
||
| 281 | data[i] = 0; |
||
| 282 | sz = x+1; |
||
| 283 | return data[x]; |
||
| 284 | } |
||
| 285 | |||
| 286 | // otherwise we go get more space |
||
| 287 | if (x >= arraySize) { |
||
| 288 | int newArraySize = arraySize * 2; |
||
| 289 | if (newArraySize < x) |
||
| 290 | newArraySize = x; |
||
| 1745 | fmk | 291 | // int *newData = (int *)malloc(newArraySize*sizeof(int)); |
| 292 | int *newData = new int[newArraySize]; |
||
| 2 | fmk | 293 | if (newData != 0) { |
| 294 | // copy the old |
||
| 295 | for (int i=0; i<sz; i++) |
||
| 296 | newData[i] = data[i]; |
||
| 297 | // zero the new |
||
| 298 | for (int j=sz; j<arraySize; j++) |
||
| 299 | newData[j] = 0; |
||
| 300 | |||
| 301 | sz = x+1; |
||
| 302 | // release the memory held by the old |
||
| 1745 | fmk | 303 | // free((void *)data); |
| 2152 | fmk | 304 | if (fromFree == 0) |
| 305 | delete [] data; |
||
| 2 | fmk | 306 | data = newData; |
| 307 | arraySize = newArraySize; |
||
| 308 | |||
| 309 | return newData[x]; |
||
| 310 | } |
||
| 311 | else { |
||
| 312 | // we could not allocate more mem .. leave the current size |
||
| 1271 | fmk | 313 | opserr << "ID::[]): ran out of memory with arraySize " << arraySize << endln; |
| 2 | fmk | 314 | return ID_NOT_VALID_ENTRY; |
| 315 | } |
||
| 316 | } |
||
| 317 | |||
| 318 | // we should never get here, but some compilers need this line |
||
| 319 | return ID_NOT_VALID_ENTRY; |
||
| 320 | } |
||
| 321 | |||
| 322 | |||
| 2175 | fmk | 323 | int |
| 324 | ID::resize(int newSize){ |
||
| 2 | fmk | 325 | |
| 2175 | fmk | 326 | // first check that newSize is valid |
| 327 | if (newSize <= 0) { |
||
| 328 | opserr << "ID::resize() - size specified " << newSize << " <= 0\n"; |
||
| 329 | return -1; |
||
| 330 | } |
||
| 331 | |||
| 332 | |||
| 333 | if (sz > newSize) { |
||
| 334 | |||
| 335 | // is size smaller than current, simply reset sz |
||
| 336 | sz = newSize; |
||
| 337 | |||
| 338 | } else if (newSize < arraySize) { |
||
| 339 | |||
| 340 | // see if we can just enlarge the array |
||
| 341 | // without having to go get more space |
||
| 342 | |||
| 343 | for (int i=sz; i<newSize; i++) |
||
| 344 | data[i] = 0; |
||
| 345 | sz = newSize; |
||
| 346 | |||
| 347 | } else if (newSize > arraySize) { |
||
| 348 | |||
| 349 | // otherwise we go get more space |
||
| 350 | |||
| 351 | int *newData = new int[newSize]; |
||
| 352 | if (newData != 0) { |
||
| 353 | // copy the old |
||
| 354 | for (int i=0; i<sz; i++) |
||
| 355 | newData[i] = data[i]; |
||
| 356 | // zero the new |
||
| 357 | for (int j=sz; j<newSize; j++) |
||
| 358 | newData[j] = 0; |
||
| 359 | |||
| 360 | sz = newSize; |
||
| 361 | // release the memory held by the old |
||
| 362 | // free((void *)data); |
||
| 363 | delete [] data; |
||
| 364 | data = newData; |
||
| 365 | arraySize = newSize; |
||
| 366 | |||
| 367 | } else { |
||
| 368 | opserr << "ID::resize() - out of memory creating ID of size " << newSize << "\n"; |
||
| 369 | return -1; |
||
| 370 | } |
||
| 371 | } |
||
| 372 | |||
| 373 | return 0; |
||
| 374 | } |
||
| 375 | |||
| 376 | |||
| 377 | |||
| 2 | fmk | 378 | // ID &operator=(const ID &V): |
| 379 | // the assignment operator, This is assigned to be a copy of V. if sizes |
||
| 380 | // are not compatable this.data [] is deleted. The data pointers will not |
||
| 381 | // point to the same area in mem after the assignment. |
||
| 382 | // |
||
| 383 | |||
| 384 | ID & |
||
| 385 | ID::operator=(const ID &V) |
||
| 386 | { |
||
| 387 | // first check we are not trying v = v |
||
| 388 | if (this != &V) { |
||
| 389 | |||
| 390 | // check size compatability, if different delete |
||
| 391 | // old and make room for new. |
||
| 392 | if (sz != V.sz) { |
||
| 393 | if (arraySize < V.sz) { |
||
| 394 | arraySize = V.sz; |
||
| 395 | if (data != 0) |
||
| 1745 | fmk | 396 | //free((void *)data); |
| 397 | delete [] data; |
||
| 398 | // data = (int *)malloc(arraySize*sizeof(int)); |
||
| 399 | data = new int[arraySize]; |
||
| 2 | fmk | 400 | // check we got the memory requested |
| 401 | if (data == 0) { |
||
| 1271 | fmk | 402 | opserr << "WARNING ID::=(ID) - ran out of memory "; |
| 403 | opserr << "for new array of size" << arraySize << endln; |
||
| 2 | fmk | 404 | sz = 0; |
| 405 | arraySize = 0; |
||
| 406 | } |
||
| 407 | } |
||
| 968 | fmk | 408 | sz = V.sz; |
| 2 | fmk | 409 | } |
| 410 | |||
| 411 | // copy the data |
||
| 412 | for (int i=0; i<sz; i++) |
||
| 413 | data[i] = V(i); |
||
| 414 | } |
||
| 415 | |||
| 416 | return *this; |
||
| 417 | } |
||
| 418 | |||
| 419 | |||
| 420 | |||
| 421 | |||
| 422 | |||
| 1271 | fmk | 423 | // friend OPS_Stream &operator<<(OPS_Stream &s, const ID &V) |
| 424 | // A function is defined to allow user to print the IDs using OPS_Streams. |
||
| 2 | fmk | 425 | |
| 1271 | fmk | 426 | OPS_Stream &operator<<(OPS_Stream &s, const ID &V) |
| 2 | fmk | 427 | { |
| 428 | for (int i=0; i<V.Size(); i++) |
||
| 429 | { |
||
| 430 | s << V(i) << " "; |
||
| 431 | } |
||
| 1271 | fmk | 432 | return s << endln; |
| 2 | fmk | 433 | } |
| 434 | |||
| 435 | // friend istream &operator>>(istream &s, ID &V) |
||
| 436 | // A function is defined to allow user to input the data into a ID which has already |
||
| 437 | // been constructed with data, i.e. ID(int) or ID(const ID &) constructors. |
||
| 438 | |||
| 1271 | fmk | 439 | /* |
| 2 | fmk | 440 | istream &operator>>(istream &s, ID &V) |
| 441 | { |
||
| 442 | for (int i=0; i<V.Size(); i++) |
||
| 443 | s >> V(i); |
||
| 444 | |||
| 445 | return s; |
||
| 446 | } |
||
| 1271 | fmk | 447 | */ |
| 2 | fmk | 448 | |
| 449 | |||
| 450 | |||
| 2152 | fmk | 451 | int |
| 452 | ID::insert(int x) |
||
| 453 | { |
||
| 454 | int middle = 0; |
||
| 455 | int left = 0; |
||
| 456 | int right = sz-1; |
||
| 457 | if (sz != 0) { |
||
| 458 | while (left <= right) { |
||
| 459 | middle = (left + right)/2; |
||
| 460 | double dataMiddle = data[middle]; |
||
| 461 | if (x == dataMiddle) |
||
| 2160 | fmk | 462 | return 1; // already there |
| 2152 | fmk | 463 | else if (x > dataMiddle) |
| 464 | left = middle + 1; |
||
| 465 | else |
||
| 466 | right = middle-1; |
||
| 467 | } |
||
| 468 | } |
||
| 2 | fmk | 469 | |
| 2152 | fmk | 470 | // we need to enlarge the array .. see if we can do it |
| 471 | // without having to go get more space |
||
| 472 | |||
| 473 | middle = left; |
||
| 2418 | fmk | 474 | |
| 2160 | fmk | 475 | /* |
| 476 | for (int i=middle; i<sz; i++) |
||
| 2418 | fmk | 477 | (*this)[i+1] = (*this)[i]; |
| 2160 | fmk | 478 | (*this)[i]=middle; |
| 479 | return middle; |
||
| 2418 | fmk | 480 | */ |
| 2160 | fmk | 481 | |
| 2152 | fmk | 482 | if (sz < arraySize) { |
| 483 | |||
| 484 | int i = sz; |
||
| 485 | while (i > middle) { |
||
| 486 | data[i] = data[i-1]; |
||
| 487 | i--; |
||
| 488 | } |
||
| 2418 | fmk | 489 | sz++; |
| 2152 | fmk | 490 | data[i] = x; |
| 2160 | fmk | 491 | return 0; |
| 2152 | fmk | 492 | } else { |
| 2418 | fmk | 493 | int newArraySize = (sz+1) * 2; |
| 494 | int *newData = new int[newArraySize]; |
||
| 495 | if (newData != 0) { |
||
| 496 | |||
| 2152 | fmk | 497 | // copy the old |
| 2160 | fmk | 498 | for (int ii=0; ii<middle; ii++) |
| 2418 | fmk | 499 | newData[ii] = data[ii]; |
| 500 | newData[middle] = x; |
||
| 501 | |||
| 502 | for (int jj=middle; jj<sz; jj++) |
||
| 503 | newData[jj+1] = data[jj]; |
||
| 504 | |||
| 2152 | fmk | 505 | sz++; |
| 2418 | fmk | 506 | |
| 507 | if (data != 0 && fromFree == 0) |
||
| 508 | delete [] data; |
||
| 2152 | fmk | 509 | data = newData; |
| 510 | arraySize = newArraySize; |
||
| 511 | |||
| 2160 | fmk | 512 | return 0; |
| 2418 | fmk | 513 | |
| 514 | } else |
||
| 515 | return -1; |
||
| 2152 | fmk | 516 | } |
| 2418 | fmk | 517 | return -1; // should never get here |
| 2152 | fmk | 518 | } |
| 519 |