the goto fortran90 command convert to matlab

5 views (last 30 days)
Hi,
How i can best convert the goto command of f90, to matlab. the f2matlab function available does very poor job on this. This is the part of the f90 code interested in:
do n=2,350
if (b<=a(n)) goto 10
end do
n=350
print*,'Increase upper bound of assets getupp',b
10 consleft=c0(nnnn-1,eeee)
consright=c0(nnnn,eeee)
I will appreciate any help and explanations on this

Accepted Answer

dpb
dpb on 11 Jun 2014
Edited: dpb on 11 Jun 2014
The other Fortran solution is better refactoring than what I had posted earlier (with the correction of the oversight of missing the redefinition of n, anyway) so I removed my version.
However, the "Matlab way" would remove the loop entirely. sotoo--
if all(a(2:350)<b)
n=350;
disp(['Increase upper bound of assets getupp' num2str(b)])
end
I've no idea if f2matlab has the ability to vectorize anything or not; I'd suspect probably not but I've never used it.
  3 Comments
msh
msh on 12 Jun 2014
Edited: msh on 12 Jun 2014
One clarification, the " loop" in the Fortran code, as I wrote it in my question, essentially says that if the "condition" is true, then go to the relevant line and execute the algorithm. Is that correct? So, essentially the "go to" does what it says.
Now, I am not sure whether is crucial or not, but having the correct n, is very important for the algorithm. since the line with label 10 (in the fortran code) is
consleft=c0(n-1,eeee)
By mistake I wrote :
consleft=c0(nnnn-1,eeee)
consright=c0(nnnn,eeee)
The difference is that if the condition is true, the value of n is taken from when the condition is true, Am I right ? So, I wonder whether still makes any difference what you are suggesting me.
dpb
dpb on 12 Jun 2014
Edited: dpb on 12 Jun 2014
...essentially the "go to" does what it says.
Precisely. As used here it is a Matlab break from a loop with the enhanced feature of a target location that changes execution path unilaterally to that location. As in break, the loop construct is terminated entirely; unlike it wherein the only place one can go is the line directly following the associated end, this gives the ability to have the fixup code inline w/ no additional logic. It's essentially a try...catch block before there was such a formal structured construct.
...since the line with label 10 ... is [dependent on the loop variable]...
Ooooh...that's does make a difference--as you posted, the code basically checked for any value of the array against the reference and if so, branched. I wondered at the construction some but one often finds strange-looking things in old code.
With the correction that the value of the index at which the test occurs is actually used, then the result of the replacement of the loop by the pure logical will not give the necessary information as one dosn't find the n that way.

Sign in to comment.

More Answers (4)

Sara
Sara on 11 Jun 2014
I would eliminate the need for the goto altogether. Try this:
n = 2;
while(b > a(n) && n < 350)
n = n + 1;
end
if(b > a(n))
print*,'Increase upper bound of assets getupp',b
end
consleft=c0(nnnn-1,eeee)
consright=c0(nnnn,eeee)
  1 Comment
dpb
dpb on 11 Jun 2014
Edited: dpb on 11 Jun 2014
The above missed resetting n ...
...
if(b > a(n))
n=350
print*,'Increase upper bound of assets getupp',b
end
...

Sign in to comment.


dpb
dpb on 12 Jun 2014
...essentially the "go to" does what it says.
Precisely. It is a Matlab break with a target location that changes execution path unilaterally to that location.
...since the line with label 10 ... is [based on n, not another variable]
Ooooh...that's does make a difference--as you posted, the code basically checked for any value of the array against the reference and if so, branched. I wondered at the construction some but one often finds strange-looking things in old code.
With the correction that the value of the index at which the test occurs is actually used, then the result of the replacement of the loop by the pure logical will not give the necessary information as one dosn't find the n that way.
One possible solution--
n=find(b<=a(2:350),1)+1; % locate 1st position a<b excluding first
if ~isempty(n) % if no value found, reset n and warn...
n=350;
disp(['Increase upper bound of assets getupp' num2str(b)])
end
consleft=c0(n-1,eeee)
...
Can you tell the upper dimension for the array a from the code? I suppose keeping the hardcoded limits is safest, I typed in a(2:end) by habit and got me wondering.
  2 Comments
msh
msh on 12 Jun 2014
Thanks again, indeed the code is somehow old and is based in f90. In what I posted I tried to simplify things and get straight to the point. The original fortran code is the following
function getsav (aaaa,eeee) result(savings)
integer :: nnnn, eeee
real ( kind =8 ) :: aaaa, savings, normaaaa
normaaaa=aaaa
do nnnn = 2, agrid
if ( normaaaa <= a(nnnn) ) goto 10
end do
nnnn=agrid
write(6,*)'hits the upperbound of asset in GETSAV',&
normaaaa
write(7,*)'hits the upperbound of asset in GETSAV',&
normaaaa
10 savings = interpol(a(nnnn-1), a(nnnn), &
ystar(nnnn-1,eeee),ystar(nnnn,eeee), normaaaa)
end function getsav
  • 1. The inputs, "aaaa" and "eeee" are real numbers
  • 2. the "a" is a previously defined array
So, I guess now that the modified simple code with the correction i made, it captures the spirit of this one. In this case, your answer above seems to be more consistent with this piece of code. Correct ?
dpb
dpb on 12 Jun 2014
Edited: dpb on 13 Jun 2014
I presume then that "a" and "agrid" as well as the other argument arrays are in COMMON?
Another coding anomaly is there's no reason for the temporary "normaaa"; might as well use "aaaa" itself unless the function interpol() modifies its arguments. Again, another case of probably ought to follow the original unless delved deeply into the bowels. Matlab, being as it does not allow one to modify arguments is a difficult translation from Fortran if there are such function side effects.
Try
function r=testit(x)
r=x;
x=2*x;
a=[1:3];
testit(a)
a
In Fortran the equivalent function will end up with the array "a" being modified; not so in Matlab.
But, for the specific logic block in question, "yes" the updated logic will reproduce the Fortran behavior.
ADDENDUM
To my surprise, f2matlab did recognize the side-effects of a prototype function I gave it and moved created a second output return from the Matlab function in which to pass back the argument with the side effects. So, kudos to its author in being clever enough to incorporate it.

Sign in to comment.


dpb
dpb on 5 Jun 2021
Edited: dpb on 5 Jun 2021
OK, came back -- when indent code, the construct is more readily visible -- the two loops are completely independent and the first
DO 20 II=1,NB
IF(AK(II))10,20,10
10 IBL=II
GO TO 30
20 CONTINUE
IBL=NB
30 CONTINUE
is reducible to
DO 20 II=1,NB
IF AK(II) .NE. 0
IBL=II
GO TO 30
ENDIF
20 CONTINUE
IBL=NB
30 CONTINUE
...
which is equivalent to
DO II=1,NB
IF AK(II) .NE. 0
IBL=II
EXIT
ENDIF
ENDDO
IBL=MIN(IBL,NB)
...
which with the rest could then be turned into MATLAB syntax altho the above introductory snippet would more naturally be written in "the MATLAB way" as
ibl=find(AK,1); % get first nonzero location in AK
if isempty(ibl), ibl=nb; end % all zero array; use array upper bound
You'll have to decipher what the indexing in the second loop is doing but the above two lines replace everything down through the line
30 CONTINUE
so all you have to replace is the second loop construct.

kushal jana
kushal jana on 5 Jun 2021
Edited: dpb on 5 Jun 2021
SUBROUTINE SEARCH(AK,NB,IST,IEND,GSTIF)
IMPLICIT DOUBLE PRECISION(A-H,O-Z)
DIMENSION AK(4000),GSTIF(1000000)
DO 20 II=1,NB
IF(AK(II))10,20,10
10 IBL=II
GO TO 30
20 CONTINUE
IBL=NB
30 CONTINUE
ICOUNT=NB-IBL+1
IEND=IEND+ICOUNT
DO 40 II=IST,IEND
JJ=II-IST+IBL
GSTIF(II)=AK(JJ)
40 CONTINUE
IST=IST+ICOUNT
RETURN
END
can someone convert this fortran code
  2 Comments
dpb
dpb on 5 Jun 2021
While could figure out what(*) the completely undocumented/uncommented code is doing, I simply am not able to take the time to do that.
It would be far more likely somebody will respond if you'll describe the specific input/output the subroutine receives/returns -- it will be far simpler (and generate much more efficient code, besides) to write MATLAB code to perform the wanted calculations than to do a literal translation of the Fortran code as written.
(*) I did scan it and looked to see if it were trivial, but it'll take some effort to decipher this...
joker holy
joker holy on 14 Jul 2022
function [GSTIF]=SEARCH(AK,NB,IEND,IST)
% mod by qm,2022.7.14
% GSTIF=zeros(1000000);
for II=1:NB
if (AK(II)<0)||(AK(II)>0)
IBL=II;
else
IBL=NB;
end
end
ICOUNT=NB-IBL+1;
IEND=IEND+ICOUNT;
for II=IST:IEND
JJ=II-IST+IBL;
GSTIF(II)=AK(JJ);
end
IST=IST+ICOUNT;
return
end

Sign in to comment.

Categories

Find more on Fortran with MATLAB in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!