Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: expand variables allowing for any number of indices in EXCEPT clause #118

Merged
merged 18 commits into from
Sep 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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