OMCompiler/Compiler/BackEnd/Matching.mo
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * This file is part of OpenModelica. | ||
| 3 | * | ||
| 4 | * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC), | ||
| 5 | * c/o Linköpings universitet, Department of Computer and Information Science, | ||
| 6 | * SE-58183 Linköping, Sweden. | ||
| 7 | * | ||
| 8 | * All rights reserved. | ||
| 9 | * | ||
| 10 | * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR | ||
| 11 | * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8. | ||
| 12 | * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES | ||
| 13 | * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL | ||
| 14 | * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. | ||
| 15 | * | ||
| 16 | * The OpenModelica software and the OSMC (Open Source Modelica Consortium) | ||
| 17 | * Public License (OSMC-PL) are obtained from OSMC, either from the above | ||
| 18 | * address, from the URLs: | ||
| 19 | * http://www.openmodelica.org or | ||
| 20 | * https://github.com/OpenModelica/ or | ||
| 21 | * http://www.ida.liu.se/projects/OpenModelica, | ||
| 22 | * and in the OpenModelica distribution. | ||
| 23 | * | ||
| 24 | * GNU AGPL version 3 is obtained from: | ||
| 25 | * https://www.gnu.org/licenses/licenses.html#GPL | ||
| 26 | * | ||
| 27 | * This program is distributed WITHOUT ANY WARRANTY; without | ||
| 28 | * even the implied warranty of MERCHANTABILITY or FITNESS | ||
| 29 | * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH | ||
| 30 | * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL. | ||
| 31 | * | ||
| 32 | * See the full OSMC Public License conditions for more details. | ||
| 33 | * | ||
| 34 | */ | ||
| 35 | |||
| 36 | encapsulated package Matching | ||
| 37 | " file: Matching.mo | ||
| 38 | package: Matching | ||
| 39 | description: Matching contains functions for matching algorithms" | ||
| 40 | |||
| 41 | |||
| 42 | |||
| 43 | import BackendDAE; | ||
| 44 | import BackendDAEFunc; | ||
| 45 | import DAE; | ||
| 46 | |||
| 47 | protected | ||
| 48 | |||
| 49 | import Absyn; | ||
| 50 | import Array; | ||
| 51 | import BackendDAEEXT; | ||
| 52 | import BackendDAEUtil; | ||
| 53 | import BackendDump; | ||
| 54 | import BackendEquation; | ||
| 55 | import BackendVariable; | ||
| 56 | import ClockIndexes; | ||
| 57 | import Config; | ||
| 58 | import Debug; | ||
| 59 | import Differentiate; | ||
| 60 | import DumpGraphML; | ||
| 61 | import ElementSource; | ||
| 62 | import Error; | ||
| 63 | import Ceval; | ||
| 64 | import Expression; | ||
| 65 | import Flags; | ||
| 66 | import IndexReduction; | ||
| 67 | import Inline; | ||
| 68 | import List; | ||
| 69 | import MetaModelica.Dangerous; | ||
| 70 | import UnorderedMap; | ||
| 71 | import UnorderedSet; | ||
| 72 | import Util; | ||
| 73 | import Sorting; | ||
| 74 | import System; | ||
| 75 | protected import ComponentReferenceBasics; | ||
| 76 | |||
| 77 | // ============================================================================= | ||
| 78 | // just a matching algorithm | ||
| 79 | // - PerfectMatching | ||
| 80 | // - RegularMatching | ||
| 81 | // | ||
| 82 | // ============================================================================= | ||
| 83 | |||
| 84 | public function PerfectMatching " | ||
| 85 | This function fails if there is no perfect matching for the given system." | ||
| 86 | input BackendDAE.AdjacencyMatrix m; | ||
| 87 | output array<Integer> ass1 "eqn := ass1[var]"; | ||
| 88 | output array<Integer> ass2 "var := ass2[eqn]"; | ||
| 89 | protected | ||
| 90 | Integer N = arrayLength(m); | ||
| 91 | algorithm | ||
| 92 | 2018 | ass1 := arrayCreate(N, -1); | |
| 93 | 2018 | ass2 := arrayCreate(N, -1); | |
| 94 |
2/4✗ Branch 1 not taken.
✓ Branch 2 taken 2018 times.
✓ Branch 4 taken 2018 times.
✗ Branch 5 not taken.
|
2018 | (ass1, ass2, true, _, _) := ContinueMatching(m, N, N, ass1, ass2, true); |
| 95 | end PerfectMatching; | ||
| 96 | |||
| 97 | public function RegularMatching " | ||
| 98 | This function returns at least a partial matching for singular systems, starting from scratch. | ||
| 99 | Unmatched nodes are represented by -1. The eMark and vMark vectors are only relevant if | ||
| 100 | perfectMatching = false." | ||
| 101 | input BackendDAE.AdjacencyMatrix m; | ||
| 102 | input Integer nVars; | ||
| 103 | input Integer nEqns; | ||
| 104 | output array<Integer> ass1 "eqn := ass1[var]"; | ||
| 105 | output array<Integer> ass2 "var := ass2[eqn]"; | ||
| 106 | output Boolean perfectMatching; | ||
| 107 | output array<Boolean> eMark "equations contained in the minimal structurally singular subset"; | ||
| 108 | output array<Boolean> vMark "variables contained in the minimal structurally singular subset"; | ||
| 109 | algorithm | ||
| 110 | 48069 | ass1 := arrayCreate(nVars, -1); | |
| 111 | 48069 | ass2 := arrayCreate(nEqns, -1); | |
| 112 | 48069 | (ass1, ass2, perfectMatching, eMark, vMark) := ContinueMatching(m, nVars, nEqns, ass1, ass2, false); | |
| 113 | end RegularMatching; | ||
| 114 | |||
| 115 | public function ContinueMatching " | ||
| 116 | This function returns at least a partial matching for singular systems. | ||
| 117 | Unmatched nodes are represented by -1." | ||
| 118 | input BackendDAE.AdjacencyMatrix m; | ||
| 119 | input Integer nVars; | ||
| 120 | input Integer nEqns; | ||
| 121 | input output array<Integer> ass1 "eqn := ass1[var]"; | ||
| 122 | input output array<Integer> ass2 "var := ass2[eqn]"; | ||
| 123 | input Boolean stopAtSingularity = false; | ||
| 124 | output Boolean perfectMatching = true; | ||
| 125 | output array<Boolean> eMark; | ||
| 126 | output array<Boolean> vMark; | ||
| 127 | protected | ||
| 128 | Integer i, j; | ||
| 129 | array<Integer> eMarkIx, vMarkIx; | ||
| 130 | Integer eMarkN=0, vMarkN=0, eDead=0, vDead=0; | ||
| 131 | Boolean success; | ||
| 132 | algorithm | ||
| 133 | 97627 | vMark := arrayCreate(nVars, false); | |
| 134 | 97627 | eMark := arrayCreate(nEqns, false); | |
| 135 | 97627 | vMarkIx := arrayCreate(nVars, 0); | |
| 136 | 97627 | eMarkIx := arrayCreate(nEqns, 0); | |
| 137 | |||
| 138 | i := 1; | ||
| 139 |
2/2✓ Branch 0 taken 655996 times.
✓ Branch 1 taken 97627 times.
|
753623 | while i <= nEqns loop |
| 140 | 655996 | j := ass2[i]; | |
| 141 |
3/4✓ Branch 0 taken 73080 times.
✓ Branch 1 taken 582916 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 73080 times.
|
655996 | if not (j>0 and ass1[j] == i) then |
| 142 | // What a failed search visited is closed under alternating paths, so it | ||
| 143 | // stays marked and later searches skip it. | ||
| 144 | 582916 | (success, eMarkN, vMarkN) := BBPathFound(i, m, eMark, vMark, ass1, ass2, eMarkIx, vMarkIx, eDead, vDead); | |
| 145 |
2/2✓ Branch 0 taken 522322 times.
✓ Branch 1 taken 60594 times.
|
582916 | if success then |
| 146 | 522322 | clearMarks(eMark, eMarkIx, eDead, eMarkN); | |
| 147 | 522322 | clearMarks(vMark, vMarkIx, vDead, vMarkN); | |
| 148 | else | ||
| 149 | perfectMatching := false; | ||
| 150 | 60594 | eDead := eMarkN; | |
| 151 | 60594 | vDead := vMarkN; | |
| 152 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 60594 times.
|
60594 | if stopAtSingularity then |
| 153 | ✗ | return; | |
| 154 | end if; | ||
| 155 | end if; | ||
| 156 | end if; | ||
| 157 | 655996 | i := i+1; | |
| 158 | end while; | ||
| 159 | end ContinueMatching; | ||
| 160 | |||
| 161 | protected function clearMarks "Sets arr[arrIx[from+1:to]] to false" | ||
| 162 | input array<Boolean> arr; | ||
| 163 | input array<Integer> arrIx; | ||
| 164 | input Integer from, to; | ||
| 165 | algorithm | ||
| 166 |
2/2✓ Branch 0 taken 489923 times.
✓ Branch 1 taken 554721 times.
|
2603476 | for i in from+1:to loop |
| 167 | 1558832 | arrayUpdate(arr, arrIx[i], false); | |
| 168 | end for; | ||
| 169 | end clearMarks; | ||
| 170 | |||
| 171 | public function BBMatching | ||
| 172 | input BackendDAE.EqSystem inSys; | ||
| 173 | input BackendDAE.Shared inShared; | ||
| 174 | input Boolean clearMatching; | ||
| 175 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 176 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 177 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 178 | output BackendDAE.EqSystem outSys = inSys; | ||
| 179 | output BackendDAE.Shared outShared = inShared; | ||
| 180 | output BackendDAE.StructurallySingularSystemHandlerArg outArg = inArg; | ||
| 181 | protected | ||
| 182 | Integer i; | ||
| 183 | Boolean success = true; | ||
| 184 | BackendDAE.AdjacencyMatrix m; | ||
| 185 | Integer nVars, nEqns, j; | ||
| 186 | array<Integer> ass1, ass2; | ||
| 187 | array<Boolean> eMark, vMark; | ||
| 188 | array<Integer> eMarkIx, vMarkIx; | ||
| 189 | Integer eMarkN=0, vMarkN=0; | ||
| 190 | list<Integer> mEqns; | ||
| 191 | algorithm | ||
| 192 | //BackendDAE.EQSYSTEM(m=SOME(m), matching=BackendDAE.MATCHING(ass1=ass1, ass2=ass2)) := outSys; | ||
| 193 | ✗ | SOME(m) := outSys.m; | |
| 194 | ✗ | nEqns := BackendDAEUtil.systemSize(outSys); | |
| 195 | ✗ | nVars := BackendVariable.daenumVariables(outSys); | |
| 196 | // Be carefull, since matching may have been generated with not distinguishing between | ||
| 197 | // state and their derivative, which leads to wrong traversing of bibartite graph!!!! | ||
| 198 | //(ass1, ass2) := getAssignment(clearMatching, nVars, nEqns, inSys); | ||
| 199 | //if clearMatching then | ||
| 200 | ✗ | ass2 := arrayCreate(nEqns, -1); | |
| 201 | ✗ | ass1 := arrayCreate(nVars, -1); | |
| 202 | //BBCheapMatching(nEqns, m, ass1, ass2); | ||
| 203 | //end if; | ||
| 204 | ✗ | vMark := arrayCreate(nVars, false); | |
| 205 | ✗ | eMark := arrayCreate(nEqns, false); | |
| 206 | ✗ | vMarkIx := arrayCreate(nVars, 0); | |
| 207 | ✗ | eMarkIx := arrayCreate(nEqns, 0); | |
| 208 | i := 1; | ||
| 209 | ✗ | while i <= nEqns and success loop | |
| 210 | ✗ | j := ass2[i]; | |
| 211 | ✗ | if ((j>0) and ass1[j] == i) then | |
| 212 | success :=true; | ||
| 213 | else | ||
| 214 | ✗ | clearArrayWithKnownSetIndexes(eMark, eMarkIx, eMarkN); | |
| 215 | ✗ | clearArrayWithKnownSetIndexes(vMark, vMarkIx, vMarkN); | |
| 216 | ✗ | (success,eMarkN,vMarkN) := BBPathFound(i, m, eMark, vMark, ass1, ass2, eMarkIx, vMarkIx, 0, 0); | |
| 217 | ✗ | if not success then | |
| 218 | mEqns := {}; | ||
| 219 | ✗ | for j in 1:nEqns loop | |
| 220 | ✗ | if eMark[j] then | |
| 221 | mEqns:=j::mEqns; | ||
| 222 | end if; | ||
| 223 | end for; | ||
| 224 | ✗ | (_, i, outSys, outShared, ass1, ass2, outArg) := sssHandler({mEqns}, i, outSys, outShared, ass1, ass2, outArg); | |
| 225 | ✗ | SOME(m) := outSys.m; | |
| 226 | //nEqns := BackendDAEUtil.systemSize(outSys); | ||
| 227 | //nVars := BackendVariable.daenumVariables(outSys); | ||
| 228 | //ass1 := assignmentsArrayExpand(ass1, nVars, arrayLength(ass1), -1); | ||
| 229 | //ass2 := assignmentsArrayExpand(ass2, nEqns, arrayLength(ass2), -1); | ||
| 230 | //vMark := assignmentsArrayBooleanExpand(vMark, nVars, arrayLength(vMark), false); | ||
| 231 | //eMark := assignmentsArrayBooleanExpand(eMark, nEqns, arrayLength(eMark), false); | ||
| 232 | success := true; | ||
| 233 | ✗ | i := i-1; | |
| 234 | end if; | ||
| 235 | end if; | ||
| 236 | ✗ | i := i+1; | |
| 237 | end while; | ||
| 238 | if success then | ||
| 239 | ✗ | outSys := BackendDAEUtil.setEqSystMatching(outSys, BackendDAE.MATCHING(ass1, ass2, {})); | |
| 240 | else | ||
| 241 | print("\nSingular System!!!\n"); | ||
| 242 | end if; | ||
| 243 | end BBMatching; | ||
| 244 | |||
| 245 | protected function BBPathFound | ||
| 246 | "Searches an augmenting path starting at equation i." | ||
| 247 | input Integer i; | ||
| 248 | input BackendDAE.AdjacencyMatrix m; | ||
| 249 | input array<Boolean> eMark; | ||
| 250 | input array<Boolean> vMark; | ||
| 251 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 252 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 253 | input array<Integer> eMarkIx; | ||
| 254 | input array<Integer> vMarkIx; | ||
| 255 | output Boolean success=false; | ||
| 256 | input output Integer eMarkN, vMarkN; | ||
| 257 | protected | ||
| 258 | list<tuple<Integer, Integer, list<Integer>>> stack = {} "(eqn, var descended through, vars left to try)"; | ||
| 259 | list<Integer> vars = {}; | ||
| 260 | Integer eqn = i, var, parent; | ||
| 261 | Boolean enter = true, descended; | ||
| 262 | algorithm | ||
| 263 | while true loop | ||
| 264 |
2/2✓ Branch 0 taken 1167537 times.
✓ Branch 1 taken 412601 times.
|
1580138 | if enter then |
| 265 | enter := false; | ||
| 266 | vars := {}; | ||
| 267 |
1/2✓ Branch 1 taken 1167537 times.
✗ Branch 2 not taken.
|
1167537 | if not arrayGet(eMark, eqn) then |
| 268 | 1167537 | arrayUpdate(eMark, eqn, true); | |
| 269 | 1167537 | eMarkN := eMarkN+1; | |
| 270 | 1167537 | arrayUpdate(eMarkIx, eMarkN, eqn); | |
| 271 | |||
| 272 |
2/2✓ Branch 1 taken 3013677 times.
✓ Branch 2 taken 645215 times.
|
3658892 | for j in m[eqn] loop |
| 273 | // negative entries in adjacence matrix belong to states!!! | ||
| 274 |
3/4✓ Branch 0 taken 3013677 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 522322 times.
✓ Branch 4 taken 2491355 times.
|
3013677 | if (j>0 and ass1[j] <= 0) then |
| 275 | success := true; | ||
| 276 | 522322 | arrayUpdate(ass1, j, eqn); | |
| 277 | 522322 | arrayUpdate(ass2, eqn, j); | |
| 278 | break; | ||
| 279 | end if; | ||
| 280 | end for; | ||
| 281 | |||
| 282 | if success then | ||
| 283 |
2/2✓ Branch 0 taken 172020 times.
✓ Branch 1 taken 522322 times.
|
694342 | for frame in stack loop |
| 284 | 172020 | (parent, var, _) := frame; | |
| 285 | 172020 | arrayUpdate(ass1, var, parent); | |
| 286 | 172020 | arrayUpdate(ass2, parent, var); | |
| 287 | end for; | ||
| 288 | 522322 | return; | |
| 289 | end if; | ||
| 290 | vars := m[eqn]; | ||
| 291 | end if; | ||
| 292 | end if; | ||
| 293 | |||
| 294 | descended := false; | ||
| 295 |
2/2✓ Branch 0 taken 1905515 times.
✓ Branch 1 taken 473195 times.
|
2378710 | while not listEmpty(vars) loop |
| 296 | 1905515 | var::vars := vars; | |
| 297 | // negative entries in adjacence matrix belong to states!!! | ||
| 298 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 1905515 times.
✓ Branch 3 taken 1320894 times.
✓ Branch 4 taken 584621 times.
|
1905515 | if (var>0 and not vMark[var]) then |
| 299 | 584621 | arrayUpdate(vMark, var, true); | |
| 300 | 584621 | vMarkN := vMarkN+1; | |
| 301 | 584621 | arrayUpdate(vMarkIx, vMarkN, var); | |
| 302 | 584621 | stack := (eqn, var, vars)::stack; | |
| 303 | 584621 | eqn := ass1[var]; | |
| 304 | enter := true; | ||
| 305 | descended := true; | ||
| 306 | 584621 | break; | |
| 307 | end if; | ||
| 308 | end while; | ||
| 309 | |||
| 310 |
2/2✓ Branch 0 taken 584621 times.
✓ Branch 1 taken 473195 times.
|
1057816 | if not descended then |
| 311 |
2/2✓ Branch 0 taken 60594 times.
✓ Branch 1 taken 412601 times.
|
473195 | if listEmpty(stack) then |
| 312 | 60594 | return; | |
| 313 | end if; | ||
| 314 | 412601 | (eqn, _, vars)::stack := stack; | |
| 315 | end if; | ||
| 316 | end while; | ||
| 317 | end BBPathFound; | ||
| 318 | |||
| 319 | protected function BBCheapMatching | ||
| 320 | input Integer nEqns; | ||
| 321 | input BackendDAE.AdjacencyMatrix m; | ||
| 322 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 323 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 324 | protected | ||
| 325 | Integer i, j; | ||
| 326 | Boolean success=false; | ||
| 327 | list<Integer> vars; | ||
| 328 | algorithm | ||
| 329 | ✗ | for i in 1:nEqns loop | |
| 330 | ✗ | vars := m[i]; | |
| 331 | ✗ | while not success and not listEmpty(vars) loop | |
| 332 | ✗ | j::vars := vars; | |
| 333 | // negative entries in adjacence matrix belong to states!!! | ||
| 334 | ✗ | if (j>0 and ass1[j] <= 0) then | |
| 335 | success := true; | ||
| 336 | ✗ | arrayUpdate(ass1, j, i); | |
| 337 | ✗ | arrayUpdate(ass2, i, j); | |
| 338 | end if; | ||
| 339 | end while; | ||
| 340 | end for; | ||
| 341 | end BBCheapMatching; | ||
| 342 | |||
| 343 | public function invertMatching "author: lochel | ||
| 344 | ass1 <-> ass2" | ||
| 345 | input array<Integer> inAss; | ||
| 346 | output array<Integer> outAss; | ||
| 347 | protected | ||
| 348 | Integer N = arrayLength(inAss); | ||
| 349 | Integer j; | ||
| 350 | algorithm | ||
| 351 | ✗ | outAss := arrayCreate(N, -1); | |
| 352 | ✗ | for i in 1:N loop | |
| 353 | ✗ | j := inAss[i]; | |
| 354 | ✗ | if j > 0 then | |
| 355 | ✗ | outAss[inAss[i]] := i; | |
| 356 | end if; | ||
| 357 | end for; | ||
| 358 | end invertMatching; | ||
| 359 | |||
| 360 | // ============================================================================= | ||
| 361 | // Matching Algorithms | ||
| 362 | // | ||
| 363 | // ============================================================================= | ||
| 364 | |||
| 365 | public function DFSLH | ||
| 366 | "depth first search with look ahead feature. basically the same like MC21A." | ||
| 367 | input BackendDAE.EqSystem isyst; | ||
| 368 | input BackendDAE.Shared ishared; | ||
| 369 | input Boolean clearMatching; | ||
| 370 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 371 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 372 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 373 | output BackendDAE.EqSystem osyst; | ||
| 374 | output BackendDAE.Shared oshared; | ||
| 375 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 376 | algorithm | ||
| 377 | (osyst,oshared,outArg) := | ||
| 378 | matchcontinue isyst | ||
| 379 | local | ||
| 380 | Integer nvars,neqns; | ||
| 381 | array<Integer> vec1,vec2,emark,vmark; | ||
| 382 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 383 | BackendDAE.EqSystem syst; | ||
| 384 | BackendDAE.Shared shared; | ||
| 385 | BackendDAE.AdjacencyMatrix m; | ||
| 386 | BackendDAE.AdjacencyMatrixT mt; | ||
| 387 | |||
| 388 | case BackendDAE.EQSYSTEM(m=SOME(m),mT=SOME(mt)) | ||
| 389 | algorithm | ||
| 390 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 391 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 392 | ✗ | true := intGt(nvars,0); | |
| 393 | ✗ | true := intGt(neqns,0); | |
| 394 | ✗ | vmark := arrayCreate(nvars,-1); | |
| 395 | ✗ | emark := arrayCreate(neqns,-1); | |
| 396 | ✗ | (vec1,vec2) := getAssignment(clearMatching,nvars,neqns,isyst); | |
| 397 | ✗ | cheapmatchingalgorithm(nvars,neqns,m,mt,vec1,vec2,false); | |
| 398 | ✗ | (vec1,vec2,syst,shared,arg) := DFSLH2(isyst,ishared,nvars,neqns,1,emark,vmark,vec1,vec2,inMatchingOptions,sssHandler,inArg); | |
| 399 | ✗ | syst := BackendDAEUtil.setEqSystMatching(syst,BackendDAE.MATCHING(vec1,vec2,{})); | |
| 400 | ✗ | then | |
| 401 | (syst,shared,arg); | ||
| 402 | // fail case if system is empty | ||
| 403 | case _ | ||
| 404 | algorithm | ||
| 405 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 406 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 407 | ✗ | false := intGt(nvars,0); | |
| 408 | ✗ | false := intGt(neqns,0); | |
| 409 | ✗ | vec1 := listArray({}); | |
| 410 | ✗ | vec2 := listArray({}); | |
| 411 | ✗ | syst := BackendDAEUtil.setEqSystMatching(isyst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 412 | then | ||
| 413 | (syst,ishared,inArg); | ||
| 414 | else | ||
| 415 | algorithm | ||
| 416 | ✗ | if Flags.isSet(Flags.FAILTRACE) then | |
| 417 | ✗ | Debug.trace("- Matching.DFSLH failed\n"); | |
| 418 | end if; | ||
| 419 | ✗ | then | |
| 420 | fail(); | ||
| 421 | end matchcontinue; | ||
| 422 | end DFSLH; | ||
| 423 | |||
| 424 | protected function DFSLH2 | ||
| 425 | "author: PA | ||
| 426 | This is the outer loop of the matching algorithm | ||
| 427 | The find_path algorithm is called for each equation/variable. | ||
| 428 | inputs: (BackendDAE,AdjacencyMatrix, AdjacencyMatrixT | ||
| 429 | ,int /* number of vars */ | ||
| 430 | ,int /* number of eqns */ | ||
| 431 | ,int /* current var */ | ||
| 432 | ,Assignments /* assignments, array of eqn indices */ | ||
| 433 | ,Assignments /* assignments, array of var indices */ | ||
| 434 | ,MatchingOptions) /* options for matching alg. */ | ||
| 435 | outputs: (Assignments, /* assignments, array of equation indices */ | ||
| 436 | Assignments, /* assignments, list of variable indices */ | ||
| 437 | BackendDAE, BackendDAE.AdjacencyMatrix, AdjacencyMatrixT)" | ||
| 438 | input BackendDAE.EqSystem isyst; | ||
| 439 | input BackendDAE.Shared ishared; | ||
| 440 | input Integer nv; | ||
| 441 | input Integer nf; | ||
| 442 | input Integer i; | ||
| 443 | input array<Integer> emark; | ||
| 444 | input array<Integer> vmark; | ||
| 445 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 446 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 447 | input BackendDAE.MatchingOptions match_opts; | ||
| 448 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 449 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 450 | output array<Integer> outAssignments1; | ||
| 451 | output array<Integer> outAssignments2; | ||
| 452 | output BackendDAE.EqSystem osyst; | ||
| 453 | output BackendDAE.Shared oshared; | ||
| 454 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 455 | algorithm | ||
| 456 | (outAssignments1,outAssignments2,osyst,oshared,outArg):= | ||
| 457 | matchcontinue (isyst, match_opts) | ||
| 458 | local | ||
| 459 | array<Integer> ass1_1,ass2_1,ass1_2,ass2_2,ass1_3,ass2_3,emark1,vmark1; | ||
| 460 | BackendDAE.AdjacencyMatrix m; | ||
| 461 | BackendDAE.AdjacencyMatrixT mt; | ||
| 462 | Integer i_1,nv_1,nf_1; | ||
| 463 | BackendDAE.EquationArray eqns; | ||
| 464 | list<Integer> eqn_lst,meqns; | ||
| 465 | BackendDAE.StructurallySingularSystemHandlerArg arg,arg1; | ||
| 466 | BackendDAE.EqSystem syst; | ||
| 467 | BackendDAE.Shared shared; | ||
| 468 | case (syst as BackendDAE.EQSYSTEM(m=SOME(m),mT=SOME(mt)), _) | ||
| 469 | algorithm | ||
| 470 | ✗ | true := intGe(i,nv); | |
| 471 | ✗ | (ass1_1,ass2_1) := pathFound(m, mt, i, i,emark, vmark, ass1, ass2) "eMark(i)=vMark(i)=false; eMark(i)=vMark(i)=false exit loop"; | |
| 472 | ✗ | then | |
| 473 | (ass1_1,ass2_1,syst,ishared,inArg); | ||
| 474 | |||
| 475 | case (syst as BackendDAE.EQSYSTEM(m=SOME(_),mT=SOME(_)), _) | ||
| 476 | algorithm | ||
| 477 | ✗ | i_1 := i + 1; | |
| 478 | ✗ | true := intGt(ass2[i],0); | |
| 479 | ✗ | (ass1_2,ass2_2,syst,shared,arg) := DFSLH2(syst, ishared, nv, nf, i_1, emark, vmark, ass1, ass2, match_opts, sssHandler, inArg); | |
| 480 | then | ||
| 481 | (ass1_2,ass2_2,syst,shared,arg); | ||
| 482 | |||
| 483 | case (syst as BackendDAE.EQSYSTEM(m=SOME(m),mT=SOME(mt)), _) | ||
| 484 | algorithm | ||
| 485 | ✗ | i_1 := i + 1; | |
| 486 | ✗ | (ass1_1,ass2_1) := pathFound(m, mt, i, i,emark, vmark, ass1, ass2) "eMark(i)=vMark(i)=false"; | |
| 487 | ✗ | (ass1_2,ass2_2,syst,shared,arg) := DFSLH2(syst, ishared, nv, nf, i_1, emark, vmark, ass1_1, ass2_1, match_opts, sssHandler, inArg); | |
| 488 | then | ||
| 489 | (ass1_2,ass2_2,syst,shared,arg); | ||
| 490 | |||
| 491 | case (_, (BackendDAE.INDEX_REDUCTION(),_)) | ||
| 492 | algorithm | ||
| 493 | ✗ | meqns := getMarked(nf,i,emark,{}); | |
| 494 | ✗ | (_,i_1,syst,shared,ass1_1,ass2_1,arg) := sssHandler({meqns},i,isyst,ishared,ass1,ass2,inArg) | |
| 495 | "path_found failed, Try index reduction using dummy derivatives. | ||
| 496 | When a constraint exist between states and index reduction is needed | ||
| 497 | the dummy derivative will select one of the states as a dummy state | ||
| 498 | (and the derivative of that state as a dummy derivative). | ||
| 499 | For instance, u1=u2 is a constraint between states. Choose u1 as dummy state | ||
| 500 | and der(u1) as dummy derivative, named der_u1. The differentiated function | ||
| 501 | then becomes: der_u1 = der(u2). | ||
| 502 | In the dummy derivative method this equation is added and the original equation | ||
| 503 | u1=u2 is kept. This is not the case for the original pantilides algorithm, where | ||
| 504 | the original equation is removed from the system."; | ||
| 505 | ✗ | eqns := BackendEquation.getEqnsFromEqSystem(syst); | |
| 506 | ✗ | nf_1 := BackendEquation.equationArraySize(eqns) "and try again, restarting. This could be optimized later. It should not | |
| 507 | be necessary to restart the matching, according to Bernard Bachmann. Instead one | ||
| 508 | could continue the matching as usual. This was tested (2004-11-22) and it does not | ||
| 509 | work to continue without restarting. | ||
| 510 | For instance the Influenca model \"../testsuite/mofiles/Influenca.mo\" does not work if | ||
| 511 | not restarting. | ||
| 512 | 2004-12-29 PA. This was a bug, assignment lists needed to be expanded with the size | ||
| 513 | of the system in order to work. SO: Matching is not needed to be restarted from | ||
| 514 | scratch."; | ||
| 515 | ✗ | nv_1 := BackendVariable.varsSize(BackendVariable.daeVars(syst)); | |
| 516 | ✗ | ass1_2 := assignmentsArrayExpand(ass1_1, nv_1,arrayLength(ass1_1),-1); | |
| 517 | ✗ | ass2_2 := assignmentsArrayExpand(ass2_1, nf_1,arrayLength(ass2_1),-1); | |
| 518 | ✗ | vmark1 := assignmentsArrayExpand(vmark, nv_1,arrayLength(vmark),-1); | |
| 519 | ✗ | emark1 := assignmentsArrayExpand(emark, nf_1,arrayLength(emark),-1); | |
| 520 | ✗ | (ass1_3,ass2_3,syst,shared,arg1) := DFSLH2(syst,shared,nv_1,nf_1,i_1,emark1, vmark1,ass1_2,ass2_2,match_opts,sssHandler,arg); | |
| 521 | then | ||
| 522 | (ass1_3,ass2_3,syst,shared,arg1); | ||
| 523 | |||
| 524 | case (_, _) | ||
| 525 | algorithm | ||
| 526 | ✗ | eqn_lst := getMarked(nf,i,emark,{}); | |
| 527 | ✗ | singularSystemError({eqn_lst},i,isyst,ishared,ass1,ass2,inArg); | |
| 528 | ✗ | then | |
| 529 | fail(); | ||
| 530 | end matchcontinue; | ||
| 531 | end DFSLH2; | ||
| 532 | |||
| 533 | protected function pathFound "author: PA | ||
| 534 | This function is part of the matching algorithm. | ||
| 535 | It tries to find a matching for the equation index given as | ||
| 536 | third argument, i. | ||
| 537 | inputs: (AdjacencyMatrix, BackendDAE.AdjacencyMatrixT, int /* equation */, | ||
| 538 | Assignments, Assignments) | ||
| 539 | outputs: (Assignments, Assignments)" | ||
| 540 | input BackendDAE.AdjacencyMatrix m; | ||
| 541 | input BackendDAE.AdjacencyMatrixT mt; | ||
| 542 | input Integer i; | ||
| 543 | input Integer imark; | ||
| 544 | input array<Integer> emark; | ||
| 545 | input array<Integer> vmark; | ||
| 546 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 547 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 548 | output array<Integer> outAssignments1; | ||
| 549 | output array<Integer> outAssignments2; | ||
| 550 | algorithm | ||
| 551 | (outAssignments1,outAssignments2):= | ||
| 552 | matchcontinue ass2 | ||
| 553 | local | ||
| 554 | array<Integer> ass1_1,ass2_1; | ||
| 555 | case _ | ||
| 556 | algorithm | ||
| 557 | ✗ | arrayUpdate(emark,i,imark) "Side effect"; | |
| 558 | ✗ | (ass1_1,ass2_1) := assignOneInEqn(m, mt, i, ass1, ass2); | |
| 559 | then | ||
| 560 | (ass1_1,ass2_1); | ||
| 561 | case _ | ||
| 562 | algorithm | ||
| 563 | ✗ | (ass1_1,ass2_1) := forallUnmarkedVarsInEqn(m, mt, i, imark, emark, vmark, ass1, ass2); | |
| 564 | then | ||
| 565 | (ass1_1,ass2_1); | ||
| 566 | end matchcontinue; | ||
| 567 | end pathFound; | ||
| 568 | |||
| 569 | protected function assignOneInEqn "author: PA | ||
| 570 | Helper function to pathFound." | ||
| 571 | input BackendDAE.AdjacencyMatrix m; | ||
| 572 | input BackendDAE.AdjacencyMatrixT mt; | ||
| 573 | input Integer i; | ||
| 574 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 575 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 576 | output array<Integer> outAssignments1; | ||
| 577 | output array<Integer> outAssignments2; | ||
| 578 | protected | ||
| 579 | list<Integer> vars; | ||
| 580 | algorithm | ||
| 581 | ✗ | vars := BackendDAEUtil.varsInEqn(m, i); | |
| 582 | ✗ | (outAssignments1,outAssignments2):= assignFirstUnassigned(i, vars, ass1, ass2); | |
| 583 | end assignOneInEqn; | ||
| 584 | |||
| 585 | protected function assignFirstUnassigned | ||
| 586 | "author: PA | ||
| 587 | This function assigns the first unassign variable to the equation | ||
| 588 | given as first argument. It is part of the matching algorithm. | ||
| 589 | inputs: (int /* equation */, | ||
| 590 | int list /* variables */, | ||
| 591 | BackendDAE.Assignments /* ass1 */, | ||
| 592 | BackendDAE.Assignments /* ass2 */) | ||
| 593 | outputs: (Assignments, /* ass1 */ | ||
| 594 | Assignments) /* ass2 */" | ||
| 595 | input Integer i; | ||
| 596 | input list<Integer> inIntegerLst2; | ||
| 597 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 598 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 599 | output array<Integer> outAssignments1; | ||
| 600 | output array<Integer> outAssignments2; | ||
| 601 | algorithm | ||
| 602 | (outAssignments1,outAssignments2):= | ||
| 603 | matchcontinue inIntegerLst2 | ||
| 604 | local | ||
| 605 | array<Integer> ass1_1,ass2_1; | ||
| 606 | Integer v; | ||
| 607 | list<Integer> vs; | ||
| 608 | case v :: _ | ||
| 609 | algorithm | ||
| 610 | ✗ | false := intGt(ass1[v],0); | |
| 611 | ✗ | ass1_1 := arrayUpdate(ass1,v,i); | |
| 612 | ✗ | ass2_1 := arrayUpdate(ass2,i,v); | |
| 613 | ✗ | then | |
| 614 | (ass1_1,ass2_1); | ||
| 615 | case _ :: vs | ||
| 616 | algorithm | ||
| 617 | ✗ | (ass1_1,ass2_1) := assignFirstUnassigned(i, vs, ass1, ass2); | |
| 618 | then | ||
| 619 | (ass1_1,ass2_1); | ||
| 620 | end matchcontinue; | ||
| 621 | end assignFirstUnassigned; | ||
| 622 | |||
| 623 | protected function forallUnmarkedVarsInEqn | ||
| 624 | "author: PA | ||
| 625 | This function is part of the matching algorithm. | ||
| 626 | It loops over all umarked variables in an equation. | ||
| 627 | inputs: (AdjacencyMatrix, | ||
| 628 | AdjacencyMatrixT, | ||
| 629 | int, | ||
| 630 | BackendDAE.Assignments /* ass1 */, | ||
| 631 | BackendDAE.Assignments /* ass2 */) | ||
| 632 | outputs: (Assignments, Assignments)" | ||
| 633 | input BackendDAE.AdjacencyMatrix m; | ||
| 634 | input BackendDAE.AdjacencyMatrixT mt; | ||
| 635 | input Integer i; | ||
| 636 | input Integer imark; | ||
| 637 | input array<Integer> emark; | ||
| 638 | input array<Integer> vmark; | ||
| 639 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 640 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 641 | output array<Integer> outAssignments1; | ||
| 642 | output array<Integer> outAssignments2; | ||
| 643 | protected | ||
| 644 | list<Integer> vars,vars_1; | ||
| 645 | algorithm | ||
| 646 | ✗ | vars := BackendDAEUtil.varsInEqn(m, i); | |
| 647 | ✗ | vars_1 := List.filter1OnTrue(vars, isNotVMarked, (imark, vmark)); | |
| 648 | ✗ | (outAssignments1,outAssignments2) := forallUnmarkedVarsInEqnBody(m, mt, i, imark, emark, vmark, vars_1, ass1, ass2); | |
| 649 | end forallUnmarkedVarsInEqn; | ||
| 650 | |||
| 651 | protected function isNotVMarked | ||
| 652 | "author: PA | ||
| 653 | This function succeds for variables that are not marked." | ||
| 654 | input Integer i; | ||
| 655 | input tuple<Integer,array<Integer>> inTpl; | ||
| 656 | output Boolean outB; | ||
| 657 | protected | ||
| 658 | Integer imark; | ||
| 659 | array<Integer> vmark; | ||
| 660 | algorithm | ||
| 661 | ✗ | (imark,vmark) := inTpl; | |
| 662 | ✗ | outB := not intEq(imark,vmark[i]); | |
| 663 | end isNotVMarked; | ||
| 664 | |||
| 665 | protected function forallUnmarkedVarsInEqnBody | ||
| 666 | "author: PA | ||
| 667 | This function is part of the matching algorithm. | ||
| 668 | It is the body of the loop over all unmarked variables. | ||
| 669 | inputs: (AdjacencyMatrix, BackendDAE.AdjacencyMatrixT, | ||
| 670 | int, | ||
| 671 | int list /* var list */ | ||
| 672 | Assignments | ||
| 673 | Assignments) | ||
| 674 | outputs: (Assignments, Assignments)" | ||
| 675 | input BackendDAE.AdjacencyMatrix m; | ||
| 676 | input BackendDAE.AdjacencyMatrixT mt; | ||
| 677 | input Integer i; | ||
| 678 | input Integer imark; | ||
| 679 | input array<Integer> emark; | ||
| 680 | input array<Integer> vmark; | ||
| 681 | input list<Integer> inIntegerLst4; | ||
| 682 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 683 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 684 | output array<Integer> outAssignments1; | ||
| 685 | output array<Integer> outAssignments2; | ||
| 686 | algorithm | ||
| 687 | (outAssignments1,outAssignments2):= | ||
| 688 | matchcontinue inIntegerLst4 | ||
| 689 | local | ||
| 690 | Integer assarg,v; | ||
| 691 | array<Integer> ass1_1,ass2_1,ass1_2,ass2_2; | ||
| 692 | list<Integer> vs; | ||
| 693 | case v :: _ | ||
| 694 | algorithm | ||
| 695 | ✗ | arrayUpdate(vmark,v,imark); | |
| 696 | ✗ | assarg := ass1[v]; | |
| 697 | ✗ | (ass1_1,ass2_1) := pathFound(m, mt, assarg, imark, emark, vmark, ass1, ass2); | |
| 698 | ✗ | ass1_2 := arrayUpdate(ass1_1,v,i); | |
| 699 | ✗ | ass2_2 := arrayUpdate(ass2_1,i,v); | |
| 700 | ✗ | then | |
| 701 | (ass1_2,ass2_2); | ||
| 702 | case _ :: vs | ||
| 703 | algorithm | ||
| 704 | ✗ | (ass1_1,ass2_1) := forallUnmarkedVarsInEqnBody(m, mt, i, imark, emark, vmark, vs, ass1, ass2); | |
| 705 | then | ||
| 706 | (ass1_1,ass2_1); | ||
| 707 | end matchcontinue; | ||
| 708 | end forallUnmarkedVarsInEqnBody; | ||
| 709 | |||
| 710 | |||
| 711 | public function BFSB | ||
| 712 | " complexity O(n*tau) | ||
| 713 | author: Frenkel TUD 2012-03" | ||
| 714 | input BackendDAE.EqSystem isyst; | ||
| 715 | input BackendDAE.Shared ishared; | ||
| 716 | input Boolean clearMatching; | ||
| 717 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 718 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 719 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 720 | output BackendDAE.EqSystem osyst; | ||
| 721 | output BackendDAE.Shared oshared; | ||
| 722 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 723 | algorithm | ||
| 724 | (osyst,oshared,outArg) := | ||
| 725 | matchcontinue isyst | ||
| 726 | local | ||
| 727 | Integer nvars,neqns; | ||
| 728 | array<Integer> vec1,vec2; | ||
| 729 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 730 | BackendDAE.EqSystem syst; | ||
| 731 | BackendDAE.Shared shared; | ||
| 732 | array<Integer> rowmarks,parentcolum; | ||
| 733 | BackendDAE.AdjacencyMatrix m; | ||
| 734 | BackendDAE.AdjacencyMatrixT mt; | ||
| 735 | |||
| 736 | case BackendDAE.EQSYSTEM(m=SOME(m),mT=SOME(mt)) | ||
| 737 | algorithm | ||
| 738 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 739 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 740 | ✗ | true := intGt(nvars,0); | |
| 741 | ✗ | true := intGt(neqns,0); | |
| 742 | ✗ | rowmarks := arrayCreate(nvars,-1); | |
| 743 | ✗ | parentcolum := arrayCreate(nvars,-1); | |
| 744 | ✗ | (vec1,vec2) := getAssignment(clearMatching,nvars,neqns,isyst); | |
| 745 | ✗ | cheapmatchingalgorithm(nvars,neqns,m,mt,vec1,vec2,false); | |
| 746 | ✗ | (vec1,vec2,syst,shared,arg) := BFSB1(1,1,nvars,neqns,m,mt,rowmarks,parentcolum,vec1,vec2,isyst,ishared,inMatchingOptions, sssHandler, inArg); | |
| 747 | ✗ | syst := BackendDAEUtil.setEqSystMatching(syst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 748 | ✗ | then | |
| 749 | (syst,shared,arg); | ||
| 750 | |||
| 751 | // fail case if system is empty | ||
| 752 | case _ | ||
| 753 | algorithm | ||
| 754 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 755 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 756 | ✗ | false := intGt(nvars,0); | |
| 757 | ✗ | false := intGt(neqns,0); | |
| 758 | ✗ | vec1 := listArray({}); | |
| 759 | ✗ | vec2 := listArray({}); | |
| 760 | ✗ | syst := BackendDAEUtil.setEqSystMatching(isyst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 761 | then | ||
| 762 | (syst,ishared,inArg); | ||
| 763 | |||
| 764 | else | ||
| 765 | algorithm | ||
| 766 | ✗ | if Flags.isSet(Flags.FAILTRACE) then | |
| 767 | ✗ | Debug.trace("- Matching.BFSB failed\n"); | |
| 768 | end if; | ||
| 769 | ✗ | then | |
| 770 | fail(); | ||
| 771 | end matchcontinue; | ||
| 772 | end BFSB; | ||
| 773 | |||
| 774 | protected function BFSB1 | ||
| 775 | "function helper for BFSB, traverses all colums and perform a BFSB phase on each | ||
| 776 | author: Frenkel TUD 2012-03" | ||
| 777 | input Integer i; | ||
| 778 | input Integer rowmark; | ||
| 779 | input Integer nv; | ||
| 780 | input Integer ne; | ||
| 781 | input BackendDAE.AdjacencyMatrix m "m[eqnindx] = list(varindx)"; | ||
| 782 | input BackendDAE.AdjacencyMatrixT mT "mT[varindx] = list(eqnindx)"; | ||
| 783 | input array<Integer> rowmarks; | ||
| 784 | input array<Integer> parentcolum; | ||
| 785 | input array<Integer> ass1 "ass[eqnindx]=varindx"; | ||
| 786 | input array<Integer> ass2 "ass[varindx]=eqnindx"; | ||
| 787 | input BackendDAE.EqSystem isyst; | ||
| 788 | input BackendDAE.Shared ishared; | ||
| 789 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 790 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 791 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 792 | output array<Integer> outAss1; | ||
| 793 | output array<Integer> outAss2; | ||
| 794 | output BackendDAE.EqSystem osyst; | ||
| 795 | output BackendDAE.Shared oshared; | ||
| 796 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 797 | algorithm | ||
| 798 | (outAss1,outAss2,osyst,oshared,outArg):= | ||
| 799 | matchcontinue inArg | ||
| 800 | local | ||
| 801 | list<Integer> visitedcolums; | ||
| 802 | BackendDAE.AdjacencyMatrix m1,mt1; | ||
| 803 | Integer nv_1,ne_1,i_1; | ||
| 804 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 805 | BackendDAE.EqSystem syst; | ||
| 806 | BackendDAE.Shared shared; | ||
| 807 | array<Integer> ass1_1,ass1_2,ass2_1,ass2_2,rowmarks1,parentcolum1; | ||
| 808 | |||
| 809 | case _ | ||
| 810 | algorithm | ||
| 811 | ✗ | true:=intGt(i,ne); | |
| 812 | ✗ | then | |
| 813 | (ass1,ass2,isyst,ishared,inArg); | ||
| 814 | |||
| 815 | case _ | ||
| 816 | algorithm | ||
| 817 | // not assigned | ||
| 818 | ✗ | false := intGt(ass1[i],0); | |
| 819 | // search augmenting paths | ||
| 820 | ✗ | visitedcolums := BFSBphase({i},rowmark,i,nv,ne,m,mT,rowmarks,parentcolum,ass1,ass2,{},{}); | |
| 821 | // if visitedcolums is not zero matching fails -> try index reduction and matching aggain | ||
| 822 | ✗ | (_,i_1,syst as BackendDAE.EQSYSTEM(m=SOME(m1),mT=SOME(mt1)),shared,nv_1,ne_1,ass1_1,ass2_1,arg) := reduceIndexifNecessary(visitedcolums,i,isyst,ishared,nv,ne,ass1,ass2,inMatchingOptions,sssHandler,inArg); | |
| 823 | ✗ | rowmarks1 := assignmentsArrayExpand(rowmarks,nv_1,arrayLength(rowmarks),-1); | |
| 824 | ✗ | parentcolum1 := assignmentsArrayExpand(parentcolum,nv_1,arrayLength(parentcolum),-1); | |
| 825 | ✗ | (ass1_2,ass2_2,syst,shared,arg) := BFSB1(i_1,rowmark+1,nv_1,ne_1,m1,mt1,rowmarks1,parentcolum1,ass1_1,ass2_1,syst,shared,inMatchingOptions,sssHandler,arg); | |
| 826 | then | ||
| 827 | (ass1_2,ass2_2,syst,shared,arg); | ||
| 828 | |||
| 829 | case _ | ||
| 830 | algorithm | ||
| 831 | ✗ | true := intGt(ass1[i],0); | |
| 832 | ✗ | (ass1_1,ass2_1,syst,shared,arg) := BFSB1(i+1,rowmark,nv,ne,m,mT,rowmarks,parentcolum,ass1,ass2,isyst,ishared,inMatchingOptions,sssHandler,inArg); | |
| 833 | then | ||
| 834 | (ass1_1,ass2_1,syst,shared,arg); | ||
| 835 | |||
| 836 | else | ||
| 837 | algorithm | ||
| 838 | ✗ | Error.addInternalError("function BFSB1 failed in equation " + intString(i), sourceInfo()); | |
| 839 | ✗ | then | |
| 840 | fail(); | ||
| 841 | |||
| 842 | end matchcontinue; | ||
| 843 | end BFSB1; | ||
| 844 | |||
| 845 | protected function BFSBphase | ||
| 846 | "function helper for BFSB, traverses all colums and perform a BFSB phase on each | ||
| 847 | author: Frenkel TUD 2012-03" | ||
| 848 | input list<Integer> queue; | ||
| 849 | input Integer rowmark; | ||
| 850 | input Integer i; | ||
| 851 | input Integer nv; | ||
| 852 | input Integer ne; | ||
| 853 | input BackendDAE.AdjacencyMatrix m; | ||
| 854 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 855 | input array<Integer> rowmarks; | ||
| 856 | input array<Integer> parentcolum; | ||
| 857 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 858 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 859 | input list<Integer> nextQueue; | ||
| 860 | input list<Integer> inVisitedColums; | ||
| 861 | output list<Integer> outVisitedColums "This list stores all visited collums, if no augmenting path is found | ||
| 862 | it could be used to prune the nodes, if a path is found the list is empty"; | ||
| 863 | algorithm | ||
| 864 | outVisitedColums := | ||
| 865 | match (queue, nextQueue) | ||
| 866 | local | ||
| 867 | list<Integer> rest,queue1,rows; | ||
| 868 | Integer c; | ||
| 869 | Boolean b; | ||
| 870 | case ({}, {}) then inVisitedColums; | ||
| 871 | case ({}, _) | ||
| 872 | ✗ | then | |
| 873 | BFSBphase(nextQueue,rowmark,i,nv,ne,m,mT,rowmarks,parentcolum,ass1,ass2,{},inVisitedColums); | ||
| 874 | case (c::rest, _) | ||
| 875 | algorithm | ||
| 876 | // traverse all adiacent rows | ||
| 877 | ✗ | rows := List.select(m[c], Util.intPositive); | |
| 878 | ✗ | (queue1,b) := BFSBtraverseRows(rows,nextQueue,rowmark,i,c,nv,ne,m,mT,rowmarks,parentcolum,ass1,ass2); | |
| 879 | ✗ | then | |
| 880 | BFSBphase1(b,rest,rowmark,i,nv,ne,m,mT,rowmarks,parentcolum,ass1,ass2,queue1,c::inVisitedColums); | ||
| 881 | else | ||
| 882 | algorithm | ||
| 883 | ✗ | Error.addInternalError("function BFSBphase failed in equation " + intString(i), sourceInfo()); | |
| 884 | ✗ | then | |
| 885 | fail(); | ||
| 886 | |||
| 887 | end match; | ||
| 888 | end BFSBphase; | ||
| 889 | |||
| 890 | protected function BFSBphase1 | ||
| 891 | "function helper for BFSB, traverses all colums and perform a BFSB phase on each | ||
| 892 | author: Frenkel TUD 2012-03" | ||
| 893 | input Boolean inPathFound; | ||
| 894 | input list<Integer> queue; | ||
| 895 | input Integer rowmark; | ||
| 896 | input Integer i; | ||
| 897 | input Integer nv; | ||
| 898 | input Integer ne; | ||
| 899 | input BackendDAE.AdjacencyMatrix m; | ||
| 900 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 901 | input array<Integer> rowmarks; | ||
| 902 | input array<Integer> parentcolum; | ||
| 903 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 904 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 905 | input list<Integer> nextQueue; | ||
| 906 | input list<Integer> inVisitedColums; | ||
| 907 | output list<Integer> outVisitedColums; | ||
| 908 | algorithm | ||
| 909 | outVisitedColums := | ||
| 910 | match inPathFound | ||
| 911 | case true then {}; | ||
| 912 | case false | ||
| 913 | ✗ | then | |
| 914 | BFSBphase(queue,rowmark,i,nv,ne,m,mT,rowmarks,parentcolum,ass1,ass2,nextQueue,inVisitedColums); | ||
| 915 | else | ||
| 916 | algorithm | ||
| 917 | ✗ | Error.addInternalError("function BFSBphase1 failed", sourceInfo()); | |
| 918 | ✗ | then | |
| 919 | fail(); | ||
| 920 | end match; | ||
| 921 | end BFSBphase1; | ||
| 922 | |||
| 923 | protected function BFSBtraverseRows | ||
| 924 | "function helper for BFSB, traverses all vars of a equations and search a augmenting path | ||
| 925 | author: Frenkel TUD 2012-03" | ||
| 926 | input list<Integer> rows; | ||
| 927 | input list<Integer> queue; | ||
| 928 | input Integer rowmark; | ||
| 929 | input Integer i; | ||
| 930 | input Integer c; | ||
| 931 | input Integer nv; | ||
| 932 | input Integer ne; | ||
| 933 | input BackendDAE.AdjacencyMatrix m; | ||
| 934 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 935 | input array<Integer> rowmarks; | ||
| 936 | input array<Integer> parentcolum; | ||
| 937 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 938 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 939 | output list<Integer> outEqnqueue; | ||
| 940 | output Boolean pathFound; | ||
| 941 | algorithm | ||
| 942 | (outEqnqueue,pathFound):= | ||
| 943 | matchcontinue rows | ||
| 944 | local | ||
| 945 | list<Integer> rest,queue1,queue2; | ||
| 946 | Integer rc,r; | ||
| 947 | Boolean b; | ||
| 948 | ✗ | case {} then (listReverse(queue),false); | |
| 949 | case r::_ | ||
| 950 | algorithm | ||
| 951 | // row is unmatched -> augmenting path found | ||
| 952 | ✗ | true := intLt(ass2[r],0); | |
| 953 | ✗ | BFSBreasign(i,c,parentcolum,r,ass1,ass2); | |
| 954 | ✗ | then | |
| 955 | ({},true); | ||
| 956 | case r::rest | ||
| 957 | algorithm | ||
| 958 | // row is matched | ||
| 959 | ✗ | rc := ass2[r]; | |
| 960 | ✗ | false := intLt(rc,0); | |
| 961 | ✗ | queue1 := BFSBenque(queue,rowmark,c,rc,r,intLt(rowmarks[r],rowmark),rowmarks,parentcolum); | |
| 962 | ✗ | (queue2,b) := BFSBtraverseRows(rest,queue1,rowmark,i,c,nv,ne,m,mT,rowmarks,parentcolum,ass1,ass2); | |
| 963 | then | ||
| 964 | (queue2,b); | ||
| 965 | else | ||
| 966 | algorithm | ||
| 967 | ✗ | Error.addInternalError("function BFSBtraverseRows failed in equation " + intString(i), sourceInfo()); | |
| 968 | ✗ | then | |
| 969 | fail(); | ||
| 970 | |||
| 971 | end matchcontinue; | ||
| 972 | end BFSBtraverseRows; | ||
| 973 | |||
| 974 | protected function BFSBreasign | ||
| 975 | "function helper for BFSB, reasignment(rematching) allong the augmenting path | ||
| 976 | remove all edges from the assignments that are in the path | ||
| 977 | add all other edges to the assignment | ||
| 978 | author: Frenkel TUD 2012-03" | ||
| 979 | input Integer i; | ||
| 980 | input Integer c; | ||
| 981 | input array<Integer> parentcolum; | ||
| 982 | input Integer l; | ||
| 983 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 984 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 985 | algorithm | ||
| 986 | () := matchcontinue ass2 | ||
| 987 | local | ||
| 988 | Integer r; | ||
| 989 | case _ | ||
| 990 | algorithm | ||
| 991 | ✗ | true := intEq(i,c); | |
| 992 | ✗ | arrayUpdate(ass1,c,l); | |
| 993 | ✗ | arrayUpdate(ass2,l,c); | |
| 994 | then (); | ||
| 995 | case _ | ||
| 996 | algorithm | ||
| 997 | ✗ | r := ass1[c]; | |
| 998 | ✗ | arrayUpdate(ass1,c,l); | |
| 999 | ✗ | arrayUpdate(ass2,l,c); | |
| 1000 | ✗ | BFSBreasign(i,parentcolum[r],parentcolum,r,ass1,ass2); | |
| 1001 | then | ||
| 1002 | (); | ||
| 1003 | else | ||
| 1004 | algorithm | ||
| 1005 | ✗ | Error.addInternalError("function BFSBreasign failed", sourceInfo()); | |
| 1006 | ✗ | then | |
| 1007 | fail(); | ||
| 1008 | end matchcontinue; | ||
| 1009 | end BFSBreasign; | ||
| 1010 | |||
| 1011 | protected function BFSBenque | ||
| 1012 | "function helper for BFSB, enque a collum if the row is not visited | ||
| 1013 | author: Frenkel TUD 2012-03" | ||
| 1014 | input list<Integer> queue; | ||
| 1015 | input Integer rowmark; | ||
| 1016 | input Integer c; | ||
| 1017 | input Integer rc; | ||
| 1018 | input Integer r; | ||
| 1019 | input Boolean visited; | ||
| 1020 | input array<Integer> rowmarks; | ||
| 1021 | input array<Integer> parentcolum; | ||
| 1022 | output list<Integer> outEqnqueue; | ||
| 1023 | algorithm | ||
| 1024 | outEqnqueue:= | ||
| 1025 | match visited | ||
| 1026 | case false then queue; | ||
| 1027 | case true | ||
| 1028 | algorithm | ||
| 1029 | // mark row | ||
| 1030 | ✗ | arrayUpdate(rowmarks,r,rowmark); | |
| 1031 | // store parent colum | ||
| 1032 | ✗ | arrayUpdate(parentcolum,r,c); | |
| 1033 | then | ||
| 1034 | (rc::queue); | ||
| 1035 | else | ||
| 1036 | algorithm | ||
| 1037 | ✗ | Error.addInternalError("function BFSBenque failed", sourceInfo()); | |
| 1038 | ✗ | then | |
| 1039 | fail(); | ||
| 1040 | |||
| 1041 | end match; | ||
| 1042 | end BFSBenque; | ||
| 1043 | |||
| 1044 | |||
| 1045 | public function DFSB | ||
| 1046 | " complexity O(n*tau) | ||
| 1047 | author: Frenkel TUD 2012-03" | ||
| 1048 | input BackendDAE.EqSystem isyst; | ||
| 1049 | input BackendDAE.Shared ishared; | ||
| 1050 | input Boolean clearMatching; | ||
| 1051 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 1052 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 1053 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 1054 | output BackendDAE.EqSystem osyst; | ||
| 1055 | output BackendDAE.Shared oshared; | ||
| 1056 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 1057 | algorithm | ||
| 1058 | (osyst,oshared,outArg) := | ||
| 1059 | matchcontinue isyst | ||
| 1060 | local | ||
| 1061 | Integer nvars,neqns; | ||
| 1062 | BackendDAE.AdjacencyMatrix m; | ||
| 1063 | BackendDAE.AdjacencyMatrixT mt; | ||
| 1064 | array<Integer> vec1,vec2; | ||
| 1065 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 1066 | BackendDAE.EqSystem syst; | ||
| 1067 | BackendDAE.Shared shared; | ||
| 1068 | array<Integer> rowmarks; | ||
| 1069 | |||
| 1070 | case BackendDAE.EQSYSTEM(m=SOME(m),mT=SOME(mt)) | ||
| 1071 | algorithm | ||
| 1072 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 1073 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 1074 | ✗ | true := intGt(nvars,0); | |
| 1075 | ✗ | true := intGt(neqns,0); | |
| 1076 | ✗ | rowmarks := arrayCreate(nvars,-1); | |
| 1077 | ✗ | (vec1,vec2) := getAssignment(clearMatching,nvars,neqns,isyst); | |
| 1078 | ✗ | cheapmatchingalgorithm(nvars,neqns,m,mt,vec1,vec2,false); | |
| 1079 | ✗ | (vec1,vec2,syst,shared,arg) := DFSB1(1,1,nvars,neqns,m,mt,rowmarks,vec1,vec2,isyst,ishared,inMatchingOptions,sssHandler,inArg); | |
| 1080 | ✗ | syst := BackendDAEUtil.setEqSystMatching(syst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 1081 | ✗ | then | |
| 1082 | (syst,shared,arg); | ||
| 1083 | |||
| 1084 | // fail case if system is empty | ||
| 1085 | case _ | ||
| 1086 | algorithm | ||
| 1087 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 1088 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 1089 | ✗ | false := intGt(nvars,0); | |
| 1090 | ✗ | false := intGt(neqns,0); | |
| 1091 | ✗ | vec1 := listArray({}); | |
| 1092 | ✗ | vec2 := listArray({}); | |
| 1093 | ✗ | syst := BackendDAEUtil.setEqSystMatching(isyst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 1094 | then | ||
| 1095 | (syst,ishared,inArg); | ||
| 1096 | |||
| 1097 | else | ||
| 1098 | algorithm | ||
| 1099 | ✗ | if Flags.isSet(Flags.FAILTRACE) then | |
| 1100 | ✗ | Debug.trace("- Matching.BFSB failed\n"); | |
| 1101 | end if; | ||
| 1102 | ✗ | then | |
| 1103 | fail(); | ||
| 1104 | end matchcontinue; | ||
| 1105 | end DFSB; | ||
| 1106 | |||
| 1107 | protected function DFSB1 | ||
| 1108 | "function helper for DFSB, traverses all colums and perform a DFSB phase on each | ||
| 1109 | author: Frenkel TUD 2012-03" | ||
| 1110 | input Integer i; | ||
| 1111 | input Integer rowmark; | ||
| 1112 | input Integer nv; | ||
| 1113 | input Integer ne; | ||
| 1114 | input BackendDAE.AdjacencyMatrix m "m[eqnindx] = list(varindx)"; | ||
| 1115 | input BackendDAE.AdjacencyMatrixT mT "mT[varindx] = list(eqnindx)"; | ||
| 1116 | input array<Integer> rowmarks; | ||
| 1117 | input array<Integer> ass1 "ass[eqnindx]=varindx"; | ||
| 1118 | input array<Integer> ass2 "ass[varindx]=eqnindx"; | ||
| 1119 | input BackendDAE.EqSystem isyst; | ||
| 1120 | input BackendDAE.Shared ishared; | ||
| 1121 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 1122 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 1123 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 1124 | output array<Integer> outAss1; | ||
| 1125 | output array<Integer> outAss2; | ||
| 1126 | output BackendDAE.EqSystem osyst; | ||
| 1127 | output BackendDAE.Shared oshared; | ||
| 1128 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 1129 | algorithm | ||
| 1130 | (outAss1,outAss2,osyst,oshared,outArg):= | ||
| 1131 | matchcontinue inArg | ||
| 1132 | local | ||
| 1133 | list<Integer> visitedcolums; | ||
| 1134 | BackendDAE.AdjacencyMatrix m1,mt1; | ||
| 1135 | Integer nv_1,ne_1,i_1; | ||
| 1136 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 1137 | BackendDAE.EqSystem syst; | ||
| 1138 | BackendDAE.Shared shared; | ||
| 1139 | array<Integer> ass1_1,ass1_2,ass2_1,ass2_2,rowmarks1; | ||
| 1140 | case _ | ||
| 1141 | algorithm | ||
| 1142 | ✗ | true:=intGt(i,ne); | |
| 1143 | ✗ | then | |
| 1144 | (ass1,ass2,isyst,ishared,inArg); | ||
| 1145 | case _ | ||
| 1146 | algorithm | ||
| 1147 | // not assigned | ||
| 1148 | ✗ | false := intGt(ass1[i],0); | |
| 1149 | // search augmenting paths | ||
| 1150 | ✗ | visitedcolums := DFSBphase({i},rowmark,i,nv,ne,m,mT,rowmarks,ass1,ass2,{i}); | |
| 1151 | // if visitedcolums is not zero matching fails -> try index reduction and matching aggain | ||
| 1152 | // if visitedcolums is not zero matching fails -> try index reduction and matching aggain | ||
| 1153 | ✗ | (_,i_1,syst as BackendDAE.EQSYSTEM(m=SOME(m1),mT=SOME(mt1)),shared,nv_1,ne_1,ass1_1,ass2_1,arg) := reduceIndexifNecessary(visitedcolums,i,isyst,ishared,nv,ne,ass1,ass2,inMatchingOptions,sssHandler,inArg); | |
| 1154 | ✗ | rowmarks1 := assignmentsArrayExpand(rowmarks,nv_1,arrayLength(rowmarks),-1); | |
| 1155 | ✗ | (ass1_2,ass2_2,syst,shared,arg) := DFSB1(i_1,rowmark+1,nv_1,ne_1,m1,mt1,rowmarks1,ass1_1,ass2_1,syst,shared,inMatchingOptions,sssHandler,arg); | |
| 1156 | then | ||
| 1157 | (ass1_2,ass2_2,syst,shared,arg); | ||
| 1158 | |||
| 1159 | case _ | ||
| 1160 | algorithm | ||
| 1161 | ✗ | true := intGt(ass1[i],0); | |
| 1162 | ✗ | (ass1_1,ass2_1,syst,shared,arg) := DFSB1(i+1,rowmark,nv,ne,m,mT,rowmarks,ass1,ass2,isyst,ishared,inMatchingOptions,sssHandler,inArg); | |
| 1163 | then | ||
| 1164 | (ass1_1,ass2_1,syst,shared,arg); | ||
| 1165 | |||
| 1166 | else | ||
| 1167 | algorithm | ||
| 1168 | ✗ | Error.addInternalError("function DFSB1 failed in equation " + intString(i), sourceInfo()); | |
| 1169 | ✗ | then | |
| 1170 | fail(); | ||
| 1171 | |||
| 1172 | end matchcontinue; | ||
| 1173 | end DFSB1; | ||
| 1174 | |||
| 1175 | protected function DFSBphase | ||
| 1176 | "function helper for DFSB, traverses all colums and perform a DFSB phase on each | ||
| 1177 | author: Frenkel TUD 2012-03" | ||
| 1178 | input list<Integer> stack; | ||
| 1179 | input Integer i; | ||
| 1180 | input Integer c; | ||
| 1181 | input Integer nv; | ||
| 1182 | input Integer ne; | ||
| 1183 | input BackendDAE.AdjacencyMatrix m; | ||
| 1184 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 1185 | input array<Integer> rowmarks; | ||
| 1186 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 1187 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 1188 | input list<Integer> inVisitedColums; | ||
| 1189 | output list<Integer> outVisitedColums "This list stores all visited collums, if no augmenting path is found | ||
| 1190 | it could be used to prune the nodes, if a path is found the list is empty"; | ||
| 1191 | algorithm | ||
| 1192 | outVisitedColums := | ||
| 1193 | match stack | ||
| 1194 | local | ||
| 1195 | list<Integer> rows; | ||
| 1196 | case {} then inVisitedColums; | ||
| 1197 | case _ | ||
| 1198 | algorithm | ||
| 1199 | // traverse all adiacent rows | ||
| 1200 | ✗ | rows := List.select(m[c], Util.intPositive); | |
| 1201 | ✗ | then | |
| 1202 | DFSBtraverseRows(rows,stack,i,nv,ne,m,mT,rowmarks,ass1,ass2,inVisitedColums); | ||
| 1203 | else | ||
| 1204 | algorithm | ||
| 1205 | ✗ | Error.addInternalError("function DFSBphase failed in equation " + intString(c), sourceInfo()); | |
| 1206 | ✗ | then | |
| 1207 | fail(); | ||
| 1208 | |||
| 1209 | end match; | ||
| 1210 | end DFSBphase; | ||
| 1211 | |||
| 1212 | protected function DFSBtraverseRows | ||
| 1213 | "function helper for DFSB, traverses all vars of a equations and search a augmenting path | ||
| 1214 | author: Frenkel TUD 2012-03" | ||
| 1215 | input list<Integer> rows; | ||
| 1216 | input list<Integer> stack; | ||
| 1217 | input Integer i; | ||
| 1218 | input Integer nv; | ||
| 1219 | input Integer ne; | ||
| 1220 | input BackendDAE.AdjacencyMatrix m; | ||
| 1221 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 1222 | input array<Integer> rowmarks; | ||
| 1223 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 1224 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 1225 | input list<Integer> inVisitedColums; | ||
| 1226 | output list<Integer> outVisitedColums; | ||
| 1227 | algorithm | ||
| 1228 | outVisitedColums:= | ||
| 1229 | matchcontinue rows | ||
| 1230 | local | ||
| 1231 | list<Integer> rest,visitedColums; | ||
| 1232 | Integer rc,r; | ||
| 1233 | case {} then inVisitedColums; | ||
| 1234 | case r::_ | ||
| 1235 | algorithm | ||
| 1236 | // row is unmatched -> augmenting path found | ||
| 1237 | ✗ | true := intLt(ass2[r],0); | |
| 1238 | ✗ | DFSBreasign(stack,r,ass1,ass2); | |
| 1239 | then | ||
| 1240 | {}; | ||
| 1241 | case r::rest | ||
| 1242 | algorithm | ||
| 1243 | // row is matched | ||
| 1244 | ✗ | rc := ass2[r]; | |
| 1245 | ✗ | false := intLt(rc,0); | |
| 1246 | ✗ | true := intLt(rowmarks[r],i); | |
| 1247 | ✗ | arrayUpdate(rowmarks,r,i); | |
| 1248 | ✗ | visitedColums := DFSBphase(rc::stack,i,rc,nv,ne,m,mT,rowmarks,ass1,ass2,rc::inVisitedColums); | |
| 1249 | ✗ | then | |
| 1250 | DFSBtraverseRows1(rest,stack,i,nv,ne,m,mT,rowmarks,ass1,ass2,visitedColums); | ||
| 1251 | case _::rest | ||
| 1252 | ✗ | then | |
| 1253 | DFSBtraverseRows(rest,stack,i,nv,ne,m,mT,rowmarks,ass1,ass2,inVisitedColums); | ||
| 1254 | else | ||
| 1255 | algorithm | ||
| 1256 | ✗ | Error.addInternalError("function DFSBtraverseRows failed", sourceInfo()); | |
| 1257 | ✗ | then | |
| 1258 | fail(); | ||
| 1259 | |||
| 1260 | end matchcontinue; | ||
| 1261 | end DFSBtraverseRows; | ||
| 1262 | |||
| 1263 | protected function DFSBtraverseRows1 | ||
| 1264 | "function helper for DFSBtraverseRows | ||
| 1265 | author: Frenkel TUD 2012-03" | ||
| 1266 | input list<Integer> rows; | ||
| 1267 | input list<Integer> stack; | ||
| 1268 | input Integer i; | ||
| 1269 | input Integer nv; | ||
| 1270 | input Integer ne; | ||
| 1271 | input BackendDAE.AdjacencyMatrix m; | ||
| 1272 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 1273 | input array<Integer> rowmarks; | ||
| 1274 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 1275 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 1276 | input list<Integer> inVisitedColums; | ||
| 1277 | output list<Integer> outVisitedColums; | ||
| 1278 | algorithm | ||
| 1279 | outVisitedColums:= | ||
| 1280 | match inVisitedColums | ||
| 1281 | case {} then inVisitedColums; | ||
| 1282 | ✗ | else DFSBtraverseRows(rows,stack,i,nv,ne,m,mT,rowmarks,ass1,ass2,inVisitedColums); | |
| 1283 | end match; | ||
| 1284 | end DFSBtraverseRows1; | ||
| 1285 | |||
| 1286 | protected function DFSBreasign | ||
| 1287 | "function helper for DFSB, reasignment(rematching) allong the augmenting path | ||
| 1288 | remove all edges from the assignments that are in the path | ||
| 1289 | add all other edges to the assignment | ||
| 1290 | author: Frenkel TUD 2012-03" | ||
| 1291 | input list<Integer> stack; | ||
| 1292 | input Integer r; | ||
| 1293 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 1294 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 1295 | algorithm | ||
| 1296 | () := match stack | ||
| 1297 | local | ||
| 1298 | Integer c,rc; | ||
| 1299 | list<Integer> rest; | ||
| 1300 | case {} then (); | ||
| 1301 | case c::rest | ||
| 1302 | algorithm | ||
| 1303 | 251 | rc := ass1[c]; | |
| 1304 | 251 | arrayUpdate(ass1,c,r); | |
| 1305 | 251 | arrayUpdate(ass2,r,c); | |
| 1306 | 251 | DFSBreasign(rest,rc,ass1,ass2); | |
| 1307 | then (); | ||
| 1308 | end match; | ||
| 1309 | end DFSBreasign; | ||
| 1310 | |||
| 1311 | public function MC21A | ||
| 1312 | " complexity O(n*tau) | ||
| 1313 | author: Frenkel TUD 2012-03" | ||
| 1314 | input BackendDAE.EqSystem isyst; | ||
| 1315 | input BackendDAE.Shared ishared; | ||
| 1316 | input Boolean clearMatching; | ||
| 1317 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 1318 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 1319 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 1320 | output BackendDAE.EqSystem osyst; | ||
| 1321 | output BackendDAE.Shared oshared; | ||
| 1322 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 1323 | algorithm | ||
| 1324 | (osyst,oshared,outArg) := | ||
| 1325 | matchcontinue isyst | ||
| 1326 | local | ||
| 1327 | Integer nvars,neqns; | ||
| 1328 | BackendDAE.AdjacencyMatrix m; | ||
| 1329 | BackendDAE.AdjacencyMatrixT mt; | ||
| 1330 | array<Integer> vec1,vec2; | ||
| 1331 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 1332 | BackendDAE.EqSystem syst; | ||
| 1333 | BackendDAE.Shared shared; | ||
| 1334 | array<Integer> rowmarks,lookahead; | ||
| 1335 | |||
| 1336 | case syst as BackendDAE.EQSYSTEM(m=SOME(m),mT=SOME(mt)) | ||
| 1337 | algorithm | ||
| 1338 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 1339 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 1340 | ✗ | true := intGt(nvars,0); | |
| 1341 | ✗ | true := intGt(neqns,0); | |
| 1342 | ✗ | rowmarks := arrayCreate(nvars,-1); | |
| 1343 | ✗ | lookahead := arrayCreate(neqns,0); | |
| 1344 | ✗ | (vec1,vec2) := getAssignment(clearMatching,nvars,neqns,isyst); | |
| 1345 | ✗ | cheapmatchingalgorithm(nvars,neqns,m,mt,vec1,vec2,false); | |
| 1346 | ✗ | (vec1,vec2,syst,shared,arg) := MC21A1(1,1,nvars,neqns,m,mt,rowmarks,lookahead,vec1,vec2,isyst,ishared,inMatchingOptions,sssHandler,inArg); | |
| 1347 | ✗ | syst := BackendDAEUtil.setEqSystMatching(syst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 1348 | ✗ | then | |
| 1349 | (syst,shared,arg); | ||
| 1350 | // fail case if system is empty | ||
| 1351 | case _ | ||
| 1352 | algorithm | ||
| 1353 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 1354 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 1355 | ✗ | false := intGt(nvars,0); | |
| 1356 | ✗ | false := intGt(neqns,0); | |
| 1357 | ✗ | vec1 := listArray({}); | |
| 1358 | ✗ | vec2 := listArray({}); | |
| 1359 | ✗ | syst := BackendDAEUtil.setEqSystMatching(isyst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 1360 | then | ||
| 1361 | (syst,ishared,inArg); | ||
| 1362 | else | ||
| 1363 | algorithm | ||
| 1364 | ✗ | if Flags.isSet(Flags.FAILTRACE) then | |
| 1365 | ✗ | Debug.trace("- Matching.MC21A failed\n"); | |
| 1366 | end if; | ||
| 1367 | ✗ | then | |
| 1368 | fail(); | ||
| 1369 | end matchcontinue; | ||
| 1370 | end MC21A; | ||
| 1371 | |||
| 1372 | protected function MC21A1 | ||
| 1373 | "function helper for MC21A, traverses all colums and perform a MC21A phase on each | ||
| 1374 | author: Frenkel TUD 2012-03" | ||
| 1375 | input Integer i; | ||
| 1376 | input Integer rowmark; | ||
| 1377 | input Integer nv; | ||
| 1378 | input Integer ne; | ||
| 1379 | input BackendDAE.AdjacencyMatrix m "m[eqnindx] = list(varindx)"; | ||
| 1380 | input BackendDAE.AdjacencyMatrixT mT "mT[varindx] = list(eqnindx)"; | ||
| 1381 | input array<Integer> rowmarks; | ||
| 1382 | input array<Integer> lookahead; | ||
| 1383 | input array<Integer> ass1 "ass[eqnindx]=varindx"; | ||
| 1384 | input array<Integer> ass2 "ass[varindx]=eqnindx"; | ||
| 1385 | input BackendDAE.EqSystem isyst; | ||
| 1386 | input BackendDAE.Shared ishared; | ||
| 1387 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 1388 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 1389 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 1390 | output array<Integer> outAss1; | ||
| 1391 | output array<Integer> outAss2; | ||
| 1392 | output BackendDAE.EqSystem osyst; | ||
| 1393 | output BackendDAE.Shared oshared; | ||
| 1394 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 1395 | algorithm | ||
| 1396 | (outAss1,outAss2,osyst,oshared,outArg):= | ||
| 1397 | matchcontinue inArg | ||
| 1398 | local | ||
| 1399 | list<Integer> visitedcolums,changedEqns; | ||
| 1400 | BackendDAE.AdjacencyMatrix m1,mt1; | ||
| 1401 | Integer nv_1,ne_1,i_1; | ||
| 1402 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 1403 | BackendDAE.EqSystem syst; | ||
| 1404 | BackendDAE.Shared shared; | ||
| 1405 | array<Integer> ass1_1,ass1_2,ass2_1,ass2_2,rowmarks1,lookahead1; | ||
| 1406 | |||
| 1407 | case _ | ||
| 1408 | algorithm | ||
| 1409 | ✗ | true:=intGt(i,ne); | |
| 1410 | ✗ | then | |
| 1411 | (ass1,ass2,isyst,ishared,inArg); | ||
| 1412 | case _ | ||
| 1413 | algorithm | ||
| 1414 | // not assigned | ||
| 1415 | ✗ | false := intGt(ass1[i],0); | |
| 1416 | // search augmenting paths | ||
| 1417 | ✗ | visitedcolums := MC21Aphase({i},rowmark,i,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,{i}); | |
| 1418 | // if visitedcolums is not zero matching fails -> try index reduction and matching aggain | ||
| 1419 | ✗ | (changedEqns,i_1,syst as BackendDAE.EQSYSTEM(m=SOME(m1),mT=SOME(mt1)),shared,nv_1,ne_1,ass1_1,ass2_1,arg) := reduceIndexifNecessary(visitedcolums,i,isyst,ishared,nv,ne,ass1,ass2,inMatchingOptions,sssHandler,inArg); | |
| 1420 | ✗ | (rowmarks1,lookahead1) := MC21A1fixArrays(visitedcolums,nv_1,ne_1,rowmarks,lookahead,changedEqns); | |
| 1421 | ✗ | (ass1_2,ass2_2,syst,shared,arg) := MC21A1(i_1,rowmark+1,nv_1,ne_1,m1,mt1,rowmarks1,lookahead1,ass1_1,ass2_1,syst,shared,inMatchingOptions,sssHandler,arg); | |
| 1422 | then | ||
| 1423 | (ass1_2,ass2_2,syst,shared,arg); | ||
| 1424 | case _ | ||
| 1425 | algorithm | ||
| 1426 | ✗ | true := intGt(ass1[i],0); | |
| 1427 | ✗ | (ass1_1,ass2_1,syst,shared,arg) := MC21A1(i+1,rowmark,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,isyst,ishared,inMatchingOptions,sssHandler,inArg); | |
| 1428 | then | ||
| 1429 | (ass1_1,ass2_1,syst,shared,arg); | ||
| 1430 | else | ||
| 1431 | algorithm | ||
| 1432 | ✗ | Error.addInternalError("function MC21A1 failed in equation " + intString(i), sourceInfo()); | |
| 1433 | ✗ | then | |
| 1434 | fail(); | ||
| 1435 | end matchcontinue; | ||
| 1436 | end MC21A1; | ||
| 1437 | |||
| 1438 | protected function MC21A1fixArrays | ||
| 1439 | "function: MC21A1fixArrays, fixes lookahead and rowmarks after system has been index reduced | ||
| 1440 | author: Frenkel TUD 2012-04" | ||
| 1441 | input list<Integer> meqns "Marked Equations for Index Reduction"; | ||
| 1442 | input Integer nv; | ||
| 1443 | input Integer ne; | ||
| 1444 | input array<Integer> rowmarks; | ||
| 1445 | input array<Integer> lookahead; | ||
| 1446 | input list<Integer> changedEqns; | ||
| 1447 | output array<Integer> outrowmarks; | ||
| 1448 | output array<Integer> outlookahead; | ||
| 1449 | algorithm | ||
| 1450 | (outrowmarks,outlookahead):= | ||
| 1451 | match meqns | ||
| 1452 | local | ||
| 1453 | Integer memsize; | ||
| 1454 | array<Integer> rowmarks1,lookahead1; | ||
| 1455 | case {} then (rowmarks,lookahead); | ||
| 1456 | case _::_ | ||
| 1457 | algorithm | ||
| 1458 | memsize := arrayLength(rowmarks); | ||
| 1459 | ✗ | rowmarks1 := assignmentsArrayExpand(rowmarks,nv,memsize,-1); | |
| 1460 | ✗ | lookahead1 := assignmentsArrayExpand(lookahead,ne,memsize,0); | |
| 1461 | ✗ | MC21A1fixArray(changedEqns,lookahead1); | |
| 1462 | then | ||
| 1463 | (rowmarks1,lookahead1); | ||
| 1464 | else | ||
| 1465 | algorithm | ||
| 1466 | ✗ | Error.addInternalError("function MC21A1fixArrays failed", sourceInfo()); | |
| 1467 | ✗ | then | |
| 1468 | fail(); | ||
| 1469 | end match; | ||
| 1470 | end MC21A1fixArrays; | ||
| 1471 | |||
| 1472 | protected function MC21A1fixArray | ||
| 1473 | "author: Frenkel TUD 2012-04" | ||
| 1474 | input list<Integer> meqns "Marked Equations for Index Reduction"; | ||
| 1475 | input array<Integer> arr; | ||
| 1476 | algorithm | ||
| 1477 | () := | ||
| 1478 | match meqns | ||
| 1479 | local | ||
| 1480 | Integer e; | ||
| 1481 | list<Integer> rest; | ||
| 1482 | case {} then (); | ||
| 1483 | case e::rest | ||
| 1484 | algorithm | ||
| 1485 | 54 | arrayUpdate(arr,e,0); | |
| 1486 | 54 | MC21A1fixArray(rest,arr); | |
| 1487 | then | ||
| 1488 | (); | ||
| 1489 | else | ||
| 1490 | algorithm | ||
| 1491 | ✗ | Error.addInternalError("function MC21A1fixArray failed", sourceInfo()); | |
| 1492 | ✗ | then | |
| 1493 | fail(); | ||
| 1494 | end match; | ||
| 1495 | end MC21A1fixArray; | ||
| 1496 | |||
| 1497 | protected function MC21Aphase | ||
| 1498 | "function helper for MC21A, traverses all colums and perform a MC21A phase on each | ||
| 1499 | author: Frenkel TUD 2012-03" | ||
| 1500 | input list<Integer> stack; | ||
| 1501 | input Integer i; | ||
| 1502 | input Integer c; | ||
| 1503 | input Integer nv; | ||
| 1504 | input Integer ne; | ||
| 1505 | input BackendDAE.AdjacencyMatrix m; | ||
| 1506 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 1507 | input array<Integer> rowmarks; | ||
| 1508 | input array<Integer> lookahead; | ||
| 1509 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 1510 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 1511 | input list<Integer> inVisitedColums; | ||
| 1512 | output list<Integer> outVisitedColums "This list stores all visited collums, if no augmenting path is found | ||
| 1513 | it could be used to prune the nodes, if a path is found the list is empty"; | ||
| 1514 | algorithm | ||
| 1515 | outVisitedColums := | ||
| 1516 | match stack | ||
| 1517 | local | ||
| 1518 | list<Integer> rows; | ||
| 1519 | Boolean b; | ||
| 1520 | case {} then inVisitedColums; | ||
| 1521 | case _ | ||
| 1522 | algorithm | ||
| 1523 | // traverse all adiacent rows | ||
| 1524 | ✗ | rows := List.select(m[c], Util.intPositive); | |
| 1525 | ✗ | b := intLt(lookahead[c],listLength(rows)); | |
| 1526 | ✗ | then | |
| 1527 | MC21Achecklookahead(b,rows,stack,i,c,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,inVisitedColums); | ||
| 1528 | else | ||
| 1529 | algorithm | ||
| 1530 | ✗ | Error.addInternalError("function MC21Aphase failed in equation " + intString(c), sourceInfo()); | |
| 1531 | ✗ | then | |
| 1532 | fail(); | ||
| 1533 | end match; | ||
| 1534 | end MC21Aphase; | ||
| 1535 | |||
| 1536 | protected function MC21Achecklookahead | ||
| 1537 | "function helper for MC21A, traverses all vars of a equations and search a augmenting path | ||
| 1538 | author: Frenkel TUD 2012-03" | ||
| 1539 | input Boolean dolookahaed; | ||
| 1540 | input list<Integer> rows; | ||
| 1541 | input list<Integer> stack; | ||
| 1542 | input Integer i; | ||
| 1543 | input Integer c; | ||
| 1544 | input Integer nv; | ||
| 1545 | input Integer ne; | ||
| 1546 | input BackendDAE.AdjacencyMatrix m; | ||
| 1547 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 1548 | input array<Integer> rowmarks; | ||
| 1549 | input array<Integer> lookahead; | ||
| 1550 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 1551 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 1552 | input list<Integer> inVisitedColums; | ||
| 1553 | output list<Integer> outVisitedColums; | ||
| 1554 | algorithm | ||
| 1555 | ✗ | outVisitedColums:= | |
| 1556 | match dolookahaed | ||
| 1557 | case true | ||
| 1558 | then | ||
| 1559 | MC21AtraverseRowsUnmatched(rows,rows,stack,i,c,listLength(rows),nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,inVisitedColums); | ||
| 1560 | else | ||
| 1561 | MC21AtraverseRows(rows,stack,i,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,inVisitedColums); | ||
| 1562 | end match; | ||
| 1563 | end MC21Achecklookahead; | ||
| 1564 | |||
| 1565 | protected function MC21AtraverseRowsUnmatched | ||
| 1566 | "function helper for MC21A, traverses all vars of a equations and search a augmenting path | ||
| 1567 | author: Frenkel TUD 2012-03" | ||
| 1568 | input list<Integer> rows; | ||
| 1569 | input list<Integer> rows1; | ||
| 1570 | input list<Integer> stack; | ||
| 1571 | input Integer i; | ||
| 1572 | input Integer c; | ||
| 1573 | input Integer l; | ||
| 1574 | input Integer nv; | ||
| 1575 | input Integer ne; | ||
| 1576 | input BackendDAE.AdjacencyMatrix m; | ||
| 1577 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 1578 | input array<Integer> rowmarks; | ||
| 1579 | input array<Integer> lookahead; | ||
| 1580 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 1581 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 1582 | input list<Integer> inVisitedColums; | ||
| 1583 | output list<Integer> outVisitedColums; | ||
| 1584 | algorithm | ||
| 1585 | outVisitedColums:= | ||
| 1586 | matchcontinue rows | ||
| 1587 | local | ||
| 1588 | list<Integer> rest; | ||
| 1589 | Integer r; | ||
| 1590 | case {} | ||
| 1591 | algorithm | ||
| 1592 | ✗ | arrayUpdate(lookahead,c,l); | |
| 1593 | ✗ | then | |
| 1594 | MC21AtraverseRows(rows1,stack,i,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,inVisitedColums); | ||
| 1595 | case r::_ | ||
| 1596 | algorithm | ||
| 1597 | // row is unmatched -> augmenting path found | ||
| 1598 | ✗ | true := intLt(ass2[r],0); | |
| 1599 | ✗ | DFSBreasign(stack,r,ass1,ass2); | |
| 1600 | then | ||
| 1601 | {}; | ||
| 1602 | case _::rest | ||
| 1603 | ✗ | then | |
| 1604 | MC21AtraverseRowsUnmatched(rest,rows1,stack,i,c,l,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,inVisitedColums); | ||
| 1605 | end matchcontinue; | ||
| 1606 | end MC21AtraverseRowsUnmatched; | ||
| 1607 | |||
| 1608 | protected function MC21AtraverseRows | ||
| 1609 | "function helper for MC21A, traverses all vars of a equations and search a augmenting path | ||
| 1610 | author: Frenkel TUD 2012-03" | ||
| 1611 | input list<Integer> rows; | ||
| 1612 | input list<Integer> stack; | ||
| 1613 | input Integer i; | ||
| 1614 | input Integer nv; | ||
| 1615 | input Integer ne; | ||
| 1616 | input BackendDAE.AdjacencyMatrix m; | ||
| 1617 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 1618 | input array<Integer> rowmarks; | ||
| 1619 | input array<Integer> lookahead; | ||
| 1620 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 1621 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 1622 | input list<Integer> inVisitedColums; | ||
| 1623 | output list<Integer> outVisitedColums; | ||
| 1624 | algorithm | ||
| 1625 | outVisitedColums:= | ||
| 1626 | matchcontinue rows | ||
| 1627 | local | ||
| 1628 | list<Integer> rest,visitedColums; | ||
| 1629 | Integer rc,r; | ||
| 1630 | case {} then inVisitedColums; | ||
| 1631 | case r::rest | ||
| 1632 | algorithm | ||
| 1633 | // row is matched | ||
| 1634 | ✗ | rc := ass2[r]; | |
| 1635 | ✗ | false := intLt(rc,0); | |
| 1636 | ✗ | true := intLt(rowmarks[r],i); | |
| 1637 | ✗ | arrayUpdate(rowmarks,r,i); | |
| 1638 | ✗ | visitedColums := MC21Aphase(rc::stack,i,rc,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,rc::inVisitedColums); | |
| 1639 | ✗ | then | |
| 1640 | MC21AtraverseRows1(rest,stack,i,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,visitedColums); | ||
| 1641 | case _::rest | ||
| 1642 | ✗ | then | |
| 1643 | MC21AtraverseRows(rest,stack,i,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,inVisitedColums); | ||
| 1644 | else | ||
| 1645 | algorithm | ||
| 1646 | ✗ | Error.addInternalError("function MC21AtraverseRows failed", sourceInfo()); | |
| 1647 | ✗ | then | |
| 1648 | fail(); | ||
| 1649 | end matchcontinue; | ||
| 1650 | end MC21AtraverseRows; | ||
| 1651 | |||
| 1652 | protected function MC21AtraverseRows1 | ||
| 1653 | "function helper for MC21AtraverseRows | ||
| 1654 | author: Frenkel TUD 2012-03" | ||
| 1655 | input list<Integer> rows; | ||
| 1656 | input list<Integer> stack; | ||
| 1657 | input Integer i; | ||
| 1658 | input Integer nv; | ||
| 1659 | input Integer ne; | ||
| 1660 | input BackendDAE.AdjacencyMatrix m; | ||
| 1661 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 1662 | input array<Integer> rowmarks; | ||
| 1663 | input array<Integer> lookahead; | ||
| 1664 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 1665 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 1666 | input list<Integer> inVisitedColums; | ||
| 1667 | output list<Integer> outVisitedColums; | ||
| 1668 | algorithm | ||
| 1669 | outVisitedColums:= | ||
| 1670 | match inVisitedColums | ||
| 1671 | case {} then inVisitedColums; | ||
| 1672 | ✗ | else MC21AtraverseRows(rows,stack,i,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,inVisitedColums); | |
| 1673 | end match; | ||
| 1674 | end MC21AtraverseRows1; | ||
| 1675 | |||
| 1676 | |||
| 1677 | public function PF | ||
| 1678 | " complexity O(n*tau) | ||
| 1679 | author: Frenkel TUD 2012-03" | ||
| 1680 | input BackendDAE.EqSystem isyst; | ||
| 1681 | input BackendDAE.Shared ishared; | ||
| 1682 | input Boolean clearMatching; | ||
| 1683 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 1684 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 1685 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 1686 | output BackendDAE.EqSystem osyst; | ||
| 1687 | output BackendDAE.Shared oshared; | ||
| 1688 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 1689 | algorithm | ||
| 1690 | (osyst,oshared,outArg) := | ||
| 1691 | matchcontinue isyst | ||
| 1692 | local | ||
| 1693 | Integer nvars,neqns; | ||
| 1694 | BackendDAE.AdjacencyMatrix m; | ||
| 1695 | BackendDAE.AdjacencyMatrixT mt; | ||
| 1696 | array<Integer> vec1,vec2; | ||
| 1697 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 1698 | BackendDAE.EqSystem syst; | ||
| 1699 | BackendDAE.Shared shared; | ||
| 1700 | array<Integer> rowmarks,lookahead; | ||
| 1701 | list<Integer> unmatched; | ||
| 1702 | case BackendDAE.EQSYSTEM(m=SOME(m),mT=SOME(mt)) | ||
| 1703 | algorithm | ||
| 1704 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 1705 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 1706 | ✗ | true := intGt(nvars,0); | |
| 1707 | ✗ | true := intGt(neqns,0); | |
| 1708 | ✗ | (vec1,vec2) := getAssignment(clearMatching,nvars,neqns,isyst); | |
| 1709 | ✗ | rowmarks := arrayCreate(nvars,-1); | |
| 1710 | ✗ | lookahead := arrayCreate(neqns,0); | |
| 1711 | ✗ | unmatched := cheapmatchingalgorithm(nvars,neqns,m,mt,vec1,vec2,true); | |
| 1712 | ✗ | (vec1,vec2,syst,shared,arg) := PF1(0,unmatched,rowmarks,lookahead,isyst,ishared,nvars,neqns,vec1,vec2,inMatchingOptions,sssHandler,inArg); | |
| 1713 | ✗ | syst := BackendDAEUtil.setEqSystMatching(syst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 1714 | ✗ | then | |
| 1715 | (syst,shared,arg); | ||
| 1716 | // fail case if system is empty | ||
| 1717 | case _ | ||
| 1718 | algorithm | ||
| 1719 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 1720 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 1721 | ✗ | false := intGt(nvars,0); | |
| 1722 | ✗ | false := intGt(neqns,0); | |
| 1723 | ✗ | vec1 := listArray({}); | |
| 1724 | ✗ | vec2 := listArray({}); | |
| 1725 | ✗ | syst := BackendDAEUtil.setEqSystMatching(isyst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 1726 | then | ||
| 1727 | (syst,ishared,inArg); | ||
| 1728 | else | ||
| 1729 | algorithm | ||
| 1730 | ✗ | if Flags.isSet(Flags.FAILTRACE) then | |
| 1731 | ✗ | Debug.trace("- Matching.PF failed\n"); | |
| 1732 | end if; | ||
| 1733 | ✗ | then | |
| 1734 | fail(); | ||
| 1735 | end matchcontinue; | ||
| 1736 | end PF; | ||
| 1737 | |||
| 1738 | protected function PF1 | ||
| 1739 | "function: PF1, helper for PF | ||
| 1740 | author: Frenkel TUD 2012-03" | ||
| 1741 | input Integer i; | ||
| 1742 | input list<Integer> unmatched; | ||
| 1743 | input array<Integer> rowmarks; | ||
| 1744 | input array<Integer> lookahead; | ||
| 1745 | input BackendDAE.EqSystem isyst; | ||
| 1746 | input BackendDAE.Shared ishared; | ||
| 1747 | input Integer nv; | ||
| 1748 | input Integer ne; | ||
| 1749 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 1750 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 1751 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 1752 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 1753 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 1754 | output array<Integer> outAss1; | ||
| 1755 | output array<Integer> outAss2; | ||
| 1756 | output BackendDAE.EqSystem osyst; | ||
| 1757 | output BackendDAE.Shared oshared; | ||
| 1758 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 1759 | algorithm | ||
| 1760 | (outAss1,outAss2,osyst,oshared,outArg):= | ||
| 1761 | match (unmatched, isyst) | ||
| 1762 | local | ||
| 1763 | BackendDAE.AdjacencyMatrix m,mt; | ||
| 1764 | Integer nv_1,ne_1,i_1; | ||
| 1765 | list<Integer> unmatched1; | ||
| 1766 | list<list<Integer>> meqns; | ||
| 1767 | BackendDAE.StructurallySingularSystemHandlerArg arg,arg1; | ||
| 1768 | BackendDAE.EqSystem syst; | ||
| 1769 | BackendDAE.Shared shared; | ||
| 1770 | array<Integer> ass1_1,ass1_2,ass2_1,ass2_2,rowmarks1,lookahead1; | ||
| 1771 | case ({}, _) | ||
| 1772 | then | ||
| 1773 | (ass1,ass2,isyst,ishared,inArg); | ||
| 1774 | case (_, BackendDAE.EQSYSTEM(m=SOME(m),mT=SOME(mt))) | ||
| 1775 | algorithm | ||
| 1776 | ✗ | (i_1,unmatched1) := PFaugmentmatching(i,unmatched,nv,ne,m,mt,rowmarks,lookahead,ass1,ass2,listLength(unmatched),{}); | |
| 1777 | ✗ | meqns := getEqnsforIndexReduction(unmatched1,ne,m,mt,ass1,ass2,inArg); | |
| 1778 | ✗ | (unmatched1,rowmarks1,lookahead1,nv_1,ne_1,ass1_1,ass2_1,syst,shared,arg) := PF2(meqns,unmatched1,{},rowmarks,lookahead,isyst,ishared,nv,ne,ass1,ass2,inMatchingOptions,sssHandler,inArg); | |
| 1779 | ✗ | (ass1_2,ass2_2,syst,shared,arg1) := PF1(i_1+1,unmatched1,rowmarks1,lookahead1,syst,shared,nv_1,ne_1,ass1_1,ass2_1,inMatchingOptions,sssHandler,arg); | |
| 1780 | then | ||
| 1781 | (ass1_2,ass2_2,syst,shared,arg1); | ||
| 1782 | end match; | ||
| 1783 | end PF1; | ||
| 1784 | |||
| 1785 | protected function PF2 | ||
| 1786 | "function: PF2, helper for PF | ||
| 1787 | author: Frenkel TUD 2012-03" | ||
| 1788 | input list<list<Integer>> meqns "Marked Equations for Index Reduction"; | ||
| 1789 | input list<Integer> unmatched; | ||
| 1790 | input list<Integer> changedEqns; | ||
| 1791 | input array<Integer> rowmarks; | ||
| 1792 | input array<Integer> lookahead; | ||
| 1793 | input BackendDAE.EqSystem isyst; | ||
| 1794 | input BackendDAE.Shared ishared; | ||
| 1795 | input Integer nv; | ||
| 1796 | input Integer ne; | ||
| 1797 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 1798 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 1799 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 1800 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 1801 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 1802 | output list<Integer> outunmatched; | ||
| 1803 | output array<Integer> outrowmarks; | ||
| 1804 | output array<Integer> outlookahead; | ||
| 1805 | output Integer nvars; | ||
| 1806 | output Integer neqns; | ||
| 1807 | output array<Integer> outAss1; | ||
| 1808 | output array<Integer> outAss2; | ||
| 1809 | output BackendDAE.EqSystem osyst; | ||
| 1810 | output BackendDAE.Shared oshared; | ||
| 1811 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 1812 | algorithm | ||
| 1813 | (outunmatched,outrowmarks,outlookahead,nvars,neqns,outAss1,outAss2,osyst,oshared,outArg):= | ||
| 1814 | match (meqns, inMatchingOptions) | ||
| 1815 | local | ||
| 1816 | Integer nv_1,ne_1; | ||
| 1817 | list<Integer> unmatched1; | ||
| 1818 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 1819 | BackendDAE.EqSystem syst; | ||
| 1820 | BackendDAE.Shared shared; | ||
| 1821 | array<Integer> ass1_1,ass2_1,rowmarks1,lookahead1; | ||
| 1822 | |||
| 1823 | case ({}, _) | ||
| 1824 | then | ||
| 1825 | (unmatched,rowmarks,lookahead,nv,ne,ass1,ass2,isyst,ishared,inArg); | ||
| 1826 | case (_, (BackendDAE.INDEX_REDUCTION(),_)) | ||
| 1827 | algorithm | ||
| 1828 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | (unmatched1,_,syst,shared,ass2_1,ass1_1,arg) := sssHandler(meqns,0,isyst,ishared,ass2,ass1,inArg); |
| 1829 | 2 | ne_1 := BackendDAEUtil.systemSize(syst); | |
| 1830 | 2 | nv_1 := BackendVariable.daenumVariables(syst); | |
| 1831 | 2 | ass1_1 := assignmentsArrayExpand(ass1_1,ne_1,ne,-1); | |
| 1832 | 2 | ass2_1 := assignmentsArrayExpand(ass2_1,nv_1,nv,-1); | |
| 1833 | 2 | rowmarks1 := assignmentsArrayExpand(rowmarks,nv_1,nv,-1); | |
| 1834 | 2 | lookahead1 := assignmentsArrayExpand(lookahead,ne_1,ne,0); | |
| 1835 | 2 | MC21A1fixArray(unmatched1,lookahead1); | |
| 1836 | 2 | then | |
| 1837 | (unmatched1,rowmarks1,lookahead1,nv_1,ne_1,ass1_1,ass2_1,syst,shared,arg); | ||
| 1838 | case (_, _) | ||
| 1839 | algorithm | ||
| 1840 | ✗ | singularSystemError(meqns,0,isyst,ishared,ass1,ass2,inArg); | |
| 1841 | ✗ | then | |
| 1842 | fail(); | ||
| 1843 | end match; | ||
| 1844 | end PF2; | ||
| 1845 | |||
| 1846 | protected function PFaugmentmatching | ||
| 1847 | "function helper for PFaugmentmatching, traverses all unmatched | ||
| 1848 | colums and perform one pass of the augmenting proceure | ||
| 1849 | author: Frenkel TUD 2012-03" | ||
| 1850 | input Integer i; | ||
| 1851 | input list<Integer> U; | ||
| 1852 | input Integer nv; | ||
| 1853 | input Integer ne; | ||
| 1854 | input BackendDAE.AdjacencyMatrix m "m[eqnindx] = list(varindx)"; | ||
| 1855 | input BackendDAE.AdjacencyMatrixT mT "mT[varindx] = list(eqnindx)"; | ||
| 1856 | input array<Integer> rowmarks; | ||
| 1857 | input array<Integer> lookahead; | ||
| 1858 | input array<Integer> ass1 "ass[eqnindx]=varindx"; | ||
| 1859 | input array<Integer> ass2 "ass[varindx]=eqnindx"; | ||
| 1860 | input Integer previousUnmatched; | ||
| 1861 | input list<Integer> unMatched; | ||
| 1862 | output Integer outI; | ||
| 1863 | output list<Integer> outUnmatched; | ||
| 1864 | algorithm | ||
| 1865 | (outI,outUnmatched):= | ||
| 1866 | matchcontinue U | ||
| 1867 | local | ||
| 1868 | list<Integer> rest,unmatched; | ||
| 1869 | Integer c,i_1; | ||
| 1870 | Boolean b; | ||
| 1871 | case {} | ||
| 1872 | algorithm | ||
| 1873 | // no augmenting path is found in pass | ||
| 1874 | ✗ | true:=intEq(previousUnmatched,listLength(unMatched)); | |
| 1875 | ✗ | then | |
| 1876 | (i,unMatched); | ||
| 1877 | case {} | ||
| 1878 | algorithm | ||
| 1879 | // augmenting path is found in pass, next round | ||
| 1880 | ✗ | (i_1,unmatched) := PFaugmentmatching(i+1,unMatched,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,listLength(unMatched),{}); | |
| 1881 | then | ||
| 1882 | (i_1,unmatched); | ||
| 1883 | case c::rest | ||
| 1884 | algorithm | ||
| 1885 | ✗ | true := intGt(ass1[c],-1); | |
| 1886 | ✗ | (i_1,unmatched) := PFaugmentmatching(i,rest,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,previousUnmatched,unMatched); | |
| 1887 | then | ||
| 1888 | (i_1,unmatched); | ||
| 1889 | case c::rest | ||
| 1890 | algorithm | ||
| 1891 | ✗ | b := PFphase({c},i,c,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2); | |
| 1892 | ✗ | unmatched := List.consOnTrue(not b, c, unMatched); | |
| 1893 | ✗ | (i_1,unmatched) := PFaugmentmatching(i,rest,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,previousUnmatched,unmatched); | |
| 1894 | then | ||
| 1895 | (i_1,unmatched); | ||
| 1896 | else | ||
| 1897 | algorithm | ||
| 1898 | ✗ | Error.addInternalError("function PFaugmentmatching failed", sourceInfo()); | |
| 1899 | ✗ | then | |
| 1900 | fail(); | ||
| 1901 | end matchcontinue; | ||
| 1902 | end PFaugmentmatching; | ||
| 1903 | |||
| 1904 | protected function PFphase | ||
| 1905 | "function helper for PF, traverses all colums and perform a PF phase on each | ||
| 1906 | author: Frenkel TUD 2012-03" | ||
| 1907 | input list<Integer> stack; | ||
| 1908 | input Integer i; | ||
| 1909 | input Integer c; | ||
| 1910 | input Integer nv; | ||
| 1911 | input Integer ne; | ||
| 1912 | input BackendDAE.AdjacencyMatrix m; | ||
| 1913 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 1914 | input array<Integer> rowmarks; | ||
| 1915 | input array<Integer> lookahead; | ||
| 1916 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 1917 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 1918 | output Boolean matched; | ||
| 1919 | algorithm | ||
| 1920 | matched := | ||
| 1921 | match stack | ||
| 1922 | local | ||
| 1923 | list<Integer> rows; | ||
| 1924 | Boolean b; | ||
| 1925 | case {} then false; | ||
| 1926 | case _ | ||
| 1927 | algorithm | ||
| 1928 | // traverse all adiacent rows | ||
| 1929 | ✗ | rows := List.select(m[c], Util.intPositive); | |
| 1930 | ✗ | b := intLt(lookahead[c],listLength(rows)); | |
| 1931 | ✗ | then | |
| 1932 | PFchecklookahead(b,rows,stack,i,c,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2); | ||
| 1933 | else | ||
| 1934 | algorithm | ||
| 1935 | ✗ | Error.addInternalError("function PFphase failed in equation " + intString(c), sourceInfo()); | |
| 1936 | ✗ | then | |
| 1937 | fail(); | ||
| 1938 | |||
| 1939 | end match; | ||
| 1940 | end PFphase; | ||
| 1941 | |||
| 1942 | protected function PFchecklookahead | ||
| 1943 | "function helper for PF, traverses all vars of a equations and search a augmenting path | ||
| 1944 | author: Frenkel TUD 2012-03" | ||
| 1945 | input Boolean dolookahaed; | ||
| 1946 | input list<Integer> rows; | ||
| 1947 | input list<Integer> stack; | ||
| 1948 | input Integer i; | ||
| 1949 | input Integer c; | ||
| 1950 | input Integer nv; | ||
| 1951 | input Integer ne; | ||
| 1952 | input BackendDAE.AdjacencyMatrix m; | ||
| 1953 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 1954 | input array<Integer> rowmarks; | ||
| 1955 | input array<Integer> lookahead; | ||
| 1956 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 1957 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 1958 | output Boolean matched; | ||
| 1959 | algorithm | ||
| 1960 | ✗ | matched:= | |
| 1961 | match dolookahaed | ||
| 1962 | case true | ||
| 1963 | then | ||
| 1964 | PFtraverseRowsUnmatched(rows,rows,stack,i,c,listLength(rows),nv,ne,m,mT,rowmarks,lookahead,ass1,ass2); | ||
| 1965 | else | ||
| 1966 | PFtraverseRows(rows,stack,i,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2); | ||
| 1967 | end match; | ||
| 1968 | end PFchecklookahead; | ||
| 1969 | |||
| 1970 | protected function PFtraverseRowsUnmatched | ||
| 1971 | "function helper for PF, traverses all vars of a equations and search a augmenting path | ||
| 1972 | author: Frenkel TUD 2012-03" | ||
| 1973 | input list<Integer> rows; | ||
| 1974 | input list<Integer> rows1; | ||
| 1975 | input list<Integer> stack; | ||
| 1976 | input Integer i; | ||
| 1977 | input Integer c; | ||
| 1978 | input Integer l; | ||
| 1979 | input Integer nv; | ||
| 1980 | input Integer ne; | ||
| 1981 | input BackendDAE.AdjacencyMatrix m; | ||
| 1982 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 1983 | input array<Integer> rowmarks; | ||
| 1984 | input array<Integer> lookahead; | ||
| 1985 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 1986 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 1987 | output Boolean matched; | ||
| 1988 | algorithm | ||
| 1989 | matched:= | ||
| 1990 | matchcontinue rows | ||
| 1991 | local | ||
| 1992 | list<Integer> rest; | ||
| 1993 | Integer r; | ||
| 1994 | case {} | ||
| 1995 | algorithm | ||
| 1996 | ✗ | arrayUpdate(lookahead,c,l); | |
| 1997 | ✗ | then | |
| 1998 | PFtraverseRows(rows1,stack,i,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2); | ||
| 1999 | case r::_ | ||
| 2000 | algorithm | ||
| 2001 | // row is unmatched -> augmenting path found | ||
| 2002 | ✗ | true := intLt(ass2[r],0); | |
| 2003 | ✗ | DFSBreasign(stack,r,ass1,ass2); | |
| 2004 | then | ||
| 2005 | true; | ||
| 2006 | case _::rest | ||
| 2007 | ✗ | then | |
| 2008 | PFtraverseRowsUnmatched(rest,rows1,stack,i,c,l,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2); | ||
| 2009 | end matchcontinue; | ||
| 2010 | end PFtraverseRowsUnmatched; | ||
| 2011 | |||
| 2012 | protected function PFtraverseRows | ||
| 2013 | "function helper for PF, traverses all vars of a equations and search a augmenting path | ||
| 2014 | author: Frenkel TUD 2012-03" | ||
| 2015 | input list<Integer> rows; | ||
| 2016 | input list<Integer> stack; | ||
| 2017 | input Integer i; | ||
| 2018 | input Integer nv; | ||
| 2019 | input Integer ne; | ||
| 2020 | input BackendDAE.AdjacencyMatrix m; | ||
| 2021 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 2022 | input array<Integer> rowmarks; | ||
| 2023 | input array<Integer> lookahead; | ||
| 2024 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 2025 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 2026 | output Boolean matched; | ||
| 2027 | algorithm | ||
| 2028 | matched:= | ||
| 2029 | matchcontinue rows | ||
| 2030 | local | ||
| 2031 | list<Integer> rest; | ||
| 2032 | Integer rc,r; | ||
| 2033 | Boolean b; | ||
| 2034 | case {} then false; | ||
| 2035 | case r::rest | ||
| 2036 | algorithm | ||
| 2037 | // row is matched | ||
| 2038 | ✗ | rc := ass2[r]; | |
| 2039 | ✗ | false := intLt(rc,0); | |
| 2040 | ✗ | false := intEq(rowmarks[r],i); | |
| 2041 | ✗ | arrayUpdate(rowmarks,r,i); | |
| 2042 | ✗ | b := PFphase(rc::stack,i,rc,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2); | |
| 2043 | ✗ | then | |
| 2044 | PFtraverseRows1(rest,stack,i,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,b); | ||
| 2045 | case _::rest | ||
| 2046 | ✗ | then | |
| 2047 | PFtraverseRows(rest,stack,i,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2); | ||
| 2048 | else | ||
| 2049 | algorithm | ||
| 2050 | ✗ | Error.addInternalError("function PFtraverseRows failed", sourceInfo()); | |
| 2051 | ✗ | then | |
| 2052 | fail(); | ||
| 2053 | end matchcontinue; | ||
| 2054 | end PFtraverseRows; | ||
| 2055 | |||
| 2056 | protected function PFtraverseRows1 | ||
| 2057 | "function helper for PFtraverseRows | ||
| 2058 | author: Frenkel TUD 2012-03" | ||
| 2059 | input list<Integer> rows; | ||
| 2060 | input list<Integer> stack; | ||
| 2061 | input Integer i; | ||
| 2062 | input Integer nv; | ||
| 2063 | input Integer ne; | ||
| 2064 | input BackendDAE.AdjacencyMatrix m; | ||
| 2065 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 2066 | input array<Integer> rowmarks; | ||
| 2067 | input array<Integer> lookahead; | ||
| 2068 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 2069 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 2070 | input Boolean inMatched; | ||
| 2071 | output Boolean matched; | ||
| 2072 | algorithm | ||
| 2073 | ✗ | matched:= | |
| 2074 | match inMatched | ||
| 2075 | case true then inMatched; | ||
| 2076 | else PFtraverseRows(rows,stack,i,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2); | ||
| 2077 | end match; | ||
| 2078 | end PFtraverseRows1; | ||
| 2079 | |||
| 2080 | public function PFPlus | ||
| 2081 | " complexity O(n*tau) | ||
| 2082 | author: Frenkel TUD 2012-03" | ||
| 2083 | input BackendDAE.EqSystem isyst; | ||
| 2084 | input BackendDAE.Shared ishared; | ||
| 2085 | input Boolean clearMatching; | ||
| 2086 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 2087 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 2088 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 2089 | output BackendDAE.EqSystem osyst; | ||
| 2090 | output BackendDAE.Shared oshared; | ||
| 2091 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 2092 | algorithm | ||
| 2093 | (osyst,oshared,outArg) := | ||
| 2094 | matchcontinue isyst | ||
| 2095 | local | ||
| 2096 | Integer nvars,neqns; | ||
| 2097 | BackendDAE.AdjacencyMatrix m; | ||
| 2098 | BackendDAE.AdjacencyMatrixT mt; | ||
| 2099 | array<Integer> vec1,vec2; | ||
| 2100 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 2101 | BackendDAE.EqSystem syst; | ||
| 2102 | BackendDAE.Shared shared; | ||
| 2103 | array<Integer> rowmarks,lookahead; | ||
| 2104 | list<Integer> unmatched; | ||
| 2105 | case BackendDAE.EQSYSTEM(m=SOME(m),mT=SOME(mt)) | ||
| 2106 | algorithm | ||
| 2107 | 646 | neqns := BackendDAEUtil.systemSize(isyst); | |
| 2108 | 646 | nvars := BackendVariable.daenumVariables(isyst); | |
| 2109 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 646 times.
|
646 | true := intGt(nvars,0); |
| 2110 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 646 times.
|
646 | true := intGt(neqns,0); |
| 2111 | 646 | (vec1,vec2) := getAssignment(clearMatching,nvars,neqns,isyst); | |
| 2112 | 646 | rowmarks := arrayCreate(nvars,-1); | |
| 2113 | 646 | lookahead := arrayCreate(neqns,0); | |
| 2114 | 646 | unmatched := cheapmatchingalgorithm(nvars,neqns,m,mt,vec1,vec2,true); | |
| 2115 | 646 | (_,vec1,vec2,syst,shared,arg) := PFPlus1(0,unmatched,rowmarks,lookahead,isyst,ishared,nvars,neqns,vec1,vec2,inMatchingOptions,sssHandler,inArg); | |
| 2116 | 646 | syst := BackendDAEUtil.setEqSystMatching(syst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 2117 | 646 | then | |
| 2118 | (syst,shared,arg); | ||
| 2119 | // fail case if system is empty | ||
| 2120 | case _ | ||
| 2121 | algorithm | ||
| 2122 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 2123 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 2124 | ✗ | false := intGt(nvars,0); | |
| 2125 | ✗ | false := intGt(neqns,0); | |
| 2126 | ✗ | vec1 := listArray({}); | |
| 2127 | ✗ | vec2 := listArray({}); | |
| 2128 | ✗ | syst := BackendDAEUtil.setEqSystMatching(isyst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 2129 | then | ||
| 2130 | (syst,ishared,inArg); | ||
| 2131 | else | ||
| 2132 | algorithm | ||
| 2133 | ✗ | if Flags.isSet(Flags.FAILTRACE) then | |
| 2134 | ✗ | Debug.trace("- Matching.PFPlus failed\n"); | |
| 2135 | end if; | ||
| 2136 | ✗ | then | |
| 2137 | fail(); | ||
| 2138 | end matchcontinue; | ||
| 2139 | end PFPlus; | ||
| 2140 | |||
| 2141 | protected function PFPlus1 | ||
| 2142 | "function: PFPlus1, helper for PFPlus | ||
| 2143 | author: Frenkel TUD 2012-03" | ||
| 2144 | input Integer i; | ||
| 2145 | input list<Integer> unmatched; | ||
| 2146 | input array<Integer> rowmarks; | ||
| 2147 | input array<Integer> lookahead; | ||
| 2148 | input BackendDAE.EqSystem isyst; | ||
| 2149 | input BackendDAE.Shared ishared; | ||
| 2150 | input Integer nv; | ||
| 2151 | input Integer ne; | ||
| 2152 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 2153 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 2154 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 2155 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 2156 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 2157 | output Integer outI; | ||
| 2158 | output array<Integer> outAss1; | ||
| 2159 | output array<Integer> outAss2; | ||
| 2160 | output BackendDAE.EqSystem osyst; | ||
| 2161 | output BackendDAE.Shared oshared; | ||
| 2162 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 2163 | algorithm | ||
| 2164 | (outI,outAss1,outAss2,osyst,oshared,outArg):= | ||
| 2165 | match (unmatched, isyst) | ||
| 2166 | local | ||
| 2167 | BackendDAE.AdjacencyMatrix m,mt; | ||
| 2168 | Integer nv_1,ne_1,i_1; | ||
| 2169 | list<Integer> unmatched1; | ||
| 2170 | list<list<Integer>> meqns; | ||
| 2171 | BackendDAE.StructurallySingularSystemHandlerArg arg,arg1; | ||
| 2172 | BackendDAE.EqSystem syst; | ||
| 2173 | BackendDAE.Shared shared; | ||
| 2174 | array<Integer> ass1_1,ass1_2,ass2_1,ass2_2,rowmarks1,lookahead1; | ||
| 2175 | case ({}, _) | ||
| 2176 | then | ||
| 2177 | (i,ass1,ass2,isyst,ishared,inArg); | ||
| 2178 | case (_, syst as BackendDAE.EQSYSTEM(m=SOME(m),mT=SOME(mt))) | ||
| 2179 | algorithm | ||
| 2180 | 11 | (i_1,unmatched1) := PFPlusaugmentmatching(i,unmatched,nv,ne,m,mt,rowmarks,lookahead,ass1,ass2,listLength(unmatched),{},false); | |
| 2181 | 11 | meqns := getEqnsforIndexReduction(unmatched1,ne,m,mt,ass1,ass2,inArg); | |
| 2182 | 11 | (unmatched1,rowmarks1,lookahead1,nv_1,ne_1,ass1_1,ass2_1,syst,shared,arg) := PF2(meqns,unmatched1,{},rowmarks,lookahead,syst,ishared,nv,ne,ass1,ass2,inMatchingOptions,sssHandler,inArg); | |
| 2183 | 11 | (i_1,ass1_2,ass2_2,syst,shared,arg1) := PFPlus1(i_1+1,unmatched1,rowmarks1,lookahead1,syst,shared,nv_1,ne_1,ass1_1,ass2_1,inMatchingOptions,sssHandler,arg); | |
| 2184 | then | ||
| 2185 | (i_1,ass1_2,ass2_2,syst,shared,arg1); | ||
| 2186 | end match; | ||
| 2187 | end PFPlus1; | ||
| 2188 | |||
| 2189 | protected function PFPlusaugmentmatching | ||
| 2190 | "function helper for PFPlusaugmentmatching, traverses all unmatched | ||
| 2191 | colums and perform one pass of the augmenting proceure | ||
| 2192 | author: Frenkel TUD 2012-03" | ||
| 2193 | input Integer i; | ||
| 2194 | input list<Integer> U; | ||
| 2195 | input Integer nv; | ||
| 2196 | input Integer ne; | ||
| 2197 | input BackendDAE.AdjacencyMatrix m "m[eqnindx] = list(varindx)"; | ||
| 2198 | input BackendDAE.AdjacencyMatrixT mT "mT[varindx] = list(eqnindx)"; | ||
| 2199 | input array<Integer> rowmarks; | ||
| 2200 | input array<Integer> lookahead; | ||
| 2201 | input array<Integer> ass1 "ass[eqnindx]=varindx"; | ||
| 2202 | input array<Integer> ass2 "ass[varindx]=eqnindx"; | ||
| 2203 | input Integer previousUnmatched; | ||
| 2204 | input list<Integer> unMatched; | ||
| 2205 | input Boolean reverseRows; | ||
| 2206 | output Integer outI; | ||
| 2207 | output list<Integer> outUnMatched; | ||
| 2208 | algorithm | ||
| 2209 | (outI,outUnMatched) := | ||
| 2210 | matchcontinue U | ||
| 2211 | local | ||
| 2212 | list<Integer> rest,unmatched; | ||
| 2213 | Integer c,i_1; | ||
| 2214 | Boolean b; | ||
| 2215 | case {} | ||
| 2216 | algorithm | ||
| 2217 | // no augmenting path is found in pass | ||
| 2218 |
2/2✓ Branch 1 taken 13 times.
✓ Branch 2 taken 11 times.
|
24 | true:=intEq(previousUnmatched,listLength(unMatched)); |
| 2219 | 11 | then | |
| 2220 | (i,unMatched); | ||
| 2221 | case {} | ||
| 2222 | algorithm | ||
| 2223 | // augmenting path is found in pass, next round | ||
| 2224 | 13 | (i_1,unmatched) := PFPlusaugmentmatching(i+1,unMatched,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,listLength(unMatched),{},reverseRows); | |
| 2225 | then | ||
| 2226 | (i_1,unmatched); | ||
| 2227 | case c::rest | ||
| 2228 | algorithm | ||
| 2229 |
1/2✓ Branch 1 taken 89 times.
✗ Branch 2 not taken.
|
89 | true := intGt(ass1[c],-1); |
| 2230 | ✗ | (i_1,unmatched) := PFPlusaugmentmatching(i,rest,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,previousUnmatched,unMatched,reverseRows); | |
| 2231 | then | ||
| 2232 | (i_1,unmatched); | ||
| 2233 | case c::rest | ||
| 2234 | algorithm | ||
| 2235 | 89 | b := PFPlusphase({c},i,c,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,reverseRows); | |
| 2236 | 89 | unmatched := List.consOnTrue(not b, c, unMatched); | |
| 2237 | 89 | (i_1,unmatched) := PFPlusaugmentmatching(i,rest,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,previousUnmatched,unmatched,not reverseRows); | |
| 2238 | then | ||
| 2239 | (i_1,unmatched); | ||
| 2240 | else | ||
| 2241 | algorithm | ||
| 2242 | ✗ | Error.addInternalError("function PFPlusaugmentmatching failed", sourceInfo()); | |
| 2243 | ✗ | then | |
| 2244 | fail(); | ||
| 2245 | end matchcontinue; | ||
| 2246 | end PFPlusaugmentmatching; | ||
| 2247 | |||
| 2248 | protected function PFPlusphase | ||
| 2249 | "function helper for PFPlus, traverses all colums and perform a PFPlus phase on each | ||
| 2250 | author: Frenkel TUD 2012-03" | ||
| 2251 | input list<Integer> stack; | ||
| 2252 | input Integer i; | ||
| 2253 | input Integer c; | ||
| 2254 | input Integer nv; | ||
| 2255 | input Integer ne; | ||
| 2256 | input BackendDAE.AdjacencyMatrix m; | ||
| 2257 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 2258 | input array<Integer> rowmarks; | ||
| 2259 | input array<Integer> lookahead; | ||
| 2260 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 2261 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 2262 | input Boolean reverseRows; | ||
| 2263 | output Boolean matched; | ||
| 2264 | algorithm | ||
| 2265 | matched := | ||
| 2266 | match (stack, reverseRows) | ||
| 2267 | local | ||
| 2268 | list<Integer> rows; | ||
| 2269 | Boolean b; | ||
| 2270 | case ({}, _) then false; | ||
| 2271 | case (_, false) | ||
| 2272 | algorithm | ||
| 2273 | // traverse all adiacent rows | ||
| 2274 | 500 | rows := List.select(m[c], Util.intPositive); | |
| 2275 | 500 | b := intLt(lookahead[c],listLength(rows)); | |
| 2276 | 500 | then | |
| 2277 | PFPluschecklookahead(b,rows,stack,i,c,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,reverseRows); | ||
| 2278 | case (_, true) | ||
| 2279 | algorithm | ||
| 2280 | // traverse all adiacent rows | ||
| 2281 | 117 | rows := List.select(m[c], Util.intPositive); | |
| 2282 | 117 | b := intLt(lookahead[c],listLength(rows)); | |
| 2283 | 117 | then | |
| 2284 | PFPluschecklookahead(b,listReverse(rows),stack,i,c,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,reverseRows); | ||
| 2285 | else | ||
| 2286 | algorithm | ||
| 2287 | ✗ | Error.addInternalError("function PFPlusphase failed in equation " + intString(c), sourceInfo()); | |
| 2288 | ✗ | then | |
| 2289 | fail(); | ||
| 2290 | |||
| 2291 | end match; | ||
| 2292 | end PFPlusphase; | ||
| 2293 | |||
| 2294 | protected function PFPluschecklookahead | ||
| 2295 | "function helper for PFPlus, traverses all vars of a equations and search a augmenting path | ||
| 2296 | author: Frenkel TUD 2012-03" | ||
| 2297 | input Boolean dolookahaed; | ||
| 2298 | input list<Integer> rows; | ||
| 2299 | input list<Integer> stack; | ||
| 2300 | input Integer i; | ||
| 2301 | input Integer c; | ||
| 2302 | input Integer nv; | ||
| 2303 | input Integer ne; | ||
| 2304 | input BackendDAE.AdjacencyMatrix m; | ||
| 2305 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 2306 | input array<Integer> rowmarks; | ||
| 2307 | input array<Integer> lookahead; | ||
| 2308 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 2309 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 2310 | input Boolean reverseRows; | ||
| 2311 | output Boolean matched; | ||
| 2312 | algorithm | ||
| 2313 |
2/2✓ Branch 0 taken 480 times.
✓ Branch 1 taken 137 times.
|
617 | matched:= |
| 2314 | match dolookahaed | ||
| 2315 | case true | ||
| 2316 | then | ||
| 2317 | PFPlustraverseRowsUnmatched(rows,rows,stack,i,c,listLength(rows),nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,reverseRows); | ||
| 2318 | else | ||
| 2319 | PFPlustraverseRows(rows,stack,i,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,reverseRows); | ||
| 2320 | end match; | ||
| 2321 | end PFPluschecklookahead; | ||
| 2322 | |||
| 2323 | protected function PFPlustraverseRowsUnmatched | ||
| 2324 | "function helper for PFPlus, traverses all vars of a equations and search a augmenting path | ||
| 2325 | author: Frenkel TUD 2012-03" | ||
| 2326 | input list<Integer> rows; | ||
| 2327 | input list<Integer> rows1; | ||
| 2328 | input list<Integer> stack; | ||
| 2329 | input Integer i; | ||
| 2330 | input Integer c; | ||
| 2331 | input Integer l; | ||
| 2332 | input Integer nv; | ||
| 2333 | input Integer ne; | ||
| 2334 | input BackendDAE.AdjacencyMatrix m; | ||
| 2335 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 2336 | input array<Integer> rowmarks; | ||
| 2337 | input array<Integer> lookahead; | ||
| 2338 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 2339 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 2340 | input Boolean reverseRows; | ||
| 2341 | output Boolean matched; | ||
| 2342 | algorithm | ||
| 2343 | matched:= | ||
| 2344 | matchcontinue rows | ||
| 2345 | local | ||
| 2346 | list<Integer> rest; | ||
| 2347 | Integer r; | ||
| 2348 | case {} | ||
| 2349 | algorithm | ||
| 2350 | 415 | arrayUpdate(lookahead,c,l); | |
| 2351 | 415 | then | |
| 2352 | PFPlustraverseRows(rows1,stack,i,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,reverseRows); | ||
| 2353 | case r::_ | ||
| 2354 | algorithm | ||
| 2355 | // row is unmatched -> augmenting path found | ||
| 2356 |
2/2✓ Branch 1 taken 1148 times.
✓ Branch 2 taken 65 times.
|
1213 | true := intLt(ass2[r],0); |
| 2357 | 65 | DFSBreasign(stack,r,ass1,ass2); | |
| 2358 | then | ||
| 2359 | true; | ||
| 2360 | case _::rest | ||
| 2361 | 1148 | then | |
| 2362 | PFPlustraverseRowsUnmatched(rest,rows1,stack,i,c,l,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,reverseRows); | ||
| 2363 | end matchcontinue; | ||
| 2364 | end PFPlustraverseRowsUnmatched; | ||
| 2365 | |||
| 2366 | protected function PFPlustraverseRows | ||
| 2367 | "function helper for PFPlus, traverses all vars of a equations and search a augmenting path | ||
| 2368 | author: Frenkel TUD 2012-03" | ||
| 2369 | input list<Integer> rows; | ||
| 2370 | input list<Integer> stack; | ||
| 2371 | input Integer i; | ||
| 2372 | input Integer nv; | ||
| 2373 | input Integer ne; | ||
| 2374 | input BackendDAE.AdjacencyMatrix m; | ||
| 2375 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 2376 | input array<Integer> rowmarks; | ||
| 2377 | input array<Integer> lookahead; | ||
| 2378 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 2379 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 2380 | input Boolean reverseRows; | ||
| 2381 | output Boolean matched; | ||
| 2382 | algorithm | ||
| 2383 | matched:= | ||
| 2384 | matchcontinue rows | ||
| 2385 | local | ||
| 2386 | list<Integer> rest; | ||
| 2387 | Integer rc,r; | ||
| 2388 | Boolean b; | ||
| 2389 | case {} then false; | ||
| 2390 | case r::rest | ||
| 2391 | algorithm | ||
| 2392 | // row is matched | ||
| 2393 | 1213 | rc := ass2[r]; | |
| 2394 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1213 times.
|
1213 | false := intLt(rc,0); |
| 2395 |
2/2✓ Branch 1 taken 685 times.
✓ Branch 2 taken 528 times.
|
1213 | false := intEq(rowmarks[r],i); |
| 2396 | 528 | arrayUpdate(rowmarks,r,i); | |
| 2397 | 528 | b := PFPlusphase(rc::stack,i,rc,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,reverseRows); | |
| 2398 | 528 | then | |
| 2399 | PFPlustraverseRows1(rest,stack,i,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,b,reverseRows); | ||
| 2400 | case _::rest | ||
| 2401 | 685 | then | |
| 2402 | PFPlustraverseRows(rest,stack,i,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,reverseRows); | ||
| 2403 | else | ||
| 2404 | algorithm | ||
| 2405 | ✗ | Error.addInternalError("function PFPlustraverseRows failed", sourceInfo()); | |
| 2406 | ✗ | then | |
| 2407 | fail(); | ||
| 2408 | end matchcontinue; | ||
| 2409 | end PFPlustraverseRows; | ||
| 2410 | |||
| 2411 | protected function PFPlustraverseRows1 | ||
| 2412 | "function helper for PFPlustraverseRows | ||
| 2413 | author: Frenkel TUD 2012-03" | ||
| 2414 | input list<Integer> rows; | ||
| 2415 | input list<Integer> stack; | ||
| 2416 | input Integer i; | ||
| 2417 | input Integer nv; | ||
| 2418 | input Integer ne; | ||
| 2419 | input BackendDAE.AdjacencyMatrix m; | ||
| 2420 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 2421 | input array<Integer> rowmarks; | ||
| 2422 | input array<Integer> lookahead; | ||
| 2423 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 2424 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 2425 | input Boolean inMatched; | ||
| 2426 | input Boolean reverseRows; | ||
| 2427 | output Boolean matched; | ||
| 2428 | algorithm | ||
| 2429 |
2/2✓ Branch 0 taken 342 times.
✓ Branch 1 taken 186 times.
|
528 | matched:= |
| 2430 | match inMatched | ||
| 2431 | case true then inMatched; | ||
| 2432 | else PFPlustraverseRows(rows,stack,i,nv,ne,m,mT,rowmarks,lookahead,ass1,ass2,reverseRows); | ||
| 2433 | end match; | ||
| 2434 | end PFPlustraverseRows1; | ||
| 2435 | |||
| 2436 | public function HK | ||
| 2437 | " complexity O(sqrt(n)*tau) | ||
| 2438 | author: Frenkel TUD 2012-03" | ||
| 2439 | input BackendDAE.EqSystem isyst; | ||
| 2440 | input BackendDAE.Shared ishared; | ||
| 2441 | input Boolean clearMatching; | ||
| 2442 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 2443 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 2444 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 2445 | output BackendDAE.EqSystem osyst; | ||
| 2446 | output BackendDAE.Shared oshared; | ||
| 2447 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 2448 | algorithm | ||
| 2449 | (osyst,oshared,outArg) := | ||
| 2450 | matchcontinue isyst | ||
| 2451 | local | ||
| 2452 | Integer nvars,neqns; | ||
| 2453 | BackendDAE.AdjacencyMatrix m; | ||
| 2454 | BackendDAE.AdjacencyMatrixT mt; | ||
| 2455 | array<Integer> vec1,vec2; | ||
| 2456 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 2457 | BackendDAE.EqSystem syst; | ||
| 2458 | BackendDAE.Shared shared; | ||
| 2459 | array<Integer> rowmarks,level,collummarks; | ||
| 2460 | list<Integer> unmatched; | ||
| 2461 | case BackendDAE.EQSYSTEM(m=SOME(m),mT=SOME(mt)) | ||
| 2462 | algorithm | ||
| 2463 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 2464 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 2465 | ✗ | true := intGt(nvars,0); | |
| 2466 | ✗ | true := intGt(neqns,0); | |
| 2467 | ✗ | (vec1,vec2) := getAssignment(clearMatching,nvars,neqns,isyst); | |
| 2468 | ✗ | rowmarks := arrayCreate(nvars,-1); | |
| 2469 | ✗ | collummarks := arrayCreate(neqns,-1); | |
| 2470 | ✗ | level := arrayCreate(neqns,-1); | |
| 2471 | ✗ | unmatched := cheapmatchingalgorithm(nvars,neqns,m,mt,vec1,vec2,true); | |
| 2472 | ✗ | (vec1,vec2,syst,shared,arg) := HK1(0,unmatched,rowmarks,collummarks,level,isyst,ishared,nvars,neqns,vec1,vec2,inMatchingOptions,sssHandler,inArg); | |
| 2473 | ✗ | syst := BackendDAEUtil.setEqSystMatching(syst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 2474 | ✗ | then | |
| 2475 | (syst,shared,arg); | ||
| 2476 | // fail case if system is empty | ||
| 2477 | case _ | ||
| 2478 | algorithm | ||
| 2479 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 2480 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 2481 | ✗ | false := intGt(nvars,0); | |
| 2482 | ✗ | false := intGt(neqns,0); | |
| 2483 | ✗ | vec1 := listArray({}); | |
| 2484 | ✗ | vec2 := listArray({}); | |
| 2485 | ✗ | syst := BackendDAEUtil.setEqSystMatching(isyst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 2486 | then | ||
| 2487 | (syst,ishared,inArg); | ||
| 2488 | else | ||
| 2489 | algorithm | ||
| 2490 | ✗ | if Flags.isSet(Flags.FAILTRACE) then | |
| 2491 | ✗ | Debug.trace("- Matching.HK failed\n"); | |
| 2492 | end if; | ||
| 2493 | ✗ | then | |
| 2494 | fail(); | ||
| 2495 | end matchcontinue; | ||
| 2496 | end HK; | ||
| 2497 | |||
| 2498 | protected function HK1 | ||
| 2499 | "function: HK1, helper for HK | ||
| 2500 | author: Frenkel TUD 2012-03" | ||
| 2501 | input Integer i; | ||
| 2502 | input list<Integer> unmatched; | ||
| 2503 | input array<Integer> rowmarks; | ||
| 2504 | input array<Integer> collummarks; | ||
| 2505 | input array<Integer> level; | ||
| 2506 | input BackendDAE.EqSystem isyst; | ||
| 2507 | input BackendDAE.Shared ishared; | ||
| 2508 | input Integer nv; | ||
| 2509 | input Integer ne; | ||
| 2510 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 2511 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 2512 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 2513 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 2514 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 2515 | output array<Integer> outAss1; | ||
| 2516 | output array<Integer> outAss2; | ||
| 2517 | output BackendDAE.EqSystem osyst; | ||
| 2518 | output BackendDAE.Shared oshared; | ||
| 2519 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 2520 | algorithm | ||
| 2521 | (outAss1,outAss2,osyst,oshared,outArg):= | ||
| 2522 | match (unmatched, isyst) | ||
| 2523 | local | ||
| 2524 | BackendDAE.AdjacencyMatrix m,mt; | ||
| 2525 | Integer nv_1,ne_1,i_1; | ||
| 2526 | list<Integer> unmatched1; | ||
| 2527 | list<list<Integer>> meqns; | ||
| 2528 | BackendDAE.StructurallySingularSystemHandlerArg arg,arg1; | ||
| 2529 | BackendDAE.EqSystem syst; | ||
| 2530 | BackendDAE.Shared shared; | ||
| 2531 | array<Integer> ass1_1,ass1_2,ass2_1,ass2_2,rowmarks1,collummarks1,level1; | ||
| 2532 | case ({}, _) | ||
| 2533 | then | ||
| 2534 | (ass1,ass2,isyst,ishared,inArg); | ||
| 2535 | case (_, syst as BackendDAE.EQSYSTEM(m=SOME(m),mT=SOME(mt))) | ||
| 2536 | algorithm | ||
| 2537 | ✗ | (i_1,unmatched1) := HKphase(i,unmatched,nv,ne,m,mt,rowmarks,collummarks,level,ass1,ass2,listLength(unmatched),{}); | |
| 2538 | ✗ | meqns := getEqnsforIndexReduction(unmatched1,ne,m,mt,ass1,ass2,inArg); | |
| 2539 | ✗ | (unmatched1,rowmarks1,collummarks1,level1,nv_1,ne_1,ass1_1,ass2_1,syst,shared,arg) := HK2(meqns,unmatched1,{},rowmarks,collummarks,level,syst,ishared,nv,ne,ass1,ass2,inMatchingOptions,sssHandler,inArg); | |
| 2540 | ✗ | (ass1_2,ass2_2,syst,shared,arg1) := HK1(i_1+1,unmatched1,rowmarks1,collummarks1,level1,syst,shared,nv_1,ne_1,ass1_1,ass2_1,inMatchingOptions,sssHandler,arg); | |
| 2541 | then | ||
| 2542 | (ass1_2,ass2_2,syst,shared,arg1); | ||
| 2543 | end match; | ||
| 2544 | end HK1; | ||
| 2545 | |||
| 2546 | protected function HK2 | ||
| 2547 | "function: HK2, helper for HK | ||
| 2548 | author: Frenkel TUD 2012-03" | ||
| 2549 | input list<list<Integer>> meqns "Marked Equations for Index Reduction"; | ||
| 2550 | input list<Integer> unmatched; | ||
| 2551 | input list<Integer> changedEqns; | ||
| 2552 | input array<Integer> rowmarks; | ||
| 2553 | input array<Integer> collummarks; | ||
| 2554 | input array<Integer> level; | ||
| 2555 | input BackendDAE.EqSystem isyst; | ||
| 2556 | input BackendDAE.Shared ishared; | ||
| 2557 | input Integer nv; | ||
| 2558 | input Integer ne; | ||
| 2559 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 2560 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 2561 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 2562 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 2563 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 2564 | output list<Integer> outunmatched; | ||
| 2565 | output array<Integer> outrowmarks; | ||
| 2566 | output array<Integer> outcollummarks; | ||
| 2567 | output array<Integer> outlevel; | ||
| 2568 | output Integer nvars; | ||
| 2569 | output Integer neqns; | ||
| 2570 | output array<Integer> outAss1; | ||
| 2571 | output array<Integer> outAss2; | ||
| 2572 | output BackendDAE.EqSystem osyst; | ||
| 2573 | output BackendDAE.Shared oshared; | ||
| 2574 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 2575 | algorithm | ||
| 2576 | (outunmatched,outrowmarks,outcollummarks,outlevel,nvars,neqns,outAss1,outAss2,osyst,oshared,outArg):= | ||
| 2577 | match (meqns, inMatchingOptions) | ||
| 2578 | local | ||
| 2579 | Integer nv_1,ne_1; | ||
| 2580 | list<Integer> unmatched1; | ||
| 2581 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 2582 | BackendDAE.EqSystem syst; | ||
| 2583 | BackendDAE.Shared shared; | ||
| 2584 | array<Integer> ass1_1,ass2_1,rowmarks1,collummarks1,level1; | ||
| 2585 | |||
| 2586 | case ({}, _) | ||
| 2587 | then | ||
| 2588 | (unmatched,rowmarks,collummarks,level,nv,ne,ass1,ass2,isyst,ishared,inArg); | ||
| 2589 | case (_, (BackendDAE.INDEX_REDUCTION(),_)) | ||
| 2590 | algorithm | ||
| 2591 | ✗ | (unmatched1,_,syst,shared,ass2_1,ass1_1,arg) := sssHandler(meqns,0,isyst,ishared,ass2,ass1,inArg); | |
| 2592 | ✗ | ne_1 := BackendDAEUtil.systemSize(syst); | |
| 2593 | ✗ | nv_1 := BackendVariable.daenumVariables(syst); | |
| 2594 | ✗ | ass1_1 := assignmentsArrayExpand(ass1_1,ne_1,arrayLength(ass1),-1); | |
| 2595 | ✗ | ass2_1 := assignmentsArrayExpand(ass2_1,nv_1,arrayLength(ass2),-1); | |
| 2596 | ✗ | rowmarks1 := assignmentsArrayExpand(rowmarks,nv_1,arrayLength(rowmarks),-1); | |
| 2597 | ✗ | collummarks1 := assignmentsArrayExpand(collummarks,ne_1,arrayLength(collummarks),-1); | |
| 2598 | ✗ | level1 := assignmentsArrayExpand(level,ne_1,arrayLength(level),-1); | |
| 2599 | ✗ | then | |
| 2600 | (unmatched1,rowmarks1,collummarks1,level1,nv_1,ne_1,ass1_1,ass2_1,syst,shared,arg); | ||
| 2601 | case (_, _) | ||
| 2602 | algorithm | ||
| 2603 | ✗ | singularSystemError(meqns,0,isyst,ishared,ass1,ass2,inArg); | |
| 2604 | ✗ | then | |
| 2605 | fail(); | ||
| 2606 | end match; | ||
| 2607 | end HK2; | ||
| 2608 | |||
| 2609 | protected function HKphase | ||
| 2610 | "function helper for HK, traverses all unmatched | ||
| 2611 | colums and run a BFS and DFS | ||
| 2612 | author: Frenkel TUD 2012-03" | ||
| 2613 | input Integer i; | ||
| 2614 | input list<Integer> U; | ||
| 2615 | input Integer nv; | ||
| 2616 | input Integer ne; | ||
| 2617 | input BackendDAE.AdjacencyMatrix m "m[eqnindx] = list(varindx)"; | ||
| 2618 | input BackendDAE.AdjacencyMatrixT mT "mT[varindx] = list(eqnindx)"; | ||
| 2619 | input array<Integer> rowmarks; | ||
| 2620 | input array<Integer> collummarks; | ||
| 2621 | input array<Integer> level; | ||
| 2622 | input array<Integer> ass1 "ass[eqnindx]=varindx"; | ||
| 2623 | input array<Integer> ass2 "ass[varindx]=eqnindx"; | ||
| 2624 | input Integer previousUnmatched; | ||
| 2625 | input list<Integer> unMatched; | ||
| 2626 | output Integer outI; | ||
| 2627 | output list<Integer> outunMatched; | ||
| 2628 | algorithm | ||
| 2629 | (outI,outunMatched):= | ||
| 2630 | matchcontinue U | ||
| 2631 | local | ||
| 2632 | list<Integer> unmatched; | ||
| 2633 | list<tuple<Integer,Integer>> rows; | ||
| 2634 | Integer i_1; | ||
| 2635 | case {} | ||
| 2636 | algorithm | ||
| 2637 | // no augmenting path is found in phase | ||
| 2638 | ✗ | true:=intEq(previousUnmatched,listLength(unMatched)); | |
| 2639 | ✗ | then | |
| 2640 | (i,unMatched); | ||
| 2641 | case {} | ||
| 2642 | algorithm | ||
| 2643 | // augmenting path is found in phase, next round | ||
| 2644 | ✗ | (i_1,unmatched) := HKphase(i+1,unMatched,nv,ne,m,mT,rowmarks,collummarks,level,ass1,ass2,listLength(unMatched),{}); | |
| 2645 | then | ||
| 2646 | (i_1,unmatched); | ||
| 2647 | case _ | ||
| 2648 | algorithm | ||
| 2649 | // BFS phase to get the level information | ||
| 2650 | ✗ | rows := HKBFS(U,nv,ne,m,mT,rowmarks,i,level,NONE(),ass1,ass2,{}); | |
| 2651 | // DFS to match | ||
| 2652 | ✗ | HKDFS(rows,i,nv,ne,m,mT,collummarks,level,ass1,ass2,{}); | |
| 2653 | // remove matched collums from U | ||
| 2654 | ✗ | unmatched := HKgetUnmatched(U,ass1,{}); | |
| 2655 | ✗ | (i_1,unmatched) := HKphase(i,{},nv,ne,m,mT,rowmarks,collummarks,level,ass1,ass2,previousUnmatched,unmatched); | |
| 2656 | then | ||
| 2657 | (i_1,unmatched); | ||
| 2658 | else | ||
| 2659 | algorithm | ||
| 2660 | ✗ | Error.addInternalError("function HKphase failed", sourceInfo()); | |
| 2661 | ✗ | then | |
| 2662 | fail(); | ||
| 2663 | end matchcontinue; | ||
| 2664 | end HKphase; | ||
| 2665 | |||
| 2666 | protected function HKgetUnmatched | ||
| 2667 | input list<Integer> U; | ||
| 2668 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 2669 | input list<Integer> inUnmatched; | ||
| 2670 | output list<Integer> outUnmatched; | ||
| 2671 | algorithm | ||
| 2672 | outUnmatched:= | ||
| 2673 | matchcontinue U | ||
| 2674 | local | ||
| 2675 | list<Integer> rest; | ||
| 2676 | Integer c; | ||
| 2677 | case {} then inUnmatched; | ||
| 2678 | case c::rest | ||
| 2679 | algorithm | ||
| 2680 | ✗ | true := intGt(ass1[c],0); | |
| 2681 | ✗ | then | |
| 2682 | HKgetUnmatched(rest,ass1,inUnmatched); | ||
| 2683 | case c::rest | ||
| 2684 | ✗ | then | |
| 2685 | HKgetUnmatched(rest,ass1,c::inUnmatched); | ||
| 2686 | end matchcontinue; | ||
| 2687 | end HKgetUnmatched; | ||
| 2688 | |||
| 2689 | protected function HKBFS | ||
| 2690 | "function helper for HK, traverses all colums and perform a BFSB phase on each to get the level information | ||
| 2691 | the BFS stops at a colum with unmatched rows | ||
| 2692 | author: Frenkel TUD 2012-03" | ||
| 2693 | input list<Integer> colums; | ||
| 2694 | input Integer nv; | ||
| 2695 | input Integer ne; | ||
| 2696 | input BackendDAE.AdjacencyMatrix m "m[eqnindx] = list(varindx)"; | ||
| 2697 | input BackendDAE.AdjacencyMatrixT mT "mT[varindx] = list(eqnindx)"; | ||
| 2698 | input array<Integer> rowmarks; | ||
| 2699 | input Integer i; | ||
| 2700 | input array<Integer> level; | ||
| 2701 | input Option<Integer> lowestL "lowest level find unmatched rows"; | ||
| 2702 | input array<Integer> ass1 "ass[eqnindx]=varindx"; | ||
| 2703 | input array<Integer> ass2 "ass[varindx]=eqnindx"; | ||
| 2704 | input list<tuple<Integer,Integer>> inRows "(row,level)"; | ||
| 2705 | output list<tuple<Integer,Integer>> outRows "unmatched rows found by BFS"; | ||
| 2706 | algorithm | ||
| 2707 | outRows:= | ||
| 2708 | match colums | ||
| 2709 | local | ||
| 2710 | list<Integer> rest; | ||
| 2711 | list<tuple<Integer,Integer>> rows; | ||
| 2712 | Integer c; | ||
| 2713 | Option<Integer> ll; | ||
| 2714 | case {} then inRows; | ||
| 2715 | case c::rest | ||
| 2716 | algorithm | ||
| 2717 | ✗ | (rows,ll) := HKBFSBphase({c},i,0,lowestL,nv,ne,m,mT,rowmarks,level,ass1,ass2,inRows,{}); | |
| 2718 | ✗ | then | |
| 2719 | HKBFS(rest,nv,ne,m,mT,rowmarks,i,level,ll,ass1,ass2,rows); | ||
| 2720 | else | ||
| 2721 | algorithm | ||
| 2722 | ✗ | Error.addInternalError("function HKBFS failed in phase " + intString(i), sourceInfo()); | |
| 2723 | ✗ | then | |
| 2724 | fail(); | ||
| 2725 | end match; | ||
| 2726 | end HKBFS; | ||
| 2727 | |||
| 2728 | protected function HKBFSBphase | ||
| 2729 | "function helper for HKBFS, traverses all colums and perform a BFSB phase on each | ||
| 2730 | author: Frenkel TUD 2012-03" | ||
| 2731 | input list<Integer> queue; | ||
| 2732 | input Integer i; | ||
| 2733 | input Integer l "current level"; | ||
| 2734 | input Option<Integer> lowestL "lowest level find unmatched rows"; | ||
| 2735 | input Integer nv; | ||
| 2736 | input Integer ne; | ||
| 2737 | input BackendDAE.AdjacencyMatrix m; | ||
| 2738 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 2739 | input array<Integer> rowmarks; | ||
| 2740 | input array<Integer> level; | ||
| 2741 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 2742 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 2743 | input list<tuple<Integer,Integer>> inRows; | ||
| 2744 | input list<Integer> queue1; | ||
| 2745 | output list<tuple<Integer,Integer>> outRows; | ||
| 2746 | output Option<Integer> outlowestL; | ||
| 2747 | algorithm | ||
| 2748 | (outRows,outlowestL) := | ||
| 2749 | match (queue, lowestL, queue1) | ||
| 2750 | local | ||
| 2751 | list<Integer> rest,queue2,cr; | ||
| 2752 | list<tuple<Integer,Integer>> rows; | ||
| 2753 | Integer c,lowl,l_1; | ||
| 2754 | Boolean b; | ||
| 2755 | Option<Integer> ll; | ||
| 2756 | ✗ | case ({}, _, {}) then (inRows,lowestL); | |
| 2757 | case ({}, SOME(lowl), _) | ||
| 2758 | algorithm | ||
| 2759 | ✗ | l_1 := l+1; | |
| 2760 | ✗ | b := intGt(l_1,lowl); | |
| 2761 | ✗ | (rows,ll) := HKBFSBphase1(b,queue1,i,l_1,lowestL,nv,ne,m,mT,rowmarks,level,ass1,ass2,inRows,{}); | |
| 2762 | then | ||
| 2763 | (rows,ll); | ||
| 2764 | case ({}, NONE(), _) | ||
| 2765 | algorithm | ||
| 2766 | ✗ | (rows,ll) := HKBFSBphase(queue1,i,l+1,lowestL,nv,ne,m,mT,rowmarks,level,ass1,ass2,inRows,{}); | |
| 2767 | then | ||
| 2768 | (rows,ll); | ||
| 2769 | case (c::rest, _, _) | ||
| 2770 | algorithm | ||
| 2771 | // traverse all adiacent rows | ||
| 2772 | ✗ | cr := List.select(m[c], Util.intPositive); | |
| 2773 | ✗ | arrayUpdate(level,c,l); | |
| 2774 | ✗ | (queue2,rows,b) := HKBFStraverseRows(cr,{},i,l,m,mT,rowmarks,level,ass1,ass2,inRows,false); | |
| 2775 | ✗ | queue2 := listAppend(queue1,queue2); | |
| 2776 | ✗ | ll := if b then SOME(l) else lowestL; | |
| 2777 | ✗ | (rows,ll) := HKBFSBphase(rest,i,l,ll,nv,ne,m,mT,rowmarks,level,ass1,ass2,rows,queue2); | |
| 2778 | then | ||
| 2779 | (rows,ll); | ||
| 2780 | else | ||
| 2781 | algorithm | ||
| 2782 | ✗ | Error.addInternalError("function HKBFSBphase failed in phase " + intString(i), sourceInfo()); | |
| 2783 | ✗ | then | |
| 2784 | fail(); | ||
| 2785 | |||
| 2786 | end match; | ||
| 2787 | end HKBFSBphase; | ||
| 2788 | |||
| 2789 | protected function HKBFSBphase1 | ||
| 2790 | "function helper for HKBFSB | ||
| 2791 | author: Frenkel TUD 2012-03" | ||
| 2792 | input Boolean inUnMaRowFound; | ||
| 2793 | input list<Integer> queue; | ||
| 2794 | input Integer i; | ||
| 2795 | input Integer l; | ||
| 2796 | input Option<Integer> lowestL; | ||
| 2797 | input Integer nv; | ||
| 2798 | input Integer ne; | ||
| 2799 | input BackendDAE.AdjacencyMatrix m; | ||
| 2800 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 2801 | input array<Integer> rowmarks; | ||
| 2802 | input array<Integer> level; | ||
| 2803 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 2804 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 2805 | input list<tuple<Integer,Integer>> inRows; | ||
| 2806 | input list<Integer> queue1; | ||
| 2807 | output list<tuple<Integer,Integer>> outRows; | ||
| 2808 | output Option<Integer> outlowestL; | ||
| 2809 | algorithm | ||
| 2810 | (outRows,outlowestL) := | ||
| 2811 | match inUnMaRowFound | ||
| 2812 | local | ||
| 2813 | Option<Integer> ll; | ||
| 2814 | list<tuple<Integer,Integer>> rows; | ||
| 2815 | ✗ | case true then (inRows,SOME(l)); | |
| 2816 | case false | ||
| 2817 | algorithm | ||
| 2818 | ✗ | (rows,ll) := HKBFSBphase(queue,i,l,lowestL,nv,ne,m,mT,rowmarks,level,ass1,ass2,inRows,queue1); | |
| 2819 | then | ||
| 2820 | (rows,ll); | ||
| 2821 | else | ||
| 2822 | algorithm | ||
| 2823 | ✗ | Error.addInternalError("function HKBFSBphase1 failed", sourceInfo()); | |
| 2824 | ✗ | then | |
| 2825 | fail(); | ||
| 2826 | end match; | ||
| 2827 | end HKBFSBphase1; | ||
| 2828 | |||
| 2829 | protected function HKBFStraverseRows | ||
| 2830 | "function helper for BFSB, traverses all rows of a collum and set level | ||
| 2831 | author: Frenkel TUD 2012-03" | ||
| 2832 | input list<Integer> rows; | ||
| 2833 | input list<Integer> queue; | ||
| 2834 | input Integer i; | ||
| 2835 | input Integer l; | ||
| 2836 | input BackendDAE.AdjacencyMatrix m; | ||
| 2837 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 2838 | input array<Integer> rowmarks; | ||
| 2839 | input array<Integer> level; | ||
| 2840 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 2841 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 2842 | input list<tuple<Integer,Integer>> inRows; | ||
| 2843 | input Boolean inunmarowFound; | ||
| 2844 | output list<Integer> outEqnqueue; | ||
| 2845 | output list<tuple<Integer,Integer>> outRows; | ||
| 2846 | output Boolean unmarowFound; | ||
| 2847 | algorithm | ||
| 2848 | (outEqnqueue,outRows,unmarowFound):= | ||
| 2849 | matchcontinue rows | ||
| 2850 | local | ||
| 2851 | list<Integer> rest,queue1; | ||
| 2852 | list<tuple<Integer,Integer>> rowstpl; | ||
| 2853 | Integer rc,r; | ||
| 2854 | Boolean b; | ||
| 2855 | ✗ | case {} then (listReverse(queue),inRows,inunmarowFound); | |
| 2856 | case r::rest | ||
| 2857 | algorithm | ||
| 2858 | // row is visited | ||
| 2859 | ✗ | false := intLt(rowmarks[r],i); | |
| 2860 | ✗ | (queue1,rowstpl,b) := HKBFStraverseRows(rest,queue,i,l,m,mT,rowmarks,level,ass1,ass2,inRows,inunmarowFound); | |
| 2861 | then | ||
| 2862 | (queue1,rowstpl,b); | ||
| 2863 | case r::rest | ||
| 2864 | algorithm | ||
| 2865 | // row is unmatched | ||
| 2866 | ✗ | true := intLt(ass2[r],0); | |
| 2867 | ✗ | arrayUpdate(rowmarks,r,i); | |
| 2868 | ✗ | (queue1,rowstpl,b) := HKBFStraverseRows(rest,queue,i,l,m,mT,rowmarks,level,ass1,ass2,(r,l)::inRows,true); | |
| 2869 | then | ||
| 2870 | (queue1,rowstpl,b); | ||
| 2871 | case r::rest | ||
| 2872 | algorithm | ||
| 2873 | // row is matched | ||
| 2874 | ✗ | rc := ass2[r]; | |
| 2875 | ✗ | false := intLt(rc,0); | |
| 2876 | ✗ | arrayUpdate(rowmarks,r,i); | |
| 2877 | ✗ | (queue1,rowstpl,b) := HKBFStraverseRows(rest,rc::queue,i,l,m,mT,rowmarks,level,ass1,ass2,inRows,inunmarowFound); | |
| 2878 | then | ||
| 2879 | (queue1,rowstpl,b); | ||
| 2880 | else | ||
| 2881 | algorithm | ||
| 2882 | ✗ | Error.addInternalError("function HKBFStraverseRows failed in phase " + intString(i), sourceInfo()); | |
| 2883 | ✗ | then | |
| 2884 | fail(); | ||
| 2885 | |||
| 2886 | end matchcontinue; | ||
| 2887 | end HKBFStraverseRows; | ||
| 2888 | |||
| 2889 | protected function HKDFS | ||
| 2890 | "function helper for HKDFSB, traverses all colums and perform a DFSB phase on each | ||
| 2891 | author: Frenkel TUD 2012-03" | ||
| 2892 | input list<tuple<Integer,Integer>> unmatchedRows; | ||
| 2893 | input Integer i; | ||
| 2894 | input Integer nv; | ||
| 2895 | input Integer ne; | ||
| 2896 | input BackendDAE.AdjacencyMatrix m "m[eqnindx] = list(varindx)"; | ||
| 2897 | input BackendDAE.AdjacencyMatrixT mT "mT[varindx] = list(eqnindx)"; | ||
| 2898 | input array<Integer> collummarks; | ||
| 2899 | input array<Integer> level; | ||
| 2900 | input array<Integer> ass1 "ass[eqnindx]=varindx"; | ||
| 2901 | input array<Integer> ass2 "ass[varindx]=eqnindx"; | ||
| 2902 | input list<Integer> inUnmatchedRows; | ||
| 2903 | output list<Integer> outUnmatchedRows; | ||
| 2904 | algorithm | ||
| 2905 | outUnmatchedRows:= | ||
| 2906 | match unmatchedRows | ||
| 2907 | local | ||
| 2908 | list<tuple<Integer,Integer>> rest; | ||
| 2909 | list<Integer> ur; | ||
| 2910 | Integer r,l; | ||
| 2911 | Boolean b; | ||
| 2912 | case {} then inUnmatchedRows; | ||
| 2913 | case (r,l)::rest | ||
| 2914 | algorithm | ||
| 2915 | // search augmenting paths | ||
| 2916 | ✗ | b := HKDFSphase({r},i,r,l,nv,ne,m,mT,collummarks,level,ass1,ass2,false); | |
| 2917 | ✗ | ur := List.consOnTrue(not b,r,inUnmatchedRows); | |
| 2918 | ✗ | then | |
| 2919 | HKDFS(rest,i,nv,ne,m,mT,collummarks,level,ass1,ass2,ur); | ||
| 2920 | else | ||
| 2921 | algorithm | ||
| 2922 | ✗ | Error.addInternalError("function HKDFS failed in phase " + intString(i), sourceInfo()); | |
| 2923 | ✗ | then | |
| 2924 | fail(); | ||
| 2925 | |||
| 2926 | end match; | ||
| 2927 | end HKDFS; | ||
| 2928 | |||
| 2929 | protected function HKDFSphase | ||
| 2930 | "function helper for HKDFSBphase, traverses all colums and perform a DFSB phase on each | ||
| 2931 | author: Frenkel TUD 2012-03" | ||
| 2932 | input list<Integer> stack; | ||
| 2933 | input Integer i; | ||
| 2934 | input Integer r; | ||
| 2935 | input Integer l; | ||
| 2936 | input Integer nv; | ||
| 2937 | input Integer ne; | ||
| 2938 | input BackendDAE.AdjacencyMatrix m; | ||
| 2939 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 2940 | input array<Integer> collummarks; | ||
| 2941 | input array<Integer> level; | ||
| 2942 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 2943 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 2944 | input Boolean inMatched; | ||
| 2945 | output Boolean matched; | ||
| 2946 | algorithm | ||
| 2947 | matched := | ||
| 2948 | match stack | ||
| 2949 | local | ||
| 2950 | list<Integer> collums; | ||
| 2951 | case {} then inMatched; | ||
| 2952 | case _ | ||
| 2953 | algorithm | ||
| 2954 | // traverse all adiacent rows | ||
| 2955 | ✗ | collums := List.select(mT[r], Util.intPositive); | |
| 2956 | ✗ | then | |
| 2957 | HKDFStraverseCollums(collums,stack,i,l,nv,ne,m,mT,collummarks,level,ass1,ass2,inMatched); | ||
| 2958 | else | ||
| 2959 | algorithm | ||
| 2960 | ✗ | Error.addInternalError("function HKDFSphase failed in phase " + intString(i), sourceInfo()); | |
| 2961 | ✗ | then | |
| 2962 | fail(); | ||
| 2963 | end match; | ||
| 2964 | end HKDFSphase; | ||
| 2965 | |||
| 2966 | protected function HKDFStraverseCollums | ||
| 2967 | "function helper for HKDFSB, traverses all collums of a row and search a augmenting path | ||
| 2968 | author: Frenkel TUD 2012-03" | ||
| 2969 | input list<Integer> collums; | ||
| 2970 | input list<Integer> stack; | ||
| 2971 | input Integer i; | ||
| 2972 | input Integer l; | ||
| 2973 | input Integer nv; | ||
| 2974 | input Integer ne; | ||
| 2975 | input BackendDAE.AdjacencyMatrix m; | ||
| 2976 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 2977 | input array<Integer> collummarks; | ||
| 2978 | input array<Integer> level; | ||
| 2979 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 2980 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 2981 | input Boolean inMatched; | ||
| 2982 | output Boolean matched; | ||
| 2983 | algorithm | ||
| 2984 | matched:= | ||
| 2985 | matchcontinue collums | ||
| 2986 | local | ||
| 2987 | list<Integer> rest; | ||
| 2988 | Integer r,c; | ||
| 2989 | Boolean b; | ||
| 2990 | case {} then inMatched; | ||
| 2991 | case c::rest | ||
| 2992 | algorithm | ||
| 2993 | // collum is not in graph | ||
| 2994 | ✗ | false := intEq(level[c],l); | |
| 2995 | ✗ | then | |
| 2996 | HKDFStraverseCollums(rest,stack,i,l,nv,ne,m,mT,collummarks,level,ass1,ass2,inMatched); | ||
| 2997 | case c::_ | ||
| 2998 | algorithm | ||
| 2999 | // collum is in graph | ||
| 3000 | ✗ | true := intEq(level[c],l); | |
| 3001 | // collum is unvisited | ||
| 3002 | ✗ | true := intLt(collummarks[c],i); | |
| 3003 | // collum is unmatched | ||
| 3004 | ✗ | true := intLt(ass1[c],0); | |
| 3005 | ✗ | HKDFSreasign(stack,c,ass1,ass2); | |
| 3006 | then | ||
| 3007 | true; | ||
| 3008 | case c::rest | ||
| 3009 | algorithm | ||
| 3010 | // collum is in graph | ||
| 3011 | ✗ | true := intEq(level[c],l); | |
| 3012 | // collum is unvisited | ||
| 3013 | ✗ | true := intLt(collummarks[c],i); | |
| 3014 | // collum is matched | ||
| 3015 | ✗ | r := ass1[c]; | |
| 3016 | ✗ | false := intLt(r,0); | |
| 3017 | ✗ | arrayUpdate(collummarks,c,i); | |
| 3018 | ✗ | b := HKDFSphase(r::stack,i,r,l-1,nv,ne,m,mT,collummarks,level,ass1,ass2,inMatched); | |
| 3019 | ✗ | then | |
| 3020 | HKDFStraverseCollums1(b,rest,stack,i,l,nv,ne,m,mT,collummarks,level,ass1,ass2); | ||
| 3021 | case c::rest | ||
| 3022 | algorithm | ||
| 3023 | // collum is in graph | ||
| 3024 | ✗ | true := intEq(level[c],l); | |
| 3025 | // collum is visited | ||
| 3026 | ✗ | false := intLt(collummarks[c],i); | |
| 3027 | ✗ | then | |
| 3028 | HKDFStraverseCollums(rest,stack,i,l,nv,ne,m,mT,collummarks,level,ass1,ass2,inMatched); | ||
| 3029 | else | ||
| 3030 | algorithm | ||
| 3031 | ✗ | Error.addInternalError("function HKDFStraverseCollums failed", sourceInfo()); | |
| 3032 | ✗ | then | |
| 3033 | fail(); | ||
| 3034 | end matchcontinue; | ||
| 3035 | end HKDFStraverseCollums; | ||
| 3036 | |||
| 3037 | protected function HKDFStraverseCollums1 | ||
| 3038 | "function helper for HKDFSBtraverseCollums | ||
| 3039 | author: Frenkel TUD 2012-03" | ||
| 3040 | input Boolean inMatched; | ||
| 3041 | input list<Integer> rows; | ||
| 3042 | input list<Integer> stack; | ||
| 3043 | input Integer i; | ||
| 3044 | input Integer l; | ||
| 3045 | input Integer nv; | ||
| 3046 | input Integer ne; | ||
| 3047 | input BackendDAE.AdjacencyMatrix m; | ||
| 3048 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 3049 | input array<Integer> collummarks; | ||
| 3050 | input array<Integer> level; | ||
| 3051 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 3052 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 3053 | output Boolean matched; | ||
| 3054 | algorithm | ||
| 3055 | ✗ | matched:= | |
| 3056 | match inMatched | ||
| 3057 | case true then inMatched; | ||
| 3058 | else HKDFStraverseCollums(rows,stack,i,l,nv,ne,m,mT,collummarks,level,ass1,ass2,inMatched); | ||
| 3059 | end match; | ||
| 3060 | end HKDFStraverseCollums1; | ||
| 3061 | |||
| 3062 | protected function HKDFSreasign | ||
| 3063 | "function helper for HKDFS, reasignment(rematching) allong the augmenting path | ||
| 3064 | remove all edges from the assignments that are in the path | ||
| 3065 | add all other edges to the assignment | ||
| 3066 | author: Frenkel TUD 2012-03" | ||
| 3067 | input list<Integer> stack; | ||
| 3068 | input Integer c; | ||
| 3069 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 3070 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 3071 | algorithm | ||
| 3072 | () := match stack | ||
| 3073 | local | ||
| 3074 | Integer r,cr; | ||
| 3075 | list<Integer> rest; | ||
| 3076 | case {} then (); | ||
| 3077 | case r::rest | ||
| 3078 | algorithm | ||
| 3079 | ✗ | cr := ass2[r]; | |
| 3080 | ✗ | arrayUpdate(ass1,c,r); | |
| 3081 | ✗ | arrayUpdate(ass2,r,c); | |
| 3082 | ✗ | HKDFSreasign(rest,cr,ass1,ass2); | |
| 3083 | then (); | ||
| 3084 | end match; | ||
| 3085 | end HKDFSreasign; | ||
| 3086 | |||
| 3087 | |||
| 3088 | public function HKDW | ||
| 3089 | " complexity O(sqrt(n)*tau) | ||
| 3090 | author: Frenkel TUD 2012-03" | ||
| 3091 | input BackendDAE.EqSystem isyst; | ||
| 3092 | input BackendDAE.Shared ishared; | ||
| 3093 | input Boolean clearMatching; | ||
| 3094 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 3095 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 3096 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 3097 | output BackendDAE.EqSystem osyst; | ||
| 3098 | output BackendDAE.Shared oshared; | ||
| 3099 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 3100 | algorithm | ||
| 3101 | (osyst,oshared,outArg) := | ||
| 3102 | matchcontinue isyst | ||
| 3103 | local | ||
| 3104 | Integer nvars,neqns; | ||
| 3105 | BackendDAE.AdjacencyMatrix m; | ||
| 3106 | BackendDAE.AdjacencyMatrixT mt; | ||
| 3107 | array<Integer> vec1,vec2; | ||
| 3108 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 3109 | BackendDAE.EqSystem syst; | ||
| 3110 | BackendDAE.Shared shared; | ||
| 3111 | array<Integer> rowmarks,level,collummarks; | ||
| 3112 | list<Integer> unmatched; | ||
| 3113 | case BackendDAE.EQSYSTEM(m=SOME(m),mT=SOME(mt)) | ||
| 3114 | algorithm | ||
| 3115 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 3116 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 3117 | ✗ | true := intGt(nvars,0); | |
| 3118 | ✗ | true := intGt(neqns,0); | |
| 3119 | ✗ | (vec1,vec2) := getAssignment(clearMatching,nvars,neqns,isyst); | |
| 3120 | ✗ | rowmarks := arrayCreate(nvars,-1); | |
| 3121 | ✗ | collummarks := arrayCreate(neqns,-1); | |
| 3122 | ✗ | level := arrayCreate(neqns,-1); | |
| 3123 | ✗ | unmatched := cheapmatchingalgorithm(nvars,neqns,m,mt,vec1,vec2,true); | |
| 3124 | ✗ | (vec1,vec2,syst,shared,arg) := HKDW1(0,unmatched,rowmarks,collummarks,level,isyst,ishared,nvars,neqns,vec1,vec2,inMatchingOptions,sssHandler,inArg); | |
| 3125 | ✗ | syst := BackendDAEUtil.setEqSystMatching(syst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 3126 | ✗ | then | |
| 3127 | (syst,shared,arg); | ||
| 3128 | // fail case if system is empty | ||
| 3129 | case _ | ||
| 3130 | algorithm | ||
| 3131 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 3132 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 3133 | ✗ | false := intGt(nvars,0); | |
| 3134 | ✗ | false := intGt(neqns,0); | |
| 3135 | ✗ | vec1 := listArray({}); | |
| 3136 | ✗ | vec2 := listArray({}); | |
| 3137 | ✗ | syst := BackendDAEUtil.setEqSystMatching(isyst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 3138 | then | ||
| 3139 | (syst,ishared,inArg); | ||
| 3140 | else | ||
| 3141 | algorithm | ||
| 3142 | ✗ | if Flags.isSet(Flags.FAILTRACE) then | |
| 3143 | ✗ | Debug.trace("- Matching.HKDW failed\n"); | |
| 3144 | end if; | ||
| 3145 | ✗ | then | |
| 3146 | fail(); | ||
| 3147 | end matchcontinue; | ||
| 3148 | end HKDW; | ||
| 3149 | |||
| 3150 | protected function HKDW1 | ||
| 3151 | "function: HKDW1, helper for HKDW | ||
| 3152 | author: Frenkel TUD 2012-03" | ||
| 3153 | input Integer i; | ||
| 3154 | input list<Integer> unmatched; | ||
| 3155 | input array<Integer> rowmarks; | ||
| 3156 | input array<Integer> collummarks; | ||
| 3157 | input array<Integer> level; | ||
| 3158 | input BackendDAE.EqSystem isyst; | ||
| 3159 | input BackendDAE.Shared ishared; | ||
| 3160 | input Integer nv; | ||
| 3161 | input Integer ne; | ||
| 3162 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 3163 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 3164 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 3165 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 3166 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 3167 | output array<Integer> outAss1; | ||
| 3168 | output array<Integer> outAss2; | ||
| 3169 | output BackendDAE.EqSystem osyst; | ||
| 3170 | output BackendDAE.Shared oshared; | ||
| 3171 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 3172 | algorithm | ||
| 3173 | (outAss1,outAss2,osyst,oshared,outArg):= | ||
| 3174 | match (unmatched, isyst) | ||
| 3175 | local | ||
| 3176 | BackendDAE.AdjacencyMatrix m,mt; | ||
| 3177 | Integer nv_1,ne_1,i_1; | ||
| 3178 | list<Integer> unmatched1; | ||
| 3179 | list<list<Integer>> meqns; | ||
| 3180 | BackendDAE.StructurallySingularSystemHandlerArg arg,arg1; | ||
| 3181 | BackendDAE.EqSystem syst; | ||
| 3182 | BackendDAE.Shared shared; | ||
| 3183 | array<Integer> ass1_1,ass1_2,ass2_1,ass2_2,rowmarks1,collummarks1,level1; | ||
| 3184 | case ({}, _) | ||
| 3185 | then | ||
| 3186 | (ass1,ass2,isyst,ishared,inArg); | ||
| 3187 | case (_, syst as BackendDAE.EQSYSTEM(m=SOME(m),mT=SOME(mt))) | ||
| 3188 | algorithm | ||
| 3189 | ✗ | (i_1,unmatched1) := HKDWphase(i,unmatched,nv,ne,m,mt,rowmarks,collummarks,level,ass1,ass2,listLength(unmatched),{}); | |
| 3190 | ✗ | meqns := getEqnsforIndexReduction(unmatched1,ne,m,mt,ass1,ass2,inArg); | |
| 3191 | ✗ | (unmatched1,rowmarks1,collummarks1,level1,nv_1,ne_1,ass1_1,ass2_1,syst,shared,arg) := HK2(meqns,unmatched1,{},rowmarks,collummarks,level,syst,ishared,nv,ne,ass1,ass2,inMatchingOptions,sssHandler,inArg); | |
| 3192 | ✗ | (ass1_2,ass2_2,syst,shared,arg1) := HKDW1(i_1+1,unmatched1,rowmarks1,collummarks1,level1,syst,shared,nv_1,ne_1,ass1_1,ass2_1,inMatchingOptions,sssHandler,arg); | |
| 3193 | then | ||
| 3194 | (ass1_2,ass2_2,syst,shared,arg1); | ||
| 3195 | end match; | ||
| 3196 | end HKDW1; | ||
| 3197 | |||
| 3198 | protected function HKDWphase | ||
| 3199 | "function helper for HKDW, traverses all unmatched | ||
| 3200 | colums and run a BFS and DFS | ||
| 3201 | author: Frenkel TUD 2012-03" | ||
| 3202 | input Integer i; | ||
| 3203 | input list<Integer> U; | ||
| 3204 | input Integer nv; | ||
| 3205 | input Integer ne; | ||
| 3206 | input BackendDAE.AdjacencyMatrix m "m[eqnindx] = list(varindx)"; | ||
| 3207 | input BackendDAE.AdjacencyMatrixT mT "mT[varindx] = list(eqnindx)"; | ||
| 3208 | input array<Integer> rowmarks; | ||
| 3209 | input array<Integer> collummarks; | ||
| 3210 | input array<Integer> level; | ||
| 3211 | input array<Integer> ass1 "ass[eqnindx]=varindx"; | ||
| 3212 | input array<Integer> ass2 "ass[varindx]=eqnindx"; | ||
| 3213 | input Integer previousUnmatched; | ||
| 3214 | input list<Integer> unMatched; | ||
| 3215 | output Integer outI; | ||
| 3216 | output list<Integer> outunMatched; | ||
| 3217 | algorithm | ||
| 3218 | (outI,outunMatched):= | ||
| 3219 | matchcontinue U | ||
| 3220 | local | ||
| 3221 | list<Integer> unmatched; | ||
| 3222 | list<tuple<Integer,Integer>> rows; | ||
| 3223 | list<Integer> ur; | ||
| 3224 | Integer i_1; | ||
| 3225 | case {} | ||
| 3226 | algorithm | ||
| 3227 | // no augmenting path is found in phase | ||
| 3228 | ✗ | true:=intEq(previousUnmatched,listLength(unMatched)); | |
| 3229 | ✗ | then | |
| 3230 | (i,unMatched); | ||
| 3231 | case {} | ||
| 3232 | algorithm | ||
| 3233 | // augmenting path is found in phase, next round | ||
| 3234 | ✗ | (i_1,unmatched) := HKphase(i+1,unMatched,nv,ne,m,mT,rowmarks,collummarks,level,ass1,ass2,listLength(unMatched),{}); | |
| 3235 | then | ||
| 3236 | (i_1,unmatched); | ||
| 3237 | case _ | ||
| 3238 | algorithm | ||
| 3239 | // BFS phase to get the level information | ||
| 3240 | ✗ | rows := HKBFS(U,nv,ne,m,mT,rowmarks,i,level,NONE(),ass1,ass2,{}); | |
| 3241 | // DFS to match | ||
| 3242 | ✗ | ur := HKDFS(rows,i,nv,ne,m,mT,collummarks,level,ass1,ass2,{}); | |
| 3243 | // second DFS in full graph | ||
| 3244 | ✗ | HKDWDFS(ur,i,nv,ne,m,mT,collummarks,ass1,ass2); | |
| 3245 | // remove matched collums from U | ||
| 3246 | ✗ | unmatched := HKgetUnmatched(U,ass1,{}); | |
| 3247 | ✗ | (i_1,unmatched) := HKphase(i,{},nv,ne,m,mT,rowmarks,collummarks,level,ass1,ass2,previousUnmatched,unmatched); | |
| 3248 | then | ||
| 3249 | (i_1,unmatched); | ||
| 3250 | else | ||
| 3251 | algorithm | ||
| 3252 | ✗ | Error.addInternalError("function HKDWphase failed", sourceInfo()); | |
| 3253 | ✗ | then | |
| 3254 | fail(); | ||
| 3255 | end matchcontinue; | ||
| 3256 | end HKDWphase; | ||
| 3257 | |||
| 3258 | protected function HKDWDFS | ||
| 3259 | "function helper for HKDWDFSB, traverses all colums and perform a DFSB phase on each | ||
| 3260 | author: Frenkel TUD 2012-03" | ||
| 3261 | input list<Integer> unmatchedRows; | ||
| 3262 | input Integer i; | ||
| 3263 | input Integer nv; | ||
| 3264 | input Integer ne; | ||
| 3265 | input BackendDAE.AdjacencyMatrix m "m[eqnindx] = list(varindx)"; | ||
| 3266 | input BackendDAE.AdjacencyMatrixT mT "mT[varindx] = list(eqnindx)"; | ||
| 3267 | input array<Integer> collummarks; | ||
| 3268 | input array<Integer> ass1 "ass[eqnindx]=varindx"; | ||
| 3269 | input array<Integer> ass2 "ass[varindx]=eqnindx"; | ||
| 3270 | algorithm | ||
| 3271 | ():= | ||
| 3272 | match unmatchedRows | ||
| 3273 | local | ||
| 3274 | list<Integer> rest; | ||
| 3275 | Integer r; | ||
| 3276 | case {} then (); | ||
| 3277 | case r::rest | ||
| 3278 | algorithm | ||
| 3279 | // search augmenting paths | ||
| 3280 | ✗ | HKDWDFSphase({r},i,r,nv,ne,m,mT,collummarks,ass1,ass2,false); | |
| 3281 | ✗ | HKDWDFS(rest,i,nv,ne,m,mT,collummarks,ass1,ass2); | |
| 3282 | then | ||
| 3283 | (); | ||
| 3284 | else | ||
| 3285 | algorithm | ||
| 3286 | ✗ | Error.addInternalError("function HKDWDFS failed in phase " + intString(i), sourceInfo()); | |
| 3287 | ✗ | then | |
| 3288 | fail(); | ||
| 3289 | |||
| 3290 | end match; | ||
| 3291 | end HKDWDFS; | ||
| 3292 | |||
| 3293 | protected function HKDWDFSphase | ||
| 3294 | "function helper for HKDWDFSBphase, traverses all colums and perform a DFSB phase on each | ||
| 3295 | author: Frenkel TUD 2012-03" | ||
| 3296 | input list<Integer> stack; | ||
| 3297 | input Integer i; | ||
| 3298 | input Integer r; | ||
| 3299 | input Integer nv; | ||
| 3300 | input Integer ne; | ||
| 3301 | input BackendDAE.AdjacencyMatrix m; | ||
| 3302 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 3303 | input array<Integer> collummarks; | ||
| 3304 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 3305 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 3306 | input Boolean inMatched; | ||
| 3307 | output Boolean matched; | ||
| 3308 | algorithm | ||
| 3309 | matched := | ||
| 3310 | match stack | ||
| 3311 | local | ||
| 3312 | list<Integer> collums; | ||
| 3313 | case {} then inMatched; | ||
| 3314 | case _ | ||
| 3315 | algorithm | ||
| 3316 | // traverse all adiacent rows | ||
| 3317 | ✗ | collums := List.select(mT[r], Util.intPositive); | |
| 3318 | ✗ | then | |
| 3319 | HKDWDFStraverseCollums(collums,stack,i,nv,ne,m,mT,collummarks,ass1,ass2,inMatched); | ||
| 3320 | else | ||
| 3321 | algorithm | ||
| 3322 | ✗ | Error.addInternalError("function HKDWDFSphase failed in phase " + intString(i), sourceInfo()); | |
| 3323 | ✗ | then | |
| 3324 | fail(); | ||
| 3325 | end match; | ||
| 3326 | end HKDWDFSphase; | ||
| 3327 | |||
| 3328 | protected function HKDWDFStraverseCollums | ||
| 3329 | "function helper for HKDWDFSB, traverses all collums of a row and search a augmenting path | ||
| 3330 | author: Frenkel TUD 2012-03" | ||
| 3331 | input list<Integer> collums; | ||
| 3332 | input list<Integer> stack; | ||
| 3333 | input Integer i; | ||
| 3334 | input Integer nv; | ||
| 3335 | input Integer ne; | ||
| 3336 | input BackendDAE.AdjacencyMatrix m; | ||
| 3337 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 3338 | input array<Integer> collummarks; | ||
| 3339 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 3340 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 3341 | input Boolean inMatched; | ||
| 3342 | output Boolean matched; | ||
| 3343 | algorithm | ||
| 3344 | matched:= | ||
| 3345 | matchcontinue collums | ||
| 3346 | local | ||
| 3347 | list<Integer> rest; | ||
| 3348 | Integer r,c; | ||
| 3349 | Boolean b; | ||
| 3350 | case {} then inMatched; | ||
| 3351 | case c::_ | ||
| 3352 | algorithm | ||
| 3353 | // collum is unvisited | ||
| 3354 | ✗ | true := intLt(collummarks[c],i); | |
| 3355 | // collum is unmatched | ||
| 3356 | ✗ | true := intLt(ass1[c],0); | |
| 3357 | ✗ | HKDFSreasign(stack,c,ass1,ass2); | |
| 3358 | then | ||
| 3359 | true; | ||
| 3360 | case c::rest | ||
| 3361 | algorithm | ||
| 3362 | // collum is unvisited | ||
| 3363 | ✗ | true := intLt(collummarks[c],i); | |
| 3364 | // collum is matched | ||
| 3365 | ✗ | r := ass1[c]; | |
| 3366 | ✗ | false := intLt(r,0); | |
| 3367 | ✗ | arrayUpdate(collummarks,c,i); | |
| 3368 | ✗ | b := HKDWDFSphase(r::stack,i,r,nv,ne,m,mT,collummarks,ass1,ass2,inMatched); | |
| 3369 | ✗ | then | |
| 3370 | HKDWDFStraverseCollums1(b,rest,stack,i,nv,ne,m,mT,collummarks,ass1,ass2); | ||
| 3371 | case c::rest | ||
| 3372 | algorithm | ||
| 3373 | // collum is visited | ||
| 3374 | ✗ | false := intLt(collummarks[c],i); | |
| 3375 | ✗ | then | |
| 3376 | HKDWDFStraverseCollums(rest,stack,i,nv,ne,m,mT,collummarks,ass1,ass2,inMatched); | ||
| 3377 | else | ||
| 3378 | algorithm | ||
| 3379 | ✗ | Error.addInternalError("function HKDWDFStraverseCollums failed", sourceInfo()); | |
| 3380 | ✗ | then | |
| 3381 | fail(); | ||
| 3382 | end matchcontinue; | ||
| 3383 | end HKDWDFStraverseCollums; | ||
| 3384 | |||
| 3385 | protected function HKDWDFStraverseCollums1 | ||
| 3386 | "function helper for HKDWDFSBtraverseCollums | ||
| 3387 | author: Frenkel TUD 2012-03" | ||
| 3388 | input Boolean inMatched; | ||
| 3389 | input list<Integer> rows; | ||
| 3390 | input list<Integer> stack; | ||
| 3391 | input Integer i; | ||
| 3392 | input Integer nv; | ||
| 3393 | input Integer ne; | ||
| 3394 | input BackendDAE.AdjacencyMatrix m; | ||
| 3395 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 3396 | input array<Integer> collummarks; | ||
| 3397 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 3398 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 3399 | output Boolean matched; | ||
| 3400 | algorithm | ||
| 3401 | ✗ | matched:= | |
| 3402 | match inMatched | ||
| 3403 | case true then inMatched; | ||
| 3404 | else HKDWDFStraverseCollums(rows,stack,i,nv,ne,m,mT,collummarks,ass1,ass2,inMatched); | ||
| 3405 | end match; | ||
| 3406 | end HKDWDFStraverseCollums1; | ||
| 3407 | |||
| 3408 | |||
| 3409 | public function ABMP | ||
| 3410 | " complexity O(sqrt(n)*tau) | ||
| 3411 | author: Frenkel TUD 2012-03" | ||
| 3412 | input BackendDAE.EqSystem isyst; | ||
| 3413 | input BackendDAE.Shared ishared; | ||
| 3414 | input Boolean clearMatching; | ||
| 3415 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 3416 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 3417 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 3418 | output BackendDAE.EqSystem osyst; | ||
| 3419 | output BackendDAE.Shared oshared; | ||
| 3420 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 3421 | algorithm | ||
| 3422 | (osyst,oshared,outArg) := | ||
| 3423 | matchcontinue isyst | ||
| 3424 | local | ||
| 3425 | Integer nvars,neqns; | ||
| 3426 | BackendDAE.AdjacencyMatrix m; | ||
| 3427 | BackendDAE.AdjacencyMatrixT mt; | ||
| 3428 | array<Integer> vec1,vec2; | ||
| 3429 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 3430 | BackendDAE.EqSystem syst; | ||
| 3431 | BackendDAE.Shared shared; | ||
| 3432 | array<Integer> rowmarks,level,collummarks,rlevel,colptrs; | ||
| 3433 | list<Integer> unmatched; | ||
| 3434 | case BackendDAE.EQSYSTEM(m=SOME(m),mT=SOME(mt)) | ||
| 3435 | algorithm | ||
| 3436 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 3437 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 3438 | ✗ | true := intGt(nvars,0); | |
| 3439 | ✗ | true := intGt(neqns,0); | |
| 3440 | ✗ | (vec1,vec2) := getAssignment(clearMatching,nvars,neqns,isyst); | |
| 3441 | ✗ | rowmarks := arrayCreate(nvars,-1); | |
| 3442 | ✗ | collummarks := arrayCreate(neqns,-1); | |
| 3443 | ✗ | level := arrayCreate(neqns,-1); | |
| 3444 | ✗ | rlevel := arrayCreate(nvars,nvars); | |
| 3445 | ✗ | colptrs := arrayCreate(neqns,-1); | |
| 3446 | ✗ | unmatched := cheapmatchingalgorithm(nvars,neqns,m,mt,vec1,vec2,true); | |
| 3447 | ✗ | (vec1,vec2,syst,shared,arg) := ABMP1(1,unmatched,rowmarks,collummarks,level,rlevel,colptrs,isyst,ishared,nvars,neqns,vec1,vec2,inMatchingOptions,sssHandler,inArg); | |
| 3448 | ✗ | syst := BackendDAEUtil.setEqSystMatching(syst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 3449 | ✗ | then | |
| 3450 | (syst,shared,arg); | ||
| 3451 | // fail case if system is empty | ||
| 3452 | case _ | ||
| 3453 | algorithm | ||
| 3454 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 3455 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 3456 | ✗ | false := intGt(nvars,0); | |
| 3457 | ✗ | false := intGt(neqns,0); | |
| 3458 | ✗ | vec1 := listArray({}); | |
| 3459 | ✗ | vec2 := listArray({}); | |
| 3460 | ✗ | syst := BackendDAEUtil.setEqSystMatching(isyst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 3461 | then | ||
| 3462 | (syst,ishared,inArg); | ||
| 3463 | else | ||
| 3464 | algorithm | ||
| 3465 | ✗ | if Flags.isSet(Flags.FAILTRACE) then | |
| 3466 | ✗ | Debug.trace("- Matching.ABMP failed\n"); | |
| 3467 | end if; | ||
| 3468 | ✗ | then | |
| 3469 | fail(); | ||
| 3470 | end matchcontinue; | ||
| 3471 | end ABMP; | ||
| 3472 | |||
| 3473 | protected function ABMP1 | ||
| 3474 | "function: ABMP1, helper for HKABMP | ||
| 3475 | author: Frenkel TUD 2012-03" | ||
| 3476 | input Integer i; | ||
| 3477 | input list<Integer> unmatched; | ||
| 3478 | input array<Integer> rowmarks; | ||
| 3479 | input array<Integer> collummarks; | ||
| 3480 | input array<Integer> level; | ||
| 3481 | input array<Integer> rlevel; | ||
| 3482 | input array<Integer> colptrs; | ||
| 3483 | input BackendDAE.EqSystem isyst; | ||
| 3484 | input BackendDAE.Shared ishared; | ||
| 3485 | input Integer nv; | ||
| 3486 | input Integer ne; | ||
| 3487 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 3488 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 3489 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 3490 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 3491 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 3492 | output array<Integer> outAss1; | ||
| 3493 | output array<Integer> outAss2; | ||
| 3494 | output BackendDAE.EqSystem osyst; | ||
| 3495 | output BackendDAE.Shared oshared; | ||
| 3496 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 3497 | algorithm | ||
| 3498 | (outAss1,outAss2,osyst,oshared,outArg):= | ||
| 3499 | match (unmatched, isyst) | ||
| 3500 | local | ||
| 3501 | BackendDAE.AdjacencyMatrix m,mt; | ||
| 3502 | Integer nv_1,ne_1,i_1,lim; | ||
| 3503 | list<Integer> unmatched1; | ||
| 3504 | list<list<Integer>> meqns; | ||
| 3505 | BackendDAE.StructurallySingularSystemHandlerArg arg,arg1; | ||
| 3506 | BackendDAE.EqSystem syst; | ||
| 3507 | BackendDAE.Shared shared; | ||
| 3508 | array<Integer> ass1_1,ass1_2,ass2_1,ass2_2,rowmarks1,collummarks1,level1,rlevel1; | ||
| 3509 | case ({}, _) | ||
| 3510 | then | ||
| 3511 | (ass1,ass2,isyst,ishared,inArg); | ||
| 3512 | case (_, BackendDAE.EQSYSTEM(m=SOME(m),mT=SOME(mt))) | ||
| 3513 | algorithm | ||
| 3514 | ✗ | lim := integer(0.1 * sqrt(arrayLength(ass1))); | |
| 3515 | ✗ | unmatched1 := ABMPphase(unmatched,i,nv,ne,m,mt,rowmarks,rlevel,colptrs,lim,ass1,ass2); | |
| 3516 | ✗ | (i_1,unmatched1) := HKphase(i+1,unmatched,nv,ne,m,mt,rowmarks,collummarks,level,ass1,ass2,listLength(unmatched),{}); | |
| 3517 | ✗ | meqns := getEqnsforIndexReduction(unmatched1,ne,m,mt,ass1,ass2,inArg); | |
| 3518 | ✗ | (unmatched1,rowmarks1,collummarks1,level1,rlevel1,nv_1,ne_1,ass1_1,ass2_1,syst,shared,arg) := ABMP2(meqns,unmatched1,{},rowmarks,collummarks,level,rlevel,isyst,ishared,nv,ne,ass1,ass2,inMatchingOptions,sssHandler,inArg); | |
| 3519 | ✗ | (ass1_2,ass2_2,syst,shared,arg1) := ABMP1(i_1+1,unmatched1,rowmarks1,collummarks1,level1,rlevel1,colptrs,syst,shared,nv_1,ne_1,ass1_1,ass2_1,inMatchingOptions,sssHandler,arg); | |
| 3520 | then | ||
| 3521 | (ass1_2,ass2_2,syst,shared,arg1); | ||
| 3522 | end match; | ||
| 3523 | end ABMP1; | ||
| 3524 | |||
| 3525 | protected function ABMP2 | ||
| 3526 | "function: ABMP2, helper for ABMP | ||
| 3527 | author: Frenkel TUD 2012-03" | ||
| 3528 | input list<list<Integer>> meqns "Marked Equations for Index Reduction"; | ||
| 3529 | input list<Integer> unmatched; | ||
| 3530 | input list<Integer> changedEqns; | ||
| 3531 | input array<Integer> rowmarks; | ||
| 3532 | input array<Integer> collummarks; | ||
| 3533 | input array<Integer> level; | ||
| 3534 | input array<Integer> rlevel; | ||
| 3535 | input BackendDAE.EqSystem isyst; | ||
| 3536 | input BackendDAE.Shared ishared; | ||
| 3537 | input Integer nv; | ||
| 3538 | input Integer ne; | ||
| 3539 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 3540 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 3541 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 3542 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 3543 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 3544 | output list<Integer> outunmatched; | ||
| 3545 | output array<Integer> outrowmarks; | ||
| 3546 | output array<Integer> outcollummarks; | ||
| 3547 | output array<Integer> outlevel; | ||
| 3548 | output array<Integer> outrlevel; | ||
| 3549 | output Integer nvars; | ||
| 3550 | output Integer neqns; | ||
| 3551 | output array<Integer> outAss1; | ||
| 3552 | output array<Integer> outAss2; | ||
| 3553 | output BackendDAE.EqSystem osyst; | ||
| 3554 | output BackendDAE.Shared oshared; | ||
| 3555 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 3556 | algorithm | ||
| 3557 | (outunmatched,outrowmarks,outcollummarks,outlevel,outrlevel,nvars,neqns,outAss1,outAss2,osyst,oshared,outArg):= | ||
| 3558 | match (meqns, inMatchingOptions) | ||
| 3559 | local | ||
| 3560 | Integer nv_1,ne_1; | ||
| 3561 | list<Integer> unmatched1; | ||
| 3562 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 3563 | BackendDAE.EqSystem syst; | ||
| 3564 | BackendDAE.Shared shared; | ||
| 3565 | array<Integer> ass1_1,ass2_1,rowmarks1,collummarks1,level1,rlevel1; | ||
| 3566 | |||
| 3567 | case ({}, _) | ||
| 3568 | then | ||
| 3569 | (unmatched,rowmarks,collummarks,level,rlevel,nv,ne,ass1,ass2,isyst,ishared,inArg); | ||
| 3570 | case (_, (BackendDAE.INDEX_REDUCTION(),_)) | ||
| 3571 | algorithm | ||
| 3572 | ✗ | (unmatched1,_,syst,shared,ass2_1,ass1_1,arg) := sssHandler(meqns,0,isyst,ishared,ass2,ass1,inArg); | |
| 3573 | ✗ | ne_1 := BackendDAEUtil.systemSize(syst); | |
| 3574 | ✗ | nv_1 := BackendVariable.daenumVariables(syst); | |
| 3575 | ✗ | ass1_1 := assignmentsArrayExpand(ass1_1,ne_1,arrayLength(ass1_1),-1); | |
| 3576 | ✗ | ass2_1 := assignmentsArrayExpand(ass2_1,nv_1,arrayLength(ass2_1),-1); | |
| 3577 | ✗ | rowmarks1 := assignmentsArrayExpand(rowmarks,nv_1,arrayLength(rowmarks),-1); | |
| 3578 | ✗ | collummarks1 := assignmentsArrayExpand(collummarks,ne_1,arrayLength(collummarks),-1); | |
| 3579 | ✗ | rlevel1 := arrayCreate(arrayLength(ass2_1),arrayLength(ass2_1)); | |
| 3580 | ✗ | level1 := assignmentsArrayExpand(level,ne_1,arrayLength(level),-1); | |
| 3581 | ✗ | then | |
| 3582 | (unmatched1,rowmarks1,collummarks1,level1,rlevel1,nv_1,ne_1,ass1_1,ass2_1,syst,shared,arg); | ||
| 3583 | case (_, _) | ||
| 3584 | algorithm | ||
| 3585 | ✗ | singularSystemError(meqns,0,isyst,ishared,ass2,ass1,inArg); | |
| 3586 | ✗ | then | |
| 3587 | fail(); | ||
| 3588 | end match; | ||
| 3589 | end ABMP2; | ||
| 3590 | |||
| 3591 | protected function ABMPphase | ||
| 3592 | "function helper for ABMP, traverses all unmatched | ||
| 3593 | colums and run a BFS and DFS to assign level information | ||
| 3594 | and increase matching. | ||
| 3595 | author: Frenkel TUD 2012-03" | ||
| 3596 | input list<Integer> U; | ||
| 3597 | input Integer i; | ||
| 3598 | input Integer nv; | ||
| 3599 | input Integer ne; | ||
| 3600 | input BackendDAE.AdjacencyMatrix m "m[eqnindx] = list(varindx)"; | ||
| 3601 | input BackendDAE.AdjacencyMatrixT mT "mT[varindx] = list(eqnindx)"; | ||
| 3602 | input array<Integer> rowmarks; | ||
| 3603 | input array<Integer> level; | ||
| 3604 | input array<Integer> colptrs; | ||
| 3605 | input Integer lim; | ||
| 3606 | input array<Integer> ass1 "ass[eqnindx]=varindx"; | ||
| 3607 | input array<Integer> ass2 "ass[varindx]=eqnindx"; | ||
| 3608 | output list<Integer> unMatched; | ||
| 3609 | algorithm | ||
| 3610 | unMatched:= | ||
| 3611 | match U | ||
| 3612 | local | ||
| 3613 | list<Integer> ur; | ||
| 3614 | case {} then {}; | ||
| 3615 | case _ | ||
| 3616 | algorithm | ||
| 3617 | // BFS to assign levels | ||
| 3618 | ✗ | ur := ABMPBFSphase(U,i,0,lim,listLength(U),nv,ne,m,mT,rowmarks,level,ass1,ass2,{},{}); | |
| 3619 | ✗ | then | |
| 3620 | ABMPphase1(U,ur,i,nv,ne,m,mT,rowmarks,level,colptrs,lim,ass1,ass2); | ||
| 3621 | else | ||
| 3622 | algorithm | ||
| 3623 | ✗ | Error.addInternalError("function ABMPphase failed", sourceInfo()); | |
| 3624 | ✗ | then | |
| 3625 | fail(); | ||
| 3626 | end match; | ||
| 3627 | end ABMPphase; | ||
| 3628 | |||
| 3629 | protected function ABMPphase1 | ||
| 3630 | "function helper for ABMP, traverses all unmatched | ||
| 3631 | colums and run a BFS and DFS to assign level information | ||
| 3632 | and increase matching. | ||
| 3633 | author: Frenkel TUD 2012-03" | ||
| 3634 | input list<Integer> U; | ||
| 3635 | input list<Integer> unmatchedRows; | ||
| 3636 | input Integer i; | ||
| 3637 | input Integer nv; | ||
| 3638 | input Integer ne; | ||
| 3639 | input BackendDAE.AdjacencyMatrix m "m[eqnindx] = list(varindx)"; | ||
| 3640 | input BackendDAE.AdjacencyMatrixT mT "mT[varindx] = list(eqnindx)"; | ||
| 3641 | input array<Integer> rowmarks; | ||
| 3642 | input array<Integer> level; | ||
| 3643 | input array<Integer> colptrs; | ||
| 3644 | input Integer lim; | ||
| 3645 | input array<Integer> ass1 "ass[eqnindx]=varindx"; | ||
| 3646 | input array<Integer> ass2 "ass[varindx]=eqnindx"; | ||
| 3647 | output list<Integer> unMatched; | ||
| 3648 | algorithm | ||
| 3649 | unMatched:= | ||
| 3650 | match unmatchedRows | ||
| 3651 | local | ||
| 3652 | list<Integer> unmatched; | ||
| 3653 | Integer L,r; | ||
| 3654 | case {} then U; | ||
| 3655 | case r::_ | ||
| 3656 | algorithm | ||
| 3657 | ✗ | L := level[r]; | |
| 3658 | ✗ | ABMPDFS(unmatchedRows,0,L,nv,ne,m,mT,level,colptrs,ass1,ass2,{}); | |
| 3659 | // remove unmatched collums from U | ||
| 3660 | ✗ | unmatched := HKgetUnmatched(U,ass1,{}); | |
| 3661 | ✗ | then | |
| 3662 | ABMPphase2(unmatched,i,L,nv,ne,m,mT,rowmarks,level,colptrs,lim,ass1,ass2); | ||
| 3663 | else | ||
| 3664 | algorithm | ||
| 3665 | ✗ | Error.addInternalError("function ABMPphase1 failed", sourceInfo()); | |
| 3666 | ✗ | then | |
| 3667 | fail(); | ||
| 3668 | end match; | ||
| 3669 | end ABMPphase1; | ||
| 3670 | |||
| 3671 | protected function ABMPphase2 | ||
| 3672 | "function helper for ABMP, traverses all unmatched | ||
| 3673 | colums and run a BFS and DFS to assign level information | ||
| 3674 | and increase matching. | ||
| 3675 | author: Frenkel TUD 2012-03" | ||
| 3676 | input list<Integer> U; | ||
| 3677 | input Integer i; | ||
| 3678 | input Integer L; | ||
| 3679 | input Integer nv; | ||
| 3680 | input Integer ne; | ||
| 3681 | input BackendDAE.AdjacencyMatrix m "m[eqnindx] = list(varindx)"; | ||
| 3682 | input BackendDAE.AdjacencyMatrixT mT "mT[varindx] = list(eqnindx)"; | ||
| 3683 | input array<Integer> rowmarks; | ||
| 3684 | input array<Integer> level; | ||
| 3685 | input array<Integer> colptrs; | ||
| 3686 | input Integer lim; | ||
| 3687 | input array<Integer> ass1 "ass[eqnindx]=varindx"; | ||
| 3688 | input array<Integer> ass2 "ass[varindx]=eqnindx"; | ||
| 3689 | output list<Integer> unMatched; | ||
| 3690 | algorithm | ||
| 3691 | unMatched:= | ||
| 3692 | matchcontinue U | ||
| 3693 | case {} then U; | ||
| 3694 | case _ | ||
| 3695 | algorithm | ||
| 3696 | ✗ | true := intGt(50*L,listLength(U)); | |
| 3697 | then | ||
| 3698 | U; | ||
| 3699 | case _ | ||
| 3700 | // next round width updated level | ||
| 3701 | ✗ | then | |
| 3702 | ABMPphase(U,i,nv,ne,m,mT,rowmarks,level,colptrs,lim,ass1,ass2); | ||
| 3703 | else | ||
| 3704 | algorithm | ||
| 3705 | ✗ | Error.addInternalError("function ABMPphase2 failed", sourceInfo()); | |
| 3706 | ✗ | then | |
| 3707 | fail(); | ||
| 3708 | end matchcontinue; | ||
| 3709 | end ABMPphase2; | ||
| 3710 | |||
| 3711 | protected function ABMPBFSphase | ||
| 3712 | "function helper for ABMP, traverses all colums and set level information | ||
| 3713 | author: Frenkel TUD 2012-03" | ||
| 3714 | input list<Integer> queue; | ||
| 3715 | input Integer i; | ||
| 3716 | input Integer L; | ||
| 3717 | input Integer lim; | ||
| 3718 | input Integer lim1; | ||
| 3719 | input Integer nv; | ||
| 3720 | input Integer ne; | ||
| 3721 | input BackendDAE.AdjacencyMatrix m; | ||
| 3722 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 3723 | input array<Integer> rowmarks; | ||
| 3724 | input array<Integer> level; | ||
| 3725 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 3726 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 3727 | input list<Integer> nextqueue; | ||
| 3728 | input list<Integer> unMatched; | ||
| 3729 | output list<Integer> outunMatched; | ||
| 3730 | algorithm | ||
| 3731 | outunMatched := | ||
| 3732 | match (queue, nextqueue) | ||
| 3733 | local | ||
| 3734 | list<Integer> rest,rows,queue1,unmatched; | ||
| 3735 | Integer c,l; | ||
| 3736 | Boolean b; | ||
| 3737 | case ({}, {}) then unMatched; | ||
| 3738 | case ({}, _) | ||
| 3739 | algorithm | ||
| 3740 | ✗ | l := L+2; | |
| 3741 | ✗ | b := intGt(l,lim) or intGt(50*l,lim1); | |
| 3742 | ✗ | then | |
| 3743 | ABMPBFSphase1(b,nextqueue,i,l,lim,lim1,nv,ne,m,mT,rowmarks,level,ass1,ass2,{},unMatched); | ||
| 3744 | case (c::rest, _) | ||
| 3745 | algorithm | ||
| 3746 | // traverse all adiacent rows | ||
| 3747 | ✗ | rows := List.select(m[c], Util.intPositive); | |
| 3748 | ✗ | (queue1,unmatched) := ABMPBFStraverseRows(rows,i,L,nv,ne,m,mT,rowmarks,level,ass1,ass2,nextqueue,unMatched); | |
| 3749 | ✗ | then | |
| 3750 | ABMPBFSphase(rest,i,L,lim,lim1,nv,ne,m,mT,rowmarks,level,ass1,ass2,queue1,unmatched); | ||
| 3751 | else | ||
| 3752 | algorithm | ||
| 3753 | ✗ | Error.addInternalError("function ABMPBFSphase failed", sourceInfo()); | |
| 3754 | ✗ | then | |
| 3755 | fail(); | ||
| 3756 | end match; | ||
| 3757 | end ABMPBFSphase; | ||
| 3758 | |||
| 3759 | protected function ABMPBFSphase1 | ||
| 3760 | "function helper for ABMPBFSphase | ||
| 3761 | author: Frenkel TUD 2012-03" | ||
| 3762 | input Boolean inStop; | ||
| 3763 | input list<Integer> queue; | ||
| 3764 | input Integer i; | ||
| 3765 | input Integer L; | ||
| 3766 | input Integer lim; | ||
| 3767 | input Integer lim1; | ||
| 3768 | input Integer nv; | ||
| 3769 | input Integer ne; | ||
| 3770 | input BackendDAE.AdjacencyMatrix m; | ||
| 3771 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 3772 | input array<Integer> rowmarks; | ||
| 3773 | input array<Integer> level; | ||
| 3774 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 3775 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 3776 | input list<Integer> nextqueue; | ||
| 3777 | input list<Integer> unMatched; | ||
| 3778 | output list<Integer> outunMatched; | ||
| 3779 | algorithm | ||
| 3780 | outunMatched := | ||
| 3781 | match inStop | ||
| 3782 | case true then unMatched; | ||
| 3783 | case false | ||
| 3784 | ✗ | then | |
| 3785 | ABMPBFSphase(queue,i,L,lim,lim1,nv,ne,m,mT,rowmarks,level,ass1,ass2,nextqueue,unMatched); | ||
| 3786 | else | ||
| 3787 | algorithm | ||
| 3788 | ✗ | Error.addInternalError("function ABMPBFSphase1 failed", sourceInfo()); | |
| 3789 | ✗ | then | |
| 3790 | fail(); | ||
| 3791 | end match; | ||
| 3792 | end ABMPBFSphase1; | ||
| 3793 | |||
| 3794 | protected function ABMPBFStraverseRows | ||
| 3795 | "function helper for ABMPBFS, traverses all rows and assign level informaiton | ||
| 3796 | author: Frenkel TUD 2012-03" | ||
| 3797 | input list<Integer> rows; | ||
| 3798 | input Integer i; | ||
| 3799 | input Integer L; | ||
| 3800 | input Integer nv; | ||
| 3801 | input Integer ne; | ||
| 3802 | input BackendDAE.AdjacencyMatrix m; | ||
| 3803 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 3804 | input array<Integer> rowmarks; | ||
| 3805 | input array<Integer> level; | ||
| 3806 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 3807 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 3808 | input list<Integer> queue; | ||
| 3809 | input list<Integer> unMatched; | ||
| 3810 | output list<Integer> outEqnqueue; | ||
| 3811 | output list<Integer> outUnmatched; | ||
| 3812 | algorithm | ||
| 3813 | (outEqnqueue,outUnmatched):= | ||
| 3814 | matchcontinue rows | ||
| 3815 | local | ||
| 3816 | list<Integer> rest,queue1,unmatched; | ||
| 3817 | Integer rc,r; | ||
| 3818 | ✗ | case {} then (listReverse(queue),unMatched); | |
| 3819 | case r::rest | ||
| 3820 | algorithm | ||
| 3821 | // row is unvisited | ||
| 3822 | ✗ | false := intEq(rowmarks[r],i); | |
| 3823 | // row is unmatched | ||
| 3824 | ✗ | true := intLt(ass2[r],0); | |
| 3825 | ✗ | arrayUpdate(level,r,L); | |
| 3826 | ✗ | arrayUpdate(rowmarks,r,i); | |
| 3827 | ✗ | (queue1,unmatched) := ABMPBFStraverseRows(rest,i,L,nv,ne,m,mT,rowmarks,level,ass1,ass2,queue,r::unMatched); | |
| 3828 | then | ||
| 3829 | (queue1,unmatched); | ||
| 3830 | case r::rest | ||
| 3831 | algorithm | ||
| 3832 | // row is unvisited | ||
| 3833 | ✗ | false := intEq(rowmarks[r],i); | |
| 3834 | // row is matched | ||
| 3835 | ✗ | rc := ass2[r]; | |
| 3836 | ✗ | false := intLt(rc,0); | |
| 3837 | ✗ | arrayUpdate(rowmarks,r,i); | |
| 3838 | ✗ | (queue1,unmatched) := ABMPBFStraverseRows(rest,i,L,nv,ne,m,mT,rowmarks,level,ass1,ass2,rc::queue,unMatched); | |
| 3839 | then | ||
| 3840 | (queue1,unmatched); | ||
| 3841 | case r::rest | ||
| 3842 | algorithm | ||
| 3843 | // row is visited | ||
| 3844 | ✗ | true := intEq(rowmarks[r],i); | |
| 3845 | ✗ | (queue1,unmatched) := ABMPBFStraverseRows(rest,i,L,nv,ne,m,mT,rowmarks,level,ass1,ass2,queue,unMatched); | |
| 3846 | then | ||
| 3847 | (queue1,unmatched); | ||
| 3848 | else | ||
| 3849 | algorithm | ||
| 3850 | ✗ | Error.addInternalError("function ABMPBFStraverseRows failed", sourceInfo()); | |
| 3851 | ✗ | then | |
| 3852 | fail(); | ||
| 3853 | end matchcontinue; | ||
| 3854 | end ABMPBFStraverseRows; | ||
| 3855 | |||
| 3856 | protected function ABMPDFS | ||
| 3857 | "function helper for ABMPDFS, traverses all rows and perform a DFSB phase on each | ||
| 3858 | author: Frenkel TUD 2012-03" | ||
| 3859 | input list<Integer> unmatchedRows; | ||
| 3860 | input Integer i; | ||
| 3861 | input Integer L; | ||
| 3862 | input Integer nv; | ||
| 3863 | input Integer ne; | ||
| 3864 | input BackendDAE.AdjacencyMatrix m "m[eqnindx] = list(varindx)"; | ||
| 3865 | input BackendDAE.AdjacencyMatrixT mT "mT[varindx] = list(eqnindx)"; | ||
| 3866 | input array<Integer> level; | ||
| 3867 | input array<Integer> colptrs; | ||
| 3868 | input array<Integer> ass1 "ass[eqnindx]=varindx"; | ||
| 3869 | input array<Integer> ass2 "ass[varindx]=eqnindx"; | ||
| 3870 | input list<Integer> unMatched; | ||
| 3871 | algorithm | ||
| 3872 | ():= | ||
| 3873 | matchcontinue unmatchedRows | ||
| 3874 | local | ||
| 3875 | list<Integer> rest,unmatched; | ||
| 3876 | Integer r,i_1; | ||
| 3877 | Boolean b; | ||
| 3878 | case {} then (); | ||
| 3879 | case _ | ||
| 3880 | algorithm | ||
| 3881 | ✗ | false := intLt(i,ne); | |
| 3882 | then (); | ||
| 3883 | case r::rest | ||
| 3884 | algorithm | ||
| 3885 | // search augmenting paths | ||
| 3886 | ✗ | arrayUpdate(colptrs,r,0); | |
| 3887 | ✗ | (i_1,b) := ABMPDFSphase({r},i,r,nv,ne,m,mT,level,colptrs,ass1,ass2); | |
| 3888 | ✗ | unmatched := List.consOnTrue(not b, r, unMatched); | |
| 3889 | ✗ | ABMPDFS1(b,r,rest,unmatched,i_1,L,nv,ne,m,mT,level,colptrs,ass1,ass2); | |
| 3890 | then | ||
| 3891 | (); | ||
| 3892 | else | ||
| 3893 | algorithm | ||
| 3894 | ✗ | Error.addInternalError("function ABMPBFS failed", sourceInfo()); | |
| 3895 | ✗ | then | |
| 3896 | fail(); | ||
| 3897 | end matchcontinue; | ||
| 3898 | end ABMPDFS; | ||
| 3899 | |||
| 3900 | protected function ABMPDFS1 | ||
| 3901 | "function helper for ABMPDFS, traverses all rows and perform a DFSB phase on each | ||
| 3902 | author: Frenkel TUD 2012-03" | ||
| 3903 | input Boolean inMatched; | ||
| 3904 | input Integer r; | ||
| 3905 | input list<Integer> unmatchedRows; | ||
| 3906 | input list<Integer> unMatched; | ||
| 3907 | input Integer i; | ||
| 3908 | input Integer L; | ||
| 3909 | input Integer nv; | ||
| 3910 | input Integer ne; | ||
| 3911 | input BackendDAE.AdjacencyMatrix m "m[eqnindx] = list(varindx)"; | ||
| 3912 | input BackendDAE.AdjacencyMatrixT mT "mT[varindx] = list(eqnindx)"; | ||
| 3913 | input array<Integer> level; | ||
| 3914 | input array<Integer> colptrs; | ||
| 3915 | input array<Integer> ass1 "ass[eqnindx]=varindx"; | ||
| 3916 | input array<Integer> ass2 "ass[varindx]=eqnindx"; | ||
| 3917 | algorithm | ||
| 3918 | ():= | ||
| 3919 | matchcontinue (inMatched, unmatchedRows, unMatched) | ||
| 3920 | local | ||
| 3921 | list<Integer> unmatched; | ||
| 3922 | Integer r1,r2,l; | ||
| 3923 | case (_, {}, _) then (); | ||
| 3924 | case (true, _, _) | ||
| 3925 | algorithm | ||
| 3926 | ✗ | true := intGt(50*L,listLength(unmatchedRows)+listLength(unMatched)); | |
| 3927 | then (); | ||
| 3928 | case (true, _, {}) | ||
| 3929 | algorithm | ||
| 3930 | ✗ | false := intGt(50*L,listLength(unmatchedRows)+listLength(unMatched)); | |
| 3931 | ✗ | ABMPDFS(unmatchedRows,i,L,nv,ne,m,mT,level,colptrs,ass1,ass2,{}); | |
| 3932 | then (); | ||
| 3933 | case (true, r1::_, r2::{}) | ||
| 3934 | algorithm | ||
| 3935 | ✗ | false := intGt(50*L,listLength(unmatchedRows)+listLength(unMatched)); | |
| 3936 | ✗ | false := intEq(L,level[r1]); | |
| 3937 | ✗ | l := level[r2]; | |
| 3938 | ✗ | ABMPDFS(r2::unmatchedRows,i,l,nv,ne,m,mT,level,colptrs,ass1,ass2,{}); | |
| 3939 | then (); | ||
| 3940 | case (true, r1::_, _) | ||
| 3941 | algorithm | ||
| 3942 | ✗ | false := intGt(50*L,listLength(unmatchedRows)+listLength(unMatched)); | |
| 3943 | ✗ | false := intEq(L,level[r1]); | |
| 3944 | ✗ | r2::unmatched := listReverse(unMatched); | |
| 3945 | ✗ | l := level[r2]; | |
| 3946 | ✗ | unmatched := listAppend(unmatched,r2::unmatchedRows) annotation(__OpenModelica_DisableListAppendWarning=true); | |
| 3947 | ✗ | ABMPDFS(unmatchedRows,i,l,nv,ne,m,mT,level,colptrs,ass1,ass2,{}); | |
| 3948 | then (); | ||
| 3949 | case (_, r1::_, {}) | ||
| 3950 | algorithm | ||
| 3951 | ✗ | false := intEq(L,level[r1]); | |
| 3952 | ✗ | l := level[r]; | |
| 3953 | ✗ | ABMPDFS(unmatchedRows,i,l,nv,ne,m,mT,level,colptrs,ass1,ass2,{}); | |
| 3954 | then (); | ||
| 3955 | case (_, r1::_, _) | ||
| 3956 | algorithm | ||
| 3957 | ✗ | false := intEq(L,level[r1]); | |
| 3958 | ✗ | r2::unmatched := listReverse(unMatched); | |
| 3959 | ✗ | l := level[r2]; | |
| 3960 | ✗ | unmatched := listAppend(r2::unmatched,unmatchedRows); | |
| 3961 | ✗ | ABMPDFS(unmatched,i,l,nv,ne,m,mT,level,colptrs,ass1,ass2,{}); | |
| 3962 | then (); | ||
| 3963 | case (_, r1::_, _) | ||
| 3964 | algorithm | ||
| 3965 | ✗ | true := intEq(L,level[r1]); | |
| 3966 | ✗ | ABMPDFS(unmatchedRows,i,L,nv,ne,m,mT,level,colptrs,ass1,ass2,unMatched); | |
| 3967 | then (); | ||
| 3968 | else | ||
| 3969 | algorithm | ||
| 3970 | ✗ | Error.addInternalError("function ABMPBFS1 failed", sourceInfo()); | |
| 3971 | ✗ | then | |
| 3972 | fail(); | ||
| 3973 | end matchcontinue; | ||
| 3974 | end ABMPDFS1; | ||
| 3975 | |||
| 3976 | protected function ABMPDFSphase | ||
| 3977 | "function helper for ABMPDFSBphase, traverses all colums and perform a DFSB phase on each | ||
| 3978 | author: Frenkel TUD 2012-03" | ||
| 3979 | input list<Integer> stack; | ||
| 3980 | input Integer i; | ||
| 3981 | input Integer r; | ||
| 3982 | input Integer nv; | ||
| 3983 | input Integer ne; | ||
| 3984 | input BackendDAE.AdjacencyMatrix m; | ||
| 3985 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 3986 | input array<Integer> level; | ||
| 3987 | input array<Integer> colptrs; | ||
| 3988 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 3989 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 3990 | output Integer outI; | ||
| 3991 | output Boolean matched; | ||
| 3992 | algorithm | ||
| 3993 | (outI,matched) := | ||
| 3994 | match stack | ||
| 3995 | local | ||
| 3996 | list<Integer> collums; | ||
| 3997 | Integer desL,i_1; | ||
| 3998 | Boolean b; | ||
| 3999 | case {} then (i,false); | ||
| 4000 | case _ | ||
| 4001 | algorithm | ||
| 4002 | // traverse all adiacent rows | ||
| 4003 | ✗ | collums := List.select(mT[r], Util.intPositive); | |
| 4004 | ✗ | collums := List.stripN(collums,colptrs[r]); | |
| 4005 | ✗ | desL := level[r]-2; | |
| 4006 | ✗ | (i_1,b) := ABMPDFStraverseCollums(collums,1,stack,r,i,desL,nv,ne,m,mT,level,colptrs,ass1,ass2); | |
| 4007 | then | ||
| 4008 | (i_1,b); | ||
| 4009 | else | ||
| 4010 | algorithm | ||
| 4011 | ✗ | Error.addInternalError("function ABMPDFSphase failed in phase " + intString(i), sourceInfo()); | |
| 4012 | ✗ | then | |
| 4013 | fail(); | ||
| 4014 | end match; | ||
| 4015 | end ABMPDFSphase; | ||
| 4016 | |||
| 4017 | protected function ABMPDFStraverseCollums | ||
| 4018 | "function helper for ABMPDFSB, traverses all collums of a row and search a augmenting path | ||
| 4019 | author: Frenkel TUD 2012-03" | ||
| 4020 | input list<Integer> collums; | ||
| 4021 | input Integer counter; | ||
| 4022 | input list<Integer> stack; | ||
| 4023 | input Integer r; | ||
| 4024 | input Integer i; | ||
| 4025 | input Integer desL; | ||
| 4026 | input Integer nv; | ||
| 4027 | input Integer ne; | ||
| 4028 | input BackendDAE.AdjacencyMatrix m; | ||
| 4029 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 4030 | input array<Integer> level; | ||
| 4031 | input array<Integer> colptrs; | ||
| 4032 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 4033 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 4034 | output Integer outI; | ||
| 4035 | output Boolean matched; | ||
| 4036 | algorithm | ||
| 4037 | (outI,matched):= | ||
| 4038 | matchcontinue collums | ||
| 4039 | local | ||
| 4040 | list<Integer> rest; | ||
| 4041 | Integer rc,c,i_1; | ||
| 4042 | Boolean b; | ||
| 4043 | case {} | ||
| 4044 | algorithm | ||
| 4045 | ✗ | arrayUpdate(level,r,level[r]+2); | |
| 4046 | ✗ | arrayUpdate(colptrs,r,0); | |
| 4047 | ✗ | then | |
| 4048 | (i+1,false); | ||
| 4049 | case c::_ | ||
| 4050 | algorithm | ||
| 4051 | // collum is unmatched | ||
| 4052 | ✗ | true := intLt(ass1[c],0); | |
| 4053 | ✗ | arrayUpdate(colptrs,r,counter); | |
| 4054 | ✗ | HKDFSreasign(stack,c,ass1,ass2); | |
| 4055 | ✗ | then | |
| 4056 | (i,true); | ||
| 4057 | case c::rest | ||
| 4058 | algorithm | ||
| 4059 | // collum is unvisited | ||
| 4060 | ✗ | true := intEq(level[c],desL); | |
| 4061 | // collum is matched | ||
| 4062 | ✗ | rc := ass1[c]; | |
| 4063 | ✗ | true := intGt(rc,0); | |
| 4064 | ✗ | arrayUpdate(colptrs,r,counter); | |
| 4065 | ✗ | (i_1,b) := ABMPDFSphase(rc::stack,i,rc,nv,ne,m,mT,level,colptrs,ass1,ass2); | |
| 4066 | ✗ | (i_1,b) := ABMPDFStraverseCollums1(b,counter+1,rest,stack,r,i_1,desL,nv,ne,m,mT,level,colptrs,ass1,ass2); | |
| 4067 | then | ||
| 4068 | (i_1,b); | ||
| 4069 | case _::rest | ||
| 4070 | algorithm | ||
| 4071 | ✗ | (i_1,b) := ABMPDFStraverseCollums(rest,counter+1,stack,r,i,desL,nv,ne,m,mT,level,colptrs,ass1,ass2); | |
| 4072 | then | ||
| 4073 | (i_1,b); | ||
| 4074 | else | ||
| 4075 | algorithm | ||
| 4076 | ✗ | Error.addInternalError("function ABMPDFSBtraverseCollums failed", sourceInfo()); | |
| 4077 | ✗ | then | |
| 4078 | fail(); | ||
| 4079 | end matchcontinue; | ||
| 4080 | end ABMPDFStraverseCollums; | ||
| 4081 | |||
| 4082 | protected function ABMPDFStraverseCollums1 | ||
| 4083 | "function helper for ABMPDFSBtraverseCollums | ||
| 4084 | author: Frenkel TUD 2012-03" | ||
| 4085 | input Boolean inMatched; | ||
| 4086 | input Integer counter; | ||
| 4087 | input list<Integer> rows; | ||
| 4088 | input list<Integer> stack; | ||
| 4089 | input Integer r; | ||
| 4090 | input Integer i; | ||
| 4091 | input Integer desL; | ||
| 4092 | input Integer nv; | ||
| 4093 | input Integer ne; | ||
| 4094 | input BackendDAE.AdjacencyMatrix m; | ||
| 4095 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 4096 | input array<Integer> level; | ||
| 4097 | input array<Integer> colptrs; | ||
| 4098 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 4099 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 4100 | output Integer outI; | ||
| 4101 | output Boolean matched; | ||
| 4102 | algorithm | ||
| 4103 | (outI,matched):= | ||
| 4104 | match (inMatched, i) | ||
| 4105 | local | ||
| 4106 | Integer i_1; | ||
| 4107 | Boolean b; | ||
| 4108 | case (true, i_1) | ||
| 4109 | ✗ | then (i_1,true); | |
| 4110 | else | ||
| 4111 | algorithm | ||
| 4112 | ✗ | (i_1,b) := ABMPDFStraverseCollums(rows,counter,stack,r,i,desL,nv,ne,m,mT,level,colptrs,ass1,ass2); | |
| 4113 | then | ||
| 4114 | (i_1,b); | ||
| 4115 | end match; | ||
| 4116 | end ABMPDFStraverseCollums1; | ||
| 4117 | |||
| 4118 | |||
| 4119 | public function PR_FIFO_FAIR | ||
| 4120 | " complexity O(n*tau) | ||
| 4121 | author: Frenkel TUD 2012-04" | ||
| 4122 | input BackendDAE.EqSystem isyst; | ||
| 4123 | input BackendDAE.Shared ishared; | ||
| 4124 | input Boolean clearMatching; | ||
| 4125 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 4126 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 4127 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 4128 | output BackendDAE.EqSystem osyst; | ||
| 4129 | output BackendDAE.Shared oshared; | ||
| 4130 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 4131 | algorithm | ||
| 4132 | (osyst,oshared,outArg) := | ||
| 4133 | matchcontinue isyst | ||
| 4134 | local | ||
| 4135 | Integer nvars,neqns; | ||
| 4136 | BackendDAE.AdjacencyMatrix m; | ||
| 4137 | BackendDAE.AdjacencyMatrixT mt; | ||
| 4138 | array<Integer> vec1,vec2; | ||
| 4139 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 4140 | BackendDAE.EqSystem syst; | ||
| 4141 | BackendDAE.Shared shared; | ||
| 4142 | array<Integer> l_label,r_label; | ||
| 4143 | list<Integer> unmatched; | ||
| 4144 | |||
| 4145 | case BackendDAE.EQSYSTEM(m=SOME(m),mT=SOME(mt)) | ||
| 4146 | algorithm | ||
| 4147 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 4148 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 4149 | ✗ | true := intGt(nvars,0); | |
| 4150 | ✗ | true := intGt(neqns,0); | |
| 4151 | ✗ | (vec1,vec2) := getAssignment(clearMatching,nvars,neqns,isyst); | |
| 4152 | ✗ | l_label := arrayCreate(neqns,-1); | |
| 4153 | ✗ | r_label := arrayCreate(nvars,-1); | |
| 4154 | ✗ | unmatched := cheapmatchingalgorithm(nvars,neqns,m,mt,vec1,vec2,true); | |
| 4155 | ✗ | (vec1,vec2,syst,shared,arg) := PR_FIFO_FAIR1(unmatched,l_label,r_label,isyst,ishared,nvars,neqns,vec1,vec2,inMatchingOptions,sssHandler,inArg); | |
| 4156 | ✗ | syst := BackendDAEUtil.setEqSystMatching(syst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 4157 | ✗ | then | |
| 4158 | (syst,shared,arg); | ||
| 4159 | // fail case if system is empty | ||
| 4160 | case _ | ||
| 4161 | algorithm | ||
| 4162 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 4163 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 4164 | ✗ | false := intGt(nvars,0); | |
| 4165 | ✗ | false := intGt(neqns,0); | |
| 4166 | ✗ | vec1 := listArray({}); | |
| 4167 | ✗ | vec2 := listArray({}); | |
| 4168 | ✗ | syst := BackendDAEUtil.setEqSystMatching(isyst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 4169 | then | ||
| 4170 | (syst,ishared,inArg); | ||
| 4171 | else | ||
| 4172 | algorithm | ||
| 4173 | ✗ | if Flags.isSet(Flags.FAILTRACE) then | |
| 4174 | ✗ | Debug.trace("- Matching.PR_FIFO_FAIR failed\n"); | |
| 4175 | end if; | ||
| 4176 | ✗ | then | |
| 4177 | fail(); | ||
| 4178 | end matchcontinue; | ||
| 4179 | end PR_FIFO_FAIR; | ||
| 4180 | |||
| 4181 | protected function PR_FIFO_FAIR1 | ||
| 4182 | "function: PR_FIFO_FAIR1, helper for PR_FIFO_FAIR | ||
| 4183 | author: Frenkel TUD 2012-03" | ||
| 4184 | input list<Integer> unmatched; | ||
| 4185 | input array<Integer> l_label; | ||
| 4186 | input array<Integer> r_label; | ||
| 4187 | input BackendDAE.EqSystem isyst; | ||
| 4188 | input BackendDAE.Shared ishared; | ||
| 4189 | input Integer nv; | ||
| 4190 | input Integer ne; | ||
| 4191 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 4192 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 4193 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 4194 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 4195 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 4196 | output array<Integer> outAss1; | ||
| 4197 | output array<Integer> outAss2; | ||
| 4198 | output BackendDAE.EqSystem osyst; | ||
| 4199 | output BackendDAE.Shared oshared; | ||
| 4200 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 4201 | algorithm | ||
| 4202 | (outAss1,outAss2,osyst,oshared,outArg):= | ||
| 4203 | matchcontinue (unmatched, isyst, inArg) | ||
| 4204 | local | ||
| 4205 | BackendDAE.AdjacencyMatrix m,mt; | ||
| 4206 | Integer nv_1,ne_1; | ||
| 4207 | list<Integer> unmatched1; | ||
| 4208 | list<list<Integer>> meqns; | ||
| 4209 | String eqn_str,var_str; | ||
| 4210 | BackendDAE.StructurallySingularSystemHandlerArg arg,arg1; | ||
| 4211 | DAE.ElementSource source; | ||
| 4212 | SourceInfo info; | ||
| 4213 | BackendDAE.EqSystem syst; | ||
| 4214 | BackendDAE.Shared shared; | ||
| 4215 | array<Integer> ass1_1,ass1_2,ass2_1,ass2_2,l_label1,r_label1; | ||
| 4216 | array<Integer> mapIncRowEqn; | ||
| 4217 | case ({}, _, _) | ||
| 4218 | ✗ | then | |
| 4219 | (ass1,ass2,isyst,ishared,inArg); | ||
| 4220 | case (_, syst as BackendDAE.EQSYSTEM(m=SOME(m),mT=SOME(mt)), _) | ||
| 4221 | algorithm | ||
| 4222 | ✗ | PR_Global_Relabel(l_label,r_label,nv,ne,m,mt,ass1,ass2); | |
| 4223 | ✗ | PR_FIFO_FAIRphase(0,unmatched,nv+ne,-1,nv,ne,m,mt,l_label,r_label,ass1,ass2,{}); | |
| 4224 | ✗ | unmatched1 := getUnassigned(ne, ass1, {}); | |
| 4225 | ✗ | meqns := getEqnsforIndexReduction(unmatched1,ne,m,mt,ass1,ass2,inArg); | |
| 4226 | ✗ | (unmatched1,l_label1,r_label1,nv_1,ne_1,ass1_1,ass2_1,syst,shared,arg) := PR_FIFO_FAIR2(meqns,unmatched1,{},l_label,r_label,syst,ishared,nv,ne,ass1,ass2,inMatchingOptions,sssHandler,inArg); | |
| 4227 | ✗ | (ass1_2,ass2_2,syst,shared,arg1) := PR_FIFO_FAIR1(unmatched1,l_label1,r_label1,syst,shared,nv_1,ne_1,ass1_1,ass2_1,inMatchingOptions,sssHandler,arg); | |
| 4228 | then | ||
| 4229 | (ass1_2,ass2_2,syst,shared,arg1); | ||
| 4230 | case (_, _, (_,_,_,mapIncRowEqn,_)) | ||
| 4231 | algorithm | ||
| 4232 | // get from scalar eqns indexes the indexes in the equation array | ||
| 4233 | ✗ | unmatched1 := List.map1r(unmatched,arrayGet,mapIncRowEqn); | |
| 4234 | ✗ | unmatched1 := List.uniqueIntN(unmatched1,arrayLength(mapIncRowEqn)); | |
| 4235 | ✗ | eqn_str := BackendDump.dumpMarkedEqns(isyst, unmatched1); | |
| 4236 | ✗ | unmatched1 := getUnassigned(nv, ass2, {}); | |
| 4237 | ✗ | var_str := BackendDump.dumpMarkedVars(isyst, unmatched1); | |
| 4238 | ✗ | source := BackendEquation.markedEquationSource(isyst, listHead(unmatched1)); | |
| 4239 | ✗ | info := ElementSource.getElementSourceFileInfo(source); | |
| 4240 | ✗ | Error.addSourceMessage(Error.STRUCT_SINGULAR_SYSTEM, {eqn_str,var_str}, info); | |
| 4241 | ✗ | then | |
| 4242 | fail(); | ||
| 4243 | end matchcontinue; | ||
| 4244 | end PR_FIFO_FAIR1; | ||
| 4245 | |||
| 4246 | protected function PR_FIFO_FAIR2 | ||
| 4247 | "function: PR_FIFO_FAIR2, helper for PR_FIFO_FAIR | ||
| 4248 | author: Frenkel TUD 2012-03" | ||
| 4249 | input list<list<Integer>> meqns "Marked Equations for Index Reduction"; | ||
| 4250 | input list<Integer> unmatched; | ||
| 4251 | input list<Integer> changedEqns; | ||
| 4252 | input array<Integer> l_label; | ||
| 4253 | input array<Integer> r_label; | ||
| 4254 | input BackendDAE.EqSystem isyst; | ||
| 4255 | input BackendDAE.Shared ishared; | ||
| 4256 | input Integer nv; | ||
| 4257 | input Integer ne; | ||
| 4258 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 4259 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 4260 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 4261 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 4262 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 4263 | output list<Integer> outunmatched; | ||
| 4264 | output array<Integer> outl_label; | ||
| 4265 | output array<Integer> outr_label; | ||
| 4266 | output Integer nvars; | ||
| 4267 | output Integer neqns; | ||
| 4268 | output array<Integer> outAss1; | ||
| 4269 | output array<Integer> outAss2; | ||
| 4270 | output BackendDAE.EqSystem osyst; | ||
| 4271 | output BackendDAE.Shared oshared; | ||
| 4272 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 4273 | algorithm | ||
| 4274 | (outunmatched,outl_label,outr_label,nvars,neqns,outAss1,outAss2,osyst,oshared,outArg):= | ||
| 4275 | match (meqns, inMatchingOptions) | ||
| 4276 | local | ||
| 4277 | Integer nv_1,ne_1; | ||
| 4278 | list<Integer> unmatched1; | ||
| 4279 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 4280 | BackendDAE.EqSystem syst; | ||
| 4281 | BackendDAE.Shared shared; | ||
| 4282 | array<Integer> ass1_1,ass2_1,l_label1,r_label1; | ||
| 4283 | |||
| 4284 | case ({}, _) | ||
| 4285 | then | ||
| 4286 | (unmatched,l_label,r_label,nv,ne,ass1,ass2,isyst,ishared,inArg); | ||
| 4287 | case (_, (BackendDAE.INDEX_REDUCTION(),_)) | ||
| 4288 | algorithm | ||
| 4289 | ✗ | (unmatched1,_,syst,shared,ass2_1,ass1_1,arg) := sssHandler(meqns,0,isyst,ishared,ass2,ass1,inArg); | |
| 4290 | ✗ | ne_1 := BackendDAEUtil.systemSize(syst); | |
| 4291 | ✗ | nv_1 := BackendVariable.daenumVariables(syst); | |
| 4292 | ✗ | ass1_1 := assignmentsArrayExpand(ass1_1,ne_1,arrayLength(ass1_1),-1); | |
| 4293 | ✗ | ass2_1 := assignmentsArrayExpand(ass2_1,nv_1,arrayLength(ass2_1),-1); | |
| 4294 | ✗ | l_label1 := assignmentsArrayExpand(l_label,ne_1,arrayLength(l_label),-1); | |
| 4295 | ✗ | r_label1 := assignmentsArrayExpand(r_label,nv_1,arrayLength(r_label),-1); | |
| 4296 | ✗ | then | |
| 4297 | (unmatched1,l_label1,r_label1,nv_1,ne_1,ass1_1,ass2_1,syst,shared,arg); | ||
| 4298 | case (_, _) | ||
| 4299 | algorithm | ||
| 4300 | ✗ | singularSystemError(meqns,0,isyst,ishared,ass1,ass2,inArg); | |
| 4301 | ✗ | then | |
| 4302 | fail(); | ||
| 4303 | end match; | ||
| 4304 | end PR_FIFO_FAIR2; | ||
| 4305 | |||
| 4306 | protected function PR_Global_Relabel | ||
| 4307 | "function PR_Global_Relabel, helper for PR_FIFO_FAIR, | ||
| 4308 | update the labels of eatch vertex | ||
| 4309 | author: Frenkel TUD 2012-04" | ||
| 4310 | input array<Integer> l_label; | ||
| 4311 | input array<Integer> r_label; | ||
| 4312 | input Integer nv; | ||
| 4313 | input Integer ne; | ||
| 4314 | input BackendDAE.AdjacencyMatrix m; | ||
| 4315 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 4316 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 4317 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 4318 | protected | ||
| 4319 | list<Integer> queue; | ||
| 4320 | Integer max; | ||
| 4321 | algorithm | ||
| 4322 | ✗ | max := nv+ne; | |
| 4323 | ✗ | PR_Global_Relabel_init_l_label(1,ne,max,l_label); | |
| 4324 | ✗ | queue := PR_Global_Relabel_init_r_label(1,nv,max,r_label,ass2,{}); | |
| 4325 | ✗ | PR_Global_Relabel1(queue,l_label,r_label,max,nv,ne,m,mT,ass1,ass2,{}); | |
| 4326 | end PR_Global_Relabel; | ||
| 4327 | |||
| 4328 | protected function PR_Global_Relabel_init_l_label | ||
| 4329 | "function PR_Global_Relabel_init_l_label, helper for PR_Global_Relabel | ||
| 4330 | author: Frenkel TUD 2012-04" | ||
| 4331 | input Integer i; | ||
| 4332 | input Integer ne; | ||
| 4333 | input Integer max; | ||
| 4334 | input array<Integer> l_label; | ||
| 4335 | algorithm | ||
| 4336 | ✗ | if not intGt(i,ne) then | |
| 4337 | ✗ | arrayUpdate(l_label,i,max); | |
| 4338 | ✗ | PR_Global_Relabel_init_l_label(i+1,ne,max,l_label); | |
| 4339 | end if; | ||
| 4340 | end PR_Global_Relabel_init_l_label; | ||
| 4341 | |||
| 4342 | protected function PR_Global_Relabel_init_r_label | ||
| 4343 | "function PR_Global_Relabel_init_r_label, helper for PR_Global_Relabel | ||
| 4344 | author: Frenkel TUD 2012-04" | ||
| 4345 | input Integer i; | ||
| 4346 | input Integer nv; | ||
| 4347 | input Integer max; | ||
| 4348 | input array<Integer> r_label; | ||
| 4349 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 4350 | input list<Integer> inQueue; | ||
| 4351 | output list<Integer> outQueue; | ||
| 4352 | algorithm | ||
| 4353 | outQueue := matchcontinue inQueue | ||
| 4354 | case _ | ||
| 4355 | algorithm | ||
| 4356 | ✗ | true := intGt(i,nv); | |
| 4357 | ✗ | then | |
| 4358 | listReverse(inQueue); | ||
| 4359 | case _ | ||
| 4360 | algorithm | ||
| 4361 | ✗ | false := intGt(i,nv); | |
| 4362 | ✗ | false := intGt(ass2[i],0); | |
| 4363 | ✗ | arrayUpdate(r_label,i,0); | |
| 4364 | ✗ | then | |
| 4365 | PR_Global_Relabel_init_r_label(i+1,nv,max,r_label,ass2,i::inQueue); | ||
| 4366 | else | ||
| 4367 | algorithm | ||
| 4368 | ✗ | arrayUpdate(r_label,i,max); | |
| 4369 | ✗ | then | |
| 4370 | PR_Global_Relabel_init_r_label(i+1,nv,max,r_label,ass2,inQueue); | ||
| 4371 | end matchcontinue; | ||
| 4372 | end PR_Global_Relabel_init_r_label; | ||
| 4373 | |||
| 4374 | protected function PR_Global_Relabel1 | ||
| 4375 | "function PR_Global_Relabel, helper for PR_FIFO_FAIR, | ||
| 4376 | update the labels of eatch vertex | ||
| 4377 | author: Frenkel TUD 2012-04" | ||
| 4378 | input list<Integer> queue; | ||
| 4379 | input array<Integer> l_label; | ||
| 4380 | input array<Integer> r_label; | ||
| 4381 | input Integer max; | ||
| 4382 | input Integer nv; | ||
| 4383 | input Integer ne; | ||
| 4384 | input BackendDAE.AdjacencyMatrix m; | ||
| 4385 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 4386 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 4387 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 4388 | input list<Integer> nextqueue; | ||
| 4389 | algorithm | ||
| 4390 | () := matchcontinue(queue, nextqueue) | ||
| 4391 | local | ||
| 4392 | list<Integer> rest,collums,queue1; | ||
| 4393 | Integer r; | ||
| 4394 | case({}, {}) then (); | ||
| 4395 | case({}, _) | ||
| 4396 | algorithm | ||
| 4397 | ✗ | PR_Global_Relabel1(listReverse(nextqueue),l_label,r_label,max,nv,ne,m,mT,ass1,ass2,{}); | |
| 4398 | then | ||
| 4399 | (); | ||
| 4400 | case(r::rest, _) | ||
| 4401 | algorithm | ||
| 4402 | ✗ | collums := List.select(mT[r], Util.intPositive); | |
| 4403 | ✗ | queue1 := PR_Global_Relabel_traverseCollums(collums,max,r,l_label,r_label,nv,ne,m,mT,ass1,ass2,nextqueue); | |
| 4404 | ✗ | PR_Global_Relabel1(rest,l_label,r_label,max,nv,ne,m,mT,ass1,ass2,queue1); | |
| 4405 | then | ||
| 4406 | (); | ||
| 4407 | end matchcontinue; | ||
| 4408 | end PR_Global_Relabel1; | ||
| 4409 | |||
| 4410 | protected function PR_Global_Relabel_traverseCollums | ||
| 4411 | "function helper for PR_Global_Relabel1, traverses all collums of a row and asing label indexes | ||
| 4412 | author: Frenkel TUD 2012-04" | ||
| 4413 | input list<Integer> collums; | ||
| 4414 | input Integer max; | ||
| 4415 | input Integer r; | ||
| 4416 | input array<Integer> l_label; | ||
| 4417 | input array<Integer> r_label; | ||
| 4418 | input Integer nv; | ||
| 4419 | input Integer ne; | ||
| 4420 | input BackendDAE.AdjacencyMatrix m; | ||
| 4421 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 4422 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 4423 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 4424 | input list<Integer> nextqueue; | ||
| 4425 | output list<Integer> outQueue; | ||
| 4426 | algorithm | ||
| 4427 | outQueue:= | ||
| 4428 | matchcontinue collums | ||
| 4429 | local | ||
| 4430 | list<Integer> rest; | ||
| 4431 | Integer rc,c; | ||
| 4432 | case {} then nextqueue; | ||
| 4433 | case c::rest | ||
| 4434 | algorithm | ||
| 4435 | ✗ | true := intEq(l_label[c],max); | |
| 4436 | ✗ | arrayUpdate(l_label,c,r_label[r]+1); | |
| 4437 | ✗ | rc := ass1[c]; | |
| 4438 | ✗ | true := intGt(rc,-1); | |
| 4439 | ✗ | true := intEq(r_label[rc] ,max); | |
| 4440 | ✗ | arrayUpdate(r_label,rc,l_label[c]+1); | |
| 4441 | ✗ | then | |
| 4442 | PR_Global_Relabel_traverseCollums(rest,max,r,l_label,r_label,nv,ne,m,mT,ass1,ass2,rc::nextqueue); | ||
| 4443 | case _::rest | ||
| 4444 | ✗ | then | |
| 4445 | PR_Global_Relabel_traverseCollums(rest,max,r,l_label,r_label,nv,ne,m,mT,ass1,ass2,nextqueue); | ||
| 4446 | else | ||
| 4447 | algorithm | ||
| 4448 | ✗ | Error.addInternalError("function PR_Global_Relabel_traverseCollums failed", sourceInfo()); | |
| 4449 | ✗ | then | |
| 4450 | fail(); | ||
| 4451 | end matchcontinue; | ||
| 4452 | end PR_Global_Relabel_traverseCollums; | ||
| 4453 | |||
| 4454 | |||
| 4455 | protected function PR_FIFO_FAIRphase | ||
| 4456 | "function PR_FIFO_FAIRphase, match rows and collums with push relabel tecnic | ||
| 4457 | author: Frenkel TUD 2012-04" | ||
| 4458 | input Integer relabels; | ||
| 4459 | input list<Integer> U; | ||
| 4460 | input Integer max; | ||
| 4461 | input Integer min_vertex; | ||
| 4462 | input Integer nv; | ||
| 4463 | input Integer ne; | ||
| 4464 | input BackendDAE.AdjacencyMatrix m; | ||
| 4465 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 4466 | input array<Integer> l_label; | ||
| 4467 | input array<Integer> r_label; | ||
| 4468 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 4469 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 4470 | input list<Integer> nextqueue; | ||
| 4471 | algorithm | ||
| 4472 | () := matchcontinue(U, nextqueue) | ||
| 4473 | local | ||
| 4474 | list<Integer> rest,queue; | ||
| 4475 | Integer c,min_label,rlcount,minvertex; | ||
| 4476 | case({}, {}) then (); | ||
| 4477 | case({}, _) | ||
| 4478 | algorithm | ||
| 4479 | ✗ | PR_FIFO_FAIRphase(relabels,nextqueue,max,min_vertex,nv,ne,m,mT,l_label,r_label,ass1,ass2,{}); | |
| 4480 | then (); | ||
| 4481 | case(_, _) | ||
| 4482 | algorithm | ||
| 4483 | ✗ | true := intEq(relabels,max); | |
| 4484 | ✗ | PR_Global_Relabel(l_label,r_label,nv,ne,m,mT,ass1,ass2); | |
| 4485 | ✗ | PR_FIFO_FAIRphase(0,U,max,min_vertex,nv,ne,m,mT,l_label,r_label,ass1,ass2,nextqueue); | |
| 4486 | then (); | ||
| 4487 | case(c::rest, _) | ||
| 4488 | algorithm | ||
| 4489 | ✗ | (rlcount,min_label,minvertex) := PR_FIFO_FAIRphase1(intLt(l_label[c],max),relabels+1,c,min_vertex,max,max,nv,ne,m,mT,l_label,r_label,ass1,ass2); | |
| 4490 | ✗ | queue := PR_FIFO_FAIRrelabel(c,minvertex,min_label,max,nv,ne,m,mT,l_label,r_label,ass1,ass2,nextqueue); | |
| 4491 | ✗ | PR_FIFO_FAIRphase(rlcount,rest,max,minvertex,nv,ne,m,mT,l_label,r_label,ass1,ass2,queue); | |
| 4492 | then (); | ||
| 4493 | end matchcontinue; | ||
| 4494 | end PR_FIFO_FAIRphase; | ||
| 4495 | |||
| 4496 | protected function PR_FIFO_FAIRphase1 | ||
| 4497 | "function helper for PR_FIFO_FAIRphase | ||
| 4498 | author: Frenkel TUD 2012-04" | ||
| 4499 | input Boolean b; | ||
| 4500 | input Integer relabels; | ||
| 4501 | input Integer max_vertex; | ||
| 4502 | input Integer min_vertec; | ||
| 4503 | input Integer min_label; | ||
| 4504 | input Integer max; | ||
| 4505 | input Integer nv; | ||
| 4506 | input Integer ne; | ||
| 4507 | input BackendDAE.AdjacencyMatrix m; | ||
| 4508 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 4509 | input array<Integer> l_label; | ||
| 4510 | input array<Integer> r_label; | ||
| 4511 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 4512 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 4513 | output Integer outRelabels; | ||
| 4514 | output Integer outMinLabels; | ||
| 4515 | output Integer outMinVertex; | ||
| 4516 | algorithm | ||
| 4517 | (outRelabels,outMinLabels,outMinVertex) := | ||
| 4518 | match b | ||
| 4519 | local | ||
| 4520 | Integer rel,minlab,minvert,tmp; | ||
| 4521 | case true | ||
| 4522 | algorithm | ||
| 4523 | ✗ | tmp := intMod(l_label[max_vertex],4); | |
| 4524 | ✗ | (rel,minlab,minvert) := PR_FIFO_FAIRphase2(intEq(tmp,1),relabels,max_vertex,min_vertec,min_label,max,nv,ne,m,mT,l_label,r_label,ass1,ass2); | |
| 4525 | then | ||
| 4526 | (rel,minlab,minvert); | ||
| 4527 | else | ||
| 4528 | ✗ | then | |
| 4529 | (relabels,min_label,min_vertec); | ||
| 4530 | end match; | ||
| 4531 | end PR_FIFO_FAIRphase1; | ||
| 4532 | |||
| 4533 | protected function PR_FIFO_FAIRphase2 | ||
| 4534 | "function helper for PR_FIFO_FAIRphase | ||
| 4535 | author: Frenkel TUD 2012-04" | ||
| 4536 | input Boolean b; | ||
| 4537 | input Integer relabels; | ||
| 4538 | input Integer max_vertex; | ||
| 4539 | input Integer min_vertec; | ||
| 4540 | input Integer min_label; | ||
| 4541 | input Integer max; | ||
| 4542 | input Integer nv; | ||
| 4543 | input Integer ne; | ||
| 4544 | input BackendDAE.AdjacencyMatrix m; | ||
| 4545 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 4546 | input array<Integer> l_label; | ||
| 4547 | input array<Integer> r_label; | ||
| 4548 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 4549 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 4550 | output Integer outRelabels; | ||
| 4551 | output Integer outMinLabels; | ||
| 4552 | output Integer outMinVertex; | ||
| 4553 | algorithm | ||
| 4554 | (outRelabels,outMinLabels,outMinVertex) := | ||
| 4555 | match b | ||
| 4556 | local | ||
| 4557 | list<Integer> rows; | ||
| 4558 | Integer rel,minlab,minvert; | ||
| 4559 | case true | ||
| 4560 | algorithm | ||
| 4561 | ✗ | rows := List.select(m[max_vertex], Util.intPositive); | |
| 4562 | ✗ | (rel,minlab,minvert) := PR_FIFO_FAIRphase_traverseRows(rows,relabels,max_vertex,min_vertec,min_label,max,nv,ne,m,mT,l_label,r_label,ass1,ass2); | |
| 4563 | then | ||
| 4564 | (rel,minlab,minvert); | ||
| 4565 | else | ||
| 4566 | algorithm | ||
| 4567 | ✗ | rows := List.select(m[max_vertex], Util.intPositive); | |
| 4568 | ✗ | rows := listReverse(rows); | |
| 4569 | ✗ | (rel,minlab,minvert) := PR_FIFO_FAIRphase_traverseRows(rows,relabels,max_vertex,min_vertec,min_label,max,nv,ne,m,mT,l_label,r_label,ass1,ass2); | |
| 4570 | then | ||
| 4571 | (rel,minlab,minvert); | ||
| 4572 | end match; | ||
| 4573 | end PR_FIFO_FAIRphase2; | ||
| 4574 | |||
| 4575 | protected function PR_FIFO_FAIRphase_traverseRows | ||
| 4576 | "function helper for PR_FIFO_FAIRphase2 | ||
| 4577 | author: Frenkel TUD 2012-04" | ||
| 4578 | input list<Integer> rows; | ||
| 4579 | input Integer relabels; | ||
| 4580 | input Integer max_vertex; | ||
| 4581 | input Integer min_vertex; | ||
| 4582 | input Integer min_label; | ||
| 4583 | input Integer max; | ||
| 4584 | input Integer nv; | ||
| 4585 | input Integer ne; | ||
| 4586 | input BackendDAE.AdjacencyMatrix m; | ||
| 4587 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 4588 | input array<Integer> l_label; | ||
| 4589 | input array<Integer> r_label; | ||
| 4590 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 4591 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 4592 | output Integer outRelabels; | ||
| 4593 | output Integer outMinLabels; | ||
| 4594 | output Integer outMinVertex; | ||
| 4595 | algorithm | ||
| 4596 | (outRelabels,outMinLabels,outMinVertex) := | ||
| 4597 | matchcontinue rows | ||
| 4598 | local | ||
| 4599 | list<Integer> rest; | ||
| 4600 | Integer r,minlabel,minvertex,rel; | ||
| 4601 | ✗ | case {} then (relabels,min_label,min_vertex); | |
| 4602 | case r::_ | ||
| 4603 | algorithm | ||
| 4604 | ✗ | true := intLt(r_label[r],min_label); | |
| 4605 | minlabel := r_label[r]; | ||
| 4606 | minvertex := r; | ||
| 4607 | ✗ | true := intEq(r_label[minvertex],l_label[max_vertex]-1); | |
| 4608 | ✗ | then | |
| 4609 | (relabels-1,minlabel,minvertex); | ||
| 4610 | case r::rest | ||
| 4611 | algorithm | ||
| 4612 | ✗ | true := intLt(r_label[r],min_label); | |
| 4613 | minlabel := r_label[r]; | ||
| 4614 | minvertex := r; | ||
| 4615 | ✗ | false := intEq(r_label[minvertex],l_label[max_vertex]-1); | |
| 4616 | ✗ | (rel,minlabel,minvertex) := PR_FIFO_FAIRphase_traverseRows(rest,relabels,max_vertex,minvertex,minlabel,max,nv,ne,m,mT,l_label,r_label,ass1,ass2); | |
| 4617 | then | ||
| 4618 | (rel,minlabel,minvertex); | ||
| 4619 | case _::rest | ||
| 4620 | algorithm | ||
| 4621 | ✗ | (rel,minlabel,minvertex) := PR_FIFO_FAIRphase_traverseRows(rest,relabels,max_vertex,min_vertex,min_label,max,nv,ne,m,mT,l_label,r_label,ass1,ass2); | |
| 4622 | then | ||
| 4623 | (rel,minlabel,minvertex); | ||
| 4624 | else | ||
| 4625 | algorithm | ||
| 4626 | ✗ | Error.addInternalError("function PR_FIFO_FAIRphase_traverseRows failed", sourceInfo()); | |
| 4627 | ✗ | then | |
| 4628 | fail(); | ||
| 4629 | end matchcontinue; | ||
| 4630 | end PR_FIFO_FAIRphase_traverseRows; | ||
| 4631 | |||
| 4632 | protected function PR_FIFO_FAIRrelabel | ||
| 4633 | "function helper for PR_FIFO_FAIRphase | ||
| 4634 | author: Frenkel TUD 2012-04" | ||
| 4635 | input Integer max_vertex; | ||
| 4636 | input Integer min_vertex; | ||
| 4637 | input Integer min_label; | ||
| 4638 | input Integer max; | ||
| 4639 | input Integer nv; | ||
| 4640 | input Integer ne; | ||
| 4641 | input BackendDAE.AdjacencyMatrix m; | ||
| 4642 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 4643 | input array<Integer> l_label; | ||
| 4644 | input array<Integer> r_label; | ||
| 4645 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 4646 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 4647 | input list<Integer> inQueue; | ||
| 4648 | output list<Integer> outQueue; | ||
| 4649 | algorithm | ||
| 4650 | outQueue := matchcontinue inQueue | ||
| 4651 | local | ||
| 4652 | Integer next_vertex; | ||
| 4653 | case _ | ||
| 4654 | algorithm | ||
| 4655 | ✗ | true := intLt(min_label,max); | |
| 4656 | ✗ | true := intLt(ass2[min_vertex],0); | |
| 4657 | ✗ | arrayUpdate(ass2,min_vertex,max_vertex); | |
| 4658 | ✗ | arrayUpdate(ass1,max_vertex,min_vertex); | |
| 4659 | ✗ | arrayUpdate(r_label,min_vertex,min_label+2); | |
| 4660 | then | ||
| 4661 | inQueue; | ||
| 4662 | case _ | ||
| 4663 | algorithm | ||
| 4664 | ✗ | true := intLt(min_label,max); | |
| 4665 | ✗ | false := intLt(ass2[min_vertex],0); | |
| 4666 | next_vertex := ass2[min_vertex]; | ||
| 4667 | ✗ | arrayUpdate(ass2,min_vertex,max_vertex); | |
| 4668 | ✗ | arrayUpdate(ass1,max_vertex,min_vertex); | |
| 4669 | ✗ | arrayUpdate(ass1,next_vertex,-1); | |
| 4670 | ✗ | arrayUpdate(l_label,max_vertex,min_label+1); | |
| 4671 | ✗ | arrayUpdate(r_label,min_vertex,min_label+2); | |
| 4672 | then | ||
| 4673 | next_vertex::inQueue; | ||
| 4674 | else | ||
| 4675 | then | ||
| 4676 | inQueue; | ||
| 4677 | end matchcontinue; | ||
| 4678 | end PR_FIFO_FAIRrelabel; | ||
| 4679 | |||
| 4680 | |||
| 4681 | // ============================================================================= | ||
| 4682 | // cheap matching implementations | ||
| 4683 | // | ||
| 4684 | // ============================================================================= | ||
| 4685 | |||
| 4686 | protected function cheapmatchingalgorithm | ||
| 4687 | "function cheapmatchingalgorithm, traverses all colums and look for a cheap matching, a unmatch row | ||
| 4688 | author: Frenkel TUD 2012-07" | ||
| 4689 | input Integer nv; | ||
| 4690 | input Integer ne; | ||
| 4691 | input BackendDAE.AdjacencyMatrix m "m[eqnindx] = list(varindx)"; | ||
| 4692 | input BackendDAE.AdjacencyMatrixT mT "mT[varindx] = list(eqnindx)"; | ||
| 4693 | input array<Integer> ass1 "ass[eqnindx]=varindx"; | ||
| 4694 | input array<Integer> ass2 "ass[varindx]=eqnindx"; | ||
| 4695 | input Boolean intRangeUsed; | ||
| 4696 | output list<Integer> outUnMatched; | ||
| 4697 | algorithm | ||
| 4698 | 646 | outUnMatched := cheapmatchingalgorithm1(Config.getCheapMatchingAlgorithm(),nv,ne,m,mT,ass1,ass2,intRangeUsed); | |
| 4699 | end cheapmatchingalgorithm; | ||
| 4700 | |||
| 4701 | protected function cheapmatchingalgorithm1 | ||
| 4702 | " author: Frenkel TUD 2012-07" | ||
| 4703 | input Integer algorithmid; | ||
| 4704 | input Integer nv; | ||
| 4705 | input Integer ne; | ||
| 4706 | input BackendDAE.AdjacencyMatrix m "m[eqnindx] = list(varindx)"; | ||
| 4707 | input BackendDAE.AdjacencyMatrixT mT "mT[varindx] = list(eqnindx)"; | ||
| 4708 | input array<Integer> ass1 "ass[eqnindx]=varindx"; | ||
| 4709 | input array<Integer> ass2 "ass[varindx]=eqnindx"; | ||
| 4710 | input Boolean intRangeUsed; | ||
| 4711 | output list<Integer> outUnMatched; | ||
| 4712 | algorithm | ||
| 4713 | outUnMatched := match(algorithmid, intRangeUsed) | ||
| 4714 | ✗ | case(1, _) then cheapmatching(1,nv,ne,m,mT,ass1,ass2,{}); | |
| 4715 | 646 | case(3, _) then ks_rand_cheapmatching(nv,ne,m,mT,ass1,ass2); | |
| 4716 | ✗ | case(_, true) then getUnassigned(ne, ass1, {}); | |
| 4717 | else {}; | ||
| 4718 | end match; | ||
| 4719 | end cheapmatchingalgorithm1; | ||
| 4720 | |||
| 4721 | protected function cheapmatching | ||
| 4722 | "function cheapmatching, traverses all colums and look for a cheap matching, a unmatch row | ||
| 4723 | author: Frenkel TUD 2012-03" | ||
| 4724 | input Integer i; | ||
| 4725 | input Integer nv; | ||
| 4726 | input Integer ne; | ||
| 4727 | input BackendDAE.AdjacencyMatrix m "m[eqnindx] = list(varindx)"; | ||
| 4728 | input BackendDAE.AdjacencyMatrixT mT "mT[varindx] = list(eqnindx)"; | ||
| 4729 | input array<Integer> ass1 "ass[eqnindx]=varindx"; | ||
| 4730 | input array<Integer> ass2 "ass[varindx]=eqnindx"; | ||
| 4731 | input list<Integer> inUnMatched; | ||
| 4732 | output list<Integer> outUnMatched; | ||
| 4733 | algorithm | ||
| 4734 | outUnMatched:= | ||
| 4735 | matchcontinue inUnMatched | ||
| 4736 | local | ||
| 4737 | list<Integer> rows; | ||
| 4738 | case _ | ||
| 4739 | algorithm | ||
| 4740 | ✗ | true:=intGt(i,ne); | |
| 4741 | then | ||
| 4742 | inUnMatched; | ||
| 4743 | case _ | ||
| 4744 | algorithm | ||
| 4745 | // search cheap matching | ||
| 4746 | ✗ | rows := List.select(m[i], Util.intPositive); | |
| 4747 | ✗ | cheapmatching1(rows,i,ass1,ass2); | |
| 4748 | ✗ | then | |
| 4749 | cheapmatching(i+1,nv,ne,m,mT,ass1,ass2,inUnMatched); | ||
| 4750 | case _ | ||
| 4751 | // unmatched add to list | ||
| 4752 | ✗ | then | |
| 4753 | cheapmatching(i+1,nv,ne,m,mT,ass1,ass2,i::inUnMatched); | ||
| 4754 | else | ||
| 4755 | algorithm | ||
| 4756 | ✗ | Error.addInternalError("function cheapmatching failed in equation " + intString(i), sourceInfo()); | |
| 4757 | ✗ | then | |
| 4758 | fail(); | ||
| 4759 | end matchcontinue; | ||
| 4760 | end cheapmatching; | ||
| 4761 | |||
| 4762 | protected function cheapmatching1 | ||
| 4763 | "function helper for cheapmatching, traverses all rows, fails if no unmatched is found | ||
| 4764 | author: Frenkel TUD 2012-03" | ||
| 4765 | input list<Integer> rows; | ||
| 4766 | input Integer c; | ||
| 4767 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 4768 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 4769 | algorithm | ||
| 4770 | ():= | ||
| 4771 | matchcontinue rows | ||
| 4772 | local | ||
| 4773 | list<Integer> rest; | ||
| 4774 | Integer r; | ||
| 4775 | case r::_ | ||
| 4776 | algorithm | ||
| 4777 | // row is unmatched -> return | ||
| 4778 | ✗ | true := intLt(ass2[r],0); | |
| 4779 | ✗ | arrayUpdate(ass1,c,r); | |
| 4780 | ✗ | arrayUpdate(ass2,r,c); | |
| 4781 | then | ||
| 4782 | (); | ||
| 4783 | case _::rest | ||
| 4784 | algorithm | ||
| 4785 | ✗ | cheapmatching1(rest,c,ass1,ass2); | |
| 4786 | then | ||
| 4787 | (); | ||
| 4788 | end matchcontinue; | ||
| 4789 | end cheapmatching1; | ||
| 4790 | |||
| 4791 | protected function ks_rand_cheapmatching | ||
| 4792 | "function ks_rand_cheapmatching, Random Karp-Sipser | ||
| 4793 | author: Frenkel TUD 2012-04" | ||
| 4794 | input Integer nv; | ||
| 4795 | input Integer ne; | ||
| 4796 | input BackendDAE.AdjacencyMatrix m "m[eqnindx] = list(varindx)"; | ||
| 4797 | input BackendDAE.AdjacencyMatrixT mT "mT[varindx] = list(eqnindx)"; | ||
| 4798 | input array<Integer> ass1 "ass[eqnindx]=varindx"; | ||
| 4799 | input array<Integer> ass2 "ass[varindx]=eqnindx"; | ||
| 4800 | output list<Integer> outUnMatched; | ||
| 4801 | protected | ||
| 4802 | list<Integer> onecolums, onerows; | ||
| 4803 | array<Integer> col_degrees, row_degrees,randarr; | ||
| 4804 | algorithm | ||
| 4805 | 646 | col_degrees := arrayCreate(ne,0); | |
| 4806 | 646 | row_degrees := arrayCreate(ne,0); | |
| 4807 | 646 | onerows := getOneRows(ne,mT,row_degrees,{}); | |
| 4808 | 646 | onecolums := getOneRows(nv,m,col_degrees,{}); | |
| 4809 | 646 | randarr := Array.createIntRange(ne); | |
| 4810 | 646 | setrandArray(ne,randarr); | |
| 4811 | 646 | ks_rand_cheapmatching1(1,ne,onecolums,onerows,col_degrees,row_degrees,randarr,m,mT,ass1,ass2); | |
| 4812 | 646 | outUnMatched := getUnassigned(ne,ass1,{}); | |
| 4813 | end ks_rand_cheapmatching; | ||
| 4814 | |||
| 4815 | protected function ks_rand_cheapmatching1 | ||
| 4816 | "function ks_rand_cheapmatching1, helper for ks_rand_cheapmatching. | ||
| 4817 | author: Frenkel TUD 2012-04" | ||
| 4818 | input Integer i; | ||
| 4819 | input Integer ne; | ||
| 4820 | input list<Integer> onecolums; | ||
| 4821 | input list<Integer> onerows; | ||
| 4822 | input array<Integer> col_degrees; | ||
| 4823 | input array<Integer> row_degrees; | ||
| 4824 | input array<Integer> randarr; | ||
| 4825 | input BackendDAE.AdjacencyMatrix m; | ||
| 4826 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 4827 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 4828 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 4829 | protected | ||
| 4830 | list<Integer> onecolums1,onerows1; | ||
| 4831 | Integer c; | ||
| 4832 | Boolean b; | ||
| 4833 | algorithm | ||
| 4834 |
2/2✓ Branch 0 taken 2970 times.
✓ Branch 1 taken 646 times.
|
3616 | if intLe(i,ne) then |
| 4835 | 2970 | ks_rand_match(onerows,onecolums,row_degrees,col_degrees,mT,m,ass2,ass1); | |
| 4836 | 2970 | c := randarr[i]; | |
| 4837 |
4/4✓ Branch 1 taken 80 times.
✓ Branch 2 taken 2890 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 74 times.
|
2970 | b := intLt(ass1[c],0) and intGt(col_degrees[c],0); |
| 4838 | 2970 | (onecolums1,onerows1) := ks_rand_cheapmatching2(b,c,col_degrees,row_degrees,randarr,m,mT,ass1,ass2); | |
| 4839 | 2970 | ks_rand_cheapmatching1(i+1,ne,onecolums1,onerows1,col_degrees,row_degrees,randarr,m,mT,ass1,ass2); | |
| 4840 | end if; | ||
| 4841 | end ks_rand_cheapmatching1; | ||
| 4842 | |||
| 4843 | protected function ks_rand_cheapmatching2 | ||
| 4844 | "function ks_rand_cheapmatching2, helper for ks_rand_cheapmatching. | ||
| 4845 | author: Frenkel TUD 2012-04" | ||
| 4846 | input Boolean b; | ||
| 4847 | input Integer c; | ||
| 4848 | input array<Integer> col_degrees; | ||
| 4849 | input array<Integer> row_degrees; | ||
| 4850 | input array<Integer> randarr; | ||
| 4851 | input BackendDAE.AdjacencyMatrix m; | ||
| 4852 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 4853 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 4854 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 4855 | output list<Integer> onecolums; | ||
| 4856 | output list<Integer> onerows; | ||
| 4857 | algorithm | ||
| 4858 | (onecolums,onerows) := match b | ||
| 4859 | local | ||
| 4860 | list<Integer> clst,rlst,lst; | ||
| 4861 | Integer e_id,r; | ||
| 4862 | case true | ||
| 4863 | algorithm | ||
| 4864 | 74 | e_id := realInt(realMod(System.realRand(),intReal(col_degrees[c]))); | |
| 4865 | 74 | lst := List.select(m[c], Util.intPositive); | |
| 4866 | 74 | (rlst,r) := ks_rand_cheapmatching3(e_id,lst,row_degrees,c,ass1,ass2,{},0); | |
| 4867 | 74 | lst := List.select(mT[r], Util.intPositive); | |
| 4868 | 74 | clst := ks_rand_cheapmatching4(lst,row_degrees[r],col_degrees,ass1,{}); | |
| 4869 | then | ||
| 4870 | (clst,rlst); | ||
| 4871 | else | ||
| 4872 | ({},{}); | ||
| 4873 | end match; | ||
| 4874 | end ks_rand_cheapmatching2; | ||
| 4875 | |||
| 4876 | protected function ks_rand_cheapmatching3 | ||
| 4877 | "function ks_rand_cheapmatching3, helper for ks_rand_match. | ||
| 4878 | author: Frenkel TUD 2012-04" | ||
| 4879 | input Integer e_id; | ||
| 4880 | input list<Integer> rows; | ||
| 4881 | input array<Integer> row_degrees; | ||
| 4882 | input Integer c; | ||
| 4883 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 4884 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 4885 | input list<Integer> onerows; | ||
| 4886 | input Integer inR; | ||
| 4887 | output list<Integer> outonerows; | ||
| 4888 | output Integer outR; | ||
| 4889 | algorithm | ||
| 4890 | (outonerows,outR) := matchcontinue rows | ||
| 4891 | local | ||
| 4892 | list<Integer> rest,stack,statck1; | ||
| 4893 | Integer r,r_1; | ||
| 4894 | 27 | case {} then (onerows,inR); | |
| 4895 | case r::rest | ||
| 4896 | algorithm | ||
| 4897 |
2/2✓ Branch 1 taken 44 times.
✓ Branch 2 taken 84 times.
|
128 | true := intLt(ass2[r],0); |
| 4898 |
2/2✓ Branch 0 taken 37 times.
✓ Branch 1 taken 47 times.
|
84 | true := intEq(e_id,0); |
| 4899 | 47 | arrayUpdate(ass1,c,r); | |
| 4900 | 47 | arrayUpdate(ass2,r,c); | |
| 4901 | 47 | stack := ks_rand_match_degree(rest,row_degrees,ass2,onerows); | |
| 4902 | 47 | then | |
| 4903 | (stack,r); | ||
| 4904 | case r::rest | ||
| 4905 | algorithm | ||
| 4906 |
2/2✓ Branch 1 taken 44 times.
✓ Branch 2 taken 37 times.
|
81 | true := intLt(ass2[r],0); |
| 4907 | 37 | arrayUpdate(row_degrees,r,row_degrees[r]-1); | |
| 4908 | 37 | stack := List.consOnTrue(intEq(row_degrees[r],1),r,onerows); | |
| 4909 | 37 | (statck1,r_1) := ks_rand_cheapmatching3(e_id-1,rest,row_degrees,c,ass1,ass2,stack,r); | |
| 4910 | then | ||
| 4911 | (statck1,r_1); | ||
| 4912 | case r::rest | ||
| 4913 | algorithm | ||
| 4914 | 44 | (statck1,r_1) := ks_rand_cheapmatching3(e_id-1,rest,row_degrees,c,ass1,ass2,onerows,r); | |
| 4915 | then | ||
| 4916 | (statck1,r_1); | ||
| 4917 | end matchcontinue; | ||
| 4918 | end ks_rand_cheapmatching3; | ||
| 4919 | |||
| 4920 | protected function ks_rand_cheapmatching4 | ||
| 4921 | "function ks_rand_cheapmatching4, helper for ks_rand_cheapmatching. | ||
| 4922 | author: Frenkel TUD 2012-04" | ||
| 4923 | input list<Integer> cols; | ||
| 4924 | input Integer count; | ||
| 4925 | input array<Integer> col_degrees; | ||
| 4926 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 4927 | input list<Integer> inStack; | ||
| 4928 | output list<Integer> outStack; | ||
| 4929 | algorithm | ||
| 4930 | outStack := matchcontinue cols | ||
| 4931 | local | ||
| 4932 | list<Integer> rest,stack; | ||
| 4933 | Integer c; | ||
| 4934 | case {} then inStack; | ||
| 4935 | case _ | ||
| 4936 | algorithm | ||
| 4937 |
2/2✓ Branch 0 taken 270 times.
✓ Branch 1 taken 15 times.
|
285 | false := intGt(count,0); |
| 4938 | then | ||
| 4939 | inStack; | ||
| 4940 | case c::rest | ||
| 4941 | algorithm | ||
| 4942 |
2/2✓ Branch 1 taken 131 times.
✓ Branch 2 taken 139 times.
|
270 | true := intLt(ass1[c],0); |
| 4943 | 139 | arrayUpdate(col_degrees,c,col_degrees[c]-1); | |
| 4944 | 139 | stack := List.consOnTrue(intEq(col_degrees[c],1),c,inStack); | |
| 4945 | 139 | then | |
| 4946 | ks_rand_cheapmatching4(rest,count-1,col_degrees,ass1,stack); | ||
| 4947 | case _::rest | ||
| 4948 | 131 | then | |
| 4949 | ks_rand_cheapmatching4(rest,count,col_degrees,ass1,inStack); | ||
| 4950 | end matchcontinue; | ||
| 4951 | end ks_rand_cheapmatching4; | ||
| 4952 | |||
| 4953 | protected function getOneRows | ||
| 4954 | "function getOneRows, helper for ks_rand_cheapmatching. | ||
| 4955 | return all rows with length == 1 | ||
| 4956 | author: Frenkel TUD 2012-04" | ||
| 4957 | input Integer n; | ||
| 4958 | input BackendDAE.AdjacencyMatrix m; | ||
| 4959 | input array<Integer> degrees; | ||
| 4960 | input list<Integer> inOneRows; | ||
| 4961 | output list<Integer> outOneRows; | ||
| 4962 | algorithm | ||
| 4963 | outOneRows := match n | ||
| 4964 | local | ||
| 4965 | list<Integer> lst,onerows; | ||
| 4966 | Integer l; | ||
| 4967 | 1292 | case 0 then listReverse(inOneRows); | |
| 4968 | else | ||
| 4969 | algorithm | ||
| 4970 | 5940 | lst := List.select(m[n], Util.intPositive); | |
| 4971 | 5940 | l := listLength(lst); | |
| 4972 | 5940 | arrayUpdate(degrees,n,l); | |
| 4973 | 5940 | onerows := List.consOnTrue(intEq(l,1),n,inOneRows); | |
| 4974 | 5940 | then | |
| 4975 | getOneRows(n-1,m,degrees,onerows); | ||
| 4976 | end match; | ||
| 4977 | end getOneRows; | ||
| 4978 | |||
| 4979 | protected function setrandArray | ||
| 4980 | "function setrandArray, helper for ks_rand_cheapmatching. | ||
| 4981 | return all rows with length == 1 | ||
| 4982 | author: Frenkel TUD 2012-04" | ||
| 4983 | input Integer n; | ||
| 4984 | input array<Integer> randarr; | ||
| 4985 | algorithm | ||
| 4986 | () := match n | ||
| 4987 | local | ||
| 4988 | Integer z,tmp; | ||
| 4989 | case 0 then (); | ||
| 4990 | else | ||
| 4991 | algorithm | ||
| 4992 | 2970 | z := realInt(realMod(System.realRand(),intReal(n)))+1; | |
| 4993 | 2970 | tmp := randarr[n]; | |
| 4994 | 2970 | arrayUpdate(randarr,n,randarr[z]); | |
| 4995 | 2970 | arrayUpdate(randarr,z,tmp); | |
| 4996 | 2970 | setrandArray(n-1,randarr); | |
| 4997 | then | ||
| 4998 | (); | ||
| 4999 | end match; | ||
| 5000 | end setrandArray; | ||
| 5001 | |||
| 5002 | protected function ks_rand_match | ||
| 5003 | "function ks_rand_match, helper for ks_rand_cheapmatching. | ||
| 5004 | author: Frenkel TUD 2012-04" | ||
| 5005 | input list<Integer> stack1; | ||
| 5006 | input list<Integer> stack2; | ||
| 5007 | input array<Integer> degrees1; | ||
| 5008 | input array<Integer> degrees2; | ||
| 5009 | input BackendDAE.AdjacencyMatrix m1; | ||
| 5010 | input BackendDAE.AdjacencyMatrix m2; | ||
| 5011 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 5012 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 5013 | algorithm | ||
| 5014 | () := matchcontinue (stack1, stack2) | ||
| 5015 | local | ||
| 5016 | Integer e; | ||
| 5017 | list<Integer> rest,lst,stack; | ||
| 5018 | case ({}, {}) then (); | ||
| 5019 | case (e::rest, {}) | ||
| 5020 | algorithm | ||
| 5021 |
2/2✓ Branch 1 taken 9 times.
✓ Branch 2 taken 1257 times.
|
1266 | true := intEq(degrees1[e],1); |
| 5022 |
2/2✓ Branch 1 taken 899 times.
✓ Branch 2 taken 358 times.
|
1257 | true := intLt(ass1[e],0); |
| 5023 | 358 | lst := List.select(m1[e], Util.intPositive); | |
| 5024 | 358 | stack := ks_rand_match1(e,lst,rest,degrees1,degrees2,m2,ass1,ass2); | |
| 5025 | 358 | ks_rand_match(stack,{},degrees1,degrees2,m1,m2,ass1,ass2); | |
| 5026 | then | ||
| 5027 | (); | ||
| 5028 | case (_::rest, {}) | ||
| 5029 | algorithm | ||
| 5030 | 908 | ks_rand_match(rest,{},degrees1,degrees2,m1,m2,ass1,ass2); | |
| 5031 | then | ||
| 5032 | (); | ||
| 5033 | case ({}, e::rest) | ||
| 5034 | algorithm | ||
| 5035 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
|
17 | true := intEq(degrees2[e],1); |
| 5036 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
|
17 | true := intLt(ass2[e],0); |
| 5037 | 17 | lst := List.select(m2[e], Util.intPositive); | |
| 5038 | 17 | stack := ks_rand_match1(e,lst,rest,degrees2,degrees1,m1,ass2,ass1); | |
| 5039 | 17 | ks_rand_match(stack,{},degrees2,degrees1,m2,m1,ass2,ass1); | |
| 5040 | then | ||
| 5041 | (); | ||
| 5042 | case ({}, _::rest) | ||
| 5043 | algorithm | ||
| 5044 | ✗ | ks_rand_match(rest,{},degrees2,degrees1,m2,m1,ass2,ass1); | |
| 5045 | then | ||
| 5046 | (); | ||
| 5047 | case (e::rest, _) | ||
| 5048 | algorithm | ||
| 5049 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1554 times.
|
1554 | true := intEq(degrees1[e],1); |
| 5050 |
2/2✓ Branch 1 taken 459 times.
✓ Branch 2 taken 1095 times.
|
1554 | true := intLt(ass1[e],0); |
| 5051 | 1095 | lst := List.select(m1[e], Util.intPositive); | |
| 5052 | 1095 | stack := ks_rand_match1(e,lst,rest,degrees1,degrees2,m2,ass1,ass2); | |
| 5053 | 1095 | ks_rand_match(stack2,stack,degrees2,degrees1,m2,m1,ass2,ass1); | |
| 5054 | then | ||
| 5055 | (); | ||
| 5056 | case (_::rest, _) | ||
| 5057 | algorithm | ||
| 5058 | 459 | ks_rand_match(stack2,rest,degrees2,degrees1,m2,m1,ass2,ass1); | |
| 5059 | then | ||
| 5060 | (); | ||
| 5061 | end matchcontinue; | ||
| 5062 | end ks_rand_match; | ||
| 5063 | |||
| 5064 | protected function ks_rand_match1 | ||
| 5065 | "function ks_rand_match1, helper for ks_rand_match. | ||
| 5066 | author: Frenkel TUD 2012-04" | ||
| 5067 | input Integer i; | ||
| 5068 | input list<Integer> entries; | ||
| 5069 | input list<Integer> stack; | ||
| 5070 | input array<Integer> degrees1; | ||
| 5071 | input array<Integer> degrees2; | ||
| 5072 | input BackendDAE.AdjacencyMatrix adjacency; | ||
| 5073 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 5074 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 5075 | output list<Integer> outStack; | ||
| 5076 | algorithm | ||
| 5077 | outStack := matchcontinue entries | ||
| 5078 | local | ||
| 5079 | list<Integer> rest,lst; | ||
| 5080 | Integer e; | ||
| 5081 | case {} then stack; | ||
| 5082 | case e::_ | ||
| 5083 | algorithm | ||
| 5084 |
2/2✓ Branch 1 taken 680 times.
✓ Branch 2 taken 1443 times.
|
2123 | true := intLt(ass2[e],0); |
| 5085 | 1443 | lst := List.select(adjacency[e], Util.intPositive); | |
| 5086 | 1443 | arrayUpdate(ass1,i,e); | |
| 5087 | 1443 | arrayUpdate(ass2,e,i); | |
| 5088 | 1443 | then | |
| 5089 | ks_rand_match_degree(lst,degrees1,ass1,stack); | ||
| 5090 | case _::rest | ||
| 5091 | 680 | then | |
| 5092 | ks_rand_match1(i,rest,stack,degrees1,degrees2,adjacency,ass1,ass2); | ||
| 5093 | end matchcontinue; | ||
| 5094 | end ks_rand_match1; | ||
| 5095 | |||
| 5096 | protected function ks_rand_match_degree | ||
| 5097 | "function ks_rand_match_degree, helper for ks_rand_match. | ||
| 5098 | author: Frenkel TUD 2012-04" | ||
| 5099 | input list<Integer> entries; | ||
| 5100 | input array<Integer> degrees; | ||
| 5101 | input array<Integer> ass; | ||
| 5102 | input list<Integer> inStack; | ||
| 5103 | output list<Integer> outStack; | ||
| 5104 | algorithm | ||
| 5105 | outStack := matchcontinue entries | ||
| 5106 | local | ||
| 5107 | list<Integer> rest,stack; | ||
| 5108 | Integer e; | ||
| 5109 | case {} then inStack; | ||
| 5110 | case e::rest | ||
| 5111 | algorithm | ||
| 5112 |
2/2✓ Branch 1 taken 1923 times.
✓ Branch 2 taken 1560 times.
|
3483 | true := intLt(ass[e],0); |
| 5113 | 1560 | arrayUpdate(degrees,e,degrees[e]-1); | |
| 5114 | 1560 | stack := List.consOnTrue(intEq(degrees[e],1),e,inStack); | |
| 5115 | 1560 | then | |
| 5116 | ks_rand_match_degree(rest,degrees,ass,stack); | ||
| 5117 | case _::rest | ||
| 5118 | 1923 | then | |
| 5119 | ks_rand_match_degree(rest,degrees,ass,inStack); | ||
| 5120 | end matchcontinue; | ||
| 5121 | end ks_rand_match_degree; | ||
| 5122 | |||
| 5123 | // ============================================================================= | ||
| 5124 | // C-Implementation Stuff from | ||
| 5125 | // Kamer Kaya, Johannes Langguth and Bora Ucar | ||
| 5126 | // see: http://bmi.osu.edu/~kamer/index.html | ||
| 5127 | // ============================================================================= | ||
| 5128 | |||
| 5129 | public function DFSBExternal | ||
| 5130 | "function: DFSBExternal" | ||
| 5131 | input BackendDAE.EqSystem isyst; | ||
| 5132 | input BackendDAE.Shared ishared; | ||
| 5133 | input Boolean clearMatching; | ||
| 5134 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 5135 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 5136 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 5137 | output BackendDAE.EqSystem osyst; | ||
| 5138 | output BackendDAE.Shared oshared; | ||
| 5139 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 5140 | algorithm | ||
| 5141 | (osyst,oshared,outArg) := | ||
| 5142 | matchcontinue inArg | ||
| 5143 | local | ||
| 5144 | Integer nvars,neqns; | ||
| 5145 | array<Integer> vec1,vec2; | ||
| 5146 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 5147 | BackendDAE.EqSystem syst; | ||
| 5148 | BackendDAE.Shared shared; | ||
| 5149 | case _ | ||
| 5150 | algorithm | ||
| 5151 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 5152 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 5153 | ✗ | true := intGt(nvars,0); | |
| 5154 | ✗ | true := intGt(neqns,0); | |
| 5155 | ✗ | (vec1,vec2) := getAssignment(clearMatching,nvars,neqns,isyst); | |
| 5156 | ✗ | true := if not clearMatching then BackendDAEEXT.setAssignment(neqns, nvars, vec1, vec2) else true; | |
| 5157 | ✗ | (vec1,vec2,syst,shared,arg) := matchingExternal({},false,1,Config.getCheapMatchingAlgorithm(),if clearMatching then 1 else 0,isyst,ishared,nvars, neqns, vec1, vec2, inMatchingOptions, sssHandler, inArg); | |
| 5158 | ✗ | syst := BackendDAEUtil.setEqSystMatching(syst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 5159 | ✗ | then | |
| 5160 | (syst,shared,arg); | ||
| 5161 | // fail case if system is empty | ||
| 5162 | case _ | ||
| 5163 | algorithm | ||
| 5164 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 5165 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 5166 | ✗ | false := intGt(nvars,0); | |
| 5167 | ✗ | false := intGt(neqns,0); | |
| 5168 | ✗ | vec1 := listArray({}); | |
| 5169 | ✗ | vec2 := listArray({}); | |
| 5170 | ✗ | syst := BackendDAEUtil.setEqSystMatching(isyst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 5171 | then | ||
| 5172 | (syst,ishared,inArg); | ||
| 5173 | else | ||
| 5174 | algorithm | ||
| 5175 | ✗ | if Flags.isSet(Flags.FAILTRACE) then | |
| 5176 | ✗ | Debug.trace("- Matching.DFSBExternal failed\n"); | |
| 5177 | end if; | ||
| 5178 | ✗ | then | |
| 5179 | fail(); | ||
| 5180 | end matchcontinue; | ||
| 5181 | end DFSBExternal; | ||
| 5182 | |||
| 5183 | public function BFSBExternal | ||
| 5184 | "function: BFSBExternal" | ||
| 5185 | input BackendDAE.EqSystem isyst; | ||
| 5186 | input BackendDAE.Shared ishared; | ||
| 5187 | input Boolean clearMatching; | ||
| 5188 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 5189 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 5190 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 5191 | output BackendDAE.EqSystem osyst; | ||
| 5192 | output BackendDAE.Shared oshared; | ||
| 5193 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 5194 | algorithm | ||
| 5195 | (osyst,oshared,outArg) := | ||
| 5196 | matchcontinue inArg | ||
| 5197 | local | ||
| 5198 | Integer nvars,neqns; | ||
| 5199 | array<Integer> vec1,vec2; | ||
| 5200 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 5201 | BackendDAE.EqSystem syst; | ||
| 5202 | BackendDAE.Shared shared; | ||
| 5203 | case _ | ||
| 5204 | algorithm | ||
| 5205 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 5206 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 5207 | ✗ | true := intGt(nvars,0); | |
| 5208 | ✗ | true := intGt(neqns,0); | |
| 5209 | ✗ | (vec1,vec2) := getAssignment(clearMatching,nvars,neqns,isyst); | |
| 5210 | ✗ | true := if not clearMatching then BackendDAEEXT.setAssignment(neqns, nvars, vec1, vec2) else true; | |
| 5211 | ✗ | (vec1,vec2,syst,shared,arg) := matchingExternal({},false,2,Config.getCheapMatchingAlgorithm(),if clearMatching then 1 else 0,isyst,ishared,nvars, neqns, vec1, vec2, inMatchingOptions, sssHandler, inArg); | |
| 5212 | ✗ | syst := BackendDAEUtil.setEqSystMatching(syst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 5213 | ✗ | then | |
| 5214 | (syst,shared,arg); | ||
| 5215 | // fail case if system is empty | ||
| 5216 | case _ | ||
| 5217 | algorithm | ||
| 5218 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 5219 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 5220 | ✗ | false := intGt(nvars,0); | |
| 5221 | ✗ | false := intGt(neqns,0); | |
| 5222 | ✗ | vec1 := listArray({}); | |
| 5223 | ✗ | vec2 := listArray({}); | |
| 5224 | ✗ | syst := BackendDAEUtil.setEqSystMatching(isyst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 5225 | then | ||
| 5226 | (syst,ishared,inArg); | ||
| 5227 | else | ||
| 5228 | algorithm | ||
| 5229 | ✗ | if Flags.isSet(Flags.FAILTRACE) then | |
| 5230 | ✗ | Debug.trace("- Matching.BFSBExternal failed\n"); | |
| 5231 | end if; | ||
| 5232 | ✗ | then | |
| 5233 | fail(); | ||
| 5234 | end matchcontinue; | ||
| 5235 | end BFSBExternal; | ||
| 5236 | |||
| 5237 | public function MC21AExternal | ||
| 5238 | "function: MC21AExternal" | ||
| 5239 | input BackendDAE.EqSystem isyst; | ||
| 5240 | input BackendDAE.Shared ishared; | ||
| 5241 | input Boolean clearMatching; | ||
| 5242 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 5243 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 5244 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 5245 | output BackendDAE.EqSystem osyst; | ||
| 5246 | output BackendDAE.Shared oshared; | ||
| 5247 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 5248 | algorithm | ||
| 5249 | (osyst,oshared,outArg) := | ||
| 5250 | matchcontinue inArg | ||
| 5251 | local | ||
| 5252 | Integer nvars,neqns; | ||
| 5253 | array<Integer> vec1,vec2; | ||
| 5254 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 5255 | BackendDAE.EqSystem syst; | ||
| 5256 | BackendDAE.Shared shared; | ||
| 5257 | case _ | ||
| 5258 | algorithm | ||
| 5259 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 5260 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 5261 | ✗ | true := intGt(nvars,0); | |
| 5262 | ✗ | true := intGt(neqns,0); | |
| 5263 | ✗ | (vec1,vec2) := getAssignment(clearMatching,nvars,neqns,isyst); | |
| 5264 | ✗ | true := if not clearMatching then BackendDAEEXT.setAssignment(neqns, nvars, vec1, vec2) else true; | |
| 5265 | ✗ | (vec1,vec2,syst,shared,arg) := matchingExternal({},false,3,Config.getCheapMatchingAlgorithm(),if clearMatching then 1 else 0,isyst,ishared,nvars, neqns, vec1, vec2, inMatchingOptions, sssHandler, inArg); | |
| 5266 | ✗ | syst := BackendDAEUtil.setEqSystMatching(syst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 5267 | ✗ | then | |
| 5268 | (syst,shared,arg); | ||
| 5269 | // fail case if system is empty | ||
| 5270 | case _ | ||
| 5271 | algorithm | ||
| 5272 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 5273 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 5274 | ✗ | false := intGt(nvars,0); | |
| 5275 | ✗ | false := intGt(neqns,0); | |
| 5276 | ✗ | vec1 := listArray({}); | |
| 5277 | ✗ | vec2 := listArray({}); | |
| 5278 | ✗ | syst := BackendDAEUtil.setEqSystMatching(isyst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 5279 | then | ||
| 5280 | (syst,ishared,inArg); | ||
| 5281 | else | ||
| 5282 | algorithm | ||
| 5283 | ✗ | if Flags.isSet(Flags.FAILTRACE) then | |
| 5284 | ✗ | Debug.trace("- Matching.MC21AExternal failed\n"); | |
| 5285 | end if; | ||
| 5286 | ✗ | then | |
| 5287 | fail(); | ||
| 5288 | end matchcontinue; | ||
| 5289 | end MC21AExternal; | ||
| 5290 | |||
| 5291 | public function PFExternal | ||
| 5292 | "function: PFExternal" | ||
| 5293 | input BackendDAE.EqSystem isyst; | ||
| 5294 | input BackendDAE.Shared ishared; | ||
| 5295 | input Boolean clearMatching; | ||
| 5296 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 5297 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 5298 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 5299 | output BackendDAE.EqSystem osyst; | ||
| 5300 | output BackendDAE.Shared oshared; | ||
| 5301 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 5302 | algorithm | ||
| 5303 | (osyst,oshared,outArg) := | ||
| 5304 | matchcontinue inArg | ||
| 5305 | local | ||
| 5306 | Integer nvars,neqns; | ||
| 5307 | array<Integer> vec1,vec2; | ||
| 5308 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 5309 | BackendDAE.EqSystem syst; | ||
| 5310 | BackendDAE.Shared shared; | ||
| 5311 | case _ | ||
| 5312 | algorithm | ||
| 5313 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 5314 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 5315 | ✗ | true := intGt(nvars,0); | |
| 5316 | ✗ | true := intGt(neqns,0); | |
| 5317 | ✗ | (vec1,vec2) := getAssignment(clearMatching,nvars,neqns,isyst); | |
| 5318 | ✗ | true := if not clearMatching then BackendDAEEXT.setAssignment(neqns, nvars, vec1, vec2) else true; | |
| 5319 | ✗ | (vec1,vec2,syst,shared,arg) := matchingExternal({},false,4,Config.getCheapMatchingAlgorithm(),if clearMatching then 1 else 0,isyst,ishared,nvars, neqns, vec1, vec2, inMatchingOptions, sssHandler, inArg); | |
| 5320 | ✗ | syst := BackendDAEUtil.setEqSystMatching(syst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 5321 | ✗ | then | |
| 5322 | (syst,shared,arg); | ||
| 5323 | // fail case if system is empty | ||
| 5324 | case _ | ||
| 5325 | algorithm | ||
| 5326 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 5327 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 5328 | ✗ | false := intGt(nvars,0); | |
| 5329 | ✗ | false := intGt(neqns,0); | |
| 5330 | ✗ | vec1 := listArray({}); | |
| 5331 | ✗ | vec2 := listArray({}); | |
| 5332 | ✗ | syst := BackendDAEUtil.setEqSystMatching(isyst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 5333 | then | ||
| 5334 | (syst,ishared,inArg); | ||
| 5335 | else | ||
| 5336 | algorithm | ||
| 5337 | ✗ | if Flags.isSet(Flags.FAILTRACE) then | |
| 5338 | ✗ | Debug.trace("- Matching.PFExternal failed\n"); | |
| 5339 | end if; | ||
| 5340 | ✗ | then | |
| 5341 | fail(); | ||
| 5342 | end matchcontinue; | ||
| 5343 | end PFExternal; | ||
| 5344 | |||
| 5345 | public function PFPlusExternal | ||
| 5346 | "function: PFExternal" | ||
| 5347 | input BackendDAE.EqSystem isyst; | ||
| 5348 | input BackendDAE.Shared ishared; | ||
| 5349 | input Boolean clearMatching; | ||
| 5350 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 5351 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 5352 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 5353 | output BackendDAE.EqSystem osyst; | ||
| 5354 | output BackendDAE.Shared oshared; | ||
| 5355 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 5356 | protected | ||
| 5357 | Integer nvars,neqns; | ||
| 5358 | algorithm | ||
| 5359 | 122529 | neqns := BackendDAEUtil.systemSize(isyst); | |
| 5360 | 122529 | nvars := BackendVariable.daenumVariables(isyst); | |
| 5361 | (osyst,oshared,outArg) := | ||
| 5362 | matchcontinue inArg | ||
| 5363 | local | ||
| 5364 | array<Integer> vec1,vec2; | ||
| 5365 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 5366 | BackendDAE.EqSystem syst; | ||
| 5367 | BackendDAE.Shared shared; | ||
| 5368 | case _ guard intGt(nvars,0) and intGt(neqns,0) | ||
| 5369 | algorithm | ||
| 5370 | 118741 | (vec1,vec2) := getAssignment(clearMatching,nvars,neqns,isyst); | |
| 5371 |
3/4✓ Branch 0 taken 59370 times.
✓ Branch 1 taken 59371 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 59370 times.
|
118741 | true := if not clearMatching then BackendDAEEXT.setAssignment(neqns, nvars, vec1, vec2) else true; |
| 5372 |
2/2✓ Branch 0 taken 59370 times.
✓ Branch 1 taken 59371 times.
|
178111 | (vec1,vec2,syst,shared,arg) := matchingExternal({},false,5,Config.getCheapMatchingAlgorithm(),if clearMatching then 1 else 0,isyst,ishared,nvars, neqns, vec1, vec2, inMatchingOptions, sssHandler, inArg); |
| 5373 | 118740 | syst := BackendDAEUtil.setEqSystMatching(syst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 5374 | 118740 | then | |
| 5375 | (syst,shared,arg); | ||
| 5376 | // fail case if system is empty | ||
| 5377 | case _ guard not intGt(nvars,0) and not intGt(neqns,0) | ||
| 5378 | algorithm | ||
| 5379 | 3788 | vec1 := listArray({}); | |
| 5380 | 3788 | vec2 := listArray({}); | |
| 5381 | 3788 | syst := BackendDAEUtil.setEqSystMatching(isyst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 5382 | then | ||
| 5383 | (syst,ishared,inArg); | ||
| 5384 | else | ||
| 5385 | algorithm | ||
| 5386 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
|
1 | if Flags.isSet(Flags.FAILTRACE) then |
| 5387 | ✗ | Debug.trace("- Matching.PFPlusExternal failed\n"); | |
| 5388 | end if; | ||
| 5389 | 1 | then | |
| 5390 | fail(); | ||
| 5391 | end matchcontinue; | ||
| 5392 | end PFPlusExternal; | ||
| 5393 | |||
| 5394 | public function HKExternal | ||
| 5395 | "function: HKExternal" | ||
| 5396 | input BackendDAE.EqSystem isyst; | ||
| 5397 | input BackendDAE.Shared ishared; | ||
| 5398 | input Boolean clearMatching; | ||
| 5399 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 5400 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 5401 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 5402 | output BackendDAE.EqSystem osyst; | ||
| 5403 | output BackendDAE.Shared oshared; | ||
| 5404 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 5405 | algorithm | ||
| 5406 | (osyst,oshared,outArg) := | ||
| 5407 | matchcontinue inArg | ||
| 5408 | local | ||
| 5409 | Integer nvars,neqns; | ||
| 5410 | array<Integer> vec1,vec2; | ||
| 5411 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 5412 | BackendDAE.EqSystem syst; | ||
| 5413 | BackendDAE.Shared shared; | ||
| 5414 | case _ | ||
| 5415 | algorithm | ||
| 5416 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 5417 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 5418 | ✗ | true := intGt(nvars,0); | |
| 5419 | ✗ | true := intGt(neqns,0); | |
| 5420 | ✗ | (vec1,vec2) := getAssignment(clearMatching,nvars,neqns,isyst); | |
| 5421 | ✗ | true := if not clearMatching then BackendDAEEXT.setAssignment(neqns, nvars, vec1, vec2) else true; | |
| 5422 | ✗ | (vec1,vec2,syst,shared,arg) := matchingExternal({},false,6,Config.getCheapMatchingAlgorithm(),if clearMatching then 1 else 0,isyst,ishared,nvars, neqns, vec1, vec2, inMatchingOptions, sssHandler, inArg); | |
| 5423 | ✗ | syst := BackendDAEUtil.setEqSystMatching(syst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 5424 | ✗ | then | |
| 5425 | (syst,shared,arg); | ||
| 5426 | // fail case if system is empty | ||
| 5427 | case _ | ||
| 5428 | algorithm | ||
| 5429 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 5430 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 5431 | ✗ | false := intGt(nvars,0); | |
| 5432 | ✗ | false := intGt(neqns,0); | |
| 5433 | ✗ | vec1 := listArray({}); | |
| 5434 | ✗ | vec2 := listArray({}); | |
| 5435 | ✗ | syst := BackendDAEUtil.setEqSystMatching(isyst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 5436 | then | ||
| 5437 | (syst,ishared,inArg); | ||
| 5438 | else | ||
| 5439 | algorithm | ||
| 5440 | ✗ | if Flags.isSet(Flags.FAILTRACE) then | |
| 5441 | ✗ | Debug.trace("- Matching.HKExternal failed\n"); | |
| 5442 | end if; | ||
| 5443 | ✗ | then | |
| 5444 | fail(); | ||
| 5445 | end matchcontinue; | ||
| 5446 | end HKExternal; | ||
| 5447 | |||
| 5448 | public function HKDWExternal | ||
| 5449 | "function: HKDWExternal" | ||
| 5450 | input BackendDAE.EqSystem isyst; | ||
| 5451 | input BackendDAE.Shared ishared; | ||
| 5452 | input Boolean clearMatching; | ||
| 5453 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 5454 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 5455 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 5456 | output BackendDAE.EqSystem osyst; | ||
| 5457 | output BackendDAE.Shared oshared; | ||
| 5458 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 5459 | algorithm | ||
| 5460 | (osyst,oshared,outArg) := | ||
| 5461 | matchcontinue inArg | ||
| 5462 | local | ||
| 5463 | Integer nvars,neqns; | ||
| 5464 | array<Integer> vec1,vec2; | ||
| 5465 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 5466 | BackendDAE.EqSystem syst; | ||
| 5467 | BackendDAE.Shared shared; | ||
| 5468 | case _ | ||
| 5469 | algorithm | ||
| 5470 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 5471 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 5472 | ✗ | true := intGt(nvars,0); | |
| 5473 | ✗ | true := intGt(neqns,0); | |
| 5474 | ✗ | (vec1,vec2) := getAssignment(clearMatching,nvars,neqns,isyst); | |
| 5475 | ✗ | true := if not clearMatching then BackendDAEEXT.setAssignment(neqns, nvars, vec1, vec2) else true; | |
| 5476 | ✗ | (vec1,vec2,syst,shared,arg) := matchingExternal({},false,7,Config.getCheapMatchingAlgorithm(),if clearMatching then 1 else 0,isyst,ishared,nvars, neqns, vec1, vec2, inMatchingOptions, sssHandler, inArg); | |
| 5477 | ✗ | syst := BackendDAEUtil.setEqSystMatching(syst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 5478 | ✗ | then | |
| 5479 | (syst,shared,arg); | ||
| 5480 | // fail case if system is empty | ||
| 5481 | case _ | ||
| 5482 | algorithm | ||
| 5483 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 5484 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 5485 | ✗ | false := intGt(nvars,0); | |
| 5486 | ✗ | false := intGt(neqns,0); | |
| 5487 | ✗ | vec1 := listArray({}); | |
| 5488 | ✗ | vec2 := listArray({}); | |
| 5489 | ✗ | syst := BackendDAEUtil.setEqSystMatching(isyst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 5490 | then | ||
| 5491 | (syst,ishared,inArg); | ||
| 5492 | else | ||
| 5493 | algorithm | ||
| 5494 | ✗ | if Flags.isSet(Flags.FAILTRACE) then | |
| 5495 | ✗ | Debug.trace("- Matching.HKDWExternal failed\n"); | |
| 5496 | end if; | ||
| 5497 | ✗ | then | |
| 5498 | fail(); | ||
| 5499 | end matchcontinue; | ||
| 5500 | end HKDWExternal; | ||
| 5501 | |||
| 5502 | public function ABMPExternal | ||
| 5503 | "function: ABMPExternal" | ||
| 5504 | input BackendDAE.EqSystem isyst; | ||
| 5505 | input BackendDAE.Shared ishared; | ||
| 5506 | input Boolean clearMatching; | ||
| 5507 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 5508 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 5509 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 5510 | output BackendDAE.EqSystem osyst; | ||
| 5511 | output BackendDAE.Shared oshared; | ||
| 5512 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 5513 | algorithm | ||
| 5514 | (osyst,oshared,outArg) := | ||
| 5515 | matchcontinue inArg | ||
| 5516 | local | ||
| 5517 | Integer nvars,neqns; | ||
| 5518 | array<Integer> vec1,vec2; | ||
| 5519 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 5520 | BackendDAE.EqSystem syst; | ||
| 5521 | BackendDAE.Shared shared; | ||
| 5522 | case _ | ||
| 5523 | algorithm | ||
| 5524 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 5525 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 5526 | ✗ | true := intGt(nvars,0); | |
| 5527 | ✗ | true := intGt(neqns,0); | |
| 5528 | ✗ | (vec1,vec2) := getAssignment(clearMatching,nvars,neqns,isyst); | |
| 5529 | ✗ | true := if not clearMatching then BackendDAEEXT.setAssignment(neqns, nvars, vec1, vec2) else true; | |
| 5530 | ✗ | (vec1,vec2,syst,shared,arg) := matchingExternal({},false,8,Config.getCheapMatchingAlgorithm(),if clearMatching then 1 else 0,isyst,ishared,nvars, neqns, vec1, vec2, inMatchingOptions, sssHandler, inArg); | |
| 5531 | ✗ | syst := BackendDAEUtil.setEqSystMatching(syst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 5532 | ✗ | then | |
| 5533 | (syst,shared,arg); | ||
| 5534 | // fail case if system is empty | ||
| 5535 | case _ | ||
| 5536 | algorithm | ||
| 5537 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 5538 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 5539 | ✗ | false := intGt(nvars,0); | |
| 5540 | ✗ | false := intGt(neqns,0); | |
| 5541 | ✗ | vec1 := listArray({}); | |
| 5542 | ✗ | vec2 := listArray({}); | |
| 5543 | ✗ | syst := BackendDAEUtil.setEqSystMatching(isyst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 5544 | then | ||
| 5545 | (syst,ishared,inArg); | ||
| 5546 | else | ||
| 5547 | algorithm | ||
| 5548 | ✗ | if Flags.isSet(Flags.FAILTRACE) then | |
| 5549 | ✗ | Debug.trace("- Matching.ABMPExternal failed\n"); | |
| 5550 | end if; | ||
| 5551 | ✗ | then | |
| 5552 | fail(); | ||
| 5553 | end matchcontinue; | ||
| 5554 | end ABMPExternal; | ||
| 5555 | |||
| 5556 | public function PR_FIFO_FAIRExternal | ||
| 5557 | "function: PR_FIFO_FAIRExternal" | ||
| 5558 | input BackendDAE.EqSystem isyst; | ||
| 5559 | input BackendDAE.Shared ishared; | ||
| 5560 | input Boolean clearMatching; | ||
| 5561 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 5562 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 5563 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 5564 | output BackendDAE.EqSystem osyst; | ||
| 5565 | output BackendDAE.Shared oshared; | ||
| 5566 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 5567 | algorithm | ||
| 5568 | (osyst,oshared,outArg) := | ||
| 5569 | matchcontinue inArg | ||
| 5570 | local | ||
| 5571 | Integer nvars,neqns; | ||
| 5572 | array<Integer> vec1,vec2; | ||
| 5573 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 5574 | BackendDAE.EqSystem syst; | ||
| 5575 | BackendDAE.Shared shared; | ||
| 5576 | case _ | ||
| 5577 | algorithm | ||
| 5578 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 5579 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 5580 | ✗ | true := intGt(nvars,0); | |
| 5581 | ✗ | true := intGt(neqns,0); | |
| 5582 | ✗ | (vec1,vec2) := getAssignment(clearMatching,nvars,neqns,isyst); | |
| 5583 | ✗ | true := if not clearMatching then BackendDAEEXT.setAssignment(neqns, nvars, vec1, vec2) else true; | |
| 5584 | ✗ | (vec1,vec2,syst,shared,arg) := matchingExternal({},false,10,Config.getCheapMatchingAlgorithm(),if clearMatching then 1 else 0,isyst,ishared,nvars, neqns, vec1, vec2, inMatchingOptions, sssHandler, inArg); | |
| 5585 | ✗ | syst := BackendDAEUtil.setEqSystMatching(syst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 5586 | ✗ | then | |
| 5587 | (syst,shared,arg); | ||
| 5588 | // fail case if system is empty | ||
| 5589 | case _ | ||
| 5590 | algorithm | ||
| 5591 | ✗ | neqns := BackendDAEUtil.systemSize(isyst); | |
| 5592 | ✗ | nvars := BackendVariable.daenumVariables(isyst); | |
| 5593 | ✗ | false := intGt(nvars,0); | |
| 5594 | ✗ | false := intGt(neqns,0); | |
| 5595 | ✗ | vec1 := listArray({}); | |
| 5596 | ✗ | vec2 := listArray({}); | |
| 5597 | ✗ | syst := BackendDAEUtil.setEqSystMatching(isyst,BackendDAE.MATCHING(vec2,vec1,{})); | |
| 5598 | then | ||
| 5599 | (syst,ishared,inArg); | ||
| 5600 | else | ||
| 5601 | algorithm | ||
| 5602 | ✗ | if Flags.isSet(Flags.FAILTRACE) then | |
| 5603 | ✗ | Debug.trace("- Matching.PR_FIFO_FAIRExternal failed\n"); | |
| 5604 | end if; | ||
| 5605 | ✗ | then | |
| 5606 | fail(); | ||
| 5607 | end matchcontinue; | ||
| 5608 | end PR_FIFO_FAIRExternal; | ||
| 5609 | |||
| 5610 | protected function matchingExternal | ||
| 5611 | "function: matchingExternal, helper for external matching algorithms | ||
| 5612 | author: Frenkel TUD" | ||
| 5613 | input list<list<Integer>> meqns "Marked Equations for Index Reduction"; | ||
| 5614 | input Boolean internalCall "true if function is called from it self"; | ||
| 5615 | input Integer algIndx "Index of the algorithm, see BackendDAEEXT.matching"; | ||
| 5616 | input Integer cheapMatching "Method for cheap Matching"; | ||
| 5617 | input Integer clearMatching; | ||
| 5618 | input BackendDAE.EqSystem isyst; | ||
| 5619 | input BackendDAE.Shared ishared; | ||
| 5620 | input Integer nv; | ||
| 5621 | input Integer ne; | ||
| 5622 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 5623 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 5624 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 5625 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 5626 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 5627 | output array<Integer> outAss1; | ||
| 5628 | output array<Integer> outAss2; | ||
| 5629 | output BackendDAE.EqSystem osyst; | ||
| 5630 | output BackendDAE.Shared oshared; | ||
| 5631 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 5632 | algorithm | ||
| 5633 | 238029 | Error.checkCancel(); | |
| 5634 | (outAss1,outAss2,osyst,oshared,outArg):= | ||
| 5635 | match (meqns,internalCall,isyst,inMatchingOptions) | ||
| 5636 | local | ||
| 5637 | BackendDAE.AdjacencyMatrix m,mt, m1,m1t; | ||
| 5638 | Integer nv_1,ne_1,memsize; | ||
| 5639 | list<Integer> unmatched_eqs; | ||
| 5640 | list<list<Integer>> meqns1, comps; | ||
| 5641 | BackendDAE.StructurallySingularSystemHandlerArg arg,arg1; | ||
| 5642 | BackendDAE.EqSystem syst; | ||
| 5643 | BackendDAE.Shared shared; | ||
| 5644 | array<Integer> ass1_1,ass1_2,ass1_3,ass2_1,ass2_2,ass2_3; | ||
| 5645 | Boolean changed = false; | ||
| 5646 | case ({},true,_,_) | ||
| 5647 | then | ||
| 5648 | (ass1,ass2,isyst,ishared,inArg); | ||
| 5649 | case ({},false,BackendDAE.EQSYSTEM(m=SOME(m),mT=SOME(mt)),_) | ||
| 5650 | algorithm | ||
| 5651 | 119015 | matchingExternalsetAdjacencyMatrix(nv,ne,m); | |
| 5652 | 119015 | BackendDAEEXT.matching(nv,ne,algIndx,cheapMatching,1.0,clearMatching); | |
| 5653 | 119015 | BackendDAEEXT.getAssignment(ass1,ass2); | |
| 5654 | |||
| 5655 | /* | ||
| 5656 | ----------------------------------------- | ||
| 5657 | Try to transform analytical to structural | ||
| 5658 | singularities and destroy algebraic loops | ||
| 5659 | ----------------------------------------- | ||
| 5660 | */ | ||
| 5661 | |||
| 5662 | // flat-copy everything | ||
| 5663 | 119015 | (ass1_1, ass2_1) := (ass1, ass2); | |
| 5664 | 119015 | syst := isyst; | |
| 5665 | |||
| 5666 | /* check if index type is solvable and is unprocessed and if index reduction is activated */ | ||
| 5667 |
5/6✓ Branch 1 taken 119015 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 59375 times.
✓ Branch 5 taken 59640 times.
✓ Branch 7 taken 1510 times.
✓ Branch 8 taken 57865 times.
|
119015 | if (not Flags.getConfigBool(Flags.NO_ASSC)) and BackendDAEUtil.hasIndexTypeSolvableAndUnprocessedScalar(syst) and BackendDAEUtil.doIndexReduction(inMatchingOptions) then |
| 5668 | /* set the system to processed so that it gets analyzed only once */ | ||
| 5669 | 1510 | syst := BackendDAEUtil.setAnalyticalToStructuralProcessed(syst, true); | |
| 5670 | |||
| 5671 | /* create NORMAL() adjacency matrix for sorting first */ | ||
| 5672 | 1510 | (_, m1, _, _, _) := BackendDAEUtil.getAdjacencyMatrixScalar(isyst, BackendDAE.NORMAL(), NONE(), BackendDAEUtil.isInitializationDAE(ishared)); | |
| 5673 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1510 times.
|
3020 | comps := Sorting.Tarjan(m1, ass2_1); |
| 5674 | |||
| 5675 |
2/2✓ Branch 0 taken 37761 times.
✓ Branch 1 taken 1510 times.
|
39271 | for comp in comps loop |
| 5676 | 37761 | (ass1_1, ass2_1, syst, changed) := BackendDAEUtil.analyticalToStructuralSingularity(comp, ass1_1, ass2_1, syst, changed); | |
| 5677 | end for; | ||
| 5678 | |||
| 5679 | /* only do matching again if anything has changed */ | ||
| 5680 |
2/2✓ Branch 0 taken 108 times.
✓ Branch 1 taken 1402 times.
|
1510 | if changed then |
| 5681 | 108 | BackendDAEEXT.setAssignment(nv,ne,ass1_1,ass2_1); | |
| 5682 |
4/8✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 108 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 108 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 108 times.
|
108 | BackendDAE.EQSYSTEM(m=SOME(m),mT=SOME(mt)) := syst; |
| 5683 | 108 | matchingExternalsetAdjacencyMatrix(nv,ne,m); | |
| 5684 | /* Call with clearMatching = 0 to reuse old information */ | ||
| 5685 | 108 | BackendDAEEXT.matching(nv,ne,algIndx,cheapMatching,1.0,0); | |
| 5686 | 108 | BackendDAEEXT.getAssignment(ass1_1,ass2_1); | |
| 5687 | end if; | ||
| 5688 | |||
| 5689 | end if; | ||
| 5690 | |||
| 5691 | |||
| 5692 | /* get unmatched equations for index reduction */ | ||
| 5693 | 119015 | unmatched_eqs := getUnassigned(ne, ass1_1, {}); | |
| 5694 | |||
| 5695 |
3/4✓ Branch 1 taken 11 times.
✓ Branch 2 taken 119004 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 11 times.
|
119015 | if Flags.isSet(Flags.BLT_DUMP) and Flags.isSet(Flags.GRAPHML) then BackendDump.dumpBipartiteGraphEqSystem(isyst, ishared, "BeforMatching_"+intString(arrayLength(m))+"_unmatched "+intString(listLength(unmatched_eqs))); end if; |
| 5696 |
4/4✓ Branch 1 taken 11 times.
✓ Branch 2 taken 119004 times.
✓ Branch 3 taken 1 time.
✓ Branch 4 taken 10 times.
|
119015 | if Flags.isSet(Flags.BLT_DUMP) and not listEmpty(unmatched_eqs) then print("unmatched equations: "+stringDelimitList(List.map(unmatched_eqs,intString),", ")+"\n\n"); end if; |
| 5697 | |||
| 5698 | /* | ||
| 5699 | ------------------------------------- | ||
| 5700 | Check if Index Reduction is necessary | ||
| 5701 | ------------------------------------- | ||
| 5702 | */ | ||
| 5703 |
2/2✓ Branch 0 taken 118739 times.
✓ Branch 1 taken 276 times.
|
119015 | if listEmpty(unmatched_eqs) then |
| 5704 | 118739 | meqns1 := {}; | |
| 5705 | else | ||
| 5706 | // remove some edges which do not have to be traversed when finding the MSSS | ||
| 5707 | 276 | m1 := arrayCopy(m); | |
| 5708 | 276 | m1t := arrayCopy(mt); | |
| 5709 | 276 | (m1,m1t) := removeEdgesForNoDerivativeFunctionInputs(m1,m1t,syst,ishared); | |
| 5710 | 276 | (m1,m1t) := removeEdgesToDiscreteEquations(m1,m1t,syst,ishared); | |
| 5711 | |||
| 5712 | 276 | meqns1 := getEqnsforIndexReduction(unmatched_eqs,ne,m1,m1t,ass1_1,ass2_1,inArg); | |
| 5713 | end if; | ||
| 5714 | /* | ||
| 5715 | ----------------------------------------- | ||
| 5716 | remove artificial states which cause | ||
| 5717 | problems for differentiation | ||
| 5718 | ----------------------------------------- | ||
| 5719 | */ | ||
| 5720 |
2/2✓ Branch 0 taken 276 times.
✓ Branch 1 taken 118739 times.
|
119015 | if not listEmpty(meqns1) then |
| 5721 | 276 | (syst, meqns1, ass1_1, ass2_1) := sanityCheckArtificialStates(syst, ishared, nv, ne, meqns1, ass1_1, ass2_1, algIndx, cheapMatching, clearMatching, inArg); | |
| 5722 | else | ||
| 5723 | 118739 | (syst, meqns1, ass1_1, ass2_1) := (syst, meqns1, ass1_1, ass2_1); | |
| 5724 | end if; | ||
| 5725 |
4/4✓ Branch 1 taken 11 times.
✓ Branch 2 taken 119003 times.
✓ Branch 3 taken 1 time.
✓ Branch 4 taken 10 times.
|
119014 | if Flags.isSet(Flags.BLT_DUMP) and not listEmpty(meqns1) |
| 5726 | 1 | then print("Index Reduction neccessary!\n" | |
| 5727 | + "MSS subsets:\n " + stringDelimitList(List.map(meqns1,Util.intLstString),"\n ")+"\n\n"); | ||
| 5728 | end if; | ||
| 5729 | |||
| 5730 | //Debug information | ||
| 5731 | //if listLength(List.flatten(meqns1)) >= 5 then meqs_short = List.firstN(List.flatten(meqns1),5); else meqs_short = List.flatten(meqns1); end if; | ||
| 5732 | //BackendDump.dumpBipartiteGraphEqSystem(isyst,ishared,"MSSS_"+stringDelimitList(List.map(meqs_short,intString),"_")); | ||
| 5733 | 119288 | (ass1_1,ass2_1,syst,shared,arg) := matchingExternal(meqns1,true,algIndx,-1,0,syst,ishared,nv,ne,ass1_1,ass2_1,inMatchingOptions,sssHandler,inArg); | |
| 5734 | then | ||
| 5735 | (ass1_1,ass2_1,syst,shared,arg); | ||
| 5736 | case (_::_,_,_,(BackendDAE.INDEX_REDUCTION(),_)) | ||
| 5737 | algorithm | ||
| 5738 | memsize := arrayLength(ass1); | ||
| 5739 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 274 times.
|
274 | (_,_,syst,shared,ass2_1,ass1_1,arg) := sssHandler(meqns,0,isyst,ishared,ass2,ass1,inArg); |
| 5740 | 274 | ne_1 := BackendDAEUtil.systemSize(syst); | |
| 5741 | 274 | nv_1 := BackendVariable.daenumVariables(syst); | |
| 5742 | 274 | ass1_2 := assignmentsArrayExpand(ass1_1,ne_1,memsize,-1); | |
| 5743 | 274 | ass2_2 := assignmentsArrayExpand(ass2_1,nv_1,memsize,-1); | |
| 5744 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 274 times.
|
274 | true := BackendDAEEXT.setAssignment(ne_1,nv_1,ass1_2,ass2_2); |
| 5745 | 274 | (ass1_3,ass2_3,syst,shared,arg1) := matchingExternal({},false,algIndx,cheapMatching,clearMatching,syst,shared,nv_1,ne_1,ass1_2,ass2_2,inMatchingOptions,sssHandler,arg); | |
| 5746 | then | ||
| 5747 | (ass1_3,ass2_3,syst,shared,arg1); | ||
| 5748 | |||
| 5749 | else | ||
| 5750 | algorithm | ||
| 5751 | ✗ | singularSystemError(meqns,0,isyst,ishared,ass1,ass2,inArg); | |
| 5752 | ✗ | then | |
| 5753 | fail(); | ||
| 5754 | |||
| 5755 | end match; | ||
| 5756 | end matchingExternal; | ||
| 5757 | |||
| 5758 | protected function sanityCheckArtificialStates | ||
| 5759 | "author: kabdelhak 2019-09 FHB | ||
| 5760 | Checks if all equations that have to be differentiated for index reduction can | ||
| 5761 | be differentiated by all artificial states. Reverts all those for which we | ||
| 5762 | cannot derive to be algebraic variables. | ||
| 5763 | Ticket: 5459 | ||
| 5764 | ----------------------------- INFO ----------------------------- | ||
| 5765 | Artificial states are those which do not naturally appear | ||
| 5766 | differentiated in the system of DAEs, but have been forced | ||
| 5767 | to be states with 'StateSelect.always' or 'StateSelect.prefer'. | ||
| 5768 | ----------------------------------------------------------------" | ||
| 5769 | input output BackendDAE.EqSystem syst; | ||
| 5770 | input BackendDAE.Shared shared; | ||
| 5771 | input Integer nv; | ||
| 5772 | input Integer ne; | ||
| 5773 | input output list<list<Integer>> eqns; | ||
| 5774 | input output array<Integer> ass1; | ||
| 5775 | input output array<Integer> ass2; | ||
| 5776 | input Integer algIndx "Index of the algorithm, see BackendDAEEXT.matching"; | ||
| 5777 | input Integer cheapMatching "Method for cheap Matching"; | ||
| 5778 | input Integer clearMatching; | ||
| 5779 | input BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 5780 | protected | ||
| 5781 | list<list<Integer>> eqns_1, unassignedStates, unassignedEqns; | ||
| 5782 | list<Integer> flat_unassignedStates, flat_eqns, unmatched1, unassigned, preferStates; | ||
| 5783 | UnorderedSet<Integer> excessStates = UnorderedSet.new(Util.id, intEq); | ||
| 5784 | list<BackendDAE.Var> reverted = {}; | ||
| 5785 | Option<UnorderedSet<DAE.ComponentRef>> derCrefs = NONE(); | ||
| 5786 | UnorderedSet<DAE.ComponentRef> dcrs; | ||
| 5787 | BackendDAE.ConstraintEquations constraintEqns; | ||
| 5788 | Integer otherStates; | ||
| 5789 | array<Integer> scalarToArrayMap; | ||
| 5790 | list<BackendDAE.Var> artificialStates = {}, undiffable_artificial = {}; | ||
| 5791 | list<BackendDAE.Equation> equations = {}; | ||
| 5792 | list<tuple<BackendDAE.Equation, Option<list<DAE.Exp>>>> eqn_forms = {}; | ||
| 5793 | list<DAE.Exp> residual_exps; | ||
| 5794 | Option<list<DAE.Exp>> opt_exps; | ||
| 5795 | array<BackendDAE.Var> state_array; | ||
| 5796 | array<list<BackendDAE.Equation>> failed_eqns; | ||
| 5797 | UnorderedMap<DAE.ComponentRef, Integer> state_map; | ||
| 5798 | UnorderedSet<Integer> eqn_states; | ||
| 5799 | UnorderedSet<Integer> visited_states = UnorderedSet.new(Util.id, intEq); | ||
| 5800 | UnorderedSet<Integer> visited_eqns = UnorderedSet.new(Util.id, intEq); | ||
| 5801 | Integer arrayIdx, n_states; | ||
| 5802 | BackendDAE.Var var; | ||
| 5803 | BackendDAE.Equation form_eqn; | ||
| 5804 | DAE.ComponentRef cr; | ||
| 5805 | DAE.Exp residualExp, diffExp; | ||
| 5806 | BackendDAE.AdjacencyMatrix m, mt, m1, m1t; | ||
| 5807 | String msg; | ||
| 5808 | algorithm | ||
| 5809 | try | ||
| 5810 | // Get the information about MSSS from index reduction | ||
| 5811 | 276 | (eqns_1, unassignedStates, unassignedEqns, _) := IndexReduction.minimalStructurallySingularSystem(eqns, syst, shared, ass2, ass1, arg); | |
| 5812 | else | ||
| 5813 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
|
1 | if Flags.isSet(Flags.BLT_DUMP) then |
| 5814 | ✗ | singularSystemError(eqns, 0, syst, shared, ass1, ass2, arg); | |
| 5815 | end if; | ||
| 5816 | 1 | fail(); | |
| 5817 | end try; | ||
| 5818 | // A subset with more unassigned equations than states other than the | ||
| 5819 | // artificial prefer states turns some of those into dummy states anyway. | ||
| 5820 | // Before anything is differentiated, leave them algebraic instead. | ||
| 5821 | 275 | (_, constraintEqns, _, _, _) := arg; | |
| 5822 |
4/4✓ Branch 1 taken 179 times.
✓ Branch 2 taken 96 times.
✓ Branch 3 taken 1423 times.
✓ Branch 4 taken 275 times.
|
1973 | for states in if Array.all(constraintEqns, listEmpty) then unassignedStates else {} loop |
| 5823 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1423 times.
|
1423 | unassigned :: unassignedEqns := unassignedEqns; |
| 5824 | otherStates := 0; | ||
| 5825 | preferStates := {}; | ||
| 5826 |
2/2✓ Branch 0 taken 4398 times.
✓ Branch 1 taken 1423 times.
|
5821 | for state in states loop |
| 5827 | 4398 | var := BackendVariable.getVarAt(syst.orderedVars, state); | |
| 5828 |
4/4✓ Branch 1 taken 229 times.
✓ Branch 2 taken 4169 times.
✓ Branch 4 taken 208 times.
✓ Branch 5 taken 21 times.
|
4398 | if BackendVariable.isArtificialState(var) and BackendVariable.varStateSelectPrefer(var) then |
| 5829 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 208 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 169 times.
|
208 | if isNone(derCrefs) then |
| 5830 | 39 | derCrefs := SOME(derivedCrefs(syst, shared)); | |
| 5831 | end if; | ||
| 5832 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 208 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 208 times.
|
208 | SOME(dcrs) := derCrefs; |
| 5833 |
2/2✓ Branch 1 taken 35 times.
✓ Branch 2 taken 173 times.
|
208 | if UnorderedSet.contains(var.varName, dcrs) then |
| 5834 | 35 | otherStates := otherStates + 1; | |
| 5835 | else | ||
| 5836 | preferStates := state :: preferStates; | ||
| 5837 | end if; | ||
| 5838 | else | ||
| 5839 | 4190 | otherStates := otherStates + 1; | |
| 5840 | end if; | ||
| 5841 | end for; | ||
| 5842 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1419 times.
|
1423 | if listLength(unassigned) > otherStates then |
| 5843 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 4 times.
|
19 | for state in preferStates loop |
| 5844 |
1/2✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
|
15 | if UnorderedSet.add(state, excessStates) then |
| 5845 | 15 | var := BackendVariable.getVarAt(syst.orderedVars, state); | |
| 5846 | 15 | reverted := BackendVariable.setVarKind(var, BackendDAE.VARIABLE()) :: reverted; | |
| 5847 | end if; | ||
| 5848 | end for; | ||
| 5849 | end if; | ||
| 5850 | end for; | ||
| 5851 |
3/4✓ Branch 1 taken 1 time.
✓ Branch 2 taken 274 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 time.
|
275 | if Flags.isSet(Flags.BLT_DUMP) and not listEmpty(reverted) then |
| 5852 | ✗ | print(BackendDump.varListStringShort(reverted, "Artificial states that cannot all be states, treated as algebraic")); | |
| 5853 | end if; | ||
| 5854 | 275 | flat_unassignedStates := List.flatten(unassignedStates); | |
| 5855 | // Collect artificial states | ||
| 5856 |
2/2✓ Branch 0 taken 7620 times.
✓ Branch 1 taken 275 times.
|
7895 | for state in flat_unassignedStates loop |
| 5857 |
4/4✓ Branch 1 taken 7600 times.
✓ Branch 2 taken 20 times.
✓ Branch 4 taken 5279 times.
✓ Branch 5 taken 2321 times.
|
7620 | if not UnorderedSet.contains(state, excessStates) and UnorderedSet.add(state, visited_states) then |
| 5858 | 5279 | var := BackendVariable.getVarAt(syst.orderedVars, state); | |
| 5859 |
2/2✓ Branch 1 taken 957 times.
✓ Branch 2 taken 4322 times.
|
5279 | if BackendVariable.isArtificialState(var) then |
| 5860 | artificialStates := var :: artificialStates; | ||
| 5861 | end if; | ||
| 5862 | end if; | ||
| 5863 | end for; | ||
| 5864 |
4/4✓ Branch 0 taken 174 times.
✓ Branch 1 taken 101 times.
✓ Branch 2 taken 172 times.
✓ Branch 3 taken 2 times.
|
275 | if listEmpty(artificialStates) and listEmpty(reverted) then |
| 5865 | 172 | return; | |
| 5866 | end if; | ||
| 5867 | 103 | flat_eqns := List.flatten(eqns_1); // use eqns_1 (without discrete) | |
| 5868 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 103 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 103 times.
|
103 | SOME((_, scalarToArrayMap, _, _, _)) := syst.mapping; |
| 5869 |
2/2✓ Branch 0 taken 2472 times.
✓ Branch 1 taken 103 times.
|
2575 | for scalar_eqn in flat_eqns loop |
| 5870 | try | ||
| 5871 | 2472 | arrayIdx := scalarToArrayMap[scalar_eqn]; | |
| 5872 |
1/2✓ Branch 1 taken 2472 times.
✗ Branch 2 not taken.
|
2472 | if UnorderedSet.add(arrayIdx, visited_eqns) then |
| 5873 | 2472 | equations := BackendEquation.get(syst.orderedEqs, arrayIdx) :: equations; | |
| 5874 | end if; | ||
| 5875 | else | ||
| 5876 | // equation can't be found -- scalar index to array index failed? | ||
| 5877 | end try; | ||
| 5878 | end for; | ||
| 5879 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 103 times.
|
103 | state_array := listArray(artificialStates); |
| 5880 | 103 | n_states := arrayLength(state_array); | |
| 5881 | 103 | failed_eqns := arrayCreate(n_states, {}); | |
| 5882 | 103 | state_map := UnorderedMap.new<Integer>(ComponentReferenceBasics.hashComponentRef, | |
| 5883 | ComponentReferenceBasics.crefEqual, Util.nextPrime(n_states)); | ||
| 5884 |
2/2✓ Branch 0 taken 101 times.
✓ Branch 1 taken 2 times.
|
1060 | for i in 1:n_states loop |
| 5885 | 957 | UnorderedMap.add(BackendVariable.varCref(state_array[i]), i, state_map); | |
| 5886 | end for; | ||
| 5887 | // The residual form is state independent; an equation without one stays | ||
| 5888 | // undiffable for every artificial state. | ||
| 5889 |
2/2✓ Branch 0 taken 2472 times.
✓ Branch 1 taken 103 times.
|
2575 | for eqn in equations loop |
| 5890 | 2472 | Error.checkCancel(); | |
| 5891 | try | ||
| 5892 | 2472 | residual_exps := {}; | |
| 5893 |
2/2✓ Branch 1 taken 2472 times.
✓ Branch 2 taken 2472 times.
|
4944 | for res in BackendEquation.equationToScalarResidualForm(eqn, shared.functionTree) loop |
| 5894 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2472 times.
|
2472 | BackendDAE.RESIDUAL_EQUATION(exp = residualExp) := res; |
| 5895 | residual_exps := residualExp :: residual_exps; | ||
| 5896 | end for; | ||
| 5897 | 4944 | eqn_forms := (eqn, SOME(listReverse(residual_exps))) :: eqn_forms; | |
| 5898 | else | ||
| 5899 | ✗ | eqn_forms := (eqn, NONE()) :: eqn_forms; | |
| 5900 | end try; | ||
| 5901 | end for; | ||
| 5902 | // Look up the states an equation mentions instead of scanning all equations | ||
| 5903 | // for every state. | ||
| 5904 |
2/2✓ Branch 1 taken 2472 times.
✓ Branch 2 taken 103 times.
|
2575 | for form in listReverse(eqn_forms) loop |
| 5905 | 2472 | (form_eqn, opt_exps) := form; | |
| 5906 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 2472 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2472 times.
|
2472 | if isNone(opt_exps) then |
| 5907 | ✗ | for i in 1:n_states loop | |
| 5908 | ✗ | failed_eqns[i] := form_eqn :: failed_eqns[i]; | |
| 5909 | end for; | ||
| 5910 | else | ||
| 5911 | 2472 | SOME(residual_exps) := opt_exps; | |
| 5912 | 2472 | eqn_states := UnorderedSet.new(Util.id, intEq); | |
| 5913 |
2/2✓ Branch 0 taken 2472 times.
✓ Branch 1 taken 2472 times.
|
4944 | for res_exp in residual_exps loop |
| 5914 | 2472 | Expression.traverseExpTopDown(res_exp, function collectArtificialStates(stateMap = state_map, states = eqn_states), false); | |
| 5915 | end for; | ||
| 5916 |
2/2✓ Branch 1 taken 2715 times.
✓ Branch 2 taken 2472 times.
|
5187 | for i in UnorderedSet.toList(eqn_states) loop |
| 5917 | 2715 | Error.checkCancel(); | |
| 5918 | 2715 | cr := BackendVariable.varCref(state_array[i]); | |
| 5919 | try | ||
| 5920 |
2/2✓ Branch 0 taken 2715 times.
✓ Branch 1 taken 2698 times.
|
5413 | for res_exp in residual_exps loop |
| 5921 | // Only check if the equation actually contains the cref | ||
| 5922 |
1/2✓ Branch 1 taken 2715 times.
✗ Branch 2 not taken.
|
2715 | if Expression.expHasCref(res_exp, cr) then |
| 5923 | // Check if the equation can be differentiated by the artificial state | ||
| 5924 | 2715 | (diffExp,_,_) := Inline.forceInlineExp(res_exp,(SOME(shared.functionTree),{DAE.NORM_INLINE(),DAE.DEFAULT_INLINE()}),DAE.emptyElementSource,Ceval.cevalSimpleWithFunctionTreeReturnExp); | |
| 5925 | 2715 | diffExp := Expression.replaceDerOpInExp(diffExp); | |
| 5926 | 2715 | Differentiate.differentiateExpSolve(diffExp, cr, SOME(shared.functionTree)); | |
| 5927 | // Check if the equation contains smooth(0, cr) | ||
| 5928 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2698 times.
|
2698 | false := Expression.expHasCrefInSmoothZero(diffExp, cr); |
| 5929 | end if; | ||
| 5930 | end for; | ||
| 5931 | else | ||
| 5932 | 34 | failed_eqns[i] := form_eqn :: failed_eqns[i]; | |
| 5933 | end try; | ||
| 5934 | end for; | ||
| 5935 | end if; | ||
| 5936 | end for; | ||
| 5937 |
2/2✓ Branch 0 taken 101 times.
✓ Branch 1 taken 2 times.
|
1060 | for i in 1:n_states loop |
| 5938 |
2/2✓ Branch 1 taken 17 times.
✓ Branch 2 taken 940 times.
|
957 | if not listEmpty(failed_eqns[i]) then |
| 5939 | 17 | var := state_array[i]; | |
| 5940 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
|
17 | if Flags.isSet(Flags.BLT_DUMP) then |
| 5941 | ✗ | for eqn in listReverse(failed_eqns[i]) loop | |
| 5942 | ✗ | print("### The Equation ### \n" + BackendDump.equationString(eqn) + | |
| 5943 | "\n\n--- could not be differentiated for artificial variable ---\n " + | ||
| 5944 | ComponentReferenceBasics.printComponentRefStr(var.varName) + ".\n\n"); | ||
| 5945 | end for; | ||
| 5946 | end if; | ||
| 5947 | // revert the varKind from STATE to VARIABLE | ||
| 5948 | 17 | undiffable_artificial := BackendVariable.setVarKind(var, BackendDAE.VARIABLE()) :: undiffable_artificial; | |
| 5949 | end if; | ||
| 5950 | end for; | ||
| 5951 | |||
| 5952 |
4/4✓ Branch 0 taken 100 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 97 times.
✓ Branch 3 taken 3 times.
|
103 | if not (listEmpty(undiffable_artificial) and listEmpty(reverted)) then |
| 5953 | 6 | syst.orderedVars := BackendVariable.addVars(listAppend(reverted, undiffable_artificial), syst.orderedVars); | |
| 5954 | 6 | (syst, _, _, _, _) := BackendDAEUtil.getAdjacencyMatrixScalar(syst, BackendDAE.SOLVABLE(), SOME(shared.functionTree), BackendDAEUtil.isInitializationDAE(shared)); | |
| 5955 | |||
| 5956 |
4/8✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
|
6 | if isSome(syst.m) and isSome(syst.mT) then |
| 5957 | 6 | SOME(m) := syst.m; | |
| 5958 | 6 | SOME(mt) := syst.mT; | |
| 5959 | // It would be great to replace full matching by continue matching, | ||
| 5960 | // to reuse old information, but somehow it does something different. | ||
| 5961 | // (ass1, ass2) := ContinueMatching(m, nv, ne, ass1, ass2); | ||
| 5962 | 6 | matchingExternalsetAdjacencyMatrix(nv, ne, m); | |
| 5963 | 6 | BackendDAEEXT.matching(nv, ne, algIndx, cheapMatching, 1.0, clearMatching); | |
| 5964 | 6 | BackendDAEEXT.getAssignment(ass1, ass2); | |
| 5965 | 6 | unmatched1 := getUnassigned(ne, ass1, {}); | |
| 5966 | 6 | m1 := arrayCopy(m); | |
| 5967 | 6 | m1t := arrayCopy(mt); | |
| 5968 | 6 | (m1,m1t) := removeEdgesForNoDerivativeFunctionInputs(m1, m1t, syst, shared); | |
| 5969 | 6 | (m1,m1t) := removeEdgesToDiscreteEquations(m1, m1t, syst, shared); | |
| 5970 | 6 | eqns := getEqnsforIndexReduction(unmatched1, ne, m1, m1t, ass1, ass2, arg); | |
| 5971 | end if; | ||
| 5972 | |||
| 5973 |
1/4✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
6 | if Flags.isSet(Flags.BLT_DUMP) and not listEmpty(undiffable_artificial) then |
| 5974 | ✗ | print("----------------------------- INFO -----------------------------\n" + | |
| 5975 | " Artificial states are those which do not naturally appear\n" + | ||
| 5976 | " differentiated in the system of DAEs, but have been forced\n" + | ||
| 5977 | " to be states with 'StateSelect.always' or 'StateSelect.prefer'.\n" + | ||
| 5978 | " The ones mentioned above will be treated as if they had \n" + | ||
| 5979 | "'StateSelect.default'.\n" + | ||
| 5980 | "----------------------------------------------------------------\n\n"); | ||
| 5981 | end if; | ||
| 5982 | |||
| 5983 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
|
6 | if not listEmpty(undiffable_artificial) then |
| 5984 | 3 | msg := BackendDump.varListStringShort(undiffable_artificial,"They will be treated as if they had stateSelect=StateSelect.default") + | |
| 5985 | "Please use -d=bltdump for more information.\n"; | ||
| 5986 | 3 | Error.addMessage(Error.STATE_STATESELECT_PREFER_REVERT, {msg}); | |
| 5987 | end if; | ||
| 5988 | end if; | ||
| 5989 | end sanityCheckArtificialStates; | ||
| 5990 | |||
| 5991 | protected function derivedCrefs | ||
| 5992 | "Returns the crefs that occur differentiated in the equations or the initial | ||
| 5993 | equations, and the crefs that are the derivative of a state." | ||
| 5994 | input BackendDAE.EqSystem syst; | ||
| 5995 | input BackendDAE.Shared shared; | ||
| 5996 | output UnorderedSet<DAE.ComponentRef> crefs = UnorderedSet.new(ComponentReferenceBasics.hashComponentRef, ComponentReferenceBasics.crefEqual); | ||
| 5997 | algorithm | ||
| 5998 | 39 | BackendDAEUtil.traverseBackendDAEExpsEqns(syst.orderedEqs, Expression.traverseSubexpressionsHelper, (collectDerCref, crefs)); | |
| 5999 | 39 | BackendDAEUtil.traverseBackendDAEExpsEqns(BackendEquation.getInitialEqnsFromShared(shared), Expression.traverseSubexpressionsHelper, (collectDerCref, crefs)); | |
| 6000 |
2/2✓ Branch 1 taken 4066 times.
✓ Branch 2 taken 39 times.
|
4105 | for var in BackendVariable.varList(syst.orderedVars) loop |
| 6001 | () := match var.varKind | ||
| 6002 | local | ||
| 6003 | DAE.ComponentRef cr; | ||
| 6004 | case BackendDAE.STATE(derName = SOME(cr)) | ||
| 6005 | algorithm | ||
| 6006 | 171 | UnorderedSet.add(cr, crefs); | |
| 6007 | then (); | ||
| 6008 | else (); | ||
| 6009 | end match; | ||
| 6010 | end for; | ||
| 6011 | end derivedCrefs; | ||
| 6012 | |||
| 6013 | protected function collectDerCref | ||
| 6014 | input output DAE.Exp exp; | ||
| 6015 | input output UnorderedSet<DAE.ComponentRef> crefs; | ||
| 6016 | algorithm | ||
| 6017 | () := match exp | ||
| 6018 | local | ||
| 6019 | DAE.ComponentRef cr; | ||
| 6020 | case DAE.CALL(path = Absyn.IDENT("der"), expLst = {DAE.CREF(componentRef = cr)}) | ||
| 6021 | algorithm | ||
| 6022 | 407 | UnorderedSet.add(cr, crefs); | |
| 6023 | then (); | ||
| 6024 | else (); | ||
| 6025 | end match; | ||
| 6026 | end collectDerCref; | ||
| 6027 | |||
| 6028 | protected function collectArtificialStates | ||
| 6029 | "Collects the indices of the artificial states occurring in the expression. | ||
| 6030 | Mirrors Expression.expHasCref, which does not look inside pre()." | ||
| 6031 | input DAE.Exp exp; | ||
| 6032 | input Boolean arg; | ||
| 6033 | input UnorderedMap<DAE.ComponentRef, Integer> stateMap; | ||
| 6034 | input UnorderedSet<Integer> states; | ||
| 6035 | output DAE.Exp outExp = exp; | ||
| 6036 | output Boolean cont; | ||
| 6037 | output Boolean outArg = arg; | ||
| 6038 | protected | ||
| 6039 | Integer index; | ||
| 6040 | algorithm | ||
| 6041 | cont := match exp | ||
| 6042 | case DAE.CALL(path = Absyn.IDENT("pre")) then false; | ||
| 6043 | case DAE.CREF() | ||
| 6044 | algorithm | ||
| 6045 | () := match UnorderedMap.get(exp.componentRef, stateMap) | ||
| 6046 | 3776 | case SOME(index) algorithm UnorderedSet.add(index, states); then (); | |
| 6047 | else (); | ||
| 6048 | end match; | ||
| 6049 | then true; | ||
| 6050 | else true; | ||
| 6051 | end match; | ||
| 6052 | end collectArtificialStates; | ||
| 6053 | |||
| 6054 | protected function removeEdgesToDiscreteEquations"" | ||
| 6055 | input BackendDAE.AdjacencyMatrix m; | ||
| 6056 | input BackendDAE.AdjacencyMatrixT mt; | ||
| 6057 | input BackendDAE.EqSystem sys; | ||
| 6058 | input BackendDAE.Shared shared; | ||
| 6059 | output BackendDAE.AdjacencyMatrix mOut; | ||
| 6060 | output BackendDAE.AdjacencyMatrixT mtOut; | ||
| 6061 | protected | ||
| 6062 | Boolean isDiscrete; | ||
| 6063 | Integer idx, idx2, size, varIdx; | ||
| 6064 | list<Integer> varIdxs, eqIdxs; | ||
| 6065 | BackendDAE.EquationArray eqs; | ||
| 6066 | BackendDAE.Variables vars; | ||
| 6067 | list<BackendDAE.Var> varLst; | ||
| 6068 | array<list<Integer>> eqIdxArray; | ||
| 6069 | UnorderedSet<Integer> idxSet; | ||
| 6070 | algorithm | ||
| 6071 | 282 | vars := sys.orderedVars; | |
| 6072 | 282 | eqs := sys.orderedEqs; | |
| 6073 | idx := 1; | ||
| 6074 | idx2 := 0; | ||
| 6075 | 282 | eqIdxArray := arrayCreate(BackendEquation.getNumberOfEquations(eqs), {}); | |
| 6076 | //algorithms with size>n occur as n single nodes in the adjacency matrix, delete the rows for each of them | ||
| 6077 |
2/2✓ Branch 1 taken 53096 times.
✓ Branch 2 taken 282 times.
|
53378 | for eq in BackendEquation.equationList(eqs) loop |
| 6078 | 53096 | size := BackendEquation.equationSize(BackendEquation.get(eqs, idx)); | |
| 6079 | 53096 | eqIdxs := List.map1(List.intRange(size),intAdd,idx2); | |
| 6080 | 53096 | arrayUpdate(eqIdxArray, idx, eqIdxs); | |
| 6081 | 53096 | idx := idx+1; | |
| 6082 | 53096 | idx2 := size+idx2; | |
| 6083 | end for; | ||
| 6084 | idx := 1; | ||
| 6085 |
2/2✓ Branch 1 taken 53096 times.
✓ Branch 2 taken 282 times.
|
53378 | for eq in BackendEquation.equationList(eqs) loop |
| 6086 | 53096 | Error.checkCancel(); | |
| 6087 | //print("Check equation "+BackendDump.equationString(eq)+"\n"); | ||
| 6088 | 53096 | isDiscrete := BackendEquation.isWhenEquationOrDiscreteAlgorithm(eq,vars); | |
| 6089 |
2/2✓ Branch 0 taken 66 times.
✓ Branch 1 taken 53030 times.
|
53096 | if isDiscrete then |
| 6090 | 66 | varLst := BackendEquation.equationVars(eq,vars); | |
| 6091 | |||
| 6092 | 66 | varIdxs := BackendVariable.getVarIndexFromVars(varLst,vars); | |
| 6093 | 66 | eqIdxs := eqIdxArray[idx]; | |
| 6094 | //print("remove edges between eqs: "+stringDelimitList(List.map(eqIdxs,intString),", ")+" and vars "+stringDelimitList(List.map(varIdxs,intString),", ")+"\n"); | ||
| 6095 | //update m | ||
| 6096 | 66 | idxSet := UnorderedSet.fromList(varIdxs, Util.id, intEq); | |
| 6097 |
2/2✓ Branch 0 taken 91 times.
✓ Branch 1 taken 66 times.
|
157 | for e in eqIdxs loop |
| 6098 | 91 | arrayUpdate(m, e, UnorderedSet.difference_list_set(m[e], varIdxs, idxSet)); | |
| 6099 | end for; | ||
| 6100 | //update mt | ||
| 6101 | 66 | idxSet := UnorderedSet.fromList(eqIdxs, Util.id, intEq); | |
| 6102 |
2/2✓ Branch 0 taken 187 times.
✓ Branch 1 taken 66 times.
|
253 | for varIdx in varIdxs loop |
| 6103 | 187 | arrayUpdate(mt, varIdx, UnorderedSet.difference_list_set(mt[varIdx], eqIdxs, idxSet)); | |
| 6104 | end for; | ||
| 6105 | end if; | ||
| 6106 | 53096 | idx := idx+1; | |
| 6107 | end for; | ||
| 6108 | mOut := m; | ||
| 6109 | mtOut := mt; | ||
| 6110 | end removeEdgesToDiscreteEquations; | ||
| 6111 | |||
| 6112 | protected function removeEdgesForNoDerivativeFunctionInputs"when gathering the minimal structurally singular subsets from the unmatches equations, | ||
| 6113 | some edges dont have to be considered e.g. edges between a function call and an input variable if the input variable will not be derived when deriving the function | ||
| 6114 | author: Waurich TUD 10-2015" | ||
| 6115 | input BackendDAE.AdjacencyMatrix m; | ||
| 6116 | input BackendDAE.AdjacencyMatrixT mt; | ||
| 6117 | input BackendDAE.EqSystem sys; | ||
| 6118 | input BackendDAE.Shared shared; | ||
| 6119 | output BackendDAE.AdjacencyMatrix mOut; | ||
| 6120 | output BackendDAE.AdjacencyMatrixT mtOut; | ||
| 6121 | protected | ||
| 6122 | Boolean hasNoDerAnno; | ||
| 6123 | Integer idx, varIdx; | ||
| 6124 | list<Integer> varIdxs, row; | ||
| 6125 | BackendDAE.EquationArray eqs; | ||
| 6126 | BackendDAE.Variables vars; | ||
| 6127 | AvlTreePathFunction.Tree functionTree; | ||
| 6128 | list<DAE.ComponentRef> noDerInputs; | ||
| 6129 | algorithm | ||
| 6130 | 282 | vars := sys.orderedVars; | |
| 6131 | 282 | eqs := sys.orderedEqs; | |
| 6132 | 282 | functionTree := shared.functionTree; | |
| 6133 | idx := 1; | ||
| 6134 |
2/2✓ Branch 1 taken 53096 times.
✓ Branch 2 taken 282 times.
|
53378 | for eq in BackendEquation.equationList(eqs) loop |
| 6135 | 53096 | Error.checkCancel(); | |
| 6136 | 53096 | (hasNoDerAnno,noDerInputs) := BackendDAEUtil.isFuncCallWithNoDerAnnotation(eq,functionTree); | |
| 6137 |
2/2✓ Branch 0 taken 8471 times.
✓ Branch 1 taken 44625 times.
|
53096 | if hasNoDerAnno then |
| 6138 | 8471 | (_,varIdxs) := BackendVariable.getVarLst(noDerInputs,vars); | |
| 6139 | //print("remove edges between eq: "+intString(idx)+" and vars "+stringDelimitList(List.map(varIdxs,intString),", ")+"\n"); | ||
| 6140 | //update m | ||
| 6141 | 8471 | row := m[idx]; | |
| 6142 | 8471 | row := UnorderedSet.difference_list(row,varIdxs,Util.id,intEq); | |
| 6143 | 8471 | arrayUpdate(m,idx,row); | |
| 6144 | //update mt | ||
| 6145 |
2/2✓ Branch 0 taken 61093 times.
✓ Branch 1 taken 8471 times.
|
69564 | for varIdx in varIdxs loop |
| 6146 | 61093 | row := arrayGet(mt,varIdx); | |
| 6147 | 61093 | row := List.deleteMemberOnTrue(idx,row,intEq); | |
| 6148 | 61093 | arrayUpdate(mt,varIdx,row); | |
| 6149 | end for; | ||
| 6150 | end if; | ||
| 6151 | 53096 | idx := idx+1; | |
| 6152 | end for; | ||
| 6153 | mOut := m; | ||
| 6154 | mtOut := mt; | ||
| 6155 | end removeEdgesForNoDerivativeFunctionInputs; | ||
| 6156 | |||
| 6157 | protected function countadjacencyMatrixEntries | ||
| 6158 | input Integer n; | ||
| 6159 | input BackendDAE.AdjacencyMatrix m; | ||
| 6160 | output Integer outCount = 0; | ||
| 6161 | algorithm | ||
| 6162 |
2/2✓ Branch 0 taken 1028 times.
✓ Branch 1 taken 119945 times.
|
1223124 | for i in 1:n loop |
| 6163 |
2/2✓ Branch 1 taken 5328435 times.
✓ Branch 2 taken 1102151 times.
|
6430586 | for e in m[i] loop |
| 6164 |
2/2✓ Branch 0 taken 5125299 times.
✓ Branch 1 taken 203136 times.
|
5328435 | if intGt(e,0) then |
| 6165 | 5125299 | outCount := outCount + 1; | |
| 6166 | end if; | ||
| 6167 | end for; | ||
| 6168 | end for; | ||
| 6169 | end countadjacencyMatrixEntries; | ||
| 6170 | |||
| 6171 | public function matchingExternalsetAdjacencyMatrix | ||
| 6172 | "author: Frenkel TUD 2012-04 | ||
| 6173 | " | ||
| 6174 | input Integer nv; | ||
| 6175 | input Integer ne; | ||
| 6176 | input array<list<Integer>> m; | ||
| 6177 | protected | ||
| 6178 | Integer nz; | ||
| 6179 | algorithm | ||
| 6180 | 120973 | nz := countadjacencyMatrixEntries(ne,m); | |
| 6181 | 120973 | BackendDAEEXT.setAdjacencyMatrix(nv,ne,nz,m); | |
| 6182 | end matchingExternalsetAdjacencyMatrix; | ||
| 6183 | |||
| 6184 | // ============================================================================= | ||
| 6185 | // Util Functions | ||
| 6186 | // | ||
| 6187 | // ============================================================================= | ||
| 6188 | |||
| 6189 | public function reachableEquations "author: lochel | ||
| 6190 | Returns a list of reachable nodes (equations), corresponding | ||
| 6191 | to those equations that uses the solved variable of this equation. | ||
| 6192 | The edges of the graph that identifies strong components/blocks are | ||
| 6193 | dependencies between blocks. A directed edge e = (n1, n2) means | ||
| 6194 | that n1 solves for a variable (e.g. \'a\') that is used in the equation | ||
| 6195 | of n2, i.e. the equation of n1 must be solved before the equation of n2." | ||
| 6196 | input Integer eqn; | ||
| 6197 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 6198 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 6199 | output list<Integer> outEqNodes; | ||
| 6200 | protected | ||
| 6201 | Integer var; | ||
| 6202 | algorithm | ||
| 6203 | ✗ | var := ass2[eqn] "get the variable that is solved in given equation"; | |
| 6204 | ✗ | outEqNodes := if var > 0 then list(e for e guard(e > 0 and e <> eqn) in mT[var]) else {} "get the equations that depend on that variable"; | |
| 6205 | end reachableEquations; | ||
| 6206 | |||
| 6207 | public function incomingEquations "author: lochel | ||
| 6208 | Returns a list of incoming nodes (equations), corresponding | ||
| 6209 | to those variables that occur in this equation." | ||
| 6210 | input Integer eqn; | ||
| 6211 | input BackendDAE.AdjacencyMatrix m; | ||
| 6212 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 6213 | output list<Integer> outEqNodes; | ||
| 6214 | algorithm | ||
| 6215 |
10/10✓ Branch 1 taken 819280 times.
✓ Branch 2 taken 31261 times.
✓ Branch 4 taken 393887 times.
✓ Branch 5 taken 425393 times.
✓ Branch 6 taken 1418 times.
✓ Branch 7 taken 392469 times.
✓ Branch 8 taken 850541 times.
✓ Branch 9 taken 425393 times.
✓ Branch 10 taken 392469 times.
✓ Branch 11 taken 425393 times.
|
1275934 | outEqNodes := list(ass1[var] for var guard(var > 0 and ass1[var] <> eqn and ass1[var] > 0) in m[eqn]); |
| 6216 | end incomingEquations; | ||
| 6217 | |||
| 6218 | public function isAssigned | ||
| 6219 | "author: Frenkel TUD 2012-05" | ||
| 6220 | input array<Integer> ass; | ||
| 6221 | input Integer i; | ||
| 6222 | output Boolean b; | ||
| 6223 | algorithm | ||
| 6224 | 188 | b := intGt(ass[intAbs(i)],0); | |
| 6225 | end isAssigned; | ||
| 6226 | |||
| 6227 | public function isUnAssigned | ||
| 6228 | "author: Frenkel TUD 2012-05" | ||
| 6229 | input array<Integer> ass; | ||
| 6230 | input Integer i; | ||
| 6231 | output Boolean b; | ||
| 6232 | algorithm | ||
| 6233 | 45195 | b := intLt(ass[intAbs(i)],1); | |
| 6234 | end isUnAssigned; | ||
| 6235 | |||
| 6236 | public function getMarked | ||
| 6237 | "author: Frenkel TUD 2012-05" | ||
| 6238 | input Integer ne; | ||
| 6239 | input Integer mark; | ||
| 6240 | input array<Integer> markArr; | ||
| 6241 | input list<Integer> iMarked; | ||
| 6242 | output list<Integer> oMarked; | ||
| 6243 | algorithm | ||
| 6244 | oMarked := match ne | ||
| 6245 | local | ||
| 6246 | list<Integer> marked; | ||
| 6247 | case 0 | ||
| 6248 | then | ||
| 6249 | iMarked; | ||
| 6250 | case _ | ||
| 6251 | algorithm | ||
| 6252 | ✗ | marked := List.consOnTrue(intEq(markArr[ne],mark), ne, iMarked); | |
| 6253 | ✗ | then | |
| 6254 | getMarked(ne-1,mark,markArr,marked); | ||
| 6255 | end match; | ||
| 6256 | end getMarked; | ||
| 6257 | |||
| 6258 | public function getUnassigned "author: Frenkel TUD 2012-05 | ||
| 6259 | return all Indices with ass[indx]<1, traverses the | ||
| 6260 | array from the ne element to the first." | ||
| 6261 | input Integer ne; | ||
| 6262 | input array<Integer> ass; | ||
| 6263 | input list<Integer> inUnassigned; | ||
| 6264 | output list<Integer> outUnassigned; | ||
| 6265 | algorithm | ||
| 6266 | outUnassigned := match ne | ||
| 6267 | local | ||
| 6268 | list<Integer> unassigned; | ||
| 6269 | case 0 | ||
| 6270 | then | ||
| 6271 | inUnassigned; | ||
| 6272 | case _ | ||
| 6273 | algorithm | ||
| 6274 | 988351 | unassigned := List.consOnTrue(intLt(ass[ne],1), ne, inUnassigned); | |
| 6275 | 988351 | then | |
| 6276 | getUnassigned(ne-1,ass,unassigned); | ||
| 6277 | end match; | ||
| 6278 | end getUnassigned; | ||
| 6279 | |||
| 6280 | public function anyUnassigned | ||
| 6281 | "author: kabdelhak FHB 2019-08 | ||
| 6282 | returns true if any assignment is -1." | ||
| 6283 | input Integer ne; | ||
| 6284 | input array<Integer> ass; | ||
| 6285 | output Boolean b; | ||
| 6286 | algorithm | ||
| 6287 | b := match ne | ||
| 6288 | local | ||
| 6289 | case 0 | ||
| 6290 | then false; | ||
| 6291 | case _ guard(intLt(ass[ne],1)) | ||
| 6292 | then true; | ||
| 6293 | 112 | else anyUnassigned(ne-1,ass); | |
| 6294 | end match; | ||
| 6295 | end anyUnassigned; | ||
| 6296 | |||
| 6297 | public function getAssignedArray "author: lochel" | ||
| 6298 | input array<Integer> ass; | ||
| 6299 | output array<Boolean> outIsAssigned; | ||
| 6300 | protected | ||
| 6301 | Integer N = arrayLength(ass); | ||
| 6302 | algorithm | ||
| 6303 | ✗ | outIsAssigned := arrayCreate(N, false); | |
| 6304 | ✗ | for i in 1:N loop | |
| 6305 | ✗ | if ass[i] > 0 then | |
| 6306 | ✗ | arrayUpdate(outIsAssigned, i, true); | |
| 6307 | end if; | ||
| 6308 | end for; | ||
| 6309 | end getAssignedArray; | ||
| 6310 | |||
| 6311 | public function getAssigned | ||
| 6312 | "author: Frenkel TUD 2012-05 | ||
| 6313 | return all Indixes with ass[indx]>0, traverses the | ||
| 6314 | array from the ne element to the first." | ||
| 6315 | input Integer ne; | ||
| 6316 | input array<Integer> ass; | ||
| 6317 | input list<Integer> inAssigned; | ||
| 6318 | output list<Integer> outAssigned; | ||
| 6319 | algorithm | ||
| 6320 | outAssigned := match ne | ||
| 6321 | local | ||
| 6322 | list<Integer> assigned; | ||
| 6323 | case 0 | ||
| 6324 | then | ||
| 6325 | inAssigned; | ||
| 6326 | case _ | ||
| 6327 | algorithm | ||
| 6328 | 6622 | assigned := List.consOnTrue(intGt(ass[ne],0), ne, inAssigned); | |
| 6329 | 6622 | then | |
| 6330 | getAssigned(ne-1,ass,assigned); | ||
| 6331 | end match; | ||
| 6332 | end getAssigned; | ||
| 6333 | |||
| 6334 | public function getEqnsforIndexReduction | ||
| 6335 | "function getEqnsforIndexReduction, collect all equations for the index reduction from a given set of | ||
| 6336 | unmatched equations | ||
| 6337 | author: Frenkel TUD 2012-04" | ||
| 6338 | input list<Integer> U; | ||
| 6339 | input Integer neqns; | ||
| 6340 | input BackendDAE.AdjacencyMatrix m "m[eqnindx] = list(varindx)"; | ||
| 6341 | input BackendDAE.AdjacencyMatrixT mT "mT[varindx] = list(eqnindx)"; | ||
| 6342 | input array<Integer> ass1 "ass[eqnindx]=varindx"; | ||
| 6343 | input array<Integer> ass2 "ass[varindx]=eqnindx"; | ||
| 6344 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 6345 | output list<list<Integer>> eqns; | ||
| 6346 | algorithm | ||
| 6347 | eqns := match(U, inArg) | ||
| 6348 | local | ||
| 6349 | Integer lengthU; | ||
| 6350 | array<Integer> colummarks; | ||
| 6351 | array<list<Integer>> mapEqnIncRow,subsets; | ||
| 6352 | array<Integer> mapIncRowEqn; | ||
| 6353 | case({}, _) then {}; | ||
| 6354 | case(_, (_,_,mapEqnIncRow,mapIncRowEqn,_)) | ||
| 6355 | algorithm | ||
| 6356 | 283 | colummarks := arrayCreate(neqns,-1); | |
| 6357 | 283 | lengthU := listLength(U); | |
| 6358 | 283 | subsets := arrayCreate(lengthU,{}) "maximal number of subsets is each unassigned eqn has its own"; | |
| 6359 | 283 | subsets := getEqnsforIndexReduction1(U,m,mT,1,colummarks,ass1,ass2,mapEqnIncRow,mapIncRowEqn,subsets); | |
| 6360 | // remove empty subsets | ||
| 6361 | 283 | then | |
| 6362 | removeEmptySubsets(1,lengthU,subsets,{}); | ||
| 6363 | end match; | ||
| 6364 | end getEqnsforIndexReduction; | ||
| 6365 | |||
| 6366 | protected function removeEmptySubsets | ||
| 6367 | input Integer index; | ||
| 6368 | input Integer length; | ||
| 6369 | input array<list<Integer>> subsets; | ||
| 6370 | input list<list<Integer>> iAcc; | ||
| 6371 | output list<list<Integer>> oAcc; | ||
| 6372 | algorithm | ||
| 6373 | oAcc := match iAcc | ||
| 6374 | local | ||
| 6375 | list<Integer> eqns; | ||
| 6376 | list<list<Integer>> acc; | ||
| 6377 | case _ | ||
| 6378 | guard intLe(index,length) | ||
| 6379 | algorithm | ||
| 6380 | 2905 | eqns := subsets[index]; | |
| 6381 | 2905 | acc := appendNonEmpty(eqns,iAcc); | |
| 6382 | 2905 | then | |
| 6383 | removeEmptySubsets(index+1,length,subsets,acc); | ||
| 6384 | else iAcc; | ||
| 6385 | end match; | ||
| 6386 | end removeEmptySubsets; | ||
| 6387 | |||
| 6388 | protected function appendNonEmpty | ||
| 6389 | input list<Integer> eqns; | ||
| 6390 | input list<list<Integer>> iAcc; | ||
| 6391 | output list<list<Integer>> oAcc; | ||
| 6392 | algorithm | ||
| 6393 | oAcc := match eqns | ||
| 6394 | case {} then iAcc; | ||
| 6395 | else eqns::iAcc; | ||
| 6396 | end match; | ||
| 6397 | end appendNonEmpty; | ||
| 6398 | |||
| 6399 | protected function getEqnsforIndexReduction1 | ||
| 6400 | "function getEqnsforIndexReduction1, helper for getEqnsforIndexReduction | ||
| 6401 | author: Frenkel TUD 2012-04" | ||
| 6402 | input list<Integer> U; | ||
| 6403 | input BackendDAE.AdjacencyMatrix m "m[eqnindx] = list(varindx)"; | ||
| 6404 | input BackendDAE.AdjacencyMatrixT mT "mT[varindx] = list(eqnindx)"; | ||
| 6405 | input Integer mark; | ||
| 6406 | input array<Integer> colummarks; | ||
| 6407 | input array<Integer> ass1 "ass[eqnindx]=varindx"; | ||
| 6408 | input array<Integer> ass2 "ass[varindx]=eqnindx"; | ||
| 6409 | input array<list<Integer>> mapEqnIncRow "eqn indx -> skalar Eqn indexes"; | ||
| 6410 | input array<Integer> mapIncRowEqn "scalar eqn index -> eqn indx"; | ||
| 6411 | input array<list<Integer>> inSubsets; | ||
| 6412 | output array<list<Integer>> outSubsets; | ||
| 6413 | algorithm | ||
| 6414 | outSubsets:= match U | ||
| 6415 | local | ||
| 6416 | list<Integer> rest,eqns; | ||
| 6417 | Integer e,e1; | ||
| 6418 | case {} then inSubsets; | ||
| 6419 | case e::rest | ||
| 6420 | guard not intGt(colummarks[e],0) | ||
| 6421 | algorithm | ||
| 6422 | 2905 | Error.checkCancel(); | |
| 6423 | // row is not visited | ||
| 6424 | // if it is a multi dim equation take all scalare equations | ||
| 6425 | 2905 | e1 := mapIncRowEqn[e]; | |
| 6426 | 2905 | eqns := mapEqnIncRow[e1]; | |
| 6427 | 2905 | List.fold1r(eqns,arrayUpdate,mark,colummarks); | |
| 6428 | // print("Seach for unassigned Eqns " + stringDelimitList(List.map(eqns,intString),", ") + "\n"); | ||
| 6429 | 2905 | eqns := getEqnsforIndexReductionphase(eqns,m,mT,mark,colummarks,ass1,ass2,mapEqnIncRow,mapIncRowEqn,inSubsets,eqns); | |
| 6430 | // print("Found Eqns " + stringDelimitList(List.map(eqns,intString),", ") + "\n"); | ||
| 6431 | 2905 | Array.appendToElement(mark,eqns,inSubsets); | |
| 6432 | 2905 | then | |
| 6433 | getEqnsforIndexReduction1(rest,m,mT,mark+1,colummarks,ass1,ass2,mapEqnIncRow,mapIncRowEqn,inSubsets); | ||
| 6434 | case _::rest | ||
| 6435 | ✗ | then | |
| 6436 | getEqnsforIndexReduction1(rest,m,mT,mark,colummarks,ass1,ass2,mapEqnIncRow,mapIncRowEqn,inSubsets); | ||
| 6437 | end match; | ||
| 6438 | end getEqnsforIndexReduction1; | ||
| 6439 | |||
| 6440 | protected function getEqnsforIndexReductionphase | ||
| 6441 | "author: Frenkel TUD 2012-04" | ||
| 6442 | input list<Integer> elst; | ||
| 6443 | input BackendDAE.AdjacencyMatrix m; | ||
| 6444 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 6445 | input Integer mark; | ||
| 6446 | input array<Integer> colummarks; | ||
| 6447 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 6448 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 6449 | input array<list<Integer>> mapEqnIncRow "eqn indx -> skalar Eqn indexes"; | ||
| 6450 | input array<Integer> mapIncRowEqn "scalar eqn index -> eqn indx"; | ||
| 6451 | input array<list<Integer>> inSubsets; | ||
| 6452 | input list<Integer> inEqns; | ||
| 6453 | output list<Integer> outEqns; | ||
| 6454 | algorithm | ||
| 6455 | outEqns := | ||
| 6456 | match elst | ||
| 6457 | local | ||
| 6458 | Integer e; | ||
| 6459 | list<Integer> rows,rest,eqns; | ||
| 6460 | case {} then inEqns; | ||
| 6461 | case e::rest | ||
| 6462 | algorithm | ||
| 6463 | // traverse all adiacent rows | ||
| 6464 | 7728 | rows := List.select(m[e], Util.intPositive); | |
| 6465 | //print("search in Vars " + stringDelimitList(List.map(rows,intString),", ") + " from equation " + intString(e) + "\n"); | ||
| 6466 | 7728 | eqns := getEqnsforIndexReductiontraverseRows(rows,{},m,mT,mark,colummarks,ass1,ass2,mapEqnIncRow,mapIncRowEqn,inSubsets,inEqns); | |
| 6467 | 7728 | then | |
| 6468 | getEqnsforIndexReductionphase(rest,m,mT,mark,colummarks,ass1,ass2,mapEqnIncRow,mapIncRowEqn,inSubsets,eqns); | ||
| 6469 | else | ||
| 6470 | then | ||
| 6471 | fail(); | ||
| 6472 | end match; | ||
| 6473 | end getEqnsforIndexReductionphase; | ||
| 6474 | |||
| 6475 | protected function getEqnsforIndexReductiontraverseRows | ||
| 6476 | "author: Frenkel TUD 2012-04" | ||
| 6477 | input list<Integer> rows; | ||
| 6478 | input list<Integer> nextColums; | ||
| 6479 | input BackendDAE.AdjacencyMatrix m; | ||
| 6480 | input BackendDAE.AdjacencyMatrixT mT; | ||
| 6481 | input Integer mark; | ||
| 6482 | input array<Integer> colummarks; | ||
| 6483 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 6484 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 6485 | input array<list<Integer>> mapEqnIncRow "eqn indx -> skalar Eqn indexes"; | ||
| 6486 | input array<Integer> mapIncRowEqn "scalar eqn index -> eqn indx"; | ||
| 6487 | input array<list<Integer>> inSubsets; | ||
| 6488 | input list<Integer> inEqns; | ||
| 6489 | output list<Integer> outEqns; | ||
| 6490 | algorithm | ||
| 6491 | outEqns:= | ||
| 6492 | match (rows, nextColums) | ||
| 6493 | local | ||
| 6494 | list<Integer> rest,queue,nextqueue,eqns; | ||
| 6495 | Integer rc,r,e; | ||
| 6496 | case ({}, {}) then inEqns; | ||
| 6497 | case ({}, _) | ||
| 6498 | 2866 | then | |
| 6499 | getEqnsforIndexReductionphase(nextColums,m,mT,mark,colummarks,ass1,ass2,mapEqnIncRow,mapIncRowEqn,inSubsets,inEqns); | ||
| 6500 | case (r::rest, _) | ||
| 6501 | algorithm | ||
| 6502 | // row is matched | ||
| 6503 | // print("check Row " + intString(r) + "\n"); | ||
| 6504 | 13785 | rc := ass2[r]; | |
| 6505 | // print("check Colum " + intString(rc) + "\n"); | ||
| 6506 |
5/6✓ Branch 2 taken 13666 times.
✓ Branch 3 taken 119 times.
✓ Branch 4 taken 13666 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 5519 times.
✓ Branch 8 taken 8147 times.
|
13785 | if List.exist1(mT[r],intEq,rc) and intGt(rc,0) and not intEq(colummarks[rc],mark) then |
| 6507 |
2/2✓ Branch 0 taken 696 times.
✓ Branch 1 taken 4823 times.
|
5519 | if intGt(colummarks[rc],0) then |
| 6508 | 696 | mergeSubsets(mark,colummarks[rc],inSubsets,colummarks); | |
| 6509 | nextqueue := nextColums; | ||
| 6510 | queue := inEqns; | ||
| 6511 | else | ||
| 6512 | // if it is a multi dim equation take all scalare equations | ||
| 6513 | 4823 | e := mapIncRowEqn[rc]; | |
| 6514 | 4823 | eqns := mapEqnIncRow[e]; | |
| 6515 | 4823 | List.fold1r(eqns,arrayUpdate,mark,colummarks); | |
| 6516 | // print("add to nextQueue and Queue " + stringDelimitList(List.map(eqns,intString),", ") + "\n"); | ||
| 6517 | 4823 | nextqueue := listAppend(nextColums,eqns); | |
| 6518 | 4823 | queue := listAppend(inEqns,eqns); | |
| 6519 | //(nextqueue,queue) = getEqnsforIndexReductiontraverseColums(mT[r],colummarks,ass1,rc::nextColums,rc::inEqns); | ||
| 6520 | end if; | ||
| 6521 | else | ||
| 6522 | nextqueue := nextColums; | ||
| 6523 | queue := inEqns; | ||
| 6524 | end if; | ||
| 6525 | 13785 | then | |
| 6526 | getEqnsforIndexReductiontraverseRows(rest,nextqueue,m,mT,mark,colummarks,ass1,ass2,mapEqnIncRow,mapIncRowEqn,inSubsets,queue); | ||
| 6527 | end match; | ||
| 6528 | end getEqnsforIndexReductiontraverseRows; | ||
| 6529 | |||
| 6530 | protected function mergeSubsets | ||
| 6531 | input Integer mark; | ||
| 6532 | input Integer markColum; | ||
| 6533 | input array<list<Integer>> inSubsets; | ||
| 6534 | input array<Integer> colummarks; | ||
| 6535 | protected | ||
| 6536 | list<Integer> eqns; | ||
| 6537 | algorithm | ||
| 6538 | 696 | eqns := inSubsets[markColum]; | |
| 6539 | 696 | Array.appendToElement(mark,eqns,inSubsets); | |
| 6540 | 696 | arrayUpdate(inSubsets,markColum,{}); | |
| 6541 | 696 | List.fold1r(eqns,arrayUpdate,mark,colummarks); | |
| 6542 | end mergeSubsets; | ||
| 6543 | |||
| 6544 | protected function reduceIndexifNecessary | ||
| 6545 | "function: reduceIndexifNecessary, calls sssHandler if system need index reduction | ||
| 6546 | author: Frenkel TUD 2012-04" | ||
| 6547 | input list<Integer> meqns "Marked Equations for Index Reduction"; | ||
| 6548 | input Integer actualEqn; | ||
| 6549 | input BackendDAE.EqSystem isyst; | ||
| 6550 | input BackendDAE.Shared ishared; | ||
| 6551 | input Integer nv; | ||
| 6552 | input Integer ne; | ||
| 6553 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 6554 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 6555 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 6556 | input BackendDAEFunc.StructurallySingularSystemHandlerFunc sssHandler; | ||
| 6557 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 6558 | output list<Integer> outchangedEqns; | ||
| 6559 | output Integer continueEqn; | ||
| 6560 | output BackendDAE.EqSystem osyst; | ||
| 6561 | output BackendDAE.Shared oshared; | ||
| 6562 | output Integer nvars; | ||
| 6563 | output Integer neqns; | ||
| 6564 | output array<Integer> outAss1; | ||
| 6565 | output array<Integer> outAss2; | ||
| 6566 | output BackendDAE.StructurallySingularSystemHandlerArg outArg; | ||
| 6567 | algorithm | ||
| 6568 | (outchangedEqns,continueEqn,osyst,oshared,nvars,neqns,outAss1,outAss2,outArg):= | ||
| 6569 | match (meqns, inMatchingOptions) | ||
| 6570 | local | ||
| 6571 | Integer nv_1,ne_1,i_1; | ||
| 6572 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 6573 | BackendDAE.EqSystem syst; | ||
| 6574 | BackendDAE.Shared shared; | ||
| 6575 | array<Integer> ass1_1,ass1_2,ass2_1,ass2_2; | ||
| 6576 | list<Integer> changedEqns; | ||
| 6577 | |||
| 6578 | case ({}, _) | ||
| 6579 | ✗ | then | |
| 6580 | ({},actualEqn+1,isyst,ishared,nv,ne,ass1,ass2,inArg); | ||
| 6581 | case (_::_, (BackendDAE.INDEX_REDUCTION(),_)) | ||
| 6582 | algorithm | ||
| 6583 | ✗ | (changedEqns,i_1,syst,shared,ass2_1,ass1_1,arg) := sssHandler({meqns},actualEqn,isyst,ishared,ass2,ass1,inArg); | |
| 6584 | ✗ | ne_1 := BackendDAEUtil.systemSize(syst); | |
| 6585 | ✗ | nv_1 := BackendVariable.daenumVariables(syst); | |
| 6586 | ✗ | ass1_2 := assignmentsArrayExpand(ass1_1,ne_1,arrayLength(ass1_1),-1); | |
| 6587 | ✗ | ass2_2 := assignmentsArrayExpand(ass2_1,nv_1,arrayLength(ass2_1),-1); | |
| 6588 | then | ||
| 6589 | (changedEqns,i_1,syst,shared,nv_1,ne_1,ass1_2,ass2_2,arg); | ||
| 6590 | case (_, _) | ||
| 6591 | algorithm | ||
| 6592 | ✗ | singularSystemError({meqns},actualEqn,isyst,ishared,ass1,ass2,inArg); | |
| 6593 | ✗ | then | |
| 6594 | fail(); | ||
| 6595 | end match; | ||
| 6596 | end reduceIndexifNecessary; | ||
| 6597 | |||
| 6598 | protected function assignmentsArrayExpand | ||
| 6599 | "function helper for assignmentsArrayExpand | ||
| 6600 | author: Frenkel TUD 2012-04" | ||
| 6601 | input array<Integer> ass; | ||
| 6602 | input Integer needed; | ||
| 6603 | input Integer memsize; | ||
| 6604 | input Integer default; | ||
| 6605 | output array<Integer> outAss; | ||
| 6606 | algorithm | ||
| 6607 | outAss := matchcontinue default | ||
| 6608 | case _ | ||
| 6609 | algorithm | ||
| 6610 |
1/2✓ Branch 0 taken 556 times.
✗ Branch 1 not taken.
|
556 | true := intGt(memsize,needed); |
| 6611 | then | ||
| 6612 | ass; | ||
| 6613 | case _ | ||
| 6614 | algorithm | ||
| 6615 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 556 times.
|
556 | false := intGt(memsize,needed); |
| 6616 | 556 | then | |
| 6617 | Array.expand(needed-memsize, ass, default); | ||
| 6618 | else | ||
| 6619 | algorithm | ||
| 6620 | ✗ | Error.addInternalError("function assignmentsArrayExpand failed", sourceInfo()); | |
| 6621 | ✗ | then | |
| 6622 | fail(); | ||
| 6623 | end matchcontinue; | ||
| 6624 | end assignmentsArrayExpand; | ||
| 6625 | |||
| 6626 | protected function assignmentsArrayBooleanExpand | ||
| 6627 | "function helper for assignmentsArrayExpand | ||
| 6628 | author: Frenkel TUD 2012-04" | ||
| 6629 | input array<Boolean> ass; | ||
| 6630 | input Integer needed; | ||
| 6631 | input Integer memsize; | ||
| 6632 | input Boolean default; | ||
| 6633 | output array<Boolean> outAss; | ||
| 6634 | algorithm | ||
| 6635 | outAss := matchcontinue default | ||
| 6636 | case _ | ||
| 6637 | algorithm | ||
| 6638 | ✗ | true := intGt(memsize,needed); | |
| 6639 | then | ||
| 6640 | ass; | ||
| 6641 | case _ | ||
| 6642 | algorithm | ||
| 6643 | ✗ | false := intGt(memsize,needed); | |
| 6644 | ✗ | then | |
| 6645 | Array.expand(needed-memsize, ass, default); | ||
| 6646 | else | ||
| 6647 | algorithm | ||
| 6648 | ✗ | Error.addInternalError("function assignmentsArrayExpand failed", sourceInfo()); | |
| 6649 | ✗ | then | |
| 6650 | fail(); | ||
| 6651 | end matchcontinue; | ||
| 6652 | end assignmentsArrayBooleanExpand; | ||
| 6653 | |||
| 6654 | protected function checkAssignment | ||
| 6655 | "author: Frenkel TUD 2012-06 | ||
| 6656 | Check if the assignment is complet/maximum, | ||
| 6657 | returns all unmatched equations" | ||
| 6658 | input Integer indx; | ||
| 6659 | input Integer ne; | ||
| 6660 | input array<Integer> ass1 "eqn := ass1[var]"; | ||
| 6661 | input array<Integer> ass2 "var := ass2[eqn]"; | ||
| 6662 | input list<Integer> inUnassigned; | ||
| 6663 | output list<Integer> outUnassigned; | ||
| 6664 | protected | ||
| 6665 | list<Integer> unassigned; | ||
| 6666 | algorithm | ||
| 6667 | ✗ | if intGt(indx,ne) then | |
| 6668 | outUnassigned := inUnassigned; | ||
| 6669 | else | ||
| 6670 | ✗ | unassigned := List.consOnTrue(intLt(ass1[indx],0), indx, inUnassigned); | |
| 6671 | ✗ | outUnassigned := checkAssignment(indx+1,ne,ass1,ass2,unassigned); | |
| 6672 | end if; | ||
| 6673 | end checkAssignment; | ||
| 6674 | |||
| 6675 | protected function getAssignment | ||
| 6676 | input Boolean clearMatching; | ||
| 6677 | input Integer nVars; | ||
| 6678 | input Integer nEqns; | ||
| 6679 | input BackendDAE.EqSystem iSyst; | ||
| 6680 | output array<Integer> ass1 "ass[eqnindx]=varindx"; | ||
| 6681 | output array<Integer> ass2 "ass[varindx]=eqnindx"; | ||
| 6682 | algorithm | ||
| 6683 | (ass1,ass2) := match(clearMatching, iSyst) | ||
| 6684 | case(false, BackendDAE.EQSYSTEM(matching=BackendDAE.MATCHING(ass1=ass1,ass2=ass2))) guard intGe(nVars,arrayLength(ass1)) and intGe(nEqns,arrayLength(ass2)) | ||
| 6685 | then | ||
| 6686 | (ass2,ass1); | ||
| 6687 | else | ||
| 6688 | algorithm | ||
| 6689 | 59694 | ass2 := arrayCreate(nEqns,-1); | |
| 6690 | 59694 | ass1 := arrayCreate(nVars,-1); | |
| 6691 | then | ||
| 6692 | (ass2,ass1); | ||
| 6693 | end match; | ||
| 6694 | end getAssignment; | ||
| 6695 | |||
| 6696 | // ============================================================================= | ||
| 6697 | // tests | ||
| 6698 | // | ||
| 6699 | // ============================================================================= | ||
| 6700 | |||
| 6701 | public function testMatchingAlgorithms | ||
| 6702 | "function testMatchingAlgorithms, test all matching algorithms | ||
| 6703 | author: Frenkel TUD 2012-03" | ||
| 6704 | input BackendDAE.EqSystem isyst; | ||
| 6705 | input BackendDAE.Shared ishared; | ||
| 6706 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 6707 | protected | ||
| 6708 | Real t; | ||
| 6709 | Integer nv,ne,cheapID; | ||
| 6710 | array<list<Integer>> m; | ||
| 6711 | array<Integer> vec1,vec2; | ||
| 6712 | list<tuple<String,BackendDAEFunc.matchingAlgorithmFunc>> matchingAlgorithms; | ||
| 6713 | list<tuple<String,Integer>> extmatchingAlgorithms; | ||
| 6714 | BackendDAE.EqSystem syst; | ||
| 6715 | algorithm | ||
| 6716 | ✗ | ne := BackendDAEUtil.systemSize(isyst); | |
| 6717 | ✗ | nv := BackendVariable.daenumVariables(isyst); | |
| 6718 | ✗ | print("Systemsize: " + intString(ne) + "\n"); | |
| 6719 | ✗ | matchingAlgorithms := {("OMCNew: ",DFSLH), | |
| 6720 | ("BFSB: ",BFSB), | ||
| 6721 | ("DFSB: ",DFSB), | ||
| 6722 | ("MC21A: ",MC21A), | ||
| 6723 | ("PF: ",PF), | ||
| 6724 | ("PFPlus: ",PFPlus), | ||
| 6725 | ("HK: ",HK), | ||
| 6726 | ("HKDW: ",HKDW), | ||
| 6727 | ("ABMP: ",ABMP), | ||
| 6728 | ("PR: ",PR_FIFO_FAIR)}; | ||
| 6729 | ✗ | syst := randSortSystem(isyst,ishared); | |
| 6730 | ✗ | testMatchingAlgorithms1(matchingAlgorithms,syst,ishared,inMatchingOptions); | |
| 6731 | |||
| 6732 | ✗ | System.realtimeTick(ClockIndexes.RT_PROFILER0); | |
| 6733 | ✗ | (_,m,_) := BackendDAEUtil.getAdjacencyMatrixfromOption(syst,BackendDAE.NORMAL(),NONE(),BackendDAEUtil.isInitializationDAE(ishared)); | |
| 6734 | ✗ | matchingExternalsetAdjacencyMatrix(nv,ne,m); | |
| 6735 | cheapID := 3; | ||
| 6736 | ✗ | t := System.realtimeTock(ClockIndexes.RT_PROFILER0); | |
| 6737 | ✗ | print("SetMEXT: " + realString(t) + "\n"); | |
| 6738 | extmatchingAlgorithms := {("DFSEXT: ",1), | ||
| 6739 | ("BFSEXT: ",2), | ||
| 6740 | ("MC21AEXT: ",3), | ||
| 6741 | ("PFEXT: ",4), | ||
| 6742 | ("PFPlusEXT:",5), | ||
| 6743 | ("HKEXT: ",6), | ||
| 6744 | ("HKDWEXT ",7), | ||
| 6745 | ("ABMPEXT ",8), | ||
| 6746 | ("PREXT: ",10)}; | ||
| 6747 | ✗ | testExternMatchingAlgorithms1(extmatchingAlgorithms,cheapID,nv,ne); | |
| 6748 | ✗ | System.realtimeTick(ClockIndexes.RT_PROFILER0); | |
| 6749 | ✗ | vec1 := arrayCreate(ne,-1); | |
| 6750 | ✗ | vec2 := arrayCreate(nv,-1); | |
| 6751 | ✗ | BackendDAEEXT.getAssignment(vec1,vec2); | |
| 6752 | ✗ | print("GetAssEXT: " + realString(t) + "\n"); | |
| 6753 | ✗ | System.realtimeTick(ClockIndexes.RT_PROFILER0); | |
| 6754 | //unassigned := checkAssignment(1,ne,vec1,vec2,{}); | ||
| 6755 | //print("Unnasigned: " + intString(listLength(unassigned)) + "\n"); | ||
| 6756 | //print("Unassigned:\n"); | ||
| 6757 | //BackendDump.debuglst((unassigned,intString,"\n","\n")); | ||
| 6758 | //BackendDump.dumpMatching(vec1); | ||
| 6759 | end testMatchingAlgorithms; | ||
| 6760 | |||
| 6761 | public function testMatchingAlgorithms1 | ||
| 6762 | "function testMatchingAlgorithms1, helper for testMatchingAlgorithms | ||
| 6763 | author: Frenkel TUD 2012-04" | ||
| 6764 | input list<tuple<String,BackendDAEFunc.matchingAlgorithmFunc>> matchingAlgorithms; | ||
| 6765 | input BackendDAE.EqSystem isyst; | ||
| 6766 | input BackendDAE.Shared ishared; | ||
| 6767 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 6768 | algorithm | ||
| 6769 | () := | ||
| 6770 | matchcontinue matchingAlgorithms | ||
| 6771 | local | ||
| 6772 | list<tuple<String,BackendDAEFunc.matchingAlgorithmFunc>> rest; | ||
| 6773 | String str; | ||
| 6774 | BackendDAEFunc.matchingAlgorithmFunc matchingAlgorithm; | ||
| 6775 | Real t; | ||
| 6776 | case {} | ||
| 6777 | then (); | ||
| 6778 | case (str,matchingAlgorithm)::rest | ||
| 6779 | algorithm | ||
| 6780 | ✗ | System.realtimeTick(ClockIndexes.RT_PROFILER0); | |
| 6781 | ✗ | testMatchingAlgorithm(10,matchingAlgorithm,isyst,ishared,inMatchingOptions); | |
| 6782 | ✗ | t := System.realtimeTock(ClockIndexes.RT_PROFILER0); | |
| 6783 | ✗ | print(str + realString(realDiv(t,10.0)) + "\n"); | |
| 6784 | ✗ | testMatchingAlgorithms1(rest,isyst,ishared,inMatchingOptions); | |
| 6785 | then | ||
| 6786 | (); | ||
| 6787 | case (str,_)::rest | ||
| 6788 | algorithm | ||
| 6789 | ✗ | print(str + "failed!\n"); | |
| 6790 | ✗ | testMatchingAlgorithms1(rest,isyst,ishared,inMatchingOptions); | |
| 6791 | then | ||
| 6792 | (); | ||
| 6793 | end matchcontinue; | ||
| 6794 | end testMatchingAlgorithms1; | ||
| 6795 | |||
| 6796 | protected function testMatchingAlgorithm | ||
| 6797 | "function testMatchingAlgorithm, tests a specific matching algorithm | ||
| 6798 | author: Frenkel TUD 2012-04" | ||
| 6799 | input Integer index; | ||
| 6800 | input BackendDAEFunc.matchingAlgorithmFunc matchingAlgorithm; | ||
| 6801 | input BackendDAE.EqSystem isyst; | ||
| 6802 | input BackendDAE.Shared ishared; | ||
| 6803 | input BackendDAE.MatchingOptions inMatchingOptions; | ||
| 6804 | algorithm | ||
| 6805 | () := | ||
| 6806 | match index | ||
| 6807 | local | ||
| 6808 | BackendDAE.StructurallySingularSystemHandlerArg arg; | ||
| 6809 | case 0 | ||
| 6810 | then (); | ||
| 6811 | else | ||
| 6812 | algorithm | ||
| 6813 | ✗ | arg := IndexReduction.getStructurallySingularSystemHandlerArg(isyst,ishared,listArray({}),listArray({})); | |
| 6814 | ✗ | matchingAlgorithm(isyst,ishared,true,inMatchingOptions,IndexReduction.pantelidesIndexReduction,arg); | |
| 6815 | ✗ | testMatchingAlgorithm(index-1,matchingAlgorithm,isyst,ishared,inMatchingOptions); | |
| 6816 | then | ||
| 6817 | (); | ||
| 6818 | end match; | ||
| 6819 | end testMatchingAlgorithm; | ||
| 6820 | |||
| 6821 | public function testExternMatchingAlgorithms1 | ||
| 6822 | "function testExternMatchingAlgorithms1, helper for testMatchingAlgorithms | ||
| 6823 | author: Frenkel TUD 2012-04" | ||
| 6824 | input list<tuple<String,Integer>> matchingAlgorithms; | ||
| 6825 | input Integer cheapId; | ||
| 6826 | input Integer nv; | ||
| 6827 | input Integer ne; | ||
| 6828 | protected | ||
| 6829 | String str; | ||
| 6830 | Integer matchingAlgorithm; | ||
| 6831 | Real t; | ||
| 6832 | algorithm | ||
| 6833 | ✗ | for alg in matchingAlgorithms loop | |
| 6834 | ✗ | (str,matchingAlgorithm) := alg; | |
| 6835 | try | ||
| 6836 | ✗ | System.realtimeTick(ClockIndexes.RT_PROFILER0); | |
| 6837 | ✗ | testExternMatchingAlgorithm(10,matchingAlgorithm,cheapId,nv,ne); | |
| 6838 | ✗ | t := System.realtimeTock(ClockIndexes.RT_PROFILER0); | |
| 6839 | ✗ | print(str + realString(realDiv(t,10.0)) + "\n"); | |
| 6840 | else | ||
| 6841 | ✗ | print(str + "failed!\n"); | |
| 6842 | end try; | ||
| 6843 | end for; | ||
| 6844 | end testExternMatchingAlgorithms1; | ||
| 6845 | |||
| 6846 | public function testExternMatchingAlgorithm | ||
| 6847 | "function testMatchingAlgorithm, tests a specific matching algorithm | ||
| 6848 | author: Frenkel TUD 2012-04" | ||
| 6849 | input Integer index; | ||
| 6850 | input Integer matchingAlgorithm; | ||
| 6851 | input Integer cheapId; | ||
| 6852 | input Integer nv; | ||
| 6853 | input Integer ne; | ||
| 6854 | algorithm | ||
| 6855 | () := | ||
| 6856 | match index | ||
| 6857 | case 0 | ||
| 6858 | then (); | ||
| 6859 | else | ||
| 6860 | algorithm | ||
| 6861 | ✗ | BackendDAEEXT.matching(nv,ne,matchingAlgorithm,cheapId,1.0,1); | |
| 6862 | ✗ | testExternMatchingAlgorithm(index-1,matchingAlgorithm,cheapId,nv,ne); | |
| 6863 | then | ||
| 6864 | (); | ||
| 6865 | end match; | ||
| 6866 | end testExternMatchingAlgorithm; | ||
| 6867 | |||
| 6868 | protected function randSortSystem | ||
| 6869 | "function randSortSystem, resort all equations and variables in random order | ||
| 6870 | author: Frenkel TUD 2012-043" | ||
| 6871 | input BackendDAE.EqSystem isyst; | ||
| 6872 | input BackendDAE.Shared ishared; | ||
| 6873 | output BackendDAE.EqSystem osyst; | ||
| 6874 | algorithm | ||
| 6875 | osyst := match isyst | ||
| 6876 | local | ||
| 6877 | Integer ne, nv; | ||
| 6878 | array<Integer> randarr, randarr1; | ||
| 6879 | BackendDAE.Variables vars; | ||
| 6880 | BackendDAE.EquationArray eqns; | ||
| 6881 | BackendDAE.EqSystem syst; | ||
| 6882 | |||
| 6883 | case syst as BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns) | ||
| 6884 | algorithm | ||
| 6885 | ✗ | ne := BackendDAEUtil.systemSize(isyst); | |
| 6886 | ✗ | nv := BackendVariable.daenumVariables(isyst); | |
| 6887 | ✗ | randarr := Array.createIntRange(ne); | |
| 6888 | ✗ | setrandArray(ne, randarr); | |
| 6889 | ✗ | randarr1 := Array.createIntRange(nv); | |
| 6890 | ✗ | setrandArray(nv, randarr1); | |
| 6891 | ✗ | syst.orderedEqs := randSortSystem1( ne, 0, randarr, eqns, BackendEquation.listEquation({}), | |
| 6892 | BackendEquation.get, BackendEquation.add ); | ||
| 6893 | ✗ | syst.orderedVars := randSortSystem1( nv, 0, randarr1, vars, BackendVariable.emptyVars(), | |
| 6894 | BackendVariable.getVarAt, BackendVariable.addVar ); | ||
| 6895 | ✗ | (syst, _, _) := BackendDAEUtil.getAdjacencyMatrix( BackendDAEUtil.clearEqSyst(syst), BackendDAE.NORMAL(), NONE(), BackendDAEUtil.isInitializationDAE(ishared)); | |
| 6896 | then | ||
| 6897 | syst; | ||
| 6898 | end match; | ||
| 6899 | end randSortSystem; | ||
| 6900 | |||
| 6901 | protected function randSortSystem1 | ||
| 6902 | input Integer index; | ||
| 6903 | input Integer offset "obsolete"; | ||
| 6904 | input array<Integer> randarr; | ||
| 6905 | input Type_a oldTypeA; | ||
| 6906 | input Type_a newTypeA; | ||
| 6907 | input getFunc get; | ||
| 6908 | input setFunc set; | ||
| 6909 | output Type_a outTypeA; | ||
| 6910 | replaceable type Type_a subtypeof Any; | ||
| 6911 | replaceable type Type_b subtypeof Any; | ||
| 6912 | partial function getFunc | ||
| 6913 | input Type_a inTypeA; | ||
| 6914 | input Integer inInteger; | ||
| 6915 | output Type_b outTypeB; | ||
| 6916 | end getFunc; | ||
| 6917 | partial function setFunc | ||
| 6918 | input Type_b inTypeB; | ||
| 6919 | input Type_a inTypeA; | ||
| 6920 | output Type_a outTypeA; | ||
| 6921 | end setFunc; | ||
| 6922 | algorithm | ||
| 6923 | outTypeA := match index | ||
| 6924 | local | ||
| 6925 | Type_b tb; | ||
| 6926 | Type_a ta; | ||
| 6927 | case 0 | ||
| 6928 | then newTypeA; | ||
| 6929 | else | ||
| 6930 | algorithm | ||
| 6931 | ✗ | tb := get(oldTypeA,randarr[index]+offset); | |
| 6932 | ✗ | ta := set(tb,newTypeA); | |
| 6933 | ✗ | then | |
| 6934 | randSortSystem1(index-1,offset,randarr,oldTypeA,ta,get,set); | ||
| 6935 | end match; | ||
| 6936 | end randSortSystem1; | ||
| 6937 | |||
| 6938 | |||
| 6939 | protected function singularSystemError | ||
| 6940 | input list<list<Integer>> eqns; | ||
| 6941 | input Integer actualEqn; | ||
| 6942 | input BackendDAE.EqSystem isyst; | ||
| 6943 | input BackendDAE.Shared ishared; | ||
| 6944 | input array<Integer> inAssignments1; | ||
| 6945 | input array<Integer> inAssignments2; | ||
| 6946 | input BackendDAE.StructurallySingularSystemHandlerArg inArg; | ||
| 6947 | protected | ||
| 6948 | Integer n; | ||
| 6949 | list<Integer> unmatched,unmatched1,vars; | ||
| 6950 | String eqn_str,var_str; | ||
| 6951 | DAE.ElementSource source; | ||
| 6952 | SourceInfo info; | ||
| 6953 | array<Integer> mapIncRowEqn; | ||
| 6954 | algorithm | ||
| 6955 | ✗ | (_,_,_,mapIncRowEqn,_) := inArg; | |
| 6956 | ✗ | n := BackendDAEUtil.systemSize(isyst); | |
| 6957 | // for debugging | ||
| 6958 | /* BackendDump.printEqSystem(isyst); | ||
| 6959 | BackendDump.dumpMatching(inAssignments1); | ||
| 6960 | BackendDump.dumpMatching(inAssignments2); | ||
| 6961 | syst := BackendDAEUtil.setEqSystMatching(isyst, BackendDAE.MATCHING(inAssignments1,inAssignments2,{})); | ||
| 6962 | DumpGraphML.dumpSystem(syst,ishared,NONE(),"SingularSystem" + intString(n) + ".graphml",false); | ||
| 6963 | */ | ||
| 6964 | // get from scalar eqns indexes the indexes in the equation array | ||
| 6965 | ✗ | unmatched := List.flatten(eqns); | |
| 6966 | ✗ | unmatched1 := List.map1r(unmatched,arrayGet,mapIncRowEqn); | |
| 6967 | ✗ | unmatched1 := List.uniqueIntN(unmatched1,arrayLength(mapIncRowEqn)); | |
| 6968 | ✗ | eqn_str := BackendDump.dumpMarkedEqns(isyst, unmatched1); | |
| 6969 | ✗ | vars := getUnassigned(n, inAssignments2, {}); | |
| 6970 | ✗ | vars := List.fold1(unmatched,getAssignedVars,inAssignments1,vars); | |
| 6971 | ✗ | var_str := BackendDump.dumpMarkedVars(isyst, vars); | |
| 6972 | ✗ | source := BackendEquation.markedEquationSource(isyst, listHead(unmatched1)); | |
| 6973 | ✗ | info := ElementSource.getElementSourceFileInfo(source); | |
| 6974 | ✗ | Error.addSourceMessage(Error.STRUCT_SINGULAR_SYSTEM, {eqn_str,var_str}, info); | |
| 6975 | end singularSystemError; | ||
| 6976 | |||
| 6977 | protected function getAssignedVars | ||
| 6978 | input Integer e; | ||
| 6979 | input array<Integer> ass; | ||
| 6980 | input list<Integer> iAcc; | ||
| 6981 | output list<Integer> oAcc; | ||
| 6982 | protected | ||
| 6983 | Integer i; | ||
| 6984 | Boolean b; | ||
| 6985 | algorithm | ||
| 6986 | ✗ | i := ass[e]; | |
| 6987 | ✗ | b := intGt(i,0); | |
| 6988 | ✗ | oAcc := List.consOnTrue(b,i,iAcc); | |
| 6989 | end getAssignedVars; | ||
| 6990 | |||
| 6991 | protected function clearArrayWithKnownSetIndexes "Sets elements of arr in arrIx[1:n] to false; if n>0.3*size(arr), clear all of them" | ||
| 6992 | input array<Boolean> arr; | ||
| 6993 | input array<Integer> arrIx; | ||
| 6994 | input Integer n; | ||
| 6995 | protected | ||
| 6996 | constant Boolean debug = false; | ||
| 6997 | algorithm | ||
| 6998 | ✗ | if n>0.3*arrayLength(arr) then | |
| 6999 | ✗ | for i in 1:arrayLength(arr) loop | |
| 7000 | Dangerous.arrayUpdateNoBoundsChecking(arr, i, false); | ||
| 7001 | end for; | ||
| 7002 | else | ||
| 7003 | ✗ | true := n <= arrayLength(arrIx); | |
| 7004 | ✗ | for i in 1:n loop | |
| 7005 | ✗ | arrayUpdate(arr, Dangerous.arrayGetNoBoundsChecking(arrIx, i), false); | |
| 7006 | end for; | ||
| 7007 | end if; | ||
| 7008 | if debug then | ||
| 7009 | for e in 1:arrayLength(arr) loop | ||
| 7010 | Error.assertion(not arrayGet(arr,e), "clearArrayWithKnownSetIndexes failed: " + String(e) + " n=" + String(n)+" ixs="+stringDelimitList(list(String(arrayGet(arrIx,i)) for i in 1:n),","), sourceInfo()); | ||
| 7011 | end for; | ||
| 7012 | end if; | ||
| 7013 | end clearArrayWithKnownSetIndexes; | ||
| 7014 | |||
| 7015 | annotation(__OpenModelica_Interface="backend"); | ||
| 7016 | end Matching; | ||
| 7017 |