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.