Array First Index in Fortran - arrays

I thought the first index of an array in Fortran is 1. But why does this code work? (Code is a modified segment of Wavewatch, http://polar.ncep.noaa.gov/waves/wavewatch/)
DO KINDEX=0, TOTAL+1
NUM = NUM * SCALE
SIG (KINDEX) = NUM
END DO

As you've already been told Fortran array indexing is, by default, 1-based but the programmer can choose any integer within the range of the integer kind used for index values. There is, though, another wrinkle of which you should be aware. Fortran doesn't by default, either at compile-time (where it would be impossible in many cases) or at run-time (possible but expensive), check that array index expressions are in bounds.
There is a lot of Fortran code in the wild with this problem and I've come across cases where a program has worked, apparently correctly, for many years without this being spotted. Use your compiler's options to create a version of the program which checks array bounds expressions at run-time, run it and see what happens.
Or, as you've already been told, SIG may have been declared with 0 as its lowest index.

You thought it wrong. Arrays can be declared to start from any integer.
REAL SIG(42:58)

Related

How to define array for user input? [duplicate]

Is it possible to use real numbers as iterators and array indices when compiling with gfortran? Here is some example code:
program test
real i
real testarray(5)
testarray = 0.
do i=1,5
write(*,*) testarray(i)
end do
end program
I want to run some code that I did not write. It compiles fine with the intel compiler on windows, but I want to compile and run it in linux with the gfortran compiler. I'm currently getting errors using real numbers as array indices and do loop iterators.
Thanks!
Why would you want to use real numbers as array and loop indices?
If you need to use the real value of the index, do something like:
program test
integer i
real testarray(5)
testarray = 0.
do i=1,5
testarray(i) = REAL(i)
end do
end program
And of course you could go the other direction if you needed to,
integer j
do j = 1, INTEGER(testarray(1))
...
end do
for example. The standard doesn't allow non-integer indices. They don't make sense either -- what is the 1.5 index in your array?
It appears that the real array indexing is an extension that should be possible if you compile with --std=gnu. But support for that may not always be there as it is not part of the standard.
If you don't want to see the warnings, then try --std=legacy. Otherwise "gnu", as already suggested. The gfortran manual states:
As an extension, GNU Fortran allows the use of REAL expressions or
variables as array indices.
and
The default value for std is ‘gnu’, which specifies a superset of the
Fortran 95 standard that includes all of the extensions supported by
GNU Fortran, although warnings will be given for obsolete extensions
not recommended for use in new code. The ‘legacy’ value is equivalent
but without the warnings for obsolete extensions, and may be useful
for old non-standard programs.
Using real variables as loop indices was deleted from the language standard with Fortran 95. Because of the amount of legacy code that uses this, it is likely to remain in compilers for decades.
Another possibility is to implement this as a function or subroutine. The user experience would be similar tab(x) loohs like an array or like a function, but would allow more control (for example you can check if x is within eps of some value of x0 for which you have defined a value).
In general the idea seems dangerous due to rounding errors.
If you are working on rational numbers or let say srqt's of integer numers, then it is again ideal case when f(x) as a function applies (with x bein e.g. a derived type that contains numerator and denominator).
So my final answer is: write it as a function.

Is there a way to use an array as an address for another array in Fortran [duplicate]

Is it possible in modern Fortran to use a vector to index a multidimensional array? That is, given, say,
integer, dimension(3) :: index = [4,6,9]
double precision, dimension(10,10,10) :: data
is there a better (more general) way to access data(4,6,9) than writing data(index(1), index(2), index(3))? It would be good not to have to hard-code the rank of the data array.
(Naively I would like to write data(index) but of course this actually means something different - subset "gathering" - requiring data to be a rank-one array itself.)
For what it's worth this is essentially the same question as multidimensional index by array of indices in JavaScript, but in Fortran instead. Unfortunately the clever answers there won't work with predefined array ranks.
No. And all the workarounds I can think of are ghastly hacks, you're better off writing a function to take data and index as arguments and spit out the element(s) you want.
You might, however, be able to use modern Fortran's capabilities for array rank remapping to do exactly the opposite, which might satisfy your wish to play fast-and-loose with array ranks.
Given the declaration
double precision, dimension(1000), target :: data
you can define a rank-3 pointer
double precision, pointer :: index_3d(:,:,:)
and then set it like this:
index_3d(1:10,1:10,1:10) => data
and hey presto, you can now use both rank-3 and rank-1 indices into data, which is close to what you want to do. I've not used this in anger yet, but a couple of simple tests haven't revealed any serious problems.

Dynamic array in Fortran 77

I have to write a subroutine in Fortran 77(i'm using Intel Fortran), which reads the measured values from a text file and stores them in a matrix.
Since the number of measured values is always variable, I must dynamically allocate the matrix.
I know that the dynamic allocation is only possible from Fortran 90, but at that time people had the same problems, so it is also possible.
How would you proceed?
I do not want to reserve too much space for the matrix because the method is impractical for me.
If you really are restricted to Fortran 77, you do not do dynamic allocation. Instead, declare an array that is larger than what you think you will likely need, without it being too large to prevent the program from running on your target system. Then store your values in that large array, separately keeping track of how many elements of the large array that you use. If your choice of array size was not large enough, let the user know and terminate the program.
People found the lack of dynamic allocation in Fortran 77 very restrictive, so they often resorted to using non-standard language extensions. If you decide to go down the path of language extensions, then these days the best extension to Fortran 77 to use in this situation is the allocatable array feature introduced with Fortran 90. I think it is fair to say that all actively maintained compilers that can handle Fortran 77 will also handle Fortran 90 allocatable arrays (and then some).
As many people have pointed out, you don't have to stick to Fortran77, even if much of what is already written is Fortran77 compatible. Even the few features that have been deleted in Fortran 95 See Wikipedia for a list, your compiler will probably still work fine, as long as you don't switch from Fixed Form to Free Form in the same file.
Pre-F90, what people would probably do is to declare arrays that are (hoped to be) big enough for any use case, then only use the first elements of that array.
One thing that I am not certain about, but which might be useful, is the change of scope. Short example:
subroutine main(n)
implicit none
integer n
integer a(n)
print*, "Please enter the ", n, " numbers"
read*, a
print*, "Sum is ", sum(a)
end subroutine main
program dynamic
implicit none
integer n
print*, "Enter size of array:"
read*, n
call main(n)
end program dynamic
I'm curious to know whether this would be Fortran77 compliant. I honestly don't know. #francescalus has convinced me that it isn't.

Assigning a zero to all array elements in C

In the program I'm working on, this particular operation is definitely not going to be the bottleneck, but it did get me thinking. From the answers to questions such as this one and this one I've learned two ways to easily (efficiently) set all the elements of an array to zero in C:
double myArray[3];
static const double zeroes[3] = {0};
memcpy(myArray, zeroes, sizeof(zeroes));
and
double myArray[3];
memset(myArray, 0, numberOfElementsInMyArray * sizeof(myArray[0]));
Before I move onto my real question: I'm not entirely sure but based on the information I've read, I assume this method would, at least in principle, fill the array with int zeroes (well, unsigned char's but these seem to be fairly equivalent). Is that correct? If so, is an explicit conversion of the int zeroes to double zeroes necessary or is it done implicitly if myArray is declared as an array of double's?
Anyway, my real question is this: if the array isn't very big at all (like the myArray I've declared above), is either of these methods still preferred over a little loop? What if you have a few arrays of the same small size that all need to be assigned zeroes? If commented properly, do you think readability is a factor in the decision and favours a particular solution?
Just to be entirely clear: I am not looking to initialize an array to zeroes.
If it's just a small array (like three elements), it probably won't make much difference whether you use mem* functions, or a loop, or three distinct assignments. In fact, that latter case may even be faster as you're not suffering the cost of a function call:
myArry[0] = myArray[1] = myArray[2] = 0;
But, even if one is faster, the difference would probably not be worth worrying about. I tend to optimise for readability first then, if needed, optimise for space/storage later.
If it was a choice between memcpy and memset, I'd choose the latter (assuming, as seems to be the case, that the all-zero bit pattern actually represented 0.0 in your implementation) for two reasons:
it doesn't require storage of a zeroed array; and
the former will get you into trouble if you change the size of one array and forget the other.
And, for what it's worth, your memset solution doesn't need to have the multiplication. Since you can get the size of the entire array, you can just do:
memset (myArray, 0, sizeof (myArray));
i think the first method of setting without using a loop is better for performance
what happen is that the merroy of array is bitwised by 0 (& 0) so it faster than using a loop for each element in the array.

What is faster in C: structs or arrays?

I want to implement (what represents abstractly) a two dimensional 4x4 matrix. All the code I write for matrix multiplication et cetera will be entirely "unrolled" as it were -- that is to say, I will not be using loops to access and write data entries in the matrix.
My question is: In C, would it be faster to use a struct as such:
typedef struct {
double e0, e1, e2, e3, e4, ..., e15
} My4x4Matrix;
Or would this be faster:
typedef double My4x4Matrix[16];
Given that I will be accessing each matrix element individually as such:
My4x4Matrix a,b,c;
// (Some initialization of a and b.)
...
c.e0=a.e0+b.e0;
c.e1=a.e1+b.e1;
...
Or
My4x4Matrix a,b,c;
// (Some initialization of a and b.)
...
c[0]=a[0]+b[0];
c[1]=a[1]+b[1];
...
Or are they exactly the same speed?
Any decent compiler will generate the exact same code, byte-for-byte. However, using arrays allows you a lot more flexibility; when accessing the matrix elements, you can choose whether you want to access fixed locations or address positions with variables.
I also highly question your choice to "unwind" (unroll?) all the operations by hand. Any good compiler can fully unroll loops with a constant number of iterations for you, and can perhaps even generate SIMD code and/or optimally schedule the order of instructions. You'll have a hard time doing better by hand, and you'll end up with code that's hideous to read. The fact that you asked this question suggests to me that you're probably not sufficiently experienced to do better than even a naive optimizing compiler.
Struct elements (fields) can only be accessed by their names explicitly specified in the program's source, which means that every time you access a field the actual field must be selected and hardcoded at compile time. If you wanted to implement the same thing with arrays, that would mean that you would use explicit constant compile-time array indices (as in your example). In this case the performance of the two will be exactly the same and the code generated will be exactly the same (excluding from consideration "malicious" compilers).
However, note that arrays provide you with an extra degree of freedom: if necessary, you can select array elements by a run-time index. This is something that's not possible with structs. Only you know whether it matters to you.
On the other hand, note also that arrays in C are not copyable, which means that you'll be forced to use memcpy to copy your array-based My4x4Matrix. With struct-based version normal language-level copying will work. With arrays this issue can be worked around by wrapping the actual array in a struct.
I guess both are the same speed. The difference between a struct and an array is just its meaning (in human terms.) Both will be compiled as memory addresses.
I would say the best way is to create a test to try it yourself. Results may vary based on system environments and compilers.

Resources