7

To implement "Hero's Method" for approximating $\sqrt{c}$, one iterates the function (x + c/x)/2 for a given number c (e.g., 2) starting with some initial value of x. This can be implemented by defining first the function

g[c_, x_] := (x + c/x)/2

of two variables, next fixing the first variable to get the pure function g[2, #]&, and finally iterating with Nest (or NestList, etc.):

Nest[g[2, #]&, 1.0, 5]

Another way is to define

h[c_][x_] := (x + c/x)/2

and then iterate h[2], as in:

Nest[h[2], 1.0, 5]

Yet h[2] evaluates to nothing more than itself:

h[2]
(* h[2] *)

Technical question: What kind of creature is the expression h[2]? It acts as if it were a function. Can one say something more to describe or characterize it? (Yes, I realize that currying is involved here.)

Subsidiary pedagogical question (which may be unsuitable for this forum): For a Mathematica beginner, which approach to iterating (for a fixed c) is likely to be easier to understand — fixing the first argument to g and making a pure function, on the one hand, or defining h as shown, on the other hand? How does the answer to the technical question affect the answer to this pedagogical question?

MarcoB
  • 67,153
  • 18
  • 91
  • 189
murray
  • 11,888
  • 2
  • 26
  • 50
  • Try h[2][y]... – ciao Aug 30 '15 at 20:03
  • This is "Heron´s method", not "Hero´s method" - even he must have been a clever guy ;-) – mgamer Aug 30 '15 at 20:08
  • 1
    Actually, the method is widely cited as "Hero's Method", e.g. in https://en.wikipedia.org/wiki/Methods_of_computing_square_roots. And it's also knows as the" Babylonian method". But yes, the English transliteration of the Greek name Ἥρων" is "Heron". – murray Aug 30 '15 at 20:12
  • @ciao: Yes, I know what I get for h[2][y] or h[2][x], etc. But how can one characterize h[2] itself? That was my question. – murray Aug 30 '15 at 20:15
  • 1
    It is simply an expression which by itself does not get rewritten non-trivially, so stays inert. It is not different from any other expression that doesn't have global rewrite rules applicable to it. You can make it behave as a function, however. Technically, this is realized via SubValues. This allows you to pass the "arguments" collected in h (like 2 in this case), to the body of the "function" (r.h.s. of the rule). This is useful, since it allows you to separate parameters which are fixed externally (behaves like constants, 2 here), from those which are passed dynamically. – Leonid Shifrin Aug 30 '15 at 20:22
  • 2
    @murray One useful thing here is to think how would you alternatively implement such a construct. If you want it to have exactly the same semantics, you can do something like h[c_]:=Function[x, (x + c/x)/2]. This reveals that you create a closure, closed over the value of c. So, this is one way to think also about h[c][x] construct when defined with rules, from the functional programming (operational) viewpoint - although the mechanism is technically very different. – Leonid Shifrin Aug 30 '15 at 20:25
  • Closely related, perhaps duplicate: Define parameterized function – Jens Aug 30 '15 at 20:35
  • @Jens: the "closely related" post you cite tells me something I already know, namely, that SubValues[h] gives what I expect. But it still doesn't say anything about what h[2] is. – murray Aug 30 '15 at 20:47
  • I think a good way to rephrase my technical question is to ask: "How would you explain to a Mathematica beginner what the object h[2] is?" – murray Aug 30 '15 at 20:48
  • @murray That depends on what the meaning of "is" is... – Jens Aug 30 '15 at 21:13
  • To give a short answer, I would say that for practical purposes it really is appropriate to call h a parametrized function, where 2 in h[2] is the parameter value. That has explanatory value to the extent that it allows you to remember when it's used, even if it doesn't describe the technical subtleties. – Jens Aug 30 '15 at 21:23
  • @Jens: Yes, I definitely like calling h a "parameterized function", with the 2 in h[2] a value of the parameter. I'm beginning to sense that it makes little sense to ask what h[2] is other than to say it's a function and look at h[2][x] or h[2][1], etc. -- no more sense than to ask what, say, Sin "is". – murray Aug 30 '15 at 21:29
  • @mgamer, both "Hero" and "Heron" are in fact acceptable; the same situation applies with his triangle area formula. – J. M.'s missing motivation Aug 30 '15 at 23:47
  • If one is going to regard h as a parameterized function, i.e., a family of functions, then one might as well use a subscript definition: Subscript[h, c_][x_] := (x + c/x)/2, so that StandardForm notation such as $h_2$ resembles a traditional mathematical notation for one of a family of functions. – murray Sep 02 '15 at 19:31

1 Answers1

6

This is pitched at the "how to understand" level, not the "how is it implemented" level. I've basically presented how I think of these things, without really caring about how Mathematica carries them out.

The object h[2][x] is just another expression-with-head. The head is h[2], which just happens to have a more complicated form than is perhaps usual. In the same way, Function[{x}, 5 x][4] is an expression whose head is Function[{x}, 5 x]. In this case, the complicated head is so complicated that Mathematica actually has a replacement rule to deal with its simplification.

To understand it more completely, it might help to meditate on the result of f[4] /. f -> h[2]. Structurally, the expression is basically identical.

I prefer to do both of your options: I would define g in two ways simultaneously.

g[c_, x_] := (x + c/x)/2
g[c_] := g[c, #]&

or for the second line

g[c_][x_] := g[c, x]

This more closely mimics the Select[function][list] forms introduced in 10.2, which are forms I use a lot and very much like.

It also has the benefit that simplification can be performed one time only. For instance, suppose $f(c, x)$ required a costly computation for each $c$, but it was fast to analyse as $x$ varied. I'm thinking LinearSolve, for instance. Then the following form is very neat.

f[c_, x_] := f[c][x]
f[c_] := f[c] = Function[{x}, (* time-consuming thing *)]
Patrick Stevens
  • 6,107
  • 1
  • 16
  • 42