> However, to optimize the calculation the following is more efficient

I tested it, but didn't find it any faster.
Naming makes it a lot clearer though.

RBS

On Fri, Oct 18, 2019 at 10:56 PM Keith Medcalf <kmedc...@dessus.com> wrote:

>
> We are calculating the square root using Newtons Method of successive
> approximation
>
> https://pages.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/sqrt.html
>
> (x>0)*(y+x/y)/2 yi
>
> is computing the new guess of the square root of x based on the last guess
> y and calling that calculation yi (the AS keyword is omitted).  The (x>0)
> part is to make sure that x is always a positive number otherwise the new
> guess will be 0.  This means that the attempt to find the square root of a
> negative number (or 0) will always return 0 for each of two iterations thus
> meeting the stop condition because abs(0 - 0) is less than any positive
> number.
>
> To use a CTE with better named variables one would use:
>
> with guesses(findRootOf, guessRoot, iteration)
>   as (
>          select ?, 1.0, 1
>       union all
>          select findRootOf, (findRootOf > 0) * (guessRoot + findRootOf /
> guessRoot) / 2.0 as newGuess, iteration + 1
>            from guesses
>           where abs(newGuess - guessRoot) > 1e-12
>           limit 32
>      )
>   select guessRoot
>     from guesses
> order by iteration desc
>    limit 1;
>
> However, to optimize the calculation the following is more efficient
> (since it only calculates the new guess once each iteration, and computes
> to the limit of precision).  We are substituting calculating the guess
> twice and its difference from a constant (9 operations) with computing the
> actual precision (6 operations):
>
> with guesses(findRootOf, guessRoot, iteration)
>   as (
>          select ?, 1.0, 1
>       union all
>          select findRootOf, (findRootOf > 0) * (guessRoot + findRootOf /
> guessRoot) / 2.0, iteration + 1
>            from guesses
>           where abs(guessRoot*guessRoot - findRootOf) >
> (2.22044604925031e-16 * FindRootOf)
>           limit 32
>      )
>   select guessRoot
>     from guesses
> order by iteration desc
>    limit 1;
>
> where 2.22044604925031e-16 is the epsilon of IEEE754 double precision
> floating point numbers (the limit of computational precision in the last
> binary place)
>
> --
> The fact that there's a Highway to Hell but only a Stairway to Heaven says
> a lot about anticipated traffic volume.
>
> >-----Original Message-----
> >From: sqlite-users <sqlite-users-boun...@mailinglists.sqlite.org> On
> >Behalf Of Bart Smissaert
> >Sent: Friday, 18 October, 2019 14:55
> >To: SQLite mailing list <sqlite-users@mailinglists.sqlite.org>
> >Subject: Re: [sqlite] Standard deviation last x entries
> >
> >Hi Olaf,
> >
> >Could you tell me what this is doing:
> >
> >,(x>0)*(y+x/y)/2 yi
> >
> >Especially the yi after the 2
> >How does the yi relate to the preceding bit?
> >
> >RBS
> >
> >
> >
> >On Fri, Oct 18, 2019 at 8:26 PM Olaf Schmidt <n...@vbrichclient.com> wrote:
> >
> >> Am 18.10.2019 um 19:45 schrieb Bart Smissaert:
> >>
> >> > Regarding:
> >> >
> >> > With r(s2, s, i) As (Select 2, 1, 1 Union All
> >> >     Select s2, (s2>0)*(s+s2/s)*.5, i+1 From r Where Abs(s2-s*s)>1e-12
> >> > Limit 32
> >> > ) Select s From r Order By i Desc Limit 1
> >> >
> >> > How would this work if I wanted to update all the values in a table
> >> column
> >> > to have the square root?
> >>
> >> Well, as with any other (single-value-returning) Sub-Select
> >> (which was enclosed in parentheses)...
> >>
> >> E.g.
> >>       "Update MyTable Set MyCol = (Select 1)"
> >> would update MyCol with the value 1 across the whole table...
> >>
> >> Same thing basically (only "a bit larger") with a CTE-based
> >> "Single-Value-SubSelect"...
> >>
> >> BTW, I've updated and tuned the thing a bit (which should now
> >> offer more precision, and ~20% more performance as well):
> >>
> >> With  r (x, y, i) As (
> >>    Select ?, 1, 1  Union All
> >>    Select x,(x>0)*(y+x/y)/2 yi,i+1 From r Where Abs(yi-y)>1e-12 Limit
> >32
> >> ) Select y From r Order By i Desc Limit 1
> >>
> >> Note the question-marked "Parameter" for the "squared Input-Value"
> >> (in the first Select Statement of the CTEs triple).
> >>
> >> Integrated into an Update-Query it could look this way:
> >>
> >> Update MyTable Set MySquareRoot = ( -- SubSelect-Opening-Paren...
> >>   With  r (x, y, i) As (
> >>     Select MySquaredValue, 1, 1  Union All
> >>     Select x,(x>0)*(y+x/y)/2 yi,i+1 From r Where Abs(yi-y)>1e-12 Limit
> >32
> >>   ) Select y From r Order By i Desc Limit 1
> >> ) -- SubSelect-Closing-Paren...
> >>
> >> HTH
> >>
> >> Olaf
> >>
> >> _______________________________________________
> >> sqlite-users mailing list
> >> sqlite-users@mailinglists.sqlite.org
> >> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
> >>
> >_______________________________________________
> >sqlite-users mailing list
> >sqlite-users@mailinglists.sqlite.org
> >http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>
>
>
> _______________________________________________
> sqlite-users mailing list
> sqlite-users@mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to