How to define array for user input? [duplicate] - arrays

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.

Related

C Vectorization: Is it possible to do elementwise operation in array like python-vectorization?

I am moving from python to C, in the hope of faster implementation, and trying to learn vectorization in C equivalent to python vectorization. For example, assume that we have binary array Input_Binary_Array, if I want to multiply each element for the index, say, i, by 2**i and then sum all non-zero, in python-vectorization we do the following:
case 1 : Value = (2. ** (np.nonzero(Input_Binary_Array)[0] + 1)).sum()
Or if we do slicing and do elementwise addition/subtraction/multiplication, we do the following:
case 2 : Array_opr= (Input_Binary_Array[size:] * 2**Size -Input_Binary_Array[:-size])
C is a powerful low-level language, so simple for/while loop is quite faster, but I am not sure that there are no equivalent vectorizations like python.
So, my question is, is there an explicit vectorization code for:
1.
multiplying all elements of an array
with a constant number (scalar)
2.
elementwise addition, subtraction, division for 2 given arrays of same size.
3.
slicing, summing, cumulative summing
or, the simple for, while loop is the only faster option to do above operations like python vectorization (case 1, 2)?
The answer is to either use a library to achieve those things, or write one. The C language by itself is fairly minimalist. It's part of the appeal. Some libraries out there include the Intel MLK, and there's gsl, which has that along with huge number of other functions, and more.
Now, with that said, I would recommend that if moving from Python to C is your plan, moving from Python to C++ is the better one. The reason that I say this is because C++ already has a lot of the tools you would be looking for to build what you like syntactically.
Specifically, you want to look at C++ std::vector, iterators, ranges and lambda expressions, all within C++20 and working rather well. I was able to make my own iterator on my own sort of weird collection and then have Linq style functions tacked onto it, with Linq semantics...
So I could say
mycollection<int> myvector = { 1, 2, 4, 5 };
Something like that anyway - the initializer expression rules I forget sometimes.
auto v = mycollection
.where( []( auto& itm ) { itm > 3; } )
.sum( []( auto& itm ) { return itm; } );
and get more or less what I expect.
Since you control the iterator down to every single detail you could ever want (and the std framework already thought of many), you can make it go as fast as you need, use multiple cores and so on.
In fact, I think STL for MS and maybe GCC both actually have swap in parallel algorithms where you just use them.
So C is good, but consider C++, if you are going that "C like" route. Because that's the only way you'll get the performance you want with the syntax you need.
Iterators basically let you wrap the concept of a for loop as an object. So,
So, my question is, is there an explicit vectorization code for:
1.
multiplying all elements of an array
with a constant number (scalar)
The C language itself does not have a syntax for expressing that with a single simple statement. One would ordinarily write a loop to perform the multiplication element by element, or possibly find or write a library that handles it.
Note also that as far as I am aware, the Python language does not have this either. In particular, the product of a Python list and an integer n is not scalar multiplication of the list elements, but rather a list with n times as many elements. Some of your Python examples look like they may be using Numpy, which can provide for that sort of thing, but that's a third-party package, analogous to a library in C.
elementwise addition, subtraction, division for 2 given arrays of same
size.
Same as above. Including this not being in Python, either, at least not as the effect of any built-in Python operator on objects of a built-in type.
slicing, summing, cumulative summing
C has limited array slicing, in that you can access contiguous subarrays of an array more or less as arrays in their own right. The term "slice" is not typically used, however.
C does not have built-in sum() functions for arrays.
or, the simple for, while loop is the only faster option to do above
operations like python vectorization (case 1, 2)?
There are lots and lots of third-party C libraries, including some good ones for linear algebra. The C language and standard library does not have such features built in. One would typically choose among writing explicit loops, writing a custom library, and integrating a third party library based on how much your code relies on such operations, whether you need or can benefit from customization to your particular cases, and whether the operations need to be highly optimized.

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.

Array First Index in Fortran

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)

In Lua, what is #INF and #IND?

I'm fairly new to Lua. While testing I discovered #INF/#IND. However, I can't find a good reference that explains it.
What are #INF, #IND, and similar (such as negatives) and how do you generate and use them?
#INF is infinite, #IND is NaN. Give it a test:
print(1/0)
print(0/0)
Output on my Windows machine:
1.#INF
-1.#IND
As there's no standard representation for these in ANSI C, you may get different result. For instance:
inf
-nan
Expanding #YuHao already good answer.
Lua does little when converting a number to a string, since it heavily relies on the underlying C library implementation. In fact Lua print implementation calls Lua tostring which in turn (after a series of other calls) uses the lua_number2str macro, which is defined in terms of C sprintf. Thus in the end you see whatever representation for infinities and NaNs the C implementation uses (this may vary according to which compiler was used to compile Lua and which C runtime your application is linked to).
#YuHao has already answered what the OP has effectively asked: what does +/-1.#INF (+-inf) and -1.#IND (nan) mean.
What I want to do here is just to add some value to the question/answer by expanding on to deal with -- to check -- them (which I just needed and learned to):
inf (+/-1.#INF) are the highest number(+/-) that Lua can represent, and the Language provides such value(s) for you through math.huge. So you can test if a number is +/-INF:
local function isINF(value)
return value == math.huge or value == -math.huge
end
nan (-1.#IND) is something that can not be handled numerically, and the result of any operation involving it is also Not-a-number(*). Long-story-short... if a number is a NaN, comparing it against itself will (always) be False. The function below implements the simplest way for checking if a NaN:
local function isNAN(value)
return value ~= value
end
(*): This (NaN) is formally defined some where in the IEEE754 standard (floating-point numbers).

FORTRAN and C interoperability - can REAL(4)s be too small?

We've been having some weird crashes in some Intel FORTRAN code, and I eventually tracked the line down to:
L_F = EXP(-L_B2*L_BETASQ*L_DS)
Where the -L_B2*L_BETASQ*L_DS term evaluated to approximately -230. As it happens, EXP(-230) evaluates to about 1e-100. In all other known cases, L_DS is much smaller, resulting in the smallest (known) return from EXP being about 1e-50, which does not cause an error.
As soon as FORTRAN evaluates the clause EXP(-230), you get:
forrtl: severe (157): Program Exception - access violation
Image PC Routine Line Source
But no other information.
Exception 157 is generally concerned with interoperability, and you cannot debug into EXP in FORTRAN as it cannot find a particular .c file - which presumably means that EXP is implemented in C (which I find surprising).
My hypothesis is that FORTRAN has implemented EXP in C, but the interface cannot translate floats which are smaller than 1e-100 into REAL(4)s. As I had previously believed floats and REAL(4)s to be byte-wise identical, I cannot back this hypothesis up - and I cannot find anything anywhere about it.
Before I close this bug down, can anyone confirm or deny my hypothesis - or provide me with another?
Best regards,
Mike
EDIT: I'm going to mark this question as answered, as High Performance Mark has answered the immediate question.
My hypothesis is unfortunately incorrect - I've tried to trap the problem doing this:
L_ARG = L_B2*L_BETASQ*L_DS
IF (L_ARG .GT. 230.0) THEN
L_F = 0.0
ELSE
L_F = EXP(-L_ARG)
ENDIF
Unfortunately, the exception now (apparently) occurs in the L_ARG .GT. 230.0 clause. This either means that the debugging in Release mode is worse than I thought, or it's some sort of 'stored up' floating point error (see "Floating-point invalid operation" when inputting float to a stringstream).
Fortran hasn't (necessarily) implemented anything in C. The implementation of standard intrinsics is compiler-specific; it is common to find that implementations call libm or one of its relatives. From Intel's (or any other compiler writer's) point of view this makes sense, write one robust and fast implementation of exp in whatever language takes your fancy and call it from Fortran, C, Ada, COBOL, and all the other languages you've ever heard of. It may even be sensible to write it in C. Part of your hypothesis may, therefore, be correct.
However, unless you are explicitly writing C code and Fortran code and making a single binary from it there's not really any interoperability (in the Fortran standard sense) going on, all the dirty details of that are (or should be) hidden from you; the compiler ought to generate correct calls to whatever libraries it uses to implement exp and get the return values whatever they may be including NaNs and similar.
Certainly, the value of exp(-230) is 0.00000000 for a 4-byte real but I see no reason why a Fortran program which uses a library written in C should raise an access violation because it comes across those numbers. I think it is far more likely that you have an error elsewhere in your program, perhaps trying to access an array element outside the bounds of the array, and that your run-time fails to identify it at the right location in the source code. This is not uncommon.
EDIT
I wrote this stuff about interoperability before (re-)reading the question. Now that you've clarified that you are using interoperability features, it may be of interest or use ...
You can certainly not depend on your Fortran's real(4) and your C's float being identical; it is very likely but not certain. Most of the modern Fortran compilers (including Intel's) use kind type parameters which match the number of bytes in their representation, so the code 4 indicates that you are dealing with a 4-byte real which, on an IEEE-754 compliant processor, should be the same as a C float. The Fortran standards do not require any correspondence between those kind type parameters and the number of bytes used to represent a number. It's always worth checking your compiler documentation or doing some tests.
If you are concerned about interoperability you should probably be using Fortran's intrinsic features. For example if you
use :: iso_c_binding
you have available a number of constants including C_FLOAT which can be used like this:
real(C_FLOAT) :: a_fortran_float
If your Fortran compiler supports this then a_fortran_float should match a C float on a companion processor. This last term is left somewhat undefined, in practice compilers from the same stable seem always to be companions, for different stables sometimes yes sometimes no. The Intel Fortran and C and C++ compilers seem to be companions in the required sense. It would not surprise me to learn that the Intel Fortran and MS C++ compilers do not play nicely together.
My vague recollections of C include an uncertainty that float is standardised, in which case you can't be sure, without testing or reading the documentation, that you really do have a 4-byte IEEE single-precision floating-point number on that side of your interoperation either.

Resources