MATLAB Transforming part of matlab code to Fortran90

AI Thread Summary
The discussion revolves around the challenges of converting MATLAB code into Fortran90, highlighting specific errors encountered during the process. Key issues include the incorrect use of MATLAB functions like `cumsum`, `ubound`, and array indexing, which do not have direct equivalents in Fortran. Participants emphasize the need to understand the MATLAB code thoroughly before attempting the conversion, as many built-in functions in MATLAB require custom implementations in Fortran. The errors reported primarily stem from syntax issues and the misuse of functions that are not defined in Fortran, necessitating a careful review and adjustment of the code. Overall, a deeper comprehension of both languages and their functionalities is crucial for a successful transformation.
i_a_n
Messages
78
Reaction score
0
Here are my Fortran codes:
Code:
program test
implicitnone

integer*4 nxProjPad, cf, numViews, cc, index, indRad, iv, i, INDEX1, d, n
real*4 v4, v5, RSS, S1, F1, gMDL
real*4, dimension(:), allocatable :: array, sum, cumsum, transpose, log, SS1, SSs

nxProjPad=185
numViews=180
allocate(array(numViews*nxProjPad))
v4 = 0.
v5 = 0.
SS = 0.
cc = 5.
indRad = 1
index = 1
cf = NINT(nxProjPad/2.)
do  iv = 1, numViews
do i = 1, nxProjPad
v4 = v4 + array(index)
v5 = v5 + array(indRad)
SS = SS + (array(index))**2
indRad = indRad + 1
index = index + 1
enddo
enddo
SS1 = SS(1:cf-cc)
SS1 = SS1 + SS(ubound(SS1):cf+cc)

CALL KB08AD( SS1, nxProjPad, INDEX1 )

SSs = SS1

d = size(SSs)

n = nxProjPad

RSS = (sum(SSs(1:ubound(SSs)))-cumsum(transpose(SSs))))/numViews

S1  = RSS / (n-2*(1:d))

F1  = (cumsum(transpose(SSs))/numViews) / (2*(1:d)*S1)

gMDL = log(S1) + 0.5*((1:d)/n)*log(F1)do  iv = 1, numViews

array(cc-1+INDEX1(d+1:ubound(INDEX1))) = 0

array(size(C, 1)-cc-INDEX1(d+1:ubound(INDEX1))) = 0

enddo

deallocate(array)

endprogram test
And it is transformed from this short MATLAB code:

Code:
cf = round(size(C, 1)/2);
SS = sum(abs(C).^2, 2);

cc  = 5;
SS1 = SS(1:cf-cc);
SS1 = SS1 + SS(end:-1:cf+cc);

[SSs,id] = sort(SS1, 'descend');

d       = length(SSs);
n       = size(y, 1);

RSS = (sum(SSs) - cumsum(SSs'))/length(theta);
S1  = RSS ./ (n-2*(1:d));
F1  = (cumsum(SSs')/length(theta)) ./ (2*(1:d).*S1);
gMDL = log(S1) + 0.5*((1:d)/n).*log(F1);
[~, d] = min(gMDL(1:round(d/2)));

C1(cc-1+id(d+1:end), :) = 0;
C1(size(C, 1)-cc-id(d+1:end), :) = 0;
The errors I got are:

Code:
test.f90:37:0: SS1 = SS(1:cf-cc)

 1

Error: Unclassifiable statement at (1)

test.f90:38:0: SS1 = SS1 + SS(ubound(SS1):cf+cc)

 1

Error: Unclassifiable statement at (1)

test.f90:46:0: RSS = (sum(SSs(1:ubound(SSs)))-cumsum(transpose(SSs))))/numViews

 1

Error: Unclassifiable statement at (1)

test.f90:47:19: Error: Expected a right parenthesis in expression at (1)

test.f90:48:47: Error: Expected a right parenthesis in expression at (1)

test.f90:49:24: Error: Expected a right parenthesis in expression at (1)

test.f90:52:21: Error: Syntax error in argument list at (1)

test.f90:53:30: Error: Syntax error in argument list at (1)

test.f90:16:2: SS = 0.

  1

Error: Symbol ‘ss’ at (1) has no IMPLICIT type
I think you can notice which parts I am trying to transform. So how should I make my Fortran code correct and the same functionality as in matlab?

Any corrections are welcome!
 
Physics news on Phys.org
i_a_n said:
Fortran:
implicitnone

 <snip>
real*4, dimension(:), allocatable :: array, sum, cumsum, transpose, log, SS1, SSs

<snip>
 SS = 0.
< snip>
SS = SS + (array(index))**2
You declared variables names SS1 and SSs, but your code uses a variable named SS, which is not declared. That's the cause of your first error.

The second error is caused in part by your use of cumsum(), which is available in matlab, but as far as I know, not available as an intrinsic function in Fortran of any kind. You won't be able to use some of the functions that are being used in the MATLAB code -- instead you'll have to figure out what they're doing and write functions in Fortran to duplicate that behavior.
 
Mark44 said:
You declared variables names SS1 and SSs, but your code uses a variable named SS, which is not declared. That's the cause of your first error.

The second error is caused in part by your use of cumsum(), which is available in matlab, but as far as I know, not available as an intrinsic function in Fortran of any kind. You won't be able to use some of the functions that are being used in the MATLAB code -- instead you'll have to figure out what they're doing and write functions in Fortran to duplicate that behavior.
I modified my code as follow:

Code:
program test

implicitnoneinteger*4 nxProjPad, cf, numViews, cc, index, indRad, iv, i, INDEX1, d, n

real*4 v4, v5, RSS, S1, F1, gMDLreal*4, dimension(:), allocatable :: array, sum, cumsum, transpose, log, SS, SS1, SSsnxProjPad=185

numViews=180allocate(array(numViews*nxProjPad))v4 = 0.

v5 = 0.

SS = 0.

cc = 5.indRad = 1

index = 1cf = NINT(nxProjPad/2.)do  iv = 1, numViews

do i = 1, nxProjPad

v4 = v4 + array(index)v5 = v5 + array(indRad)

SS = SS + (array(index))**2indRad = indRad + 1index = index + 1

enddo

enddoSS1 = SS(1:cf-cc)

SS1 = SS1 + SS(ubound(SS1):cf+cc)CALL KB08AD( SS1, nxProjPad, INDEX1 )SSs = SS1

d = size(SSs)

n = nxProjPadRSS = (sum(SSs(1:ubound(SSs)))-cumsum(transpose(SSs)))/numViews

S1  = RSS / (n-2*(1:d))

F1  = (cumsum(transpose(SSs))/numViews) / (2*(1:d)*S1)

gMDL = log(S1) + 0.5*((1:d)/n)*log(F1)do  iv = 1, numViews

array(cc-1+INDEX1(d+1:ubound(INDEX1))) = 0

array(size(C, 1)-cc-INDEX1(d+1:ubound(INDEX1))) = 0

enddodeallocate(array)

endprogram test

but now the errors are:
Code:
test.f90:47:19: Error: Expected a right parenthesis in expression at (1)

test.f90:48:47: Error: Expected a right parenthesis in expression at (1)

test.f90:49:24: Error: Expected a right parenthesis in expression at (1)

test.f90:52:21: Error: Syntax error in argument list at (1)

test.f90:53:30: Error: Syntax error in argument list at (1)

test.f90:38:15: SS1 = SS1 + SS(ubound(SS1):cf+cc)

              1

Error: Array index at (1) must be scalar

test.f90:46:48: RSS = (sum(SSs(1:ubound(SSs)))-cumsum(transpose(SSs)))/numViews

                                                1

Warning: Legacy Extension: REAL array index at (1)

test.f90:46:38: RSS = (sum(SSs(1:ubound(SSs)))-cumsum(transpose(SSs)))/numViews

                                      1

Warning: Legacy Extension: REAL array index at (1)

test.f90:46:17: RSS = (sum(SSs(1:ubound(SSs)))-cumsum(transpose(SSs)))/numViews

                1

Error: Array index at (1) must be scalar

and I also think that we have a cumsum function in Fortran 90.

Thank you!
 
The code you have in post #3 is a very long way from doing what you want it to do. Before you attempt to transform the MATLAB code into its Fortran equivalent, you absolutely need to understand the MATLAB code. And by that, I mean you need to understand what every line of the code is doing. Here is from your first post:
i_a_n said:
Matlab:
cf = round(size(C, 1)/2);
SS = sum(abs(C).^2, 2);

cc  = 5;
SS1 = SS(1:cf-cc);
SS1 = SS1 + SS(end:-1:cf+cc);

[SSs,id] = sort(SS1, 'descend');

d       = length(SSs);
n       = size(y, 1);

RSS = (sum(SSs) - cumsum(SSs'))/length(theta);
S1  = RSS ./ (n-2*(1:d));
F1  = (cumsum(SSs')/length(theta)) ./ (2*(1:d).*S1);
gMDL = log(S1) + 0.5*((1:d)/n).*log(F1);
[~, d] = min(gMDL(1:round(d/2)));

C1(cc-1+id(d+1:end), :) = 0;
C1(size(C, 1)-cc-id(d+1:end), :) = 0;
In your code you declare sum, cumsum, transpost, and log as arrays. In the MATLAB code, these are NOT arrays -- they are functions built into matlab.

In addition to these functions, the MATLAB code uses several other functions, among then round(), size(), abs(), sort(), length(), min(), id(). In several places end is used as a function, and the transpose operator - ' - is used.

Again, your focus should be on understanding what the MATLAB code is doing, some of which seems to be missing. For example, Is C an array? Where does it get its values? Where does y get its values? Same question for theta.
 
So thank you for your reply. Now I modified my code as:
Code:
program test

implicitnoneinteger*4 nxProjPad, cf, numViews, cc, index, indRad, iv, i, INDEX1, d, n

real*4 v4, v5, RSS, S1, F1, gMDLreal*4, dimension(:), allocatable :: array, SS, SS1, SSsnxProjPad=185

numViews=180allocate(array(numViews*nxProjPad))v4 = 0.

v5 = 0.

SS = 0.

cc = 5.indRad = 1

index = 1cf = NINT(nxProjPad/2.)do  iv = 1, numViews

do i = 1, nxProjPad

v4 = v4 + array(index)v5 = v5 + array(indRad)

SS = SS + (array(index))**2indRad = indRad + 1index = index + 1

enddo

enddoSS1 = SS(1:cf-cc)

SS1 = SS1 + SS(ubound(SS1):cf+cc)CALL KB08AD( SS1, nxProjPad, INDEX1 )SSs = SS1

d = size(SSs)

n = nxProjPadRSS = (sum(SSs(1:ubound(SSs)))-cumsum(transpose(SSs)))/numViews

S1  = RSS / (n-2*(1:d))

F1  = (cumsum(transpose(SSs))/numViews) / (2*(1:d)*S1)

gMDL = log(S1) + 0.5*((1:d)/n)*log(F1)do  iv = 1, numViews

array(cc-1+INDEX1(d+1:ubound(INDEX1))) = 0

array(size(C, 1)-cc-INDEX1(d+1:ubound(INDEX1))) = 0

enddodeallocate(array)

endprogram test

And I get errors:
Code:
test.f90:47:19: Error: Expected a right parenthesis in expression at (1)

test.f90:48:47: Error: Expected a right parenthesis in expression at (1)

test.f90:49:24: Error: Expected a right parenthesis in expression at (1)

test.f90:52:21: Error: Syntax error in argument list at (1)

test.f90:53:30: Error: Syntax error in argument list at (1)

test.f90:38:15: SS1 = SS1 + SS(ubound(SS1):cf+cc)

              1

Error: Array index at (1) must be scalar

test.f90:46:48: RSS = (sum(SSs(1:ubound(SSs)))-cumsum(transpose(SSs)))/numViews

                                                1

Error: ‘matrix’ argument of ‘transpose’ intrinsic at (1) must be of rank 2

Can you explain what each error means and what I should do? Let's start from the first one: why "Expected a right parenthesis in expression"?

Thank you very much!
 
i_a_n said:
Can you explain what each error means and what I should do? Let's start from the first one: why "Expected a right parenthesis in expression"?
Let's go with the first 5.
test.f90:47:19: Error: Expected a right parenthesis in expression at (1)

test.f90:48:47: Error: Expected a right parenthesis in expression at (1)

test.f90:49:24: Error: Expected a right parenthesis in expression at (1)

test.f90:52:21: Error: Syntax error in argument list at (1)

test.f90:53:30: Error: Syntax error in argument list at (1)
test.f90 is the source code you are writing. The number after the colon (:) is the line where the error is encountered. In your editor, turn on line numbers (or manually count lines. The first three errors, on lines 47, 48, and 49, should be statements that involve parentheses. If you can identify these lines, I might be able to help you figure out what's wrong.

Similar idea with the next two errors.
 
Line 47:
Code:
S1  = RSS / (n-2*(1:d))
Line 48:
Code:
F1  = (cumsum(transpose(SSs))/numViews) / (2*(1:d)*S1)
Line 49:
Code:
gMDL = log(S1) + 0.5*((1:d)/n)*log(F1)
Line 52:
Code:
array(cc-1+INDEX1(d+1:ubound(INDEX1))) = 0
Line 53:
Code:
array(size(C, 1)-cc-INDEX1(d+1:ubound(INDEX1))) = 0

But I don't see a seemingly error with the use of parenthesis.
Thank you very much!
 
i_a_n said:
Line 47:
Code:
S1  = RSS / (n-2*(1:d))
Above -- you can't do this. You need to assign values to the S1 array one by one. See this link for examples. In particular, the 1:d business is MATLAB syntax, not Fortran. You have this syntax in several of the lines below.
i_a_n said:
Line 48:
Code:
F1  = (cumsum(transpose(SSs))/numViews) / (2*(1:d)*S1)
Same as above, but in addition, cumsum() and transpose() are functions in matlab, not in fortran. As I said before, you need to look at the MATLAB documentation for these functions, and figure out how to implement them in Fortran. Please reread what I said in post #4.
i_a_n said:
Line 49:
Code:
gMDL = log(S1) + 0.5*((1:d)/n)*log(F1)
Same comment as for line 47. In addition, you can't take the log of an entire array, but you can take the log of one element of an array.
i_a_n said:
Line 52:
Code:
array(cc-1+INDEX1(d+1:ubound(INDEX1))) = 0
ubound() is a MATLAB function, not a Fortran function. In addition, the index of an array has to be an integer. It's possible that what's in the outermost pair of parentheses is not an integer
i_a_n said:
Line 53:
Code:
array(size(C, 1)-cc-INDEX1(d+1:ubound(INDEX1))) = 0
Same as above (for line 52).
i_a_n said:
But I don't see a seemingly error with the use of parenthesis.
Thank you very much!
As I said before,
Again, your focus should be on understanding what the MATLAB code is doing.
That means that you need to look at the documentation for the built-in functions the MATLAB code is using, and see if these functions have Fortran counterparts (most don't). For the MATLAB functions with no Fortran counterparts, you need to write Fortran code to implement them.
 
I understand this MATLAB code EXACTLY. What I am stuck with is just how to transform it to Fortran. I may read more tutorials (btw, ubound is not a MATLAB function)

Thanks anyway.
 
Back
Top