Horner's rule for two-variable polynomial

前端 未结 2 1620
挽巷
挽巷 2021-01-19 00:16

Horner\'s rule is used to simplify the process of evaluating a polynomial at specific variable values. https://rosettacode.org/wiki/Horner%27s_rule_for_polynomial_evaluation

相关标签:
2条回答
  • 2021-01-19 01:03

    Your second approach seems to be on the right track. If you have already defined horner, what you need to do is to apply horner to the result of mapping horner applied to inner list x over the outer list, something like:

    fun evalXY coeffLists x y = horner (map (fn coeffList => horner coeffList x) coeffLists) y
    

    You could replace the two calls to horner by the corresponding folds, but it would be much less readable.

    Note that if you reverse the order of the two parameters in horner then you can shorted evalXY:

    fun horner x coeffList = foldr (fn (a, b) => a + b * x) (0.0) coeffList
    fun evalXY x y coeffLists = horner y (map (horner x) coeffLists)
    

    The point being that the way currying works, if you use this second order then horner x is already a function of coeffList so you no longer need the anonymous function fn coeffList => horner coeffList x. The moral of the story is that when defining a curried function, you should think carefully about the order of the parameters since it will make some partial applications easier to create than others.

    By the way, SML is fussy. In your discussion of horner you said that you would call it like horner list 2. It would need to be horner list 2.0. Similarly, in your second attempt, using 0 rather than 0.0 is problematic.

    0 讨论(0)
  • 2021-01-19 01:04

    You're very close. Let's begin by formalizing the problem. Given coefficients C as a nested list like you indicated, you want to evaluate

    Notice that you can pull out the s from the inner sum, to get

    Look closely at the inner sum. This is just a polynomial on variable x with coefficients given by . In SML, we can write the inner sum in terms of your horner function as

    fun sumj Ci = horner Ci x
    

    Let's go a step further and define

    In SML, this is val D = map sumj C. We can now write the original polynomial in terms of D:

    It should be clear that this is just another instance of horner, since we have a polynomial with coefficients . In SML, the value of this polynomial is

    horner D y
    

    ...and we're done!


    Here's the final code:

    fun horner2 C x y =
      let
        fun sumj Ci = horner Ci x
        val D = map sumj C
      in
        horner D y
      end
    

    Isn't that nice? All we need is multiple applications of Horner's method, and map.

    0 讨论(0)
提交回复
热议问题