Skip to content

Commit

Permalink
fix: expand variables allowing for any number of indices in EXCEPT cl…
Browse files Browse the repository at this point in the history
…ause (#118)

Fixes #117
  • Loading branch information
ToddFincannon authored Sep 27, 2021
1 parent 7c51641 commit d92343e
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 74 deletions.
44 changes: 44 additions & 0 deletions models/except/except.dat
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,50 @@ e[A3,C2]
0 5
e[A3,C3]
0 5
except3[E1,F1,G1]
0 3
except3[E1,F1,G2]
0 3
except3[E1,F2,G1]
0 3
except3[E1,F2,G2]
0 3
except3[E2,F1,G1]
0 3
except3[E2,F1,G2]
0 3
except3[E2,F2,G1]
0 3
except4[E1,F1,G1,H1]
0 4
except4[E1,F1,G1,H2]
0 4
except4[E1,F1,G2,H1]
0 4
except4[E1,F1,G2,H2]
0 4
except4[E1,F2,G1,H1]
0 4
except4[E1,F2,G1,H2]
0 4
except4[E1,F2,G2,H1]
0 4
except4[E1,F2,G2,H2]
0 4
except4[E2,F1,G1,H1]
0 4
except4[E2,F1,G1,H2]
0 4
except4[E2,F1,G2,H1]
0 4
except4[E2,F1,G2,H2]
0 4
except4[E2,F2,G1,H1]
0 4
except4[E2,F2,G1,H2]
0 4
except4[E2,F2,G2,H1]
0 4
f[A1,C1]
0 6
FINAL TIME
Expand Down
11 changes: 9 additions & 2 deletions models/except/except.mdl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ SubA2: A2 ~~|
DimC: C1, C2, C3 ~~|
SubC: C2, C3 ~~|
DimD: D1, D2 -> (DimA: SubA, A1) ~~|
DimE: E1, E2 ~~|
DimF: F1, F2 ~~|
DimG: G1, G2 ~~|
DimH: H1, H2 ~~|

a[DimA] = 1 ~~|
b[SubA] = 2 ~~|
Expand All @@ -14,6 +18,8 @@ e[DimA, SubC] = 5 ~~|
f[A1, C1] = 6 ~~|
g[DimA] :EXCEPT: [A1] = 7 ~~|
h[DimA] :EXCEPT: [SubA] = 8 ~~|
j[DimD] = 10, 20 ~~|
k[DimA] :EXCEPT: [A1] = a[DimA] + j[DimD] ~~|
o[SubA] :EXCEPT: [SubA2] = 9 ~~|
p[DimA, DimC] :EXCEPT: [A1, C1] = 10 ~~|
q[DimA, DimC] :EXCEPT: [SubA, C2] = 11 ~~|
Expand All @@ -26,8 +32,9 @@ v[SubA] :EXCEPT: [A1] = a[SubA] ~~|
w[DimA] :EXCEPT: [SubA] = a[DimA] ~~|
x[DimA] :EXCEPT: [SubA] = c[DimA, C1] ~~|
y[SubA, SubC] :EXCEPT: [A3, C3] = c[SubA, SubC] ~~|
j[DimD] = 10, 20 ~~|
k[DimA] :EXCEPT: [A1] = a[DimA] + j[DimD] ~~|

except3[DimE, DimF, DimG] :EXCEPT: [E2, F2, G2] = 3 ~~|
except4[DimE, DimF, DimG, DimH] :EXCEPT: [E2, F2, G2, H2] = 4 ~~|

INITIAL TIME = 0 ~~|
FINAL TIME = 1 ~~|
Expand Down
2 changes: 1 addition & 1 deletion src/Helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ export let listConcat = (a, x, addSpaces = false) => {
export let cdbl = x => {
// Convert a number into a C double constant.
let s = x.toString()
if (!s.includes('.') && !s.includes('e')) {
if (!s.includes('.') && !s.toLowerCase().includes('e')) {
s += '.0'
}
return s
Expand Down
96 changes: 25 additions & 71 deletions src/VariableReader.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,80 +94,34 @@ export default class VariableReader extends ModelReader {
}
expandVars(expanding) {
// Expand the indicated subscripts into variable objects in the expandedVars list.
let isException = (indName, exceptSub) => {
// Compare the LHS index name directly to an exception index subscript.
let result = false
if (isIndex(exceptSub)) {
result = indName === exceptSub
} else if (isDimension(exceptSub)) {
result = R.contains(indName, sub(exceptSub).value)
}
return result
}
let skipExpansion = (indName, expansionPos) => {
// Look for this index in each of the exception subscript lists at expansionsPos.
let skip = false
for (const exceptSubs of this.var.exceptSubscripts) {
let exceptSub = exceptSubs[expansionPos]
if (isException(indName, exceptSub)) {
skip = true
break
}
}
return skip
}
let skipExpansion2 = indNames => {
let skip = false
for (let exceptSubs of this.var.exceptSubscripts) {
if (isException(indNames[0], exceptSubs[0]) && isException(indNames[1], exceptSubs[1])) {
skip = true
break
debugLog(`expanding ${this.var.varName}[${strlist(this.var.subscripts)}] subscripts`, strlist(this.var.subscripts))
let expansion = []
let separationDims = []
// Construct an array with an array at each subscript position. If the subscript is expanded at that position,
// it will become an array of indices. Otherwise, it remains an index or dimension as a single-valued array.
for (let i = 0; i < this.var.subscripts.length; i++) {
let subscript = this.var.subscripts[i]
let value
if (expanding[i]) {
separationDims.push(subscript)
if (isDimension(subscript)) {
value = sub(subscript).value
}
}
return skip
expansion.push(value || [subscript])
}
let numSubscriptsToExpand = expanding.reduce((n, x) => n + (!!x ? 1 : 0), 0)
if (numSubscriptsToExpand === 1) {
let expansionPos = expanding[0] ? 0 : 1
let expansionSubscript = this.var.subscripts[expansionPos]
// An exception subscript can be an index. Expand on a single index or on all indices of a dimension.
let expansionSubs = isIndex(expansionSubscript) ? [sub(expansionSubscript).name] : sub(expansionSubscript).value
debugLog(`expanding ${this.var.varName}[${strlist(this.var.subscripts)}] subscript`, expansionSubscript)
for (let indName of expansionSubs) {
if (!skipExpansion(indName, expansionPos)) {
let v = new Variable(this.var.eqnCtx)
v.varName = this.var.varName
v.subscripts = replaceInArray(expansionSubscript, indName, this.var.subscripts)
v.separationDims.push(expansionSubscript)
debugLog(` ${strlist(v.subscripts)}`)
this.expandedVars.push(v)
}
}
} else if (numSubscriptsToExpand === 2) {
debugLog(
`expanding ${this.var.varName}[${strlist(this.var.subscripts)}] subscripts`,
strlist(this.var.subscripts)
)
// Find the subscripts we need to expand.
let separationDims = []
for (let i = 0; i < expanding.length; i++) {
if (expanding[i]) {
separationDims.push(this.var.subscripts[i])
}
}
let expansionSubs = separationDims.map(s => (isIndex(s) ? [sub(s).name] : sub(s).value))
for (let indNames of cartesianProductOf(expansionSubs)) {
if (!skipExpansion2(indNames)) {
let v = new Variable(this.var.eqnCtx)
v.varName = this.var.varName
v.subscripts = []
for (let i = 0; i < expanding.length; i++) {
v.subscripts.push(expanding[i] ? indNames.shift() : this.var.subscripts[i])
}
v.separationDims = separationDims
debugLog(` ${strlist(v.subscripts)}`)
this.expandedVars.push(v)
}
// Generate an array of fully expanded subscripts.
let expandedSubs = cartesianProductOf(expansion)
for (let subs of expandedSubs) {
// Skip expansions that match exception subscripts.
if (!R.any(e => R.equals(e, subs), this.var.exceptSubscripts)) {
// Add a new variable to the expanded vars.
let v = new Variable(this.var.eqnCtx)
v.varName = this.var.varName
v.subscripts = subs
v.separationDims = separationDims
debugLog(` ${strlist(v.subscripts)}`)
this.expandedVars.push(v)
}
}
}
Expand Down

0 comments on commit d92343e

Please sign in to comment.