Re-slicing slices in Golang - arrays

I recently picked up the Go language, and now I am confused with the following code:
package main
import "fmt"
func main() {
a := make([]int, 5)
printSlice("a", a)
b := make([]int, 0, 5)
printSlice("b", b)
c := b[:2]
printSlice("c", c)
d := c[2:5]
printSlice("d", d)
}
func printSlice(s string, x []int) {
fmt.Printf("%s len=%d cap=%d %v\n",
s, len(x), cap(x), x)
}
And the result:
a len=5 cap=5 [0 0 0 0 0]
b len=0 cap=5 []
c len=2 cap=5 [0 0] //why the capacity of c not 2 but 5 instead
d len=3 cap=3 [0 0 0]

c is a slice taken from the array b. This isn't a copy, but just a window over the 2 first elements of b.
As b has a capacity of 5, c could be extended to take the 3 other places (in fact it makes a new slice but over the same place in memory).
The maximal capacity of the slice is the capacity of the underlying array minus the position of the start of the slice in the array :
array : [0 0 0 0 0 0 0 0 0 0 0 0]
array : <---- capacity --->
slice : [0 0 0 0]
slice : <---- capacity --->
Maybe this program will make it more clear that c and d are just windows over b :
func main() {
b := make([]int, 0, 5)
c := b[:2]
d := c[1:5] // this is equivalent to d := b[1:5]
d[0] = 1
printSlice("c", c)
printSlice("d", d)
}
Output :
c len=2 cap=5 [0 1] // modifying d has modified c
d len=4 cap=4 [1 0 0 0]

Note that in go 1.2 (Q4 2013, 1.2rc1 is available now), you can associate to a slice a capacity of its own (instead of a capacity deduced from the underlying array).
See "Three-index slices", and the design document.
A slicing operation creates a new slice by describing a contiguous section of an already-created array or slice:
var array [10]int
slice := array[2:4]
The capacity of the slice is the maximum number of elements that the slice may hold, even after reslicing; it reflects the size of the underlying array.
In this example, the capacity of the slice variable is 8.
(capacity of the underlying array minus the position of the start of the slice in the array)
array : [0 0 0 0 0 0 0 0 0 0]
array : <---- capacity --->
slice : [0 0]
slice : <-- capacity --> 8 (10-2)
Go 1.2 adds new syntax to allow a slicing operation to specify the capacity as well as the length.
A second colon introduces the capacity value, which must be less than or equal to the capacity of the source slice or array, adjusted for the origin.
For instance,
slice = array[2:4:6]
array : [0 0 0 0 0 0 0 0 0 0]
array : <---- capacity ---> 10
slice : [0 0]
slice : <- cap-> 4 (6-2)
sets the slice to have the same length as in the earlier example but its capacity is now only 4 elements (6-2).
It is impossible to use this new slice value to access the last two elements of the original array.
The main argument is to give programmers more control over append.
a[i : j : k]
That slice has:
indices starting at 0
length equals to j - i
capacity equals to k - i
The evaluation panics if i <= j <= k <= cap(a) is not true.

Related

How can I input successive different values from a single vector across the same position in multiple arrays arranged in a list in R?

I have arranged a large number of arrays into a list and I have a vector which is the same length as the number of arrays with different values. For each array in the list, I would like to input the successive specific values in the vector into the same position in the successive arrays in the list.
For example, if I had 10 arrays of 5x3x10 in a list, and a vector of length 10 with 10 different values, I would like the first value of the vector to go into the first array at position [1,1,1], the second value of the vector to go into the second array at position [1,1,1], the third value of the vector to go into the third array at position [1,1,1], and so on to the tenth value of the vector going into the tenth array at position [1,1,1].
Here is my current code (simplified).
All the variables/arrays are provide as necessary.
Currently I have a function that attempts to do this, but the way its written does not allow for the successive values of the variable to be put into the successive arrays. Rather the function tries to put all the values of the variable into the position [1,1,1] of each array, and as such, returns an error.
#Starting variables
dt = 1
person_id <- c("a", "b", "c", "d", "e")
clinic_id <- c("c1", "c2", "c3")
time_id <- seq(2008.5, 2017.5, by = dt)
first <- c(13,14,10,8,6,8,7,9,10,12)
second <- c(16,8,9,4,5,6,2,3,4,5)
numbers <- data.frame(first,second)
dims <- list(person = person_id,
clinic = clinic_id,
time = time_id)
#Create 10 arrays
for (i in 1:10) {
assign(paste("modarrays", i, sep=""),
array(NA, lengths(dims), dims) )
}
#Creating array list with 10 arrays
modarraysall <- lapply(ls(pattern="modarrays"),get)
arraynames <- sapply(ls(pattern="modarrays"),as.name)
names(modarraysall) <- arraynames
#Initial values in array
initval <- function(x){
x[,,1] <- 0.0
x <- x
}
modarraysallnew <- lapply(modarraysall, initval)
#Values from vector of dataframe into array
#This is where it all goes wrong.
numbersintoarray <- function(x){
x[1,1,1] <- numbers$first
x <- x
}
modarraysallnew <- lapply(modarraysallnew, numbersintoarray)
There is no output from this function implementation because I get an error saying
Error in x[1, 1, 1] <- numbers$first :
number of items to replace is not a multiple of replacement length
I think I know what is wrong. This function wants to put the value of numbers$first into position [1,1,1] of each array across the list. However, numbers$first is a length of 10 values where as position [1,1,1] in each array is only one position. Therefore, I know this function is wrong. But how do I write a function that takes each successive value from numbers$first and puts that into each successive array in the list at position [1,1,1].
Below I have shown what I would like the arrays too look like afterwards.
modarrays1[,,1]
clinic
person c1 c2 c3
a 13 0 0
b 0 0 0
c 0 0 0
d 0 0 0
e 0 0 0
modarrays1[,,2]
clinic
person c1 c2 c3
a 14 0 0
b 0 0 0
c 0 0 0
d 0 0 0
e 0 0 0
modarrays1[,,3]
clinic
person c1 c2 c3
a 10 0 0
b 0 0 0
c 0 0 0
d 0 0 0
e 0 0 0
....
modarrays10[,,1]
clinic
person c1 c2 c3
a 12 0 0
b 0 0 0
c 0 0 0
d 0 0 0
e 0 0 0
I realize I could write this out one array at a time. However, in my actual model code I have 54 arrays in the list so would like to be able to write a function to do this instead.
If you want to perform a function element-wise across two different lists or vectors, your best bet is to use mapply or Map. They need a function that takes as many arguments as lists/vectors you are providing. So in your case, you could try:
numbersintoarray <- function(arr, val) {
arr[1, 1, 1] <- val
return(arr)
}
m <- Map(numbersintoarray, modarraysallnew, numbers$first)
m$modarrays1[ , , 1]
# clinic
# person c1 c2 c3
# a 13 0 0
# b 0 0 0
# c 0 0 0
# d 0 0 0
# e 0 0 0

R: create an array of matrices from a list

I am trying to create an array from matrices. The matrices are all of identical dimensions (NxN). I have every matrix in a single csv file without header. Data are tab delimited.
In other threads it was suggested to do it as follows:
temp = list.files(pattern="*.csv")
named.list <- lapply(temp, read.csv,header=FALSE, sep = "")
arr <- abind(named.list)
However, this does not create what I want. This creates a 2-dimenaional Nx(N*k) data frame (where N = columns/rows and k = number of matrices).
So in my case I have 5 matrices, 40 columns and 40 rows each. Using abind creates a [1:40, 1:200] data frame.
> str(arr)
int [1:40, 1:200] 0 1 0 0 0 0 0 0 0 0 ...
- attr(*, "dimnames")=List of 2
..$ : NULL
..$ : chr [1:200] "V1" "V2" "V3" "V4" ...
What I want is a [1:40, 1:40, 1:5] three-dimensional array of matrices:
> str(z)
int [1:40, 1:40, 1:5] 0 1 0 0 0 0 0 0 0 0 ...
I think my fundamental problem is that I cannot manage to convert the list of data frames in named.list to a list of matrices.
this worked for me
temp = list.files(pattern="*.csv")
r <- simplify2array(temp)
However, the resulting array had dimensions [nrow, ncol, n] where the first two elements are matrix dimensions and the last is the number of matrices stored in r. My specific analysis required [n, nrow, ncol] to achieve this change I used the aperm function as follows r <- aperm(r, c(3,1,2)) based on this answer function from base package that is a generalization of the transpose t() function
I solved it, the "abind" got me close. The following line was missing:
arr2<-array(arr,dim= c(40,40,5))
This gives me:
str(arr2)
int [1:40, 1:40, 1:5] 0 1 0 0 0 0 0 0 0 0 ...
abind is the way to go. If rbindlist was used beforehand, the structure of the individual data sets gets messed up.
You can use:
library(data.table)
arr <- rbindlist(named.list ,use.names = T,fill = T);

Golang Array Pointer

I want to elucidate this behavior in Golang,
Why when you take the memory reference on array and you change values from this reference nothing change in the referencing array.
One example :
var t [5]int
printType(t,"t")
p := &t
printType(p,"p")
x := *p
x[0] = 4
printType(x,"x")
printType(p,"p")
printType(t,"t")
This code return
[t] Type:[5]int Kind:array Adr:%!p([5]int=[0 0 0 0 0]) Value:([0 0 0 0 0])
[p] Type:*[5]int Kind:ptr Adr:0xc4200142d0 Value:(&[0 0 0 0 0])
[x] Type:[5]int Kind:array Adr:%!p([5]int=[4 0 0 0 0]) Value:([4 0 0 0 0])
[p] Type:*[5]int Kind:ptr Adr:0xc4200142d0 Value:(&[0 0 0 0 0])
[t] Type:[5]int Kind:array Adr:%!p([5]int=[0 0 0 0 0]) Value:([0 0 0 0 0])
you can see the memory address is the same but the value "4" is not present.
Method printType
func printType(i interface {},message string) {
k := reflect.TypeOf(i).Kind().String()
fmt.Printf("[%s] Type:%T Kind:%s Adr:%[2]p Value:(%[2]v)\n",message,i,k)
}
Okay found it, the operator ":=" allocate an new memory address.
No, it doesn't allocate anything.
var t [5]int is a value. Note that according to spec [5]int if full type name in this case. You can think of it as of a struct with 5 int fields. Line x := *p makes dereferencing pointer to the t (a value). Assigning value creates a copy of it. If you want to pass a "reference" to t make slice of it: t[:].
Okay found it, the operator ":=" allocates a new memory address.

How to insert elements according to array of indices in MATLAB?

Say, I have Index array I = [2 4 6]
Another, array A =[1 0 0]
I want to insert elements of array A in array C at position 2 , 4 and 6.
Array C is initially empty.
Run 2: I = [1, 7, 8]
A = [0 0 1]
I would want to insert elements of array A in array C at position 1 , 7 and 8.
And, so on.
Please help.
Thanks.
Cheery essentially answered the question for you, but in order to be complete, simply use the array I and index into C and use I to place the values of A into the corresponding slots in C. As such:
C(I) = A;
If C was not already allocated, then C will pad whatever you didn't index with zeroes. As such, given your two examples, this is what we get:
I1 = [2 4 6];
I2 = [1 7 8];
A1 = [1 0 0];
A2 = [0 0 1];
C1(I1) = A1
C2(I2) = A2
C1 =
0 1 0 0 0 0
C2 =
0 0 0 0 0 0 0 1
However, because your array A already has zeroes, you can't really see the effect of this type of assignment. If you change up your array A into some other values that don't include zero, then you'll see that this does work.

How to compare each element with each element of cell array without a two loops?

I have a two cell arrays R and C (two vectors with R(n-elements), C(m-elements)) and my task is to compare each element of R with each element of R and each element of C with each element of C. Comparison is to finding intersection of two cells. In result I want to obtain two matrices. One matrix Q for R nxn, where in cell Q(i,j) is intersection of two elements R(i) and R(j) and second matrix P for C mxm, where in cell P(i,j) is intersection of two elements C(i) and C(j).
Generally I can do this using two for-loops, but my data is quite big and I wonder if there is any method to speed up the computation?
The first idea was to replace the cell array, where in each cell are the indexes of rows (vector R) or columns (vector C) which I want to compare (rows and columns of binary matrix BM, BM is input data) . So If R(1) = {2 3 4}, and BM is 5x5, then R(1,:)=[0 1 1 1 0]. Now having this binary matrix R I could compare each row with each row only with one loop. But then I still need to come back to number of rows eg
R(1,:) = [0 1 1 1 0];
R(2,:) = [0 1 1 0 0]; %then
Q(1,2) = [0 1 1 0 0]; %(intersection of element R(1) and R(2)) and
C(1,:) = [1 1 0 0 0];
C(2,:) = [1 0 0 1 0]; %then
P(1,2) = [1 0 0 0 0]; % Now I want to obtain
Results(i,j) = sum(BM(Q(1,2),P(1,2)))=sum(BM([2 3],[1]));
Do you have any idea how to cope with this, and compare two vectors of cell array without a two loops?
Since Q( k, l ) is a vector with numCols (5 in your example) it cannot be stored in a 2D matrix Q: Q should either be a 2D cell array, or a 3D matrix.
Using the binary matrix directly to obtain Q (row intersections):
>> Q = bsxfun( #times, permute( BM, [1 3 2] ), permute( BM, [3 1 2] ) );
Now, Q( k, l, : ) holds the intersection betwee the k-th and l-th rows of BM.
Same goes for P:
>> P = bsxfun( #times, permute( BM, [3 2 1] ), permute( BM, [2 3 1] ) );

Resources