Concatencation+collecting of ranges in Julia - julia

According to documentation, [A; B; C; ...] calls vcat(). So, to concatenate and collect a comprehension of ranges this way
>>[1:4; 6:9; 20:23]
12-element Array{Int64,1}:
1
2
3
4
6
7
8
9
20
21
22
23
I tried to use vcat(), but it does not do collecting
vcat([i:i+3 for i in [1,6,20]])
3-element Array{UnitRange{Int64},1}:
1:4
6:9
20:23
Is there a simple way to collect all values from a comprehension of ranges?

Simply add ... to get
julia> vcat([i:i+3 for i in [1,6,20]]...)
12-element Array{Int64,1}:
1
2
3
4
6
7
8
9
20
21
22
23

Related

R Script to rearrange the elements of a vector by interleaving it

How to write an R-script to initialize a vector with integers, rearrange the elements by interleaving the
first half elements with the second half elements and store in the same vector without using pre-defined function and display the updated vector.
This sounds like a homework question, and it would be nice to see some effort on your own part, but it's pretty straightforward to do this in R.
Suppose your vector looks like this:
vec <- 1:20
vec
#> [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Then you can just do:
c(t(cbind(vec[1:10], vec[11:20])))
#> [1] 1 11 2 12 3 13 4 14 5 15 6 16 7 17 8 18 9 19 10 20
This works by joining the two vectors into a 10 x 2 matrix, then transposing that matrix and turning it into a vector.
We may use matrix directly and concatenate
c(matrix(vec, nrow = 2, byrow = TRUE))
-output
[1] 1 11 2 12 3 13 4 14 5 15 6 16 7 17 8 18 9 19 10 20
data
vec <- 1:20
Or using mapply:
vec <- 1:20
c(mapply(\(x,y) c(x,y), vec[1:10], vec[11:20]))
#> [1] 1 11 2 12 3 13 4 14 5 15 6 16 7 17 8 18 9 19 10 20
We can try this using order + %%
> vec[order((seq_along(vec) - 1) %% (length(vec) / 2))]
[1] 1 11 2 12 3 13 4 14 5 15 6 16 7 17 8 18 9 19 10 20
Another way is to use rbind on the 2 halves of the vector, which creates a matrix with two rows. Then, we can then turn the matrix into a vector, which will go through column by column (i.e., 1, 11, 2, 12...). However, this will only work for even vectors.
vec <- 1:20
c(rbind(vec[1:10], vec[11:20]))
# [1] 1 11 2 12 3 13 4 14 5 15 6 16 7 17 8 18 9 19 10 20
So, for uneven vectors, we can use order, which will return the indices of the numbers in the two seq_along vectors.
vec2 <- 1:21
order(c(seq_along(vec2[1:10]),seq_along(vec2[11:21])))
# [1] 1 11 2 12 3 13 4 14 5 15 6 16 7 17 8 18 9 19 10 20 21

How to do some operation in the elements of a vector with previous elements

This may have been a very basic question, but I am scratching my head ..
Suppose I have a vector v with 10 elements
v <- 1:10
> v
[1] 1 2 3 4 5 6 7 8 9 10
Now I want to perform some operation (2 argument function) say + on its elements with previous elements, to get an output like.. 1+1 1+2 2+3 3+4.. and so on. For the first element where no previous value is there, I'll take first value only. I can perform this operation by manually creating another vector something like c(v[1], v[-length(v)]), but I think/presume there may be some direct method/in-built function to do so.
> v + c(v[1], v[-length(v)])
[1] 2 3 5 7 9 11 13 15 17 19
#OR if product is the operation
> v * c(v[1], v[-length(v)])
[1] 1 2 6 12 20 30 42 56 72 90
Please guide
This can be achieved with dplyr::lag or data.table::shift, although I am not sure if this is what you were looking for.
v + dplyr::lag(v, default = v[1])
#[1] 2 3 5 7 9 11 13 15 17 19
Perhaps you may want to try mapply.
v <- 1:10
init <- v[1]
mapply(`+`, c(init, v[-length(v)]), v)
# [1] 2 3 5 7 9 11 13 15 17 19
mapply(`*`, c(init, v[-length(v)]), v)
# [1] 1 2 6 12 20 30 42 56 72 90
mapply(`^`, c(init, v[-length(v)]), v)
# [1] 1 1 8 81 1024 15625 279936 5764801 134217728 3486784401

`map` equivalent to 2d list comprehension

In 1d, I can use either of these:
[i for i in 1:5]
or
map(1:5) do i
i
end
both produce
[1,2,3,4,5]
Is there a way to use map in higher dimensions? e.g. to replicate
[x + y for x in 1:5,y in 10:13]
which produces
5×4 Array{Int64,2}:
11 12 13 14
12 13 14 15
13 14 15 16
14 15 16 17
15 16 17 18
You can do this:
julia> map(Iterators.product(1:3, 10:15)) do (x,y)
x+y
end
3×6 Array{Int64,2}:
11 12 13 14 15 16
12 13 14 15 16 17
13 14 15 16 17 18
The comprehension you wrote is I think just collect(x+y for (x,y) in Iterators.product(1:5, 10:13)), . Note the brackets (x,y), as the do function gets a tuple. Unlike x,y when it gets two arguments:
julia> map(1:3, 11:13) do x,y
x+y
end
3-element Array{Int64,1}:
12
14
16
This, of course, is not the map equivalent that you are looking for, but in some cases like this you can use broadcasting with a vector and a transposed vector:
x = 1:5
y = (10:13)'
x .+ y
At the REPL:
julia> (1:5) .+ (10:13)'
5×4 Array{Int64,2}:
11 12 13 14
12 13 14 15
13 14 15 16
14 15 16 17
15 16 17 18

How to create a table with flexible columns based on variables control in R?

I want to create a tale like:
1 1 6 6 10 10 ...
2 2 7 7 11 11 ...
3 3 8 8 12 12 ...
4 4 9 9 13 13 ...
5 5 14 14 ...
15 15 ...
I want to use variables:
n (repeat) and m(total number of columns) and k(k=the prior columns's end number+1,for example: 6=5+1, and 10=9+1), and different number length of row
to create a table.
I know I can use like:
rep(list(1:5,6:9,10:15), each = 2)),
but how to make them as parameters using a general expression to list list(1:5,6:9,10:15,..use n,m,k expression...).
I tried to use loop for (i in 1:m) etc.. but cannot work it out
finally I want a sequence by using unlist(): 1,2,3,4,5,6,1,2,3,4,5,6......)
Many thanks.
Maybe the code below can help
len <- c(5,4,6)
res <- unlist(unname(rep(split(1:sum(len),
findInterval(1:sum(len),cumsum(len)+1)),
each = 2)))
which gives
> res
[1] 1 2 3 4 5 1 2 3 4 5 6 7 8 9 6 7 8 9 10 11 12 13 14 15 10 11 12 13 14 15
Probably, something like this would be helpful.
#Number of times to repeat
r <- 2
#Length of each sequence
len <- c(5, 4, 6)
#Get the end of the sequence
end <- cumsum(Glen)
#Calculate the start of each sequence
start <- c(1, end[-length(end)] + 1)
#Create a sequence of start and end and repeat it r times
Map(function(x, y) rep(seq(x, y), r), start, end)
#[[1]]
# [1] 1 2 3 4 5 1 2 3 4 5
#[[2]]
#[1] 6 7 8 9 6 7 8 9
#[[3]]
# [1] 10 11 12 13 14 15 10 11 12 13 14 15
You could unlist to get it as one vector.
unlist(Map(function(x, y) rep(seq(x, y), r), start, end))

Smart way to convert polars to Cartesian coordinates with numpy

I have an array of Cartesian coordinates produced from polars in a usual way:
for k in range(0, Phi_term):
for j in range(0, R_term):
X[k,j] = R[j]*np.cos(phi[k]);
Y[k,j] = R[j]*np.sin(phi[k]);
The problem is that the zeroth element of such an array corresponds to the origin of the polar circle. I would like to have an array of the same elements but starting in the top right corner. For example, elements in the current array distribute in the following way (for the upper half):
11 10 9 6 7 8
14 13 12 3 4 5
17 16 15 0 1 2
(imagine it's a circle). What I want to get is the grid starting with the zeroth element:
0 1 2 3 4 5
6 7 8 9 10 11
12 13 14 15 16 17
though preserving the values, i.e. the value of the 11th element of the initial array is now the value of the 0th element of the new array.
Is there any smart way to perform such a transformation in numpy?
def quasiCartesianOrder(arr, R_term, Phi_term):
# deal with odd phi count by starting from top of top spike.
rhsOddOffset = 0
if Phi_term % 2 == 1:
rhsOddOffset = R_term
for r in xrange(0, R_term):
yield (Phi_term + 1)/2 * R_term - r - 1
# 'rectangular' section, starting down 11 o'clock and up 1 o'clock.
phiBaseLeft = Phi_term / 2 + rhsOddOffset/R_term
phiBaseRight = Phi_term / 2
for phiLine in xrange(0, Phi_term / 2):
# down 11
base = (phiBaseLeft + phiLine) * R_term - 1
for idx in xrange(base + R_term, base, -1):
yield idx
# up 1
base = (phiBaseRight - phiLine ) * R_term
for idx in xrange(base - R_term, base):
yield idx
Behaviour:
11
10
9
14 13 12 6 7 8
17 16 15 3 4 5
20 19 18 0 1 2
Becomes
0
1
2
3 4 5 6 7 8
9 10 11 12 13 14
15 16 17 18 19 20
Result
11 10 9 14 13 12 6 7 8 17 16 15 3 4 5 20 19 18 0 1 2
The style is a generator, so that you can iterate. If you just want the indices themselves, call list with the returned generator, and you should be able to use that with numpy's index arrays stuff.

Resources