Skip to content

Commit

Permalink
ExpressionSolve:
Browse files Browse the repository at this point in the history
improved numeric for makeProduct


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@23777 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
Vitalij Ruge committed Dec 14, 2014
1 parent c9615a7 commit cad9e5c
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 14 deletions.
62 changes: 48 additions & 14 deletions Compiler/BackEnd/ExpressionSolve.mo
Expand Up @@ -554,8 +554,8 @@ algorithm

eWithX = Expression.expandFactors(inExp1);
(factorWithX, factorWithoutX) = List.split1OnTrue(eWithX, expHasCref, inExp3);
pWithX = makeProductLstIf(factorWithX);
pWithoutX = makeProductLstIf(factorWithoutX);
pWithX = makeProductLstSort(factorWithX);
pWithoutX = makeProductLstSort(factorWithoutX);

e = Expression.makeDiv(rhs, pWithoutX);

Expand Down Expand Up @@ -878,13 +878,13 @@ algorithm

f1 := Expression.expandFactors(e1);
(factorWithX1, factorWithoutX1) := List.split1OnTrue(f1, expHasCref, inExp3);
pWithX1 := makeProductLstIf(factorWithX1);
pWithoutX1 := makeProductLstIf(factorWithoutX1);
pWithX1 := makeProductLstSort(factorWithX1);
pWithoutX1 := makeProductLstSort(factorWithoutX1);

f2 := Expression.expandFactors(inExp2);
(factorWithX2, factorWithoutX2) := List.split1OnTrue(f2, expHasCref, inExp3);
(pWithX2,_) := ExpressionSimplify.simplify1(makeProductLstIf(factorWithX2));
pWithoutX2 := makeProductLstIf(factorWithoutX2);
(pWithX2,_) := ExpressionSimplify.simplify1(makeProductLstSort(factorWithX2));
pWithoutX2 := makeProductLstSort(factorWithoutX2);
//print("\nf1 =");print(ExpressionDump.printExpListStr(f1));
//print("\nf2 =");print(ExpressionDump.printExpListStr(f2));

Expand Down Expand Up @@ -1041,8 +1041,6 @@ protected function unifyFunCallsWork
end unifyFunCallsWork;




protected function solveFunCalls
"
- inline modelica functions
Expand Down Expand Up @@ -1498,7 +1496,7 @@ protected function isCrefInIFEXPwork " helper for isCrefInIFEXP"
end match;
end isCrefInIFEXPwork;

protected function makeProductLstIf
protected function makeProductLstSort
"Takes a list of expressions an makes a product
expression multiplying all elements in the list.

Expand All @@ -1509,29 +1507,65 @@ protected function makeProductLstIf
output DAE.Exp outExp;
protected
DAE.Type tp;
list<DAE.Exp> expLstDiv, expLst, expLst2;
DAE.Exp e, e1, e2;
DAE.Operator op;
algorithm
if List.isEmpty(inExpLst) then
outExp := DAE.RCONST(1.0);
return;
end if;

tp := Expression.typeof(listGet(inExpLst,1));
outExp := Expression.makeConstOne(tp);

for elem in inExpLst loop
(expLstDiv, expLst) := List.splitOnTrue(inExpLst, Expression.isDivBinary);
outExp := makeProductLstSort2(expLst, tp);
if not List.isEmpty(expLstDiv) then
expLst2 := {};
expLst := {};

for elem in expLstDiv loop
DAE.BINARY(e1,op,e2) := elem;
expLst := e1::expLst;
expLst2 := e2::expLst2;
end for;

if not List.isEmpty(expLst2) then
e := makeProductLstSort(expLst2);
if not Expression.isOne(e) then
outExp := Expression.makeDiv(outExp,e);
end if;
end if;

if not List.isEmpty(expLst) then
e := makeProductLstSort(expLst);
outExp := Expression.expMul(outExp,e);
end if;

end if;

end makeProductLstSort;

protected function makeProductLstSort2
input list<DAE.Exp> inExpLst;
input DAE.Type tp;
output DAE.Exp outExp := Expression.makeConstOne(tp);
protected
list<DAE.Exp> rest;
algorithm
rest := ExpressionSimplify.simplifyList(inExpLst, {});
for elem in rest loop
if not Expression.isOne(elem) then
outExp := match(elem)
local DAE.Exp e1,e2,e3;
case(DAE.IFEXP(e1,e2,e3))
then DAE.IFEXP(e1, Expression.expMul(outExp,e2), Expression.expMul(outExp,e3));
case(DAE.BINARY(e1,DAE.DIV(),e2)) then Expression.makeDiv(Expression.expMul(outExp,e1),e2);
else Expression.expMul(outExp, elem);
end match;
end if;
end for;

end makeProductLstIf;

end makeProductLstSort2;

annotation(__OpenModelica_Interface="backend");
end ExpressionSolve;
12 changes: 12 additions & 0 deletions Compiler/FrontEnd/Expression.mo
Expand Up @@ -7175,6 +7175,18 @@ algorithm
end match;
end isDiv;

public function isDivBinary "returns true if BINARY is a/b"
input DAE.Exp iExp;
output Boolean res;
protected
DAE.Operator op;
algorithm
res := match(iExp)
case(DAE.BINARY(_,op,_)) then isDiv(op);
else false;
end match;
end isDivBinary;

public function isFunCall "return true if expression is DAE.CALL(path=Absyn.IDENT(name))"
input DAE.Exp iExp;
input String name;
Expand Down

0 comments on commit cad9e5c

Please sign in to comment.