b311480e |
1 | // Created on: 1991-04-19 |
2 | // Created by: Arnaud BOUZY |
3 | // Copyright (c) 1991-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
0797d9d3 |
17 | #ifndef OCCT_DEBUG |
7fd59977 |
18 | #define No_Standard_RangeError |
19 | #define No_Standard_OutOfRange |
20 | #endif |
21 | |
42cf5bc1 |
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> |
7fd59977 |
30 | #include <Standard_OutOfRange.hxx> |
42cf5bc1 |
31 | #include <Standard_Type.hxx> |
32 | #include <TCollection_AsciiString.hxx> |
7fd59977 |
33 | #include <TColStd_Array1OfInteger.hxx> |
7fd59977 |
34 | |
92efcf78 |
35 | IMPLEMENT_STANDARD_RTTIEXT(Expr_Sum,Expr_PolyExpression) |
36 | |
7fd59977 |
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) { |
9775fa61 |
128 | throw Standard_OutOfRange(); |
7fd59977 |
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 | } |
7fd59977 |
173 | Standard_Real vals = 0.; |
7fd59977 |
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 | } |