BJmatrix.cpp

Go to the documentation of this file.
00001                                                                         
00002 // $Revision: 1.2 $                                                              
00003 // $Date: 2003/02/14 23:01:48 $                                                                  
00004 // $Source: /usr/local/cvs/OpenSees/SRC/nDarray/BJmatrix.cpp,v $                                                                
00005 
00006                                                                         
00007                                                                         
00009 //################################################################################
00010 //# COPY-YES  (C):     :-))                                                      #
00011 //# PROJECT:           Object Oriented Finite Element Program                    #
00012 //# PURPOSE:                                                                     #
00013 //# CLASS:             BJmatrix                                                  #
00014 //#                                                                              #
00015 //# VERSION:                                                                     #
00016 //# LANGUAGE:          C++.ver >= 2.0 ( Borland C++ ver=3.10, SUN C++ ver=2.1 )  #
00017 //# TARGET OS:         DOS || UNIX || . . .                                      #
00018 //# DESIGNER(S):       Boris Jeremic                                             #
00019 //# PROGRAMMER(S):     Boris Jeremic                                             #
00020 //#                    Bruce Eckel { changed/improved a lot by BJ }              #
00021 //#                                                                              #
00022 //# DATE:              November '92                                              #
00023 //# UPDATE HISTORY:    05 - __ avgust '93.  redefined as derived class from      #
00024 //#                                 nDarray class                                #
00025 //#                    january 06 '93  added BJmatrix2BJtensor_1, BJmatrix2BJtensor_2    #
00026 //#                                   BJmatrix2BJtensor_3                        #
00027 //#                    August 22-29 '94 choped to separate files and worked on   #
00028 //#                                   const and & issues                         #
00029 //#                    August 30-31 '94 added use_def_dim to full the CC         #
00030 //#                                   resolved problem with temoraries for       #
00031 //#                                   operators + and - ( +=, -= )               #
00032 //#                                                                              #
00033 //#                    May 10 2000 Xiaoyan found a bug with                      #
00034 //#        BJmatrix::BJmatrix(int rows, int columns, double *initvalues):        #
00035 //#           nDarray( 2, rows, columns, initvalues){ }                          #
00036 //#                                                                              #
00037 //#                                                                              #
00038 //#                                                                              #
00039 //################################################################################
00040 //*/
00041 #ifndef MATRIX_CC
00042 #define MATRIX_CC
00043 //  #include "basics.h"
00044 //  #include "nDarray.h"
00045 #include "BJmatrix.h"
00046 //#include "BJvector.h"
00047 #include <OPS_Stream.h>
00048 
00049 #define TINY  1e-20
00050 void BJmatrix::error(char * msg1, char * msg2)
00051   {
00052     ::fprintf(stderr,"BJmatrix error: %s %s\n", msg1, msg2);
00053     exit( 1 );
00054   }
00055 
00056 //##############################################################################
00057 BJmatrix::BJmatrix(int rows, int columns, double initval):
00058   nDarray( 2, rows, columns, initval){ } // calling the appropriate
00059                                           // base constructor
00060 //##############################################################################
00061 BJmatrix::BJmatrix(int rows, int columns, double *initvalues):
00062   nDarray( 2, rows, columns, initvalues){ } // calling the appropriate
00063                                              // base constructor
00064 //Xiaoyan found a bug it should be initvalue instead of *initvalue
00065 //##############################################################################
00066 //  special for vector
00067 BJmatrix::BJmatrix(int rank, int rows, int columns, double *initvalues):
00068   nDarray( rank, rows, columns, initvalues){ } // calling the appropriate
00069                                              // base constructor
00070 //##############################################################################
00071 //  special for vector
00072 BJmatrix::BJmatrix(int rank, int rows, int columns, double initvalues):
00073   nDarray( rank, rows, columns, initvalues){ } // calling the appropriate
00074                                              // base constructor
00075 //##############################################################################
00076 BJmatrix::BJmatrix(char *flag, int dimension ): // create an ident BJmatrix
00077   nDarray("NO")           // with base class constructor cancelation
00078   {
00079     if ( flag[0] != 'I' && flag[0] != 'e' )
00080      {
00081       ::printf("\nTo create a 2nd rank Kronecker delta type: nDarray (\"I\",2);\n");
00082       ::exit( 1 );
00083      }
00084 // create the structure:
00085      pc_nDarray_rep = new nDarray_rep; // this 'new' is overloaded
00086      rank(2);  //rank_of_nDarray here BJmatrix = 2
00087 
00088 // in the case of nDarray_rank=0 add one to get right thing from the
00089 // operator new
00090      set_dim_pointer( new int[rank()] );  // array for dimensions
00091      long int number = dimension*dimension;
00092      total_number(number);
00093      for( int idim = 1 ; idim <= rank() ; idim++ )
00094        {
00095          dim()[idim-1] = dimension;
00096        }
00097 
00098 // allocate memory for the actual nDarray as nDarray
00099      set_data_pointer( new double [ (size_t) total_number() ]);
00100        if (!data())
00101          {
00102            ::printf("\a\nInsufficient memory for array\n");
00103            ::exit(1);
00104          }
00105 
00106      set_reference_count(+1);  // so far, there's one reference
00107 
00108      for ( int i2=1 ; i2<=dim(1) ; i2++ )
00109        for ( int j2=1 ; j2<=dim(2) ; j2++ )
00110          val(i2,j2) = (i2 == j2 ? 1  : 0);
00111 }
00112 
00113 //#############################################################################
00114 // error message when trying to read a 'standard'
00115 // BJmatrix file:
00116 static char nonstandard[] =
00117 "is a 'non-standard'file. A 'standard' BJmatrix file must\n"
00118 "start with the dimensions of the BJmatrix, i.e.:\n"
00119 "\t rows= 12 columns= 14\n or abbreviated: r= 12 c= 14\n"
00120 "Notice rows appear before columns, and chars are lowercase\n"
00121 "comments follow '!' signs to end of line, data follows :::\n";
00122 
00123 //#############################################################################
00124 // read from "standard" BJmatrix file:
00125 BJmatrix::BJmatrix(char *initfile):
00126   nDarray("NO")           // with base class constructor cancelation
00127 {
00128 #define BSIZE 120
00129   FILE *from;
00130 
00131   int rows    = 0;
00132   int columns = 0;
00133 
00134   if ((from = fopen(initfile,"r")) == 0)
00135     error("cannot open BJmatrix initializer file", initfile);
00136   char buf[BSIZE], *cp, *cp2;
00137   int rfound = 0, cfound = 0, colonsfound = 0;
00138 //        /*Parse file initialization header  */
00139   while( fgets(buf, BSIZE, from) )         // for each header line
00140     {
00141 // Remove comments with ANSI C library function 'strp
00142       if( ( cp = strpbrk(buf,"!")) != NULL ) // look for comments
00143         *cp = '\0';  // terminate string at comment
00144       if(( cp = strpbrk(buf,"r")) != NULL )
00145         if (( cp2 = strpbrk(cp, "=")) != NULL )
00146           if (( cp = strpbrk( cp2, "0123456789")) != NULL )
00147             {
00148               rows = atoi(cp);
00149               rfound++;  // flag to say rows were found
00150             }
00151       if( ( cp = strpbrk(buf,"c") ) != NULL )
00152          if ( ( cp2 = strpbrk(cp, "=")) != NULL )
00153            if ( ( cp = strpbrk(cp2, "O123456789")) != NULL )
00154              {
00155                columns = atoi(cp);
00156                cfound++;  // flag to say cols were found
00157              }
00158       if ( strstr(buf,":::") != NULL )
00159         {
00160           colonsfound++;
00161           break; //... out of "while" loop
00162         }
00163     }
00164   if ( !rfound || !cfound || !colonsfound )
00165     {
00166       fprintf(stderr, " %s%s", initfile, nonstandard);
00167       exit(1);
00168     }
00169 
00170 // let's construct a BJmatrix
00171 
00172 // create the structure:
00173   pc_nDarray_rep = new nDarray_rep; // this 'new' is overloaded
00174   rank(2);  // rank_of_nDarray here BJmatrix = 2
00175 
00176   set_dim_pointer( (new int[ rank() ]) );// array for dimensions
00177   long int number = rows*columns;
00178   total_number(number);
00179 
00180   dim()[0] = rows;
00181   dim()[1] = columns;
00182 
00183 // allocate memory for the actual nDarray as nDarray
00184   set_data_pointer( new double [ (size_t) total_number() ] );
00185     if (!data())
00186       {
00187         ::printf("\a\nInsufficient memory for array\n");
00188         ::exit(1);
00189       }
00190 
00191   set_reference_count(+1);  // so far, there's one reference
00192 
00193   for ( int row=1 ; row <= rows ; row++ )
00194     for ( int col=1 ; col <= columns ; col++ )
00195       {
00196         char nb[20];
00197         fscanf(from, "%s", nb); // scan for space-delimited string
00198         val(row,col) = (double) atof(nb); // convert it to a double
00199         if(ferror(from))
00200           error("problem with BJmatrix initializer file ", initfile);
00201       }
00202   fclose(from);
00203 }
00204 
00205 //#############################################################################
00206 // read from flat BJmatrix file: and write to test output
00207 BJmatrix::BJmatrix(char *initfile, char *outfile):
00208   nDarray("NO")           // with base class constructor cancelation
00209 {
00210 //#define BSIZE 120
00211   FILE *from;
00212 //Kai  FILE *to;
00213 
00214   int rows    = 0;
00215   int columns = 0;
00216 
00217   if ((from = fopen(initfile,"r")) == 0)
00218     error("cannot open BJmatrix initializer file", initfile);
00219 //  char buf[BSIZE];
00220   char  cp[32];
00221   fscanf(from, "%s", cp); // scan for space-delimited string
00222 //  cp = strpbrk( buf, "0123456789")
00223   rows = columns = atoi(cp);
00224 // create the structure:
00225   pc_nDarray_rep = new nDarray_rep; // this 'new' is overloaded
00226   rank(2);  // rank_of_nDarray here BJmatrix = 2
00227 
00228   set_dim_pointer( (new int[ rank() ]) );// array for dimensions
00229   long int number = rows*columns;
00230   total_number(number);
00231 
00232   dim()[0] = rows;
00233   dim()[1] = columns;
00234 
00235 // allocate memory for the actual nDarray as nDarray
00236   set_data_pointer( new double [ (size_t) total_number() ] );
00237     if (!data())
00238       {
00239         ::printf("\a\nInsufficient memory for array\n");
00240         ::exit(1);
00241       }
00242 
00243   set_reference_count(+1);  // so far, there's one reference
00244 
00245   for ( int row=1 ; row <= rows ; row++ )
00246     for ( int col=1 ; col <= columns ; col++ )
00247       {
00248         char nb[20];
00249         fscanf(from, "%s", nb); // scan for space-delimited string
00250         val(row,col) = (double) atof(nb); // convert it to a double
00251         if(ferror(from))
00252           error("problem with BJmatrix initializer file ", initfile);
00253       }
00254   fclose(from);
00255 
00256 //Kai  if ((to = fopen(outfile,"w")) == 0)
00257 //Kai    error("cannot open BJmatrix output file", outfile);
00258   write_standard(outfile, "this is a test BJmatrix output"); 
00259 }
00260 
00261 //##############################################################################
00262 BJmatrix::BJmatrix(const BJmatrix & x): // copy-initializer
00263   nDarray("NO")     // with base class constructor cancelation
00264     {
00265       x.pc_nDarray_rep->n++;  // we're adding another reference.
00266 //      x.reference_count(+1); // we're adding another reference.
00267       pc_nDarray_rep = x.pc_nDarray_rep;  // point to the new BJtensor_rep.
00268     }
00269 
00270 
00271 
00272 //##############################################################################
00273 BJmatrix::BJmatrix(const nDarray & x):
00274   nDarray( x ) { }
00275 
00276 
00277 
00278 //--// IT IS NOT INHERITED so must be defined in all derived classes
00279 //--// See ARM page 277.
00280 //--//##############################################################################
00281 //--BJmatrix::~BJmatrix()
00282 //--{
00283 //--  if (reference_count(-1) == 0)  // if reference count  goes to 0
00284 //--    {
00285 //--// DEallocate memory of the actual nDarray
00286 //--//    delete [pc_nDarray_rep->pc_nDarray_rep->total_numb] pc_nDarray_rep->pd_nDdata;
00287 //--// nema potrebe za brojem clanova koji se brisu## see ELLIS & STROUSTRUP $18.3
00288 //--//                                                and note on the p.65($5.3.4)
00289 //--//  and the page 276 ($12.4)
00290 //--    delete [] data();
00291 //--    delete [] dim();
00292 //--    delete pc_nDarray_rep;
00293 //--  }
00294 //--}
00295 
00296 
00297 //#############################################################################
00298 int BJmatrix::rows( ) const  // rows in BJmatrix
00299   {
00300     return this->dim(1);
00301   }
00302 
00303 
00304 
00305 //#############################################################################
00306 int BJmatrix::cols( ) const       // cols in BJmatrix
00307   {
00308     return this->dim(2);
00309   }
00310 
00311 
00312 
00313 //#############################################################################
00314 BJmatrix& BJmatrix::operator=( const BJmatrix & rval)
00315 {
00316       rval.pc_nDarray_rep->n++;  // we're adding another reference.
00317 //    rval.reference_count(+1);  // tell the rval it has another reference
00318 //   /*  It is important to increment the reference_counter in the new
00319 //       BJtensor before decrementing the reference_counter in the
00320 //       old BJtensor_rep to ensure proper operation when assigning a
00321 //       BJtensor_rep to itself ( after ARKoenig JOOP May/June '90 )  */
00322 
00323  // clean up current value;
00324     if( reference_count(-1) == 0)  // if nobody else is referencing us.
00325       {
00326         delete [] data();
00327         delete [] dim();
00328         delete pc_nDarray_rep;
00329       }
00330  // connect to new value
00331     pc_nDarray_rep = rval.pc_nDarray_rep;  // point at the rval BJtensor_rep
00332     return *this;
00333 }
00334 
00335 
00336 
00337 //#############################################################################
00338 void BJmatrix::write_standard(char *filename, char *msg)
00339   {
00340     FILE *to;
00341     if ((to = fopen(filename,"w")) == NULL)
00342       error("cannot open or create BJmatrix output file",filename);
00343     fprintf(to, "# %s: BJmatrix file written in \"standard\" format\n", filename);
00344     time_t clock;
00345     time(&clock);
00346     fprintf(to, "# %s", asctime(localtime(&clock)));
00347     fprintf(to, "# %s", msg);
00348     fprintf(to, "rows= %d columns= %d", rows(), cols());
00349     fprintf(to, ":::\n");
00350     for ( int row=0; row<rows() ; row++ )
00351       {
00352         for( int col=0; col<cols() ; col++ )
00353           {
00354             fprintf(to, "%6.6g  ",mval(row,col));
00355             if(ferror(to))
00356               error("problem with BJmatrix output file ", filename);
00357           }
00358         fprintf(to, "\n");
00359       }
00360 }
00361 
00362 //....//#############################################################################
00363 //....// This is from JOOP May/June 1990 after ARKoenig ( I did the rest )
00364 //....BJmatrix & BJmatrix::operator*=( const BJmatrix & rval )
00365 //....  {
00366 //....    if( this->cols() != rval.rows())
00367 //....      error("# rows of second mat must equal "
00368 //....               "# cols of first for multiply#");
00369 //....
00370 //....   int this_r = this->pc_nDarray_rep->dim[0];
00371 //....   int this_c = this->pc_nDarray_rep->dim[1];
00372 //....   int rval_r = rval.pc_nDarray_rep->dim[0];
00373 //....   int rval_c = rval.pc_nDarray_rep->dim[1];
00374 //....// temporary BJmatrix that will keep result
00375 //....   BJmatrix result( this_r, rval_c, 0.0 );
00376 //....
00377 //....// copy *this if necessery
00378 //....// i.e. if somebody else is pointing to the same nDarray_rep class
00379 //....// then allocate new memory for the this and disconect this from
00380 //....// the old one!
00381 //....    if ( this->pc_nDarray_rep->n > 1 )// see ARK in JOOP may/june '90
00382 //....      {                               // "Letter From a Newcomer"
00383 //....//..//..............................................................................
00384 //....//..// create the structure:
00385 //....//..        nDarray_rep * New_pc_nDarray_rep = new nDarray_rep; // this 'new' is overloaded
00386 //....//..        New_pc_nDarray_rep->nDarray_rank = this->pc_nDarray_rep->nDarray_rank;
00387 //....//..// in the case of nDarray_rank=0 add one to get right thing from the
00388 //....//..// operator new
00389 //....//..        int one_or0 = 0;
00390 //....//..        if(!New_pc_nDarray_rep->nDarray_rank) one_or0 = 1;
00391 //....//..        New_pc_nDarray_rep->dim = new int[New_pc_nDarray_rep->nDarray_rank+one_or0];
00392 //....//..                                  // array for dimensions
00393 //....//..        New_pc_nDarray_rep->total_numb = 1;
00394 //....//..        for( int idim = 0 ; idim < New_pc_nDarray_rep->nDarray_rank ; idim++ )
00395 //....//..          {
00396 //....//..            New_pc_nDarray_rep->dim[idim] = this->pc_nDarray_rep->dim[idim];
00397 //....//..            New_pc_nDarray_rep->total_numb *= New_pc_nDarray_rep->dim[idim];
00398 //....//..          }
00399 //....//..// allocate memory for the actual nDarray as nDarray
00400 //....//..        New_pc_nDarray_rep->pd_nDdata = new double [(size_t)New_pc_nDarray_rep->total_numb];
00401 //....//..          if (!New_pc_nDarray_rep->pd_nDdata)
00402 //....//..            {
00403 //....//..              ::printf("\a\nInsufficient memory for array\n");
00404 //....//..              ::exit(1);
00405 //....//..            }
00406 //....//..         New_pc_nDarray_rep->n = 1;  // so far, there's one reference
00407 //....//..         for ( int i=0 ; i<New_pc_nDarray_rep->total_numb ; i++ )
00408 //....//..           New_pc_nDarray_rep->pd_nDdata[i] = this->pc_nDarray_rep->pd_nDdata[i];
00409 //....//.........
00410 //....         this->pc_nDarray_rep->total_numb--;
00411 //....         this->pc_nDarray_rep = New_pc_nDarray_rep;
00412 //....//..............................................................................
00413 //....      }
00414 //....
00415 //....// multiply rval with *this
00416 //....   for ( int row=0 ; row<this_r ; row++ )
00417 //....      for ( int col=0 ; col<rval_c ; col++ )
00418 //....        {
00419 //....          double sum = 0.0;
00420 //....          for( int i=0 ; i<this_c ; i++ )
00421 //....            sum += this->pc_nDarray_rep->m[row][i]*rval.pc_nDarray_rep->m[i][col];
00422 //....          result.val(row,col) = sum;
00423 //....        }
00424 //....//..// copy result to *this
00425 //....//..   for ( int i=0 ; i<this_r ; i++ )
00426 //....//..      for ( int j=0 ; j<rval_c ; j++ )
00427 //....//..         this->pc_nDarray_rep->m[i][j] = result.val(i,j);
00428 //....// copy result to *this actually take the whole class pointer and just
00429 //....// assign it to the this
00430 //....
00431 //....   this->pc_nDarray_rep = result.pc_nDarray_rep;
00432 //....
00433 //....   return *this;
00434 //....  }
00435 //....
00436 //....//#############################################################################
00437 //....// This is from JOOP May/June 1990 after ARKoenig
00438 //....inline BJmatrix operator*(const BJmatrix & left_val, const BJmatrix & right_val)
00439 //....  {
00440 //....    BJmatrix result(left_value);
00441 //....    result *= right_val;
00442 //....    return result;
00443 //....  }
00444 //....
00445 //....
00446 
00447 
00448 
00449 
00450 //#############################################################################
00451 // OLD good version
00452 BJmatrix BJmatrix::operator*( BJmatrix & arg)
00453   {
00454     if( cols() != arg.rows())
00455       error("# rows of second mat must equal "
00456                "# cols of first for multiply#");
00457     BJmatrix result(rows(),arg.cols());
00458     for( int row=0 ; row<rows() ; row++ )
00459       for( int col=0 ; col<arg.cols() ; col++ )
00460         {
00461           double sum = 0;
00462           for( int i=0 ; i<cols() ; i++ )
00463             sum += mval(row,i)*arg.mval(i,col);
00464           result.mval(row,col) = sum;
00465         }
00466     return result; // Returning a local variable?
00467     // copy-initializer happens before the destructor,
00468     // so reference count is 2 when destructor is called,
00469     // thus destructor doesn't free the memory.
00470   }
00471 
00472 //**sky**// this is COUPLING between ordinary BJmatrix and SKYMATRIX
00473 //**sky**// it will be usefull in multiplying vector with skyBJmatrix
00474 //**sky**BJmatrix BJmatrix::operator*(const skyBJmatrix & arg)
00475 //**sky**  {
00476 //**sky**    if( cols() != arg.dimension_of_sky_M())
00477 //**sky**      error("# dimension_of_sky_M must equal "
00478 //**sky**               "# cols of first for multiply#");
00479 //**sky**    BJmatrix result(rows(),arg.dimension_of_sky_M());
00480 //**sky**    for( int row=0 ; row<rows() ; row++ )
00481 //**sky**      for( int col=0 ; col<arg.dimension_of_sky_M() ; col++ )
00482 //**sky**        {
00483 //**sky**          double sum = 0;
00484 //**sky**          for( int i=0 ; i<cols() ; i++ )
00485 //**sky**            {
00486 //**sky**//            double prvi = val(row,i);
00487 //**sky**//            double drugi = arg.full_val(i+1,col+1);
00488 //**sky**//            double temp = prvi*drugi; // in skyBJmatrix
00489 //**sky**//            sum += temp;
00490 //**sky**              sum += val(row,i)*arg.full_val(i+1,col+1);
00491 //**sky**            }
00492 //**sky**          result.val(row,col) = sum;                   // start from 1
00493 //**sky**        }
00494 //**sky**    return result; // Returning a local variable?
00495 //**sky**    // copy-initializer happens before the destructor,
00496 //**sky**    // so reference count is 2 when destructor is called,
00497 //**sky**    // thus destructor doesn't free the memory.
00498 //**sky**  }
00499 //**sky**
00500 
00501 
00502 
00503 //#############################################################################
00504 BJmatrix BJmatrix::operator*( double arg)
00505   {
00506     BJmatrix result(rows(),cols());
00507     for ( int i=0 ; i<rows() ; i++ )
00508      for ( int j=0 ; j<cols() ; j++ )
00509        result.mval(i,j) = mval(i,j) * arg;
00510     return result;
00511   }
00512 
00513 //....//#############################################################################
00514 //....// I had to overload the operator* from BJmatrix class
00515 //....// because in the case of vectors s*sT and so on
00516 //....vector BJmatrix::operator*( vector & arg)
00517 //....  {
00518 //....    if( cols() != arg.rows())
00519 //....      error("# rows of second mat must equal "
00520 //....               "# cols of first for multiply in BJmatrix::operator*( vector & arg) ");
00521 //....    vector result(arg.rows());
00522 //....      for( int row=0 ; row<arg.rows() ; row++ )
00523 //....        {
00524 //....          double sum = 0;
00525 //....          for( int i=0 ; i<cols() ; i++ )
00526 //....            sum += mval(row,i)*arg.cval(i);
00527 //....          result.val(row) = sum;
00528 //....        }
00529 //....    return result; // Returning a local variable?
00530 //....    // copy-initializer happens before the destructor,
00531 //....    // so reference count is 2 when destructor is called,
00532 //....    // thus destructor doesn't free the memory.
00533 //....  }
00534 
00535 
00536 //#############################################################################
00537 BJmatrix BJmatrix::transpose()
00538   {
00539 // This request is relaxed for vectors
00540 //    if(rows() != cols())
00541 //    error("BJmatrix must be square to transpose#\n");
00542     BJmatrix trans(cols(), rows());
00543     for ( int row=0 ; row<rows() ; row++ )
00544       for ( int col=0 ; col<cols() ; col++ )
00545         trans.mval(col,row) = mval(row,col);
00546     return trans;
00547   }
00548 
00549 //#############################################################################
00550 double BJmatrix::mmin()
00551   {
00552     double temp;
00553     if ( rows()<=0 || cols()<=0)
00554       error("bad BJmatrix size for min ()");
00555     double minimum = mval(0,0);
00556     for ( int row=0 ; row<rows() ; row++ )
00557       for ( int col=0 ; col<cols() ; col++ )
00558         if ( (temp=mval(row,col)) < minimum )
00559           minimum = temp;
00560     return minimum;
00561   }
00562 
00563 //#############################################################################
00564 double BJmatrix::mmax()
00565   {
00566     double temp;
00567     if( rows()<=0 || cols()<=0)
00568       error("bad BJmatrix size for max()");
00569     double maximum = mval(0,0);
00570     for ( int row=0 ; row<rows() ; row++ )
00571       for ( int col=0 ; col<cols() ; col++ )
00572         {
00573           if ( (temp=mval(row,col)) > maximum )
00574           maximum = temp;
00575         }
00576     return maximum;
00577   }
00578 
00579 
00580 //#############################################################################
00581 double BJmatrix::mean()
00582   {
00583     int col = 0;
00584     int row = 0;
00585     double sum = 0;
00586     for ( row=0 ; row<rows() ; row++ )
00587       for ( col=0 ; col<cols() ; col++ )
00588         sum += fabs(mval(row,col));
00589     return sum/(row*col);
00590   }
00591 
00592 
00593 //#############################################################################
00594 double BJmatrix::sum()
00595   {
00596     int col;
00597     double sum = 0;
00598     for ( int row=0 ; row<rows() ; row++ )
00599       for ( col=0 ; col<cols() ; col++ )
00600         sum += mval(row,col);
00601     return sum;
00602   }
00603 
00604 
00605 
00606 //#############################################################################
00607 double BJmatrix::variance()
00608   {
00609     int col = 0;
00610     int row = 0;
00611     double s_squared = 0;
00612     double mn = mean();
00613     for ( row=0 ; row<rows() ; row++ )
00614       for ( col=0 ; col<cols() ; col++ )
00615         {
00616           double temp = mval(row,col) - mn;
00617           temp *= temp;
00618           s_squared += temp;
00619         }
00620     s_squared /= row*col-1; // number of elements minus one
00621     return s_squared;
00622   }
00623 
00624 
00625 
00626 
00627 //#############################################################################
00628 double BJmatrix::determinant()
00629   {
00630     if( rows() != cols() )
00631       error("BJmatrix must be square for determinant()");
00632     BJmatrix indx(cols()); // create the "index vector"
00633 //    BJmatrix B(cols()); // see pp 38. in Numerical Recipes
00634     int d;
00635     // perform the decomposition once:
00636     BJmatrix decomp = lu_decompose(indx,d);
00637 //    decomp.print("decomposed BJmatrix");
00638     double determinant = d;
00639       for( int i=0 ; i < cols() ; i++ )
00640         determinant *= decomp.mval(i,i);
00641     return determinant;
00642   }
00643 
00644 
00645 //#############################################################################
00646 BJmatrix BJmatrix::inverse()
00647   {
00648     if( rows()!=cols() )
00649       error("BJmatrix must be square for inverse()");
00650     BJmatrix Y("I", rows()); // create an identity BJmatrix
00651     BJmatrix indx(cols());   // create the "index vector"
00652     BJmatrix B(cols());      // see Press & Flannery
00653     int d;
00654     // perform the decomposition once:
00655     BJmatrix decomp = lu_decompose(indx,d);
00656     for(int col=0 ; col<cols() ; col++ )
00657       {
00658         B.copy_column(Y,col,0);
00659         decomp.lu_back_subst(indx, B);
00660         Y.copy_column(B, 0, col);
00661       }
00662     return Y.transpose();
00663   }
00664 
00665 
00666 
00667 
00668 //~~~~//##############################################################################
00669 //~~~~BJtensor BJmatrix::BJmatrix2BJtensor_1()  // convert BJmatrix of to 4th order BJtensor
00670 //~~~~  {                               // I_ijkl scheme
00671 //~~~~
00672 //~~~~// building up a BJtensor back_conv
00673 //~~~~// this is special case just for 4th order with def_dim_4 !!
00674 //~~~~  BJtensor back_conv( 4, def_dim_4, 0.0);
00675 //~~~~
00676 //~~~~  int m41 = 0;
00677 //~~~~  int m42 = 0;
00678 //~~~~
00679 //~~~~// filling back the BJmatrix to BJtensor
00680 //~~~~  for ( int c44=1 ; c44<=back_conv.dim(4) ; c44++ )
00681 //~~~~    for ( int c43=1 ; c43<=back_conv.dim(3) ; c43++ )
00682 //~~~~      for ( int c42=1 ; c42<=back_conv.dim(2) ; c42++ )
00683 //~~~~        for ( int c41=1 ; c41<=back_conv.dim(1) ; c41++ )
00684 //~~~~          {
00685 //~~~~            m41 = back_conv.dim(1)*(c41-1)+c43;
00686 //~~~~            m42 = back_conv.dim(2)*(c42-1)+c44;
00687 //~~~~
00688 //~~~~            back_conv.val(c41,c42,c43,c44) = this->val(m41,m42);
00689 //~~~~          }
00690 //~~~~
00691 //~~~~//    back_conv.print("t","back to BJtensor back_conv");
00692 //~~~~    return back_conv;
00693 //~~~~  }
00694 
00695 //##############################################################################
00696 BJtensor BJmatrix::BJmatrix2BJtensor_2()  // convert BJmatrix of to 4th order BJtensor
00697   {                               // I_ikjl scheme
00698 
00699 // building up a BJtensor back_conv
00700 // this is special case just for 4th order with def_dim_4 !!
00701   BJtensor back_conv( 4, def_dim_4, 0.0);
00702 #ifdef SASA
00703   BJtensor Back_conv(4,def_dim_4_2,0.0);
00704  if(cols()==4) back_conv=Back_conv; // dimenzije su po 2
00705 #endif
00706   int m41 = 0;
00707   int m42 = 0;
00708 
00709 // filling back the BJmatrix to BJtensor
00710   for ( int c44=1 ; c44<=back_conv.dim(4) ; c44++ )
00711     for ( int c43=1 ; c43<=back_conv.dim(3) ; c43++ )
00712       for ( int c42=1 ; c42<=back_conv.dim(2) ; c42++ )
00713         for ( int c41=1 ; c41<=back_conv.dim(1) ; c41++ )
00714           {
00715             m41 = back_conv.dim(1)*(c41-1)+c42;
00716             m42 = back_conv.dim(3)*(c43-1)+c44;
00717 
00718             back_conv.val(c41,c42,c43,c44) = this->val(m41,m42);
00719           }
00720 
00721 //    back_conv.print("t","back to BJtensor back_conv");
00722     return back_conv;
00723   }
00724 
00725 //##############################################################################
00726 BJtensor BJmatrix::BJmatrix2BJtensor_22()  // convert BJmatrix of to 2th order BJtensor
00727   {                               // I_ikjl scheme
00728 
00729 // building up a BJtensor back_conv
00730 // this is special case just for 4th order with def_dim_4 !!
00731 
00732 //  BJtensor back_conv( 2, def_dim_2, 0.0);
00733   BJtensor back_conv( 2, def_dim_2, this->data());
00734 
00735 //..  //  int m41 = 0;
00736 //..  //  int m42 = 0;
00737 //..  
00738 //..  // filling back the BJmatrix to BJtensor
00739 //..     for ( int c22=1 ; c22<=back_conv.dim(2) ; c22++ )
00740 //..       for ( int c21=1 ; c21<=back_conv.dim(1) ; c21++ )
00741 //..         {
00742 //..  //         m41 = back_conv.dim(1)*(c41-1)+c42;
00743 //..  //         m42 = back_conv.dim(3)*(c43-1)+c44;
00744 //..       
00745 //..           back_conv.val(c21,c22) = this->val(m41,m42);
00746 //..         }
00747 //..  
00748 //..  //    back_conv.print("t","back to BJtensor back_conv");
00749 
00750     return back_conv;
00751   }
00752 //~~~~//##############################################################################
00753 //~~~~BJtensor BJmatrix::BJmatrix2BJtensor_3()  // convert BJmatrix of to 4th order BJtensor
00754 //~~~~  {                               // I_ilkj scheme
00755 //~~~~
00756 //~~~~// building up a BJtensor back_conv
00757 //~~~~// this is special case just for 4th order with def_dim_4 !!
00758 //~~~~  BJtensor back_conv( 4, def_dim_4, 0.0);
00759 //~~~~
00760 //~~~~  int m41 = 0;
00761 //~~~~  int m42 = 0;
00762 //~~~~
00763 //~~~~// filling back the BJmatrix to BJtensor
00764 //~~~~  for ( int c44=1 ; c44<=back_conv.dim(4) ; c44++ )
00765 //~~~~    for ( int c43=1 ; c43<=back_conv.dim(3) ; c43++ )
00766 //~~~~      for ( int c42=1 ; c42<=back_conv.dim(2) ; c42++ )
00767 //~~~~        for ( int c41=1 ; c41<=back_conv.dim(1) ; c41++ )
00768 //~~~~          {
00769 //~~~~            m41 = back_conv.dim(1)*(c41-1)+c44;
00770 //~~~~            m42 = back_conv.dim(2)*(c42-1)+c43;
00771 //~~~~
00772 //~~~~            back_conv.val(c41,c42,c43,c44) = this->val(m41,m42);
00773 //~~~~          }
00774 //~~~~
00775 //~~~~//    back_conv.print("t","back to BJtensor back_conv");
00776 //~~~~    return back_conv;
00777 //~~~~  }
00778 //~~~~
00779 //~~~~
00780 //#############################################################################
00781 //##BJmatrix BJmatrix::compress_col(int col1, int col2, int to_col)
00782 //##  {
00783 //##    BJmatrix mat_temp( rows(), cols()-1);
00784 //##//    mat_temp.print("mat_temp first appearence\n");
00785 //##    for( int row=1 ; row<=rows() ; row++ )
00786 //##      {
00787 //##        // make temp vector to be put in the to_col :
00788 //##// val STARTS from 0
00789 //##        mat_temp(row,to_col) = val(row-1,col1-1)+val(row-1,col2-1);
00790 //##      }
00791 //##//    mat_temp.print("mat_temp second appearence\n");
00792 //##
00793 //##   int temp_row=1;
00794 //##   int temp_col=1;
00795 //##
00796 //##    for( int col=1 ; col<=cols() ; col++ )
00797 //##      {
00798 //##        if( col!=col1 && col!=col2 )
00799 //##          {
00800 //##            temp_row=1;
00801 //##            if( temp_col==to_col )
00802 //##              {
00803 //##                temp_col++;
00804 //##              }
00805 //##
00806 //##          for( row=1 ; row<=rows() ; row++ )
00807 //##            {
00808 //##              mat_temp(temp_row,temp_col) = val(row-1,col-1);
00809 //##              temp_row++;
00810 //##            }
00811 //##            temp_col++;
00812 //##          }
00813 //##      }
00814 //##//    mat_temp.print("mat_temp third appearence\n");
00815 //##
00816 //##    return mat_temp;
00817 //##  }
00818 //##
00819 
00820 
00821 //#############################################################################
00822 //##BJmatrix BJmatrix::compress_row(int row1, int row2, int to_row)
00823 //##  {
00824 //##    BJmatrix mat_temp( rows()-1, cols());
00825 //##//    mat_temp.print("mat_temp first appearence\n");
00826 //##    for( int col=1 ; col<=cols() ; col++ )
00827 //##      {
00828 //##        // make temp vector to be put in the to_row :
00829 //##// val STARTS from 0
00830 //##        mat_temp(to_row,col) = val(row1-1,col-1)+val(row2-1,col-1);
00831 //##      }
00832 //##//    mat_temp.print("mat_temp second appearence\n");
00833 //##
00834 //##   int temp_col=1;
00835 //##   int temp_row=1;
00836 //##
00837 //##    for( int row=1 ; row<=rows() ; row++ )
00838 //##      {
00839 //##        if( row!=row1 && row!=row2 )
00840 //##          {
00841 //##            temp_col=1;
00842 //##            if( temp_row==to_row )
00843 //##              {
00844 //##                temp_row++;
00845 //##              }
00846 //##
00847 //##          for( col=1 ; col<=cols() ; col++ )
00848 //##            {
00849 //##              mat_temp(temp_row,temp_col) = val(row-1,col-1);
00850 //##              temp_col++;
00851 //##            }
00852 //##            temp_row++;
00853 //##          }
00854 //##      }
00855 //##//    mat_temp.print("mat_temp third appearence\n");
00856 //##
00857 //##    return mat_temp;
00858 //##  }
00859 //##
00860 //##
00861 
00862 
00864 //The private support functions for determinant & inverse.
00865 //**************************************************************/
00866 //
00867 
00868 //#############################################################################
00869 // copy the from_col of mm to the to  col of "this"
00870 void BJmatrix::copy_column( BJmatrix & mm, int from_col, int to_col)
00871   {
00872     if( rows()!=mm.rows() )
00873       error("number of rows must be equal for copy_column()");
00874     for( int row=0 ; row<rows() ; row++ )
00875       mval( row, to_col) = mm.mval(row,from_col);
00876   }
00877 
00878 
00879 //#############################################################################
00880 void BJmatrix::switch_columns(int col1, int col2 )
00881   {
00882     int row = 0;
00883     BJmatrix temp( rows() );
00884     for( row=0 ; row<rows() ; row++ )
00885       // temporarily store col 1:
00886       temp.mval(row,0) = mval(row,col1);
00887     for( row=0 ; row<rows() ; row++ )
00888       mval(row,col1 ) = mval(row,col2); // move col2 to col1
00889     for( row=0 ; row<rows() ; row++ )
00890       mval(row,col2) = temp.mval(row,0); // move temp to col2
00891   }
00892 
00893 
00894 //#############################################################################
00895 // make an image of a BJmatrix (used in L-U decomposition)
00896 void BJmatrix::deepcopy(BJmatrix & from, BJmatrix & to)
00897   {
00898     if( from.rows()!=to.rows() || from.cols()!=to.cols() )
00899       error("matrices must be equal dimensions for deepcopy()");
00900     for( int row=0 ; row<from.rows() ; row++ )
00901       for( int col=0 ; col<from.cols() ; col++ )
00902         to.mval(row,col) = from.mval(row,col);
00903 }
00904 
00905 
00906 
00907 //#############################################################################
00908 // scale a BJmatrix (used in L-U decomposition)
00909 BJmatrix BJmatrix::scale( )
00910   {
00911 //    ::fprintf(stderr,"BJmatrix BJmatrix::scale( )\n"); 
00912     double double_eps = d_macheps();
00913     double temp;
00914     if( rows()<=0 || cols()<=0 )
00915       error("bad BJmatrix size for scale()");
00916     if( rows()!=cols() )
00917       error("BJmatrix must be square for scale()");
00918     BJmatrix scale_vector(rows());
00919     for ( int col=0 ; col<cols() ; col++ )
00920       {
00921         double maximum = 0.0;
00922         for( int row=0 ; row<rows() ; row++ )
00923           if ( (temp=(double)fabs(mval(row,col))) > maximum )
00924             maximum = temp; // find max column magnitude in this row
00925           if( fabs(maximum) <= double_eps )
00926             error("singular BJmatrix in scale()");
00927           scale_vector.mval(col,0) = 1/maximum; // save the scaling
00928       }
00929     return scale_vector;
00930   }
00931 
00932 
00933 
00934 //#############################################################################
00935 BJmatrix BJmatrix::lu_decompose(BJmatrix & indx, int & d )
00936   {
00938 // Returns the L-U decomposition of a BJmatrix. indx is an output
00939 // vector that records the row permutation effected by the
00940 // partial pivoting, d is output as +-1 depending on whether the
00941 // number of row interchanges was even or odd, respectively.
00942 // This routine is used in combination with lu_back_subst to
00943 // solve linear equations or invert a BJmatrix.
00944 //*/
00945     if( rows()!=cols() )
00946       error("Matrix must be square to L-U decompose#\n");
00947     d = 1; // parity check
00948     int row=0, col=0, k=0, col_max=0; // counters
00949     double dum=0.0; // from the book - I don't know significance (Authors remark##)
00950     double sum=0.0;
00951     double maximum=0.0;
00952     BJmatrix lu_decomp(rows(),cols());
00953  // make a direct copy of the original BJmatrix.
00954     deepcopy( *this, lu_decomp );
00955     BJmatrix scale_vector = lu_decomp.scale(); // scale the BJmatrix
00956 
00957  // The loop over columns of Crout's method:
00958     for( row=0 ; row<rows() ; row++ )
00959       {
00960         if ( row>0 )        // eqn ±.3. 1 ± except for row=col:
00961           {
00962             for ( col=0 ; col <= row-1 ; col++ )
00963               {
00964                 sum = lu_decomp.mval(row,col);
00965                 if( col > 0 )
00966                   {
00967                     for( k = 0 ; k <= col-1 ; k++ )
00968                       sum -= lu_decomp.mval(row,k)*lu_decomp.mval(k, col);
00969                     lu_decomp.mval(row,col) = sum;
00970                   }
00971               }
00972           }
00973 
00974   // Initialize for the search for the largest pivot element
00975         maximum = 0;
00976   // i=j of eq 2.3.12 & i=j+ 1.. N of 2.3.13.
00977         for( col=row ; col <= cols()-1 ; col++ )
00978           {
00979             sum = lu_decomp.mval(row,col);
00980             if( row > 0 )
00981               {
00982                 for( k=0 ; k <= row-1 ; k++ )
00983                   sum -=  lu_decomp.mval(k,col)*lu_decomp.mval(row,k);
00984                 lu_decomp.mval(row,col) = sum;
00985               }
00986    // figure of merit for pivot:
00987             dum = scale_vector.mval(col,0)*fabs(sum);
00988             if ( dum >= maximum )   // is it better than the best so far?
00989               {
00990                 col_max = col;
00991                 maximum = dum;
00992               }
00993           }
00994 
00995   // Do we need to interchange rows?
00996         if( row != col_max)
00997           {
00998             lu_decomp.switch_columns(col_max,row); // Yes, do so ...
00999             d *= -1; //... and change the parity of d
01000   // also interchange the scale factor:
01001             dum = scale_vector.mval(col_max,0);
01002             // scale_vector.mval(col_max,0) = scale_vector.mval(col,0); is wrong
01003             // Bug! busted by Frank McKenna (fmckenna@ce.berkeley.edu)  
01004 
01005             scale_vector.mval(col_max,0) = scale_vector.mval(row,0); // this is OK
01006             scale_vector.mval(row,0) = dum;
01007           }
01008 
01009         indx.mval(row,0) = col_max;
01010   // Now, finally, divide by the pivot element:
01011         if( row != rows() - 1 )
01012           {
01013             if( lu_decomp.mval(row,row) == 0 )
01014               lu_decomp.mval(row,row) = TINY;
01015        // If the pivot element is zero the BJmatrix is
01016        // singular (at least to the precision of the
01017        // algorithm).  For some applications on singular
01018        // matrices, it is desirable to substitute TINY for zero
01019 
01020             dum = 1/lu_decomp.mval(row,row);
01021 
01022             for( col=row+1 ; col <= cols()-1 ; col++ )
01023               lu_decomp.mval(row,col) *= dum;
01024 
01025           }
01026 
01027       }
01028     
01029     if( lu_decomp.mval(rows()-1, cols()-1 ) == 0 )
01030       lu_decomp.mval(rows()-1, cols()-1 ) = TINY;
01031 
01032     return lu_decomp;
01033   }
01034 
01035 
01036 
01037 
01038 //#############################################################################
01039 void BJmatrix::lu_back_subst(BJmatrix & indx, BJmatrix & b)
01040   {
01042 // Solves the set of N linear equations A*X = B.  Here "this"
01043 // is the LU-decomposition of the BJmatrix A, determined by the
01044 // routine lu_decompose(). Indx is input as the permutation
01045 // vector returned  by lu_decompose().  B is input as the
01046 // right-hand side vector B,  and returns with the solution
01047 // vector X.  This routine takes into  account the possibility
01048 // that B will begin with many zero elements,  so it is efficient
01049 // for use in BJmatrix inversion.  See pp 36-37 in
01050 // Press & Flannery.
01051 //*/
01052     if( rows() != cols() )
01053       error ("non-square lu_decomp BJmatrix in lu_back_subst()");
01054     if( rows() != b.rows() )
01055       error("wrong size B vector passed to lu_back_subst()");
01056     if( rows() != indx.rows() )
01057       error("wrong size indx vector passed to lu_back_subst()");
01058     int row, col, ll;
01059     int ii = 0;
01060     double sum;
01061     for( col=0 ; col < cols() ; col++ )
01062       {
01063         ll = (int)indx.mval(col,0);
01064         sum = b.mval(ll,0);
01065         b.mval(ll,0) = b.mval(col,0);
01066         if ( ii >= 0 )
01067           for( row = ii ; row <= col-1 ; row++ )
01068             sum -= mval(row,col)*b.mval(row,0);
01069         else if( sum != 0 )
01070         ii = col;
01071         b.mval(col,0) = sum;
01072       }
01073     for( col = cols() -1 ; col >= 0 ; col-- )
01074       {
01075         sum = b.mval(col,0);
01076         if ( col < cols() - 1 )
01077           for ( row = col + 1 ; row <= rows()-1 ; row++ )
01078         sum -= mval(row,col)*b.mval(row,0);
01079   // store a component of the soln vector X:
01080         b.mval(col,0) = sum/mval(col,col);
01081       }
01082   }
01083 
01084 
01085 
01086 //#############################################################################
01087 double & BJmatrix::mval (int row, int col) // I am still keeping mval
01088   {                                      // operator for compatibility
01089      return( this->val(row+1,col+1) );   // with old BJmatrix class members
01090   }                                      // and they start from 0 !
01091     // used by BJmatrix functions which KNOW they aren't
01092     // exceeding the boundaries
01093 
01094 // // Moved to  nDarray 14 Oct. 1996
01095 // //#############################################################################
01096 // vector BJmatrix::eigenvalues(void)
01097 //   {
01098 //     int rows = this->rows();
01099 //     int cols = this->cols();
01100 //     if ( rows != cols )
01101 //       {
01102 //         ::printf("rows!=cols in eigenvalues\n");
01103 //         ::exit(1);
01104 //       }
01105 // 
01106 //     vector EV((rows), 0.0);
01107 // 
01108 // // najbezbolinije da stvarno napravim dvodimenzioni niz pa da  ga kopiram u 'a'
01109 // // PAZI oni u NRC rade kao u FORTRANU dakle nizovi od 1 do n
01110 //     double ** a = new double *[rows+1];
01111 //     if ( !a ) {::printf("memory exhausted for **a \n"); ::exit(1);}
01112 //     for ( int i=0 ; i<(rows+1) ; i++ )
01113 //       {
01114 //         a[i] = new double[rows+1];
01115 //         if ( !a[i] ) {::printf("memory exhausted for *a \n"); ::exit(1);}
01116 //       }
01117 //     double * d = new double [rows+1];
01118 //     double * e = new double [rows+1];
01119 // 
01120 //     for ( int j=0 ; j<rows ; j++) 
01121 //       for ( int k=0 ; k<rows ; k++) 
01122 //         {
01123 //           a[j+1][k+1] = this->cval(j+1,k+1);
01124 //         }
01125 // 
01126 // 
01127 // // Householder reduction of a real symmetric BJmatrix see NRC page 373
01128 //     tred2( a, rows, d, e);
01129 // // QL algorithm with implicit shift see NRC page 380
01130 //     tqli( d, e, rows, a);
01131 // // sort eigenvalues see NRC page 366
01132 //     eigsrt( d, a, rows);
01133 // 
01134 //     for ( int l=0 ; l<rows ; l++ )
01135 //       {
01136 //         EV.val(l+1) = d[l+1];
01137 //       }
01138 // 
01139 // // delete new - ed arrays
01140 //     for ( int i1=0 ; i1<rows ; i1++ )
01141 //       {
01142 //         delete a[i1];
01143 //       }
01144 //     delete a;
01145 //     delete d;
01146 //     delete e;
01147 // 
01148 //     return EV;
01149 //   }
01150 // 
01151 // //#############################################################################
01152 // BJmatrix BJmatrix::eigenvectors(void)
01153 //   {
01154 //     int rows = this->rows();
01155 //     int cols = this->cols();
01156 //     if ( rows != cols )
01157 //       {
01158 //         ::printf("rows!=cols in eigenvectors\n");
01159 //         ::exit(1);
01160 //       }
01161 // 
01162 //     BJmatrix EV(rows, rows, 0.0);
01163 // //    BJmatrix temp( rows, rows, rows, this->data() );
01164 // 
01165 // // najbezbolinije da stvarno napravim dvodimenzioni niz pa da  ga kopiram u 'a'
01166 // // PAZI oni u NRC rade kao u FORTRANU dakle nizovi od 1 - n
01167 //     double ** a = new double *[rows+1];
01168 //     if ( !a ) {::printf("memory exhausted for **a \n"); ::exit(1);}
01169 //     for ( int i=0 ; i<(rows+1) ; i++ )
01170 //       {
01171 //         a[i] = new double[rows+1];
01172 //         if ( !a[i] ) {::printf("memory exhausted for *a \n"); ::exit(1);}
01173 //       }
01174 //     double * d = new double [rows+1];
01175 //     double * e = new double [rows+1];
01176 // 
01177 //     for ( int j=0 ; j<rows ; j++) 
01178 //       for ( int k=0 ; k<rows ; k++) 
01179 //         {
01180 //           a[j+1][k+1] = this->cval(j+1,k+1);
01181 //         }
01182 // // Householder reduction of a real symmetric BJmatrix see NRC page 373
01183 //     tred2( a, rows, d, e);
01184 // // QL algorithm with implicit shift see NRC page 380
01185 //     tqli( d, e, rows, a);
01186 // // sort eigenvalues see NRC page 366
01187 //     eigsrt( d, a, rows);
01188 // 
01189 //     for ( int l=0 ; l<rows ; l++ )
01190 //       for ( int l1=0; l1<rows ; l1++ )
01191 //         {
01192 //           EV.val(l+1,l1+1) = a[l+1][l1+1];
01193 //         }
01194 // 
01195 // // delete new - ed arrays
01196 //     for ( int i1=0 ; i1<(rows+1) ; i1++ )
01197 //       {
01198 //         delete a[i1];
01199 //       }
01200 //     delete a;
01201 //     delete d;
01202 //     delete e;
01203 // 
01204 //     return EV;
01205 //   }
01206 //
01207 
01208 
01209 // // prebacen u nDarray 14 oktobra 1996
01210 // //#############################################################################
01211 // #define SIGN(a,b) ((b)<0 ? -fabs(a) : fabs(a))
01212 // 
01213 // void BJmatrix::tqli(double * d, double * e, int n, double ** z)
01214 // {
01215 //         int m,l,iter,i,k;
01216 //         double s,r,p,g,f,dd,c,b;
01217 // //   void nrerror();
01218 // 
01219 //         for (i=2;i<=n;i++) e[i-1]=e[i];
01220 //         e[n]=0.0;
01221 //         for (l=1;l<=n;l++) {
01222 //                 iter=0;
01223 //                 do {
01224 //                         for (m=l;m<=n-1;m++) {
01225 //                                 dd=fabs(d[m])+fabs(d[m+1]);
01226 //                                 if (fabs(e[m])+dd == dd) break;
01227 //                         }
01228 //                         if (m != l) {
01229 //                                 if (iter++ == 30) { ::printf("Too many iterations in TQLI\n"); ::exit(1); }
01230 //                                 g=(d[l+1]-d[l])/(2.0*e[l]);
01231 //                                 r=sqrt((g*g)+1.0);
01232 //                                 g=d[m]-d[l]+e[l]/(g+SIGN(r,g));
01233 //                                 s=c=1.0;
01234 //                                 p=0.0;
01235 //                                 for (i=m-1;i>=l;i--) {
01236 //                                         f=s*e[i];
01237 //                                         b=c*e[i];
01238 //                                         if (fabs(f) >= fabs(g)) {
01239 //                                                 c=g/f;
01240 //                                                 r=sqrt((c*c)+1.0);
01241 //                                                 e[i+1]=f*r;
01242 //                                                 c *= (s=1.0/r);
01243 //                                         } else {
01244 //                                                 s=f/g;
01245 //                                                 r=sqrt((s*s)+1.0);
01246 //                                                 e[i+1]=g*r;
01247 //                                                 s *= (c=1.0/r);
01248 //                                         }
01249 //                                         g=d[i+1]-p;
01250 //                                         r=(d[i]-g)*s+2.0*c*b;
01251 //                                         p=s*r;
01252 //                                         d[i+1]=g+p;
01253 //                                         g=c*r-b;
01254 //                                         /* Next loop can be omitted if eigenvectors not wanted */
01255 //                                         for (k=1;k<=n;k++) {
01256 //                                                 f=z[k][i+1];
01257 //                                                 z[k][i+1]=s*z[k][i]+c*f;
01258 //                                                 z[k][i]=c*z[k][i]-s*f;
01259 //                                         }
01260 //                                 }
01261 //                                 d[l]=d[l]-p;
01262 //                                 e[l]=g;
01263 //                                 e[m]=0.0;
01264 //                         }
01265 //                 } while (m != l);
01266 //         }
01267 // }
01268 // 
01269 // 
01270 // //#############################################################################
01271 // void BJmatrix::tred2(double ** a, int n, double * d, double * e)
01272 // {
01273 //         int l,k,j,i;
01274 //         double scale,hh,h,g,f;
01275 // 
01276 //         for (i=n;i>=2;i--) {
01277 //                 l=i-1;
01278 //                 h=scale=0.0;
01279 //                 if (l > 1) {
01280 //                         for (k=1;k<=l;k++)
01281 //                                 scale += fabs(a[i][k]);
01282 //                         if (scale == 0.0)
01283 //                                 e[i]=a[i][l];
01284 //                         else {
01285 //                                 for (k=1;k<=l;k++) {
01286 //                                         a[i][k] /= scale;
01287 //                                         h += a[i][k]*a[i][k];
01288 //                                 }
01289 //                                 f=a[i][l];
01290 //                                 g = f>0 ? -sqrt(h) : sqrt(h);
01291 //                                 e[i]=scale*g;
01292 //                                 h -= f*g;
01293 //                                 a[i][l]=f-g;
01294 //                                 f=0.0;
01295 //                                 for (j=1;j<=l;j++) {
01296 //                                 /* Next statement can be omitted if eigenvectors not wanted */
01297 //                                         a[j][i]=a[i][j]/h;
01298 //                                         g=0.0;
01299 //                                         for (k=1;k<=j;k++)
01300 //                                                 g += a[j][k]*a[i][k];
01301 //                                         for (k=j+1;k<=l;k++)
01302 //                                                 g += a[k][j]*a[i][k];
01303 //                                         e[j]=g/h;
01304 //                                         f += e[j]*a[i][j];
01305 //                                 }
01306 //                                 hh=f/(h+h);
01307 //                                 for (j=1;j<=l;j++) {
01308 //                                         f=a[i][j];
01309 //                                         e[j]=g=e[j]-hh*f;
01310 //                                         for (k=1;k<=j;k++)
01311 //                                                 a[j][k] -= (f*e[k]+g*a[i][k]);
01312 //                                 }
01313 //                         }
01314 //                 } else
01315 //                         e[i]=a[i][l];
01316 //                 d[i]=h;
01317 //         }
01318 //         /* Next statement can be omitted if eigenvectors not wanted */
01319 //         d[1]=0.0;
01320 //         e[1]=0.0;
01321 //         /* Contents of this loop can be omitted if eigenvectors not
01322 //                         wanted except for statement d[i]=a[i][i]; */
01323 //         for (i=1;i<=n;i++) {
01324 //                 l=i-1;
01325 //                 if (d[i]) {
01326 //                         for (j=1;j<=l;j++) {
01327 //                                 g=0.0;
01328 //                                 for (k=1;k<=l;k++)
01329 //                                         g += a[i][k]*a[k][j];
01330 //                                 for (k=1;k<=l;k++)
01331 //                                         a[k][j] -= g*a[k][i];
01332 //                         }
01333 //                 }
01334 //                 d[i]=a[i][i];
01335 //                 a[i][i]=1.0;
01336 //                 for (j=1;j<=l;j++) a[j][i]=a[i][j]=0.0;
01337 //         }
01338 // }
01339 // 
01340 // 
01341 // 
01342 // //#############################################################################
01343 // void BJmatrix::eigsrt(double * d, double ** v, int n)
01344 // {
01345 //         int k,j,i;
01346 //         double p;
01347 // 
01348 //         for (i=1;i<n;i++) {
01349 //                 p=d[k=i];
01350 //                 for (j=i+1;j<=n;j++)
01351 //                         if (d[j] >= p) p=d[k=j];
01352 //                 if (k != i) {
01353 //                         d[k]=d[i];
01354 //                         d[i]=p;
01355 //                         for (j=1;j<=n;j++) {
01356 //                                 p=v[j][i];
01357 //                                 v[j][i]=v[j][k];
01358 //                                 v[j][k]=p;
01359 //                         }
01360 //                 }
01361 //         }
01362 // }
01363 // 
01364 
01365  
01366 // //#############################################################################
01367 double*  BJmatrix::BJmatrixtoarray(int& num)
01368   {
01369         num=pc_nDarray_rep->total_numb;
01370 /*
01371         double *data = new double [num];
01372 
01373         for(int i=0 ; i< num ; i++)
01374         {
01375            data[i]=pc_nDarray_rep->pd_nDdata[i];
01376         }
01377 
01378         return data;
01379 */
01380         return pc_nDarray_rep->pd_nDdata;
01381   }
01382 
01383 
01384 
01385 #endif 
01386 
01387 
01388 
01389 
01390 
01391 
01392 

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