e05ed177f03ce88a000af007207a50c2b552c8a7
[occt.git] / src / Expr / Expr_PolyFunction.cxx
1 // Copyright:   Matra-Datavision 1991
2 // File:        Expr_PolyFunction.cxx
3 // Created:     Tue Jul  2 11:11:43 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_PolyFunction.ixx>
13 #include <Expr_Array1OfNamedUnknown.hxx>
14 #include <Expr_FunctionDerivative.hxx>
15 #include <Expr_Product.hxx>
16 #include <Expr_Sum.hxx>
17 #include <Expr_Operators.hxx>
18 #include <Expr.hxx>
19 #include <Standard_DimensionError.hxx>
20
21 Expr_PolyFunction::Expr_PolyFunction (const Handle(Expr_GeneralFunction)& func, const Expr_Array1OfGeneralExpression& exps)
22 {
23   for (Standard_Integer i=exps.Lower();i <= exps.Upper(); i++) {
24     AddOperand(exps(i));
25   }
26   myFunction = func;
27 }
28
29 Handle(Expr_GeneralFunction) Expr_PolyFunction::Function () const
30 {
31   return myFunction;
32 }
33     
34 Handle(Expr_GeneralExpression) Expr_PolyFunction::ShallowSimplified () const
35 {
36   Standard_Boolean allval = Standard_True;
37   Standard_Integer max = NbSubExpressions();
38   Standard_Integer i;
39   for (i = 1; (i <= max) && allval ; i++) {
40     allval = SubExpression(i)->IsKind(STANDARD_TYPE(Expr_NumericValue));
41   }
42   if (allval) {
43     TColStd_Array1OfReal tabval(1,max);
44     Expr_Array1OfNamedUnknown tabvar(1,max);
45     for (i=1; i<=max;i++) {
46       tabval(i) = Handle(Expr_NumericValue)::DownCast(SubExpression(i))->GetValue();
47       tabvar(i) = myFunction->Variable(i);
48     }
49     Standard_Real res = myFunction->Evaluate(tabvar,tabval);
50     return new Expr_NumericValue(res);
51   }
52   Handle(Expr_PolyFunction) me =this;
53   return me;
54 }
55
56 Handle(Expr_GeneralExpression) Expr_PolyFunction::Copy () const
57 {
58   Standard_Integer max = NbSubExpressions();
59   Expr_Array1OfGeneralExpression vars(1,max);
60   for (Standard_Integer i = 1; i <= max; i++) {
61     vars(i) = Expr::CopyShare(SubExpression(i));
62   }
63   return new Expr_PolyFunction(myFunction,vars);
64 }
65
66 Standard_Boolean Expr_PolyFunction::IsIdentical (const Handle(Expr_GeneralExpression)& Other) const
67 {
68   if (!Other->IsKind(STANDARD_TYPE(Expr_PolyFunction))) {
69     return Standard_False;
70   }
71   if (Other->NbSubExpressions() != NbSubExpressions()) {
72     return Standard_False;
73   }
74   Handle(Expr_PolyFunction) pother = Handle(Expr_PolyFunction)::DownCast(Other);
75   Handle(Expr_GeneralFunction) fother = pother->Function();
76   if (!fother->IsIdentical(Function())) {
77     return Standard_False;
78   }
79   Standard_Integer max = NbSubExpressions();
80   Handle(Expr_GeneralExpression) opother;
81   for (Standard_Integer i = 1; i<=max;i++) {
82     opother = pother->SubExpression(i);
83     if (!opother->IsIdentical(SubExpression(i))) {
84       return Standard_False;
85     }
86   }
87   return Standard_True;
88 }
89
90 Standard_Boolean Expr_PolyFunction::IsLinear () const
91 {
92   if (!ContainsUnknowns()) {
93     return Standard_True;
94   }
95   for (Standard_Integer i=1; i<= NbOperands(); i++) {
96     if (!Operand(i)->IsLinear()) {
97       return Standard_False;
98     }
99     if (!myFunction->IsLinearOnVariable(i)) {
100       return Standard_False;
101     }
102   }
103   return Standard_True;
104 }
105
106 Handle(Expr_GeneralExpression) Expr_PolyFunction::Derivative (const Handle(Expr_NamedUnknown)& X) const
107 {
108   Handle(Expr_GeneralExpression) myop;
109   Handle(Expr_NamedUnknown) thevar;
110   Handle(Expr_GeneralFunction) partderfunc;
111   Handle(Expr_PolyFunction) partder;
112   Handle(Expr_Product) partprod;
113   Standard_Integer max = NbSubExpressions();
114   Expr_Array1OfGeneralExpression theops(1,max);
115   for (Standard_Integer k=1; k<= max; k++) {
116     theops(k) = Operand(k);
117   }
118   Expr_SequenceOfGeneralExpression thesum;
119   for (Standard_Integer i = 1; i <= max; i++) {
120     thevar = myFunction->Variable(i);
121     myop = SubExpression(i);
122     partderfunc = myFunction->Derivative(thevar);
123     partder = new Expr_PolyFunction(partderfunc,theops);
124     partprod = partder->ShallowSimplified() * myop->Derivative(X);
125     thesum.Append(partprod->ShallowSimplified());
126   }
127   Handle(Expr_Sum) res = new Expr_Sum(thesum);
128   return res->ShallowSimplified();
129 }
130
131
132 Standard_Real Expr_PolyFunction::Evaluate(const Expr_Array1OfNamedUnknown& vars, const TColStd_Array1OfReal& vals) const
133 {
134   Standard_Integer max = NbSubExpressions();
135   Expr_Array1OfNamedUnknown varsfunc(1,max);
136   TColStd_Array1OfReal valsfunc(1,max);
137   for (Standard_Integer i = 1; i <= max ; i++) {
138     varsfunc(i) = myFunction->Variable(i);
139     valsfunc(i) = SubExpression(i)->Evaluate(vars,vals);
140   }
141   return myFunction->Evaluate(varsfunc,valsfunc);
142 }
143
144 TCollection_AsciiString Expr_PolyFunction::String() const
145 {
146   TCollection_AsciiString res = myFunction->GetStringName();
147   res += "(";
148   Standard_Integer max = NbOperands();
149   for (Standard_Integer i=1; i<= max; i++) {
150     res += Operand(i)->String();
151     if (i != max) {
152       res += ",";
153     }
154   }
155   res += ")";
156   return res;
157 }