Skip to content

Commit

Permalink
[BE] fix jacobian array differentiation (#7771)
Browse files Browse the repository at this point in the history
* [BE] fix jacobian array differentiation

 - fixes ticket #7550
 - problem: differentiation of arrays that have iteration as well as inner variables
 - old behavior: if any of them is an iteration variable, the whole array cref is assumed to be
 - new behavior: if it contains both, it is scalarized and treated individually (just the cref!)
 - remaining issues: just works for vectors, higher dimension tensors will throw an error

* [BE] follow up 7550 fix

 - also handle tensors by threading the crefs correctly into old structure
  • Loading branch information
kabdelhak committed Aug 17, 2021
1 parent 328b4a8 commit 1f63944
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 8 deletions.
29 changes: 22 additions & 7 deletions OMCompiler/Compiler/BackEnd/Differentiate.mo
Original file line number Diff line number Diff line change
Expand Up @@ -1079,16 +1079,16 @@ algorithm
BackendDAE.Var var;
BackendDAE.VarKind kind;

list<BackendDAE.Var> vars;
list<BackendDAE.Var> vars, scalarLst;
DAE.Type tp, arrayType;
DAE.Exp e, e1, zero, one;
DAE.Exp res, res1;
DAE.ComponentRef cr, cr1;
list<DAE.Exp> expl, expl_1;
list<DAE.Exp> expl, expl_1, diffed_exps = {};

list<DAE.Var> varLst;
list<Boolean> b_lst;
list<DAE.ComponentRef> crefs, diffCref;
list<DAE.ComponentRef> crefs, diffCref, scalarCrefs;

String s1, s2, serr, se1, matrixName;

Expand Down Expand Up @@ -1245,12 +1245,27 @@ algorithm

// d(x)/d(x) => generate seed variables
case ((DAE.CREF(componentRef = cr,ty = tp)), _, BackendDAE.DIFFINPUTDATA(independenentVars=SOME(timevars),matrixName=SOME(matrixName)), BackendDAE.GENERIC_GRADIENT(), _)
equation
algorithm
//true = List.isMemberOnTrue(cr, diffCref, ComponentReference.crefEqual);
(_::_, _) = BackendVariable.getVar(cr, timevars);
cr = createSeedCrefName(cr, matrixName);
(scalarLst, _) := BackendVariable.getVar(cr, timevars);
// fix for ticket #7550
// if not all elements (but some of them) are iteration variables
// we scalarize the cref and treat them individually. afterwards
// thread them to an DAE.ARRAY()
arrayType := ComponentReference.crefTypeFull(cr);
if not listEmpty(scalarLst) and listLength(scalarLst) <> Types.getDimensionProduct(arrayType) then
scalarCrefs := ComponentReference.expandCref(cr, true);
outFunctionTree := inFunctionTree;
for cref in scalarCrefs loop
(res1, outFunctionTree) := differentiateCrefs(Expression.crefExp(cref), inDiffwrtCref, inInputData, inDiffType, outFunctionTree, maxIter);
diffed_exps := res1 :: diffed_exps;
end for;
res := Expression.listToArray(listReverse(diffed_exps), Types.getDimensions(arrayType));
else
cr := createSeedCrefName(cr, matrixName);
res := DAE.CREF(cr, tp);
end if;

res = DAE.CREF(cr, tp);
then
(res, inFunctionTree);

Expand Down
2 changes: 1 addition & 1 deletion OMCompiler/Compiler/FrontEnd/ComponentReference.mo
Original file line number Diff line number Diff line change
Expand Up @@ -1129,7 +1129,7 @@ public function crefEqualNoStringCompare
"Returns true if two component references are equal!
IMPORTANT! do not use this function if you have
stringified components, meaning this function will
return false for: cref1: QUAL(x, IDENT(x)) != cref2: IDENT(x.y)"
return false for: cref1: QUAL(x, IDENT(y)) != cref2: IDENT(x.y)"
input DAE.ComponentRef inCref1;
input DAE.ComponentRef inCref2;
output Boolean outEqual;
Expand Down

0 comments on commit 1f63944

Please sign in to comment.