1. abs()

hey i remember ages ago someone posted asking the quickest way to code an abs()
function. The results were good, but a few who posted at the end of the thread
posted very very efficient ways to do this in euphoria, which i cannot remember.
I'm looking for speed here. Any help would be appreciated

new topic     » topic index » view message » categorize

2. Re: abs()

Chris Bensler wrote:
> FD(censored) wrote:
> 
>>hey i remember ages ago someone posted asking the quickest way to code 
>>an abs() function. The results were good, but a few who posted at the 
>>end of the thread posted very very efficient ways to do this in 
>>euphoria, which i cannot remember. I'm looking for speed here. Any help 
>>would be appreciated
> 
> I dunno about the fastest, but this beats most attempts..
> 
> }}}
<eucode>
> global function abs(object x)
>   if atom(x) then
>     if x < 0 then return -x else return x end if
>   else
>     for i = 1 to length(x) do
>       if x[i] < 0 then x[i] = -x[i] end if
>     end for
>   end if
>   return x
> end function
> </eucode>
{{{


There's fast code and there's fast (easy) to type. The above function is 
close to the fast code solution, but fails on sequences of sequences...

This minor change solves that:

global function abs(object x)
   if atom(x) then
     if x < 0 then return -x else return x end if
   else
     for i = 1 to length(x) do
       x[i] = abs(x[i])
     end for
   end if
   return x
end function


The easy to type version (but not guaranteed to be fast) is:

global function abs(object x)
     return x*((x>0)-(x<0))
end function


> if you don't have to deal with sequences (which you likely do not), you 
> can optimize for atoms..
> 
> }}}
<eucode>
> global function abs(atom a)
>   if a < 0 then return -a else return a end if
> end function
> </eucode>
{{{


Carl

-- 
[ Carl R White == aka () = The Domain of Cyrek = ]
[ Cyrek the Illogical /\ www.cyreksoft.yorks.com ]

new topic     » goto parent     » topic index » view message » categorize

3. Re: abs()

On Tue, 26 Oct 2004 11:05:02 +0100, Carl W.
<euphoria at cyreksoft.yorks.com> wrote:
> The easy to type version (but not guaranteed to be fast) is:
> 
> }}}
<eucode>
> global function abs(object x)
>      return x*((x>0)-(x<0))
> end function
> </eucode>
{{{


This will be faster:

global function abs(object x)
    return x*( 1 - 2*(x<1) )
end function


Because it only tests x once.

-- 
MrTrick

new topic     » goto parent     » topic index » view message » categorize

4. Re: abs()

Patrick Barnes wrote:
> Carl W. wrote:
> 
>>The easy to type version (but not guaranteed to be fast) is:
>>}}}
<eucode>
>>global function abs(object x)
>>     return x*((x>0)-(x<0))
>>end function
>></eucode>
{{{

> 
> This will be faster:
> 
> }}}
<eucode>
> global function abs(object x)
>     return x*( 1 - 2*(x<1) )
> end function
> </eucode>
{{{


A few tests later (I'll post the test code if requested), and 
surprisingly there's no real difference in the timings. I was about to 
concede, because the first couple of tests came back in favour of PB's 
algorithm, but they averaged out after a few more runs.

I did change the return line to:
return x*( 1 - 2*(x<0) )

...as otherwise it wouldn't return correct results for anything in the 
atom range 0.0 to 1.0.

I suspect they're equivalent in timing because they both process the 
something the same length as the x sequence 4 times: Mine for (x>0), 
(x<0), the subtraction and then the multiplication by x; PB's for (x<0), 
the Multiplication by 2, a subtraction and then the same multiplication 
by x.

This is all academic though, as the recursive version in my last message 
is faster for bigger sequences.

Carl

-- 
[ Carl R White == aka () = The Domain of Cyrek = ]
[ Cyrek the Illogical /\ www.cyreksoft.yorks.com ]

new topic     » goto parent     » topic index » view message » categorize

5. Re: abs()

On Wed, 27 Oct 2004 11:14:44 +0100, Carl W.
<euphoria at cyreksoft.yorks.com> wrote:
> I did change the return line to:
> }}}
<eucode>
>      return x*( 1 - 2*(x<0) )
> </eucode>
{{{

> ...as otherwise it wouldn't return correct results for anything in the
> atom range 0.0 to 1.0.

Hehehe... oops getlost

-- 
MrTrick

new topic     » goto parent     » topic index » view message » categorize

6. Re: abs()

On Wed, 27 Oct 2004 11:14:44 +0100, Carl W. wrote:

maybe i'm missing something here, but why the for() loop when processing a
sequence?
i haven't tested but is it faster than those posted below?

ie, where a = {1,2,{-1,-2}}, -a = {-1,-2,{1,2}}

those functions below should work fine on sequences. I have a real old computer
here (486), so small variances in execution time are noticeable.

on this PC, i found the fastest one for atoms was the simple

function abs(atom a) if (a < 0) then return -a end if return a end function


or it could use one of the ones you posted in the previous email, the difference
is really negligible.

BUT, for sequences these methods were a whopping 30-40% slower, than this:

function abs(sequence a) return sqrt(a*a) end function


so, i found, again i stress ONLY on this particular PC which is irregular at the
best of times, the most efficient all purpose algorithm to be:
function abs(object a)
	if sequence(a) then return sqrt(a*a)
	elsif (a < 0) then return -a end if
	return a
end function

which was NOT what i expected




> 
> >>The easy to type version (but not guaranteed to be fast) is:
> >>}}}
<eucode>
> >>global function abs(object x)
> >>     return x*((x>0)-(x<0))
> >>end function
> >></eucode>
{{{

> > 
> > This will be faster:
> > 
> > }}}
<eucode>
> > global function abs(object x)
> >     return x*( 1 - 2*(x<1) )
> > end function
> > </eucode>
{{{

> 
> A few tests later (I'll post the test code if requested), and 
> surprisingly there's no real difference in the timings. I was about to 
> concede, because the first couple of tests came back in favour of PB's 
> algorithm, but they averaged out after a few more runs.
> 
> I did change the return line to:
> }}}
<eucode>
>      return x*( 1 - 2*(x<0) )
> </eucode>
{{{

> ...as otherwise it wouldn't return correct results for anything in the 
> atom range 0.0 to 1.0.
> 
> I suspect they're equivalent in timing because they both process the 
> something the same length as the x sequence 4 times: Mine for (x>0), 
> (x<0), the subtraction and then the multiplication by x; PB's for (x<0), 
> the Multiplication by 2, a subtraction and then the same multiplication 
> by x.
> 
> This is all academic though, as the recursive version in my last message 
> is faster for bigger sequences.
> 
> Carl
> 
> -- 
> [ Carl R White == aka () = The Domain of Cyrek = ]
> [ Cyrek the Illogical /\ www.cyreksoft.yorks.com ]
> 
> 
> 
> 

-- 
FD(censored)

new topic     » goto parent     » topic index » view message » categorize

7. Re: abs()

FDe(censored) wrote:
> 
> On Wed, 27 Oct 2004 11:14:44 +0100, Carl W. wrote:
> 
> maybe i'm missing something here, but why the for() loop when processing a
> sequence?
> i haven't tested but is it faster than those posted below?
> 
> ie, where a = {1,2,{-1,-2}}, -a = {-1,-2,{1,2}}
> 
> those functions below should work fine on sequences. I have a real old
> computer here
> (486), so small variances in execution time are noticeable. 
> 
> on this PC, i found the fastest one for atoms was the simple
> 
> }}}
<eucode>
> function abs(atom a) if (a < 0) then return -a end if return a end function
> </eucode>
{{{

> 
> or it could use one of the ones you posted in the previous email, the
> difference is
> really negligible.
> 
> BUT, for sequences these methods were a whopping 30-40% slower, than this:
> 
> }}}
<eucode>
> function abs(sequence a) return sqrt(a*a) end function
> </eucode>
{{{

> 
> so, i found, again i stress ONLY on this particular PC which is irregular at
> the best
> of times, the most efficient all purpose algorithm to be:
> }}}
<eucode>
> 
> function abs(object a)
> 	if sequence(a) then return sqrt(a*a)
> 	elsif (a < 0) then return -a end if
> 	return a
> end function

It's not *quite* all purpose.  If you're dealing with very large magnitude
numbers, you could get bad results.  See:

http://www.listfilter.com/cgi-bin/esearch.exu?thread=1&fromMonth=8&fromYear=3&toMonth=A&toYear=3&keywords=%22ABS%22

I suppose you could also lose some precision, depending on the fp 
numbers involved.

Matt Lewis

new topic     » goto parent     » topic index » view message » categorize

8. Re: abs()

<snip>

> those functions below should work fine on sequences. I have a real old
> computer here
> (486), so small variances in execution time are noticeable. 
> 
> so, i found, again i stress ONLY on this particular PC which is irregular at
> the best
> of times, the most efficient all purpose algorithm to be:
> }}}
<eucode>

<snip>

> function abs(object a)
> 	if sequence(a) then return sqrt(a*a)
> 	elsif (a < 0) then return -a end if
> 	return a
> end function
> 
> which was NOT what i expected

And neither do I. Aren't 486's supposed to have slow fpu's?
Anyway, is it an sx or dx?

Regards, Alexander Toresson

Shhh! Be vewy quiet! I'm hunting wuntime ewwows!

new topic     » goto parent     » topic index » view message » categorize

9. Re: abs()

Matt:
> It's not *quite* all purpose.  If you're dealing with very large magnitude
> numbers, you could get bad results.

Good point. I haven't really put a whole lot of thought into this, i never
thought of using huge numbers as i don't really use numbers outside the realm of
2^30 in general purpose programming.
I'll choose the more robust from the list.

Alexander:
Umm i'm not sure. I presume it's around the DX2-80 mark, from my experience with
486's.
it's made up of spare parts and has a good network card, which itself is worth
more than the rest of the computer combined.. heheh

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu