90152fc9466051618ed6b7314726710b49ab94f5
[occt.git] / src / Expr / Expr_Division.cxx
1 //static const char* sccsid = "@(#)Expr_Division.cxx    3.2 95/01/10"; // Do not delete this line. Used by sccs.
2 // Copyright:   Matra-Datavision 1991
3 // File:        Expr_Division.cxx
4 // Created:     Wed Apr 17 14:14:22 1991
5 // Author:      Arnaud BOUZY
6 //              <adn>
7
8 #include <Expr_Division.ixx>
9 #include <Expr_Product.hxx>
10 #include <Expr_Square.hxx>
11 #include <Expr_UnaryMinus.hxx>
12 #include <Expr_Difference.hxx>
13 #include <Expr_NumericValue.hxx>
14 #include <Expr_Operators.hxx>
15 #include <Expr.hxx>
16
17 Expr_Division::Expr_Division (const Handle(Expr_GeneralExpression)& exp1, const Handle(Expr_GeneralExpression)& exp2)
18 {
19   CreateFirstOperand(exp1);
20   CreateSecondOperand(exp2);
21 }
22
23 Handle(Expr_GeneralExpression) Expr_Division::Copy () const
24 {
25   return Expr::CopyShare(FirstOperand()) / Expr::CopyShare(SecondOperand());
26 }
27   
28 Standard_Boolean Expr_Division::IsIdentical (const Handle(Expr_GeneralExpression)& Other) const
29 {
30   Standard_Boolean ident = Standard_False;
31   if (Other->IsKind(STANDARD_TYPE(Expr_Division))) {
32     Handle(Expr_GeneralExpression) myfirst = FirstOperand();
33     Handle(Expr_GeneralExpression) mysecond = SecondOperand();
34     Handle(Expr_Division) DOther = Handle(Expr_Division)::DownCast(Other);
35     Handle(Expr_GeneralExpression) fother = DOther->FirstOperand();
36     Handle(Expr_GeneralExpression) sother = DOther->SecondOperand();
37     if (myfirst->IsIdentical(fother) &&
38         mysecond->IsIdentical(sother)) {
39       ident = Standard_True;
40     }
41   }
42   return ident;
43 }
44
45 Standard_Boolean Expr_Division::IsLinear () const
46 {
47   Handle(Expr_GeneralExpression) myfirst = FirstOperand();
48   Handle(Expr_GeneralExpression) mysecond = SecondOperand();
49   if (mysecond->IsKind(STANDARD_TYPE(Expr_NamedUnknown)) || mysecond->ContainsUnknowns()) {
50     return Standard_False;
51   }
52   return (myfirst->IsLinear() && mysecond->IsLinear());
53 }
54
55 Handle(Expr_GeneralExpression) Expr_Division::Derivative (const Handle(Expr_NamedUnknown)& X) const
56 {
57   if (!Contains(X)) {
58     return new Expr_NumericValue(0.0);
59   }
60   Handle(Expr_GeneralExpression) myfirst = FirstOperand();
61   Handle(Expr_GeneralExpression) mysecond = SecondOperand();
62   Handle(Expr_GeneralExpression) myfder = myfirst->Derivative(X);
63   Handle(Expr_GeneralExpression) mysder = mysecond->Derivative(X);
64
65   // "u'v"
66   Handle(Expr_Product) firstprod = myfder * Expr::CopyShare(mysecond);
67
68   Handle(Expr_GeneralExpression) firstsimp = firstprod->ShallowSimplified();
69   // "uv'"
70   Handle(Expr_Product) secondprod = Expr::CopyShare(myfirst) * mysder;
71   Handle(Expr_GeneralExpression) secondsimp = secondprod->ShallowSimplified();
72   // "u'v - uv'"
73   Handle(Expr_Difference) mynumer = firstsimp - secondsimp;
74
75   // " v2"
76   Handle(Expr_Square) mydenom = new Expr_Square(Expr::CopyShare(mysecond));
77
78   // result = "u'v-uv' / v2"
79
80   Handle(Expr_GeneralExpression) snumer = mynumer->ShallowSimplified();
81   Handle(Expr_GeneralExpression) sdenom = mydenom->ShallowSimplified();
82   Handle(Expr_Division) result = snumer / sdenom;
83
84   return result->ShallowSimplified();
85 }
86
87 Handle(Expr_GeneralExpression) Expr_Division::ShallowSimplified () const
88 {
89   Handle(Expr_GeneralExpression) myfirst = FirstOperand();
90   Handle(Expr_GeneralExpression) mysecond = SecondOperand();
91
92   if (myfirst->IsKind(STANDARD_TYPE(Expr_NumericValue))) {
93     Handle(Expr_NumericValue) myNVfirst = Handle(Expr_NumericValue)::DownCast(myfirst);
94     if (myNVfirst->GetValue() == 0.0) {
95       // case 0/X2
96       return new Expr_NumericValue(0.0);
97     }
98     if (mysecond->IsKind(STANDARD_TYPE(Expr_NumericValue))) {
99       // case num1/num2
100       Handle(Expr_NumericValue) myNVsecond = Handle(Expr_NumericValue)::DownCast(mysecond);
101       return new Expr_NumericValue(myNVfirst->GetValue()/myNVsecond->GetValue());
102     }
103   }
104   else {
105     if (mysecond->IsKind(STANDARD_TYPE(Expr_NumericValue))) {
106       // case X1/num2
107       Handle(Expr_NumericValue) myNVsecond = Handle(Expr_NumericValue)::DownCast(mysecond);
108       if (myNVsecond->GetValue() == 1.0) {
109         // case X1/1
110         return myfirst;
111       }
112     }
113   }
114   Handle(Expr_Division) me = this;
115   return me;
116 }
117
118 Standard_Real Expr_Division::Evaluate(const Expr_Array1OfNamedUnknown& vars, const TColStd_Array1OfReal& vals) const
119 {
120   Standard_Real res = FirstOperand()->Evaluate(vars,vals);
121   return res / SecondOperand()->Evaluate(vars,vals);
122 }
123
124 TCollection_AsciiString Expr_Division::String() const
125 {
126   Handle(Expr_GeneralExpression) op1 = FirstOperand();
127   Handle(Expr_GeneralExpression) op2 = SecondOperand();
128   TCollection_AsciiString str;
129   if (op1->NbSubExpressions() > 1) {
130     str = "(";
131     str += op1->String();
132     str += ")";
133   }
134   else {
135     str = op1->String();
136   }
137   str += "/";
138   if (op2->NbSubExpressions() > 1) {
139     str += "(";
140     str += op2->String();
141     str += ")";
142   }
143   else {
144     str += op2->String();
145   }
146   return str;
147 }