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 ``*``

.

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)}

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

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

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!

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.