Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Fortran goto to Matlab

Subject: Fortran goto to Matlab

From: Khalid

Date: 1 Sep, 2010 15:00:21

Message: 1 of 7

anyone can help me with converting the following Fortran subrotine to Matlab function please. I dont really know how to convert the GOTO function:

SUBROUTINE REZCORE(ZP, Z, TC, TPC, N, IDM, COUNT)
IMPLICIT NONE
INTEGER N, IDM, COUNT
REAL ZP(0:IDM+1), Z(0:IDM), TC(0:IDM), TPC(0:IDM+1)
INTEGER K, IH, IG, J
REAL S
K=0
IH=0
10 CONTINUE
K=K+1
IG=IH
20 CONTINUE
IF(IH .GE. N) GOTO 30
IF(ZP(IH+1) .GT. Z(K)) GOTO 30
IH=IH+1
GOTO 20
30 CONTINUE
IF(IH .NE. IG) GOTO 40
TC(K)=TPC(IH+1)
GOTO 90
40 CONTINUE
S=0.0
J=IG+2
50 CONTINUE
IF(J .GT. IH) GOTO 60
S=S+(ZP(J)-ZP(J-1))*TPC(J)
J=J+1
GOTO 50
60 CONTINUE
S=S+(ZP(IG+1)-Z(K-1))*TPC(IG+1)+(Z(K)-ZP(IH))*TPC(IH+1)
TC(K)=S/(Z(K)-Z(K-1))
90 CONTINUE
IF(K .LT. N) GOTO 10
RETURN
END

Subject: Fortran goto to Matlab

From: someone

Date: 1 Sep, 2010 16:20:21

Message: 2 of 7

"Khalid " <khabuman@hotmail.com> wrote in message <i5lpq5$f3$1@fred.mathworks.com>...
> anyone can help me with converting the following Fortran subrotine to Matlab function please. I dont really know how to convert the GOTO function:
>
> SUBROUTINE REZCORE(ZP, Z, TC, TPC, N, IDM, COUNT)
> IMPLICIT NONE
> INTEGER N, IDM, COUNT
> REAL ZP(0:IDM+1), Z(0:IDM), TC(0:IDM), TPC(0:IDM+1)
> INTEGER K, IH, IG, J
> REAL S
> K=0
> IH=0
> 10 CONTINUE
> K=K+1
> IG=IH
> 20 CONTINUE
> IF(IH .GE. N) GOTO 30
> IF(ZP(IH+1) .GT. Z(K)) GOTO 30
> IH=IH+1
> GOTO 20
> 30 CONTINUE
> IF(IH .NE. IG) GOTO 40
> TC(K)=TPC(IH+1)
> GOTO 90
> 40 CONTINUE
> S=0.0
> J=IG+2
> 50 CONTINUE
> IF(J .GT. IH) GOTO 60
> S=S+(ZP(J)-ZP(J-1))*TPC(J)
> J=J+1
> GOTO 50
> 60 CONTINUE
> S=S+(ZP(IG+1)-Z(K-1))*TPC(IG+1)+(Z(K)-ZP(IH))*TPC(IH+1)
> TC(K)=S/(Z(K)-Z(K-1))
> 90 CONTINUE
> IF(K .LT. N) GOTO 10
> RETURN
> END

The way to "convert the GOTO function" is to
restructure the subroutine to avoid using it.

You might be interested in this link:

http://blogs.mathworks.com/loren/2006/04/01/goto-coming-at-long-last-vectorized-no-less/

Note: the blog was posted on April 1

Subject: Fortran goto to Matlab

From: dpb

Date: 1 Sep, 2010 16:54:15

Message: 3 of 7

Khalid wrote:
> anyone can help me with converting the following Fortran subrotine to
> Matlab function please. I dont really know how to convert the GOTO
> function:
>
> SUBROUTINE REZCORE(ZP, Z, TC, TPC, N, IDM, COUNT)
> IMPLICIT NONE
> INTEGER N, IDM, COUNT
> REAL ZP(0:IDM+1), Z(0:IDM), TC(0:IDM), TPC(0:IDM+1)
> INTEGER K, IH, IG, J
> REAL S
> K=0
> IH=0
> 10 CONTINUE
> K=K+1
> IG=IH
> 20 CONTINUE
> IF(IH .GE. N) GOTO 30
> IF(ZP(IH+1) .GT. Z(K)) GOTO 30
> IH=IH+1
> GOTO 20
> 30 CONTINUE
> IF(IH .NE. IG) GOTO 40
> TC(K)=TPC(IH+1)
> GOTO 90
> 40 CONTINUE
> S=0.0
> J=IG+2
> 50 CONTINUE
> IF(J .GT. IH) GOTO 60
> S=S+(ZP(J)-ZP(J-1))*TPC(J)
> J=J+1
> GOTO 50
> 60 CONTINUE
> S=S+(ZP(IG+1)-Z(K-1))*TPC(IG+1)+(Z(K)-ZP(IH))*TPC(IH+1)
> TC(K)=S/(Z(K)-Z(K-1))
> 90 CONTINUE
> IF(K .LT. N) GOTO 10
> RETURN
> END

As another poster said, in Matlab you'll need to restructure the code to
eliminate the GOTOs. Starting from the outside in, the overall thing is
a loop while K<N where N is a dummy argument and doesn't appear in a
quick perusal to be modified in the routine. So, I'd start w/ something
like

...
c 10 CONTINUE
loop_10: do while(K<N)
   K=K+1
   IG=IH
   ...
   TC(K)=S/(Z(K)-Z(K-1))
   90 CONTINUE
c IF(K .LT. N) GOTO 10
end do loop_10

Then, the other GOTOs such as the section

50 CONTINUE
    IF(J .GT. IH) GOTO 60
    S=S+(ZP(J)-ZP(J-1))*TPC(J)
    J=J+1
    GOTO 50
60 CONTINUE

is equivalent to

loop_50: do while(J<=IH)
    S=S+(ZP(J)-ZP(J-1))*TPC(J)
    J=J+1
end do loop_50

Repeat the above kind of translation 'til done...

Note the GOTO 90 _may_ be equivalent to CYCLE at that point altho I
didn't read the code carefully enough to be absolutely certain I point
it out to raise the possibility to get the existence of the other
construct possibilities besides simply DO WHILE may be useful/needed.

Or, of course, you'll want to make a clean copy of the routine for
archival purposes before you begin munging on it. If you have a Fortran
compiler installed it would probably be easiest to modify and test there
then translate a working routine to Matlab syntax.

The alternative would also be to simply mex the routine as it stands
although this is small enough and doesn't seem complex enough to be a
big hassle.

--

Subject: Fortran goto to Matlab

From: Miroslav Balda

Date: 1 Sep, 2010 17:26:19

Message: 4 of 7

"Khalid " <khabuman@hotmail.com> wrote in message <i5lpq5$f3$1@fred.mathworks.com>...
> anyone can help me with converting the following Fortran subrotine to Matlab function please. I dont really know how to convert the GOTO function:

SNIP

The FORTRAN >>statement<< GO TO is not a >>function<<. Matlab does not need its equivalent, because it has powerfull commands for structured programming, which make the application of goto statement useless. Since it is seen that you do not know the basic Matlab commands, you may lern them from the following conversion of your function (I do not guarantee that it works):

%function rezcore(zp,z,tc,tpc,N,idm,count)
function rezcore(zp,z,tc,tpc,n) % idm and count are not used
% REZCORE function description
%
% HELP LINES

k = 0;
ih = 0;
                            % 10
while 1
    k = k+1;
    ig = ih;
                            % 20
    while ih<n && zp(ih+1)<=z(k)
        ih = ih+1;
    end
                            % 30
    if ih==ig
        tc(k) = tpc(ih+1);
    else % 40
        s = 0;
        j = ig+2;
                            % 50
        while j<=ih
            s = s + (zp(ig+1)-zp(j-1))*tcp(j);
            j = j+1;
        end
                            % 60
        s = s + (zp(ig+1)-z(k-1))*tcp(ig+1) + (z(k)-zp(ih))*tcp(ih+1);
        tc(k) = s/(z(k)-z(k-1));
                            % 90
        if (k>=n), break, end
    end % if
end % while

I hope that it could help you and maybe others to switch from Fortran to Matlab.

Best regards,

Mira

Subject: Fortran goto to Matlab

From: Ben Barrowes

Date: 10 Jun, 2013 13:18:10

Message: 5 of 7

"Khalid " <khabuman@hotmail.com> wrote in message <i5lpq5$f3$1@fred.mathworks.com>...
> anyone can help me with converting the following Fortran subrotine to Matlab function please. I dont really know how to convert the GOTO function:
>
> SUBROUTINE REZCORE(ZP, Z, TC, TPC, N, IDM, COUNT)
> IMPLICIT NONE
> INTEGER N, IDM, COUNT
> REAL ZP(0:IDM+1), Z(0:IDM), TC(0:IDM), TPC(0:IDM+1)
> INTEGER K, IH, IG, J
> REAL S
> K=0
> IH=0
> 10 CONTINUE
> K=K+1
> IG=IH
> 20 CONTINUE
> IF(IH .GE. N) GOTO 30
> IF(ZP(IH+1) .GT. Z(K)) GOTO 30
> IH=IH+1
> GOTO 20
> 30 CONTINUE
> IF(IH .NE. IG) GOTO 40
> TC(K)=TPC(IH+1)
> GOTO 90
> 40 CONTINUE
> S=0.0
> J=IG+2
> 50 CONTINUE
> IF(J .GT. IH) GOTO 60
> S=S+(ZP(J)-ZP(J-1))*TPC(J)
> J=J+1
> GOTO 50
> 60 CONTINUE
> S=S+(ZP(IG+1)-Z(K-1))*TPC(IG+1)+(Z(K)-ZP(IH))*TPC(IH+1)
> TC(K)=S/(Z(K)-Z(K-1))
> 90 CONTINUE
> IF(K .LT. N) GOTO 10
> RETURN
> END



Khalid,

For the following, I used polyhedron's spag (free linux version), my f2matlab (published at the file exchange), and my own as yet unpublished goto remover which refactors all remaining goto's that spag could not.

Here is your fortran refactored to have no goto's:


SUBROUTINE REZCORE(ZP, Z, TC, TPC, N, IDM, COUNT)
IMPLICIT NONE
logical :: remg(3)=.true.
INTEGER , INTENT(IN) :: N
INTEGER , INTENT(IN) :: IDM
INTEGER :: COUNT
REAL , INTENT(IN) :: ZP(0:IDM + 1)
REAL , INTENT(IN) :: Z(0:IDM)
REAL , INTENT(OUT) :: TC(0:IDM)
REAL , INTENT(IN) :: TPC(0:IDM + 1)
INTEGER :: J1, K, IH, IG, J
REAL :: S
do
 if (remg(3)) then
  if (remg(2)) then
   if (remg(1)) then
    K = 0
    IH = 0
   endif
   remg(1)=.true.
10 K = K + 1
   IG = IH
  endif
  remg(2)=.true.
20 IF (IH >= N) then
   remg(3)=.false.;cycle
  endif
  IF (ZP(IH+1) > Z(K)) then
   remg(3)=.false.;cycle
  endif
  IH = IH + 1
  remg(2)=.false.;cycle
 endif
 remg(3)=.true.
30 IF (IH == IG) THEN
  TC(K) = TPC(IH+1)
 ELSE
  S = 0.0
  J = IG + 2
  J1 = J
  IF (IH - J1 + 1 > 0) THEN
   S = S + DOT_PRODUCT(ZP(J1:IH)-ZP(J1-1:IH-1),TPC(J1:IH))
  ENDIF
  S = S + (ZP(IG+1)-Z(K-1))*TPC(IG+1) + (Z(K)-ZP(IH))*TPC(IH+1)
  TC(K) = S/(Z(K)-Z(K-1))
 ENDIF
90 IF (K < N) then
  remg(1)=.false.;cycle
 endif
 exit
enddo
RETURN
END SUBROUTINE REZCORE


And here is the matlab conversion (untested) of this f90 code:



function [zp, z, tc, tpc, n, idm, count_ml]=rezcore(zp, z, tc, tpc, n, idm, count_ml);

persistent ig ih j j1 k remg s ;

if isempty(remg), remg([1:3])=true; end;
if isempty(j1), j1=0; end;
if isempty(k), k=0; end;
if isempty(ih), ih=0; end;
if isempty(ig), ig=0; end;
if isempty(j), j=0; end;
if isempty(s), s=0; end;
while (1);
 if(remg(3))
  if(remg(2))
   if(remg(1))
    k = 0;
    ih = 0;
   end;
   remg(1)=true;
   k = fix(k + 1);
   ig = fix(ih);
  end;
  remg(2)=true;
  if(ih >= n)
   remg(3)=false;
   continue;
  end;
  if(zp(ih+1+1) > z(k+1))
   remg(3)=false;
   continue;
  end;
  ih = fix(ih + 1);
  remg(2)=false;
  continue;
 end;
 remg(3)=true;
 if(ih == ig)
  tc(k+1) = tpc(ih+1+1);
 else;
  s = 0.0;
  j = fix(ig + 2);
  j1 = fix(j);
  if(ih - j1 + 1 > 0)
   s = s + dot(zp([j1:ih]+1)-zp([j1-1:ih-1]+1),tpc([j1:ih]+1));
  end;
  s = s +(zp(ig+1+1)-z(k-1+1)).*tpc(ig+1+1) +(z(k+1)-zp(ih+1)).*tpc(ih+1+1);
  tc(k+1) = s./(z(k+1)-z(k-1+1));
 end;
 if(k < n)
  remg(1)=false;
  continue;
 end;
 break;
end;
return;
end %subroutine rezcore

Subject: Fortran goto to Matlab

From: dpb

Date: 10 Jun, 2013 17:19:43

Message: 6 of 7

On 6/10/2013 8:18 AM, Ben Barrowes wrote:
> "Khalid " <khabuman@hotmail.com> wrote in message
> <i5lpq5$f3$1@fred.mathworks.com>...
>> anyone can help me with converting the following Fortran subrotine to
>> Matlab function please. I dont really know how to convert the GOTO
>> function:
>>
...[intro code elided for brevity]...

>> K=0
>> IH=0
>> 10 CONTINUE
>> K=K+1
>> IG=IH
>> 20 CONTINUE
>> IF(IH .GE. N) GOTO 30
>> IF(ZP(IH+1) .GT. Z(K)) GOTO 30
>> IH=IH+1
>> GOTO 20
>> 30 CONTINUE

...[elided for to concentrate on just a first section as example]...

>
> For the following, I used polyhedron's spag (free linux version), my
> f2matlab (published at the file exchange), and my own as yet unpublished
> goto remover which refactors all remaining goto's that spag could not.
>
> Here is your fortran refactored to have no goto's:
>
>
...

> do
> if (remg(3)) then
> if (remg(2)) then
> if (remg(1)) then
> K = 0
> IH = 0
> endif
> remg(1)=.true.
> 10 K = K + 1
> IG = IH
> endif
> remg(2)=.true.
> 20 IF (IH >= N) then
> remg(3)=.false.;cycle
> endif
> IF (ZP(IH+1) > Z(K)) then
> remg(3)=.false.;cycle
> endif
> IH = IH + 1
> remg(2)=.false.;cycle
> endif
> remg(3)=.true.
> 30 ...

>
> And here is the matlab conversion (untested) of this f90 code:
....

Which is a transliteration of the above. While it probably works and is
easier than by hand (assuming there aren't bugs in the toolset) do you
really want to try to use/maintain such a piece of code?

OTOH, if one looks at the code and interprets it, it's not _that_
difficult albeit it takes some time...the snippet above

  20 CONTINUE
     IF(IH .GE. N) GOTO 30
     IF(ZP(IH+1) .GT. Z(K)) GOTO 30
     IH=IH+1
     GOTO 20
  30 CONTINUE

Is equivalent to

    do while(IH<N)
     IF(ZP(IH+1) .GT. Z(K)) GOTO 30
     IH=IH+1
    enddo
  30 CONTINUE

which then is the same as

    do while(IH<N)
      IF(ZP(IH+1)<=Z(K)) THEN
        IH=IH+1
      ENDIF
    enddo

which can be seen to also be same as

    do while(IH<N .and. ZP(IH+1)<=Z(K))
      IH=IH+1
    enddo

In the end in Matlab this is simply

ih=find(ZP>Z,1,'first');
if isempty(ih), ih=N; end

Isn't that a whole lot easier to maintain/understand?

I'm not criticising Bob; the alternative is the inevitable result of a
machine translation is going to look like but unless there's an
overriding reason I'd suggest either

a) using the Fortran subroutine as is w/ a mex-file interface from
Matlab, or

b) actually translating the code by following its logic, or

c) implementing the desired functionality from the base
definition/functional requirements.

--

Subject: Fortran goto to Matlab

From: dpb

Date: 11 Jun, 2013 00:18:33

Message: 7 of 7

On 6/10/2013 12:19 PM, dpb wrote:
...

> do while(IH<N .and. ZP(IH+1)<=Z(K))
> IH=IH+1
> enddo
>
> In the end in Matlab this is simply
>
> ih=find(ZP>Z,1,'first');
> if isempty(ih), ih=N; end
>
> Isn't that a whole lot easier to maintain/understand?
>
...

Actually, I misspeak above, the ML version would be

ih=find(ZP<Z,1,'last');
if isempty(ih), ih=N; end

My cleaned up version of the routine is

SUBROUTINE REZCORE(ZP, Z, TC, TPC, N, IDM, COUNT)
   IMPLICIT NONE
   INTEGER N, IDM, COUNT
   REAL ZP(0:IDM+1), Z(0:IDM), TC(0:IDM), TPC(0:IDM+1)
   INTEGER K, IH, IG, J
   REAL S

   K=0
   IH=0
   do while(K<N)
     K=K+1
     IG=IH
     do while(IH<N .and. ZP(IH+1)<=Z(K))
      IH=IH+1
     enddo
     if(IH==IG) then
       TC(K)=TPC(IH+1)
     else
       S=0.0
       J=IG+2
       do while(J<=IH)
         S=S+(ZP(J)-ZP(J-1))*TPC(J)
         J=J+1
       enddo
       S=S+(ZP(IG+1)-Z(K-1))*TPC(IG+1)+(Z(K)-ZP(IH))*TPC(IH+1)
       TC(K)=S/(Z(K)-Z(K-1))
     endif
   enddo
   RETURN
END

Looks otomh that an accumarray() may be in order in Matlab...

--

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us