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