Skip to content

Commit

Permalink
- Merged TarjanTransposed and TarjanTransposedPartial
Browse files Browse the repository at this point in the history
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@25660 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
lochel committed Apr 21, 2015
1 parent aee0b0e commit bb207ee
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 154 deletions.
4 changes: 2 additions & 2 deletions Compiler/BackEnd/BackendDump.mo
Expand Up @@ -73,8 +73,8 @@ protected import GraphvizDump;
protected import Initialization;
protected import IOStream;
protected import List;
protected import Matching;
protected import SCode;
protected import Sorting;
protected import System;
protected import Util;

Expand Down Expand Up @@ -3011,7 +3011,7 @@ protected
String str;
algorithm
if i <= n then
eqns := Sorting.reachableEquations(i, mT, ass2);
eqns := Matching.reachableEquations(i, mT, ass2);
llst := List.map(eqns, List.create);
llst := List.map1(llst, List.consr, i);
slst := List.map(llst, intListStr);
Expand Down
21 changes: 21 additions & 0 deletions Compiler/BackEnd/Matching.mo
Expand Up @@ -5644,6 +5644,27 @@ end matchingExternalsetIncidenceMatrix;
//
// =============================================================================

public function reachableEquations "author: lochel
Returns a list of reachable nodes (equations), corresponding
to those equations that uses the solved variable of this equation.
The edges of the graph that identifies strong components/blocks are
dependencies between blocks. A directed edge e = (n1, n2) means
that n1 solves for a variable (e.g. \'a\') that is used in the equation
of n2, i.e. the equation of n1 must be solved before the equation of n2."
input Integer eqn;
input BackendDAE.IncidenceMatrixT mT;
input array<Integer> ass2 "var := ass2[eqn]";
output list<Integer> outEqNodes;
protected
Integer var;
list<Integer> reachable;
algorithm
var := ass2[eqn] "get the variable that is solved in given equation";
reachable := if var > 0 then mT[var] else {} "get the equations that depend on that variable";
reachable := List.select(reachable, Util.intGreaterZero) "just keep positive integers";
outEqNodes := List.removeOnTrue(eqn, intEq, reachable);
end reachableEquations;

public function isAssigned
"author: Frenkel TUD 2012-05"
input array<Integer> ass;
Expand Down
107 changes: 5 additions & 102 deletions Compiler/BackEnd/Sorting.mo
Expand Up @@ -42,6 +42,7 @@ protected import BackendDump;
protected import Debug;
protected import Error;
protected import List;
protected import Matching;
protected import Util;

public function Tarjan "author: lochel"
Expand Down Expand Up @@ -127,7 +128,8 @@ algorithm
end if;
end StrongConnect;

public function TarjanTransposed "author: lochel"
public function TarjanTransposed "author: lochel
This sorting algorithm only considers equations e with ass2[e] > 0."
input BackendDAE.IncidenceMatrixT mT;
input array<Integer> ass2 "var := ass2[eqn]";
output list<list<Integer>> outComponents = {} "eqn indices";
Expand All @@ -147,7 +149,7 @@ algorithm
onStack := arrayCreate(N, false);

for eqn in 1:N loop
if number[eqn] == -1 then
if number[eqn] == -1 and ass2[eqn] > 0 then
(S, index, outComponents) := StrongConnectTransposed(mT, ass2, eqn, S, index, number, lowlink, onStack, outComponents);
end if;
end for;
Expand Down Expand Up @@ -178,7 +180,7 @@ algorithm
outS := eqn::outS;

// Consider successors of eqn
for eqn2 in reachableEquations(eqn, mT, ass2) loop
for eqn2 in Matching.reachableEquations(eqn, mT, ass2) loop
if arrayGet(number, eqn2) == -1 then
// Successor eqn2 has not yet been visited; recurse on it
(outS, outIndex, outComponents) := StrongConnectTransposed(mT, ass2, eqn2, outS, outIndex, number, lowlink, onStack, outComponents);
Expand All @@ -203,104 +205,5 @@ algorithm
end if;
end StrongConnectTransposed;

public function TarjanTransposedPartial "author: lochel"
input BackendDAE.IncidenceMatrixT mT;
input array<Integer> ass2 "var := ass2[eqn]";
input array<Boolean> activeSet "only eqn nodes n with activeSet[n] == true are considered";
output list<list<Integer>> outComponents = {} "eqn indices";
protected
Integer index = 0;
list<Integer> S = {};

array<Integer> number, lowlink;
array<Boolean> onStack;
Integer N = arrayLength(ass2);
algorithm
//BackendDump.dumpIncidenceMatrixT(mT);
//BackendDump.dumpMatchingEqns(ass2);

number := arrayCreate(N, -1);
lowlink := arrayCreate(N, -1);
onStack := arrayCreate(N, false);

for eqn in 1:N loop
if number[eqn] == -1 and activeSet[eqn] then
(S, index, outComponents) := StrongConnectTransposedPartial(mT, ass2, activeSet, eqn, S, index, number, lowlink, onStack, outComponents);
end if;
end for;
end TarjanTransposedPartial;

protected function StrongConnectTransposedPartial "author: lochel"
input BackendDAE.IncidenceMatrixT mT;
input array<Integer> ass2 "var := ass2[eqn]";
input array<Boolean> activeSet "only eqn nodes n with activeSet[n] == true are considered";
input Integer eqn;
input list<Integer> S;
input Integer index;
input array<Integer> number;
input array<Integer> lowlink;
input array<Boolean> onStack;
input list<list<Integer>> inComponents;
output list<Integer> outS = S;
output Integer outIndex = index;
output list<list<Integer>> outComponents = inComponents;
protected
list<Integer> SCC;
Integer var, eqn2;
algorithm
// Set the depth index for eqn to the smallest unused index
arrayUpdate(number, eqn, outIndex);
arrayUpdate(lowlink, eqn, outIndex);
arrayUpdate(onStack, eqn, true);
outIndex := outIndex + 1;
outS := eqn::outS;

// Consider successors of eqn
for eqn2 in reachableEquations(eqn, mT, ass2) loop
if arrayGet(number, eqn2) == -1 and arrayGet(activeSet, eqn2) then
// Successor eqn2 has not yet been visited; recurse on it
(outS, outIndex, outComponents) := StrongConnectTransposedPartial(mT, ass2, activeSet, eqn2, outS, outIndex, number, lowlink, onStack, outComponents);
arrayUpdate(lowlink, eqn, intMin(lowlink[eqn], arrayGet(lowlink, eqn2)));
elseif arrayGet(onStack, eqn2) and arrayGet(activeSet, eqn2) then
// Successor eqn2 is in stack S and hence in the current SCC
arrayUpdate(lowlink, eqn, intMin(lowlink[eqn], arrayGet(number, eqn2)));
end if;
end for;

// If eqn is a root node, pop the stack and generate an SCC
if lowlink[eqn] == number[eqn] then
eqn2::outS := outS;
arrayUpdate(onStack, eqn2, false);
SCC := {eqn2};
while eqn <> eqn2 loop
eqn2::outS := outS;
arrayUpdate(onStack, eqn2, false);
SCC := eqn2::SCC;
end while;
outComponents := listReverse(SCC)::outComponents;
end if;
end StrongConnectTransposedPartial;

public function reachableEquations "author: PA
Returns a list of reachable nodes (equations), corresponding
to those equations that uses the solved variable of this equation.
The edges of the graph that identifies strong components/blocks are
dependencies between blocks. A directed edge e = (n1, n2) means
that n1 solves for a variable (e.g. \'a\') that is used in the equation
of n2, i.e. the equation of n1 must be solved before the equation of n2."
input Integer eqn;
input BackendDAE.IncidenceMatrixT mT;
input array<Integer> ass2 "var := ass2[eqn]";
output list<Integer> outEqNodes;
protected
Integer var;
list<Integer> reachable;
algorithm
var := ass2[eqn] "get the variable that is solved in given equation";
reachable := if var > 0 then mT[var] else {} "get the equations that depend on that variable";
reachable := List.select(reachable, Util.intGreaterZero) "just keep positive integers";
outEqNodes := List.removeOnTrue(eqn, intEq, reachable);
end reachableEquations;

annotation(__OpenModelica_Interface="backend");
end Sorting;
54 changes: 4 additions & 50 deletions Compiler/BackEnd/Tearing.mo
Expand Up @@ -320,7 +320,6 @@ protected
DAE.FunctionTree funcs;
list<Integer> asslst1, asslst2;
list<Integer> tSel_always, tSel_prefer, tSel_avoid, tSel_never;
array<Boolean> activeSet;
algorithm
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
print("\n" + BORDER + "\nBEGINNING of omcTearing\n\n");
Expand All @@ -336,9 +335,9 @@ algorithm
(subsyst,m,mt,_,_) := BackendDAEUtil.getIncidenceMatrixScalar(subsyst, BackendDAE.NORMAL(), SOME(funcs));
// DumpGraphML.dumpSystem(subsyst,ishared,NONE(),"System" + intString(size) + ".graphml");
if Flags.isSet(Flags.TEARING_DUMP) or Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
print("\n\n###BEGIN print Strong Component#####################\n(Function:omcTearing)\n");
BackendDump.printEqSystem(subsyst);
print("\n###END print Strong Component#######################\n(Function:omcTearing)\n\n\n");
print("\n\n###BEGIN print Strong Component#####################\n(Function:omcTearing)\n");
BackendDump.printEqSystem(subsyst);
print("\n###END print Strong Component#######################\n(Function:omcTearing)\n\n\n");
end if;
(me,meT,mapEqnIncRow,mapIncRowEqn) := BackendDAEUtil.getAdjacencyMatrixEnhancedScalar(subsyst,ishared,false);
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
Expand Down Expand Up @@ -398,8 +397,7 @@ algorithm
mt1 := getOtherEqSysIncidenceMatrix(mt,size,1,ass1,ass2,mt1);

// run tarjan to get order of other equations
activeSet := Matching.getAssignedArray(ass2);
othercomps := Sorting.TarjanTransposedPartial(mt1, ass2, activeSet);
othercomps := Sorting.TarjanTransposed(mt1, ass2);
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
print("\nOtherEquationsOrder:\n");
BackendDump.dumpComponentsOLD(othercomps);
Expand Down Expand Up @@ -572,27 +570,6 @@ algorithm
end matchcontinue;
end getOtherEqSysIncidenceMatrix;


protected function setIntArray "author: Frenkel TUD 2012-08"
input list<Integer> inLst;
input array<Integer> arr;
input Integer value;
output array<Integer> oarr;
algorithm
oarr := match(inLst,arr,value)
local
Integer indx;
list<Integer> rest;
case(indx::rest,_,_)
equation
arrayUpdate(arr,indx,value);
then
setIntArray(rest,arr,value);
case({},_,_) then arr;
end match;
end setIntArray;


protected function getDependenciesOfVars " function to determine which variables are influenced by the tvars"
input list<list<Integer>> iComps;
input array<Integer> ass1;
Expand Down Expand Up @@ -3427,29 +3404,6 @@ algorithm
end selectFromList_help;


protected function replaceAt "replaces entry at position in given list by given value
author:Waurich TUD 2012-11"
input Integer inElement;
input Integer inPosition;
input list<Integer> inList;
output list<Integer> outList;
algorithm
outList := match(inElement, inPosition, inList)
local
Integer e;
list<Integer> rest;
case (_,-1, _ :: _) then inList;
case (_, 0, _ :: rest) then inElement :: rest;
case (_, _, e :: rest)
equation
(inPosition >= 1) = true;
rest = replaceAt(inElement, inPosition - 1, rest);
then
e :: rest;
end match;
end replaceAt;


protected function deleteEntriesFromIncidenceMatrix "Deletes given entries from matrix. Applicable on Incidence and on transposed Incidence.
author: ptaeuber 2015-02"
input BackendDAE.IncidenceMatrix mUpdate;
Expand Down

0 comments on commit bb207ee

Please sign in to comment.