You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
and similar. The user chooses which terms to include when the ROM is initialized (e.g., ContinuousOpInfROM(modelform="cAHB")) and there are properties for each of the operators, called c_, A_, H_, and B_, that are pretty strict about getting shapes right and so on. This setup is restrictive and a bit painful for development – right now if we want to add a new term to the above equation, e.g., a linear interaction between state and inputs or higher-order polynomial interactions, it involves a lot of changes in a lot of places. Furthermore, it's not easy to impose system-level structure, like the following:
Here, we'd ideally like to specify that there is a quadratic interaction between $\mathbf{q}_{1}$ and $\mathbf{q}_{2}$ (but not $\mathbf{q}_{1}$ and $\mathbf{q}_{1}$ or $\mathbf{q}_{2}$ and $\mathbf{q}_{2}$) in the first equation, but not in the second equation, and so on. This is also an issue for Hamiltonian OpInf, see #45.
Here's a proposed solution. Instead of feeding the ROM a string that indicates the structure, feed it a list of operators (allowing certain strings as shortcuts for the monolithic case). So something like this:
importopinfc=opinf.operators.ConstantOperator()
A=opinf.operators.LinearOperator()
H=opinf.operators.QuadraticOperator()
B=opinf.operators.InputOperator()
rom=opinf.ContinuousOpInfROM([c, A, H, B])
This would abolish the restrictive c_, A_, H_, and B_ properties in favor of an operators property in the ROM class. For the systems example, I can imagine something like this:
These operators may need some additional information, such as the size of $\mathbf{q}_{1}$$\mathbf{q}_{2}$ (which may not necessarily be equal).
To do this, each operator class would need a method like datablock(Q, U) that takes in states/inputs and spits out the chunk of the data matrix corresponding to that operator.
For example, ConstantOperator.datablock(Q, U) should always returns a vector of ones, LinearOperator.datablock(Q, U) should return Q, QuadraticOperator.datablock(Q, U) should return Q ⊗ Q, and InputOperator(Q, U) should return U.
Then, in the ROM class, we construct the data matrix with a single line:
and similar for unpacking the operator matrix after solving the least-squares problem. In contrast, right now we have something like
data_matrix_chunks= []
if'c'inself.modelform:
data_matrix_chunks.append(ones.T)
if'A'inself.modelform:
data_matrix_chunks.append(Q.T)
if'H'inself.modelform:
data_matrix_chunks.append((Q ⊗ Q).T)
if'B'inself.modelform:
data_matrix_chunks.append(U.T)
# More 'if' statements needed each time we add a new type of operatordata_matrix=np.hstack(data_matrix_chunks)
This change will introduce a few API changes, but it should mostly add functionality to the package that isn't currently available.
The text was updated successfully, but these errors were encountered:
An upcoming change toward this design will introduce state-input interaction operators, i.e., $\mathbf{N}[\mathbf{q}(t)\otimes\mathbf{u}(t)]$, and make it easier to add higher-order (arbitrary order?) polynomial terms in the future.
The existing ROM classes in the package can really only handle models of the form
and similar. The user chooses which terms to include when the ROM is initialized (e.g.,
ContinuousOpInfROM(modelform="cAHB")
) and there are properties for each of the operators, calledc_
,A_
,H_
, andB_
, that are pretty strict about getting shapes right and so on. This setup is restrictive and a bit painful for development – right now if we want to add a new term to the above equation, e.g., a linear interaction between state and inputs or higher-order polynomial interactions, it involves a lot of changes in a lot of places. Furthermore, it's not easy to impose system-level structure, like the following:Here, we'd ideally like to specify that there is a quadratic interaction between$\mathbf{q}_{1}$ and $\mathbf{q}_{2}$ (but not $\mathbf{q}_{1}$ and $\mathbf{q}_{1}$ or $\mathbf{q}_{2}$ and $\mathbf{q}_{2}$ ) in the first equation, but not in the second equation, and so on. This is also an issue for Hamiltonian OpInf, see #45.
Here's a proposed solution. Instead of feeding the ROM a string that indicates the structure, feed it a list of operators (allowing certain strings as shortcuts for the monolithic case). So something like this:
This would abolish the restrictive
c_
,A_
,H_
, andB_
properties in favor of anoperators
property in the ROM class. For the systems example, I can imagine something like this:These operators may need some additional information, such as the size of$\mathbf{q}_{1}$ $\mathbf{q}_{2}$ (which may not necessarily be equal).
To do this, each operator class would need a method like
datablock(Q, U)
that takes in states/inputs and spits out the chunk of the data matrix corresponding to that operator.For example,
ConstantOperator.datablock(Q, U)
should always returns a vector of ones,LinearOperator.datablock(Q, U)
should returnQ
,QuadraticOperator.datablock(Q, U)
should returnQ ⊗ Q
, andInputOperator(Q, U)
should returnU
.Then, in the ROM class, we construct the data matrix with a single line:
and similar for unpacking the operator matrix after solving the least-squares problem. In contrast, right now we have something like
This change will introduce a few API changes, but it should mostly add functionality to the package that isn't currently available.
The text was updated successfully, but these errors were encountered: