Java Forum / General / November 2006
how to "translate" dynamic array in FORTRAN 90 to Java code?
Shawn - 15 Nov 2006 15:35 GMT 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.
Jeffrey Schwab - 15 Nov 2006 15:37 GMT > Hi, > [quoted text clipped - 32 lines] > > ? Depending on density and performance requirements, you might prefer to use a java.util.Map<Integer, String>.
Shawn - 15 Nov 2006 16:27 GMT > Vector vec = new Vector(); > vec.add(0, new Integer(4)); [quoted text clipped - 16 lines] > > ? 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); }
}
Jeffrey Schwab - 16 Nov 2006 12:41 GMT >> Vector vec = new Vector(); >> vec.add(0, new Integer(4)); [quoted text clipped - 30 lines] > //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.
Chris Uppal - 15 Nov 2006 16:34 GMT > Previously, I use Object array in Java to translate FORTRAN array. But > now, array in Java have to be fixed size. [quoted text clipped - 10 lines] > 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
Shawn - 15 Nov 2006 16:47 GMT >> Previously, I use Object array in Java to translate FORTRAN array. But >> now, array in Java have to be fixed size. [quoted text clipped - 14 lines] > 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;
Shawn - 15 Nov 2006 16:49 GMT >> Previously, I use Object array in Java to translate FORTRAN array. But >> now, array in Java have to be fixed size. [quoted text clipped - 14 lines] > 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];
Oliver Wong - 16 Nov 2006 17:08 GMT >>> Previously, I use Object array in Java to translate FORTRAN array. But >>> now, array in Java have to be fixed size. [quoted text clipped - 24 lines] > 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
tam@lheapop.gsfc.nasa.gov - 17 Nov 2006 15:53 GMT > Hi, > [quoted text clipped - 34 lines] > > 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
Martin Gregorie - 18 Nov 2006 16:35 GMT > 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.
 Signature martin@ | Martin Gregorie gregorie. | Essex, UK org |
tam@lheapop.gsfc.nasa.gov - 20 Nov 2006 15:49 GMT ...
> 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
Martin Gregorie - 20 Nov 2006 20:14 GMT > ... >> The thing that nobody else has addressed yet is that Fortran loads [quoted text clipped - 4 lines] > > 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., [quoted text clipped - 5 lines] > 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: > [quoted text clipped - 4 lines] > ... > 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.
 Signature martin@ | Martin Gregorie gregorie. | Essex, UK org |
steve - 20 Nov 2006 21:49 GMT >> ... >>> The thing that nobody else has addressed yet is that Fortran loads [quoted text clipped - 37 lines] > 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.
Martin Gregorie - 21 Nov 2006 13:11 GMT >> ... >>> The thing that nobody else has addressed yet is that Fortran loads [quoted text clipped - 37 lines] > 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.
 Signature martin@ | Martin Gregorie gregorie. | Essex, UK org |
tam@lheapop.gsfc.nasa.gov - 21 Nov 2006 15:34 GMT ...
> > To me it looks like one of the more horrid things that can be achieved > > in COBOL with a table redefining another table. [quoted text clipped - 8 lines] > 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
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|