Search code examples
functionfortranwhere-clausesubroutine

Is there a way to make a function call within a where construct?


I would like to do something like:

Real a(10)
Real b(10)

! define a and b, then

where (a<b)
  a = f1(a,b)
elsewhere
  a = f2(a,b)
endwhere

function f1(a,b)
! somehow or another operates only where a < b
end function f1

function f2(a,b)
! somehow or another operates only where a>=b
end function f2

I guess I could do something like

a = f1(a,b)
a = f2(a,b)

function f1(a,b)
where (a<b) ...
end function f1

function f2(a,b)
where (a>=b) ...
end function f2

but I thought the way I am trying to puzzle out would be nice to have in some ways. Is there a way to do this?

In response to some comments, I want to operate on a by calling already defined functions that has too many lines of code to fit nicely here. I can't discuss the functions, but let's say, for instance that they rely on some kind of convergence loop:

function f1(a,b)

real a(10), b(10)
real f1(10)

real tmp(10), conv

real tol = 1.e-5
tmp = a
f1 = sin(b*a)
conv = max(abs(f1-tmp))

while (conv > tol)
  tmp = f1
  f1 = sin(b*tmp)
  conv = max(abs(f1-tmp))
endwhile

return

end function

And there are ways to improve this and the math might be such that it won't converge etc. etc., but this is an example that gets at what I am talking about. The thing is, I want it to operate only on the domain defined by the where construct. Thanks.


Solution

  • In the case where f1 and f2 are nonelemental functions these functions are evaluated based on all elements of the argument arrays.

    However, for an elemental function f1 or f2 only those elements of a and b matching a true mask will be processed (elementally).

    Looking at your example function, an elemental function wouldn't be suitable, so you'll have to use an alternative approach. If you can phrase the function with a where construct wrapping the whole thing, though, you may be in luck with elementals.