ID.cpp

Go to the documentation of this file.
00001 /* ****************************************************************** **
00002 **    OpenSees - Open System for Earthquake Engineering Simulation    **
00003 **          Pacific Earthquake Engineering Research Center            **
00004 **                                                                    **
00005 **                                                                    **
00006 ** (C) Copyright 1999, The Regents of the University of California    **
00007 ** All Rights Reserved.                                               **
00008 **                                                                    **
00009 ** Commercial use of this program without express permission of the   **
00010 ** University of California, Berkeley, is strictly prohibited.  See   **
00011 ** file 'COPYRIGHT'  in main directory for information on usage and   **
00012 ** redistribution,  and for a DISCLAIMER OF ALL WARRANTIES.           **
00013 **                                                                    **
00014 ** Developed by:                                                      **
00015 **   Frank McKenna (fmckenna@ce.berkeley.edu)                         **
00016 **   Gregory L. Fenves (fenves@ce.berkeley.edu)                       **
00017 **   Filip C. Filippou (filippou@ce.berkeley.edu)                     **
00018 **                                                                    **
00019 ** ****************************************************************** */
00020                                                                         
00021 // $Revision: 1.11 $
00022 // $Date: 2006/05/26 18:19:16 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/matrix/ID.cpp,v $
00024                                                                         
00025                                                                         
00026 // Written: fmk 
00027 // Revision: A
00028 //
00029 // Description: This file contains the class implementation for ID.
00030 //
00031 // What: "@(#) ID.C, revA"
00032 
00033 #include "ID.h"
00034 #include <stdlib.h>
00035 
00036 
00037 int ID::ID_NOT_VALID_ENTRY = 0;
00038 
00039 // ID():
00040 //      Standard constructor, sets size = 0;
00041 
00042 ID::ID()
00043   :sz(0), data(0), arraySize(0), fromFree(0)
00044 {
00045 
00046 }
00047 
00048 
00049 // ID(int size):
00050 //      Constructor used to allocate a ID of size size.
00051 
00052 ID::ID(int size)
00053   :sz(size), data(0), arraySize(size), fromFree(0)
00054 {
00055 
00056 #ifdef _G3DEBUG
00057   if (sz <= 0) {
00058     opserr << "ID::ID(int) - size " << size << " specified <= 0\n";
00059     sz = 1;
00060     arraySize = 1;
00061   }
00062 #endif    
00063 
00064   // create the space for the data & check space was available
00065   //  data = (int *)malloc(size*sizeof(int));
00066   data = new int[size]; 
00067   if (data == 0) {
00068     opserr << "ID::ID(int): ran out of memory with size " << size << endln;
00069     exit(-1);
00070   }
00071 
00072   // zero the data
00073   for (int i=0; i<size; i++)
00074     data[i] = 0;
00075 }
00076 
00077 
00078 // ID(int size):
00079 //      Constructor used to allocate a ID of size size.
00080 
00081 ID::ID(int size, int arraySz)
00082   :sz(size), data(0), arraySize(arraySz), fromFree(0)
00083 {
00084 #ifdef _G3DEBUG
00085   if (sz < 0) {
00086     opserr << "ID::ID(size, arraySize) - size " << size << " specified < 0\n";
00087     sz = 0;
00088   }
00089   if (arraySz <= 0) {
00090     opserr << "ID::ID(size, arraySize) - arraySize " << arraySz << " specified < 0\n";
00091     if (sz != 0) 
00092       arraySz = sz;
00093     else
00094       arraySz = 1;
00095   }
00096   if (arraySz < sz) {
00097     opserr << "ID::ID(size, arraySize) - arraySize " << arraySz  << " specified < " << size << endln;
00098     arraySz = sz;
00099   }
00100 #endif    
00101 
00102   // create the space
00103   //  data = (int *)malloc(arraySize*sizeof(int));
00104   data = new int[arraySize];
00105   if (data == 0) {
00106     opserr << "ID::ID(int, int): ran out of memory with arraySize: " << arraySize << endln;
00107     exit(-1);
00108   }
00109 
00110   // zero the data
00111   for (int i=0; i<arraySize; i++)
00112     data[i] = 0;
00113 }
00114 
00115 ID::ID(int *d, int size, bool cleanIt)
00116   :sz(size), data(d), arraySize(size), fromFree(1)
00117 {
00118   if (d == 0) { // OOPS must have been other constructor we wanted
00119     sz = 0;
00120     data = 0;
00121     arraySize = size;
00122     fromFree = 0;
00123 
00124     // create the space
00125     if (arraySize != 0) {
00126       data = (int *)malloc(arraySize*sizeof(int));
00127       if (data == 0) {
00128         opserr << "ID::ID(int, int): ran out of memory with arraySize " << arraySize << endln;
00129         exit(-1);
00130       }
00131     }
00132 
00133     // zero the data
00134     for (int i=0; i<arraySize; i++)
00135       data[i] = 0;
00136   }
00137   
00138   if (cleanIt == true)
00139     fromFree = 0;
00140 }
00141 
00142 // ID(const ID&):
00143 //      Constructor to init a ID from another.
00144 
00145 ID::ID(const ID &other)
00146   :sz(other.sz), data(0), arraySize(other.arraySize), fromFree(0)
00147 {
00148   // create the space
00149   //  data = (int *)malloc(arraySize*sizeof(int));
00150   data = new int[arraySize]; 
00151   if (data == 0) {
00152     opserr << "ID::ID(ID): ran out of memory with arraySize " << arraySize << endln,
00153     exit(-1);
00154   }
00155   
00156   // copy the data 
00157   for (int i=0; i<sz; i++)
00158     data[i] = other.data[i];
00159 }       
00160 
00161 
00162 
00163 // ~ID():
00164 //      destructor, deletes the [] data
00165 
00166 ID::~ID()
00167 {
00168   if (data != 0 && fromFree == 0) 
00169     //    free((void *)data);
00170     delete [] data;
00171 }
00172 
00173 int 
00174 ID::setData(int *newData, int size, bool cleanIt){
00175         
00176   if (data != 0 && fromFree == 0) 
00177     //    free((void *)data);
00178     delete [] data;
00179 
00180   sz = size;
00181   data = newData;
00182   
00183   if (cleanIt == false)
00184     fromFree = 1;
00185   else
00186     fromFree = 0;
00187 
00188   if (sz <= 0) {
00189     opserr << "ID::ID(int *, size) - size " << size << " specified <= 0\n";
00190     sz = 0;
00191   }
00192 
00193   return 0;
00194 }
00195 
00196 
00197 void
00198 ID::Zero(void)
00199 {
00200   for (int i=0; i<sz; i++)
00201     data[i] =0;
00202 }
00203 
00204 int
00205 ID::getLocation(int value) const
00206 {
00207   // search through ID for the value
00208   for (int i=0; i<sz; i++)
00209     if (data[i] == value)
00210       return i;
00211 
00212   // if we get here the value is not in the array
00213   return -1;
00214 }
00215 
00216 
00217 int
00218 ID::getLocationOrdered(int value) const
00219 {
00220   int middle = 0;
00221   int left = 0;
00222   int right = sz-1;
00223   if (sz != 0) {
00224     while (left <= right) {
00225       middle = (left + right)/2;
00226       double dataMiddle = data[middle];
00227       if (value == dataMiddle)
00228         return middle;   // already there
00229       else if (value > dataMiddle)
00230         left = middle + 1;
00231       else 
00232         right = middle-1;
00233     }
00234   }
00235 
00236   // if we get here the value is not in the array
00237   return -1;
00238 }
00239 
00240 
00241 int
00242 ID::removeValue(int value)
00243 {
00244   int place = -1;
00245   for (int i=0; i<sz; i++)
00246     if (data[i] == value) {
00247       place = i;
00248       // copy the rest of the components down one in ID
00249       for (int j=i; j<sz-1; j++)
00250         data[j] = data[j+1];            
00251       sz--;
00252     }
00253   return place;
00254 }    
00255 
00256 
00257 int &
00258 ID::operator[](int x) 
00259 {
00260 #ifdef _G3DEBUG
00261   // check if it is inside range [0,sz-1]
00262   if (x < 0) {
00263     opserr << "ID::[] - location " << x << " < 0\n";
00264     return ID_NOT_VALID_ENTRY;
00265   }
00266 #endif
00267 
00268   // see if quick return
00269   if (x < sz)
00270     return data[x];
00271 
00272   /*
00273    * otherwise we have to enlarge the order of the ID
00274    */
00275     
00276   // see if we can just enlarge the array
00277   // without having to go get more space
00278 
00279   if (x < arraySize) {
00280     for (int i=sz; i<x; i++)
00281       data[i] = 0;
00282     sz = x+1;
00283     return data[x];
00284   }
00285 
00286   // otherwise we go get more space
00287   if (x >= arraySize) {
00288     int newArraySize = arraySize * 2;
00289     if (newArraySize < x) 
00290       newArraySize = x;
00291     //    int *newData = (int *)malloc(newArraySize*sizeof(int));    
00292     int *newData = new int[newArraySize];
00293     if (newData != 0) {
00294       // copy the old
00295       for (int i=0; i<sz; i++)
00296         newData[i] = data[i];
00297       // zero the new
00298       for (int j=sz; j<arraySize; j++)
00299         newData[j] = 0;
00300       
00301       sz = x+1;
00302       // release the memory held by the old
00303       //      free((void *)data);           
00304       if (fromFree == 0)
00305         delete [] data;
00306       data = newData;
00307       arraySize = newArraySize;
00308       
00309       return newData[x];
00310     }
00311     else {
00312       // we could not allocate more mem .. leave the current size
00313       opserr << "ID::[]): ran out of memory with arraySize " << arraySize << endln;
00314       return ID_NOT_VALID_ENTRY;
00315     }
00316   }
00317   
00318   // we should never get here, but some compilers need this line
00319   return ID_NOT_VALID_ENTRY;    
00320 }
00321     
00322 
00323 int 
00324 ID::resize(int newSize){
00325 
00326   // first check that newSize is valid
00327   if (newSize <= 0) {
00328     opserr << "ID::resize() - size specified " << newSize << " <= 0\n";
00329     return -1;
00330   } 
00331   
00332 
00333   if (sz > newSize) {
00334 
00335     // is size smaller than current, simply reset sz
00336     sz = newSize;
00337 
00338   } else if (newSize < arraySize) {
00339 
00340     // see if we can just enlarge the array
00341     // without having to go get more space
00342     
00343     for (int i=sz; i<newSize; i++)
00344       data[i] = 0;
00345     sz = newSize;
00346 
00347   } else if (newSize > arraySize) {
00348 
00349     // otherwise we go get more space
00350     
00351     int *newData = new int[newSize];
00352     if (newData != 0) {
00353       // copy the old
00354       for (int i=0; i<sz; i++)
00355         newData[i] = data[i];
00356       // zero the new
00357       for (int j=sz; j<newSize; j++)
00358         newData[j] = 0;
00359       
00360       sz = newSize;
00361       // release the memory held by the old
00362       //      free((void *)data);           
00363       delete [] data;
00364       data = newData;
00365       arraySize = newSize;
00366 
00367     } else {
00368       opserr << "ID::resize() - out of memory creating ID of size " << newSize << "\n";
00369       return -1;      
00370     }
00371   }
00372 
00373   return 0;
00374 }
00375 
00376 
00377 
00378 // ID &operator=(const ID  &V):
00379 //      the assignment operator, This is assigned to be a copy of V. if sizes
00380 //      are not compatable this.data [] is deleted. The data pointers will not
00381 //      point to the same area in mem after the assignment.
00382 //
00383 
00384 ID &
00385 ID::operator=(const ID &V) 
00386 {
00387     // first check we are not trying v = v
00388     if (this != &V) {
00389         
00390         // check size compatability, if different delete
00391         // old and make room for new.
00392         if (sz != V.sz) {
00393             if (arraySize < V.sz) {
00394                 arraySize = V.sz;
00395                 if (data != 0)
00396                   //free((void *)data);
00397                   delete [] data;
00398                 //              data = (int *)malloc(arraySize*sizeof(int));            
00399                 data = new int[arraySize];
00400                 // check we got the memory requested
00401                 if (data == 0) {
00402                     opserr << "WARNING ID::=(ID) - ran out of memory ";
00403                     opserr << "for new array of size" << arraySize << endln;
00404                     sz = 0;
00405                     arraySize = 0;
00406                 }
00407             }
00408             sz = V.sz;
00409         }
00410         
00411         // copy the data
00412         for (int i=0; i<sz; i++)
00413             data[i] = V(i);
00414     }
00415 
00416     return *this;
00417 }
00418 
00419 
00420 
00421 
00422 
00423 // friend OPS_Stream &operator<<(OPS_Stream &s, const ID &V)
00424 //      A function is defined to allow user to print the IDs using OPS_Streams.
00425 
00426 OPS_Stream &operator<<(OPS_Stream &s, const ID &V)
00427 {
00428     for (int i=0; i<V.Size(); i++) 
00429     {
00430         s << V(i) << " ";
00431     }
00432     return s << endln;
00433 }
00434 
00435 // friend istream &operator>>(istream &s, ID &V)
00436 //      A function is defined to allow user to input the data into a ID which has already
00437 //      been constructed with data, i.e. ID(int) or ID(const ID &) constructors.
00438 
00439 /*
00440 istream &operator>>(istream &s, ID &V)
00441 {
00442     for (int i=0; i<V.Size(); i++) 
00443         s >> V(i);
00444 
00445     return s;
00446 }
00447 */
00448 
00449 
00450 
00451 int 
00452 ID::insert(int x) 
00453 {
00454   int middle = 0;
00455   int left = 0;
00456   int right = sz-1;
00457   if (sz != 0) {
00458     while (left <= right) {
00459       middle = (left + right)/2;
00460       double dataMiddle = data[middle];
00461       if (x == dataMiddle)
00462         return 1;   // already there
00463       else if (x > dataMiddle)
00464         left = middle + 1;
00465       else 
00466         right = middle-1;
00467     }
00468   }
00469 
00470   // we need to enlarge the array .. see if we can do it
00471   // without having to go get more space
00472 
00473   middle = left;
00474 
00475   /*
00476   for (int i=middle; i<sz; i++)
00477   (*this)[i+1] = (*this)[i];
00478   (*this)[i]=middle;
00479   return middle;
00480   */
00481   
00482   if (sz < arraySize) {
00483 
00484     int i = sz;
00485     while (i > middle) {
00486       data[i] = data[i-1];
00487       i--;
00488     }
00489     sz++;
00490     data[i] = x;
00491     return 0;
00492   } else {
00493     int newArraySize = (sz+1) * 2;
00494     int *newData = new int[newArraySize];
00495     if (newData != 0) {
00496       
00497       // copy the old
00498       for (int ii=0; ii<middle; ii++)
00499         newData[ii] = data[ii];
00500       newData[middle] = x;
00501       
00502       for (int jj=middle; jj<sz; jj++)
00503         newData[jj+1] = data[jj];
00504       
00505       sz++;
00506       
00507       if (data != 0 && fromFree == 0)
00508         delete [] data;
00509       data = newData;
00510       arraySize = newArraySize;
00511       
00512       return 0;
00513       
00514     } else
00515       return -1;
00516   }
00517   return -1; // should never get here
00518 }
00519 

Generated on Mon Oct 23 15:05:23 2006 for OpenSees by doxygen 1.5.0