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