I have a vector of size 700000 with all zeroes inside of it. I am trying to change the value in an index to 1. I get the index by a calculation. Here's the code:
#lang racket
; Make bitvector
(define bitvector (make-vector 700000 0))
; Fill indices
(define fillvector
(lambda (hashlist dict)
(cond [(null? hashlist) (cdr dict)]
[(null? dict) '()]
[else (vector-set! bitvector ((car hashlist) (car dict)) 1) (fillvector (cdr hashlist) dict)]
)
))
I call fillvector like this: (fillvector hashfl-1 dictionary). dictionary is a bunch of words:
(define dictionary '( (h e l l o)
(w a y)
(r a i n b o w) ))
I get this error after I run that command:
vector-set!: contract violation
expected: exact-nonnegative-integer?
given: 415458.0
argument position: 2nd
other arguments...:
'#(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0...
1
I believe the error is because the multiplication method can return a decimal value (though I made sure it would always be .0). Is there anything else I can do? Any help would be appreciated, thanks!
The procedure for converting a floating-point ("inexact") number to a non-floating-point ("exact") number is inexact->exact (or exact in R6RS and R7RS).
> (inexact->exact 415458.0)
415458
Related
I want to create a random Matrix with values of zeros and ones. With this presumption, there will be more zeros instead of ones! So I guess there should be something like a weighted Bernoulli distribution to choose between 0 or 1 each time (and more probability for choosing 0). I prefer not to limit it to just nxn matrices! I can try in an utterly not standard way like this:
julia> let mat = Matrix{Int64}(undef, 3, 5)
zero_or_one(shift) = rand()+shift>0.5 ? 0 : 1
foreach(x->mat[x]=zero_or_one(0.3), eachindex(mat))
end
julia> mat
3×5 Matrix{Int64}:
1 1 1 0 1
0 1 1 1 1
0 1 1 0 1
Note that this doesn't do the job. Because as you can see, I get more ones instead of zeros in the result.
Is there any more optimal or at least creative way? Or any module to do it?
Update:
It seems the result of this code will never change whether I change the value of shift or not 😑.
using SparseArrays?
julia> sprand(Bool, 1_000_000,1_000_000, 1e-9)
1000000×1000000 SparseMatrixCSC{Bool, Int64} with 969 stored entries:
⠀⠀⠁⠀⠢⠀⠂⠆⡄⠀⠀⠀⡈⠀⠐⠀⠁⠐⠂⠀⠀⢀⠤⠀⠀⠀⠄⠐⢀⠘⠈⠀⢂⠐⠀⠀⠆⠀⠠⠀⠀⠀⠀⢀⠈⠁⠀⠑⠀⢀⠐⠀
⠄⠀⡀⠀⠒⠠⠨⢀⣀⠀⠀⠀⠐⠤⠈⠀⠀⠀⠀⠀⠁⠁⠄⠐⠑⠅⢄⠠⠐⠀⠀⠀⠁⢀⠋⠂⠂⠂⠀⠀⠀⠀⠀⠀⠈⠄⠀⠀⠀⠄⠈⠀
⠠⠄⠀⢀⠀⢁⠐⠀⠁⠂⢂⠂⠀⠀⠠⠀⠀⠀⠁⠀⠈⠀⠀⠂⠀⠀⢀⠂⠀⠈⠀⠀⠀⠠⠀⠂⠄⠀⠄⠀⢀⠀⠀⠉⠀⠠⠤⠀⠒⡐⠀⠂
⢀⠂⠁⠀⠐⠀⠀⠀⠄⠀⢀⡘⠁⠂⠁⠀⠂⢀⠂⠅⡀⠀⠈⠡⠈⠉⢀⠩⠉⠄⡀⠀⠀⠐⠀⡀⡄⠈⠀⢀⠀⠂⠌⠀⠀⠂⠀⠀⠁⠀⠀⠀
⠂⠠⠀⡀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠂⠐⠀⠀⠂⡁⠁⠉⠈⠀⠀⠁⠀⠄⢀⠤⠀⠀⠁⡂⠠⠀⠄⠀⠀⡀⠀⢀⠥⠀⢉⠀⠀⠄⠁⠀
⠈⠀⠀⠀⠀⠅⠀⠀⠈⠀⠄⡄⠀⠀⠀⠠⠄⠈⠠⠀⠀⠐⠂⠀⠀⠀⠀⠆⠠⠀⠀⠀⠐⠀⠐⠀⠀⠀⠀⠀⠀⡀⠌⢠⠀⠀⠂⠐⠈⠀⠀⠐
⠀⡀⠁⠈⡀⠀⢀⠁⠈⠠⡈⠁⢄⠈⠀⠀⠀⢁⠐⣀⠂⠄⠄⢀⠠⠀⠐⠀⠡⠠⠄⠈⢄⢈⠂⠈⠆⠀⠁⠀⠀⠀⠃⠀⠀⠠⠀⠐⠀⠐⠘⡀
⠀⠂⠁⠰⠁⠀⠀⠀⠀⠄⠀⣐⠀⡄⠤⡀⠀⠄⠀⠐⠀⠉⠁⠀⠈⢀⣐⠠⠀⠀⠂⠀⠀⠀⠠⠂⠐⠁⠀⠀⠀⠐⡈⠀⠐⡀⠠⡁⡀⠠⡀⠈
⠈⠀⠀⠠⠀⠀⠀⠁⠠⠐⠀⠐⠄⡀⠠⠀⠀⠀⠐⡀⠀⠀⠄⠀⠀⢒⠈⠊⠀⢢⡠⠀⠀⠀⡈⠀⠀⠀⠀⠈⠉⠃⠀⡀⡉⠀⢁⠔⠀⠀⠂⠀
⠀⠀⠀⡐⠠⢀⠀⡐⠀⠈⢀⠀⠀⠀⠐⠪⠀⠂⡄⠐⠀⢀⠀⠈⠀⠀⠰⠀⠀⠀⠈⠀⠀⠠⠀⠀⠐⠀⠀⠠⠀⠀⡀⠄⠈⢂⠂⠌⠀⠀⠐⠀
⢀⠜⢈⠀⠤⠂⢄⠀⠘⠀⠀⠀⠈⠀⠀⢀⠄⠀⠠⠀⠠⠀⠀⠀⠁⠐⠁⠀⠀⠈⠁⠀⠀⢀⠀⢄⠀⠄⠀⠀⠀⠀⠀⡀⢄⠀⠅⠀⠀⠀⠀⠀
⠠⠦⠀⡐⠈⠐⠀⡄⠀⠄⠀⠀⠀⠀⡐⠀⠀⠌⠀⠨⠀⠀⠩⢀⠁⠀⠈⠐⠐⠀⠀⠀⠀⡐⠈⠀⠁⠘⠀⢀⠀⠀⠈⠀⠈⠀⠀⠐⠀⠐⠀⠈
⠀⠀⠀⢄⠤⠀⡀⠀⠀⠬⠀⠀⠂⡡⠀⠌⠠⠠⠀⠀⢀⢔⠀⠀⠀⠀⢀⠄⠀⡈⠀⠀⠈⠄⡀⠐⠀⠠⠀⠀⠠⠂⠠⠑⠀⠀⡄⢀⠁⠀⠀⢁
⠀⡀⠀⠀⠄⠀⠀⡀⠀⠀⠀⠄⠀⠂⠀⠁⠀⠀⠁⡠⠀⠀⠡⠀⠂⠂⠄⠀⣀⠄⠊⢀⠁⠀⠄⠀⠀⢀⠀⠄⠀⠁⡀⠈⠁⠀⠀⠀⢂⠀⠈⠂
⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠠⡠⢐⠀⠀⠁⠀⠂⠀⠐⠀⠒⠈⡀⡂⢀⠀⠀⠀⠡⠌⠀⠀⢀⠄⠀⢐⠀⠀⢀⠠⠀⠀⠂⠀⠀⠈⠄⠠⡠⠀⡀
⢀⠲⠀⠀⠈⠀⠀⠂⠀⠀⠀⠀⠀⣀⠨⠁⢀⠀⠀⠀⠀⠀⠰⠀⠀⢠⠀⠁⠀⢀⢀⢀⠀⡡⠀⠈⠁⠀⠁⠠⠀⡀⠀⡀⠀⠐⠀⠐⠁⡀⠂⠈
⢀⠄⠀⠀⠀⠀⠡⠀⠀⠀⠀⠀⠀⠀⢀⠀⣂⠀⠀⠀⠂⠀⠀⠀⠀⠀⠁⠀⢀⠐⠀⠀⠐⠋⠀⠀⠀⢢⠠⠀⠂⠐⠄⢈⠠⠤⠀⡀⠀⠀⠀⠀
⠀⠠⠀⠄⢀⠄⠀⠑⠀⠀⠀⠄⠀⡠⠁⡀⢔⠠⢐⠀⢀⠀⠢⠀⠀⠈⠐⠀⠀⠀⠄⠂⠀⠀⠀⠀⠀⠀⡄⠀⡈⠀⠀⠀⡀⠀⠊⡀⠀⢠⠀⠀
⠀⠀⠒⠀⡀⢐⠄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠁⠄⠀⠀⠀⠀⠀⡄⢀⡀⠀⠀⠀⠀⢀⢀⢀⠁⠁⠀⠁⠔⠀⠀⠀⠂⠀⠒⠀⢀⢈⢀⠀⠀
⠈⠀⠀⡂⠀⠁⢐⡀⠀⠀⠂⠀⠀⡂⠄⠊⠀⠀⠄⢀⠈⠈⠁⠀⠀⠈⠒⠀⠠⠑⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠄⠆⢄⠀⠀⠂⠂⠀⡀⠀⠀
⠀⠠⠄⠀⠀⠠⡀⠠⠀⠠⠀⠐⠀⠀⡌⠨⢀⠀⠀⠁⠀⠂⠀⡀⠄⠴⠀⢠⠄⠄⠄⡀⠀⠀⠂⢠⠀⠀⠀⠜⠐⠀⠀⠁⢠⠀⠄⠐⠁⠂⠀⠁
⠈⠀⠀⠀⠈⠐⠂⠈⠆⢈⠐⡀⠈⢀⠀⠐⠀⠰⠂⠀⠀⠀⠀⠀⠀⠠⠀⡂⠨⠀⠈⡀⠁⠀⠤⠈⠐⠂⠀⠀⡀⠀⠀⠀⠀⠢⠀⠠⠀⠀⠁⠀
⠠⠈⠀⠈⠠⡀⠀⠠⠀⠠⠀⠀⠐⢄⠜⠀⠈⠀⠄⡁⠀⠠⠀⠀⠀⠁⠀⠡⡀⠈⠐⠀⠂⠀⠀⠀⠀⠐⠐⡈⢀⡠⡂⠀⠀⠐⠀⠄⠀⠀⠀⠁
⢀⠁⠀⢠⠂⢁⠄⡅⠀⠠⠀⠄⠀⠠⠀⠈⡀⠈⠂⠀⠨⠈⢀⠀⢀⡈⠀⠈⡈⠂⠀⠈⠀⠀⡀⠀⠀⠀⠀⠀⠀⠊⠄⠠⠀⠀⠄⠊⠀⠈⠄⠀
⠂⠀⠀⠀⠌⠁⢀⠀⠐⠀⠀⠈⠀⠀⠁⠀⢀⠁⠪⠠⠀⠀⢐⠀⠀⠄⠀⠂⢀⡀⢐⠁⠀⣀⠒⠀⢀⢀⠀⠠⢂⠀⠀⠠⠀⠄⠐⠄⠁⠀⠀⠀
⠐⠀⠠⠀⠀⡀⠀⠄⠄⠐⠀⠁⠀⠀⠀⠀⠄⠄⠀⠀⢀⠂⠀⠰⠀⠀⠊⠀⢀⠀⠤⠀⠀⠀⠉⠀⠀⢀⠀⠁⠁⠀⠈⠁⠀⡠⡀⠐⠐⠀⠀⠀
I'd choose the Bernoulli distribution for this. Specify a success rate p, which takes value 1 with probability p and 0 with probability 1-p.
using Distributions
mat = rand(Bernoulli(0.1), 3, 4)
3×4 Matrix{Bool}:
1 0 0 0
0 0 0 0
0 0 0 0
As for your code, you chose rand()+shift>0.5 ? 0 : 1, that means if you write zero_or_one(0.3) it will give ones with probability 0.2 and zeros with probability 0.8, etc.
If you are OK with a BitMatrix:
julia> onesandzeros(shape...; threshold=0.5) = rand(shape...) .< threshold
onesandzeros (generic function with 1 method)
julia> onesandzeros(5, 8; threshold=0.2)
5×8 BitMatrix:
0 0 0 0 0 0 1 1
0 0 0 0 1 1 1 0
0 1 1 0 0 0 0 0
0 0 0 0 1 0 1 0
0 0 0 0 0 0 0 0
This amounts to sampling from a Binomial distribution.
If 0 and 1 should be equally probable, the default Binomial coefficient p = 0.5 encodes this:
julia> using Distributions
julia> rand(Binomial(), 3, 5)
3×5 Matrix{Int64}:
1 1 1 1 1
1 0 1 0 0
0 0 0 1 1
The number of 1s in the matrix is proportional to the parameter p, so if the matrix should on average contain ~10% 1 and ~90% 0, this is the same as sampling from Binomial(1, 0.1):
julia> rand(Binomial(1, 0.1), 3, 5)
3×5 Matrix{Int64}:
0 0 1 0 0
0 0 0 0 0
0 0 0 1 1
See also: Distributions.Binomial
Although based on some comments, I was somewhat convinced that the result of my code was reasonable, each time I investigated its simple procedure, I couldn't withdraw from focusing on it. I found the snag in my code. I forgot that the let blocks create a new hard scope area. So if I try returning the mat it would show a different and expected result for each run:
julia> let mat = Matrix{Int64}(undef, 3, 5)
zero_or_one(shift) = rand()+shift>0.5 ? 0 : 1
foreach(x->mat[x]=zero_or_one(0.3), eachindex(mat))
return mat
end
3×5 Matrix{Int64}:
0 0 0 0 1
0 0 0 0 0
1 0 0 1 0
Then, for making it available in the global scope, using a begin block will make the job get done:
julia> begin mat = Matrix{Int64}(undef, 3, 5)
zero_or_one(shift) = rand()+shift>0.5 ? 0 : 1
foreach(x->mat[x]=zero_or_one(0.3), eachindex(mat))
end
julia> mat
3×5 Matrix{Int64}:
0 1 0 0 1
0 0 0 0 0
1 0 0 1 0
(Note that the above results aren't precisely the same.)
In my Jupyter notebook I have the following Markdown code block:
````python
[[0 1 0 0 0 0]
[0 1 1 0 1 1] - [0 0 1 0 0 0]
[0 0 0 0 1 0]
[0 0 0 0 0 1]]
````
which is rather unexpectedly rendering as on my local machine as well as on Nbviewer. In other words the whitespace in front of the first vector [[0 1 0 0 0 0] seems to be getting ignored. I have used single spaces to create this whitespace, not tabs.
Any idea on how to resolve this problem? Thank you.
When dealing with recursive equations in mathematics, it is common to write equations that hold over some range k = 1,...,d with the implicit convention that if d < 1 then the set of equations is considered to be empty. When programming in R I would like to be able to write for loops in the same way as a mathematical statement (e.g., a recursive equation) so that it interprets a range with upper bound lower than the lower bound as being empty. This would ensure that the syntax of the algorithm mimics the syntax of the mathematical statement on which it is based.
Unfortunately, R does not interpret the for loop in this way, and so this commonly leads to errors when you program your loops in a way that mimics the underlying mathematics. For example, consider a simple function where we create a vector of zeros with length n and then change the first d values to ones using a loop over the elements in the range k = 1,...,d. If we input d < 1 into this function we would like the function to recognise that the loop is intended to be empty, so that we would get a vector of all zeros. However, using a standard for loop we get the following:
#Define a function using a recursive pattern
MY_FUNC <- function(n,d) {
OBJECT <- rep(0, n);
for (k in 1:d) { OBJECT[k] <- 1 }
OBJECT }
#Generate some values of the function
MY_FUNC(10,4);
[1] 1 1 1 1 0 0 0 0 0 0
MY_FUNC(10,1);
[1] 1 0 0 0 0 0 0 0 0 0
MY_FUNC(10,0);
[1] 1 0 0 0 0 0 0 0 0 0
#Not what we wanted
MY_FUNC(10,-2);
[1] 1 1 1 1 1 1 1 1 1 1
#Not what we wanted
My Question: Is there any function in R that performed loops like a for loop, but interprets the loop as empty if the upper bound is lower than the lower bound? If there is no existing function, is there a way to program R to read loops this way?
Please note: I am not seeking answers that simply re-write this example function in a way that removes the loop. I am aware that this can be done in this specific case, but my goal is to get the loop working more generally. This example is shown only to give a clear view of the phenomenon I am dealing with.
There is imho no generic for-loop doing what you like but you could easily make it by adding
if(d > 0) break
as the first statement at the beginning of the loop.
EDIT
If you don't want to return an error when negative input is given you can use pmax with seq_len
MY_FUNC <- function(n,d) {
OBJECT <- rep(0, n);
for (k in seq_len(pmax(0, d))) { OBJECT[k] <- 1 }
OBJECT
}
MY_FUNC(10, 4)
#[1] 1 1 1 1 0 0 0 0 0 0
MY_FUNC(10, 1)
#[1] 1 0 0 0 0 0 0 0 0 0
MY_FUNC(10, 0)
#[1] 0 0 0 0 0 0 0 0 0 0
MY_FUNC(10, -2)
#[1] 0 0 0 0 0 0 0 0 0 0
Previous Answer
Prefer seq_len over 1:d and it takes care of this situation
MY_FUNC <- function(n,d) {
OBJECT <- rep(0, n);
for (k in seq_len(d)) { OBJECT[k] <- 1 }
OBJECT
}
MY_FUNC(10, 4)
#[1] 1 1 1 1 0 0 0 0 0 0
MY_FUNC(10, 1)
#[1] 1 0 0 0 0 0 0 0 0 0
MY_FUNC(10, 0)
#[1] 0 0 0 0 0 0 0 0 0 0
MY_FUNC(10, -2)
Error in seq_len(d) : argument must be coercible to non-negative integer
The function can be vectorized
MY_FUNC <- function(n,d) {
rep(c(1, 0), c(d, n -d))
}
MY_FUNC(10, 4)
#[1] 1 1 1 1 0 0 0 0 0 0
MY_FUNC(10, 1)
#[1] 1 0 0 0 0 0 0 0 0 0
MY_FUNC(10, 0)
#[1] 0 0 0 0 0 0 0 0 0 0
MY_FUNC(10, -2)
Error in rep(c(1, 0), c(d, n - d)) : invalid 'times' argument
I am trying to store the output data from the forloop in the n.I matrix at the end of the code, but I am certain that something is wrong with my output matrix. It is giving me all the same values, either 0 or 1. I know that print(SS) is outputting the correct values and can see that the forloop is working properly.
Does anyone have any advice on how to fix the matrix, or any way that I am able to store the data from the forloop? Thanks in advance!
c=0.2
As=1
d=1
d0=0.5
s=0.5
e=0.1
ERs=e/As
C2 = c*As*exp(-d*s/d0)
#Island States (Initial Probability)
SS=0
for(i in 1:5) {
if (SS > 0) {
if (runif(1, min = 0, max = 1) < ERs){
SS = 0
}
}
else {
if (runif(1, min = 0, max = 1) < C2) {
SS = 1
}
}
print(SS)
}
n.I=matrix(c(SS), nrow=i, ncol=1, byrow=TRUE)
The efficient solution here is not to use a loop. It's unnecessary since the whole task can be easily vectorized.
Z =runif(100,0,1)
as.integer(x <= Z)
#[1] 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 1 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
#[70] 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
you can save them in a list. Not very efficient but gets the job done.
list[[1]] indicates the first element saved in a list if you want to retrieve it.
list_pos <- list() # create the list out of the for loop
for(i in 1:100) {
c=0.10 #colonization rate
A=10 #Area of all islands(km^2)
d=250 #Distance from host to target (A-T)
s=0.1 #magnitude of distance
d0=100 #Specific "half distance" for dispersal(km)
C1 = c*A*exp(-d/d0) #Mainland to Target colonization
Z =runif(1,0,1)
x <- C1*A
if(x <= Z) {
list_pos[[i]] <- print("1") # Here you can store the 1 results.print is actually not necessary.
}
if(x >= Z){
list_pos[[i]] <- print("0") # Here you can store the 0 results.print is actually not necessary.
}
}
I have an object currency I would like to select one column and the rows equal to 1 with the variable Pair.
>currency
EURUSD EURUSDi USDJPY USDJPYi GBPUSD GBPUSDi AUDUSD AUDUSDi XAUUSD XAUUSDi zeroes
2000-07-16 0 0 0 0 0 1 0 0 0 0 0
2000-07-23 0 0 0 0 0 1 0 0 0 0 0
2000-07-30 0 0 0 0 0 1 0 0 0 0 0
2000-08-06 0 0 0 0 0 0 0 0 0 1 0
2000-08-13 0 1 0 0 0 0 0 0 0 0 0
From the console I can do it with subset like this :
> subset(currency$GBPUSDi, GBPUSDi == 1)
GBPUSDi
2000-07-16 1
2000-07-23 1
2000-07-30 1
2000-08-06 1
2000-08-13 1
2000-08-20 1
But as soon as it is passed in a script with variable Pair it fails. I've searched for hours in the documentation and I'm having a headache trying to figure out what is wrong.
Please find the different command I've try :
subset (currency$Pair, Pair == 1)
subset (currency, Pair = 1, select = Pair)
weights$Cur[currency$Pair = 1]
The one that works is currency[,c(Pair)] but it only select column, how can I complete with row selection of Pair = 1 ?
currency[,c(Pair)][Pair = 1] and subset (currency[,c(Pair)], Pair = 1) with = or == doesn't work.
currency$Pair[currency$Pair == 1] should work ($Pair select column Pair and [currency$Pair == 1] select values equal to 1). It looks like it don't work in your case, because currency don't contain variable Pair.
If currency is not a dataframe but matrix, you can try
currency[currency[, c("Pair")] == 1, c("Pair")]