[comp.lang.fortran] MAX function, but carry sign

rfinch@caldwr.water.ca.gov (Ralph Finch) (04/11/91)

I wish to use the max function on absolute values, but carry the sign
of the original values. That is:

a=max(abs(a1),abs(a2)) ! but a has sign of either a1 or a2

I'm doing this with an IF statement now but wonder if there isn't some
combination of max and sign that will give the same result without an
IF statement.
-- 
Ralph Finch			916-445-0088
rfinch@water.ca.gov		...ucbvax!ucdavis!caldwr!rfinch
Any opinions expressed are my own; they do not represent the DWR

dodson@convex.COM (Dave Dodson) (04/12/91)

In article <282@venice.water.ca.gov> rfinch@caldwr.water.ca.gov (Ralph Finch) writes:
>
>I wish to use the max function on absolute values, but carry the sign
>of the original values. That is:
>
>a=max(abs(a1),abs(a2)) ! but a has sign of either a1 or a2
>
>I'm doing this with an IF statement now but wonder if there isn't some
>combination of max and sign that will give the same result without an
>IF statement.

Try the following:

a=sign(max(abs(a1),abs(a2)),(1+sign(1,abs(a1)-abs(a2)))*a1+(1-sign(1,abs(a1)-abs(a2)))*a2)

It even makes the IF statement look good, doesn't it?

----------------------------------------------------------------------

Dave Dodson		                             dodson@convex.COM
Convex Computer Corporation      Richardson, Texas      (214) 497-4234

jrbd@craycos.com (James Davies) (04/12/91)

In article <282@venice.water.ca.gov> rfinch@caldwr.water.ca.gov (Ralph Finch) writes:
>
>I wish to use the max function on absolute values, but carry the sign
>of the original values. That is:
>
>a=max(abs(a1),abs(a2)) ! but a has sign of either a1 or a2
>
>I'm doing this with an IF statement now but wonder if there isn't some
>combination of max and sign that will give the same result without an
>IF statement.

If you want the result to carry the sign of the maximum value 
(which is the most likely case), then you could use the sign of the sum
of the two, i.e.

	a = sign(max(abs(a1),abs(a2)), a1+a2)

This will give you the positive value if they are the same, but the sign
of the larger absolute value if they are different.

pmontgom@euphemia.math.ucla.edu (Peter Montgomery) (04/13/91)

In article <1991Apr12.151728.12916@craycos.com> jrbd@craycos.com (James Davies) writes:
>In article <282@venice.water.ca.gov> rfinch@caldwr.water.ca.gov (Ralph Finch) writes:

>>I wish to use the max function on absolute values, but carry the sign
>>of the original values. That is:

>>a=max(abs(a1),abs(a2)) ! but a has sign of either a1 or a2

>If you want the result to carry the sign of the maximum value 
>(which is the most likely case), then you could use the sign of the sum
>of the two, i.e.

>	a = sign(max(abs(a1),abs(a2)), a1+a2)

>This will give you the positive value if they are the same, but the sign
>of the larger absolute value if they are different.

	Another way uses the Fortran Extended MERGE function, which
adds a much-needed conditional expression construct to Fortran.  As I recall, 
MERGE(x, y, bool) returns x if bool is TRUE, y if bool is FALSE.  Then

	a = MERGE(a1, a2, ABS(a1).ge.ABS(a2)) .

This makes it obvious to a reader that a = a1 or a = a2.
Depending upon your system, it may be preferable to replace the last
test by the mathematically equivalent  a1**2 .ge. a2**2  
(assuming no overflow/underflow will occur) or by  (a1+a2)*(a1-a2).ge.0.0 .

--
        Peter L. Montgomery 
        pmontgom@MATH.UCLA.EDU 
        Department of Mathematics, UCLA, Los Angeles, CA 90024-1555
If I spent as much time on my dissertation as I do reading news, I'd graduate.

dik@cwi.nl (Dik T. Winter) (04/14/91)

In article <1991Apr12.151728.12916@craycos.com> jrbd@craycos.com (James Davies) writes:
 > In article <282@venice.water.ca.gov> rfinch@caldwr.water.ca.gov (Ralph Finch) writes:
 > >a=max(abs(a1),abs(a2)) ! but a has sign of either a1 or a2
 > >
 > 	a = sign(max(abs(a1),abs(a2)), a1+a2)

Except this fails if a1+a2 overflows.  The other solution I saw is better,
although a bit more elaborate.
--
dik t. winter, cwi, amsterdam, nederland
dik@cwi.nl