0025418: Debug output to be limited to OCC development environment
[occt.git] / src / Expr / Expr_Sum.cxx
1 // Created on: 1991-04-19
2 // Created by: Arnaud BOUZY
3 // Copyright (c) 1991-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #ifndef OCCT_DEBUG
18 #define No_Standard_RangeError
19 #define No_Standard_OutOfRange
20 #endif
21
22 #include <Expr_Sum.ixx>
23 #include <Standard_OutOfRange.hxx>
24 #include <TColStd_Array1OfInteger.hxx>
25 #include <Expr_NumericValue.hxx>
26 #include <Expr.hxx>
27
28 Expr_Sum::Expr_Sum (const Expr_SequenceOfGeneralExpression& exps)
29 {
30   Standard_Integer i;
31   Standard_Integer max = exps.Length();
32   for (i=1; i<= max; i++) {
33     AddOperand(exps(i));
34   }
35 }
36
37 Expr_Sum::Expr_Sum (const Handle(Expr_GeneralExpression)& exp1, const Handle(Expr_GeneralExpression)& exp2)
38 {
39   AddOperand(exp1);
40   AddOperand(exp2);
41 }
42
43 Handle(Expr_GeneralExpression) Expr_Sum::Copy () const
44 {
45   Expr_SequenceOfGeneralExpression ops;
46   Standard_Integer i;
47   Standard_Integer max = NbOperands();
48   for (i=1; i <= max; i++) {
49     ops.Append(Expr::CopyShare(Operand(i)));
50   }
51   return new Expr_Sum(ops);
52 }
53
54 Standard_Boolean Expr_Sum::IsIdentical (const Handle(Expr_GeneralExpression)& Other) const
55 {
56   if (!Other->IsKind(STANDARD_TYPE(Expr_Sum))) {
57     return Standard_False;
58   }
59   Handle(Expr_Sum) me = this;
60   Handle(Expr_Sum) SOther = Handle(Expr_Sum)::DownCast(Other);
61   Standard_Integer max = NbOperands();
62   if (SOther->NbOperands() != max) {
63     return Standard_False;
64   }
65   Handle(Expr_GeneralExpression) myop;
66   Handle(Expr_GeneralExpression) hisop;
67   Standard_Integer i=1;
68   TColStd_Array1OfInteger tab(1,max);
69   for (Standard_Integer k=1; k<=max;k++) {
70     tab(k)=0;
71   }
72   Standard_Boolean ident = Standard_True;
73   while ((i<=max) && (ident)) {
74     Standard_Integer j=1;
75     Standard_Boolean found = Standard_False;
76     myop = Operand(i);
77     while ((j<=max) && (!found)) {
78       hisop = SOther->Operand(j);
79       found = myop->IsIdentical(hisop);
80       if (found) {
81         found = (tab(j) == 0);
82         tab(j)=i;
83       }
84       j++;
85     }
86     ident = found;
87     i++;
88   }
89   return ident;
90 }
91
92 Standard_Boolean Expr_Sum::IsLinear () const
93 {
94   Standard_Boolean result = Standard_True;
95   Standard_Integer i=1;
96   Standard_Integer max = NbOperands();
97   while ((i <= max) && result) {
98     result = Operand(i)->IsLinear();
99     i++;
100   }
101   return result;
102 }
103
104 Handle(Expr_GeneralExpression) Expr_Sum::Derivative (const Handle(Expr_NamedUnknown)& X) const
105 {
106   Expr_SequenceOfGeneralExpression opsder;
107   Standard_Integer i;
108   Standard_Integer max = NbOperands();
109   for (i=1; i<= max; i++) {
110     opsder.Append(Operand(i)->Derivative(X));
111   }
112   Handle(Expr_Sum) deriv = new Expr_Sum(opsder);
113   return deriv->ShallowSimplified();
114 }
115
116 Handle(Expr_GeneralExpression) Expr_Sum::NDerivative (const Handle(Expr_NamedUnknown)& X, const Standard_Integer N) const
117 {
118   if (N <= 0) {
119     Standard_OutOfRange::Raise();
120   }
121   Expr_SequenceOfGeneralExpression opsder;
122   Standard_Integer i;
123   Standard_Integer max = NbOperands();
124   for (i=1; i<= max; i++) {
125     opsder.Append(Operand(i)->NDerivative(X,N));
126   }
127   Handle(Expr_Sum) deriv = new Expr_Sum(opsder);
128   return deriv->ShallowSimplified();
129 }
130
131 Handle(Expr_GeneralExpression) Expr_Sum::ShallowSimplified () const
132 {
133   Standard_Integer i;
134   Standard_Integer max = NbOperands();
135   Standard_Integer nbvals =0;
136   Handle(Expr_GeneralExpression) op;
137   Expr_SequenceOfGeneralExpression newops;
138   Standard_Boolean subsum = Standard_False;
139   for (i=1; (i<= max) && !subsum; i++) {
140     op = Operand(i);
141     subsum = op->IsKind(STANDARD_TYPE(Expr_Sum));
142   }
143   if (subsum) {
144     Handle(Expr_GeneralExpression) other;
145     Handle(Expr_Sum) sumop;
146     Standard_Integer nbssumop;
147     for (i=1; i<= max; i++) {
148       op = Operand(i);
149       if (op->IsKind(STANDARD_TYPE(Expr_Sum))) {
150         sumop = Handle(Expr_Sum)::DownCast(op);
151         nbssumop = sumop->NbOperands();
152         for (Standard_Integer j=1; j<= nbssumop; j++) {
153           other = sumop->Operand(j);
154           newops.Append(other);
155         }
156       }
157       else {
158         newops.Append(op);
159       }
160     }
161     sumop = new Expr_Sum(newops);
162     return sumop->ShallowSimplified();
163   }
164   Standard_Real vals = 0.;
165   Standard_Boolean noone = Standard_True;
166   for (i = 1; i <= max ; i++) {
167     op = Operand(i);
168     if (op->IsKind(STANDARD_TYPE(Expr_NumericValue))) {
169       Handle(Expr_NumericValue) NVop = Handle(Expr_NumericValue)::DownCast(op);
170       if (nbvals == 0) {
171         noone = Standard_False;
172         vals = NVop->GetValue();
173         nbvals = 1;
174       }
175       else {
176         vals = vals + NVop->GetValue();
177         nbvals++;
178       }
179     }
180     else {
181       newops.Append(op);
182     }
183   }
184   if (!noone) {
185     if (newops.IsEmpty()) {         // result is only numericvalue (even zero)
186       return new Expr_NumericValue(vals); 
187     }
188     if (vals != 0.0) {
189       if (nbvals == 1) {
190         Handle(Expr_Sum) me = this;
191         return me;
192       }
193       Handle(Expr_NumericValue) thevals = new Expr_NumericValue(vals);
194       newops.Append(thevals);  // non-zero value added
195       return new Expr_Sum(newops);
196     }
197     if (newops.Length() == 1) {
198       // case X + 0
199       return newops(1);
200     }
201     return new Expr_Sum(newops);
202   }
203   Handle(Expr_Sum) me = this;
204   return me;
205 }
206
207 Standard_Real Expr_Sum::Evaluate(const Expr_Array1OfNamedUnknown& vars, const TColStd_Array1OfReal& vals) const
208 {
209   Standard_Integer max = NbOperands();
210   Standard_Real res = 0.0;
211   for (Standard_Integer i=1; i<= max; i++) {
212     res = res + Operand(i)->Evaluate(vars,vals);
213   }
214   return res;
215 }
216
217 TCollection_AsciiString Expr_Sum::String() const
218 {
219   Handle(Expr_GeneralExpression) op;
220   Standard_Integer nbop = NbOperands();
221   op = Operand(1);
222   TCollection_AsciiString str;
223   if (op->NbSubExpressions() > 1) {
224     str = "(";
225     str += op->String();
226     str += ")";;
227   }
228   else {
229     str = op->String();
230   }
231   for (Standard_Integer i=2; i<=nbop; i++) {
232     str += "+";
233     op = Operand(i);
234     if (op->NbSubExpressions() > 1) {
235       str += "(";
236       str += op->String();
237       str += ")";;
238     }
239     else {
240       str += op->String();
241     }
242   }
243   return str;
244 }