Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concat 2D Arrays in f#

Tags:

f#

How can I combine two 2d arrays generally?

My assumption (I could obviously easily test this) is that they always have the same number of columns:

let concatArrays (arr1:obj[,]) (arr2:obj[,]) = 
    ([arr1; arr2]) |> Array2d.concat

This function doesnt exist though. Just to be clear, the result should produce a 2d array with length = sum of lengths and same number of columns as the original arrays2D and should be the same type as the input, here obj[,]. I could obviously do this in a looping construct but I was wondering about an f# way. Thanks.

I tried this:

let append2D (arr1:float[,]) (arr2:float[,]) = 
    let cls = arr1.GetLength 1
    let rows1 = arr1.GetLength 0
    let rows2 = arr2.GetLength 0
    Array2D.init (rows1+rows2) cls (fun i j -> match i with | a when a <= rows1 -> arr1.[i,j] | _ ->  arr2.[i,j])

But this comes back with index out of bounds error.

Update of last row:

 Array2D.init (rows1+rows2) cls (fun i j -> if i < rows1 then arr1.[i,j] else arr2.[i,j])  

Update working solution:

 Array2D.init (rows1+rows2) cls (fun i j -> if i < rows1 then arr1.[i,j] else arr2.[i-rows1,j])  

thanks all

like image 351
nik Avatar asked Oct 16 '13 11:10

nik


People also ask

How do you concatenate two arrays of different dimensions in Python?

arange(2) is given. To concatenate the array of two different dimensions. The np. column_stack((array1, array2)) is used.

How do I concatenate 3d NumPy arrays?

In numpy concatenate arrays we can easily use the function np. concatenate(). It can be used to concatenate two arrays either row-wise or column-wise. Concatenate function can take two or more arrays of the same shape and by default, it concatenates row-wise which means axis=0.


1 Answers

Following this recommendation here is a concat function for two equal column size Array2D arguments of any type 'a:

let concat (a1: 'a[,]) (a2: 'a[,]) =
    let a1l1,a1l2,a2l1,a2l2 = (Array2D.length1 a1),(Array2D.length2 a1),(Array2D.length1 a2),(Array2D.length2 a2)
    if a1l2 <> a2l2 then failwith "arrays have different column sizes"
    let result = Array2D.zeroCreate (a1l1 + a2l1) a1l2
    Array2D.blit a1 0 0 result 0 0 a1l1 a1l2
    Array2D.blit a2 0 0 result a1l1 0 a2l1 a2l2
    result

You may check this experimentally, but it would have times better performance, than any variant based on Array2D.init because Array2D.zeroCreate and Array2D.blit implementations are highly optimized.

like image 135
Gene Belitski Avatar answered Sep 22 '22 17:09

Gene Belitski