Transforming part of matlab code to Fortran90

In summary: MATLAB code is doing and then write your code in Fortran. If you are having trouble understanding what the MATLAB code is doing, you should ask questions about that on a MATLAB forum. This forum is for Fortran programming questions.
  • #1
i_a_n
83
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
  • #2
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.
 
  • #3
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!
 
  • #4
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.
 
  • #5
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!
 
  • #6
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.
 
  • #7
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!
 
  • #8
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.
 
  • #9
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.
 

1. What is the purpose of transforming part of Matlab code to Fortran90?

The purpose of transforming part of Matlab code to Fortran90 is to take advantage of the faster execution speed and better memory management of Fortran90. This can be particularly useful for scientific computing applications that require high performance and efficient use of resources.

2. Can all Matlab code be easily transformed to Fortran90?

No, not all Matlab code can be easily transformed to Fortran90. While both languages are used for scientific computing, they have different syntax and features, so some code may need to be rewritten or modified in order to be translated accurately.

3. Are there any advantages to using Matlab over Fortran90?

Yes, there are some advantages to using Matlab over Fortran90. Matlab has a user-friendly interface and built-in functions for data analysis and visualization, making it easier to use for non-experts. It also has a larger library of functions and toolboxes for various applications.

4. Is there a specific process for transforming Matlab code to Fortran90?

Yes, there is a process for transforming Matlab code to Fortran90. It involves first understanding the differences between the two languages and then rewriting or modifying the code in Fortran90 syntax. It may also involve using specific tools or libraries for translating the code accurately.

5. Are there any potential challenges or limitations when transforming Matlab code to Fortran90?

Yes, there can be potential challenges or limitations when transforming Matlab code to Fortran90. Some code may not translate accurately or efficiently, and there may be differences in how certain operations or data structures are handled in the two languages. It is important to thoroughly test the translated code to ensure its accuracy and performance.

Back
Top