Interface mismatch in dummy procedure 'f' when passing function to subroutine

I am trying to write a subroutine (to minimize) that has two arguments:

  • array of xany length
  • function fthat takes an array of this length and returns a scalar

module example:

module foo

contains

  subroutine solve(x, f)
    real, dimension(:), intent(inout) :: x
    interface
      real pure function f(y)
        import x
        real, dimension(size(x)), intent(in) :: y
      end function
    end interface

    print *, x
    print *, f(x)
  end subroutine

end module

and test program:

use foo

real, dimension(2) :: x = [1.0, 2.0]

call solve(x, g)

contains

  real pure function g(y)
    real, dimension(2), intent(in) :: y

    g = sum(y)
  end function

end

gfortran does not work:

call solve(x, g)
              1
Error: Interface mismatch in dummy procedure 'f' at (1): Shape mismatch in dimension 1 of argument 'y'

If I change size(x) => 2, then it compiles (and works) perfectly. It also works great if I change : => 2. But none of these solutions give me what I want.

Any ideas on how I can achieve this?

+2
source share
4 answers

What about:

interface
  real pure function f(y)
    real, dimension(:), intent(in) :: y
  end function
end interface

solve , . .

+5

, MSB, -fcheck=bounds, . -fcheck . gfortran. .

+2

, ... ( ), , , , , . , , .

, . - " [] ".

f SIZE(x). x - - , SIZE(x) . , .

g 2. .

f (- vs ) - , .

SIZE(x) 2 . x 2, SIZE(x) 2 - , , , - , , . f, g, shape (:), .

+1

, .

:

  • , .
  • Add additional information about the size of the matrix when passing the array to a valid function. For example f(y, sizeinfo), so that inside your actual function you can correctly declare the size of the input matrix. The allocated array can be passed to the subroutine solve, so the size can be obtained using the size (mat) in your subroutine solve.

So, the corrected version looks like this:

module foo

contains

  subroutine solve(x, f)
    real, dimension(:), intent(inout) :: x
    real,external::f
        integer::sizeinfo

    print *,'x=', x
    sizeinfo = size(x)
    print *, 'f(x)=',f(x,sizeinfo)
  end subroutine

    real function g(y,sizeinfo)
    integer::sizeinfo
    real, dimension(sizeinfo) :: y

    g = sum(y)
  end function
end module

Here is the main program:

program main
use foo

real, dimension(2) :: x = (/1.0, 2.0/)

call solve(x, g)

end program

And the result:

x=   1.000000       2.000000    
f(x)=   3.000000 
0
source

Source: https://habr.com/ru/post/1609203/


All Articles