1. abs()
- Posted by "Frank Dowling" <francis at gmx.co.uk> Oct 25, 2004
- 1654 views
- Last edited Oct 26, 2004
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
2. Re: abs()
- Posted by "Carl R. White" <euphoria at cyreksoft.yorks.com> Oct 26, 2004
- 1633 views
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 ]
3. Re: abs()
- Posted by Patrick Barnes <mrtrick at gmail.com> Oct 26, 2004
- 1649 views
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
4. Re: abs()
- Posted by "Carl R. White" <euphoria at cyreksoft.yorks.com> Oct 27, 2004
- 1665 views
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 ]
5. Re: abs()
- Posted by Patrick Barnes <mrtrick at gmail.com> Oct 27, 2004
- 1685 views
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 -- MrTrick
6. Re: abs()
- Posted by "Frankie Dowling" <francis at gmx.co.uk> Oct 27, 2004
- 1641 views
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)
7. Re: abs()
- Posted by Matt Lewis <matthewwalkerlewis at yahoo.com> Oct 27, 2004
- 1653 views
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
8. Re: abs()
- Posted by Alexander Toresson <toressonodakra at swipnet.se> Oct 27, 2004
- 1649 views
<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!
9. Re: abs()
- Posted by "Frankie Dowling" <francis at gmx.co.uk> Oct 27, 2004
- 1646 views
- Last edited Oct 28, 2004
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