Riassunto della puntata precedente che trovate nel post "Io, ChatGPT e Lorenza": stimolato da qualche domanda, chiedo a ChatGPT di risolvere un esercizio semplice da compito. Il celebre programma di Intelligenza Artificiale lo risolve in un attimo, spiegando pure i passaggi con sicumera, ma è tutto sbagliato e ChatGPT non si ravvede nemmeno quando provo ad aiutarlo... bocciato senza appello!
Non so nulla di julia, un linguaggio di programmazione che ha il nome della mia criminologa preferita e di cui sento dire meraviglie, con tanto di commenti sul web e discorsi di amici che si spingono a dire che sarebbe ottimo anche per scrivere modelli ad agenti. Eppure, vista la desolante performance di un tentativo di ChatGPT di risolvere l'equazione x^3+x+1=0, una roba standard e fattibile che uso in ogni compito tanto per scaldare i muscoli ai miei studenti, decido di partire da zero: ce la faccio con julia a trovare la soluzione, anche se non so nulla e non ho nemmeno il programma?
Sono le 13.26 e attacco con zio google per trovare l'installer, individuo subito vari siti molto ben fatti con quanto serve e parecchia documentazione. Scarico, doppio click e vedo sul terminal lo splash screen di benvenuto, a metà fra la preistoria dell'interfaccia testuale (che sempre sia lodata, per altro!) e la scelta accattivante dei colori. Due secondi e due righe dopo ho definito la mia funzione e tanto per gradire provo a vedere se tutto funziona con f(1), che produce 3, e f(-0.62)=0.141672, non lontano da zero. Chi ben comincia è già a metà dell'opera.
Altro giro per digitare la stringa di ricerca "solving equation julia" e "solving equation julia one variable", imbattendomi in una bella lista di pagine che spesso mi suggeriscono di utilizzare NLsolve o nlsolve. A dir la verità, leggendo due righe di esempio alla massima velocità, vedo che lo usano per risolvere sistemi di equazioni, anche troppa grazia visti che a me servirebbe qualcosa di più semplice, nella sola variabile x. Pesto sulla tastiera:
julia> using NLsolve│ Attempted to find missing packages in package registries but no registries are installed.└ Use package mode to install a registry. `pkg> registry add` will install the default registries.ERROR: ArgumentError: Package NLsolve not found in current path.- Run `import Pkg; Pkg.add("NLsolve")` to install the NLsolve package.Stacktrace:[1] macro expansion@ ./loading.jl:1163 [inlined][2] macro expansion@ ./lock.jl:223 [inlined][3] require(into::Module, mod::Symbol)@ Base ./loading.jl:1144julia> nlsolve(f,[-2,-1])ERROR: UndefVarError: nlsolve not definedStacktrace:[1] top-level scope
julia> import Pkg; Pkg.add("NLsolve")Installing known registries into `~/.julia`Updating registry at `~/.julia/registries/General.toml`Resolving package versions...Installed IrrationalConstants ── v0.2.2Installed DiffRules ──────────── v1.13.0Installed DiffResults ────────── v1.1.0Installed Adapt ──────────────── v3.6.1Installed Setfield ───────────── v1.1.1Installed NLsolve ────────────── v4.5.1Installed SpecialFunctions ───── v2.2.0Installed Preferences ────────── v1.4.0Installed NaNMath ────────────── v1.0.2Installed StaticArrays ───────── v1.5.24Installed StaticArraysCore ───── v1.4.0Installed OrderedCollections ─── v1.6.0Installed ConstructionBase ───── v1.5.2Installed SnoopPrecompile ────── v1.0.3Installed JLLWrappers ────────── v1.4.1Installed ChainRulesCore ─────── v1.15.7Installed NLSolversBase ──────── v7.8.3Installed Reexport ───────────── v1.2.2Installed Requires ───────────── v1.3.0Installed LogExpFunctions ────── v0.3.23Installed ArrayInterface ─────── v7.4.3Installed LineSearches ───────── v7.2.0Installed ForwardDiff ────────── v0.10.35Installed CommonSubexpressions ─ v0.3.0Installed MacroTools ─────────── v0.5.10Installed OpenSpecFun_jll ────── v0.5.5+0Installed StatsAPI ───────────── v1.6.0Installed UnPack ─────────────── v1.0.2Installed InverseFunctions ───── v0.1.9Installed Compat ─────────────── v4.6.1Installed Parameters ─────────── v0.12.3Installed Distances ──────────── v0.10.8Installed ChangesOfVariables ─── v0.1.7Installed FiniteDiff ─────────── v2.20.0Installed DocStringExtensions ── v0.9.3Downloaded artifact: OpenSpecFunUpdating `~/.julia/environments/v1.8/Project.toml`[2774e3e8] + NLsolve v4.5.1Updating `~/.julia/environments/v1.8/Manifest.toml`[79e6a3ab] + Adapt v3.6.1[4fba245c] + ArrayInterface v7.4.3[d360d2e6] + ChainRulesCore v1.15.7[9e997f8a] + ChangesOfVariables v0.1.7[bbf7d656] + CommonSubexpressions v0.3.0[34da2185] + Compat v4.6.1[187b0558] + ConstructionBase v1.5.2[163ba53b] + DiffResults v1.1.0[b552c78f] + DiffRules v1.13.0[b4f34e82] + Distances v0.10.8[ffbed154] + DocStringExtensions v0.9.3[6a86dc24] + FiniteDiff v2.20.0[f6369f11] + ForwardDiff v0.10.35[3587e190] + InverseFunctions v0.1.9[92d709cd] + IrrationalConstants v0.2.2[692b3bcd] + JLLWrappers v1.4.1[d3d80556] + LineSearches v7.2.0[2ab3a3ac] + LogExpFunctions v0.3.23[1914dd2f] + MacroTools v0.5.10[d41bc354] + NLSolversBase v7.8.3[2774e3e8] + NLsolve v4.5.1[77ba4419] + NaNMath v1.0.2[bac558e1] + OrderedCollections v1.6.0[d96e819e] + Parameters v0.12.3[21216c6a] + Preferences v1.4.0[189a3867] + Reexport v1.2.2[ae029012] + Requires v1.3.0[efcf1570] + Setfield v1.1.1[66db9d55] + SnoopPrecompile v1.0.3[276daf66] + SpecialFunctions v2.2.0[90137ffa] + StaticArrays v1.5.24[1e83bf80] + StaticArraysCore v1.4.0[82ae8749] + StatsAPI v1.6.0[3a884ed6] + UnPack v1.0.2[efe28fd5] + OpenSpecFun_jll v0.5.5+0[0dad84c5] + ArgTools v1.1.1[56f22d72] + Artifacts[2a0f44e3] + Base64[ade2ca70] + Dates[8ba89e20] + Distributed[f43a241f] + Downloads v1.6.0[7b1f6079] + FileWatching[9fa8497b] + Future[b77e0a4c] + InteractiveUtils[b27032c2] + LibCURL v0.6.3[76f85450] + LibGit2[8f399da3] + Libdl[37e2e46d] + LinearAlgebra[56ddb016] + Logging[d6f4376e] + Markdown[ca575930] + NetworkOptions v1.2.0[44cfe95a] + Pkg v1.8.0[de0858da] + Printf[3fa0cd96] + REPL[9a3f8284] + Random[ea8e919c] + SHA v0.7.0[9e88b42a] + Serialization[6462fe0b] + Sockets[2f01184e] + SparseArrays[10745b16] + Statistics[4607b0f0] + SuiteSparse[fa267f1f] + TOML v1.0.0[a4e569a6] + Tar v1.10.1[8dfed614] + Test[cf7118a7] + UUIDs[4ec0a83e] + Unicode[e66e0078] + CompilerSupportLibraries_jll v1.0.1+0[deac9b47] + LibCURL_jll v7.84.0+0[29816b5a] + LibSSH2_jll v1.10.2+0[c8ffd9c3] + MbedTLS_jll v2.28.0+0[14a3606d] + MozillaCACerts_jll v2022.2.1[4536629a] + OpenBLAS_jll v0.3.20+0[05823500] + OpenLibm_jll v0.8.1+0[83775a58] + Zlib_jll v1.2.12+3[8e850b90] + libblastrampoline_jll v5.1.1+0[8e850ede] + nghttp2_jll v1.48.0+0[3f19e933] + p7zip_jll v17.4.0+0Precompiling project...42 dependencies successfully precompiled in 42 seconds
- Think Julia: How to Think Like a Computer Scientist"; e
- La pagina https://github.com/mitmath/julia-mit è zeppa di bella roba, inlcuso il cheatsheet che mi sono già stampato;
- L'esempio vincente che ho usato per risolvere un'equazione in una variabile l'ho trovato qui;
- La pagina precedente menzionava anche Roots.jl e NonlinearSolve.jl. Studiando meglio le cose, si trovano metodi risolutivi più semplici ed efficaci di quello che ho usato io. Dopo aver guardato Roots.jl ho capito che bastava molto meno...
julia> using Roots
│ Package Roots not found, but a package named Roots is available from a
│ registry.
│ Install package?
│ (@v1.8) pkg> add Roots
└ (y/n/o) [y]: y
Resolving package versions...
Installed Roots ─────── v2.0.14
Installed CommonSolve ─ v0.2.3
Updating `~/.julia/environments/v1.8/Project.toml`
[f2b01f46] + Roots v2.0.14
Updating `~/.julia/environments/v1.8/Manifest.toml`
[38540f10] + CommonSolve v0.2.3
[f2b01f46] + Roots v2.0.14
Precompiling project...
2 dependencies successfully precompiled in 8 seconds. 42 already precompiled.
julia> find_zero(f,0)
-0.6823278038280193
julia> f(x) = x^3+x+1
f (generic function with 1 method)
julia> find_zero(f,0)
-0.6823278038280193
julia>
- Se siete appassionati di analisi numerica (che è dove "sono nato" io!), il libro di Giray Otken "First semester in numerical analysis with julia" è anche la scusa per imparare il linguaggio (se andate sulla pagina, cliccate sui pulsanti a ds per vedere o scaricare il pdf).