1 // Created on: 1991-04-17
2 // Created by: Arnaud BOUZY
3 // Copyright (c) 1991-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
23 #define No_Standard_RangeError
24 #define No_Standard_OutOfRange
27 #include <Expr_Product.ixx>
28 #include <TColStd_Array1OfInteger.hxx>
29 #include <Expr_Sum.hxx>
30 #include <Expr_UnaryMinus.hxx>
31 #include <Expr_NumericValue.hxx>
32 #include <Expr_Operators.hxx>
35 Expr_Product::Expr_Product (const Expr_SequenceOfGeneralExpression& exps)
38 Standard_Integer max = exps.Length();
39 for (i=1; i<= max; i++) {
44 Expr_Product::Expr_Product (const Handle(Expr_GeneralExpression)& exp1, const Handle(Expr_GeneralExpression)& exp2)
50 Handle(Expr_GeneralExpression) Expr_Product::Copy () const
53 Standard_Integer max = NbOperands();
54 Expr_SequenceOfGeneralExpression simps;
55 for (i=1; i<= max; i++) {
56 simps.Append(Expr::CopyShare(Operand(i)));
58 return new Expr_Product(simps);
61 Standard_Boolean Expr_Product::IsIdentical (const Handle(Expr_GeneralExpression)& Other) const
63 if (!Other->IsKind(STANDARD_TYPE(Expr_Product))) {
64 return Standard_False;
66 Handle(Expr_Product) me = this;
67 Handle(Expr_Product) POther = Handle(Expr_Product)::DownCast(Other);
68 Standard_Integer max = NbOperands();
69 if (POther->NbOperands() != max) {
70 return Standard_False;
72 Handle(Expr_GeneralExpression) myop;
73 Handle(Expr_GeneralExpression) hisop;
75 TColStd_Array1OfInteger tab(1,max);
76 for (Standard_Integer k=1; k<=max;k++) {
79 Standard_Boolean ident = Standard_True;
80 while ((i<=max) && (ident)) {
82 Standard_Boolean found = Standard_False;
84 while ((j<=max) && (!found)) {
85 hisop = POther->Operand(j);
86 found = myop->IsIdentical(hisop);
88 found = (tab(j) == 0);
99 Standard_Boolean Expr_Product::IsLinear () const
102 Standard_Integer max = NbOperands();
103 Standard_Boolean lin = Standard_True;
104 Standard_Boolean res = Standard_True;
105 Handle(Expr_GeneralExpression) asimp;
106 for (i=1; (i <= max) && res ; i++) {
108 if (asimp->IsKind(STANDARD_TYPE(Expr_NamedUnknown)) || asimp->ContainsUnknowns()) {
110 lin = Standard_False;
111 if (!asimp->IsLinear()) {
112 res = Standard_False;
116 res = Standard_False;
123 Handle(Expr_GeneralExpression) Expr_Product::Derivative (const Handle(Expr_NamedUnknown)& X) const
126 return new Expr_NumericValue(0.0);
128 Handle(Expr_GeneralExpression) firstop = Expr::CopyShare(Operand(1)); // U
129 Handle(Expr_GeneralExpression) tailop; // V
130 Standard_Integer nbop = NbOperands();
132 tailop = Expr::CopyShare(Operand(2));
135 Handle(Expr_Product) prodop = Expr::CopyShare(Operand(2))*Expr::CopyShare(Operand(3));
136 for (Standard_Integer i=4; i<= nbop; i++) {
137 prodop->AddOperand(Expr::CopyShare(Operand(i)));
141 Handle(Expr_GeneralExpression) firstder = firstop->Derivative(X); // U'
142 Handle(Expr_GeneralExpression) tailder = tailop->Derivative(X); // V'
144 Handle(Expr_Product) firstmember = firstop * tailder; // U*V'
146 Handle(Expr_Product) secondmember = firstder * tailop; // U'*V
148 Handle(Expr_Sum) resu = firstmember->ShallowSimplified() + secondmember->ShallowSimplified();
151 return resu->ShallowSimplified();
155 Handle(Expr_GeneralExpression) Expr_Product::ShallowSimplified () const
158 Standard_Integer max = NbOperands();
159 Handle(Expr_GeneralExpression) op;
160 Expr_SequenceOfGeneralExpression newops;
162 Standard_Real vals = 0.;
166 Standard_Integer nbvals = 0;
167 Standard_Boolean subprod = Standard_False;
168 for (i=1; (i<= max) && !subprod; i++) {
170 subprod = op->IsKind(STANDARD_TYPE(Expr_Product));
173 Handle(Expr_GeneralExpression) other;
174 Handle(Expr_Product) prodop;
175 Standard_Integer nbsprodop;
176 for (i=1; i<= max; i++) {
178 if (op->IsKind(STANDARD_TYPE(Expr_Product))) {
179 prodop = Handle(Expr_Product)::DownCast(op);
180 nbsprodop = prodop->NbOperands();
181 for (Standard_Integer j=1; j<= nbsprodop; j++) {
182 other = prodop->Operand(j);
183 newops.Append(other);
190 prodop = new Expr_Product(newops);
191 return prodop->ShallowSimplified();
194 Standard_Boolean noone = Standard_True;
195 for (i = 1; i <= max ; i++) {
197 if (op->IsKind(STANDARD_TYPE(Expr_NumericValue))) {
198 // numeric operands are cumulated separetly
199 Handle(Expr_NumericValue) NVop = Handle(Expr_NumericValue)::DownCast(op);
201 noone = Standard_False;
202 vals = NVop->GetValue();
207 vals = vals * NVop->GetValue();
215 // numeric operands encountered
216 if (newops.IsEmpty()) { // result is only numericvalue (even zero)
218 return new Expr_NumericValue(vals);
222 if (newops.Length() == 1) {
225 return new Expr_Product(newops);
228 Handle(Expr_GeneralExpression) thefact;
229 if (newops.Length() == 1) {
233 thefact = new Expr_Product(newops);
238 Handle(Expr_Product) me = this;
241 Handle(Expr_NumericValue) thevals = new Expr_NumericValue(vals);
242 newops.Append(thevals); // non-zero value added
243 return new Expr_Product(newops);
246 return new Expr_NumericValue(vals); // zero absorb
249 Handle(Expr_Product) me = this;
253 Standard_Real Expr_Product::Evaluate(const Expr_Array1OfNamedUnknown& vars, const TColStd_Array1OfReal& vals) const
255 Standard_Integer max = NbOperands();
256 Standard_Real res = 1.0;
257 for (Standard_Integer i=1;i<=max;i++) {
258 res = res * Operand(i)->Evaluate(vars,vals);
263 TCollection_AsciiString Expr_Product::String() const
265 Handle(Expr_GeneralExpression) op;
266 Standard_Integer nbop = NbOperands();
268 TCollection_AsciiString str;
269 if (op->NbSubExpressions() > 1) {
277 for (Standard_Integer i=2; i<=nbop; i++) {
280 if (op->NbSubExpressions() > 1) {