>> import numpy ...">

Broadcasting an array to another form (adding "fake" dimensions)

In python (using numpy), I can pass the array to another form:

>>> import numpy as np >>> a = np.array([2,3,4]) >>> b = np.zeros((3,2)) >>> b[:,:] = np.zeros((3,2)) >>> b[:,:] = a[:,np.newaxis] #<-- np.newaxis allows `a` to be "broadcasted" to the same shape as b. >>> b array([[ 2., 2.], [ 3., 3.], [ 4., 4.]]) >>> c = np.zeros((2,3)) >>> c[:,:] = a[np.newaxis,:] >>> c array([[ 2., 3., 4.], [ 2., 3., 4.]]) 

Is there a way to achieve the same effect in fortran ? I have a routine that expects 2D array transfer - I would like to "translate" my one-dimensional arrays to 2-D, as I showed above. It seems like this probably matters, my 2D array has an explicit interface.

As a side note, I thought this functionality could be provided by reshape, something like:

 real,dimension(3) :: arr1d reshape(arr1d, (/3,3/), order=(/1,/1)) 

but after reading the docs, I don’t think it’s possible, since order seems to include all the numbers 1 in "N".

Edit: To be a little clearer, I am looking for an easy way to create a couple of transformations at input a so that:

case 1

 b(i,j) .eq. a(i) !for all j, or even just j=1,2 

and

case 2

 b(j,i) .eq. a(i) !for all j, or even just j=1,2 

bonus points 1 for an arbitrary dimension:

 b(i,j,k) .eq. a(i,j) b(i,k,j) .eq. a(i,j) 

and etc.

1 disclaimer - in fact I do not have SO superusers to accrue bonus points on the defendant; -)

+7
source share
2 answers

I'm not sure what you are trying to accomplish, but here are a few snippets that might help.

reshape can take an optional argument called pad , which can be used to provide the "extra" elements that are needed when you go into an array with more elements than you started, say, from 3x4 to 2x4x2.

You may also be interested in the spread function, which is for upranking arrays, which takes a rank-N array and produces an array of rank-N + 1. The fragment in your second copy can be rewritten as

 array2d = spread(array1d,2,2) 

In this example, the second argument is the size over which the first argument will be propagated for output. The third argument is the number of copies of the input array.

PS The spread call should be spread(array1d,1,2) , I have not tested it.

EDIT in response to editing a question

Two cases, 1 and 2, are satisfied by spreading over sizes 2 and 1, respectively. In Fortran

 b = spread(a,2,j) 

and

 b = spread(a,1,j) 

Since spread returns an array with rank 1 greater than the rank of its first argument, it provides the desired arbitrary dimension. However, since it is so multithreaded to display arrays of rank 3 and higher, I am not going to.

+6
source

The modified inner shell will allow you to copy the 1D array to a 2D array. With the fairly recent Fortran compiler, their pointer method. The pointer provides a second way to access the repository, avoiding copying. This method is "overriding pointer boundaries." Example:

 program array_tst integer, dimension (4), target :: array_1d integer, dimension (:,:), pointer :: array_2d array_1d = [ 1, 2, 3, 4 ] array_2d (1:2, 1:2) => array_1d write (*, *) array_2d (1,1), array_2d (1,2), array_2d (2,1), array_2d (2,2) end program array_tst 

Also see resizing an array in fortran

PS In response to comments ... if you don't mind copying an array, here's how to use reshape:

 program array_reshape integer, dimension (4) :: array_1d integer, dimension (2, 2) :: array_2d array_1d = [ 1, 2, 3, 4 ] array_2d = reshape ( array_1d, [2,2] ) write (*, *) array_2d (1,1), array_2d (1,2), array_2d (2,1), array_2d (2,2) end program array_reshape 
+1
source

All Articles