Compare commits

...

11 Commits

Author SHA1 Message Date
jverzani
e7684ac2f7 incorporate PR 2025-06-06 12:06:10 -04:00
jverzani
878c27c5a5 Merge branch 'ptoml' 2025-06-06 06:50:09 -04:00
jverzani
c08eb90a60 Merge branch 'main' of https://github.com/jverzani/CalculusWithJuliaNotes.jl 2025-06-06 06:49:59 -04:00
jverzani
748797fee5 WIP 2025-06-06 06:49:50 -04:00
john verzani
5093863199
Merge pull request #146 from fangliu-tju/main
some typos
2025-06-06 06:46:26 -04:00
Fang Liu
8ede2b33fb some typos 2025-06-06 16:56:56 +08:00
jverzani
6065782e07 typos 2025-05-29 07:49:08 -04:00
jverzani
4d4e2342d6 Merge branch 'main' of https://github.com/jverzani/CalculusWithJuliaNotes.jl 2025-05-29 07:47:47 -04:00
jverzani
efd69d2fa1 updates 2025-05-10 15:44:25 -04:00
jverzani
38785d432a Merge branch 'main' of https://github.com/jverzani/CalculusWithJuliaNotes.jl 2025-05-09 07:33:31 -04:00
jverzani
1518e3b9be add back file 2025-05-07 12:05:34 -04:00
22 changed files with 765 additions and 37 deletions

View File

@ -1,11 +1,16 @@
[deps]
CalculusWithJulia = "a2e0e22d-7d4c-5312-9169-8b992201a882"
IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a"
LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78"
MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca"
Mustache = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70"
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5"
PlotlyKaleido = "f2990250-8cf9-495f-b13a-cce12b45703c"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
QuizQuestions = "612c44de-1021-4a21-84fb-7261cf5eb2d4"
Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665"
SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6"
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
TextWrap = "b718987f-49a8-5099-9789-dcd902bef87d"

View File

@ -1,5 +1,5 @@
version: "0.23"
engine: julia
engines: ['julia']
project:
type: book

View File

@ -5,12 +5,19 @@ DualNumbers = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74"
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a"
ImplicitEquations = "95701278-4526-5785-aba3-513cca398f19"
LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
Mustache = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70"
PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5"
PlotlyKaleido = "f2990250-8cf9-495f-b13a-cce12b45703c"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
Polynomials = "f27b6e38-b328-58d1-80ce-0feddd5e7a45"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
QuizQuestions = "612c44de-1021-4a21-84fb-7261cf5eb2d4"
Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665"
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6"
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
TaylorSeries = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea"
TermInterface = "8ea1fca8-c5ef-4a55-8b96-4e9afe9c9a3c"
TextWrap = "b718987f-49a8-5099-9789-dcd902bef87d"
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"

View File

@ -1482,7 +1482,7 @@ a = find_zero(y', 1)
numericq(a)
```
Numerically find the value of $a$ that minimizes the length of the line seqment $PQ$.
Numerically find the value of $a$ that minimizes the length of the line segment $PQ$.
```{julia}

View File

@ -7,11 +7,16 @@ DifferentialEquations = "0c46a032-eb83-5123-abaf-570d42b7fbaa"
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a"
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Mustache = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70"
PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5"
PlotlyKaleido = "f2990250-8cf9-495f-b13a-cce12b45703c"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc"
QuizQuestions = "612c44de-1021-4a21-84fb-7261cf5eb2d4"
Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665"
ScatteredInterpolation = "3f865c0f-6dca-5f4d-999b-29fe1e7e3c92"
SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6"
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
TextWrap = "b718987f-49a8-5099-9789-dcd902bef87d"

View File

@ -1,13 +1,19 @@
[deps]
CalculusWithJulia = "a2e0e22d-7d4c-5312-9169-8b992201a882"
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a"
LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
Mustache = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70"
PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5"
PlotlyKaleido = "f2990250-8cf9-495f-b13a-cce12b45703c"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc"
QuizQuestions = "612c44de-1021-4a21-84fb-7261cf5eb2d4"
Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665"
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
SplitApplyCombine = "03a91e81-4c3e-53e1-a0a4-9c0c8f19dd66"
SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6"
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
TextWrap = "b718987f-49a8-5099-9789-dcd902bef87d"
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
UnitfulUS = "7dc9378f-8956-57ef-a780-aa31cc70ff3d"

View File

@ -493,14 +493,14 @@ What looks at first glance to be just a slightly more complicated equation is th
$$
\begin{align*}
s(u) &= \int_0^u \sqrt{(-\sin(t))^2 + b\cos(t)^2} dt\\
&= \int_0^u \sqrt{\sin(t)^2 + \cos(t)^2 + c\cos(t)^2} dt \\
&=\int_0^u \sqrt{1 + c\cos(t)^2} dt.
s(u) &= \int_0^u \sqrt{(-\sin(t))^2 + (b\cos(t))^2} dt\\
&= \int_0^u \sqrt{\sin(t)^2 + \cos(t)^2 + C\cos(t)^2} dt \\
&=\int_0^u \sqrt{1 + C\cos(t)^2} dt.
\end{align*}
$$
But, despite it not looking too daunting, this integral is not tractable through our techniques and has an answer involving elliptic integrals. We can work numerically though. Letting $a=1$ and $b=2$, we have the arc length is given by:
Where $C = 2c + c^2$ is a constant. But, despite it not looking too daunting, this integral is not tractable through our techniques and has an answer involving elliptic integrals. We can work numerically though. Letting $a=1$ and $b=2$, we have the arc length is given by:
```{julia}
@ -710,7 +710,7 @@ For the latter claim, integrating in the $y$ variable gives
$$
\begin{align*}
\int_u^c (f(x)-h) dx &= \int_h^m (c - f_1^{-1}(y)) dy\\
&> \int_h^m (c - f_2^{-1}(y)) dy\\
&> \int_h^m (f_2^{-1}(y) - c) dy\\
&= \int_c^v (f(x)-h) dx
\end{align*}
$$

View File

@ -17,7 +17,7 @@ using Roots
---
The question of area has long fascinated human culture. As children, we learn early on the formulas for the areas of some geometric figures: a square is $b^2$, a rectangle $b\cdot h$ a triangle $1/2 \cdot b \cdot h$ and for a circle, $\pi r^2$. The area of a rectangle is often the intuitive basis for illustrating multiplication. The area of a triangle has been known for ages. Even complicated expressions, such as [Heron's](http://tinyurl.com/mqm9z) formula which relates the area of a triangle with measurements from its perimeter have been around for 2000 years. The formula for the area of a circle is also quite old. Wikipedia dates it as far back as the [Rhind](http://en.wikipedia.org/wiki/Rhind_Mathematical_Papyrus) papyrus for 1700 BC, with the approximation of $256/81$ for $\pi$.
The question of area has long fascinated human culture. As children, we learn early on the formulas for the areas of some geometric figures: a square is $b^2$, a rectangle $b\cdot h$, a triangle $1/2 \cdot b \cdot h$ and for a circle, $\pi r^2$. The area of a rectangle is often the intuitive basis for illustrating multiplication. The area of a triangle has been known for ages. Even complicated expressions, such as [Heron's](http://tinyurl.com/mqm9z) formula which relates the area of a triangle with measurements from its perimeter have been around for 2000 years. The formula for the area of a circle is also quite old. Wikipedia dates it as far back as the [Rhind](http://en.wikipedia.org/wiki/Rhind_Mathematical_Papyrus) papyrus for 1700 BC, with the approximation of $256/81$ for $\pi$.
The modern approach to area begins with a non-negative function $f(x)$ over an interval $[a,b]$. The goal is to compute the area under the graph. That is, the area between $f(x)$ and the $x$-axis between $a \leq x \leq b$.
@ -480,9 +480,9 @@ This is just the area of a trapezoid with heights $a$ and $b$ and side length
$$
\begin{align*}
S &= x_1 \cdot (x_1 - x_0) + x_2 \cdot (x_2 - x_1) + \cdots x_n \cdot (x_n - x_{n-1}) \\
&= (a + 1\frac{b-a}{n}) \cdot \frac{b-a}{n} + (a + 2\frac{b-a}{n}) \cdot \frac{b-a}{n} + \cdots (a + n\frac{b-a}{n}) \cdot \frac{b-a}{n}\\
&= n \cdot a \cdot (\frac{b-a}{n}) + (1 + 2 + \cdots n) \cdot (\frac{b-a}{n})^2 \\
S &= x_1 \cdot (x_1 - x_0) + x_2 \cdot (x_2 - x_1) + \cdots + x_n \cdot (x_n - x_{n-1}) \\
&= (a + 1\frac{b-a}{n}) \cdot \frac{b-a}{n} + (a + 2\frac{b-a}{n}) \cdot \frac{b-a}{n} + \cdots + (a + n\frac{b-a}{n}) \cdot \frac{b-a}{n}\\
&= n \cdot a \cdot (\frac{b-a}{n}) + (1 + 2 + \cdots + n) \cdot (\frac{b-a}{n})^2 \\
&= n \cdot a \cdot (\frac{b-a}{n}) + \frac{n(n+1)}{2} \cdot (\frac{b-a}{n})^2 \\
& \rightarrow a \cdot(b-a) + \frac{(b-a)^2}{2} \\
&= \frac{b^2}{2} - \frac{a^2}{2}.
@ -729,7 +729,7 @@ An immediate consequence would be $\int_{-\pi}^\pi \sin(x) = 0$, as would $\int_
##### Example
Numerically estimate the definite integral $\int_0^e x\log(x) dx$. (We redefine the function to be $0$ at $0$, so it is continuous.)
Numerically estimate the definite integral $\int_0^2 x\log(x) dx$. (We redefine the function to be $0$ at $0$, so it is continuous.)
We have to be a bit careful with the Riemann sum, as the left Riemann sum will have an issue at $0=x_0$ (`0*log(0)`) returns `NaN` which will poison any subsequent arithmetic operations, so the value returned will be `NaN` and not an approximate answer. We could define our function with a check:
@ -860,7 +860,7 @@ $$
\frac{b-a}{6}(f(x_1) + 4f(x_2) + f(x_3)).
$$
This formula will actually be exact for any 3rd degree polynomial. In fact an entire family of similar approximations using $n$ points can be made exact for any polynomial of degree $n-1$ or lower. But with non-evenly spaced points, even better results can be found.
This formula will actually be exact for any 2nd degree polynomial. In fact an entire family of similar approximations using $n$ points can be made exact for any polynomial of degree $n-1$ or lower. But with non-evenly spaced points, even better results can be found.
The formulas for an approximation to the integral $\int_{-1}^1 f(x) dx$ discussed so far can be written as:

View File

@ -494,7 +494,7 @@ box(f⁻¹(x₀-1Δ), x₀-2Δ, 1 - f⁻¹(x₀-1Δ), Δ, colᵣ)
box(f⁻¹(x₀-2Δ), x₀-3Δ, 1 - f⁻¹(x₀-2Δ), Δ, colᵣ)
```
The figure above suggests that the area under $f(x)$ over $[a,b]$ could be represented as the area between the curves $f^{-1}(y)$ and $y=b$ from $[f(a), f(b)]$.
The figure above suggests that the area under $f(x)$ over $[a,b]$ could be represented as the area between the curves $f^{-1}(y)$ and $x=b$ from $[f(a), f(b)]$.
---
@ -552,7 +552,7 @@ p = plot(xs, ys; line=(3, :black), ylims=(0,4), legend=false)
scatter!(p, xs, ys; marker=(7, :circle))
```
Going further, we draw the four trapezoids using different colors depending on the sign of the `xs[i+1] - xs[[i]` terms:
Going further, we draw the four trapezoids using different colors depending on the sign of the `xs[i+1] - xs[i]` terms:
```{julia}
for i in 1:4
@ -563,7 +563,7 @@ end
p
```
The yellow trapezoids appear to be colored green, as they completely overlap with parts of the blue trapezoids and blue and yellow make green. As the signs of the differences of the $x$ values is different, these areas add to $0$ in the sum, leaving just the area of the interior when the sum is computed.
The yellow trapezoids appear to be colored grey, as they completely overlap with parts of the blue trapezoids and blue and yellow make grey with lights. As the signs of the differences of the $x$ values is different, these areas add to $0$ in the sum, leaving just the area of the interior when the sum is computed.
For this particular figure, the enclosed area is
@ -964,9 +964,10 @@ end
What does this imply:
```{julia}
#| hold: true
#| echo: false
choices = ["The two enclosed areas should be equal",
"The two enclosed areas are clearly different, as they do not overap"],
"The two enclosed areas are clearly different, as they do not overap"]
radioq(choices, 1)
```
"

View File

@ -503,7 +503,7 @@ numericq(val)
###### Question
Find the center of mass of the region in the first quadrant bounded by the function $f(x) = x^3(1-x)^4$.
Find the center of mass in the $x$ variable of the region in the first quadrant bounded by the function $f(x) = x^3(1-x)^4$.
```{julia}

View File

@ -589,7 +589,7 @@ The answer will either be at a critical point, at $0$ or as $x$ goes to $\infty$
$$
[\text{erf}(x)]' = \frac{2}{\pi}e^{-x^2}.
[\text{erf}(x)]' = \frac{2}{\sqrt{\pi}}e^{-x^2}.
$$
Oh, this is never $0$, so there are no critical points. The maximum occurs at $0$ or as $x$ goes to $\infty$. Clearly at $0$, we have $\text{erf}(0)=0$, so the answer will be as $x$ goes to $\infty$.
@ -755,7 +755,7 @@ A junior engineer at `Treadmillz.com` is tasked with updating the display of cal
**********
```
In this example display there was 1 calorie burned in the first minute, then 2, then 5, 5, 4, 3, 2, 2, 1. The total is $24$.
In this example display there was 1 calorie burned in the first minute, then 2, then 5, 5, 4, 4, 3, 2, 2, 1. The total is $29$.
In her work the junior engineer found this old function for updating the display
@ -814,7 +814,7 @@ end
Then the "area" represented by the dots stays fixed over this time frame.
The engineer then thought a bit more, as the form of her answer seemed familiar. She decides to parameterize it in terms of $t$ and found with $h=1/n$: `c(t) = (C(t) - C(t-h))/h`. Ahh - the derivative approximation. But then what is the "area"? It is no longer just the sum of the dots, but in terms of the functions she finds that each column represents $c(t)\cdot h$, and the sum is just $c(t_1)h + c(t_2)h + \cdots c(t_n)h$ which looks like an approximate integral.
The engineer then thought a bit more, as the form of her answer seemed familiar. She decides to parameterize it in terms of $t$ and found with $h=1/n$: `c(t) = (C(t) - C(t-h))/h`. Ahh - the derivative approximation. But then what is the "area"? It is no longer just the sum of the dots, but in terms of the functions she finds that each column represents $c(t)\cdot h$, and the sum is just $c(t_1)h + c(t_2)h + \cdots + c(t_n)h$ which looks like an approximate integral.
If the display were to reach the modern age and replace LED "dots" with a higher-pixel display, then the function to display would be $c(t) = C'(t)$ and the area displayed would be $\int_{t-10}^t c(u) du$.

View File

@ -161,7 +161,7 @@ $$
= \int_{\log(e)}^{\log(M)} \frac{1}{u^{2}} du
= \frac{-1}{u} \big|_{1}^{\log(M)}
= \frac{-1}{\log(M)} - \frac{-1}{1}
= 1 - \frac{1}{M}.
= 1 - \frac{1}{\log(M)}.
$$
As $M$ goes to $\infty$, this will converge to $1$.

View File

@ -95,7 +95,7 @@ end
@fig-integration-by-parts shows a parametric plot of $(u(t),v(t))$ for $a \leq t \leq b$..
The total shaded area, a rectangle, is $u(b)v(b)$, the area of $A$ and $B$ combined is just $u(b)v(b) - u(a)v(a)$ or $[u(x)v(x)]\big|_a^b$. We will show that that $A$ is $\int_a^b v(x)u'(x)dx$ and $B$ is $\int_a^b u(x)v'(x)dx$ giving the formula
The total shaded area, a rectangle, is $u(b)v(b)$, the area of $A$ and $B$ combined is just $u(b)v(b) - u(a)v(a)$ or $[u(x)v(x)]\big|_a^b$. We will show that $A$ is $\int_a^b v(x)u'(x)dx$ and $B$ is $\int_a^b u(x)v'(x)dx$ giving the formula.
We can compute $A$ by a change of variables with $x=u^{-1}(t)$ (so $u'(x)dx = dt$):

View File

@ -456,7 +456,7 @@ answ = 2
radioq(choices, answ, keep_order=true)
```
If $m < n$, then why can we cancel out the $(x-c)^n$ and not have a concern?
If $m < n$, then why can we cancel out the $(x-c)^m$ and not have a concern?
```{julia}

View File

@ -263,7 +263,7 @@ ws = unzip(S.(us,vs'))
surface(ws..., alpha=0.75)
```
We compare this answer to that of the frustum of a cone with radii $1$ and $(3/2)^2$, formed by rotating the line segment connecting $(0,f(0))$ with $(3/2,f(3/2))$. From looking at the graph of the surface, these values should be comparable. The surface area of the cone part is $\pi (r_1^2 + r_0^2) / \sin(\theta) = \pi (r_1 + r_0) \cdot \sqrt{(\Delta h)^2 + (r_1-r_0)^2}$.
We compare this answer to that of the frustum of a cone with radii $1$ and $(3/2)^2$, formed by rotating the line segment connecting $(0,f(0))$ with $(3/2,f(3/2))$. From looking at the graph of the surface, these values should be comparable. The surface area of the cone part is $\pi (r_1^2 - r_0^2) / \sin(\theta) = \pi (r_1 + r_0) \cdot \sqrt{(\Delta h)^2 + (r_1-r_0)^2}$.
```{julia}
@ -354,7 +354,7 @@ That is, the surface area is simply the circumference of the circle traced out b
##### Example
The surface area of of an open cone can be computed, as the arc length is $\sqrt{h^2 + r^2}$ and the centroid of the line is a distance $r/2$ from the axis. This gives SA$=2\pi (r/2) \sqrt{h^2 + r^2} = \pi r \sqrt{h^2 + r^2}$.
The surface area of an open cone can be computed, as the arc length is $\sqrt{h^2 + r^2}$ and the centroid of the line is a distance $r/2$ from the axis. This gives SA$=2\pi (r/2) \sqrt{h^2 + r^2} = \pi r \sqrt{h^2 + r^2}$.
##### Example

View File

@ -5,6 +5,7 @@ This section uses these packages:
```{julia}
using SymPy
using Plots
using Roots
plotly()
```
@ -165,7 +166,7 @@ A = simplify(integrate(nl - f(x), (x, q, a)));
#| code-fold: true
#| code-summary: "Show the code"
@syms k::nonnegative
V = simplify(integrate(PI * (nl - f(x) - k)^2, (x, q, a)));
V = simplify(integrate(2PI*(nl-f(x))*(a - x + k),(x, q, a)));
```
----
@ -218,7 +219,7 @@ L = integrate(sqrt(1 + fp(x)^2), (x, q, a));
----
> 5. The $y$ coordinate of the midpoint ofthe line segment $PQ$
> 5. The $y$ coordinate of the midpoint of the line segment $PQ$
```{julia}
@ -300,7 +301,7 @@ end
#| code-summary: "Show the code"
# use parametric and 2π ∫ u(t) √(u'(t)^2 + v'(t)^2) dt
uu(x) = a - x
vv(x) = f(uu(x))
vv(x) = f(a - uu(x))
SA = 2PI * integrate(uu(x) * sqrt(diff(uu(x),x)^2 + diff(vv(x),x)^2), (x, q, a));
```
@ -394,11 +395,11 @@ plot!([a₀,q₀,q₀,a₀-f(a₀)/fp(a₀),a₀],
# v1, v2, v3 = [[x[i]-x[1],y[i]-y[1], 0] for i in 2:4]
# area = 1//2 * last(cross(v3,v2) + cross(v2, v1)) # 1/2 area of parallelogram
# print(simplify(area))
# -(x₁ - x₂)*(y₁ - y₃)/2 + (x₁ - x₃)*(y₁ - y₂)/2 - (x₁ - x₃)*(y₁ - y₄)/2 + (x₁ - x₄)*(y₁ - y₃)/2
# (x₁ - x₂)*(y₁ - y₃)/2 - (x₁ - x₃)*(y₁ - y₂)/2 + (x₁ - x₃)*(y₁ - y₄)/2 - (x₁ - x₄)*(y₁ - y₃)/2
tl₀ = a - f(a) / fp(a)
x₁,x₂,x₃,x₄ = (a,q,q,tl₀)
y₁, y₂, y₃, y₄ = (f(a), f(q), 0, 0)
quadrilateral = -(x₁ - x₂)*(y₁ - y₃)/2 + (x₁ - x₃)*(y₁ - y₂)/2 - (x₁ - x₃)*(y₁ - y₄)/2 + (x₁ - x₄)*(y₁ - y₃)/2;
quadrilateral = (x₁ - x₂)*(y₁ - y₃)/2 - (x₁ - x₃)*(y₁ - y₂)/2 + (x₁ - x₃)*(y₁ - y₄)/2 - (x₁ - x₄)*(y₁ - y₃)/2;
```
----
@ -415,7 +416,7 @@ article_answers = (1/(2sqrt(2)), 1/2, sqrt(3/10), 0.558480, 0.564641,
#| echo: false
# check
problems = ("1a"=>yvalue, "1b"=>lseg, "1c"=>hd,
"2a" => A, "2b" => V,
"2a" => A, "2b" => V(k=>1),
"3" => yₘ,
"4" => L,
"5" => mp,
@ -429,7 +430,7 @@ problems = ("1a"=>yvalue, "1b"=>lseg, "1c"=>hd,
)
≈ₒ(a,b) = isapprox(a, b; atol=1e-5, rtol=sqrt(eps()))
∂ = Differential(a)
solutions = [k => only(solve(∂(p) ~ 0, a)) for (k,p) in problems]
solutions = [k => (find_zero(∂(p), 0.5)) for (k,p) in problems]
[(sol=k, correct=(any(isapprox.(s, article_answers; atol=1e-5)))) for (k,s) ∈ solutions]
nothing
```

View File

@ -2,7 +2,12 @@
CalculusWithJulia = "a2e0e22d-7d4c-5312-9169-8b992201a882"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a"
LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
Mustache = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
QuizQuestions = "612c44de-1021-4a21-84fb-7261cf5eb2d4"
Richardson = "708f8203-808e-40c0-ba2d-98a6953ed40d"
Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665"
SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6"
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
TextWrap = "b718987f-49a8-5099-9789-dcd902bef87d"

View File

@ -73,7 +73,7 @@ gif(anim, imgfile, fps = 1)
caption = L"""
The first triangle has area $1/2$, the second has area $1/8$, then $3$ have area $(1/8)^2$, $4$ have area $(1/8)^3$, ...
The first triangle has area $1/2$, the second has area $1/8$, then $2$ have area $(1/8)^2$, $4$ have area $(1/8)^3$, ...
With some algebra, the total area then should be $1/2 \cdot (1 + (1/4) + (1/4)^2 + \cdots) = 2/3$.
"""

View File

@ -68,7 +68,7 @@ For more control, the command line and `IJulia` provide access to the function i
] status
```
External packages are *typically* installed from GitHub and if they are regisered, installation is as easy as calling `add`:
External packages are *typically* installed from GitHub and if they are registered, installation is as easy as calling `add`:
```{julia}

View File

@ -4,12 +4,17 @@ DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a"
IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253"
LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a"
Measures = "442fdcdd-2543-5da2-b0f3-8c86c306513e"
Mustache = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70"
PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5"
PlotlyKaleido = "f2990250-8cf9-495f-b13a-cce12b45703c"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
Polynomials = "f27b6e38-b328-58d1-80ce-0feddd5e7a45"
Primes = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae"
QuizQuestions = "612c44de-1021-4a21-84fb-7261cf5eb2d4"
RealPolynomialRoots = "87be438c-38ae-47c4-9398-763eabe5c3be"
Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665"
SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6"
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
TextWrap = "b718987f-49a8-5099-9789-dcd902bef87d"

View File

@ -0,0 +1,693 @@
# Overview of Julia commands
{{< include ../_common_code.qmd >}}
```{julia}
#| echo: false
#| results: "hidden"
using CalculusWithJulia
nothing
```
The [`Julia`](http://www.julialang.org) programming language is well suited as a computer accompaniment while learning the concepts of calculus. The following overview covers the language-specific aspects of the pre-calculus part of the [Calculus with Julia](calculuswithjulia.github.io) notes.
## Installing `Julia`
`Julia` is an *open source* project which allows anyone with a supported computer to use it free of charge.
To install locally, the [downloads](https://julialang.org/downloads/) page has directions to use the `Juliaup` utility for managing an installation. There are also links to several different binaries for manual installation. Additionally, the downloads page contains a link to a docker image. `Julia` can also be compiled from source.
`Julia` can also be run through the web.
The [https://mybinder.org/](https://mybinder.org/) service in particular allows free access, though limited in terms of allotted memory and with a relatively short timeout for inactivity.
* [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/jverzani/CalculusWithJuliaBinder.jl/main?labpath=blank-notebook.ipynb) (Image without SymPy)
* [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/jverzani/CalculusWithJuliaBinder.jl/sympy?labpath=blank-notebook.ipynb) (Image with SymPy, longer to load)
[Google colab](https://colab.research.google.com/) offers a free service with more computing power than `binder`, though setup is a bit more fussy. To use `colab` along with these notes, you need to execute a command that downloads `Julia` and installs the `CalculusWithJulia` package and a plotting package. (Modify the `pkg"add ..."` command to add other desired packages; update the julia version as necessary):
```
# Installation cell
%%capture
%%shell
if ! command -v julia 3>&1 > /dev/null
then
wget -q 'https://julialang-s3.julialang.org/bin/linux/x64/1.10/julia-1.10.2-linux-x86_64.tar.gz' \
-O /tmp/julia.tar.gz
tar -x -f /tmp/julia.tar.gz -C /usr/local --strip-components 1
rm /tmp/julia.tar.gz
fi
julia -e 'using Pkg; pkg"add IJulia CalculusWithJulia; precompile;"'
julia -e 'using Pkg; Pkg.add(url="https://github.com/mth229/BinderPlots.jl")'
echo 'Now change the runtime type'
```
(The `BinderPlots` is a light-weight, barebones, plotting package that uses `PlotlyLight` to render graphics with commands mostly following those of the `Plots` package. Though suitable for most examples herein, the `Plots` package could instead be installed)
After this executes (which can take quite some time, as in a few minutes) under the `Runtime` menu select `Change runtime type` and then select `Julia`.
After that, in a cell execute these commands to load the two installed packages:
```
using CalculusWithJulia
using BinderPlots
```
As mentioned, other packages can be chosen for installation.
## Interacting with `Julia`
At a basic level, `Julia` provides an interactive means to read commands or instructions, evaluate those commands, and then print or return those commands. At a user level, there are many different ways to interact with the reading and printing. For example:
* The REPL. The `Julia` terminal is the built-in means to interact with `Julia`. A `Julia` Terminal has a command prompt, after which commands are typed and then sent to be evaluated by the `enter` key. The terminal may look something like the following where `2+2` is evaluated:
---
```{verbatim}
$ julia
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.11.1 (2024-10-16)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia> 2 + 2
4
```
---
* An IDE. For programmers, an integrated development environment is often used to manage bigger projects. `Julia` has `Juno` and `VSCode`.
* A notebook. The [Project Juptyer](https://jupyter.org/) provides a notebook interface for interacting with `Julia` and a more `IDE` style `jupyterlab` interface. A jupyter notebook has cells where commands are typed and immediately following is the printed output returned by `Julia`. The output of a cell depends on the state of the kernel when the cell is computed, not the order of the cells in the notebook. Cells have a number attached, showing the execution order. The `Juypter` notebook is used by `binder` and can be used locally through the `IJulia` package. This notebook has the ability to display many different types of outputs in addition to plain text, such as images, marked up math text, etc.
* The [Pluto](https://github.com/fonsp/Pluto.jl) package provides a *reactive* notebook interface. Reactive means when one "cell" is modified and executed, the new values cascade to all other dependent cells which in turn are updated. This is very useful for exploring a parameter space, say. Pluto notebooks can be exported as HTML files which make them easy to read online and by clever design embed the `.jl` file that can run through `Pluto` if it is downloaded.
The `Pluto` interface has some idiosyncrasies that need explanation:
* Cells can only have one command within them. Multiple-command cells must be contained in a `begin` block or a `let` block.
* By default, the cells are *reactive*. This means when a variable in one cell is changed, then any references to that variable are also updated like a spreadsheet. This is fantastic for updating several computations at once. However it means variable names can not be repeated within a page. Pedagogically, it is convenient to use variable names and function names (e.g., `x` and `f`) repeatedly, but this is only possible *if* they are within a `let` block or a function body.
* To not repeat names, but to be able to reference a value from cell-to-cell, some Unicode variants may be used within a page. Visually these look familiar, but typing the names requires some understanding of Unicode input. The primary usages is *bold italic* (e.g., `\bix[tab]` or `\bif[tab]`) or *bold face* (e.g. `\bfx[tab]` or `\bff[tab]`).
* The notebooks snapshot the packages they depend on, which is great for reproducibility, but may lead to older versions of the packages being silently used.
## Augmenting base `Julia`
The base `Julia` installation has many features, but leaves many others to `Julia`'s package ecosystem. These notes use packages to provide plotting, symbolic math, access to special functions, numeric routines, and more.
Within `Pluto`, using add-on packages is very simple, as `Pluto` downloads and installs packages when they are requested through a `using` or `import` directive.
---
For other interfaces to `Julia` some more detail is needed.
The `Julia` package manager makes add-on packages very easy to install.
Julia comes with just a few built-in packages, one being `Pkg` which manages subsequent package installation. To add more packages, we first must *load* the `Pkg` package. This is done by issuing the following command:
```{julia}
using Pkg
```
The `using` command loads the specified package and makes all its *exported* values available for direct use. There is also the `import` command which allows the user to select which values should be imported from the package, if any, and otherwise gives access to the new functionality through the dot syntax.
Packages need to be loaded just once per session.
To use `Pkg` to "add" another package, we would have a command like:
```{julia}
#| eval: false
Pkg.add("CalculusWithJulia")
```
This command instructs `Julia` to look at its *general registry* for the `CalculusWithJulia.jl` package, download it, then install it. Once installed, a package only needs to be brought into play with the `using` or `import` commands.
:::{.callout-note}
## Note
In a terminal setting, there is a package mode, entered by typing `]` as the leading character and exited by entering `<backspace>` at a blank line. This mode allows direct access to `Pkg` with a simpler syntax. The command above would be just `add CalculusWithJulia`. As well, when a package is not installed, calling `using SomePackage` will prompt the user if they wish to install the package in the current environment.)
:::
Packages can be updated through the command `Pkg.update()`, and removed with `Pkg.rm(pkgname)`.
By default packages are installed in a common area. It may be desirable to keep packages for projects isolated. For this the `Pkg.activate` command can be used. This feature allows a means to have reproducible environments even if `Julia` or the packages used are upgraded, possibly introducing incompatibilities.
For these notes, the following packages, among others, are used:
```{julia}
#| eval: false
Pkg.add("CalculusWithJulia") # for some convenience functions and a few packages (SpecialFunctions, ForwardDiff)
Pkg.add("Plots") # for basic plotting
Pkg.add("SymPy") # for symbolic math
Pkg.add("Roots") # for numerically solving `f(x)=0` and `f(x)=g(x)`
Pkg.add("QuadGk") # for 1-dimensional numeric integration
Pkg.add("HQuadrature") # for higher-dimensional integration
```
## `Julia` commands
In a `Jupyter` notebook or `Pluto` notebook, commands are typed into a notebook cell:
```{julia}
2 + 2 # use shift-enter to evaluate
```
Commands are executed by using `shift-enter` or a run button near the cell.
In `Jupyter` multiple commands per cell are allowed. In `Pluto`, a `begin` or `let` block is used to collect multiple commands into a single cell. Commands may be separated by new lines or semicolons.
On a given line, anything **after** a `#` is a *comment* and is not processed.
The results of the last command executed will be displayed in an output area. Separating values by commas allows more than one value to be displayed. Plots are displayed when the plot object is returned by the last executed command.
In `Jupyter`, the state of the notebook is determined by the cells executed along with their order. The state of a `Pluto` notebook is a result of all the cells in the notebook being executed. The cell order does not impact this and can be rearranged by the user.
## Numbers, variable types
`Julia` has many different number types beyond the floating point type employed by most calculators. These include
* Floating point numbers: `0.5`
* Integers: `2`
* Rational numbers: `1//2`
* Complex numbers `2 + 0im`
`Julia`'s parser finds the appropriate type for the value, when read in. The following all create the number $1$ first as an integer, then a rational, then a floating point number, again as floating point number, and finally as a complex number:
```{julia}
1, 1//1, 1.0, 1e0, 1 + 0im
```
As much as possible, operations involving certain types of numbers will produce output of a given type. For example, both of these divisions produce a floating point answer, even though mathematically, they need not:
```{julia}
2/1, 1/2
```
Some powers with negative bases, like `(-3.0)^(1/3)`, are not defined. However, `Julia` provides the special-case function `cbrt` (and `sqrt`) for handling these.
Integer operations may silently overflow, producing odd answers, at first glance:
```{julia}
2^64
```
(Though the output is predictable, knowing why requires understanding of how the hardware implements these operations.)
When different types of numbers are mixed, `Julia` will usually promote the values to a common type before the operation:
```{julia}
(2 + 1//2) + 0.5
```
`Julia` will first add `2` and `1//2` promoting `2` to rational before doing so. Then add the result, `5//2` to `0.5` by promoting `5//2` to the floating point number `2.5` before proceeding.
`Julia` uses a special type to store a handful of irrational constants such as `pi`. The special type allows these constants to be treated without round off, until they mix with other floating point numbers. An irrational value for `e` is not exported; the `CalculusWithJulia` exports a floating point value `e=exp(1)`.
There are some functions that require these be explicitly promoted to floating point. This can be done by calling `float`.
The standard mathematical operations are implemented by `+`, `-`, `*`, `/`, `^`. Parentheses are used for grouping.
### Vectors
A vector is an indexed collection of similarly typed values. Vectors can be constructed with square brackets (syntax for concatenation):
```{julia}
[1, 1, 2, 3, 5, 8]
```
Values will be promoted to a common type (or type `Any` if none exists). For example, this vector will have type `Float64` due to the `1/3` computation:
```{julia}
[1, 1//2, 1/3]
```
(Vectors are used as a return type from some functions, as such, some familiarity is needed.)
Other common container types are variables of vectors (higher-dimensional arrarys, offset arrays, etc.) tuples (for heterogeneous, immutable, indexed values); named tuples (which add a name to each value in a tuple); and dictionaries (for associative relationships between a key and a value).
Regular arithmetic sequences can be defined by either:
* Range operations: `a:h:b` or `a:b` which produces a generator of values starting at `a` separated by `h` (`h` is `1` in the last form) until they reach `b`.
* The `range` function: `range(a, b, length=n)` which produces a generator of `n` values between `a` and `b`;
These constructs return range objects. A range object *compactly* stores the values it references. To see all the values, they can be collected with the `collect` function, though this is rarely needed in practice.
Random sequences are formed by `rand`, among others:
```{julia}
rand(3)
```
The call `rand()` returns a single random number (in $[0,1)$.)
## Variables
Values can be assigned variable names, with `=`. There are some variants
```{julia}
u = 2
a_really_long_name = 3
a0, b0 = 1, 2 # multiple assignment
a1 = a2 = 0 # chained assignment, sets a2 and a1 to 0
```
The names can be short, as above, or more verbose. Variable names can't start with a number, but can include numbers. Variables can also include [Unicode](../misc/unicode.html) or even be an emoji.
```{julia}
α, β = π/3, π/4
```
We can then use the variables to reference the values:
```{julia}
u + a_really_long_name + a0 - b0 + α
```
Within `Pluto`, names are idiosyncratic: within the global scope, only a single usage is possible per notebook; functions and variables can be freely renamed; structures can be redefined or renamed; ...
Outside of `Pluto`, names may be repurposed, even with values of different types (`Julia` is a dynamic language), save for (generic) function names, which have some special rules and can only be redefined as another method for the function. Generic functions are central to `Julia`'s design. Generic functions use a method table to dispatch on, so once a name is assigned to a generic function, it can not be used as a variable name; the reverse is also true.
## Functions
Functions in `Julia` are first-class objects. In these notes, we often pass them as arguments to other functions. There are many built-in functions and it is easy to define new functions.
We "call" a function by passing argument(s) to it, grouped by parentheses:
```{julia}
sqrt(10)
sin(pi/3)
log(5, 100) # log base 5 of 100
```
Without parentheses, the name (usually) refers to a generic name and the output lists the number of available implementations (methods).
```{julia}
log
```
### Built-in functions
`Julia` has numerous built-in [mathematical](https://docs.julialang.org/en/v1/manual/mathematical-operations/) functions, we review a few here:
#### Powers logs and roots
Besides `^`, there are `sqrt` and `cbrt` for powers. In addition basic functions for exponential and logarithmic functions:
```
sqrt, cbrt
exp
log # base e
log10, log2, # also log(b, x)
```
#### Trigonometric functions
The `6` standard trig functions are implemented; their implementation for degree arguments; their inverse functions; and the hyperbolic analogs.
```
sin, cos, tan, csc, sec, cot
asin, acos, atan, acsc, asec, acot
sinh, cosh, tanh, csch, sech, coth
asinh, acosh, atanh, acsch, asech, acoth
```
If degrees are preferred, the following are defined to work with arguments in degrees:
```
sind, cosd, tand, cscd, secd, cotd
```
#### Useful functions
Other useful and familiar functions are defined:
* `abs`: absolute value
* `sign`: is $\lvert x \rvert/x$ except at $x=0$, where it is $0$.
* `floor`, `ceil`: greatest integer less or least integer greater
* `max(a,b)`, `min(a,b)`: larger (or smaller) of `a` or `b`
* `maximum(xs)`, `minimum(xs)`: largest or smallest of the collection referred to by `xs`
---
In a Pluto session, the "Live docs" area shows inline documentation for the current object.
For other uses of `Julia`, the built-in documentation for an object is accessible through a leading `?`, say, `?sign`. There is also the `@doc` macro, for example:
```{julia}
#| eval: false
@doc sign
```
---
### User-defined functions
Simple mathematical functions can be defined using standard mathematical notation:
```{julia}
f(x) = -16x^2 + 100x + 2
```
The argument `x` is passed into the body of function.
Other values are found from the environment where defined:
```{julia}
#| hold: true
a = 1
f(x) = 2*a + x
f(3) # 2 * 1 + 3
a = 4
f(3) # now 2 * 4 + 3
```
User-defined functions can have $0$, $1$ or more positional arguments:
```{julia}
area(w, h) = w*h
```
Julia makes different *methods* for *generic* function names, so function definitions whose argument specification is different are for different uses, even if the name is the same. This is *polymorphism*. The practical use is that it means users need only remember a much smaller set of function names, as attempts are made to give common expectations to the same name. (That is, `+` should be used only for "add" ing objects, however defined.)
Functions can also be defined with *keyword* arguments that may have defaults specified:
```{julia}
#| hold: true
f(x; m=1, b=0) = m*x + b # note ";"
f(1) # uses m=1, b=0 -> 1 * 1 + 0
f(1, m=10) # uses m=10, b=0 -> 10 * 1 + 0
f(1, m=10, b=5) # uses m=10, b=5 -> 10 * 1 + 5
```
Keyword arguments are not considered for dispatch.
Longer functions can be defined using the `function` keyword, the last command executed is returned:
```{julia}
function f(x)
y = x^2
z = y - 3
z
end
```
Functions without names, *anonymous functions*, are made with the `->` syntax as in:
```{julia}
x -> cos(x)^2 - cos(2x)
```
These are useful when passing a function to another function or when writing a function that *returns* a function.
## Conditional statements
`Julia` provides the traditional `if-else-end` statements, but more conveniently has a `ternary` operator for the simplest case:
```{julia}
our_abs(x) = (x < 0) ? -x : x
```
## Looping
Iterating over a collection can be done with the traditional `for` loop. However, there are list comprehensions to mimic the definition of a set:
```{julia}
[x^2 for x in 1:10]
```
Comprehensions can be filtered through the `if` keyword
```{julia}
[x^2 for x in 1:10 if iseven(x)]
```
This is more efficient than creating the collection then filtering, as is done with:
```{julia}
filter(iseven, [x^2 for x in 1:10])
```
## Broadcasting, mapping
A function can be applied to each element of a vector through mapping or broadcasting. The latter is implemented in a succinct notation. Calling a function with a "." before its opening "(" will apply the function to each individual value in the argument:
```{julia}
xs = [1,2,3,4,5]
sin.(xs) # gives back [sin(1), sin(2), sin(3), sin(4), sin(5)]
```
For "infix" operators, the dot precedes the operator, as in this example instructing pointwise multiplication of each element in `xs`:
```{julia}
xs .* xs
```
Alternatively, the more traditional `map` can be used:
```{julia}
map(sin, xs)
```
## Plotting
Plotting is *not* built-in to `Julia`, rather added through add-on packages. `Julia`'s `Plots` package is an interface to several plotting packages. We mention `plotly` (built-in) for web based graphics, `pyplot`, and `gr` (also built into `Plots`) for other graphics.
We must load `Plots` before we can plot (and it must be installed before we can load it):
```{julia}
using Plots
plotly() # optionally change the backend from the default
```
With `Plots` loaded, we can plot a function by passing the function object by name to `plot`, specifying the range of `x` values to show, as follows:
```{julia}
plot(sin, 0, 2pi) # plot a function - by name - over an interval [a,b]
```
::: {.callout-note}
This is in the form of **the** basic pattern employed: `verb(function_object, arguments...)`. The verb in this example is `plot`, the object `sin`, the arguments `0, 2pi` to specify `[a,b]` domain to plot over.
:::
Plotting more than one function over `[a,b]` is achieved through the `plot!` function, which modifies the existing plot (`plot` creates a new one) by adding a new layer:
```{julia}
plot(sin, 0, 2pi)
plot!(cos, 0, 2pi)
plot!(zero, 0, 2pi) # add the line y=0
```
(There are alternatives to plot functions or other traces all at once.)
Individual points are added with `scatter` or `scatter!`:
```{julia}
plot(sin, 0, 2pi, legend=false)
plot!(cos, 0, 2pi)
scatter!([pi/4, pi+pi/4], [sin(pi/4), sin(pi + pi/4)])
```
(The extra argument `legend=false` suppresses the automatic legend drawing. There are many other useful keyword arguments to adjust attributes of a trace of a graphic. For example, passing `markersize=10` to the `scatter!` command would draw the points larger than the default.)
Plotting an *anonymous* function is a bit more immediate than the two-step approach of defining a named function then calling `plot` with this as an argument:
```{julia}
plot( x -> exp(-x/pi) * sin(x), 0, 2pi)
```
The `scatter!` function used above takes two vectors of values to describe the points to plot, one for the $x$ values and one for the matching $y$ values. The `plot` function can also produce plots with this interface. For example, here we use a comprehension to produce `y` values from the specified `x` values:
```{julia}
#| hold: true
xs = range(0, 2pi, length=251)
ys = [sin(2x) + sin(3x) + sin(4x) for x in xs]
plot(xs, ys)
```
There are different plotting interfaces. Though not shown, all of these `plot` commands produce a plot of `f`, though with minor differences:
```{julia}
#| eval: false
xs = range(a, b, length=251)
ys = f.(xs)
plot(f, a, b) # recipe for a function
plot(xs, f) # alternate recipe
plot(xs, ys) # plot coordinates as two vectors
plot([(x,f(x)) for x in xs]) # plot a vector o points
```
The choice should depend on convenience.
## Equations
Notation for `Julia` and math is *similar* for functions - but not for equations. In math, an equation might look like:
$$
x^2 + y^2 = 3
$$
In `Julia` the equals sign is **only** for *assignment* and *mutation*. The *left-hand* side of an equals sign in `Julia` is reserved for a) variable assignment; b) function definition (via `f(x) = ...`); c) indexed mutation of a vector or array; d) mutation of fields in a structure. (Vectors are indexed by a number allowing retrieval and mutation of the stored value in the container. The notation mentioned here would be `xs[2] = 3` to mutate the 2nd element of `xs` to the value `3`.
## Symbolic math
Symbolic math is available through an add-on package `SymPy` (among others). Once loaded, symbolic variables in `SymPy` are created with the macro `@syms`:
```{julia}
using SymPy
```
```{julia}
@syms x a b c
```
(A macro rewrites values into other commands before they are interpreted. Macros are prefixed with the `@` sign. In this use, the "macro" `@syms` translates `x a b c` into a command involving `SymPy`s `symbols` function.)
Symbolic expressions - unlike numeric expressions - are not immediately evaluated, though they may be simplified:
```{julia}
p = a*x^2 + b*x + c
```
To substitute a value, we can use `Julia`'s `pair` notation (`variable=>value`):
```{julia}
p(x=>2), p(x=>2, a=>3, b=>4, c=>1)
```
This is convenient notation for calling the `subs` function for `SymPy`.
SymPy expressions of a single free variable can be plotted directly:
```{julia}
plot(64 - (1/2)*32 * x^2, 0, 2)
```
* SymPy has functions for manipulating expressions: `simplify`, `expand`, `together`, `factor`, `cancel`, `apart`, $...$
* SymPy has functions for basic math: `factor`, `roots`, `solve`, `solveset`, $\dots$
* SymPy has functions for calculus: `limit`, `diff`, `integrate`, $\dots$

View File

@ -26,7 +26,7 @@ On top of these, we have special subsets, such as the natural numbers $\{1, 2, \
Mathematically, these number systems are naturally nested within each other as integers are rational numbers which are real numbers, which can be viewed as part of the complex numbers.
Calculators typically have just one type of number - floating point values. These model the real numbers. `Julia`, on the other hand, has a rich type system, and within that has many different number types. There are types that model each of the four main systems above, and within each type, specializations for how these values are stored.
Calculators typically have just one type of number - floating point values. These model the real numbers. `Julia`, on the other hand, has a rich type system, and within that has serveral different number types. There are types that model each of the four main systems above, and within each type, specializations for how these values are stored.
Most of the details will not be of interest to all, and will be described later.