Looping through many different arrays of different dimension - fortran

I have a bunch of arrays of different length which are all something like a1 = [1.0], a2 = [1.0,2.0]etc. I need to loop through all the arrays in a function and perform operations with their elements, but none of them are functions of an index. I was wondering what the best way of doing that in Fortran 95 would be? I think you could make an array of dimension (max_length, max_length), and put them all in that; this would allow you to reference each element by an index, but it would waste space and you'd have to pass the function the entire array every time you call it, rather than just the individual arrays (I don't actually know if that matters, but it seems like it would.)

Having an array of (maxlen, maxlen) will only cause trouble if you are talking about (thousands, thousands) otherwise it's just an inefficient approach.
Supposing your arrays are all of the same type and the same number of dimensions, then you could create a derived type which would hold your arrays and then create an array of the type you just created. Therefore you would have an array of variable lenth's array.
type arrays
integer(kind=8):: length !optional but very helpfull
integer(kind=8), dimension(:), allocatable:: a
end type arrays
now you can declare your array of type arrays:
type(arrays), dimension(:), allocatable:: arrayList
type(arrays):: arrayList ( 1000 ) !if you know beforehand how many arrays you need
There are two things to notice with this approach:
in my experience, looping through arrays of derived types are slower than through native type arrays.
now you access your a1, a2 as arrayList(i) % a(j) which can be scary at first sight
Source: http://courses.physics.illinois.edu/phys466/comp_info/derived.html
For aditional information, you could visit Fortran Wiki which is a very nice source.

The answer really depends on the actual case you have. If the length of the various arrays are not the same, but at least in the same order of magnitude, you may be better with one single array for all of them. You would then need, however, an additional array which gives the number of elements for every array. You function could then look something like:
module test
implicit none
integer, parameter :: dp = kind(1.0d0)
contains
subroutine process(array, nelems)
real(dp), intent(in) :: array(:,:)
integer, intent(in) :: nelems(:)
integer :: ii, jj
do ii = 1, size(arrays(dim=2))
do jj = 1, nelems(ii)
! Do something with element jj of array ii.
end do
end do
end subroutine process
end module test
where the subarray array(1:nelems(ii),ii) stores the elements of the i-th 1D array.
Following points are maybe interesting to note:
You should arrange your 1D-subarrays in the collective 2D-array column wise, so that the subarrays are continuos in the memory.
You have to pass only two arrays instead of a bunch of arrays to the subroutine. This should give a clearer code.
Of course you waste some memory, as the shape of the collective array must be (max_nr_of_elements_in_an_array, number_of_arrays). If the array lenghts are very different and you have really a lot of arrays, so that the wasted memory becomes significant, you could think about the array of arrays approach as suggested by Eudoardo. However, this is often slower as the direct approach since the individual arrays are scattered in the memory (problematic for caching).

Related

Running in a problem with matrices in ocaml

So I have just recently started programming in ocaml for my university (it is required here). I have to write a function unit->(int*int) Array Array Array which creates a 16 by 16 matrix, in which entries are Arrays which take in 4 tuples.
I was explicitly told to not write this function recursivly, so I made this :
let matrice_deplacements () =
let u = Array.make 16 (Array.make 16 [||]) in
for k=0 to 15 do
for p=0 to 15 do
u.(k).(p)<-deplacement_grille (k,p)
done;
done;
u;;
And I know for sure that the function deplacement_grille (excuse the french) works perfectly, and gives me exactly what I want ( which is the right (int*int) Array, for the good k and p)
I have absolutely no clue where the problem lies, because each time I've run this code(I've tried with 2*2 and 3*3 matrices, and it doesn't work), ocaml returns a matrix, where all the lines are the same(they are actually what was supposed to be the last line).
Any help is appreciated.
I actually wonder if this comes down to the way ocaml stores Array, it may like python, where they have the same adress.
I suggest consulting the documentation of Array.make, which explains that arrays constructed in this manner have elements that are physically equal. As such, your initial line builds 2 distinct arrays, not the 17 that you expect. (This has to be the case, since the inner constructor application (Array.make 16 [||]) is evaluated to a single array before passing it to the constructor of the outer array.)
You probably want Array.init instead, which constructs a fresh element for each index. There is also Array.make_matrix, which is like Array.make in that the matrix elements are initially physically equal.

array of pointers and pointer to an array in c++

i have a class in which it's protected section i need to declare an array with unknown size (the size is given to the constructor as a parameter), so i looked around and found out that the best possible solution is to declare an array of pointers, each element points to an integer:
int* some_array_;
and simply in the constructor i'll use the "new" operator:
some_array_ = new int[size];
and it worked, my question is: can i declare an array in a class without defining the size? and if yes how do i do it, if not then why does it work for pointers and not for a normal array?
EDIT: i know vecotrs will solve the problem but i can't use them on my HW
You have to think about how this works from the compiler's perspective. A pointer uses a specific amount of space (usually 4 bytes) and you request more space with the new operator. But how much space does an empty array use? It can't be 0 bytes and the compiler has no way of knowing what space to allocate for an array without any elements and therefore it is not allowed.
You could always use a vector. To do this, add this line of code: #include <vector> at the top of your code, and then define the vector as follows:
vector<int> vectorName;
Keep in mind that vectors are not arrays and should not be treated as such. For example, in a loop, you would want to retrieve an element of a vector like this: vectorName.at(index) and not like this: vectorName[index]
Lets say that you have an integer array of size 2. So you have Array[0,1]
Arrays are continuous byte of memery, so if you declare one and then you want to add one or more elements to end of that array, the exact next position (in this case :at index 2(or the 3rd integer) ) has a high chance of being already allocated so in that case you just cant do it. A solution is to create a new array (in this case of 3 elements) , copy the initial array into the new and in the last position add the new integer. Obviously this has a high cost so we dont do it.
A solution to this problem in C++ is Vector and in Java are ArrayLists.

Looking for a more concise way of writing a relatively common loop?

Is there a more concise way of writing this relatively common type of loop,
70 M=NTOC-N
L=0
DO 100 I=M,NTOC
L=L+1
X(L)=XI(I)
100 Y(L)=YI(I)
Without going into definitions of indexes, what it does is it copies the contents of arrays XI, YI from index M to NTOC to arrays X, Y indexes 1 to ... (NTOC-M) ... how many is needed.
While restructuring some older code, I noticed I had a large number of this kind of loops, and while I probably didn't know better at the time, I was wondering is there now a more concise way of writing this to aide code legibility / readability? While depending a lot on loops, I know Fortran nowadays has excellent support for all kinds of array operations, so if someone knows a way which they believe could be more legible, I would be very grateful on all suggestions!
Assuming n is positive, over the course of the loop i takes the values m, m+1, ..., ntoc and so the elements of xi chosen are, in order, xi(m), xi(m+1), ..., xi(ntoc). The elements of yi are similar.
In terms of an array section, xi(m:ntoc) represents the same selection of elements.
Similarly, the elements of x on the left-hand side are x(1), x(2), ..., x(ntoc-m+1) (=x(n+1)). As an array section, x(1:n+1) represents the same elements.
That means:
x(1:n+1)=xi(ntoc-n:ntoc) ! Replacing m with its value
y(1:n+1)=yi(ntoc-n:ntoc)
And if the bounds are x and y are 1 and n+1, or the arrays are allocatable, then the whole arrays x and y could be used on the left-hand sides.
For n zero or negative the array section will safely select the same elements as the loop (one or none).
If you're going to use i and l outside that fragment then you'll of course have to set those manually (and don't forgot that i will take the value ntoc+1).
Finally, if you want more incentive to get rid of that loop: note that non-block do constructs like this one are deleted by Fortran 2015.

multiplication of two integer arrays

I have a class that stores arbitrarily large integers in the model of a little-endian character array. I need to overload the multiplication operator, and I cannot think of an algorithm that works. Every solution I come up with is hindered by needing to store some values within a int,double, or even long long. all of which are invalid considering these arrays may theoretical contain an infinite number of digits.
Can anybody help me think of an algorithm for multiplication of large arrays?
(i created a function for converting a single digit integer into a character, and vice versa)
array1 = {1,2,3,4,5,6,7,8,9}
array2 = {8,7,6,5,4,3,2}
array3 = product
987654321
x 2345678
=________
when array1 and array2 may be infinitely long.
*The use of stdlib classes is prohibited, so no BigInt or Vector

searching a 2D array given the address of one element

A rather quick question concerning pointers in c++
My problem is,let's say I have a function isWon(char * sign, int i, int j). I call this method by giving
the address of an element in a 2D array
it's coordinates in a locally declared array
Is there any way of e.g. knowing the elements neighbors and getting to them?
Thanks for the help :)
If the array is a true array 2D array and not an array of pointers or something like that, then you can add/subtract to/from sign to get other elements' addresses.
For example, memory-wise the previous element in the array is at sign - 1. If you think of your 2D array as a grid, sign - 1 might not be the element in the previous "column".
You have to be careful how much you step in your array and ask yourself why you resort to such low-level dangerous mechanisms that feel out of place in C++.