use quarto, not Pluto to render pages

This commit is contained in:
jverzani
2022-07-24 16:38:24 -04:00
parent 93c993206a
commit 7b37ca828c
879 changed files with 793311 additions and 2678 deletions

View File

@@ -54,10 +54,8 @@ possible. The function $h(x)$ would have range
$[0,\infty)$. The $s(x)$ function is either $-1$ or $1$, so only has two possible values in its range. What about $g(x)$? It is a parabola that opens upward, so any $y$ values below the $y$ value of its vertex will not appear in the range. In this case, the symmetry indicates that the vertex will be at $(1/2, -1/4)$, so the range is $[-1/4, \infty)$.
```julia;echo=false;
note("""
**Thanks to Euler (1707-1783):** The formal idea of a function is a relatively modern concept in mathematics. According to [Dunham](http://www.maa.org/sites/default/files/pdf/upload_library/22/Ford/dunham1.pdf),
!!! note
**Thanks to Euler (1707-1783):** The formal idea of a function is a relatively modern concept in mathematics. According to [Dunham](http://www.maa.org/sites/default/files/pdf/upload_library/22/Ford/dunham1.pdf),
Euler defined a function as an "analytic expression composed in any way
whatsoever of the variable quantity and numbers or constant
quantities." He goes on to indicate that as Euler matured, so did
@@ -66,8 +64,6 @@ note("""
“analytic expression.” He finishes by saying: "It is fair to say
that we now study functions in analysis because of him."
""")
```
We will see that defining functions within `Julia` can be as simple a concept as Euler started with, but that the more abstract concept has a great advantage that is exploited in the design of the language.
@@ -92,28 +88,24 @@ f(pi), g(2), h(4)
For typical cases like the three above, there isn't really much new to learn.
```julia;echo=false;
note("""
!!! note
The equals sign in `Julia` always indicates either an assignment or a
mutation of the object on the left side. The definition of a function
above is an *assignment*, in that a function is added (or modified) in
a table holding the methods associated with the function's name.
The equals sign in `Julia` always indicates either an assignment or a
mutation of the object on the left side. The definition of a function
above is an *assignment*, in that a function is added (or modified) in
a table holding the methods associated with the function's name.
The equals sign restricts the expressions available on the *left*-hand
side to a) a variable name, for assignment; b) mutating an object at an index,
as in `xs[1]`; c) mutating a property of a stuct; or d) a function assignment
following this form `function_name(args...)`.
The equals sign restricts the expressions available on the *left*-hand
side to a) a variable name, for assignment; b) mutating an object at an index,
as in `xs[1]`; c) mutating a property of a stuct; or d) a function assignment
following this form `function_name(args...)`.
Whereas function
definitions and usage in `Julia` mirrors standard math notation;
equations in math are not so mirrored in `Julia`. In mathematical
equations, the left-hand of an equation is typically a complicated
algebraic expression. Not so with `Julia`, where the left hand side of
the equals sign is prescribed and quite limited.
Whereas function
definitions and usage in `Julia` mirrors standard math notation;
equations in math are not so mirrored in `Julia`. In mathematical
equations, the left-hand of an equation is typically a complicated
algebraic expression. Not so with `Julia`, where the left hand side of
the equals sign is prescribed and quite limited.
""")
```
### The domain of a function
@@ -244,17 +236,12 @@ Or similarly, a function to represent a cell phone plan where the first ``500``
cellplan(x) = x < 500 ? 20.0 : 20.0 + 0.05 * (x-500)
```
```julia;echo=false;
alert("""
Type stability. These last two definitions used `10.0` and `20.0`
instead of the integers `10` and `20` for the answer. Why the extra
typing? When `Julia` can predict the type of the output from the type
of inputs, it can be more efficient. So when possible, we help out and
ensure the output is always the same type.
""")
```
!!! warning
Type stability. These last two definitions used `10.0` and `20.0`
instead of the integers `10` and `20` for the answer. Why the extra
typing? When `Julia` can predict the type of the output from the type
of inputs, it can be more efficient. So when possible, we help out and
ensure the output is always the same type.
##### Example
@@ -303,11 +290,9 @@ end
The line `return x^2`, could have just been `x^2` as it is the last (and) only line evaluated.
```julia;echo=false;
note("""
The `return` keyword is not a function, so is not called with parentheses. An emtpy `return` statement will return a value of `nothing`.
""")
```
!!! note
The `return` keyword is not a function, so is not called with parentheses. An emtpy `return` statement will return a value of `nothing`.
##### Example
@@ -602,11 +587,9 @@ just uses the change-of-base formula for logarithms.
But not so fast, on the left side is a function with two arguments and on the right side the functions have one argument - yet they share the same name. How does `Julia` know which to use? `Julia` uses the number, order, and *type* of the positional arguments passed to a function to determine which function definition to use. This is technically known as [multiple dispatch](http://en.wikipedia.org/wiki/Multiple_dispatch) or **polymorphism**. As a feature of the language, it can be used to greatly simplify the number of functions the user must learn. The basic idea is that many functions are "generic" in that they have methods which will work differently in different scenarios.
```julia;echo=false;
alert("""
Multiple dispatch is very common in mathematics. For example, we learn different ways to add: integers (fingers, carrying), real numbers (align the decimal points), rational numbers (common denominators), complex numbers (add components), vectors (add components), polynomials (combine like monomials), ... yet we just use the same `+` notation for each operation. The concepts are related, the details different.
""")
```
!!! warning
Multiple dispatch is very common in mathematics. For example, we learn different ways to add: integers (fingers, carrying), real numbers (align the decimal points), rational numbers (common denominators), complex numbers (add components), vectors (add components), polynomials (combine like monomials), ... yet we just use the same `+` notation for each operation. The concepts are related, the details different.
`Julia` is similarly structured. `Julia` terminology would be to call the operation "`+`" a *generic function* and the different implementations *methods* of "`+`". This allows the user to just need to know a smaller collection of generic concepts yet still have the power of detail-specific implementations. To see how many different methods are defined in the base `Julia` language for the `+` operator, we can use the command `methods(+)`. As there are so many ($\approx 200$) and that number is growing, we illustrate how many different logarithm methods are implemented for "numbers:"
@@ -720,17 +703,15 @@ creates a function, this function is returned by `shift_right`.
So we could have done something more complicated like:
```julia;
p(x) = x^2 - 2x
l = shift_right(p, c=3)
f(x) = x^2 - 2x
l = shift_right(f, c=3)
```
Then `l` is a function that is derived from `p`.
Then `l` is a function that is derived from `f`.
!!! note
The value of `c` used when `l` is called is the one passed to `shift_right`. Functions like `l` that are returned by other functions also are called *closures*, as the context they are evaluated within includes the context of the function that constructs them.
```julia;echo=false
note("""
The value of `c` used when `l` is called is the one passed to `shift_right`. Functions like `l` that are returned by other functions also are called *closures*, as the context they are evaluated within includes the context of the function that constructs them.
""")
```
Anonymous functions can be created with the `function` keyword, but we will use the "arrow" notation, `arg->body` to create them, The above, could have been defined as:
@@ -741,32 +722,27 @@ shift_right_alt(f; c=0) = x -> f(x-c)
When the `->` is seen a function is being created.
```julia;echo=false;
alert("""
Generic versus anonymous functions. Julia has two types of functions,
generic ones, as defined by `f(x)=x^2` and anonymous ones, as defined
by `x -> x^2`. One gotcha is that `Julia` does not like to use the
same variable name for the two types. In general, Julia is a dynamic
language, meaning variable names can be reused with different types
of variables. But generic functions take more care, as when a new
method is defined it gets added to a method table. So repurposing the
name of a generic function for something else is not allowed (well, in `Pluto` it is.). Similarly,
repurposing an already defined variable name for a generic function is
not allowed. This comes up when we use functions that return functions
as we have different styles that can be used: When we defined `l =
shift_right(f, c=3)` the value of `l` is assigned an anonymous
function. This binding can be reused to define other variables.
However, we could have defined the function `l` through `l(x) =
shift_right(f, c=3)(x)`, being explicit about what happens to the
variable `x`. This would add a method to the generic function `l`. Meaning, we
get an error if we tried to assign a variable to `l`, such as an
expression like `l=3`. We generally employ the latter style, even though
it involves a bit more typing, as we tend to stick to methods of generic
functions for consistency.
""")
```
!!! warning
Generic versus anonymous functions. Julia has two types of functions,
generic ones, as defined by `f(x)=x^2` and anonymous ones, as defined
by `x -> x^2`. One gotcha is that `Julia` does not like to use the
same variable name for the two types. In general, Julia is a dynamic
language, meaning variable names can be reused with different types
of variables. But generic functions take more care, as when a new
method is defined it gets added to a method table. So repurposing the
name of a generic function for something else is not allowed. Similarly,
repurposing an already defined variable name for a generic function is
not allowed. This comes up when we use functions that return functions
as we have different styles that can be used: When we defined `l =
shift_right(f, c=3)` the value of `l` is assigned an anonymous
function. This binding can be reused to define other variables.
However, we could have defined the function `l` through `l(x) =
shift_right(f, c=3)(x)`, being explicit about what happens to the
variable `x`. This would add a method to the generic function `l`. Meaning, we
get an error if we tried to assign a variable to `l`, such as an
expression like `l=3`. We generally employ the latter style, even though
it involves a bit more typing, as we tend to stick to methods of generic
functions for consistency.
##### Example: the secant line
@@ -863,8 +839,8 @@ choices = [
"Domain is all non-negative numbers, range is all real numbers",
"Domain is all non-negative numbers, range is all non-negative numbers"
]
ans = 2
radioq(choices, ans)
answ = 2
radioq(choices, answ)
```
##### Question
@@ -879,8 +855,8 @@ L"Domain is all real numbers except $2$, range is all real numbers except $0$",
L"Domain is all non-negative numbers except $0$, range is all real numbers except $2$",
L"Domain is all non-negative numbers except $-2$, range is all non-negative numbers except $0$"
]
ans = 2
radioq(choices, ans)
answ = 2
radioq(choices, answ)
```
##### Question
@@ -893,8 +869,8 @@ raw"``f(x) = 2^x``",
raw"``f(x) = 1/x^2``",
raw"``f(x) = |x|``",
raw"``f(x) = \sqrt{x}``"]
ans = 1
radioq(choices, ans)
answ = 1
radioq(choices, answ)
```
@@ -908,8 +884,8 @@ q"function f(x) = sin(x + pi/3)",
q"f(x) = sin(x + pi/3)",
q"f: x -> sin(x + pi/3)",
q"f x = sin(x + pi/3)"]
ans = 3
radioq(choices, ans)
answ = 3
radioq(choices, answ)
```
###### Question
@@ -923,8 +899,8 @@ q"f(x) := (1 + x^2)^(-1)",
q"f[x] = (1 + x^2)^(-1)",
q"def f(x): (1 + x^2)^(-1)"
]
ans = 1
radioq(choices, ans)
answ = 1
radioq(choices, answ)
```
@@ -1057,8 +1033,8 @@ Will the call `C(1, mu=70)` use a value of `70` for `mu`?
```julia; hold=true;echo=false;
choices = ["Yes, this will work just as it does for keyword arguments",
"No, there will be an error that the function does not accept keyword arguments"]
ans = 2
radioq(choices, ans)
answ = 2
radioq(choices, answ)
```
###### Question
@@ -1077,8 +1053,8 @@ choices = [
"If `x` is in `[a,b]` it returns `x`, otherwise it returns `NaN`",
"`x` is the larger of the minimum of `x` and `a` and the value of `b`, aka `max(min(x,a),b)`"
]
ans = 1
radioq(choices, ans)
answ = 1
radioq(choices, answ)
```
@@ -1108,8 +1084,8 @@ L"You still get $0.649...$",
"You get a `MethodError`, as `cos(pi/4)` is evaluated as a number and `∘` is not defined for functions and numbers",
"You get a `generic` function, but this won't be callable. If tried, it will give an method error."
]
ans = 2
radioq(choices, ans, keep_order=true)
answ = 2
radioq(choices, answ, keep_order=true)
```
###### Question
@@ -1121,8 +1097,8 @@ choices = [
"It is `0.6663667453928805`, the same as `cos(sin(1))`",
"It is `0.5143952585235492`, the same as `sin(cos(1))`",
"It gives an error"]
ans = 1
radioq(choices, ans, keep_order=true)
answ = 1
radioq(choices, answ, keep_order=true)
```
###### Question
@@ -1136,8 +1112,8 @@ fn(3)
```julia; hold=true;echo=false;
choices = ["`true`","`false`"]
ans = 1
radioq(choices, ans)
answ = 1
radioq(choices, answ)
```
###### Question
@@ -1160,8 +1136,8 @@ Repeat the secant method two more times to find a better approximation for $\sqr
```julia; hold=true;echo=false;
choices = [q"4//3", q"7//5", q"58//41", q"816//577"]
ans = 3
radioq(choices, ans, keep_order=true)
answ = 3
radioq(choices, answ, keep_order=true)
```
How small is the value of $f(c)$ for this value?
@@ -1175,8 +1151,8 @@ How close is this answer to the true value of $\sqrt{2}$?
```julia; hold=true;echo=false;
choices = [L"about $8$ parts in $100$", L"about $1$ parts in $100$", L"about $4$ parts in $10,000$", L"about $2$ parts in $1,000,000$"]
ans = 3
radioq(choices, ans, keep_order=true)
answ = 3
radioq(choices, answ, keep_order=true)
```
(Finding a good approximation to $\sqrt{2}$ would be helpful to builders, for example, as it could be used to verify the trueness of a square room, say.)
@@ -1190,8 +1166,8 @@ choices = ["Just use `f = h - g`",
"Define `f(x) = h(x) - g(x)`",
"Use `x -> h(x) - g(x)` when the difference is needed"
]
ans = 1
radioq(choices, ans)
answ = 1
radioq(choices, answ)
```
###### Question