1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-05-01 10:26:12 +03:00
occt/src/Expr/Expr_Product.cxx
abv 0797d9d30a 0025418: Debug output to be limited to OCC development environment
Macros ending on "DEB" are replaced by OCCT_DEBUG across OCCT code; new macros described in documentation.
Macros starting with DEB are changed to start with "OCCT_DEBUG_".
Some code cleaned.
2014-11-05 16:55:24 +03:00

282 lines
7.4 KiB
C++

// Created on: 1991-04-17
// Created by: Arnaud BOUZY
// Copyright (c) 1991-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef OCCT_DEBUG
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#endif
#include <Expr_Product.ixx>
#include <TColStd_Array1OfInteger.hxx>
#include <Expr_Sum.hxx>
#include <Expr_UnaryMinus.hxx>
#include <Expr_NumericValue.hxx>
#include <Expr_Operators.hxx>
#include <Expr.hxx>
Expr_Product::Expr_Product (const Expr_SequenceOfGeneralExpression& exps)
{
Standard_Integer i;
Standard_Integer max = exps.Length();
for (i=1; i<= max; i++) {
AddOperand(exps(i));
}
}
Expr_Product::Expr_Product (const Handle(Expr_GeneralExpression)& exp1, const Handle(Expr_GeneralExpression)& exp2)
{
AddOperand(exp1);
AddOperand(exp2);
}
Handle(Expr_GeneralExpression) Expr_Product::Copy () const
{
Standard_Integer i;
Standard_Integer max = NbOperands();
Expr_SequenceOfGeneralExpression simps;
for (i=1; i<= max; i++) {
simps.Append(Expr::CopyShare(Operand(i)));
}
return new Expr_Product(simps);
}
Standard_Boolean Expr_Product::IsIdentical (const Handle(Expr_GeneralExpression)& Other) const
{
if (!Other->IsKind(STANDARD_TYPE(Expr_Product))) {
return Standard_False;
}
Handle(Expr_Product) me = this;
Handle(Expr_Product) POther = Handle(Expr_Product)::DownCast(Other);
Standard_Integer max = NbOperands();
if (POther->NbOperands() != max) {
return Standard_False;
}
Handle(Expr_GeneralExpression) myop;
Handle(Expr_GeneralExpression) hisop;
Standard_Integer i=1;
TColStd_Array1OfInteger tab(1,max);
for (Standard_Integer k=1; k<=max;k++) {
tab(k)=0;
}
Standard_Boolean ident = Standard_True;
while ((i<=max) && (ident)) {
Standard_Integer j=1;
Standard_Boolean found = Standard_False;
myop = Operand(i);
while ((j<=max) && (!found)) {
hisop = POther->Operand(j);
found = myop->IsIdentical(hisop);
if (found) {
found = (tab(j) == 0);
tab(j)=i;
}
j++;
}
ident = found;
i++;
}
return ident;
}
Standard_Boolean Expr_Product::IsLinear () const
{
Standard_Integer i;
Standard_Integer max = NbOperands();
Standard_Boolean lin = Standard_True;
Standard_Boolean res = Standard_True;
Handle(Expr_GeneralExpression) asimp;
for (i=1; (i <= max) && res ; i++) {
asimp = Operand(i);
if (asimp->IsKind(STANDARD_TYPE(Expr_NamedUnknown)) || asimp->ContainsUnknowns()) {
if (lin) {
lin = Standard_False;
if (!asimp->IsLinear()) {
res = Standard_False;
}
}
else {
res = Standard_False;
}
}
}
return res;
}
Handle(Expr_GeneralExpression) Expr_Product::Derivative (const Handle(Expr_NamedUnknown)& X) const
{
if (!Contains(X)) {
return new Expr_NumericValue(0.0);
}
Handle(Expr_GeneralExpression) firstop = Expr::CopyShare(Operand(1)); // U
Handle(Expr_GeneralExpression) tailop; // V
Standard_Integer nbop = NbOperands();
if (nbop == 2) {
tailop = Expr::CopyShare(Operand(2));
}
else {
Handle(Expr_Product) prodop = Expr::CopyShare(Operand(2))*Expr::CopyShare(Operand(3));
for (Standard_Integer i=4; i<= nbop; i++) {
prodop->AddOperand(Expr::CopyShare(Operand(i)));
}
tailop = prodop;
}
Handle(Expr_GeneralExpression) firstder = firstop->Derivative(X); // U'
Handle(Expr_GeneralExpression) tailder = tailop->Derivative(X); // V'
Handle(Expr_Product) firstmember = firstop * tailder; // U*V'
Handle(Expr_Product) secondmember = firstder * tailop; // U'*V
Handle(Expr_Sum) resu = firstmember->ShallowSimplified() + secondmember->ShallowSimplified();
// U*V' + U'*V
return resu->ShallowSimplified();
}
Handle(Expr_GeneralExpression) Expr_Product::ShallowSimplified () const
{
Standard_Integer i;
Standard_Integer max = NbOperands();
Handle(Expr_GeneralExpression) op;
Expr_SequenceOfGeneralExpression newops;
Standard_Real vals = 0.;
Standard_Integer nbvals = 0;
Standard_Boolean subprod = Standard_False;
for (i=1; (i<= max) && !subprod; i++) {
op = Operand(i);
subprod = op->IsKind(STANDARD_TYPE(Expr_Product));
}
if (subprod) {
Handle(Expr_GeneralExpression) other;
Handle(Expr_Product) prodop;
Standard_Integer nbsprodop;
for (i=1; i<= max; i++) {
op = Operand(i);
if (op->IsKind(STANDARD_TYPE(Expr_Product))) {
prodop = Handle(Expr_Product)::DownCast(op);
nbsprodop = prodop->NbOperands();
for (Standard_Integer j=1; j<= nbsprodop; j++) {
other = prodop->Operand(j);
newops.Append(other);
}
}
else {
newops.Append(op);
}
}
prodop = new Expr_Product(newops);
return prodop->ShallowSimplified();
}
Standard_Boolean noone = Standard_True;
for (i = 1; i <= max ; i++) {
op = Operand(i);
if (op->IsKind(STANDARD_TYPE(Expr_NumericValue))) {
// numeric operands are cumulated separetly
Handle(Expr_NumericValue) NVop = Handle(Expr_NumericValue)::DownCast(op);
if (nbvals == 0) {
noone = Standard_False;
vals = NVop->GetValue();
nbvals =1;
}
else {
nbvals++;
vals = vals * NVop->GetValue();
}
}
else {
newops.Append(op);
}
}
if (!noone) {
// numeric operands encountered
if (newops.IsEmpty()) { // result is only numericvalue (even zero)
// only numerics
return new Expr_NumericValue(vals);
}
if (vals != 0.0) {
if (vals == 1.0) {
if (newops.Length() == 1) {
return newops(1);
}
return new Expr_Product(newops);
}
if (vals == -1.0) {
Handle(Expr_GeneralExpression) thefact;
if (newops.Length() == 1) {
thefact = newops(1);
}
else {
thefact = new Expr_Product(newops);
}
return -(thefact);
}
if (nbvals == 1) {
Handle(Expr_Product) me = this;
return me;
}
Handle(Expr_NumericValue) thevals = new Expr_NumericValue(vals);
newops.Append(thevals); // non-zero value added
return new Expr_Product(newops);
}
else {
return new Expr_NumericValue(vals); // zero absorb
}
}
Handle(Expr_Product) me = this;
return me;
}
Standard_Real Expr_Product::Evaluate(const Expr_Array1OfNamedUnknown& vars, const TColStd_Array1OfReal& vals) const
{
Standard_Integer max = NbOperands();
Standard_Real res = 1.0;
for (Standard_Integer i=1;i<=max;i++) {
res = res * Operand(i)->Evaluate(vars,vals);
}
return res;
}
TCollection_AsciiString Expr_Product::String() const
{
Handle(Expr_GeneralExpression) op;
Standard_Integer nbop = NbOperands();
op = Operand(1);
TCollection_AsciiString str;
if (op->NbSubExpressions() > 1) {
str = "(";
str += op->String();
str += ")";
}
else {
str = op->String();
}
for (Standard_Integer i=2; i<=nbop; i++) {
str += "*";
op = Operand(i);
if (op->NbSubExpressions() > 1) {
str += "(";
str += op->String();
str += ")";
}
else {
str += op->String();
}
}
return str;
}