From 689d2c8902f16fa460804847e9d3143a30cdc8f7 Mon Sep 17 00:00:00 2001 From: john verzani Date: Thu, 25 Apr 2024 21:50:40 -0400 Subject: [PATCH] Lim (#66) * different display for lim * one more tweak * doc string update --- Project.toml | 2 +- src/limits.jl | 145 +++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 114 insertions(+), 33 deletions(-) diff --git a/Project.toml b/Project.toml index ec7eb6f..184f0c3 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "CalculusWithJulia" uuid = "a2e0e22d-7d4c-5312-9169-8b992201a882" -version = "0.2.2" +version = "0.2.3" [deps] Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" diff --git a/src/limits.jl b/src/limits.jl index 2e5a2c5..b2fdc2d 100644 --- a/src/limits.jl +++ b/src/limits.jl @@ -1,20 +1,41 @@ """ - lim(f, c; n=5, dir="+") + lim(f, c; n=6, m=1, dir="+-") lim(f, c, dir; n-5) Means to generate numeric table of values of `f` as `h` gets close to `c`. +* `n`, `m`: powers of `10` to add (subtract) to (from) `c`. +* `dir`: Either `"+-"` (show left and right), `"+"` (right limit), or `"-"` (left limit). Can also use functions `+`, `-`, `±`. + Example: + ``` -f(x) = sin(x) / x -lim(f, 0) +julia> f(x) = sin(x) / x +f (generic function with 1 method) + +julia> lim(f, 0) + 0.1 0.9983341664682815 + 0.01 0.9999833334166665 + 0.001 0.9999998333333416 + 0.0001 0.9999999983333334 + 1.0e-5 0.9999999999833332 + 1.0e-6 0.9999999999998334 + ⋮ ⋮ + c L? + ⋮ ⋮ +-1.0e-6 0.9999999999998334 +-1.0e-5 0.9999999999833332 +-0.0001 0.9999999983333334 +-0.001 0.9999998333333416 +-0.01 0.9999833334166665 +-0.1 0.9983341664682815 ``` """ -function lim(f::Function, c::Real; n::Int=6, m::Int=1, dir="+") +function lim(f::Function, c::Real; n::Int=6, m::Int=1, dir="+-") dir = string(dir) Limit(f, c, n, m, dir) end -lim(f::Function, c::Real, dir; n::Integer=5, m::Integer=1) = lim(f,c; n, m, dir=string(dir)) +lim(f::Function, c::Real, dir; n::Int=6, m::Int=1) = lim(f,c; n, m, dir=string(dir)) struct Limit{F,R} @@ -26,41 +47,101 @@ struct Limit{F,R} end # try to better align numbers +_l8(x) = length(string(x)) ÷ 8 + function Base.show(io::IO, L::Limit) (; f,c,n,m,dir) = L + + ms = maximum(length ∘ string, (c-1/10^n, c+1/10^n)) + sc = (sign(c-m) * sign(c+m) < 0) + + h = 1/10^n + nt = 2 + maximum(_l8, (c-h, c+h)) + (n ÷ 8) + + if dir == "+" || dir == "+-" || dir == "±" + show₊(io, L; sc, ms) + end + print_dots(io, "c", "L?"; sc, ms) + if dir == "-" || dir == "--" || dir == "+-" || dir == "±" + show₋(io, L; sc, ms) + end + nothing +end + +function show₊(io::IO, L::Limit; sc=false, ms=0) + + (; f,c,n,m,dir) = L + hs = [1/10^i for i in m:n] # close to 0 - if dir == "+" - xs = c .+ hs - else - xs = c .- hs + xsᵣ = c .+ hs + ysᵣ = string.(f.(xsᵣ)) + + last_y = nothing + + for (x,y) ∈ zip(xsᵣ, ysᵣ) + print_next(io, x, y, last_y; sc, ms) + last_y = y + println(io, "") end - ys = string.(map(f, xs)) - _l8(x) = length(string(x)) ÷ 8 - nt = 2 + _l8(first(xs)) + (n ÷ 8) - nl = false + print_dots(io; sc, ms) +end + +# show - case +function show₋(io::IO, L::Limit; sc=false, ms=0) + (; f,c,n,m,dir) = L + + hs = [1/10^i for i in n:-1:m] # close to 0 + xsₗ = c .- hs + ysₗ = string.(f.(xsₗ)) + last_y = nothing - for (x,y) ∈ zip(xs, ys) - nl && println(io, "") - nl = true - print(io, x) - m = _l8(x) - print(io, "\t"^(nt-m)) - if isnothing(last_y) - print(io, y) + + i, l = 1, length(ysₗ) + nl = true + #dir == "-" && print_dots(io; sc, ms) + print_dots(io; sc, ms) + for (x, y) ∈ zip(xsₗ, ysₗ) + if i == l + last_y = nothing + nl = false else - flag = true - ly = length(last_y) - for (i,yᵢ) ∈ enumerate(y) - if flag && i <= ly && yᵢ == last_y[i] - printstyled(io, yᵢ; bold=true) - else - print(io, yᵢ) - flag=false - end + last_y = ysₗ[i+1] + i += 1 + end + print_next(io, x, y, last_y; sc, ms) + nl && println(io, "") + end + +end + +# print dots or c L +function print_dots(io::IO, l="⋮", r="⋮"; sc, ms) + d = ms ÷ 2 + println(io, " "^d, l, " "^(4 +2d), r) +end + + +# print next number referring to last one for styling +function print_next(io::IO, x, y, last_y=nothing; sc=false, ms=0) + xₛ = string(x) + sc && x > 0 && (xₛ = " " * xₛ) + + print(io, xₛ) + l = length(xₛ) + print(io, " "^(ms - l + 5)) + if isnothing(last_y) + print(io, y) + else + flag = true + ly = length(last_y) + for (i,yᵢ) ∈ enumerate(y) + if flag && i <= ly && yᵢ == last_y[i] + printstyled(io, yᵢ; bold=true) + else + print(io, yᵢ) + flag=false end end - last_y = y end - nothing end