Open a-torgovitsky opened 4 years ago
Done! I have added a new function standard.form
, a new class lpmodel.natural
and the corresponding unit test.
The new function will convert an lpmodel.natural
object to an lpmodel
object -- in particular, consolidating the inequalities from the shape constraints, the upper and lower bounds into a new A.shp
and beta.shp
matrix in standard form.
Below is an example:
# obs matrices
Aobs <- matrix(c(1,1,2,3,3,7), nrow = 2, byrow = TRUE)
bobs <- matrix(c(6,20), nrow = 2, byrow = TRUE)
sobs <- matrix(rep("=", 2), nrow = 2, byrow = TRUE)
# shp matrices
Ashp <- matrix(c(10,0,0,2,1,2), nrow = 2, byrow = TRUE)
bshp <- matrix(c(1,10), nrow = 2, byrow = TRUE)
sshp <- matrix(c(">=", "<="), nrow = 2, byrow = TRUE)
# tgt matrices
Atgt <- matrix(c(1,2,3), nrow = 1, byrow = TRUE)
btgt <- c(9)
stgt <- c("=")
# lb and ub
xlb <- c(0.01,0.02,0.03)
xub <- c(1000,2000,3000)
# Get `lpmodel.natural`
lpmn <- lpmodel.natural(A.obs = Aobs,
A.shp = Ashp,
A.tgt = Atgt,
beta.obs = bobs,
beta.shp = bshp,
sense.shp = sshp,
x.lb = xlb,
x.ub = xub)
Applying the standard.form
function, i.e. it will give the following updated matrices.
> lpm <- standard.lpmodel(lpmn)
> lpm$A.shp
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
[1,] 2 1 2 1 0 0 0 0 0 0 0
[2,] 1 0 0 0 1 0 0 0 0 0 0
[3,] 0 1 0 0 0 1 0 0 0 0 0
[4,] 0 0 1 0 0 0 1 0 0 0 0
[5,] 10 0 0 0 0 0 0 -1 0 0 0
[6,] 1 0 0 0 0 0 0 0 -1 0 0
[7,] 0 1 0 0 0 0 0 0 0 -1 0
[8,] 0 0 1 0 0 0 0 0 0 0 -1
> lpm$beta.shp
[,1]
[1,] 1e+01
[2,] 1e+03
[3,] 2e+03
[4,] 3e+03
[5,] 1e+00
[6,] 1e-02
[7,] 2e-02
[8,] 3e-02
lpm$A.shp
and lpm$beta.shp
correspond to the "<=" constraints.
A.shp
and beta.shp
.lpm$A.shp
correspond to the ">=" constraints.
A.shp
and beta.shp
.In addition, printing the lpmn
object above (with class lpmodel.natural
) will give the following message (similar to printing a lpmodel
object):
Object Class Dimension Length
A.obs matrix 2x3 1
A.shp matrix 2x3 1
A.tgt matrix 1x3 1
beta.obs matrix 2x1 1
beta.shp matrix 2x1 1
sense.shp matrix 2x1 1
x.lb numeric 1x3 1
x.ub numeric 1x3 1
I also use the above set-up in the unit test, where I use Gurobi to confirm the objective value and the optimal vector is the same for the linear programs in standard form and the non-standard form. Thanks!
This looks great!
I will try to come up with a good real-world example for testing this. I'm going to leave the issue open until then.
Thank you! I have also just updated the README
about the part on using standard.lpmodel
and lpmodel.natural
.
Goal
Allow the user to input a linear program in a more natural form, and then have it converted directly into a standard form
lpmodel
Problem
It is not clear to me how one would go about doing this with
standard.form
. I think we need something more expressive for the user.lpmodel
An
lpmodel
has three components:A.obs
andbeta.obs
. We always know what "sense" (=
,<=
,>=
) these are to be treated in any given context.A.tgt
. This too we always know how it will be treated.A.shp
andbeta.shp
. These components are more ambiguous. They could be related with either=
,<=
or>=
.In addition, we have currently assumed that
x >= 0
is always imposed, but in general we might prefer something different; either a different lower bound, or a different upper bound, or both.A "natural form"
lpmodel
Create a new class
lpmodel.natural
that has these components:A.obs
,beta.obs
as inlpmodel
A.tgt
as inlpmodel
A.shp
,beta.shp
as inlpmodel
, but also addsense.shp
.x.lb
,x.ub
Write a function that converts an
lpmodel.natural
to anlpmodel
This could use most of the code/ideas already in
standard.form
, but would be easier for the user to understand, since it just requires specifying anlpmodel.natural
.