> But probably slower, at least for exact numbers. If "expt" were implemented naively as "for i = 1 to num", the total number of multiplications would be quadratic in degree; if it were implemented by repeated squaring, the total number of multiplications would be O(n log(n)); with Horner's algorithm or your "values" approach, it's linear.
>
> Horner's algorithm gives us
>
> (lambda (poly x)
> (for/fold ([sum 0])
> ([c (polynomial-coeffs poly)])
> (+ c (* sum x))))
If I recall correctly, Horner's algorithm also gives more precise results,
when used with pseudo real numbers.
--
Jens Axel Søgaard
Especially true when coefficients alternate signs, producing massive
cancellation. That's the main reason to use it, since floating-point
exponentiation runs in constant time. (It's also a tad faster, requiring
at least 1-2 fewer flops per coefficient... but probably many more,
because hardware `pow' is usually broken for non-rational inputs and
implementations have to work around that.)
What I'd really like, by the time the math library has polynomials, is a
Horner-like algorithm for sparse polynomials of the form
c0 + ... + cn * x^(i_n) * y^(j_n) + ...
The sequence of (i_n,j_n) can only be partially ordered, which makes it
tricky.
Neil ⊥
Sent from my iPhone
I'd have to have the terms indexed by two different orderings
(nondecreasing in x's degree and nondecreasing in y's), or be willing to
sort. That seems tricky or slowish, but much better than what I've had
in mind. It should also work with other orthogonal bases, like the
Chebyshev polynomials, using Clenshaw's algorithm (of which Horner's is
a special case).
To let you know where I'm going with this, I'm considering designs for
`math/polynomial'. I want a data type that can represent sparse
polynomials over any ring, with any orthogonal basis in that ring. Basic
polynomial ops would be +, *, and conversion to another basis or another
ring type (e.g. from Exact-Rational to Flonum). A quotient polynomial
type would lift polynomial rings to fields.
I'd also like another basic op to be generating the syntax of a function
that evaluates the polynomial. Polynomials could then be built at
expansion time - say, by building a Taylor, Chebyshev, or minimax
approximation - and then evaluated quickly at runtime.
It looks like you know what you're talking about (you probably
understood all the preceeding text and can even point out errors :D), so
I'd love to hear any ideas you have along these lines.
Neil ⊥
I may as well throw in a big item on my "wish list". It would really be nice to have a tool for visualizing surfaces defined either explicitly
z = f (x, y)
or implicitly
g(x, y, z) = c
using wire mesh diagrams or a comparable technique.
But back to polynomials, I think I'll try writing something simple. What would be interesting is yo have s nice way of representing algebraic structures in Racket so that standard constructs like algebraic extensions such as Q(i) don't have to be strongly coupled with the definition of the base ring/field. Maybe I'm asking for functors (in the mathematical sense) and categories.
Sent from my iPhone
On Oct 16, 2012, at 9:08 AM, Neil Toronto <neil.t...@gmail.com> wrote:
>
> I'd have to have the terms indexed by two different orderings (nondecreasing in x's degree and nondecreasing in y's), or be willing to sort. That seems tricky or slowish, but much better than what I've had in mind. It should also work with other orthogonal bases, like the Chebyshev polynomials, using Clenshaw's algorithm (of which Horner's is a special case).
>
> To let you know where I'm going with this, I'm considering designs for `math/polynomial'. I want a data type that can represent sparse polynomials over any ring, with any orthogonal basis in that ring. Basic polynomial ops would be +, *, and conversion to another basis or another ring type (e.g. from Exact-Rational to Flonum). A quotient polynomial type would lift polynomial rings to fields.
>
> I'd also like another basic op to be generating the syntax of a function that evaluates the polynomial. Polynomials could then be built at expansion time - say, by building a Taylor, Chebyshev, or minimax approximation - and then evaluated quickly at runtime.
>
> It looks like you know what you're talking about (you probably understood all the preceeding text and can even point out errors :D), so I'd love to hear any ideas you have along these lines.
>
> Neil ⊥
____________________
file:///usr/share/racket/doc/plot/renderer3d.html?q=isosurface#(def._((lib._plot/main..rkt)._isosurface3d))
In particular:
#lang racket
(require plot)
(define (f x y)
(+ 2 (* 2 x) (* 5 y) (* 1/2 x y y) (* 6 x x)))
(plot3d (surface3d f -1 1 -1 1))
(plot3d (contour-intervals3d f -1 1 -1 1 #:label "f(x,y)"))
(define (g x y z)
(+ (* x y) (* y z) (* z x)))
(define c 0.25)
(plot3d (isosurface3d g c -1 1 -1 1 -1 1))
(plot3d (isosurfaces3d g -1 1 -1 1 -1 1 #:label "g(x,y,z)"))
Isosurfaces are visualized using marching cubes, whose patent finally
ran out a few years ago.
> Gregory Woodhouse <gregwo...@me.com> writes:
>> I'm intrigued. I suppose pattern based macros could be used to implement
>> operations like + and * [...]
I was thinking more generics. Generic `+' and `*' could evaluate
polynomials at runtime, and generic `syntax+' and `syntax*' could emit
code that does the same.
>> and passing to the field of quotients should formally be no different
>> from rational arithmetic.
Exactly. Reducing polynomial fractions in a generic way might be tricky,
but it looks fun. :)
>> Are you interested in Chebyshev polynomials for a particular reason
>> (e.g, applications to differential equations) or as part of a more
>> general mathematics library?
Both. Chebyshev polynomials have some nice properties when used to
approximate non-polynomials; in particular, they're really close to
minimax-error approximations. `math/special-functions' already uses a
private Chebyshev polynomial implementation extensively. For many R->R
functions, I only have to chop up their domains and plonk a Chebyshev
approximation down for each piece.
Chebyshev and other orthogonal polynomial bases come up repeatedly in
solutions to differential equations. Multidimensional polynomials can be
represented by sparse polynomials over other polynomial rings. When I
considered making the private polynomial API public, I studied up on
these things a bit, and realized it would be cleaner, more likely
correct, and more generally useful if I parameterized polynomials over
arbitrary rings and bases.
>> What would be interesting is yo have s nice way of representing
>> algebraic structures in Racket so that standard constructs like
>> algebraic extensions such as Q(i) don't have to be strongly coupled
>> with the definition of the base ring/field. Maybe I'm asking for
>> functors (in the mathematical sense) and categories.
That's exactly what I need. I had been thinking I'd wait until generics
found their way into Typed Racket. But I might try defining them untyped
(where generics work right now) and importing them using
`require/typed'. I have no idea whether it will work. :D