Snowflake
Snowflake

Reputation: 3081

Constructing a constraint matrix with R

I would like to construct the following matrix for modelling an ILP in R. The actual meaning of the variables are not really relevant, what is relevant are the following properties.

I would like to construct a matrix with n ones, with n x m number of columns.

For the first row, I would like to have n ones (starting from position 0).

For the second row, I would like to first have n zeroes and then n ones, with the remaining columns to be zeroes.

For the third row, I would like to have the n x 2 zeroes and then n ones, with the remaining columns to be zeroes.

This continues until I have n x (m-1) zeroes at the start and n ones at the end.

A small demonstration of the matrix is as follows:

1 1 1 1 0 0 0 0 0 0 0 0
0 0 0 0 1 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0 1 1 1 1

The code to generate this matrix is:

f.con <- matrix(0, nrow = 3, ncol = 12)
for(i in 1:3){
  f.con[i,((i-1)*4+1):(4*i)] <- rep(1, 4)
}

I was wondering whether I can construct this matrix using a bit more vectorised approach?

Upvotes: 2

Views: 274

Answers (3)

ThomasIsCoding
ThomasIsCoding

Reputation: 101568

An easy base R solution is to use kronecker

nr <- 3
nc <- 12
f.con <- kronecker(diag(nr),t(rep(1,nc/nr)))

such that

> f.con
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,]    1    1    1    1    0    0    0    0    0     0     0     0
[2,]    0    0    0    0    1    1    1    1    0     0     0     0
[3,]    0    0    0    0    0    0    0    0    1     1     1     1
`` 

Upvotes: 1

Ronak Shah
Ronak Shah

Reputation: 388982

A vectorized approach to generate the matrix would be to first build a 0-matrix then create a row/column index based on number of columns and number of rows to assign 1.

nr <- 3
nc <- 12
f.con <- matrix(0, nrow = nr, ncol = nc)
f.con[cbind(rep(seq_len(nr), each = nc/nr), seq_len(nc))] <- 1

f.con
#     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
#[1,]    1    1    1    1    0    0    0    0    0     0     0     0
#[2,]    0    0    0    0    1    1    1    1    0     0     0     0
#[3,]    0    0    0    0    0    0    0    0    1     1     1     1

Upvotes: 1

tpetzoldt
tpetzoldt

Reputation: 5813

Maybe something similar to this:

x <- rep(rep(c(1,0), c(4,12)), 3)[1:(3*12)]
matrix(x, ncol=12, byrow=TRUE)

Upvotes: 0

Related Questions