Fortran array addition goes wrong - arrays

I'm trying to add two arrays, but for some reason the target array only contains zeros.
When i compile and run the program i don't get any errors, but the output file is wrong.
In the code i call dhscf which fills the arrays Gnaatm and Gnascf with values, i (try) to save those in gavenaa and gavenas, and the call dhscf again to get new values for Gnaatm an Gnascf. When i write all those arrays to files gavenas en gavenaa seem to be empty although Gnaatm and Gnascf aren't.
The code i'm using is:
module var
real(dp), dimension(:), allocatable :: Gnaatm(:), Gnascf(:), gavenaa(:), &
& gavenas(:)
end module
grdsam.f:
allocate (Gnaatm(nasize))
allocate (Gnascf(nasize))
allocate (gavenaa(nasize))
allocate (gavenas(nasize))
call dhscf(.....)
gavenaa = Gnaatm
gavenas = Gnascf
do ipt = 1, npt
call dhscf(....)
gavenaa = Gnaatm + gavenaa
gavenas = Gnascf + gavenas
enddo
open(unit=12, file="Zgavenaatm.txt", status="replace")
do iwrite = 1, nasize
write(12, *), iwrite, gavenaa(iwrite), Gnaatm(iwrite)
enddo
close(12)
open(unit=12, file="Zgavenascf.txt", status="replace")
do iwrite = 1, nasize
write(12, *), iwrite, gavenas(iwrite), Gnascf(iwrite)
enddo
close(12)
deallocate (Gnaatm)
deallocate (Gnascf)
deallocate (gavenaa)
deallocate (gavenas)
end grdsam
When i run the program i don't get errors, but the output file is wrong. Typical output is like this:
10 0.0000000000000000 -2.35488624992556957E-015
11 0.0000000000000000 -4.75822627213221874E-017
12 0.0000000000000000 -7.16040821425613171E-014
13 0.0000000000000000 8.33283089385797112E-021
14 0.0000000000000000 -1.04121906025281556E-014
The second column only contains zeros, but the third column does contain numbers.
So the arrays 'Gnaatm' and 'Gnascf' contain numbers, but somehow adding them to 'gavenaa' and 'gavenas' goes wrong. Can any one tell me what i'm doing wrong?
ps. i'm using the gfortran compiler on Ubuntu 12.

I would be really surprised if any fortran compiler had issues with something as basic as adding up two arrays, so either the code shown is not exactly the code you're using, or the problem is in parts of the code that are omitted.
First, you don't show it here, so I'll ask it: do you have implicit none in your code? Continuing without it would be a waste of time; it avoids many "silly" errors, like misspelled variable names.
Second, have you tried the old-fashioned debugging method of writing (parts of) the arrays you're interested in to the screen? Just put in some statements like
write(*,*) gavenaa(:5)
immediately after an assignment statement, to see if the arrays ever contain values you expect.
If you still can't find the place where things go wrong, try to reduce the code to a minimal, but complete, example that exhibits the same problem. Often the mistake will be found while doing this, but if not, it is much easier for others to help you if you can give them some code that is complete and compiles directly.

If you're just doing whole array assignments why are you bothering with forall constructs ? Since all the arrays in question have the same size you could simplify this block:
gavenaa(1:nasize) = Gnaatm(1:nasize)
forall(icount = 1:nasize)
gavenas(icount) = Gnascf(icount) + gavenas(icount)
end forall
to
gavenaa = Gnaatm
gavenas = Gnascf + gavenas
Likewise in the rest of your code.
I can't say that your use of the forall is incorrect, but it seems unnecessary and slimming your code down a bit will help you, and us, to properly diagnose and fix whatever problem you have.

Related

Remove all the rows after an index value from an array in Fortran

I want an array to remove all the rows after a certain index value from an array in Fortran. That means that if the size of the array initially is p, it should become q, where q is the index after which everything is to be removed.
Here is the relevant bit of code:
real(8), allocatable :: circlesx(:),circlesy(:)
allocate(circlesx(n**2-n))
allocate(circlesy(n**2-n))
do i=1,n-1
do j=i+1,n
call intersect2circles(stlo(i),stla(i),distance(i),stlo(j),stla(j),distance(j),ax,ay,bx,by,flag)
if (flag==0) then
circlesx(k)=ax
circlesy(k)=ay
circlesx(k+1)=bx
circlesy(k+1)=by
k=k+2
endif
enddo
enddo
The flag basically checks if two circles intersect or not. So if there is no intersection, no values are assigned to the arrays circlesx and circlesy. The size of the arrays which I am allocating at first is the maximum number of points of intersection of n circles = n^2-n. I get a segmentation fault if I don't allocate them.
Reshape also didn't work, although I might have done something wrong there. This gave an unclassifiable statement error:-
reshape(circlesx,[ n**2-n-1 ])
I want the size of the circles arrays to change to k-2 after the loops are done
So what I need is, if n=2, so circlesx and circlesy have a size of 2, then,
circlesx=[0,0]
.
.
some calculations
.
.
circlesx=[1.2,0] ! only one value has been allocated
.
.
reshape the array accordingly
.
.
circlesx=[1.2]
Is there any way to do this in Fortran? I am using an f90 file extension and using gfortran v7.3.0
Questions around here about dynamic resizing of an array generally care about enlargening the array. That is the harder problem.1
However, the fundamental considerations are much the same. Consider
integer, allocatable :: arr(:)
allocate(arr(3))
arr = [1, 2, 3]
end
With intrinsic assignment we see from elsewhere that we could just write
integer, allocatable :: arr(:)
arr = [1, 2, 3]
end
and have arr allocated to the correct shape as part of the assignment.
We've seen this to: enlarge an array
arr = [arr, 4]
remove "bad values":
arr = PACK(arr, arr>1.and.arr<4)
Selecting just the first few elements is as simple as
arr = arr(:q)
The days where compilers require special flags to compile such code correct are slowly passing, but do (especially if using an old version) check your compiler documentation for how to ensure automatic allocation happens on intrinsic assignment.
1 Even in the days without dynamic memory allocation, one handled "shorter" arrays simply. Take a static-sized array as large as you'll ever need and do some bookkeeping around how many elements are used. In modern code you may see such artefacts when using old libraries.

Add element to FORTRAN pointer?

I have an array arr in fortran going from 1 to n where I need to test each element against the elements preceding and succeeding (i.e. i against i-1 and i+1) - the problem being elements 1 and n that have n or 1 as predecessor or successor, respectively (i.e. it loops).
Instead of testing the first and last elements separately, I'd rather run a loop like:
do i=1,n
call testi(i-1,i,i+1)
end do
and define a pointer (in order to not use a dummy array and twice the memory) like
arrpointer(0) => arr(n)
arrpointer(1:n) => arr(1:n)
arrpointer(n+1) => arr(1)
to "simulate" the loop in my array. (Note that each array element is a vector - arr(i)%vec(1:m) )
The above does not work as each new definition of the pointer will overwrite the previous. So the question arises:
Is there any way to actually add an element to a pointer array without deleting the previous definitions?
PS:
As current workaround, I use an allocatable type array with the pointers:
type :: pointerarray
real, pointer :: elementpointer(:)
end type pointerarray
type(pointerarray), allocatable :: arrpointer(:)
arrpointer(0)%elementpointer => arr(n)
do i=1,n
arrpointer(i)%elementpointer => arr(i)
end do
arrpointer(n+1)%elementpointer => arr(1)
while replacing the loop as below does not work:
arrpointer(1:n)%elementpointer => arr(1:n)
However there might be a simpler way of which I am not aware, as type arrays for the pointers again make the code not as nicely readable.
I don't think there's a way to do this with pointers the way you envision. Instead, I recommend using an integer array dimensioned 0:N+1 that map to the desired 1:N range. For example:
integer :: i(0:N+1), j
real :: a(N)
! -- Setup
do j=1,N
i(j) = j
enddo
i(0) = N
i(N+1) = 1
! -- Then you can do:
do j=1,N
! call mysub(a(i(j-1)), a(i(j)), a(i(j+1)))
enddo
Alternatively, you could use a function to define i(j).
I don't have Fortran on this machine so haven't tested this. It's also not entirely clear what OP's testi routine does. So, this is not a complete answer, but might provide some useful (or useless) hints at a pointerless solution.
Don't forget the intrinsic function chsift. One way to perform, say, a one-sided difference calculation on an array would be to write
arrdiff = arr - chsift(arr,1)
cshift shifts elements from one end of the array to the other unlike its cousin eoshift which performs an end-off shift. Of course chsift is likely to require the creation of a temporary of the same size as the array (in theory it could be done without a temporary, in practice it always seems to use one) so may be unappealing on performance and memory usage grounds.

Indexing sliced array in matlab??? [duplicate]

For example, if I want to read the middle value from magic(5), I can do so like this:
M = magic(5);
value = M(3,3);
to get value == 13. I'd like to be able to do something like one of these:
value = magic(5)(3,3);
value = (magic(5))(3,3);
to dispense with the intermediate variable. However, MATLAB complains about Unbalanced or unexpected parenthesis or bracket on the first parenthesis before the 3.
Is it possible to read values from an array/matrix without first assigning it to a variable?
It actually is possible to do what you want, but you have to use the functional form of the indexing operator. When you perform an indexing operation using (), you are actually making a call to the subsref function. So, even though you can't do this:
value = magic(5)(3, 3);
You can do this:
value = subsref(magic(5), struct('type', '()', 'subs', {{3, 3}}));
Ugly, but possible. ;)
In general, you just have to change the indexing step to a function call so you don't have two sets of parentheses immediately following one another. Another way to do this would be to define your own anonymous function to do the subscripted indexing. For example:
subindex = #(A, r, c) A(r, c); % An anonymous function for 2-D indexing
value = subindex(magic(5), 3, 3); % Use the function to index the matrix
However, when all is said and done the temporary local variable solution is much more readable, and definitely what I would suggest.
There was just good blog post on Loren on the Art of Matlab a couple days ago with a couple gems that might help. In particular, using helper functions like:
paren = #(x, varargin) x(varargin{:});
curly = #(x, varargin) x{varargin{:}};
where paren() can be used like
paren(magic(5), 3, 3);
would return
ans = 16
I would also surmise that this will be faster than gnovice's answer, but I haven't checked (Use the profiler!!!). That being said, you also have to include these function definitions somewhere. I personally have made them independent functions in my path, because they are super useful.
These functions and others are now available in the Functional Programming Constructs add-on which is available through the MATLAB Add-On Explorer or on the File Exchange.
How do you feel about using undocumented features:
>> builtin('_paren', magic(5), 3, 3) %# M(3,3)
ans =
13
or for cell arrays:
>> builtin('_brace', num2cell(magic(5)), 3, 3) %# C{3,3}
ans =
13
Just like magic :)
UPDATE:
Bad news, the above hack doesn't work anymore in R2015b! That's fine, it was undocumented functionality and we cannot rely on it as a supported feature :)
For those wondering where to find this type of thing, look in the folder fullfile(matlabroot,'bin','registry'). There's a bunch of XML files there that list all kinds of goodies. Be warned that calling some of these functions directly can easily crash your MATLAB session.
At least in MATLAB 2013a you can use getfield like:
a=rand(5);
getfield(a,{1,2}) % etc
to get the element at (1,2)
unfortunately syntax like magic(5)(3,3) is not supported by matlab. you need to use temporary intermediate variables. you can free up the memory after use, e.g.
tmp = magic(3);
myVar = tmp(3,3);
clear tmp
Note that if you compare running times with the standard way (asign the result and then access entries), they are exactly the same.
subs=#(M,i,j) M(i,j);
>> for nit=1:10;tic;subs(magic(100),1:10,1:10);tlap(nit)=toc;end;mean(tlap)
ans =
0.0103
>> for nit=1:10,tic;M=magic(100); M(1:10,1:10);tlap(nit)=toc;end;mean(tlap)
ans =
0.0101
To my opinion, the bottom line is : MATLAB does not have pointers, you have to live with it.
It could be more simple if you make a new function:
function [ element ] = getElem( matrix, index1, index2 )
element = matrix(index1, index2);
end
and then use it:
value = getElem(magic(5), 3, 3);
Your initial notation is the most concise way to do this:
M = magic(5); %create
value = M(3,3); % extract useful data
clear M; %free memory
If you are doing this in a loop you can just reassign M every time and ignore the clear statement as well.
To complement Amro's answer, you can use feval instead of builtin. There is no difference, really, unless you try to overload the operator function:
BUILTIN(...) is the same as FEVAL(...) except that it will call the
original built-in version of the function even if an overloaded one
exists (for this to work, you must never overload
BUILTIN).
>> feval('_paren', magic(5), 3, 3) % M(3,3)
ans =
13
>> feval('_brace', num2cell(magic(5)), 3, 3) % C{3,3}
ans =
13
What's interesting is that feval seems to be just a tiny bit quicker than builtin (by ~3.5%), at least in Matlab 2013b, which is weird given that feval needs to check if the function is overloaded, unlike builtin:
>> tic; for i=1:1e6, feval('_paren', magic(5), 3, 3); end; toc;
Elapsed time is 49.904117 seconds.
>> tic; for i=1:1e6, builtin('_paren', magic(5), 3, 3); end; toc;
Elapsed time is 51.485339 seconds.

functions,tables and for in Lua

Right now I'm doing some tests but I cant seem to find what is wrong with this code - any idea?
function IATetris(Pieza,Rotacion,Array)
io.write("The table the script received has: ",Pieza,"\n")
RotacionInicial = Rotacion
PosInicial = 7
final = #Array --this gets the size of the array
i = 1
for y = 1, 20 do --the array of my tetris board is 20 in x and 14 in y so it would be something like this Array2D[20][14]
io.write(" First for y ",y,"\n")
Array2D[y]={} --clearing the new array
for x = 1,14 do
io.write(" First for x ",x,"\n")
if i == final then break end
io.write(" First for i",i,"\n")
Array2D[y][x] = Array[i]
i= i+1 --seems like you cant use i++ in lua
end
end
end
What I'm doing is getting 2 integers and 1 Array. I'm having to write in the console to check where the program is actually going, and what I'm getting is...
The first log message: "The table the script received has: "
and the second log message: " First for y "
But I don't get any further than those so probably the program is crashing there? This function is being called like every 20 seconds or so. I have really no idea why this is happening. Any help would be really appreciated, thank you.
If this line logs:
io.write(" First for y ",y,"\n")
and this line does not log:
io.write(" First for x ",x,"\n")
Then the problem is on one of these lines:
Array2D[y]={} --clearing the new array
for x = 1,14 do
for x... definitely works for me, so I'd suggest it's the Array2D line. There is nothing syntactically wrong with it, so it must be a runtime error. Runtime errors should be reported by Lua or the application it is embedded into. If they aren't and the function just "stops" then you are debugging blind, and you will waste a lot of time on problems like this.
The only error I can think might happen on that line would be if Array2D is not a table. Since you are trying to index it, it needs to be. Array2D isn't declared in your function, this is fine if it is a global variable that is already defined elsewhere. However if it is meant to be a local variable just for this function then you should add local Array2D = {} to it.
Without knowing what Array2D is, or what your actual error is even, it's hard to give a more accurate answer. If you really have no better method of finding out the problem than logging, this, just before the Array2D line, should test my hypothesis:
io.write("Array2D is: ", type(Array2D), "\n")
Looks like Array2D is not initialized (or not a table), so it craps on Array2D[y]={}.
You can use pcall to call a function and trap errors, like this:
local ok, msg = pcall(IATetris, pieza, rotacion, array)
if not ok then
print("ERROR:", msg)
end
Side note: you should be using the local keyword whenever possible to limit the scope of your variables.

Visual Basic 6 Empty Array Index

In VB6 it is possible to prepand array identifiers with an empty array index. For example:
Dim x(0 To 20) As Integer
x(0) = 1
Debug.Print x(0)
Debug.Print x()(0)
The debug statements appear to the same thing, even though an empty index is given to the array before the index in the last statement. Does anyone know what this is and why this works?
Does anyone know what this is and why this works?
It’s a “bug” in the compiler: for reasons of syntactical consistency with the declaration, references to an array x may also be written as x(); thus, it is possible to write the following code:
Dim x() As Integer
x() = SomeFunctionReturningAnArray()
Well, some programmers think this is more consistent than writing x = …. (I thought so, too, for a time.) That you can use it in front of dereferencing the array is simply a hole in the syntax validation, though.

Resources