How do you generate a regular non-integer sequence in julia? - julia

How are regular, non-integer sequences generated in julia?
I'm trying to get 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
In MATLAB, I would use
0.1:0.1:1
And in R
seq(0.1, 1, by = 0.1)
But I can't find anything except integer sequences in julia (e.g., 1:10). Searching for "sequence" in the docs only gives me information about how strings are sequences.

Similarly to Matlab, but with the difference that 0.1:0.1:1 defines a Range:
julia> typeof(0.1:0.1:1)
Range{Float64} (constructor with 3 methods)
and thus if an Array is needed:
julia> [0.1:0.1:1]
10-element Array{Float64,1}:
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1.0
Unfortunately, this use of Range is only briefly mentioned at this point of the documentation.
Edit: As mentioned in the comments by #ivarne it is possible to achieve a similar result using linspace:
julia> linspace(.1,1,10)
10-element Array{Float64,1}:
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1.0
but note that the results are not exactly the same due to rounding differences:
julia> linspace(.1,1,10)==[0.1:0.1:1]
false

The original answer is now deprecated. You should use collect() to generate a sequence.
## In Julia
> collect(0:.1:1)
10-element Array{Float64,1}:
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1.0
## In R
> seq(0, 1, .1)
[1] 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

They are generated the same way as in Matlab
julia> sequence = 0:.1:1
0.0:0.1:1.0
Alternatively, you can use the range() function, which allows you to specify the length, step size, or both
julia> range(0, 1, length = 5)
0.0:0.25:1.0
julia> range(0, 1, step = .01)
0.0:0.01:1.0
julia> range(0, step = .01, length = 5)
0.0:0.01:0.04
You can still do all of the thinks you would normally do with a vector, eg indexing
julia> sequence[4]
0.3
math and stats...
julia> sum(sequence)
5.5
julia> using Statistics
julia> mean(sequence)
0.5
This will (in most cases) work the same way as a vector, but nothing is actually allocated. It can be comfortable to make the vector, but in most cases you shouldn't (it's less performant). This works because
julia> sequence isa AbstractArray
true
If you truly need the vector, you can collect(), splat (...) or use a comprehension:
julia> v = collect(sequence)
11-element Array{Float64,1}:
0.0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1.0
julia> v == [sequence...] == [x for x in sequence]
true

Related

Replace the specific element in array also change other one [duplicate]

This question already has answers here:
Creating copies in Julia with = operator
(2 answers)
Closed 3 years ago.
Here is the example code. I can't understand why the first element in array B also be revised. Can I keep the same element in array B?
julia> A = [0.0 0.1 0.2 0.3];
julia> B = A;
julia> A[1] = 0.1;
julia> A
1×4 Array{Float64,2}:
0.1 0.1 0.2 0.3
julia> B
1×4 Array{Float64,2}:
0.1 0.1 0.2 0.3
Julia Array is passed by reference. You need to create a copy:
julia> A = [0.0 0.1 0.2 0.3];
julia> B = deepcopy(A)
1×4 Array{Float64,2}:
0.0 0.1 0.2 0.3
julia> A[1] = 0.1;
julia> A, B
([0.1 0.1 0.2 0.3], [0.0 0.1 0.2 0.3])
Note that for this code just copy will be also enough but if for example you have an Array of objects that you mutate deepcopy should be used.

Lower RAM consumption for a transformation of a transition matrix

I've written the following two functions, that take as input a transition matrix and which nodes should be at absorbing states and transforms it.
The first function set.absorbing.states() has 3 arguments. tm is the initial transition matrix, the second one inn is one specified innitial node, while the third one soi is the set of interest. By 'set of interest', I mean a set of nodes in that matrix that must been set as absorbing states. Such an initial matrix is the following:
tm <- read.table(row.names=1, header=FALSE, text="
A 0.2 0.3 0.1 0.2 0.1 0.1
B 0.3 0.1 0.1 0.2 0.2 0.1
C 0 0.2 0.4 0.1 0.2 0.1
D 0.2 0.1 0.2 0.3 0.1 0.1
E 0.2 0.2 0.1 0.2 0.1 0.2
F 0.3 0.2 0.4 0.1 0 0")
colnames(tm) <- row.names(tm)
As you can see there are no absorbing states in that matrix. Let's say for example that we want to set as absorbing states the A and E and a randomly selected initial node B.
By executing the first function tm1 <- set.absorbing.states( tm , "B", c("A","E")) we are getting back a matrix that the absorbing states have been setted:
A B C D E F
A 1.0 0.0 0.0 0.0 0.0 0.0
B 0.3 0.1 0.1 0.2 0.2 0.1
C 0.0 0.2 0.4 0.1 0.2 0.1
D 0.2 0.1 0.2 0.3 0.1 0.1
E 0.0 0.0 0.0 0.0 1.0 0.0
F 0.3 0.2 0.4 0.1 0.0 0.0
As you can see, A and E have been changed into absorbing states.
The next step is to transform that matrix into a way that all absorbing state nodes (both rows and columns) go to the end. So by running ptm <- transform.tm( tm1, c("A","E") ) we get back a matrix that looks like:
B C D F A E
B 0.1 0.1 0.2 0.1 0.3 0.2
C 0.2 0.4 0.1 0.1 0.0 0.2
D 0.1 0.2 0.3 0.1 0.2 0.1
F 0.2 0.4 0.1 0.0 0.3 0.0
A 0.0 0.0 0.0 0.0 1.0 0.0
E 0.0 0.0 0.0 0.0 0.0 1.0
You can see now clearly that A and E nodes went to the end of that matrix.
Here follows the function I'm using.
set.absorbing.states <- function ( tm, inn, soi )
{
set <- which( row.names(tm) %in% soi )
set <- set[which( set != inn )]
for (i in set )
tm[i,] <- 0
for (i in set)
tm[i,i] <- 1
tm
}
transform.tm <- function ( tm, soi )
{
end_sets <- which(row.names(tm) %in% soi)
ptm <- rbind( cbind(tm[-end_sets, -end_sets], tm[-end_sets, end_sets]) , cbind(tm[end_sets, -end_sets], tm[end_sets, end_sets]) )
ptm
}
The thing now is that with such small matrices, everything is working properly. But I tried to use a big matrix (20.000*20.000) and it needed 32GB RAM to execute the second function.
So is there any way to execute this in more resource efficient way ?
Use indexing will significantly reduce the number of copies that your transformation function is creating (via rbind and cbind). It is probably a bit simpler conceptually (conditional on a solid understanding of indexing with [).
transform.tm1 <- function ( tm, soi ) {
newOrder <- c(setdiff(row.names(tm), soi), soi)
tm[newOrder, newOrder]
}
Here, setdiff is used to pull the non matching names and put them at the front a the vector. Then, simply reorder the matrix via row/column names.
This returns
transform.tm1(tm1, c("A", "E"))
B C D F A E
B 0.1 0.1 0.2 0.1 0.3 0.2
C 0.2 0.4 0.1 0.1 0.0 0.2
D 0.1 0.2 0.3 0.1 0.2 0.1
F 0.2 0.4 0.1 0.0 0.3 0.0
A 0.0 0.0 0.0 0.0 1.0 0.0
E 0.0 0.0 0.0 0.0 0.0 1.0
check that they return the same results
identical(transform.tm(tm1, c("A", "E")), transform.tm1(tm1, c("A", "E")))
[1] TRUE

Normalize blocks/sub-matrices within a matrix

I want to normalize (i.e., 0-1) blocks/sub-matrices within a square matrix based on row/col names. It is important that the normalized matrix correspond to the original matrix. The below code extracts the blocks, e.g. all col/row names == "A" and normalizes it by its max value. How do I put that matrix of normalized blocks back together so it corresponds to the original matrix, such that each single value of the normalized blocks are in the same place as in the original matrix. I.e. you cannot put the blocks together and then e.g. sort the normalized matrix by the original's matrix row/col names.
#dummy code
mat <- matrix(round(runif(90, 0, 50),),9,9)
rownames(mat) <- rep(LETTERS[1:3],3)
colnames(mat) <- rep(LETTERS[1:3],3)
mat.n <- matrix(0,nrow(mat),ncol(mat), dimnames = list(rownames(mat),colnames(mat)))
for(i in 1:length(LETTERS[1:3])){
? <- mat[rownames(mat)==LETTERS[1:3][i],colnames(mat)==LETTERS[1:3][i]] / max(mat[rownames(mat)==LETTERS[1:3][i],colnames(mat)==LETTERS[1:3][i]])
#For example,
mat.n[rownames(mat)==LETTERS[1:3][i],colnames(mat)==LETTERS[1:3][i]] <- # doesn't work
}
UPDATE
Using ave() as #G. Grothendieck suggested works for the blocks, but I'm not sure how it's normalizing beyond that.
mat.n <- mat / ave(mat, rownames(mat)[row(mat)], colnames(mat)[col(mat)], FUN = max)
Within block the normalization works, e.g.
mat[rownames(mat)=="A",colnames(mat)=="A"]
A A A
A 13 18 15
A 38 33 41
A 12 18 47
mat.n[rownames(mat.n)=="A",colnames(mat.n)=="A"]
A A A
A 0.2765957 0.3829787 0.3191489
A 0.8085106 0.7021277 0.8723404
A 0.2553191 0.3829787 1.0000000
But beyond that, it looks weird.
> round(mat.n,1)
A B C A B C A B C
A 0.3 0.2 0.1 0.4 0.2 1.0 0.3 0.9 1.0
B 0.9 0.8 0.9 0.4 0.5 0.4 0.4 0.9 0.0
C 0.0 0.4 0.4 0.0 0.8 0.5 0.4 0.9 0.0
A 0.8 0.9 0.5 0.7 0.9 0.6 0.9 0.4 0.4
B 0.1 0.8 0.7 1.0 0.3 0.5 0.1 1.0 0.8
C 0.4 0.0 0.2 0.2 0.2 0.6 1.0 0.4 1.0
A 0.3 0.4 0.3 0.4 0.6 0.8 1.0 1.0 0.3
B 0.6 0.2 0.5 0.9 0.3 0.2 0.9 0.3 1.0
C 0.5 0.9 0.7 1.0 0.4 0.5 1.0 1.0 0.9
In this case, I would expect 3 1s across the whole matrix- 1 for each block. But there're 10 1s, e.g. mat.n[3,2], mat.n[1,9]. I'm not sure how this function normalized between blocks.
UPDATE 2
#Original matrix.
#Suggested solution produces `NaN`
mat <- as.matrix(read.csv(text=",1.21,1.1,2.2,1.1,1.1,1.21,2.2,2.2,1.21,1.22,1.22,1.1,1.1,2.2,2.1,2.2,2.1,2.2,2.2,2.2,1.21,2.1,2.1,1.21,1.21,1.21,1.21,1.21,2.2,1.21,2.2,1.1,1.22,1.22,1.22,1.22,1.21,1.22,2.1,2.1,2.1,1.22
1.21,0,0,0,0,0,0,0,0,292,13,0,0,0,0,0,0,0,0,0,0,22,0,0,94,19,79,0,9,0,126,0,0,0,0,0,0,0,0,0,0,0,0
1.1,0,0,0,155,166,0,0,0,0,0,0,4,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34,0,0,0,0,0,0,0,0,0,0
2.2,0,0,0,0,0,0,0,0,0,0,0,0,0,6,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.1,0,201,0,0,79,0,0,0,0,0,0,0,11,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.1,0,33,0,91,0,0,0,0,0,0,0,0,9,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.21,8,0,0,0,0,0,0,0,404,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,26,18,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0
2.2,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,162,79,1,0,0,0,0,0,0,0,0,10,0,27,0,0,0,0,0,0,0,0,0,0,0
2.2,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,33,17,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0
1.21,207,0,0,0,0,1644,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,16,17,402,0,0,0,606,0,0,0,0,0,0,0,0,0,0,0,0
1.22,13,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,0,0,15,0,0,0,0,0
1.22,0,0,0,0,0,0,0,0,0,71,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,374,6,121,6,21,0,0,0,0
1.1,0,0,0,44,0,0,0,0,0,0,0,0,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,33,0,0,0,0,0,0,0,0,0,0
1.1,0,0,0,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0
2.2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
2.1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,0,0,0,0,353,116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29,0,5,0
2.2,0,0,0,0,0,0,0,37,0,0,0,0,0,4,0,0,0,36,46,62,0,0,0,0,0,0,0,0,0,0,73,0,0,0,0,0,0,1,0,0,0,0
2.1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,61,0,0,0,0,0,0,0,38,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
2.2,17,0,23,0,0,0,444,65,0,0,0,0,0,0,0,78,0,0,42,30,15,0,0,0,0,0,0,0,4,0,18,0,0,0,0,0,0,0,0,0,0,0
2.2,0,0,0,0,0,0,75,8,0,0,0,0,0,0,0,87,0,74,0,85,0,0,0,0,0,0,0,0,1,0,19,0,25,0,0,0,0,0,0,0,0,0
2.2,0,0,13,0,0,0,12,20,0,0,0,0,0,0,0,118,0,29,92,0,25,0,0,0,0,0,0,0,0,0,16,0,48,0,0,0,0,0,0,0,0,0
1.21,14,0,1,0,0,0,0,0,17,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,3,0,20,0,0,0,0,0,0,0,0,0,0,0
2.1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,204,0,0,0,0,0,0,0,133,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,44,0,0
2.1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67,0,0,0,0,0,0,143,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,12,15,0
1.21,79,0,0,0,0,0,0,0,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,38,26,6,9,0,112,0,0,0,0,0,0,0,0,0,0,0,0
1.21,11,0,0,0,0,17,0,0,49,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1.21,40,0,0,0,0,0,0,0,122,0,0,0,0,0,0,0,0,0,0,0,3,0,0,24,11,0,887,20,0,389,0,0,0,0,0,0,0,0,0,0,0,0
1.21,14,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,50,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1.21,34,0,0,0,0,26,0,0,56,0,0,0,0,0,0,0,0,0,0,0,0,0,0,54,9,297,13,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0
2.2,0,0,0,0,0,0,39,0,0,0,0,0,0,0,0,25,0,17,12,20,25,0,0,0,0,0,0,0,0,0,393,0,7,0,0,0,0,0,0,0,0,0
1.21,177,0,0,0,0,8,0,0,775,0,0,0,0,0,0,0,0,0,0,0,0,0,0,113,0,227,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0
2.2,0,0,0,0,0,0,21,17,0,0,0,0,0,0,0,0,0,42,30,16,0,0,0,0,0,0,0,0,165,0,0,0,0,0,0,0,0,0,0,0,0,0
1.1,0,6,0,28,0,0,0,0,0,0,0,9,30,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.22,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,4,37,0,0,0,0,0,0,0,0,3,0,0,0,0,14,7,0,0,18,0,0,0,0
1.22,0,0,0,0,0,0,0,0,0,44,785,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,21,0,44,177,13,24,0,0,0,0
1.22,0,0,0,0,0,0,30,0,0,182,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,12,0,1231,135,17,0,0,0,0
1.22,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,73,1308,0,669,16,0,0,0,8
1.21,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,33,197,626,0,44,0,0,0,0
1.22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,37,12,80,0,0,0,0,16
2.1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,54,0
2.1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,27,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,0,0,0
2.1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,58,0,1,0,0,0,0,28,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,61,2,0,0
1.22,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,31,9,0,0,0,0"))
ids <- read.csv(text=",x
1,1.21
2,1.1
3,2.2
4,1.1
5,1.1
6,1.21
7,2.2
8,2.2
9,1.21
10,1.22
11,1.22
12,1.1
13,1.1
14,2.2
15,2.1
16,2.2
17,2.1
18,2.2
19,2.2
20,2.2
21,1.21
22,2.1
23,2.1
24,1.21
25,1.21
26,1.21
27,1.21
28,1.21
29,2.2
30,1.21
31,2.2
32,1.1
33,1.22
34,1.22
35,1.22
36,1.22
37,1.21
38,1.22
39,2.1
40,2.1
41,2.1
42,1.22")
mat <- mat[,-1]
rownames(mat) <- ids$x
colnames(mat) <- ids$x
ans <- mat / ave(mat, rownames(mat)[row(mat)], colnames(mat)[col(mat)], FUN = max)
Any help is much appreciated, thanks.
Use ave to get the maxima:
mat / ave(mat, rownames(mat)[row(mat)], colnames(mat)[col(mat)], FUN = max)
For example, there are 9 ones, as expected, and there is one 1 in each block also as expected. (There could be more than 9 if the matrix happened to have multiple maxima in one or more blocks but there shoud not be less than 9.)
set.seed(123)
mat <- matrix(round(runif(90, 0, 50),),9,9)
rownames(mat) <- rep(LETTERS[1:3],3)
colnames(mat) <- rep(LETTERS[1:3],3)
ans <- mat / ave(mat, rownames(mat)[row(mat)], colnames(mat)[col(mat)], FUN = max)
sum(ans == 1)
## [1] 9
# there are no duplicates (i.e. a block showing up more than once) hence
# there is exactly one 1 in each block
w <- which(ans == 1, arr = TRUE)
anyDuplicated(cbind(rownames(mat)[w[, 1]], colnames(mat)[w[, 2]]))
## [1] 0
ADDED
If some blocks are entirely zero (which is the case in UPDATE 2) then you will get NaNs for those blocks. If you want 0s instead for the all-zero blocks try this:
xmax <- function(x) if (all(x == 0)) 0 else x/max(x)
ave(mat, rownames(mat)[row(mat)], colnames(mat)[col(mat)], FUN = xmax)

connect two matrixes by columns and extract sub matrix

I have two matrixes (e.g., A and B). I would like to extract columns of B based on the order of A's first column:
For example
matrix A
name score
a 0.1
b 0.2
c 0.1
d 0.6
matrix B
a d b c g h
0.1 0.2 0.3 0.4 0.6 0.2
0.2 0.1 0.4 0.7 0.1 0.1
...
I want matrix B to look like this at the end
matrix B_modified
a b c d
0.1 0.3 0.4 0.2
0.2 0.4 0.7 0.1
Can this be done either in perl or R? thanks a lot in advance
I've no idea what problems you're facing. Here's how I've done it.
## get data as matrix
a <- read.table(header=TRUE, text="name score
a 0.1
b 0.2
c 0.1
d 0.6", stringsAsFactors=FALSE) # load directly as characters
b <- read.table(header=TRUE, text="a d b c g h
0.1 0.2 0.3 0.4 0.6 0.2
0.2 0.1 0.4 0.7 0.1 0.1", stringsAsFactors=FALSE)
a <- as.matrix(a)
b <- as.matrix(b)
Now subset to get your final result:
b[, a[, "name"]]
# a b c d
# [1,] 0.1 0.3 0.4 0.2
# [2,] 0.2 0.4 0.7 0.1
The error :
[.data.frame(b, , a[, "name"]) : undefined columns selected
means that you try to get a column non defined in b but exist in a$name. One solution is to use intersect with colnames(b). This will convert also the factor to a string and you get the right order.
b[, intersect(a[, "name"],colnames(b))] ## the order is important here
For example , I test this with this data:
b <- read.table(text='
a d b c
0.1 0.2 0.3 0.4
0.2 0.1 0.4 0.7',header=TRUE)
a <- read.table(text='name score
a 0.1
z 0.5
c 0.1
d 0.6',header=TRUE)
b[, intersect(a[, "name"],colnames(b))]
a c d
1 0.1 0.4 0.2
2 0.2 0.7 0.1
If your data originates as an R data structure then it would be perverse to export it and solve this problem using Perl. However, if you have text files that look like the data you have shown, then here is a Perl solution for you.
I have split the output on spaces. That can be changed very simply if necessary.
use strict;
use warnings;
use autodie;
sub read_file {
my ($name) = #_;
open my $fh, '<', $name;
my #data = map [ split ], <$fh>;
\#data;
}
my $matrix_a = read_file('MatrixA.txt');
my #fields = map $matrix_a->[$_][0], 1 .. $#$matrix_a;
my $matrix_b = read_file('MatrixB.txt');
my #headers = #{$matrix_b->[0]};
my #indices = map {
my $label = $_;
grep $headers[$_] eq $label, 0..$#headers
} #fields;
for my $row (0 .. $#$matrix_b) {
print join(' ', map $matrix_b->[$row][$_], #indices), "\n";
}
output
a b c d
0.1 0.3 0.4 0.2
0.2 0.4 0.7 0.1

modulus bug in R [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why are these numbers not equal?
Just noticed this bug in R. I'm guessing it's the way 0.6 is represented, but anyone know exactly what's going on?
According to R:
0.3 %% 0.2 = 0.1
0.4 %% 0.2 = 0
0.5 %% 0.2 = 0.1
**0.6 %% 0.2 = 0.2**
0.7 %% 0.2 = 0.1
0.8 %% 0.2 = 0
What's going on?
In addition to #joshua Ulrich's comment
from ?'%%'
%% and x %/% y can be used for non-integer y, e.g. 1 %/% 0.2, but the results are subject to representation error and so may be platform-dependent. Because the IEC 60059 representation of 0.2 is a binary fraction slightly larger than 0.2, the answer to 1 %/% 0.2 should be 4 but most platforms give 5.
also similar to why we get this
> .1 + .1 + .1 == .3
[1] FALSE
as #Ben Boker pointed out, you may want to use something like
> 3:8 %% 2 / 10
[1] 0.1 0.0 0.1 0.0 0.1 0.0

Resources