0022904: Clean up sccsid variables
[occt.git] / src / Expr / Expr_Difference.cxx
1 // Copyright:   Matra-Datavision 1991
2 // File:        Expr_Difference.cxx
3 // Created:     Wed Apr 17 09:32:02 1991
4 // Author:      Arnaud BOUZY
5 //              <adn>
6
7 #include <Expr_Difference.ixx>
8 #include <Expr_UnaryMinus.hxx>
9 #include <Expr_NumericValue.hxx>
10 #include <Expr_Sum.hxx>
11 #include <Expr_Operators.hxx>
12 #include <Expr.hxx>
13 #include <Standard_OutOfRange.hxx>
14
15 Expr_Difference::Expr_Difference (const Handle(Expr_GeneralExpression)& exp1, const Handle(Expr_GeneralExpression)& exp2)
16 {
17   CreateFirstOperand(exp1);
18   CreateSecondOperand(exp2);
19 }
20
21
22 Handle(Expr_GeneralExpression) Expr_Difference::ShallowSimplified() const
23 {
24   Handle(Expr_GeneralExpression) myfirst = FirstOperand();
25   Handle(Expr_GeneralExpression) mysecond = SecondOperand();
26
27   Standard_Boolean nvfirst = myfirst->IsKind(STANDARD_TYPE(Expr_NumericValue));
28   Standard_Boolean nvsecond = mysecond->IsKind(STANDARD_TYPE(Expr_NumericValue));
29   if (nvfirst && nvsecond) {
30     // case num1 - num2
31     Handle(Expr_NumericValue) myNVfirst = Handle(Expr_NumericValue)::DownCast(myfirst);
32     Handle(Expr_NumericValue) myNVsecond = Handle(Expr_NumericValue)::DownCast(mysecond);
33     return new Expr_NumericValue(myNVfirst->GetValue()-myNVsecond->GetValue());
34   }
35   if (nvfirst && !nvsecond) {
36     // case num1 - X2
37     Handle(Expr_NumericValue) myNVfirst = Handle(Expr_NumericValue)::DownCast(myfirst);
38     if (myNVfirst->GetValue() == 0.0) {
39       // case 0 - X2
40       return - mysecond;
41     }
42   }
43   if (!nvfirst && nvsecond) {
44     // case X1 - num2
45     Handle(Expr_NumericValue) myNVsecond = Handle(Expr_NumericValue)::DownCast(mysecond);
46     if (myNVsecond->GetValue() == 0.0) {
47       // case X1 - 0
48       return myfirst;
49     }
50   }
51   // Treat UnaryMinus case
52   Standard_Boolean unfirst = myfirst->IsKind(STANDARD_TYPE(Expr_UnaryMinus));
53   Standard_Boolean unsecond = mysecond->IsKind(STANDARD_TYPE(Expr_UnaryMinus));
54   if (unfirst && unsecond) {
55     // case (-ssX1) - (-ssX2) = ssX2 - ssX1
56     Handle(Expr_GeneralExpression) ssop1 = myfirst->SubExpression(1);
57     Handle(Expr_GeneralExpression) ssop2 = mysecond->SubExpression(1);
58     return ssop2 - ssop1;
59   }
60   if (unfirst && !unsecond) {
61     // case (-ssX1) - X2 = -( ssX1 + X2)
62     Handle(Expr_GeneralExpression) ssop1 = myfirst->SubExpression(1);
63     return -(ssop1 + mysecond);
64   }
65   if (!unfirst && unsecond) {
66     // case X1 - (-ssX2) = X1 + ssX2
67     Handle(Expr_GeneralExpression) ssop2 = mysecond->SubExpression(1);
68     return myfirst + ssop2;
69   }
70   Handle(Expr_Difference) me = this;
71   return me;
72 }
73
74 Handle(Expr_GeneralExpression) Expr_Difference::Copy () const
75 {
76   return Expr::CopyShare(FirstOperand()) - Expr::CopyShare(SecondOperand());
77 }
78
79 Standard_Boolean Expr_Difference::IsIdentical (const Handle(Expr_GeneralExpression)& Other) const
80 {
81   Standard_Boolean ident = Standard_False;
82   if (Other->IsKind(STANDARD_TYPE(Expr_Difference))) {
83     Handle(Expr_GeneralExpression) myfirst = FirstOperand();
84     Handle(Expr_GeneralExpression) mysecond = SecondOperand();
85     Handle(Expr_Difference) DOther = Handle(Expr_Difference)::DownCast(Other);
86     Handle(Expr_GeneralExpression) fother = DOther->FirstOperand();
87     Handle(Expr_GeneralExpression) sother = DOther->SecondOperand();
88     if ((myfirst->IsIdentical(fother)) &&
89         (mysecond->IsIdentical(sother))) {
90       ident = Standard_True;
91     }
92   }
93   return ident;
94 }
95
96 Standard_Boolean Expr_Difference::IsLinear () const
97 {
98   Handle(Expr_GeneralExpression) myfirst = FirstOperand();
99   Handle(Expr_GeneralExpression) mysecond = SecondOperand();
100   return (myfirst->IsLinear() && mysecond->IsLinear());
101 }
102
103 Handle(Expr_GeneralExpression) Expr_Difference::Derivative (const Handle(Expr_NamedUnknown)& X) const
104 {
105   if (!Contains(X)) {
106     return new Expr_NumericValue(0.0);
107   }
108   Handle(Expr_GeneralExpression) myfirst = FirstOperand();
109   Handle(Expr_GeneralExpression) mysecond = SecondOperand();
110
111   myfirst = myfirst->Derivative(X);
112   mysecond = mysecond->Derivative(X);
113   Handle(Expr_Difference) der = myfirst - mysecond;
114   return der->ShallowSimplified();
115 }
116
117 Handle(Expr_GeneralExpression) Expr_Difference::NDerivative (const Handle(Expr_NamedUnknown)& X, const Standard_Integer N) const
118 {
119   if (N <= 0) {
120     Standard_OutOfRange::Raise();
121   }
122   if (!Contains(X)) {
123     return new Expr_NumericValue(0.0);
124   }
125   Handle(Expr_GeneralExpression) myfirst = FirstOperand();
126   Handle(Expr_GeneralExpression) mysecond = SecondOperand();
127
128   myfirst = myfirst->NDerivative(X,N);
129   mysecond = mysecond->NDerivative(X,N);
130   Handle(Expr_Difference) der = myfirst - mysecond;
131   return der->ShallowSimplified();
132   
133 }
134
135
136 Standard_Real Expr_Difference::Evaluate(const Expr_Array1OfNamedUnknown& vars, const TColStd_Array1OfReal& vals) const
137 {
138   Standard_Real res = FirstOperand()->Evaluate(vars,vals);
139   return res - SecondOperand()->Evaluate(vars,vals);
140 }
141
142 TCollection_AsciiString Expr_Difference::String() const
143 {
144   Handle(Expr_GeneralExpression) op1 = FirstOperand();
145   Handle(Expr_GeneralExpression) op2 = SecondOperand();
146   TCollection_AsciiString str;
147   if (op1->NbSubExpressions() > 1) {
148     str += "(";
149     str += op1->String();
150     str += ")";
151   }
152   else {
153     str = op1->String();
154   }
155   str += "-";
156   if (op2->NbSubExpressions() > 1) {
157     str += "(";
158     str += op2->String();
159     str += ")";
160   }
161   else {
162     str += op2->String();
163   }
164   return str;
165 }