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