quick define a binary matrix without loop

I want to define a big binary 1024x1024 matrix M with elements 0 or 1 through two known functions: y1=f1(x), y2=f2(x) where x=1,2,..., 1024, y1<y2 are integers between 1 to 1024. I want matrix M to satisfy:
M[x,y]=1 if f1(x)<= y <= f2(x), and M[x,y]=0 otherwise. I can create such M using the for loop:
M<- matrix(0, nrow=1024, ncol=1024)
for (i in 1:1024){ M[i, f1(i):f2(i)]<= 1}
Is there a better way to define matrix M without a loop?

Hi,

I'm a bit confused by the operations to generate the numbers for the matrix. if y1 and y2 are functions that take argument x = 1:1024 and you then compare them, you only have 1024 outputs whereas your matrix needs 1024^2 number of values.

I'm confused about the translation between
M[x,y]=1 if f1(x)<= y <= f2(x), and M[x,y]=0
and
f1(i):f2(i)]<= 1

Could you provide a smaller example e.g. 3x3 with actual values and the desired output. That would help...

PJ

Here is a simple example:
f1<- function(x) {(x+1)(x+1<=10)+10(x+1>10)}
f2<- function(x) {(x+3)(x+3<=10)+10(x+3>10)}
M<- matrix(0, nrow=10, ncol=10)
for (i in 1:10) {M[i,f1(i):f2(i)]<-1 }
M
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 0 1 1 1 0 0 0 0 0 0
[2,] 0 0 1 1 1 0 0 0 0 0
[3,] 0 0 0 1 1 1 0 0 0 0
[4,] 0 0 0 0 1 1 1 0 0 0
[5,] 0 0 0 0 0 1 1 1 0 0
[6,] 0 0 0 0 0 0 1 1 1 0
[7,] 0 0 0 0 0 0 0 1 1 1
[8,] 0 0 0 0 0 0 0 0 1 1
[9,] 0 0 0 0 0 0 0 0 0 1
[10,] 0 0 0 0 0 0 0 0 0 1
Is there a way to define M without for loop?
Thanks!

The two functions are:
f1<- function(x) {(x+1)(x+1<=10)+10(x+1>10)}
f2<- function(x) {(x+3)(x+3<=10)+10(x+3>10)}
somehow the "*" operation was missing when I paste the code here.

It seems this website automatically removed my "" operation. I did double check that I have "" operation in function "(x+1)(x+1<=10)+10(x+1>10)". But it was automatically removed when I submitted it.

* has special meaning in markdown, which is what this site uses. To bypass, wrap it within backticks, like this `*`.

1 Like

This is not more elegant than your for loop solution, but it does not use a for loop.

f1<- function(x) {(x+1)*(x+1<=10)+10*(x+1>10)}
f2<- function(x) {(x+3)*(x+3<=10)+10*(x+3>10)}

library(purrr)

OutList <- map2(.x = f1(1:10), .y = f2(1:10), 
     .f = function(x,y) (x <= 1:10)*(1:10 <= y))

M <- do.call(rbind, OutList)
M
#>       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#>  [1,]    0    1    1    1    0    0    0    0    0     0
#>  [2,]    0    0    1    1    1    0    0    0    0     0
#>  [3,]    0    0    0    1    1    1    0    0    0     0
#>  [4,]    0    0    0    0    1    1    1    0    0     0
#>  [5,]    0    0    0    0    0    1    1    1    0     0
#>  [6,]    0    0    0    0    0    0    1    1    1     0
#>  [7,]    0    0    0    0    0    0    0    1    1     1
#>  [8,]    0    0    0    0    0    0    0    0    1     1
#>  [9,]    0    0    0    0    0    0    0    0    0     1
#> [10,]    0    0    0    0    0    0    0    0    0     1

Created on 2021-12-05 by the reprex package (v2.0.1)

1 Like

Yes this works! Thanks!

Thanks Yarnabrina for the hint! I have never used markdown and thus was confused.

Hi,

I can see I'm again too slow :stuck_out_tongue:
But I thought I'd share my solution too as I have a way of not using any loop or map, just basic vector operations.

f1<- function(x) {(x+1)*(x+1<=10)+10*(x+1>10)}
f2<- function(x) {(x+3)*(x+3<=10)+10*(x+3>10)}

n = 10
matrix((rep(f1(1:n), each = n) <= 1:n) *
         (1:n <= rep(f2(1:n), each = n)), 
       nrow = n, byrow = T)
#>       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#>  [1,]    0    1    1    1    0    0    0    0    0     0
#>  [2,]    0    0    1    1    1    0    0    0    0     0
#>  [3,]    0    0    0    1    1    1    0    0    0     0
#>  [4,]    0    0    0    0    1    1    1    0    0     0
#>  [5,]    0    0    0    0    0    1    1    1    0     0
#>  [6,]    0    0    0    0    0    0    1    1    1     0
#>  [7,]    0    0    0    0    0    0    0    1    1     1
#>  [8,]    0    0    0    0    0    0    0    0    1     1
#>  [9,]    0    0    0    0    0    0    0    0    0     1
#> [10,]    0    0    0    0    0    0    0    0    0     1

Created on 2021-12-06 by the reprex package (v2.0.1)

By the way, this implementation not necessarily faster, but I just took the challenge of coming up with a non-loop version

PJ

1 Like

Thanks PJ for sharing your code! My original motivation is to avoid loop since I need to define thousands of such matrices with different f1 and f2 functions. Over the past, R was slow in for loops and I was always trying to avoid doing loops. Now I found R is much faster in handling for loops. Thanks to the R and Rstudio developer people!

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.