0031007: Coding - eliminate warnings issued while compiling with -pedantic flag
[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
23 #include <Expr.hxx>
24 #include <Expr_GeneralExpression.hxx>
25 #include <Expr_NamedUnknown.hxx>
26 #include <Expr_NotEvaluable.hxx>
27 #include <Expr_NumericValue.hxx>
28 #include <Expr_Sum.hxx>
29 #include <Standard_NumericError.hxx>
30 #include <Standard_OutOfRange.hxx>
31 #include <Standard_Type.hxx>
32 #include <TCollection_AsciiString.hxx>
33 #include <TColStd_Array1OfInteger.hxx>
34
35 IMPLEMENT_STANDARD_RTTIEXT(Expr_Sum,Expr_PolyExpression)
36
37 Expr_Sum::Expr_Sum (const Expr_SequenceOfGeneralExpression& exps)
38 {
39   Standard_Integer i;
40   Standard_Integer max = exps.Length();
41   for (i=1; i<= max; i++) {
42     AddOperand(exps(i));
43   }
44 }
45
46 Expr_Sum::Expr_Sum (const Handle(Expr_GeneralExpression)& exp1, const Handle(Expr_GeneralExpression)& exp2)
47 {
48   AddOperand(exp1);
49   AddOperand(exp2);
50 }
51
52 Handle(Expr_GeneralExpression) Expr_Sum::Copy () const
53 {
54   Expr_SequenceOfGeneralExpression ops;
55   Standard_Integer i;
56   Standard_Integer max = NbOperands();
57   for (i=1; i <= max; i++) {
58     ops.Append(Expr::CopyShare(Operand(i)));
59   }
60   return new Expr_Sum(ops);
61 }
62
63 Standard_Boolean Expr_Sum::IsIdentical (const Handle(Expr_GeneralExpression)& Other) const
64 {
65   if (!Other->IsKind(STANDARD_TYPE(Expr_Sum))) {
66     return Standard_False;
67   }
68   Handle(Expr_Sum) me = this;
69   Handle(Expr_Sum) SOther = Handle(Expr_Sum)::DownCast(Other);
70   Standard_Integer max = NbOperands();
71   if (SOther->NbOperands() != max) {
72     return Standard_False;
73   }
74   Handle(Expr_GeneralExpression) myop;
75   Handle(Expr_GeneralExpression) hisop;
76   Standard_Integer i=1;
77   TColStd_Array1OfInteger tab(1,max);
78   for (Standard_Integer k=1; k<=max;k++) {
79     tab(k)=0;
80   }
81   Standard_Boolean ident = Standard_True;
82   while ((i<=max) && (ident)) {
83     Standard_Integer j=1;
84     Standard_Boolean found = Standard_False;
85     myop = Operand(i);
86     while ((j<=max) && (!found)) {
87       hisop = SOther->Operand(j);
88       found = myop->IsIdentical(hisop);
89       if (found) {
90         found = (tab(j) == 0);
91         tab(j)=i;
92       }
93       j++;
94     }
95     ident = found;
96     i++;
97   }
98   return ident;
99 }
100
101 Standard_Boolean Expr_Sum::IsLinear () const
102 {
103   Standard_Boolean result = Standard_True;
104   Standard_Integer i=1;
105   Standard_Integer max = NbOperands();
106   while ((i <= max) && result) {
107     result = Operand(i)->IsLinear();
108     i++;
109   }
110   return result;
111 }
112
113 Handle(Expr_GeneralExpression) Expr_Sum::Derivative (const Handle(Expr_NamedUnknown)& X) const
114 {
115   Expr_SequenceOfGeneralExpression opsder;
116   Standard_Integer i;
117   Standard_Integer max = NbOperands();
118   for (i=1; i<= max; i++) {
119     opsder.Append(Operand(i)->Derivative(X));
120   }
121   Handle(Expr_Sum) deriv = new Expr_Sum(opsder);
122   return deriv->ShallowSimplified();
123 }
124
125 Handle(Expr_GeneralExpression) Expr_Sum::NDerivative (const Handle(Expr_NamedUnknown)& X, const Standard_Integer N) const
126 {
127   if (N <= 0) {
128     throw Standard_OutOfRange();
129   }
130   Expr_SequenceOfGeneralExpression opsder;
131   Standard_Integer i;
132   Standard_Integer max = NbOperands();
133   for (i=1; i<= max; i++) {
134     opsder.Append(Operand(i)->NDerivative(X,N));
135   }
136   Handle(Expr_Sum) deriv = new Expr_Sum(opsder);
137   return deriv->ShallowSimplified();
138 }
139
140 Handle(Expr_GeneralExpression) Expr_Sum::ShallowSimplified () const
141 {
142   Standard_Integer i;
143   Standard_Integer max = NbOperands();
144   Standard_Integer nbvals =0;
145   Handle(Expr_GeneralExpression) op;
146   Expr_SequenceOfGeneralExpression newops;
147   Standard_Boolean subsum = Standard_False;
148   for (i=1; (i<= max) && !subsum; i++) {
149     op = Operand(i);
150     subsum = op->IsKind(STANDARD_TYPE(Expr_Sum));
151   }
152   if (subsum) {
153     Handle(Expr_GeneralExpression) other;
154     Handle(Expr_Sum) sumop;
155     Standard_Integer nbssumop;
156     for (i=1; i<= max; i++) {
157       op = Operand(i);
158       if (op->IsKind(STANDARD_TYPE(Expr_Sum))) {
159         sumop = Handle(Expr_Sum)::DownCast(op);
160         nbssumop = sumop->NbOperands();
161         for (Standard_Integer j=1; j<= nbssumop; j++) {
162           other = sumop->Operand(j);
163           newops.Append(other);
164         }
165       }
166       else {
167         newops.Append(op);
168       }
169     }
170     sumop = new Expr_Sum(newops);
171     return sumop->ShallowSimplified();
172   }
173   Standard_Real vals = 0.;
174   Standard_Boolean noone = Standard_True;
175   for (i = 1; i <= max ; i++) {
176     op = Operand(i);
177     if (op->IsKind(STANDARD_TYPE(Expr_NumericValue))) {
178       Handle(Expr_NumericValue) NVop = Handle(Expr_NumericValue)::DownCast(op);
179       if (nbvals == 0) {
180         noone = Standard_False;
181         vals = NVop->GetValue();
182         nbvals = 1;
183       }
184       else {
185         vals = vals + NVop->GetValue();
186         nbvals++;
187       }
188     }
189     else {
190       newops.Append(op);
191     }
192   }
193   if (!noone) {
194     if (newops.IsEmpty()) {         // result is only numericvalue (even zero)
195       return new Expr_NumericValue(vals); 
196     }
197     if (vals != 0.0) {
198       if (nbvals == 1) {
199         Handle(Expr_Sum) me = this;
200         return me;
201       }
202       Handle(Expr_NumericValue) thevals = new Expr_NumericValue(vals);
203       newops.Append(thevals);  // non-zero value added
204       return new Expr_Sum(newops);
205     }
206     if (newops.Length() == 1) {
207       // case X + 0
208       return newops(1);
209     }
210     return new Expr_Sum(newops);
211   }
212   Handle(Expr_Sum) me = this;
213   return me;
214 }
215
216 Standard_Real Expr_Sum::Evaluate(const Expr_Array1OfNamedUnknown& vars, const TColStd_Array1OfReal& vals) const
217 {
218   Standard_Integer max = NbOperands();
219   Standard_Real res = 0.0;
220   for (Standard_Integer i=1; i<= max; i++) {
221     res = res + Operand(i)->Evaluate(vars,vals);
222   }
223   return res;
224 }
225
226 TCollection_AsciiString Expr_Sum::String() const
227 {
228   Handle(Expr_GeneralExpression) op;
229   Standard_Integer nbop = NbOperands();
230   op = Operand(1);
231   TCollection_AsciiString str;
232   if (op->NbSubExpressions() > 1) {
233     str = "(";
234     str += op->String();
235     str += ")";
236   }
237   else {
238     str = op->String();
239   }
240   for (Standard_Integer i=2; i<=nbop; i++) {
241     str += "+";
242     op = Operand(i);
243     if (op->NbSubExpressions() > 1) {
244       str += "(";
245       str += op->String();
246       str += ")";
247     }
248     else {
249       str += op->String();
250     }
251   }
252   return str;
253 }