1 /* $Id$
2 *
3 * Name: sumStandardize.cpp
4 * Author: Pietro Belotti
5 * Purpose: check if expr{Group,Sum,Sub} contains a lot of quadratic/bilinear terms
6 *
7 * (C) Carnegie-Mellon University, 2007-10.
8 * This file is licensed under the Eclipse Public License (EPL)
9 */
10
11 #include <stdio.h>
12
13 #include "CouenneExprQuad.hpp"
14
15 #include "CouenneExprSum.hpp"
16 #include "CouenneExprSub.hpp"
17 #include "CouenneExprOpp.hpp"
18 #include "CouenneExprGroup.hpp"
19 #include "CouenneLQelems.hpp"
20
21 using namespace Couenne;
22
23 /// translate a sum/difference/exprOpp into:
24 ///
25 /// 1) an exprGroup, if only linear terms are present
26 /// 2) an exprQuad, if some quadratic/bilinear terms exist
27
standardize(CouenneProblem * p,bool addAux)28 exprAux *exprSum::standardize (CouenneProblem *p, bool addAux) {
29
30 // turn all elements of arglist_ and of the linear part into an exprQuad.
31 // count all potential quadratic terms for exprQuad
32
33 LinMap lmap;
34 QuadMap qmap;
35
36 int cod = code ();
37
38 CouNumber c0 = 0; // final constant term
39
40 ////////////////////////////////////////////////////////////////////////////////
41
42 // initialize linear/quad maps with the original values/indices of
43 // the linear part
44
45 if ((cod == COU_EXPRGROUP) ||
46 (cod == COU_EXPRQUAD)) { // fill linear structure
47
48 exprGroup *eg = dynamic_cast <exprGroup *> (this);
49 exprGroup::lincoeff &lcoe = eg -> lcoeff ();
50
51 c0 += eg -> getc0 ();
52
53 for (exprGroup::lincoeff::iterator el = lcoe.begin (); el != lcoe.end (); ++el)
54 lmap.insert (el -> first -> Index (), el -> second);
55
56 if (cod == COU_EXPRQUAD) { // fill quadratic structure
57
58 exprQuad *eq = dynamic_cast <exprQuad *> (this);
59 exprQuad::sparseQ &M = eq -> getQ ();
60
61 // derive quadratic part (obtain linear part)
62 for (exprQuad::sparseQ::iterator row = M.begin (); row != M.end (); ++row) {
63
64 int xind = row -> first -> Index ();
65
66 for (exprQuad::sparseQcol::iterator col = row -> second.begin ();
67 col != row -> second.end (); ++col)
68 qmap.insert (xind, col -> first -> Index (), col -> second);
69 }
70 }
71 }
72
73 ////////////////////////////////////////////////////////////////////////////////
74 //
75 // standardize all nonlinear arguments and put them into linear or
76 // quadratic form
77
78 for (int i=0; i<nargs_; i++)
79 p -> decomposeTerm (arglist_ [i], 1, c0, lmap, qmap);
80
81 ////////////////////////////////////////////////////////////////////////////////
82
83 if (p -> Jnlst () -> ProduceOutput (Ipopt::J_ALL, J_REFORMULATE)) {
84 printf ("decompTerm: lin [");
85 for (std::map <int, CouNumber>::iterator i = lmap.Map().begin (); i != lmap.Map().end (); ++i)
86 printf ("<%d,%g>", i -> first, i -> second);
87 printf ("] -- quad [");
88 for (std::map <std::pair <int, int>, CouNumber>::iterator i = qmap.Map ().begin (); i != qmap.Map ().end (); ++i)
89 printf ("<%d,%d,%g>", i -> first.first, i -> first.second, i -> second);
90 printf ("] (%g)\n", c0);
91 }
92
93 return p -> linStandardize (addAux, c0, lmap, qmap);
94 }
95
96
97 /// translate an exprOpp into:
98 ///
99 /// 1) an exprGroup, if only linear terms are present
100 /// 2) an exprQuad, if some quadratic/bilinear terms exist
101
standardize(CouenneProblem * p,bool addAux)102 exprAux *exprOpp::standardize (CouenneProblem *p, bool addAux) {
103
104 // turn all elements of arglist_ and of the linear part into an exprQuad.
105 // count all potential quadratic terms for exprQuad
106
107 LinMap lmap;
108 QuadMap qmap;
109
110 CouNumber c0 = 0; // final constant term
111
112 p -> decomposeTerm (argument_, -1., c0, lmap, qmap);
113
114 return p -> linStandardize (addAux, c0, lmap, qmap);
115 }
116
117
118 /// translate a difference (exprSub) into:
119 ///
120 /// 1) an exprGroup, if only linear terms are present
121 /// 2) an exprQuad, if some quadratic/bilinear terms exist
122
standardize(CouenneProblem * p,bool addAux)123 exprAux *exprSub::standardize (CouenneProblem *p, bool addAux) {
124
125 // turn all elements of arglist_ and of the linear part into an exprQuad.
126 // count all potential quadratic terms for exprQuad
127
128 LinMap lmap;
129 QuadMap qmap;
130
131 CouNumber c0 = 0; // final constant term
132
133 ////////////////////////////////////////////////////////////////////////////////
134
135 // standardize all nonlinear arguments and put them into linear or
136 // quadratic form
137
138 p -> decomposeTerm (arglist_ [0], 1., c0, lmap, qmap);
139 p -> decomposeTerm (arglist_ [1], -1., c0, lmap, qmap);
140
141 return p -> linStandardize (addAux, c0, lmap, qmap);
142 }
143