how to "translate" dynamic array in FORTRAN 90 to Java code?

S

Shawn

Hi,

I am translating a Fortran program to Java code. Starting FORTRAN 90, an
array size can be un-specified, for example:

DIMENSION PS(*)

is an array with size unspecified. On the run-time, its size can be
increased automatically if needed.

Previously, I use Object array in Java to translate FORTRAN array. But
now, array in Java have to be fixed size.

If I use collections in Java, like Vector or ArrayList, the problem is,
as stated in my posting previously and copied to below:


Vector vec = new Vector();
vec.add(0, new Integer(4));
vec.add(1, new Double(4.4));
vec.add(2, "How are you?");
vec.add(5, "morning");

The last one is one error and the program cannot run. I purposely
skipped a couple positions.
There is a reason that I need skipping: I am "translating" Fortran code
to Java. In the original Fortran code, it takes an array several item
positions to hold a long string, like "How are you?". In Java, it only
needs one item position to hold it. I hope to keep index in Fortran and
Java correspondent, so I need skipping to let several item positions
unused. But the program will not run now.

Maybe I need:
vec.add(3, null);
vec.add(4, null);

?

Thank you again for your help.
 
J

Jeffrey Schwab

Shawn said:
Hi,

I am translating a Fortran program to Java code. Starting FORTRAN 90, an
array size can be un-specified, for example:

DIMENSION PS(*)

is an array with size unspecified. On the run-time, its size can be
increased automatically if needed.

Previously, I use Object array in Java to translate FORTRAN array. But
now, array in Java have to be fixed size.

If I use collections in Java, like Vector or ArrayList, the problem is,
as stated in my posting previously and copied to below:


Vector vec = new Vector();
vec.add(0, new Integer(4));
vec.add(1, new Double(4.4));
vec.add(2, "How are you?");
vec.add(5, "morning");

The last one is one error and the program cannot run. I purposely
skipped a couple positions.
There is a reason that I need skipping: I am "translating" Fortran code
to Java. In the original Fortran code, it takes an array several item
positions to hold a long string, like "How are you?". In Java, it only
needs one item position to hold it. I hope to keep index in Fortran and
Java correspondent, so I need skipping to let several item positions
unused. But the program will not run now.

Maybe I need:
vec.add(3, null);
vec.add(4, null);

?

Depending on density and performance requirements, you might prefer to
use a java.util.Map<Integer, String>.
 
S

Shawn

Shawn said:
Vector vec = new Vector();
vec.add(0, new Integer(4));
vec.add(1, new Double(4.4));
vec.add(2, "How are you?");
vec.add(5, "morning");

The last one is one error and the program cannot run. I purposely
skipped a couple positions.
There is a reason that I need skipping: I am "translating" Fortran code
to Java. In the original Fortran code, it takes an array several item
positions to hold a long string, like "How are you?". In Java, it only
needs one item position to hold it. I hope to keep index in Fortran and
Java correspondent, so I need skipping to let several item positions
unused. But the program will not run now.

Maybe I need:
vec.add(3, null);
vec.add(4, null);

?

Thank you for the reply. I will consider using Map with integer as the key.

Another idea I can think of is that writing a new class PowerVector, a
subclass of Vector class.

public class PowerVector extend Vector
{
...
public void add(int index, Object obj) //overwrite add method in Vector
class
{
//looping to check all the positions from 0 to index-1, if it is
unfilled, then do: super.add(indexposition, null);
super.add(index, obj);
}

}
 
C

Chris Uppal

Shawn said:
Previously, I use Object array in Java to translate FORTRAN array. But
now, array in Java have to be fixed size.

If I use collections in Java, like Vector or ArrayList, the problem is,
as stated in my posting previously and copied to below:


Vector vec = new Vector();
vec.add(0, new Integer(4));
vec.add(1, new Double(4.4));
vec.add(2, "How are you?");
vec.add(5, "morning");

The last one is one error and the program cannot run. I purposely
skipped a couple positions.

Is there any reason why you cannot just write your own class, FortranishArray,
which behaves how you want ?

Just because java.util contains some fairly useful classes doesn't mean you
have to use them for /everything/ !

-- chris
 
S

Shawn

Chris said:
Is there any reason why you cannot just write your own class, FortranishArray,
which behaves how you want ?
I don't know how to write such an Array class, taking "[]".

FortranishArray arr = new FortranishArray();
arr[0] = 9;
arr[2] = "Good morning";
arr[5] = 3.3;
 
S

Shawn

Chris said:
Is there any reason why you cannot just write your own class, FortranishArray,
which behaves how you want ?
I don't know how to write such an Array class, taking "[]".

FortranishArray arr = new FortranishArray();
arr[0] = 9;
arr[2] = "Good morning";
arr[5] = 3.3;
....
int num = arr[0];
double d = arr[5];
 
J

Jeffrey Schwab

Shawn said:
Thank you for the reply. I will consider using Map with integer as the key.

Another idea I can think of is that writing a new class PowerVector, a
subclass of Vector class.

public class PowerVector extend Vector
{
...
public void add(int index, Object obj) //overwrite add method in
Vector class
{
//looping to check all the positions from 0 to index-1, if it is
unfilled, then do: super.add(indexposition, null);

Why only add to positions that are unfilled? You don't want to be able
to assign values to the same index multiple times?
super.add(index, obj);
}
}

Better than extending Vector might be to extend AbstractCollection. You
could use a member of type ArrayList or the like. On each assignment to
an indexed element of the container, resize the wrapped container if
need be.
 
O

Oliver Wong

Shawn said:
Chris said:
Is there any reason why you cannot just write your own class,
FortranishArray,
which behaves how you want ?
I don't know how to write such an Array class, taking "[]".

FortranishArray arr = new FortranishArray();
arr[0] = 9;
arr[2] = "Good morning";
arr[5] = 3.3;
...
int num = arr[0];
double d = arr[5];

You can't: Java doesn't allow operator overloading, and (I think) [] is
considered an operator. However, you can achieve the same semantics, even if
the syntax differs:

FortranishArray arr = new FortranishArray();
arr.set(0, 9);
arr.set(2, "Good morning");
arr.set(5, 3.3);
....
int num = arr.getAsInt(0);
double d = arr.getAsDouble(5);

- Oliver
 
T

tam

Shawn said:
Hi,

I am translating a Fortran program to Java code. Starting FORTRAN 90, an
array size can be un-specified, for example:

DIMENSION PS(*)

is an array with size unspecified. On the run-time, its size can be
increased automatically if needed.

Previously, I use Object array in Java to translate FORTRAN array. But
now, array in Java have to be fixed size.

If I use collections in Java, like Vector or ArrayList, the problem is,
as stated in my posting previously and copied to below:


Vector vec = new Vector();
vec.add(0, new Integer(4));
vec.add(1, new Double(4.4));
vec.add(2, "How are you?");
vec.add(5, "morning");

The last one is one error and the program cannot run. I purposely
skipped a couple positions.
There is a reason that I need skipping: I am "translating" Fortran code
to Java. In the original Fortran code, it takes an array several item
positions to hold a long string, like "How are you?". In Java, it only
needs one item position to hold it. I hope to keep index in Fortran and
Java correspondent, so I need skipping to let several item positions
unused. But the program will not run now.

Maybe I need:
vec.add(3, null);
vec.add(4, null);

?

Thank you again for your help.

Hi Shawn,

I think both you and some of the posters responding may have a
misunderstanding about
the meaning of the Fortran specification.

There are two kinds Fortran array specifications where the size is not
given.

The notation

real array(*)

is normally used when the array is a parameter of a subroutine, and the
real dimension will be specified in the argument...

E.g.,

program main
real myArray(100)
call sub(myArray)
end

subroutine sub(array)
real array(*)
...
end

This is exactly analagous to

void method() {
float[] myArray = new float[100];
sub(myArray);
}
void sub(float[] array) {
...
}

Fortran also has dynamically allocated arrays where the
size is determined at run time and the array
can be reallocated. I'm a bit rusty on the syntax here but it's
something like.

real, allocatable :: myArray:))
...
allocate(myArray(2*n))
...
deallocate(myArray)
....
allocate(myArray(3*n))
...

This corresponds in Java to something like:

float[] myArray;
...
myArray = new float[2*n];
...
...
myArray = new float[3*n];
...



I'm pretty sure that anything like:

program main
real myArray(*)
myArray(3) = 3.14
end
or
real myArray(3)
myArray(5) = 25
end


are illegal in all versions of the Fortran standard. Neither Fortran
nor Java provides for automatic extensions of arrays when
a user asks for an element beyond the end of the allocated array.

So your job in translating from Fortran to Java may be a bit easier
than you have been led to believe...

Regards,
Tom McGlynn
 
M

Martin Gregorie

Shawn said:
There is a reason that I need skipping: I am "translating" Fortran code
to Java. In the original Fortran code, it takes an array several item
positions to hold a long string, like "How are you?". In Java, it only
needs one item position to hold it. I hope to keep index in Fortran and
Java correspondent, so I need skipping to let several item positions
unused. But the program will not run now.
The thing that nobody else has addressed yet is that Fortran loads
strings into an array by overwriting enough array elements to
accommodate the string. To handle this acceptably and retain the
original indices you'll need to define your own class rather than
re-using anything in the standard class library.

If I was doing it I'd try the following as a first stab:

Use a Vector or, better, a TreeMap as the extensible storage inside your
class. The TreeMap will give faster access than the Vector.

The extensible storage would use a second user-defined an object class
to represent an array element. This would have an integer key value
(corresponding to the index) and fields to hold all possible value types
(Integer, Double, String, ...). Only one value type would be set in an
element. Then implement methods for reading and writing element values
using the "index" as the key to find a matching element.

This won't be startlingly fast but it will allow you to store strings
and preserve the original index values. With a bit of care it should
even allow you to reference parts of strings ( PS(3) or PS(4) in your
example. Additional methods will let you iterate through the list of
elements, etc.
 
T

tam

Martin said:
....
The thing that nobody else has addressed yet is that Fortran loads
strings into an array by overwriting enough array elements to
accommodate the string. To handle this acceptably and retain the
original indices you'll need to define your own class rather than
re-using anything in the standard class library.

I don't think that's the way Fortran character variables work...

It's a little unclear from the OP's post what he's doing but a Fortran
string is always of a defined length, e.g.,
character*15 x(10)
is an array of 10 strings each 15 characters long. [with provisions
for character*(*) for a subroutine/function parameter] Normally when
one 'loads' an array Fortran pads the result with spaces or truncates
to the specified character length. Fortran does not have variable
length
character strings (unless they were added in the F2003 standard).

Maybe the poster is using a character*1 array to store strings and
doing
their own version of variable length strings. If so a
char[] array in Java should be a very nice equivalent of the character
array..

Java has substantially greater flexibility than Fortran in
dealing with character strings, and I'd be surprised if
there was anything Fotran was doing that could not
be straightforwardly transcribed into Java. The transcription
might not be idiomatic Java but it should be easy enough to get
working.
Then one could think about transforming it
to a more standard Java practice.

Perhaps the OP could post some of the code that he is having
trouble translating.

Maybe the poster is reusing buffers in some complex fashion like:

character*1 cbuf[10000]
integer ibuf[2500]
real rbuf[2500]
equivalence (cbuf, ibuf, rbuf)
....
where the equivalence means that the three arrays share storage.

This is (afaik) illegal since characters are not allowed to be
equivalenced
to numbers but may work in some implementations. This kind
of tricky overwriting of storage is something that's a bit more
difficult to emulate in Java and might require a new class. But it's
the common storage not the character strings that is
the problem.
Regards,
Tom McGlynn
 
M

Martin Gregorie

Martin Gregorie wrote:
...

I don't think that's the way Fortran character variables work...
You're probably right: my Fortran skills are minimal (I think I wrote a
simple program about 30 years ago).
It's a little unclear from the OP's post what he's doing but a Fortran
string is always of a defined length, e.g.,
character*15 x(10)
is an array of 10 strings each 15 characters long. [with provisions
for character*(*) for a subroutine/function parameter] Normally when
one 'loads' an array Fortran pads the result with spaces or truncates
to the specified character length. Fortran does not have variable
length
character strings (unless they were added in the F2003 standard).
That's what I thought it did.
Maybe the poster is reusing buffers in some complex fashion like:

character*1 cbuf[10000]
integer ibuf[2500]
real rbuf[2500]
equivalence (cbuf, ibuf, rbuf)
...
where the equivalence means that the three arrays share storage.
I don't think he wrote the program he wants to translate but I could be
wrong.

However, it certainly looks like that sort of mapping is going on from
the way his array index is being used and his description of it.

To me it looks like one of the more horrid things that can be achieved
in COBOL with a table redefining another table.
 
S

steve

Martin Gregorie wrote:
...

I don't think that's the way Fortran character variables work...
You're probably right: my Fortran skills are minimal (I think I wrote a
simple program about 30 years ago).
It's a little unclear from the OP's post what he's doing but a Fortran
string is always of a defined length, e.g.,
character*15 x(10)
is an array of 10 strings each 15 characters long. [with provisions
for character*(*) for a subroutine/function parameter] Normally when
one 'loads' an array Fortran pads the result with spaces or truncates
to the specified character length. Fortran does not have variable
length
character strings (unless they were added in the F2003 standard).
That's what I thought it did.
Maybe the poster is reusing buffers in some complex fashion like:

character*1 cbuf[10000]
integer ibuf[2500]
real rbuf[2500]
equivalence (cbuf, ibuf, rbuf)
...
where the equivalence means that the three arrays share storage.
I don't think he wrote the program he wants to translate but I could be
wrong.

However, it certainly looks like that sort of mapping is going on from
the way his array index is being used and his description of it.

To me it looks like one of the more horrid things that can be achieved
in COBOL with a table redefining another table.

it's completely the wrong way to go about it, and it will end up as spaghetti
code.
He needs to look at what the fortran program is doing , and the results it is
providing , step back.

And re-write it in java.
 
M

Martin Gregorie

Martin said:
Martin Gregorie wrote:
...

I don't think that's the way Fortran character variables work...
You're probably right: my Fortran skills are minimal (I think I wrote a
simple program about 30 years ago).
It's a little unclear from the OP's post what he's doing but a Fortran
string is always of a defined length, e.g.,
character*15 x(10)
is an array of 10 strings each 15 characters long. [with provisions
for character*(*) for a subroutine/function parameter] Normally when
one 'loads' an array Fortran pads the result with spaces or truncates
to the specified character length. Fortran does not have variable
length
character strings (unless they were added in the F2003 standard).
That's what I thought it did.
Maybe the poster is reusing buffers in some complex fashion like:

character*1 cbuf[10000]
integer ibuf[2500]
real rbuf[2500]
equivalence (cbuf, ibuf, rbuf)
...
where the equivalence means that the three arrays share storage.
I don't think he wrote the program he wants to translate but I could be
wrong.

However, it certainly looks like that sort of mapping is going on from
the way his array index is being used and his description of it.

To me it looks like one of the more horrid things that can be achieved
in COBOL with a table redefining another table.
Afterthought. The OP doesn't say, but if the array is in the COMMON area
that its probably doing exactly the COBOL redefine thing. By using
different definitions of COMMON in different Fortran modules I think you
can sidestep the EQUIVALENCE (or any other) restriction on memory
redefinition imposed by the language.

If that's what the original Fortran program is doing then, as suggested
elsewhere in this thread, a complete rewrite is the most sensible thing
to do.
 
T

tam

Martin said:
Afterthought. The OP doesn't say, but if the array is in the COMMON area
that its probably doing exactly the COBOL redefine thing. By using
different definitions of COMMON in different Fortran modules I think you
can sidestep the EQUIVALENCE (or any other) restriction on memory
redefinition imposed by the language.

If that's what the original Fortran program is doing then, as suggested
elsewhere in this thread, a complete rewrite is the most sensible thing
to do.
It's been a while since I've used Fortran extensively, but using COMMON

to equivalence numeric and character data is, I believe, just as
illegal
as equivalencing them directly. However given the way Fortran programs
are typically compiled and linked it's an error that may easily
go undetected and unreported. So if this is indeed the issue the OP
is having, then his first step might be to get the program
working legally in Fortran! And then consider the Java translation.

If there is complex and confusing logic in the Fortran program
reusing arrays in some potentially illegal fashion, then I agree that
going back and doing a redesign (in either language) is probably
necessary to make progress.

However I could envisage something like
parameter BufferSize=30000, MaxWords=5000
character*1 buffer(BufferSize)
integer wordLen(MaxWords), wordStart(MaxWords)

...
wordStart(currWord) = bufOffset
wordLen(currWord) = currWordLen
do i=bufOffset, bufOffset+currWordLen-1
buffer(i) = ...
enddo
...
to handle variable length strings. If so I might first want to
translate this very literally to Java using char[] arrays, and
only after I get this working worry about translating to a
more natural Java idiom using Strings. Particularly if I
were not expert in either the source or
destination languages which the OP's comment imply, this makes it
easier to ensure that I'm not introducing errors in the translation.
Being able to compare with the presumably working Fortran version
will be a big advantage in getting the first Java version going.

Regards,
Tom McGlynn
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,021
Latest member
AkilahJaim

Latest Threads

Top