Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Transforming part of matlab code to Fortran90

  1. Jul 6, 2016 #1
    Here are my Fortran codes:
    Code (Text):

    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 (Text):

    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 (Text):

    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!
     
  2. jcsd
  3. Jul 7, 2016 #2

    Mark44

    Staff: Mentor

    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.
     
  4. Jul 7, 2016 #3
    I modified my code as follow:

    Code (Text):

    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, SS, 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
     
    but now the errors are:
    Code (Text):

    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!
     
  5. Jul 7, 2016 #4

    Mark44

    Staff: Mentor

    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:
    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.
     
  6. Jul 7, 2016 #5
    So thank you for your reply. Now I modified my code as:
    Code (Text):

    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, SS, 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 I get errors:
    Code (Text):

    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!
     
  7. Jul 7, 2016 #6

    Mark44

    Staff: Mentor

    Let's go with the first 5.
    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.
     
  8. Jul 7, 2016 #7
    Line 47:
    Code (Text):

    S1  = RSS / (n-2*(1:d))
     
    Line 48:
    Code (Text):

    F1  = (cumsum(transpose(SSs))/numViews) / (2*(1:d)*S1)
     
    Line 49:
    Code (Text):

    gMDL = log(S1) + 0.5*((1:d)/n)*log(F1)
     
    Line 52:
    Code (Text):

    array(cc-1+INDEX1(d+1:ubound(INDEX1))) = 0
     
    Line 53:
    Code (Text):

    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!!
     
  9. Jul 8, 2016 #8

    Mark44

    Staff: Mentor

    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.
    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.
    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.
    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
    Same as above (for line 52).
    As I said before,
    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.
     
  10. Jul 8, 2016 #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.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?
Draft saved Draft deleted



Similar Discussions: Transforming part of matlab code to Fortran90
Loading...