1 // Created on: 1991-04-19
2 // Created by: Arnaud BOUZY
3 // Copyright (c) 1991-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #define No_Standard_RangeError
19 #define No_Standard_OutOfRange
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>
30 #include <Standard_OutOfRange.hxx>
31 #include <Standard_Type.hxx>
32 #include <TCollection_AsciiString.hxx>
33 #include <TColStd_Array1OfInteger.hxx>
35 IMPLEMENT_STANDARD_RTTIEXT(Expr_Sum,Expr_PolyExpression)
37 Expr_Sum::Expr_Sum (const Expr_SequenceOfGeneralExpression& exps)
40 Standard_Integer max = exps.Length();
41 for (i=1; i<= max; i++) {
46 Expr_Sum::Expr_Sum (const Handle(Expr_GeneralExpression)& exp1, const Handle(Expr_GeneralExpression)& exp2)
52 Handle(Expr_GeneralExpression) Expr_Sum::Copy () const
54 Expr_SequenceOfGeneralExpression ops;
56 Standard_Integer max = NbOperands();
57 for (i=1; i <= max; i++) {
58 ops.Append(Expr::CopyShare(Operand(i)));
60 return new Expr_Sum(ops);
63 Standard_Boolean Expr_Sum::IsIdentical (const Handle(Expr_GeneralExpression)& Other) const
65 if (!Other->IsKind(STANDARD_TYPE(Expr_Sum))) {
66 return Standard_False;
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;
74 Handle(Expr_GeneralExpression) myop;
75 Handle(Expr_GeneralExpression) hisop;
77 TColStd_Array1OfInteger tab(1,max);
78 for (Standard_Integer k=1; k<=max;k++) {
81 Standard_Boolean ident = Standard_True;
82 while ((i<=max) && (ident)) {
84 Standard_Boolean found = Standard_False;
86 while ((j<=max) && (!found)) {
87 hisop = SOther->Operand(j);
88 found = myop->IsIdentical(hisop);
90 found = (tab(j) == 0);
101 Standard_Boolean Expr_Sum::IsLinear () const
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();
113 Handle(Expr_GeneralExpression) Expr_Sum::Derivative (const Handle(Expr_NamedUnknown)& X) const
115 Expr_SequenceOfGeneralExpression opsder;
117 Standard_Integer max = NbOperands();
118 for (i=1; i<= max; i++) {
119 opsder.Append(Operand(i)->Derivative(X));
121 Handle(Expr_Sum) deriv = new Expr_Sum(opsder);
122 return deriv->ShallowSimplified();
125 Handle(Expr_GeneralExpression) Expr_Sum::NDerivative (const Handle(Expr_NamedUnknown)& X, const Standard_Integer N) const
128 throw Standard_OutOfRange();
130 Expr_SequenceOfGeneralExpression opsder;
132 Standard_Integer max = NbOperands();
133 for (i=1; i<= max; i++) {
134 opsder.Append(Operand(i)->NDerivative(X,N));
136 Handle(Expr_Sum) deriv = new Expr_Sum(opsder);
137 return deriv->ShallowSimplified();
140 Handle(Expr_GeneralExpression) Expr_Sum::ShallowSimplified () const
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++) {
150 subsum = op->IsKind(STANDARD_TYPE(Expr_Sum));
153 Handle(Expr_GeneralExpression) other;
154 Handle(Expr_Sum) sumop;
155 Standard_Integer nbssumop;
156 for (i=1; i<= max; 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);
170 sumop = new Expr_Sum(newops);
171 return sumop->ShallowSimplified();
173 Standard_Real vals = 0.;
174 Standard_Boolean noone = Standard_True;
175 for (i = 1; i <= max ; i++) {
177 if (op->IsKind(STANDARD_TYPE(Expr_NumericValue))) {
178 Handle(Expr_NumericValue) NVop = Handle(Expr_NumericValue)::DownCast(op);
180 noone = Standard_False;
181 vals = NVop->GetValue();
185 vals = vals + NVop->GetValue();
194 if (newops.IsEmpty()) { // result is only numericvalue (even zero)
195 return new Expr_NumericValue(vals);
199 Handle(Expr_Sum) me = this;
202 Handle(Expr_NumericValue) thevals = new Expr_NumericValue(vals);
203 newops.Append(thevals); // non-zero value added
204 return new Expr_Sum(newops);
206 if (newops.Length() == 1) {
210 return new Expr_Sum(newops);
212 Handle(Expr_Sum) me = this;
216 Standard_Real Expr_Sum::Evaluate(const Expr_Array1OfNamedUnknown& vars, const TColStd_Array1OfReal& vals) const
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);
226 TCollection_AsciiString Expr_Sum::String() const
228 Handle(Expr_GeneralExpression) op;
229 Standard_Integer nbop = NbOperands();
231 TCollection_AsciiString str;
232 if (op->NbSubExpressions() > 1) {
240 for (Standard_Integer i=2; i<=nbop; i++) {
243 if (op->NbSubExpressions() > 1) {