/home/coin/SVN-release/OS-2.4.0/Couenne/src/standardize/elementBreak.cpp

Go to the documentation of this file.
00001 /* $Id: elementBreak.cpp 490 2011-01-14 16:07:12Z pbelotti $ */
00002 /*
00003  * Name:    elementBreak.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: decompose element of sum if it is of the form cx or x
00006  *
00007  * (C) Carnegie-Mellon University, 2007. 
00008  * This file is licensed under the Eclipse Public License (EPL)
00009  */
00010 
00011 #include "CouenneExpression.hpp"
00012 
00013 using namespace Couenne;
00014 
00018 
00019 void elementBreak (expression *arg, int &index, CouNumber &coeff) {
00020 
00021   CouNumber oppMulCoe = 1.;
00022   bool isMul = false;
00023   index = -1;
00024 
00025   if (arg -> Linearity () <= LINEAR) { 
00026 
00027     // check if it's w, c*w, or w/c. If more complicated (sum or
00028     // subtraction) nevermind
00029 
00030     switch (arg -> code ()) { // check element of sum
00031 
00032     case COU_EXPRCONST: // it is a constant, nevermind
00033       break; 
00034 
00035     case COU_EXPRVAR: // it is a simple variable, w
00036       index = arg -> Index ();
00037       coeff = 1.;
00038       break;
00039 
00040     case COU_EXPROPP: { // it is the opposite of a simple variable or of
00041                         // another linear term
00042 
00043       index = arg -> Argument () -> Index (); 
00044       coeff = -1.;
00045 
00046       oppMulCoe = -1; // to be used below
00047       arg = arg -> Argument (); // transfer analysis to argument of exprOpp
00048 
00049       int argcode = arg -> code ();
00050 
00051       if      (argcode == COU_EXPRMUL) isMul = true;
00052       else if (argcode != COU_EXPRDIV) break;
00053     } 
00054       // no break. Bail out of switch only if this was a -w rather
00055       // than a -c*w or a -w/c
00056 
00057     case COU_EXPRMUL: 
00058       if (isMul) { 
00059 
00060       // it is c*w or w*c. Forget the case with more than two
00061       // non-constant arguments.
00062 
00063       expression **factors = arg -> ArgList ();
00064 
00065       int pos = 0;
00066 
00067       index = (*factors) -> Index ();
00068 
00069       if (index < 0) 
00070         index = factors [pos = 1] -> Index ();
00071 
00072       if ((index >= 0) && 
00073           (fabs (coeff = oppMulCoe * factors [1 - pos] -> Value ()) < COUENNE_EPS))
00074         index = -1;
00075 
00076       break;
00077     } 
00078       // no break outside, there could be some residue from case
00079       // COU_EXPROPP
00080 
00081     case COU_EXPRDIV: { // if linear, it must be of the form w/c
00082 
00083       expression **factors = arg -> ArgList ();
00084 
00085       coeff = factors [1] -> Value ();
00086       index = (*factors) -> Index ();
00087 
00088       if (fabs (coeff) < COUENNE_EPS)
00089         index = -1;
00090       else coeff = 1. / coeff;
00091 
00092     } break;
00093 
00094     default: break;
00095     }
00096   }
00097 }

Generated on Thu Sep 22 03:05:59 2011 by  doxygen 1.4.7