/home/coin/SVN-release/OS-2.4.2/Couenne/src/expression/partial/CouenneExprJac.cpp

Go to the documentation of this file.
00001 /* $Id: CouenneExprJac.cpp 716 2011-06-26 12:43:43Z pbelotti $
00002  *
00003  * Name:    CouenneExprMatr.cpp
00004  * Authors: Pietro Belotti, Lehigh University
00005  * Purpose: Implementation, matrix expressions
00006  * 
00007  * This file is licensed under the Eclipse Public License (EPL)
00008  */
00009 
00010 #include <stdio.h> // ! must go
00011 
00012 #include "CoinHelperFunctions.hpp"
00013 
00014 #include "CouenneExprJac.hpp"
00015 #include "CouenneProblem.hpp"
00016 #include "CouenneProblemElem.hpp"
00017 #include "CouenneExprAux.hpp"
00018 
00019 using namespace Couenne;
00020 
00021 //#define DEBUG
00022 
00023 // empty constructor
00024 ExprJac::ExprJac ():
00025   nnz_   (0),
00026   iRow_  (NULL),
00027   jCol_  (NULL),
00028   expr_  (NULL),
00029   nRows_ (0) {}
00030 
00031 
00032 //destructor
00033 ExprJac::~ExprJac () {
00034 
00035   if (nnz_) {
00036 
00037     free (iRow_);
00038     free (jCol_);
00039 
00040     for (int i=0; i<nnz_; i++)
00041       delete expr_ [i];
00042 
00043     free (expr_);
00044   }
00045 }
00046 
00047 // copy constructor
00048 ExprJac::ExprJac  (const ExprJac &rhs)
00049 {operator= (rhs);}
00050 
00051 
00052 // clone
00053 ExprJac *ExprJac::clone ()
00054 {return new ExprJac (*this);}
00055 
00056 
00057 // assignment
00058 ExprJac &ExprJac::operator= (const ExprJac &rhs) {
00059 
00060   nnz_   = rhs. nnz_;
00061   nRows_ = rhs. nRows_;
00062 
00063   iRow_ = (nnz_ && rhs.iRow_) ? (int *) malloc (nnz_ * sizeof (int)) : NULL;
00064   jCol_ = (nnz_ && rhs.jCol_) ? (int *) malloc (nnz_ * sizeof (int)) : NULL;
00065 
00066   CoinCopyN (rhs.iRow_, nnz_, iRow_);
00067   CoinCopyN (rhs.jCol_, nnz_, jCol_);
00068 
00069   if (nnz_) {
00070 
00071     expr_ = (expression **) malloc (nnz_ * sizeof (expression *));
00072 
00073     for (int i=0; i<nnz_; i++)
00074       expr_ [i] = expr_ [i] -> clone ();
00075 
00076   } else expr_ = NULL;
00077 
00078   return *this;
00079 }
00080 
00081 
00083 
00084 #define reallocStep 100
00085 static void reAlloc (int nCur, int &nMax, int *&r, int *&c, expression **&e) {
00086 
00087   if (nCur >= nMax) {
00088 
00089     nMax += reallocStep;
00090 
00091     r = (int         *) realloc (r, nMax * sizeof (int));
00092     c = (int         *) realloc (c, nMax * sizeof (int));
00093     e = (expression **) realloc (e, nMax * sizeof (expression *));
00094   }
00095 }
00096 
00097 // constructor
00098 ExprJac::ExprJac (CouenneProblem *p):
00099 
00100   nnz_   (0),
00101   iRow_  (NULL),
00102   jCol_  (NULL),
00103   expr_  (NULL),
00104   nRows_ (0) {
00105 
00113 
00115   int 
00116     cursize   = 0,
00117     nRealCons = 0;
00118 
00119   reAlloc (nnz_, cursize, iRow_, jCol_, expr_);
00120 
00121   // constraints ////////////////////////////////////////////////////////////
00122 
00123   for (int i = 0; i < p -> nCons (); i++) {
00124 
00125     CouenneConstraint *c = p -> Con (i);
00126 
00127     if (c -> Body () -> Type () == AUX ||
00128         c -> Body () -> Type () == VAR) 
00129       continue;
00130 
00131     // This is a constraint of the form f(x) <= 0. Find out the
00132     // variables (original or aux) it depends on, directly
00133     // (STOP_AT_AUX)
00134 
00135     std::set <int> deplist;
00136 
00137     c -> Body () -> DepList (deplist, STOP_AT_AUX);
00138 
00139     int nTerms = 0;
00140 
00141     for (std::set <int>::iterator k = deplist.begin (); k != deplist.end (); ++k) {
00142 
00143       expression 
00144         *J = c -> Body () -> differentiate (*k), // derivative of the
00145                                                  // constraint's body
00146                                                  // w.r.t. x_i
00147 
00148         *sJ = J -> simplify (),                  // a simplification
00149         *rJ = sJ ? sJ : J;                       // the real one
00150 
00151       if (sJ) 
00152         delete J; // the only remaining expression won't be wasted
00153 
00154       if ((rJ -> Type  () == CONST) &&
00155           (rJ -> Value () == 0.)) 
00156         continue;
00157 
00158       // there is a nonzero entry!
00159 
00160       reAlloc (nnz_ + 1, cursize, iRow_, jCol_, expr_);
00161 
00162       rJ -> realign (p);
00163 
00164       iRow_ [nnz_] = nRealCons;
00165       jCol_ [nnz_] = *k;
00166       expr_ [nnz_] = rJ;
00167 
00168       nnz_++;
00169       nTerms++;
00170     }
00171 
00172     if (nTerms) {
00173       ++nRealCons; // increase the counter of real constraints 
00174       ++nRows_;    // and of rows
00175     }
00176   }
00177 
00178   // auxiliaries ////////////////////////////////////////////////////////////
00179 
00181 
00182   for (int i = 0; i < p -> nVars (); i++) {
00183 
00184     exprVar *e = p -> Var (i);
00185 
00186     if ((e -> Type () != AUX) ||
00187         (e -> Multiplicity () <= 0))
00188       continue;
00189 
00190     // this is a variable definition of the form y </>/= f(x). Find
00191     // out the variables (original or aux) it depends on, directly
00192     // (STOP_AT_AUX)
00193 
00194     std::set <int> deplist;
00195 
00196     e -> Image () -> DepList (deplist, STOP_AT_AUX);
00197 
00198     deplist.insert (e -> Index ());
00199 
00200     int nTerms = 0;
00201 
00202     for (std::set <int>::iterator k = deplist.begin (); k != deplist.end (); ++k) {
00203 
00204       expression 
00205         *J = (*k == e -> Index ()) ? 
00206              new exprConst (-1.) :
00207              e -> Image () -> differentiate (*k), // derivative of the
00208                                                   // constraint's body
00209                                                   // w.r.t. x_i
00210 
00211         *sJ = J -> simplify (),                   // a simplification
00212         *rJ = sJ ? sJ : J;                        // the real one
00213 
00214       if (sJ) 
00215         delete J; // the only remaining expression won't be wasted
00216 
00217       if ((rJ -> Type  () == CONST) &&
00218           (rJ -> Value () == 0.)) 
00219         continue; 
00220 
00221       rJ -> realign (p);
00222 
00223       // there is a nonzero entry!
00224 
00225       reAlloc (nnz_ + 1, cursize, iRow_, jCol_, expr_);
00226 
00227       iRow_ [nnz_] = nRealCons;
00228       jCol_ [nnz_] = *k;
00229       expr_ [nnz_] = rJ;
00230 
00231       ++nnz_;
00232       ++nTerms;
00233     }
00234 
00235     if (nTerms) {
00236       ++nRealCons; // increase the counter of real constraints 
00237       ++nRows_;
00238     }
00239   }
00240 
00241 #ifdef DEBUG
00242   printf ("jacobian: %d nonzeros, %d rows\n", nnz_, nRows_);
00243 
00244   for (int i=0; i<nnz_; i++) {
00245 
00246     printf ("[%d,%d]: ", iRow_ [i], jCol_ [i]);
00247 
00248     fflush (stdout);
00249     expr_ [i] -> print (); 
00250     printf ("\n");
00251   }
00252 #endif
00253 }

Generated on Wed Nov 30 03:04:03 2011 by  doxygen 1.4.7