Vector.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.12 $
00022 // $Date: 2006/10/02 20:16:35 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/matrix/Vector.cpp,v $
00024                                                                         
00025                                                                         
00026 // Written: fmk 
00027 // Created: 11/96
00028 // Revision: A
00029 //
00030 // Description: This file contains the class implementation for Vector.
00031 //
00032 // What: "@(#) Vector.C, revA"
00033 
00034 #include "Vector.h"
00035 #include "Matrix.h"
00036 #include "ID.h"
00037 #include <Tensor.h>
00038 
00039 #include <stdlib.h>
00040 #include <math.h>
00041 
00042 double Vector::VECTOR_NOT_VALID_ENTRY =0.0;
00043 
00044 // Vector():
00045 //      Standard constructor, sets size = 0;
00046 
00047 Vector::Vector()
00048 : sz(0), theData(0), fromFree(0)
00049 {
00050 
00051 }
00052 
00053 // Vector(int size):
00054 //      Constructor used to allocate a vector of size size.
00055 
00056 Vector::Vector(int size)
00057 : sz(size), theData(0), fromFree(0)
00058 {
00059 #ifdef _G3DEBUG
00060   if (sz <= 0) {
00061     opserr << "Vector::Vector(int) - size " << size << " specified <= 0\n";
00062     sz = 1;
00063   }
00064 #endif
00065 
00066   // get some space for the vector
00067   //  theData = (double *)malloc(size*sizeof(double));
00068   theData = new double [size];
00069 
00070   if (theData == 0) {
00071     opserr << "Vector::Vector(int) - out of memory creating vector of size " << size << endln;
00072     sz = 0; // set this should fatal error handler not kill process!!
00073   }
00074     
00075   // zero the components
00076   for (int i=0; i<sz; i++)
00077     theData[i] = 0.0;
00078 }
00079 
00080 
00081 // Vector::Vector(double *data, int size)
00082 
00083 Vector::Vector(double *data, int size)
00084 : sz(size),theData(data),fromFree(1)
00085 {
00086 #ifdef _G3DEBUG
00087   if (sz <= 0) {
00088     opserr << "Vector::Vector(double *, size) - size " << size << " specified <= 0\n";
00089     sz = 0;
00090   }
00091 #endif
00092 }
00093  
00094 
00095 
00096 // Vector(const Vector&):
00097 //      Constructor to init a vector from another.
00098 
00099 Vector::Vector(const Vector &other)
00100 : sz(other.sz),theData(0),fromFree(0)
00101 {
00102 #ifdef _G3DEBUG
00103   if (sz < 0) {
00104     opserr << "Vector::Vector(int) - size " << sz << " specified <= 0\n";
00105     sz = 1;
00106   }
00107 #endif
00108 
00109   //  theData = (double *)malloc(other.sz*sizeof(double));    
00110   theData = new double [other.sz];    
00111   
00112   if (theData == 0) {
00113     opserr << "Vector::Vector(int) - out of memory creating vector of size " << sz << endln;
00114     exit(-1);
00115   }
00116 
00117   // copy the component data
00118   for (int i=0; i<sz; i++)
00119     theData[i] = other.theData[i];
00120 }       
00121 
00122 
00123 
00124 
00125 
00126 
00127 // ~Vector():
00128 //      destructor, deletes the [] data
00129 
00130 Vector::~Vector()
00131 {
00132   if (sz != 0 && fromFree == 0) 
00133     delete [] theData;
00134   //  free((void *)theData);
00135 }
00136 
00137 
00138 int 
00139 Vector::setData(double *newData, int size){
00140   if (sz != 0 && fromFree == 0) 
00141     delete [] theData;      
00142   sz = size;
00143   theData = newData;
00144   fromFree = 1;
00145 
00146   if (sz <= 0) {
00147     opserr << " Vector::Vector(double *, size) - size specified: " << size << " <= 0\n";
00148     sz = 0;
00149   }
00150 
00151   return 0;
00152 }
00153 
00154 
00155 
00156 int 
00157 Vector::resize(int newSize){
00158 
00159   // first check that newSize is valid
00160   if (newSize <= 0) {
00161     opserr << "Vector::resize) - size specified " << newSize << " <= 0\n";
00162     return -1;
00163   } 
00164   
00165   // otherwise if newSize is gretaer than oldSize free old space and get new space
00166   else if (newSize > sz) {
00167 
00168     // delete the old array
00169     if (sz != 0 && fromFree == 0) 
00170         delete [] theData;
00171     sz = 0;
00172     fromFree = 0;
00173     
00174     // create new memory
00175     // theData = (double *)malloc(newSize*sizeof(double));    
00176     theData = new double[newSize];
00177     if (theData == 0) {
00178       opserr << "Vector::resize() - out of memory for size " << newSize << endln;
00179       sz = 0;
00180       return -2;
00181     }
00182     sz = newSize;
00183   }  
00184 
00185   // just set the size to be newSize .. penalty of holding onto additional
00186   // memory .. but then save the free() and malloc() calls
00187   else 
00188     sz = newSize;    
00189 
00190   return 0;
00191 }
00192 
00193 
00194 // Assemble(Vector &x, ID &y, double fact ):
00195 //      Method to assemble into object the Vector V using the ID l.
00196 //      If ID(x) does not exist program writes error message if
00197 //      VECTOR_CHECK defined, otherwise ignores it and goes on.
00198 
00199 int 
00200 Vector::Assemble(const Vector &V, const ID &l, double fact )
00201 {
00202   int result = 0;
00203   int pos;
00204   for (int i=0; i<l.Size(); i++) {
00205     pos = l(i);
00206     
00207     if (pos < 0)
00208       ;
00209     else if ((pos < sz) && (i < V.Size()))
00210       // assemble into vector
00211       theData[pos] += V.theData[i] *fact;
00212     else {
00213       result = -1;
00214       if (pos < sz)
00215         opserr << "Vector::Assemble() " << pos << " out of range [1, " << sz-1 << "]\n";
00216       else
00217         opserr << "Vector::Assemble() " << pos << " out of range [1, "<< V.Size()-1 << "]\n";
00218     }
00219   }
00220   return result;
00221 }
00222     
00223 
00224 int
00225 Vector::Normalize(void) 
00226 {
00227   double length = 0.0;
00228   for (int i=0; i<sz; i++)
00229     length += theData[i] * theData[i];
00230   length = sqrt(length);
00231   
00232   if (length == 0.0) 
00233     return -1;
00234 
00235   length = 1.0/length;
00236   for (int j=0; j<sz; j++)
00237     theData[j] *= length;
00238 
00239   return 0;
00240 }
00241 
00242 int
00243 Vector::addVector(double thisFact, const Vector &other, double otherFact )
00244 {
00245   // check if quick return
00246   if (otherFact == 0.0 && thisFact == 1.0)
00247     return 0; 
00248 
00249   // if sizes are compatable add
00250 #ifdef _G3DEBUG
00251   if (sz != other.sz) {
00252     // else sizes are incompatable, do nothing but warning
00253     opserr <<  "WARNING Vector::addVector() - incompatable Vector sizes\n";
00254     return -1;
00255   }
00256 #endif
00257 
00258 
00259   if (thisFact == 1.0) {
00260 
00261     // want: this += other * otherFact
00262     double *dataPtr = theData;
00263     double *otherDataPtr = other.theData;
00264     if (otherFact == 1.0) { // no point doing a multiplication if otherFact == 1.0
00265       for (int i=0; i<sz; i++) 
00266         *dataPtr++ += *otherDataPtr++;
00267     } else if (otherFact == -1.0) { // no point doing a multiplication if otherFact == 1.0
00268       for (int i=0; i<sz; i++) 
00269         *dataPtr++ -= *otherDataPtr++;
00270     } else 
00271       for (int i=0; i<sz; i++) 
00272         *dataPtr++ += *otherDataPtr++ * otherFact;
00273   } 
00274 
00275   else if (thisFact == 0.0) {
00276 
00277     // want: this = other * otherFact
00278     double *dataPtr = theData;
00279     double *otherDataPtr = other.theData;
00280     if (otherFact == 1.0) { // no point doing a multiplication if otherFact == 1.0
00281       for (int i=0; i<sz; i++) 
00282         *dataPtr++ = *otherDataPtr++;
00283     } else if (otherFact == -1.0) { // no point doing a multiplication if otherFact == 1.0
00284       for (int i=0; i<sz; i++) 
00285         *dataPtr++ = *otherDataPtr++;
00286     } else 
00287       for (int i=0; i<sz; i++) 
00288         *dataPtr++ = *otherDataPtr++ * otherFact;
00289   }
00290 
00291   else {
00292 
00293     // want: this = this * thisFact + other * otherFact
00294     double *dataPtr = theData;
00295     double *otherDataPtr = other.theData;
00296     if (otherFact == 1.0) { // no point doing a multiplication if otherFact == 1.0
00297       for (int i=0; i<sz; i++) {
00298         double value = *dataPtr * thisFact + *otherDataPtr++;
00299         *dataPtr++ = value;
00300       }
00301     } else if (otherFact == -1.0) { // no point doing a multiplication if otherFact == 1.0
00302       for (int i=0; i<sz; i++) {
00303         double value = *dataPtr * thisFact - *otherDataPtr++;
00304         *dataPtr++ = value;
00305       }
00306     } else 
00307       for (int i=0; i<sz; i++) {
00308         double value = *dataPtr * thisFact + *otherDataPtr++ * otherFact;
00309         *dataPtr++ = value;
00310       }
00311   } 
00312 
00313   // successfull
00314   return 0;
00315 }
00316             
00317         
00318 int
00319 Vector::addMatrixVector(double thisFact, const Matrix &m, const Vector &v, double otherFact )
00320 {
00321   // see if quick return
00322   if (thisFact == 1.0 && otherFact == 0.0)
00323     return 0;
00324 
00325   // check the sizes are compatable
00326 #ifdef _G3DEBUG
00327   // check the sizes are compatable
00328   if ((sz != m.noRows()) && (m.noCols() != v.sz)) {
00329     // otherwise incompatable sizes
00330     opserr << "Vector::addMatrixVector() - incompatable sizes\n";
00331     return -1;    
00332   }
00333 #endif
00334 
00335   if (thisFact == 1.0) {
00336 
00337     // want: this += m * v * otherFact
00338     if (otherFact == 1.0) { // no point doing multiplication if otherFact = 1.0
00339       int otherSize = v.sz;
00340       double *matrixDataPtr = m.data;
00341       double *otherDataPtr = v.theData;
00342       for (int i=0; i<otherSize; i++) {
00343         double otherData = *otherDataPtr++;
00344         for (int j=0; j<sz; j++)
00345           theData[j] += *matrixDataPtr++ * otherData;
00346       }
00347     } 
00348     else if (otherFact == -1.0) { // no point doing multiplication if otherFact = -1.0
00349       int otherSize = v.sz;
00350       double *matrixDataPtr = m.data;
00351       double *otherDataPtr = v.theData;
00352       for (int i=0; i<otherSize; i++) {
00353         double otherData = *otherDataPtr++;
00354         for (int j=0; j<sz; j++)
00355           theData[j] -= *matrixDataPtr++ * otherData;
00356       }
00357     } 
00358     else { // have to do the multiplication
00359       int otherSize = v.sz;
00360       double *matrixDataPtr = m.data;
00361       double *otherDataPtr = v.theData;
00362       for (int i=0; i<otherSize; i++) {
00363         double otherData = *otherDataPtr++ * otherFact;
00364         for (int j=0; j<sz; j++)
00365           theData[j] += *matrixDataPtr++ * otherData;
00366       }
00367     }
00368   }
00369 
00370   else if (thisFact == 0.0) {
00371     
00372     // want: this = m * v * otherFact
00373     for (int i=0; i<sz; i++)
00374       theData[i] = 0.0;
00375 
00376     if (otherFact == 1.0) { // no point doing multiplication if otherFact = 1.0
00377       int otherSize = v.sz;
00378       double *matrixDataPtr = m.data;
00379       double *otherDataPtr = v.theData;
00380       for (int i=0; i<otherSize; i++) {
00381         double otherData = *otherDataPtr++;
00382         for (int j=0; j<sz; j++)
00383           theData[j] += *matrixDataPtr++ * otherData;
00384       }
00385     } 
00386     else if (otherFact == -1.0) { // no point doing multiplication if otherFact = -1.0
00387       int otherSize = v.sz;
00388       double *matrixDataPtr = m.data;
00389       double *otherDataPtr = v.theData;
00390       for (int i=0; i<otherSize; i++) {
00391         double otherData = *otherDataPtr++;
00392         for (int j=0; j<sz; j++)
00393           theData[j] -= *matrixDataPtr++ * otherData;
00394       }
00395     } else {
00396       int otherSize = v.sz;
00397       double *matrixDataPtr = m.data;
00398       double *otherDataPtr = v.theData;
00399       for (int i=0; i<otherSize; i++) {
00400         double otherData = *otherDataPtr++ * otherFact;
00401         for (int j=0; j<sz; j++)
00402           theData[j] += *matrixDataPtr++ * otherData;
00403       }
00404     }
00405   }
00406 
00407   else {
00408 
00409     // want: this = this * thisFact + m * v * otherFact
00410     for (int i=0; i<sz; i++)
00411       theData[i] *= thisFact;
00412 
00413     if (otherFact == 1.0) { // no point doing multiplication if otherFact = 1.0
00414       int otherSize = v.sz;
00415       double *matrixDataPtr = m.data;
00416       double *otherDataPtr = v.theData;
00417       for (int i=0; i<otherSize; i++) {
00418         double otherData = *otherDataPtr++;
00419         for (int j=0; j<sz; j++)
00420           theData[j] += *matrixDataPtr++ * otherData;
00421       }
00422     } else if (otherFact == -1.0) { // no point doing multiplication if otherFact = 1.0
00423       int otherSize = v.sz;
00424       double *matrixDataPtr = m.data;
00425       double *otherDataPtr = v.theData;
00426       for (int i=0; i<otherSize; i++) {
00427         double otherData = *otherDataPtr++;
00428         for (int j=0; j<sz; j++)
00429           theData[j] -= *matrixDataPtr++ * otherData;
00430       }
00431     } else {
00432       int otherSize = v.sz;
00433       double *matrixDataPtr = m.data;
00434       double *otherDataPtr = v.theData;
00435       for (int i=0; i<otherSize; i++) {
00436         double otherData = *otherDataPtr++ * otherFact;
00437         for (int j=0; j<sz; j++)
00438           theData[j] += *matrixDataPtr++ * otherData;
00439       }
00440     }
00441   }
00442   
00443   // successfull
00444   return 0;
00445 }
00446 
00447 
00448 
00449 int
00450 Vector::addMatrixTransposeVector(double thisFact, 
00451                                  const Matrix &m, 
00452                                  const Vector &v, 
00453                                  double otherFact )
00454 {
00455   // see if quick return
00456   if (otherFact == 0.0 && thisFact == 1.0)
00457     return 0;
00458 
00459 #ifdef _G3DEBUG
00460   // check the sizes are compatable
00461   if ((sz != m.noRows()) && (m.noRows() != v.sz)) {
00462     // otherwise incompatable sizes
00463     opserr << "Vector::addMatrixTransposeVector() - incompatable sizes\n";
00464     return -1;    
00465   }
00466 #endif
00467 
00468   if (thisFact == 1.0) {
00469 
00470     // want: this += m^t * v * otherFact
00471     if (otherFact == 1.0) { // no point doing multiplication if otherFact = 1.0
00472       int otherSize = v.sz;
00473       double *matrixDataPtr = m.data;
00474       double *otherDataPtrA = v.theData;
00475       for (int i=0; i<sz; i++) {
00476         double *otherDataPtr = otherDataPtrA;
00477         double sum = 0.0;
00478         for (int j=0; j<otherSize; j++)
00479           sum += *matrixDataPtr++ * *otherDataPtr++;
00480         theData[i] += sum;
00481       }
00482     } else if (otherFact == -1.0) { // no point doing multiplication if otherFact = 1.0
00483       int otherSize = v.sz;
00484       double *matrixDataPtr = m.data;
00485       double *otherDataPtrA = v.theData;
00486       for (int i=0; i<sz; i++) {
00487         double *otherDataPtr = otherDataPtrA;
00488         double sum = 0.0;
00489         for (int j=0; j<otherSize; j++)
00490           sum += *matrixDataPtr++ * *otherDataPtr++;
00491         theData[i] -= sum;
00492       }
00493     } else {
00494       int otherSize = v.sz;
00495       double *matrixDataPtr = m.data;
00496       double *otherDataPtrA = v.theData;
00497       for (int i=0; i<sz; i++) {
00498         double *otherDataPtr = otherDataPtrA;
00499         double sum = 0.0;
00500         for (int j=0; j<otherSize; j++)
00501           sum += *matrixDataPtr++ * *otherDataPtr++;
00502         theData[i] += sum * otherFact;
00503       }
00504     }
00505   }
00506 
00507   else if (thisFact == 0.0) {
00508 
00509     // want: this = m^t * v * otherFact
00510     if (otherFact == 1.0) { // no point doing multiplication if otherFact = 1.0
00511       int otherSize = v.sz;
00512       double *matrixDataPtr = m.data;
00513       double *otherDataPtrA = v.theData;
00514       for (int i=0; i<sz; i++) {
00515         double *otherDataPtr = otherDataPtrA;
00516         double sum = 0.0;
00517         for (int j=0; j<otherSize; j++)
00518           sum += *matrixDataPtr++ * *otherDataPtr++;
00519         theData[i] = sum;
00520       }
00521     } else if (otherFact == -1.0) { // no point doing multiplication if otherFact = -1.0
00522       int otherSize = v.sz;
00523       double *matrixDataPtr = m.data;
00524       double *otherDataPtrA = v.theData;
00525       for (int i=0; i<sz; i++) {
00526         double *otherDataPtr = otherDataPtrA;
00527         double sum = 0.0;
00528         for (int j=0; j<otherSize; j++)
00529           sum += *matrixDataPtr++ * *otherDataPtr++;
00530         theData[i] = -sum;
00531       }
00532     } else {
00533       int otherSize = v.sz;
00534       double *matrixDataPtr = m.data;
00535       double *otherDataPtrA = v.theData;
00536       for (int i=0; i<sz; i++) {
00537         double *otherDataPtr = otherDataPtrA;
00538         double sum = 0.0;
00539         for (int j=0; j<otherSize; j++)
00540           sum += *matrixDataPtr++ * *otherDataPtr++;
00541         theData[i] = sum * otherFact;
00542       }
00543     }
00544   } 
00545 
00546   else {
00547 
00548     // want: this = this * thisFact + m^t * v * otherFact
00549     if (otherFact == 1.0) { // no point doing multiplication if otherFact = 1.0
00550       int otherSize = v.sz;
00551       double *matrixDataPtr = m.data;
00552       double *otherDataPtrA = v.theData;
00553       for (int i=0; i<sz; i++) {
00554         double *otherDataPtr = otherDataPtrA;
00555         double sum = 0.0;
00556         for (int j=0; j<otherSize; j++)
00557           sum += *matrixDataPtr++ * *otherDataPtr++;
00558         double value = theData[i] * thisFact + sum;
00559         theData[i] = value;
00560       }
00561     } else if (otherFact == -1.0) { // no point doing multiplication if otherFact = 1.0
00562       int otherSize = v.sz;
00563       double *matrixDataPtr = m.data;
00564       double *otherDataPtrA = v.theData;
00565       for (int i=0; i<sz; i++) {
00566         double *otherDataPtr = otherDataPtrA;
00567         double sum = 0.0;
00568         for (int j=0; j<otherSize; j++)
00569           sum += *matrixDataPtr++ * *otherDataPtr++;
00570         double value = theData[i] * thisFact - sum;
00571         theData[i] = value;
00572       }
00573     } else {
00574       int otherSize = v.sz;
00575       double *matrixDataPtr = m.data;
00576       double *otherDataPtrA = v.theData;
00577       for (int i=0; i<sz; i++) {
00578         double *otherDataPtr = otherDataPtrA;
00579         double sum = 0.0;
00580         for (int j=0; j<otherSize; j++)
00581           sum += *matrixDataPtr++ * *otherDataPtr++;
00582         double value = theData[i] * thisFact + sum * otherFact;
00583         theData[i] = value;
00584       }
00585     }
00586 }
00587 
00588   return 0;
00589 }
00590         
00591         
00592 
00593 
00594 
00595 // double Norm();
00596 //      Method to return the norm of  vector. (non-const as may save norm for later)
00597 
00598 double
00599 Vector::Norm(void) const
00600 {
00601   double value = 0;
00602   for (int i=0; i<sz; i++) {
00603     double data = theData[i];
00604     value += data*data;
00605   }
00606   return sqrt(value);
00607 }
00608 
00609 double
00610 Vector::pNorm(int p) const
00611 {
00612   double value = 0;
00613   
00614   if (p>0) {
00615     for (int i=0; i<sz; i++) {
00616       double data = fabs(theData[i]);
00617       value += pow(data,p);
00618     }
00619     return pow(value,1.0/p);
00620   } else {
00621     for (int i=0; i<sz; i++) {
00622       double data = fabs(theData[i]);
00623       value = (data>value) ? data : value;
00624     }
00625     return value;
00626   }
00627 }
00628 
00629 
00630 double &
00631 Vector::operator[](int x) 
00632 {
00633 #ifdef _G3DEBUG
00634   // check if it is inside range [0,sz-1]
00635   if (x < 0 || x >= sz) {
00636     opserr << "Vector::() - x " << x << " outside range 0 - << " << sz-1 << endln;
00637     return VECTOR_NOT_VALID_ENTRY;
00638   }
00639 #endif
00640 
00641   return theData[x];
00642 }
00643 
00644 double Vector::operator[](int x) const
00645 {
00646 #ifdef _G3DEBUG
00647   // check if it is inside range [0,sz-1]
00648   if (x < 0 || x >= sz) {
00649     opserr << "Vector::() - x " << x << " outside range 0 - " <<  sz-1 << endln;
00650     return VECTOR_NOT_VALID_ENTRY;
00651   }
00652 #endif
00653 
00654   return theData[x];
00655 }
00656 
00657 
00658 // operator()(const ID &rows) const
00659 //      Method to return a vector whose components are the components of the
00660 //      current vector located in positions given by the ID rows.
00661 
00662 
00663 Vector 
00664 Vector::operator()(const ID &rows) const
00665 {
00666   // create a new Vector to be returned
00667   Vector result(rows.Size());
00668 
00669   // check if obtained VEctor of correct size
00670   if (result.Size() != rows.Size()) {
00671     opserr << "Vector::()(ID) - new Vector could not be constructed\n";
00672     return result;
00673   }
00674 
00675   // copy the appropraite contents from current to result     
00676   int pos;
00677   for (int i=0; i<rows.Size(); i++) {
00678     pos = rows(i);
00679     if (pos <0 || pos >= sz) {
00680       opserr << "Vector::()(ID) - invalid location " << pos << " outside range [0, " << sz-1 << "]\n";
00681     } else
00682       result(i) = (*this)(pos);
00683   }
00684   return result;
00685 }
00686 
00687 
00688 // Vector &operator=(const Vector  &V):
00689 //      the assignment operator, This is assigned to be a copy of V. if sizes
00690 //      are not compatable this.theData [] is deleted. The data pointers will not
00691 //      point to the same area in mem after the assignment.
00692 //
00693 
00694 Vector &
00695 Vector::operator=(const Vector &V) 
00696 {
00697   // first check we are not trying v = v
00698   if (this != &V) {
00699 
00700           /*
00701 #ifdef _G3DEBUG
00702     // check size compatability, if different warning
00703     if (sz != V.sz) 
00704       opserr << "Vector::operator=() - vectors of differing sizes\n");
00705 #endif
00706           */
00707 
00708       if (sz != V.sz)  {
00709 
00710 #ifdef _G3DEBUG
00711           opserr << "Vector::operator=() - vectors of differing sizes\n";
00712 #endif
00713 
00714           // Check that we are not deleting an empty Vector
00715           if (this->theData != 0) delete [] this->theData;
00716 
00717           this->sz = V.sz;
00718           
00719           // Check that we are not creating an empty Vector
00720           theData = (sz != 0) ? new double[sz] : 0;
00721       }
00722 
00723 
00724       //         copy the data
00725       for (int i=0; i<sz; i++)
00726           theData[i] = V.theData[i];
00727   }
00728 
00729   return *this;
00730 }
00731 
00732 
00733 
00734 
00735 Vector &
00736 Vector::operator=(const Tensor &V) 
00737 {
00738   int rank = V.rank();
00739   if (rank != 2) {
00740     opserr << "Vector::operator=() - tensor must be of rank 2\n";
00741     return *this;
00742   }
00743   int dim = V.dim(1);
00744   if (dim != V.dim(2)) {
00745     opserr << "Vector::operator=() - tensor must have square dimensions\n";
00746     return *this;
00747   }
00748   
00749   if (dim != 2 || dim != 3 || dim != 1) {
00750     opserr << "Vector::operator=() - tensor must be of dimension 2 or 3\n";
00751     return *this;
00752   }      
00753   
00754   if (dim == 1) {
00755     if (sz != 1) {
00756       opserr << "Vector::operator=() - Vector size must be 1\n"; 
00757       return *this;
00758     }
00759     theData[0] = V.cval(1,1);
00760   } else if (dim == 2) {
00761     if (sz != 3) {
00762       opserr << "Vector::operator=() - Vector size must be 3\n"; 
00763       return *this;
00764     }
00765     theData[0] = V.cval(1,1);
00766     theData[1] = V.cval(2,2);
00767     theData[2] = V.cval(1,2);
00768   } else {
00769     if (sz != 6) {
00770       opserr << "Vector::operator=() - Vector size must be 6\n"; 
00771       return *this;
00772     }      
00773     theData[0] = V.cval(1,1);
00774     theData[1] = V.cval(2,2);
00775     theData[2] = V.cval(3,3);
00776     theData[3] = V.cval(1,2);
00777     theData[4] = V.cval(1,3);
00778     theData[5] = V.cval(2,3);
00779   }
00780   return *this;
00781 }
00782 
00783 
00784 
00785 // Vector &operator+=(double fact):
00786 //      The += operator adds fact to each element of the vector, data[i] = data[i]+fact.
00787 
00788 Vector &Vector::operator+=(double fact)
00789 {
00790   if (fact != 0.0)
00791     for (int i=0; i<sz; i++)
00792       theData[i] += fact;
00793   return *this;    
00794 }
00795 
00796 
00797 
00798 // Vector &operator-=(double fact)
00799 //      The -= operator subtracts fact from each element of the vector, data[i] = data[i]-fact.
00800 
00801 Vector &Vector::operator-=(double fact)
00802 {
00803   if (fact != 0.0)
00804     for (int i=0; i<sz; i++)
00805       theData[i] -= fact;
00806   return *this;    
00807 }
00808 
00809 
00810 
00811 // Vector &operator*=(double fact):
00812 //      The -= operator subtracts fact from each element of the vector, data[i] = data[i]-fact.
00813 
00814 Vector &Vector::operator*=(double fact)
00815 {
00816   for (int i=0; i<sz; i++)
00817     theData[i] *= fact;
00818   return *this;
00819 }
00820 
00821 
00822 
00823 // Vector &operator/=(double fact):
00824 //      The /= operator divides each element of the vector by fact, theData[i] = theData[i]/fact.
00825 //      Program exits if divide-by-zero would occur with warning message.
00826 
00827 Vector &Vector::operator/=(double fact)
00828 {
00829   if (fact == 0.0) { // instead of divide-by-zero error set to VECTOR_VERY_LARGE_VALUE
00830     for (int i=0; i<sz; i++)
00831       theData[i] = VECTOR_VERY_LARGE_VALUE;
00832   } else {
00833     for (int i=0; i<sz; i++)
00834       theData[i] /= fact;
00835   }
00836   
00837   return *this;
00838 }
00839 
00840 
00841 
00842 
00843 // Vector operator+(double fact):
00844 //      The + operator returns a Vector of the same size as current, whose components
00845 //      are return(i) = theData[i]+fact;
00846 
00847 Vector 
00848 Vector::operator+(double fact) const
00849 {
00850   Vector result(*this);
00851   if (result.Size() != sz) 
00852     opserr << "Vector::operator+(double) - ran out of memory for new Vector\n";
00853 
00854   result += fact;
00855   return result;
00856 }
00857 
00858 
00859 
00860 // Vector operator-(double fact):
00861 //      The + operator returns a Vector of the same size as current, whose components
00862 //      are return(i) = theData[i]-fact;
00863 
00864 Vector 
00865 Vector::operator-(double fact) const
00866 {
00867     Vector result(*this);
00868     if (result.Size() != sz) 
00869       opserr << "Vector::operator-(double) - ran out of memory for new Vector\n";
00870 
00871     result -= fact;
00872     return result;
00873 }
00874 
00875 
00876 
00877 // Vector operator*(double fact):
00878 //      The + operator returns a Vector of the same size as current, whose components
00879 //      are return(i) = theData[i]*fact;
00880 
00881 Vector 
00882 Vector::operator*(double fact) const
00883 {
00884     Vector result(*this);
00885     if (result.Size() != sz) 
00886       opserr << "Vector::operator*(double) - ran out of memory for new Vector\n";
00887 
00888     result *= fact;
00889     return result;
00890 }
00891 
00892 
00893 // Vector operator/(double fact):
00894 //      The + operator returns a Vector of the same size as current, whose components
00895 //      are return(i) = theData[i]/fact; Exits if divide-by-zero error.
00896 
00897 Vector 
00898 Vector::operator/(double fact) const
00899 {
00900     if (fact == 0.0) 
00901       opserr << "Vector::operator/(double fact) - divide-by-zero error coming\n";
00902 
00903     Vector result(*this);
00904     if (result.Size() != sz) 
00905       opserr << "Vector::operator/(double) - ran out of memory for new Vector\n";
00906 
00907     result /= fact;
00908     return result;
00909 }
00910 
00911 
00912 
00913 // Vector &operator+=(const Vector &V):
00914 //      The += operator adds V's data to data, data[i]+=V(i). A check to see if
00915 //      vectors are of same size is performed if VECTOR_CHECK is defined.
00916 
00917 Vector &
00918 Vector::operator+=(const Vector &other)
00919 {
00920 #ifdef _G3DEBUG
00921   if (sz != other.sz) {
00922     opserr << "WARNING Vector::operator+=(Vector):Vectors not of same sizes: " << sz << " != " << other.sz << endln;
00923     return *this;
00924   }    
00925 #endif
00926 
00927   for (int i=0; i<sz; i++)
00928     theData[i] += other.theData[i];
00929   return *this;     
00930 }
00931 
00932 
00933 
00934 // Vector &operator-=(const Vector &V):
00935 //      The -= operator subtracts V's data from  data, data[i]+=V(i). A check 
00936 //      to see if vectors are of same size is performed if VECTOR_CHECK is defined.
00937 
00938 Vector &
00939 Vector::operator-=(const Vector &other)
00940 {
00941 #ifdef _G3DEBUG
00942   if (sz != other.sz) {
00943     opserr << "WARNING Vector::operator+=(Vector):Vectors not of same sizes: " << sz << " != " << other.sz << endln;
00944     return *this;
00945   }
00946 #endif
00947   
00948   for (int i=0; i<sz; i++)
00949     theData[i] -= other.theData[i];
00950   return *this;    
00951 }
00952 
00953 
00954 
00955 // Vector operator+(const Vector &V):
00956 //      The + operator checks the two vectors are of the same size if VECTOR_CHECK is defined.
00957 //      Then returns a Vector whose components are the vector sum of current and V's data.
00958 
00959 Vector 
00960 Vector::operator+(const Vector &b) const
00961 {
00962 #ifdef _G3DEBUG
00963   if (sz != b.sz) {
00964     opserr << "WARNING Vector::operator+=(Vector):Vectors not of same sizes: " << sz << " != " << b.sz << endln;
00965     return *this;
00966   }
00967 #endif
00968 
00969     Vector result(*this);
00970 
00971     // check new Vector of correct size
00972   if (result.Size() != sz) {
00973     opserr << "Vector::operator-(Vector): new Vector not of correct size \n";
00974     return result;
00975   }
00976   result += b;
00977   return result;
00978 }
00979 
00980 
00981 // Vector operator-(const Vector &V):
00982 //      The - operator checks the two vectors are of the same size and then returns a Vector
00983 //      whose components are the vector difference of current and V's data.
00984 
00985 Vector 
00986 Vector::operator-(const Vector &b) const
00987 {
00988 #ifdef _G3DEBUG
00989   if (sz != b.sz) {
00990     opserr << "WARNING Vector::operator+=(Vector):Vectors not of same sizes: " << sz << " != " << b.sz << endln;
00991     return *this;
00992   }
00993 #endif
00994 
00995   Vector result(*this);
00996 
00997   // check new Vector of correct size
00998   if (result.Size() != sz) {
00999     opserr << "Vector::operator-(Vector): new Vector not of correct size \n";
01000     return result;
01001   }
01002 
01003   result -= b;
01004   return result;
01005 }
01006 
01007 
01008 
01009 // double operator^(const Vector &V) const;
01010 //      Method to perform (Vector)transposed * vector.
01011 double
01012 Vector::operator^(const Vector &V) const
01013 {
01014 #ifdef _G3DEBUG
01015   if (sz != V.sz) {
01016     opserr << "WARNING Vector::operator+=(Vector):Vectors not of same sizes: " << sz << " != " << V.sz << endln;
01017     return 0.0;
01018   }
01019 #endif
01020 
01021   double result = 0.0;
01022   double *dataThis = theData;
01023   double *dataV = V.theData;
01024     for (int i=0; i<sz; i++)
01025       result += *dataThis++ * *dataV++;
01026 
01027     return result;
01028 }
01029 
01030 
01031 // Vector operator/(const Matrix &M) const;    
01032 //      Method to return inv(M)*this
01033 
01034 Vector
01035 Vector::operator/(const Matrix &M) const
01036 {
01037   Vector res(M.noRows());
01038     
01039   if (M.noRows() != M.noCols()) { // if not square do least squares solution
01040     Matrix A(M^M);
01041     A.Solve(*this, res);    
01042   }
01043   else {
01044     M.Solve(*this, res);
01045   }
01046   return res;
01047 }
01048     
01049         
01050 // Vector operator==(const Vector &V):
01051 //      The == operator checks the two vectors are of the same size if VECTOR_CHECK is defined.
01052 //      Then returns 1 if all the components of the two vectors are equal and 0 otherwise.
01053 
01054 int 
01055 Vector::operator==(const Vector &V) const
01056 {
01057 #ifdef _G3DEBUG
01058   if (sz != V.sz) {
01059     opserr << "WARNING Vector::operator==(Vector):Vectors not of same sizes: " << sz << " != " << V.sz << endln;
01060     return -1;
01061   }
01062 #endif
01063 
01064   double *dataThis = theData;
01065   double *dataV = V.theData;
01066 
01067   for (int i=0; i<sz; i++)
01068     if (*dataThis++ != *dataV++)
01069       return 0;
01070 
01071   return 1;
01072 }
01073 
01074 
01075 // Vector operator!=(const Vector &V):
01076 //      The != operator checks the two vectors are of the same size if VECTOR_CHECK is defined.
01077 //      Then returns 1 if any of the components of the two vectors are unequal and 0 otherwise.
01078 
01079 int 
01080 Vector::operator!=(const Vector &V) const
01081 {
01082 #ifdef _G3DEBUG
01083   if (sz != V.sz) {
01084     opserr << "WARNING Vector::operator!=(Vector):Vectors not of same sizes: " << sz << " != " << V.sz << endln;
01085     return -1;
01086   }
01087 #endif
01088 
01089   double *dataThis = theData;
01090   double *dataV = V.theData;
01091 
01092   for (int i=0; i<sz; i++)
01093     if (*dataThis++ != *dataV++)
01094       return 1;
01095 
01096   return 0;
01097 }
01098 
01099         
01100 
01101 
01102 
01103 // friend OPS_Stream &operator<<(OPS_Stream &s, const Vector &V)
01104 //      A function is defined to allow user to print the vectors using OPS_Streams.
01105 
01106 OPS_Stream &operator<<(OPS_Stream &s, const Vector &V)
01107 {
01108   for (int i=0; i<V.Size(); i++) 
01109       s << V(i) << " ";
01110 
01111   return s << endln;
01112 }
01113 
01114 // friend istream &operator>>(istream &s, Vector &V)
01115 //      A function is defined to allow user to input the data into a Vector which has already
01116 //      been constructed with data, i.e. Vector(int) or Vector(const Vector &) constructors.
01117 
01118 /*
01119 istream &operator>>(istream &s, Vector &V)
01120 {
01121   for (int i=0; i<V.Size(); i++) 
01122     s >> V(i);
01123   
01124     return s;
01125 }
01126 */
01127 
01128 
01129 Vector operator*(double a, const Vector &V)
01130 {
01131   return V * a;
01132 }
01133 
01134 
01135 int
01136 Vector::Assemble(const Vector &V, int init_pos, double fact) 
01137 {
01138   int res = 0;
01139   int cur_pos   = init_pos;  
01140   int final_pos = init_pos + V.sz - 1;
01141   
01142   if ((init_pos >= 0) && (final_pos < sz))
01143   {
01144      for (int j=0; j<V.sz; j++) 
01145         (*this)(cur_pos++) += V(j)*fact;
01146   }
01147   else 
01148   {
01149      opserr << "WARNING: Vector::Assemble(const Vector &V, int init_pos, double fact): ";
01150      opserr << "position outside bounds \n";
01151      res = -1;
01152   }
01153 
01154   return res;
01155 }
01156 
01157 
01158 
01159 
01160 int
01161 Vector::Extract(const Vector &V, int init_pos, double fact) 
01162 {
01163   int res = 0;
01164   int cur_pos   = init_pos;  
01165   int final_pos = init_pos + sz - 1;
01166   
01167   if ((init_pos >= 0) && (final_pos < V.sz))
01168   {
01169      for (int j=0; j<sz; j++) 
01170         (*this)(j) = V(cur_pos++)*fact;
01171   }
01172   else 
01173   {
01174      opserr << "WARNING: Vector::Assemble(const Vector &V, int init_pos, double fact): ";
01175      opserr << "position outside bounds \n";
01176      res = -1;
01177   }
01178 
01179   return res;
01180 }

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