the goto fortran90 command convert to matlab
조회 수: 3 (최근 30일)
이전 댓글 표시
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
댓글 수: 0
채택된 답변
dpb
2014년 6월 11일
편집: dpb
2014년 6월 11일
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
dpb
2014년 6월 12일
편집: dpb
2014년 6월 12일
...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.
추가 답변 (4개)
Sara
2014년 6월 11일
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)
dpb
2014년 6월 12일
...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
dpb
2014년 6월 12일
편집: dpb
2014년 6월 13일
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.
dpb
2021년 6월 5일
편집: dpb
2021년 6월 5일
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.
댓글 수: 0
kushal jana
2021년 6월 5일
편집: dpb
2021년 6월 5일
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
dpb
2021년 6월 5일
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
2022년 7월 14일
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
참고 항목
카테고리
Help Center 및 File Exchange에서 Fortran with MATLAB에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!