0 Introduzione A write B br_\n C abs_max_min_pow_round_sqrt_PI_E_writeln D for_if E {_}_; F if_==_&&_!_!=_|| G cambio_dati H for_inscatolati I function_approssimare J sequenze_length_parole_e K istogrammi L disegni M for/for N tabella_array O while_else P cbrt_sign_ceil_floor_cos_sin_tan_acos_asin_atan_log10_log2_log_random p0 probabilità p1 serie p2 produttoria p3 distanza p4 triangoli p5 equazioni 2º3ºgrado
p6 bisezione p7 p8 tabulazione_max_min p9 combinazioni_binomiale p10 integrazione p11 ricorsione p12 regressione p13 data_appunti
Nelle pagine Internet come questa si possono inserire procedimenti di calcolo ("programmi") che consentono di fare elaborazioni di vario tipo. Questi procedimenti si chiamano "script". È il modo di realizzare programmi (in inglese chiamato anche coding) più usato. Vediamo degli esempi, alcuni accessibili sin dalla scuola di base. Si possono aprire contemporaneamente più sessioni di macosa.dima.unige.it/js.com. Una volta che hai realizzato un programma, non cliccare "Aggiorna" (Ctrl+R) se non vuoi perdere il documento (eventualmente prima copialo o apri un'altra sessione). Per script già redatti, usabili a "scatola nera", vedi qui; in particolare, per la scuola di base, vedi: come si disegna col computer, un gioco e questi.
A partire da questo esempio è facile inserire delle modifiche per realizzare altri programmi.
Puoi anche copiare quanto segue provando a mettere al posto di ... le righe di programma e togliendo "$" (o altro simbolo che hai usato)
per eseguirlo, ed eventualmente rimettendo "$" per apportare nuove modifiche prima di rieseguirlo (togliendo "$").
<pre><script> with(Math) {$...} </script></pre>
[Il programma è racchiuso tra <script> e </script>.
I comandi <pre> e </pre> fanno sì che il testo sia scritto in un formato prestabilito, che riservi lo stesso spazio ad ogni carattere. "document.write" fa scrivere quello che segue, indicato tra parentesi. "with(Math)" fa sì che siano inseribili delle operazioni matematiche, come quelle indicate più avanti, in C, in questo documento] A) Esempio: il calcolo di
(3/4 + 7.5 + 0.25 - 5/2)·(3/2 + 7/10 - 1/2 + 4.3) Copia e incolla:
C) Alcune delle operazioni inseribili: +-*/abs(K) valore assoluto di K,max(H,K) il massimo tra H e K,min(H,K) il minimo tra H e K,pow(H,K) H alla K,round(H) l'intero più vicino ad H,sqrt(H) la radice quadrata di H. PI indica π (di cui 3.141592653589793 è un arrotondamento), E indica il numero di Nepero (in genere indicato con e, di cui
2.718281828459045 è un arrotondamento).
Per arrotondare x = 12345.6789 ai centesimi si può usare round(x*100)/100, alle migliaia round(x*0.001)/0.001
Un esempio di calcoli, in cui viene usato writelnche dopo la stampa fa un "a capo" ("ln" sta per "line").
i = 1
|
scrivi i*2 <
| |
i = i + 1 |
| |
i < 10 ? SI'
|
| NO
|
STOP
Compare un ciclo for: il ciclo viene eseguito a partire dal valore assegnato
alla "variabile contatore" (in questo esempio "i") fino a che vale la condizione
indicata (i<10); "i=i+1" indica come viene modificata
la variabile contatore ad ogni fine ciclo;
l'istruzione che viene ripetuta èdocument.write( i*2," " )che fa scrivere il valore di i*2
seguito da " ", ossia uno spazio bianco.
Se invece di document.write(i*2," ") avessimo scritto document.writeln(i*2) avremmo ottenuto: 2 4 ... 18
Che cosa calcola il seguente programma se metti in A un numero qualunque e in N un numero naturale? Prova con un po' di valori di A e di N.
<pre><script> with(Math) {
A = 2; N = 3
P=1
for(i=0; i<=N; i=i+1) P = P*A
document.write( P )
} </script></pre>
leggi A
leggi N
poni P = 1
poni I = 0
| si'
----> I = N ? -------> scrivi P
| | no
| poni P = P*A
| poni I = I+1
| |
--------
La somma di due numeri naturalicomunque lunghi, avendo messo le cifre in due sequenze (usando un ciclo for
"decrescente" e una istruzione if, in cui "uguale" si scrive "=="):
avremmo ottenuto: -3 3 -3 3 -3 3 -3 3 -3
Le istruzioni del ciclo ora sono due; sono messe tra parentesi graffe e separate da ";".
F) Un'altra istruzione utile è if
Abbiamo visto che in una istruzione if "uguale" si scrive "=="; "e" si scrive "&&"; "not" si scrive "!";
"diverso" si scrive "!="; "o" (non esclusivo) si scrive "||".
Compaiono due cicli for, uno inscatolato nell'altro: il ciclo "i" stampa le righe;
ogni riga è stampata da un ciclo "j"; il primodocument.write(" ")scrive uno
spazio bianco prima del numero se questo ha una sola cifra; ildocument.write(" ")finale
scrive lo spazio bianco che separa un numero dal successivo; usciti dal ciclo
inscatolato,document.write("<br>")genera l'"a capo" tra una riga e la successiva.
Con piccole modifiche (quali?) viene prodotta una tabellina con più numeri:
Posso definire una funzione richiamabile da altre. Ad esempio una funzione per arrotondare alla n-esima cifra dopo il ".": function APPR(x,n) {return round(x*pow(10,n))/pow(10,n)}
<pre><script> with(Math) {function APPR(x,n) {return round(x*pow(10,n))/pow(10,n)}
function F(x) { return pow(x,5)+6*pow(x,3)+x/7 }
x = 3; document.writeln( "x=",x, " -> ",F(x) )
x = 3; document.writeln( "x=",x, " -> ",APPR(F(x),10) )
x = 3; document.writeln( "x=",x, " -> ",APPR(F(x),5) )
x = 3; document.writeln( "x=",x, " -> ",APPR(F(x),0) )
x = 3; document.writeln( "x=",x, " -> ",APPR(F(x),-1) )
x = 3; document.writeln( "x=",x, " -> ",APPR(F(x),-2) )} </script></pre>
J) La media (e somma, min, max) di unasequenzadi dati
<pre><script> with(Math) {n=5; A = [172,169,183,181,167]
min=A[0]; max=A[0]
S = 0; for(i=0; i<n; i=i+1) {S = S+A[i]; if(A[i]>max) max=A[i]; if(A[i]<min) min=A[i]}
document.write ("la somma di ",A," e' ", S, "<br>")
document.write ("la media e' ",S,"/",n, " = ", S/n,"<br>")
document.write ("min = ",min," max = ",max )
} </script></pre>
n = 5
|
A[0] = 172, A[1] = 169, A[2] = 183, A[3] = 181, A[4] = 167
|
min = A[0], max = A[0], SOMMA = 0
|
i = 0
|
SOMMA = SOMMA + A[i] <
| |
se A[i] > max prendi max = A[i] |
| |
se A[i] < min prendi min = A[i] |
| |
i = i + 1 |
| |
i < n ? SI'
|
| NO
|
scrivi i valori di SOMMA, SOMMA/n, min, max
|
STOP
Uscite:
la somma di 172,169,183,181,167 e' 872
la media e' 872/5 = 174.4
min = 167 max = 183
Alternativa, usando "length" (lunghezza), con le stesse uscite:
<pre><script> with(Math) {A = [172,169,183,181,167]
n = A.length; min = A[0]; max = A[0]
S = 0; for(i=0; i<n; i=i+1) {S = S+A[i]; if(A[i]>max) max=A[i]; if(A[i]<min) min=A[i]}
document.write ("la somma di ",A," e' ", S, "<br>")
document.write ("la media e' ",S,"/",n, " = ", S/n,"<br>")
document.write ("min = ",min," max = ",max )
} </script></pre>
Posso ordinare anche le parole:
<pre><script> with(Math) {A = ["casa", "pino", "cielo", "zio", "aria"]
n = A.length; min = A[0]; max = A[0]
for(i=0; i<n; i=i+1) {if(A[i]>max) max=A[i]; if(A[i]<min) min=A[i]}
document.write ("min = ",min ," max = ", max )
} </script></pre>
Uscita: min = aria max = zio
Non solo "minimo" e "massimo", ma l'ordinamento completo
n = 260 min = 1 max = 2.3
mediana = 1.65 1^ quarto = 1.55 3^ quarto = 1.75
media = 1.6592307692307673
Il 50% centrale dei dati ordinati cade nell'intervallo [1.55 cm, 1.75 cm]
K) Diagrammi a barre / istogrammi:
<pre><script> with(Math) {dati = [127,585,430,1256,148]
n = dati.length
totale = 0; for(i=0; i<n; i=i+1) totale = totale+dati[i]
document.write(dati); document.write(" ISTOGRAMMA:\n\n")
for(i=0; i<n; i=i+1) { p = round(dati[i]/totale*150);
for(k=1; k<=p; k=k+1) document.write("#");
document.write(" ",dati[i],"\n") }
} </script></pre>
N) In questo esempio l'utente deve preoccuparsi di gestire solo l'assegnazione a "vai",
per comandare gli spostamenti, a Destra, Sinistra, in Alto e in Basso di "0", come il movimento di una biscia. Come negli altri casi l'utente può modificare via via l'input, vedendo immediatamente i cambiamentti nelle uscite. Le righe successive sono comprensibili
dai ragazzi più grandi: viene costruita una tabella (array, in inglese) 50×50 in cui
sono contenuti per ogni colonna e ogni riga i caratteri da far apparrire sullo schermo: "0" o " " (ossia un carattere spazio bianco).
<pre><script> with(Math) {D=1; S=2; A=3; B=4
vai = [D,D,D,D,D,D,D,D,D,D,D,D,B,B,B,B,B,B,B,B,B,S,S,S,S,S,S,S,S,S,S,S,
A,A,A,A,A,A,A,D,D,D,D,D,D,D,D,B,B,B,B,B,S,S,S,S,S,S,A,A,A,D,D,D,D,B]
var T = new Array(50);
for (i=0; i<50; i=i+1) {T[i]=new Array(50)}
for (i=0; i<50; i=i+1) {for(j=0; j<50; j=j+1) T[i][j]=" "}
n = vai.length; u=0; v=0
for(i=0; i<n; i=i+1) {
if(vai[i] == D) {v=v+1; T[u][v]=0}
if(vai[i] == S) {v=v-1; T[u][v]=0}
if(vai[i] == A) {u=u-1; T[u][v]=0}
if(vai[i] == B) {u=u+1; T[u][v]=0}
}
for (i=0; i<50;i=i+1) {for(j=0; j<50; j=j+1) {document.write(T[i][j]); if(j==49) document.write("<br>")} }
} </script></pre>
O) Un'istruzione comoda (non banale per le prime classi) è while ("fin tanto che"). Un esempio: la scomposizione di un numero intero positivo in fattori primi:
P) Esempi vari
Ricordiamo, innanzi tutto, i nomi di altre funzioni (di a) utilizzabili oltre a quelle richiamate in C): cbrt(a) radice cubica,
sign(a) segno (-1, 1 o 0),
ceil(a) intero vicino non < a,
floor(a) intero vicino non > a,
cos(a) coseno,
sin(a) seno,
tan(a) tangente,
acos(a) arcocoseno,
asin(a) arcoseno,
atan(a) arcotangente,
log10(a) logaritmo in base 10,
log2(a) logaritmo in base 2,
log(a) logaritmo naturale,
random() numero a caso tra 0 ed 1.
p0)
Per generare l'uscita casuale di un dado equo si può usare floor(random()*6+1).
Per generare l'uscita di un generico numero tra 3 e 7 si può usare random()*(7-3)+3. Esempio:
(teoricamente troverei che i casi possibili sono 6*6 = 36 e quelli buoni sono 10, e 10/36 = 5/18 = 0.2777 )
Volendo quantificare la precisione della stima sperimentale (mediante un intervallo in cui al 99.7% cade la probabilità) si può usare l'aggiunta di "±3·σ√n" (per giustificazioni teoriche vedi l'argomento "teorema limite centrale"):
p1)
<pre><script> with(Math) {
n = 20; S = 0
for(i=0; i<=n; i=i+1) S = S+i
document.write(S)
} </script></pre>
210 ( = 0+1+2+...+20 )
N = 20
|
S = 0, i = 0
|
S = S + i <
| |
i = i + 1 |
| |
i ≤ N ? SI'
|
| NO
|
scrivi S
|
STOP
S = 0, i = 0
S = S+i = 0, i = i+1 = 1
i ≤ 20? sì
S = S+i = 1, i = i+1 = 2
i ≤ 20? sì
S = S+i = 3, i = i+1 = 3
i ≤ 20? sì
S = S+i = 6, i = i+1 = 4
i ≤ 20? sì
...
S = S+i = 190, i = i+1 = 20
i ≤ 20? sì
S = S+i = 210, i = i+1 = 21
i ≤ 20? no
scrivi 210
p2)
<pre><script> with(Math) {
n = 5; P = 1
for(i=1; i<=n; i=i+1) P = P*i
document.write(P)
} </script></pre>
120 ( = 1*2*3*4*5 )
N = 5
|
P = 1, i = 1
|
P = P * i <
| |
i = i + 1 |
| |
i ≤ N ? SI'
|
| NO
|
scrivi P
|
STOP
P = 1, i = 1
P = P*1 = 1, i = i+1 = 2
i ≤ 5? sì
P = P*2 = 2, i = i+1 = 3
i ≤ 5? sì
P = P*3 = 6, i = i+1 = 4
i ≤ 5? sì
P = P*4 = 24, i = i+1 = 5
i ≤ 5? sì
P = P*5 = 120, i = i+1 = 6
i ≤ 5? no
scrivi 120
p3)
<pre><script> with(Math) {
x1 = 1; y1 = 2; x2 = 6; y2 = 7
document.write( "distanza tra (",x1,",",y1,") e (",x2,",",y2,") <br>" )
document.write( sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) ) )
} </script></pre>
distanza tra (1,2) e (6,7)
7.0710678118654755
<pre><script> with(Math) {
x1 = 1; y1 = 2; z1 = 5; x2 = 6; y2 = 7; z2=1
document.write( "distanza tra (",x1,",",y1,",",z1,") e (",x2,",",y2,",",z2,") <br>" )
document.write( sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + (z1-z2)*(z1-z2) ) )
} </script></pre>
distanza tra (1,2,5) e (6,7,1)
8.12403840463596 p4)
<pre><script> with(Math) {
x1 = 1; y1 = 1
x2 = 4; y2 = 0
x3 = 0; y3 = 5
L1=sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) )
L2=sqrt( (x1-x3)*(x1-x3) + (y1-y3)*(y1-y3) )
L3=sqrt( (x3-x2)*(x3-x2) + (y3-y2)*(y3-y2) )
document.write( "P1P2 P1P3 P2P3: ", L1," ", L2," ", L3,"<br>" )
document.write( "perimetro del triangolo P1,P2,P3 = ", L1+L2+L3, "<br>" )
document.write( "area del triangolo P1,P2,P3 = ", abs(x1*(y2-y3) + x2*(y3-y1) + x3*(y1-y2))/2 )
} </script></pre>
P1P2 P1P3 P2P3: 3.1622776601683795 4.123105625617661 6.4031242374328485
perimetro del triangolo P1,P2,P3 = 13.688507523218888
area del triangolo P1,P2,P3 = 5.5
Puoi disegnare il triangolo e calcolarne area, lati, angoli con questo
script ottenendo questa immagine.
Ovvero posso generare un triangolo con questo
script e poi controllare la risposta con quanto ora visto.
p5)
Equazioni di 2º grado:
<pre><script> with(Math) {
titolo = "Soluzioni di a*x^2 + b*x + c = 0"
a = 1
b = 2
c = -15
document.write(titolo+"\n a = ",a,", b = ",b, ", c = ",c+"<br>")
d = b*b-4*a*c
k1 = -b/(2*a) + sqrt(d)/(2*a); k2 = -b/(2*a) - sqrt(d)/(2*a)
if(d < 0) document.write("non ha soluzioni")
if(d > 0) document.write(k1, " ", k2)
if(d == 0) document.write(k1)
} </script></pre>
Soluzioni di a*x^2 + b*x + c = 0
a = 1, b = 2, c = -15
3 -5
Equazioni di 3º grado
Mettiamo il procedimento risolutivo, senza spiegarlo.
soluzioni di A*x^3 + B*x^2 + C*x + D = 0
A = 1, B = 3, C = -10, D = -24
3 sol: 3 -3.9999999999999996 -2.0000000000000013 (ovvero 3 -4, -2)
soluzioni di A*x^3 + B*x^2 + C*x + D = 0
A = 1, B = 9, C = 15, D = -25
2 sol: 1 -5
soluzioni di A*x^3 + B*x^2 + C*x + D = 0
A = 1, B = 0, C = 0, D = 2
1 sol: -1.2599210498948732
p6)
Come viene calcolata la radice quadrata di un numero X?
Ad esempio procedendo per bisezione: parto da un intervallo che contiene la radice quadrata ([0,X] se X>1, [0,1/X] altrimenti), via via ne trovo la metà M, se M*M < X prendo quella destra come nuovo intervallo, altrimenti prendo quella sinistra; e così via.
<pre><script> with(Math) {
x = 1000
a = 0; if(x > 1) {b = x} else {b = 1/x}
for(n=1; n<15; n=n+1) {
m = (a+b)/2; y = m*m
if(y < x) {a = m} else {b = m}
document.writeln("n = ",n , " a = ", a," b = ",b)
}
} </script></pre>
n = 1 a = 0 b = 500
n = 2 a = 0 b = 250
n = 3 a = 0 b = 125
n = 4 a = 0 b = 62.5
n = 5 a = 31.25 b = 62.5
n = 6 a = 31.25 b = 46.875
...
n = 14 a = 31.6162109375 b = 31.67724609375
Se x = 0.1 ho:
n = 1 a = 0 b = 5
n = 2 a = 0 b = 2.5
...
n = 14 a = 0.316162109375 b = 0.3167724609375
Analogamente risolvo le equazioni f(x) = 0 a partire da un intervallo in cui f cambi segno (procedendo per bisezione: se a metà dell'intervallo la funzione ha lo stesso segno che nell'estremo sinistro assumo che la soluzione stia nella metà destra, altrimenti assumo che stia nella metà sinistra).
Esempio: risolvere (rispetto ad x) 5x = 100, partendo da [0,10]
(in quanto 50<100 e 510>100).
<pre><script> with(Math) {
function F(x) {return pow(5,x)-100}
a = 0; b = 10
for(n=10; n<3000; n=n*2) {
for(i=0; i<n; i=i+1) {
m = a+(b-a)/2; y1 = F(a); y2 = F(m); y3 = F(b)
if(y1*y2 > 0) {a = m} else {b = m}
}
document.writeln("n = ",n , " a = ", a," b = ",b)
}
} </script></pre>
n = 10 a = 2.861328125 b = 2.87109375
n = 20 a = 2.861353112384677 b = 2.8613531216979027
n = 40 a = 2.861353116146786 b = 2.8613531161467862
n = 80 a = 2.861353116146786 b = 2.8613531161467862
n = 160 a = 2.861353116146786 b = 2.8613531161467862
n = 320 a = 2.861353116146786 b = 2.8613531161467862
n = 640 a = 2.861353116146786 b = 2.8613531161467862
n = 1280 a = 2.861353116146786 b = 2.8613531161467862
n = 2560 a = 2.861353116146786 b = 2.8613531161467862
Prendo come arrotondamento della soluzione 2.8613531161468.
(con software come WolframAlpha troveremmo
2.861353116146786101340213...)
p7)
Può essere comodo tabulare in un intervallo una funzione. Ad esempio
tabuliamo x → -x4-x3+7 (con 11 valori) tra -50 e 50:
<pre><script> with(Math) {
function F(x) {return -pow(x,4)-pow(x,3)+7}
a = -50; b = 50
h=(b-a)/10
for(n=0; n<=10; n=n+1) {document.writeln("x = ",a+h*n," F(x) = ",F(a+h*n))}
} </script></pre>
x = -50 F(x) = -6124993
x = -40 F(x) = -2495993
x = -30 F(x) = -782993
x = -20 F(x) = -151993
x = -10 F(x) = -8993
x = 0 F(x) = 7
x = 10 F(x) = -10993
x = 20 F(x) = -167993
x = 30 F(x) = -836993
x = 40 F(x) = -2623993
x = 50 F(x) = -6374993
La cosa può essere utile per avere una rapida valutazione dell'andamento della funzione. In questo caso
prendendo a e b man mano più vicini ci convinceremmo che la funzione ha un andamento
/\ tra -10 e 10 (con WolframAlpha potremmo tracciare facilmente il grafico) e potremmo cercare dove assume il valore massimo. Vediamo come.
Data una funzione F, individuato un intervallo in cui l'andamento è /\, possiamo trovarne il massimo in tale intervallo, o individuatone uno in cui l'andamento è
\/ possiamo trovarne il minimo.
L'idea è quella di dividere via via l'intervallo
in 3 parti e prenderne i 2/3 in cui stia il valore cercato.
Ecco il programma per trovare il massimo (nel caso della funzione precedente):
n=10 max tra -0.8421819167132386, -0.49535131839658636 val= 7.094270215667542
n=20 max tra -0.7500533542630592, -0.7499490523620422 val= 7.105468749998371
n=40 max tra -0.750000032934137, -0.7500000329247042 val= 7.105468749999999
n=80 max tra -0.750000032934137, -0.7500000329341369 val= 7.105468749999999
n=160 max tra -0.750000032934137, -0.7500000329341369 val= 7.105468749999999
n=320 max tra -0.750000032934137, -0.7500000329341369 val= 7.105468749999999
n=640 max tra -0.750000032934137, -0.7500000329341369 val= 7.105468749999999
n=1280 max tra -0.750000032934137, -0.7500000329341369 val= 7.105468749999999
n=2560 max tra -0.750000032934137, -0.7500000329341369 val= 7.105468749999999
Intuiamo che il valore esatto del punto in cui si ha il massimo è -0.75 = -3/4 e che qui
F vale 7.10546875. I valori "strani" sulle ultime cifre sono dovuti alle approssimazioni fatte
dal programma. In ogni caso, in ogni problema reale, si deve arrotondare ad un numero relativamente piccolo
di cifre (con WolframAlpha troveremmo
esattamente -3/4 e 1819/256).
Il programma per trovare il minimo applicato al caso di x → 7*x2 - x/3 + 5:
n=10 min tra -0.21998679063150905, 0.12684380768514317 val= 5.030706157217319
n=20 min tra 0.0237545988945348, 0.02385890079555173 val= 4.9960317671489705
n=40 min tra 0.023809512484711453, 0.02380951249414428 val= 4.996031746031747
n=80 min tra 0.023809512484711453, 0.023809512484711456 val= 4.996031746031747
n=160 min tra 0.023809512484711453, 0.023809512484711456 val= 4.996031746031747
n=320 min tra 0.023809512484711453, 0.023809512484711456 val= 4.996031746031747
n=640 min tra 0.023809512484711453, 0.023809512484711456 val= 4.996031746031747
n=1280 min tra 0.023809512484711453, 0.023809512484711456 val= 4.996031746031747
n=2560 min tra 0.023809512484711453, 0.023809512484711456 val= 4.996031746031747
Il minimo è in 0.0238095124847 dove F vale 4.99603174603
(con WolframAlpha troveremmo 1/42 e 1259/252)
Un altro esempio. Abbiamo capito (tabulando la funzione) che (x*sin(x)+sqrt(x)-x*x)3-x4 ha un massimo tra 0 e 0.8.
Troviamolo con più precisione.
n=10 max tra 0.5923893715388915, 0.6062625954715576 val= 0.2980093461765785
n=20 max tra 0.599325390462832, 0.5993295625388726 val= 0.2980093461811849
n=40 max tra 0.599327315089737, 0.5993273150901144 val= 0.2980093461812495
n=80 max tra 0.599327315089737, 0.5993273150897371 val= 0.29800934618124975
n=160 max tra 0.599327315089737, 0.5993273150897371 val= 0.29800934618124975
n=320 max tra 0.599327315089737, 0.5993273150897371 val= 0.29800934618124975
n=640 max tra 0.599327315089737, 0.5993273150897371 val= 0.29800934618124975
n=1280 max tra 0.599327315089737, 0.5993273150897371 val= 0.29800934618124975
n=2560 max tra 0.599327315089737, 0.5993273150897371 val= 0.29800934618124975
Potrei prendere x = 0.5993273, y = 0.29800934618125, ma, se il problema è "pratico", è sufficiente
prendere x = 0.5993, y = 0.2980 (con Geogebra avrei invece ottenuto x = 0.6, y = 0.3!!! Con WolframAlpha avrei ottenuto
correttamente x ≈ 0.599327, y ≈ 0.298009).
p8)
Ilminimoe ilmassimodi una funzione in un intervallo, se non se ne conosce l'andamento (\/ o/\ o ...), possono essere approssimati con una fitta tabulazione. Consideriamo la stessa funzione
studiata sopra:
<pre><script> with(Math) {
function F(x) {return 7*x*x - x/3 + 5 }
a = -10; b = 10
min = 1e300; max = -1e300
n = 8*9*5*7*11*13
for(i=0; i<=n; i=i+1) {x = a+(b-a)/n*i; y = F(x); if(y<min) {min=y; x1=x}; if(y>max) {max=y; x2=x}}
document.write("min ≈ ", min, " (x=", x1, ") max ≈ ", max, " (x=", x2, ")")
} </script></pre>
min ≈ 4.996031746031746 (x=0.023809523809523725) max ≈ 708.3333333333334 (x=-10)
Ho una stima del punto in cui la funzione assume il valore minimo e una stima di questo valore:
0.023809523809523725 invece di 0.0238095124847,
4.996031746031746 invece di 4.99603174603.
p9)
Un biologo deve fare un esperimento su 2 topi, scelti tra i 4 (A, B, C e D) di cui dispone. In quanti modi può effettuare la scelta?
6: AB, AC, AD, BC, BD, CD. È il numero dei sottoinsiemi di 2 elementi di un insieme di 4 elementi, ovvero le combinazioni di 4 elementi 2 a 2. Una formuletta per contarle è 4/2·3/1 (= 6). Se dovesse scegliere 15 topi tra 25, le scelte possibili sarebbero 25/15·24/14·...·11/1. Quante sono?
<pre><script> with(Math) {
document.write(25/15*24/14*23/13*22/12*21/11*20/10*19/9*18/8*17/7*16/6*15/5*14/4*13/3*12/2*11/1)
} </script></pre>
3268760 Più di 3 milioni!
Il calcolo si può fare facilmente, e in generale, con un ciclo for. Le combinazioni C(25,15) di 25 elementi 15 a 15 sono:
L'istruzione "round" serve per non visualizzare le eventuali variazioni dai numeri interi derivanti dalle approssimazioni.
Un esempio di calcolo che utilizza i coefficienti binomiali: un calcolo relativo alla legge di distribuzione binomiale. In una certa popolazione di individui adulti di una data regione si sa che una particolare malattia infantile ha colpito in media 1 persona su 8; prese del tutto a caso 100 persone adulte di quella regione qual è la probabilità che non più di 10 siano state colpita da essa?
Per capire, vediamo come calcolare la probabilità che ne siano state colpite 3:
la probabilità che le prime 3 (o le ultime 3 o la 1ª, la 3ª e la 9ª o ) siano state colpite: (1/8)3·(1-1/8)97
i modi in cui posso scegliere i 3 elementi tra i 100: C(100,3)
la probabilità che esattamente 3 siano state colpite: C(100,3)·(1/8)3·(1-1/8)97
La soluzione del problema: C(100,0)·(1/8)0·(1-1/8)100+C(100,1)·(1/8)1·(1-1/8)99+
... + C(100,10)·(1/8)10·(1-1/8)90
L'integrazione. Consideriamo l'integrale tra 1 e 5 di x → 2*x*x + 3*x + 1.
Procediamo approssimando l'area con n rettangolini (divido l'intervallo in n intervallini che
prendo come basi dei rettangolini; come loro altezze prendo i valori della funzione nel centro di essi; se i valori
sono negativi prendo i rettangolini rivolti verso il basso). Partiamo con n=10 e man mano raddoppiamo n:
<pre><script> with(Math) {
function F(x) { return 2*x*x + 3*x + 1 }; a = 1; b = 5
document.writeln("F(x) = 2*x*x + 3*x + 1; a = 1; b = 5")
n=10
for(i = 0; i < 5; i = i+1) {
s=0; h=(b-a)/n; for (var j=0; j < n; j=j+1) {s = s + F(a+(j+1/2)*h)}
document.writeln(n, " rettangoli, integrale di F su [a,b] = ", s*h); n=n*2
}
} </script></pre>
F(x) = 2*x*x + 3*x + 1; a = 1; b = 5
10 rettangoli, integrale di F su [a,b] = 122.56000000000004
20 rettangoli, integrale di F su [a,b] = 122.64000000000001
40 rettangoli, integrale di F su [a,b] = 122.66000000000003
80 rettangoli, integrale di F su [a,b] = 122.66500000000003
160 rettangoli, integrale di F su [a,b] = 122.66624999999999
Aumentiamo n, mettendo n=10000 al posto di n=10:
F(x) = 2*x*x + 3*x + 1; a = 1; b = 5
10000 rettangoli, integrale di F su [a,b] = 122.66666655999998
20000 rettangoli, integrale di F su [a,b] = 122.66666663999993
40000 rettangoli, integrale di F su [a,b] = 122.66666665999948
80000 rettangoli, integrale di F su [a,b] = 122.6666666649996
160000 rettangoli, integrale di F su [a,b] = 122.66666666625022
Deduco che: integrale di F su [a,b] = 122.666 = 122+2/3 = 368/3
Altro esempio: calcolo di ∫[0,3] |x·(x−2)| dx
F(x) = abs(x*(x-2)); a = 0; b = 3
10 rettangoli, integrale di F su [a,b] = 2.6550000000000002
20 rettangoli, integrale di F su [a,b] = 2.6634374999999997
...
81920 rettangoli, integrale di F su [a,b] = 2.6666666664804004
163840 rettangoli, integrale di F su [a,b] = 2.6666666666201007
Deduco che ∫[0,3] |x·(x-2)| dx = 2+2/3 = 8/3 (con Geogebra avrei ottenuto 2.67!!! Per integrazione, ricerca di massimi/minimi, flessi, ... non è certo un software affidabile ...)
Altro esempio: ∫[0,π/2] cos(x) dx
function F(x) { return cos(x) }; a = 0; b = PI/2
5000 rettangoli, integrale di F su [a,b] = 1.0000000041123318
...
80000 rettangoli, integrale di F su [a,b] = 1.0000000000160585
Altro esempio: 1 − ∫[0,35] 0.1·exp(-0.1·x) dx
function F(x) { return 0.1*exp(-0.1*x) }; a = 0; b = 35
[document.writeln(n, " rettangoli, 1 - integrale di F su [a,b] = ", 1-s*h); n=n*2]
5000 rettangoli, 1 - integrale di F su [a,b] = 0.030197403222453345
10000 rettangoli, 1 - integrale di F su [a,b] = 0.030197388372357636
20000 rettangoli, 1 - integrale di F su [a,b] = 0.03019738465983124
40000 rettangoli, 1 - integrale di F su [a,b] = 0.030197383731682903
80000 rettangoli, 1 - integrale di F su [a,b] = 0.03019738349965262
p11)
È facilissimo studiare le successioni definite per ricorsione. Facciamo solo 3 esempi:
x[0] = A, x[n+1] = sqrt(x[n])
x[0] = 1, x[n+1] = (x[n] + A/x[n]) / 2
x[0] = A, x[1]=B, x[n+2] = (3*x[n+1]-x[n]) / 2
<pre><script> with(Math) {
A = 13
document.writeln("x[0] = ", A, ", x[n+1] = sqrt(x[n])")
x = A; N = 1
for(i=0; i<N; i=i+1) x = sqrt(x)
document.writeln("x[", i, "] = ", x)
} </script></pre>
Con A=13 cambiando N:
x[0] = 13, x[n+1] = sqrt(x[n])
x[1] = 3.605551275463989
x[20] = 1.0000024461293169
x[54] = 1
Con A=0.17:
x[0] = 0.17, x[n+1] = sqrt(x[n])
x[1] = 0.41231056256176607
x[54] = 0.9999999999999999
x[n] -> 1 per n -> ∞ qualunque sia A
<pre><script> with(Math) {
A = 36
document.writeln("x[0] = ", 1, ", x[n+1] = (x[n] + A/x[n]) / 2")
x = A; N = 1
for(i=0; i<N; i=i+1) x = (x + A/x)/2
document.writeln("x[", i, "] = ", x)
} </script></pre>
Con A=36 per crescenti valori di N:
x[0] = 1, x[n+1] = (x[n] + A/x[n]) / 2
x[1] = 18.5
x[2] = 10.222972972972974
x[5] = 6.0002529841194185
x[7] = 6
x[n] -> √A per n -> ∞ qualunque sia A > 0
Una successione ricorsiva con 2 valori iniziali:
<pre><script> with(Math) {
A = 1; B = 2
document.writeln("x[0] = ", A, ", x[1] = ", B, ", x[n+2] = (3*x[n+1]-x[n]) / 2")
x = [A, B]
N = 2
for(i=2; i<=N; i=i+1) x[i] = (3*x[i-1]-x[i-2]) / 2
document.writeln("x[", N, "] = ", x[N])
} </script></pre>
Con A = 1, B = 2 per crescenti valori di N:
x[0] = 1, x[1] = 2, x[n+2] = (3*x[n+1]-x[n]) / 2
x[0] = 1, x[1] = 2, x[n+2] = (3*x[n+1]-x[n]) / 2
x[55] = 2.999999999999999
Prova diversi valori di A e di B (es.: A = -3; B = 9 → x[55] = 21) e verifica che:
x[n] -> 2*B - A
p12)
La regressione lineare. Che cosa posso dire della funzione lineare F tale che F(5)=10 il cui grafico passa per i punti seguenti? (vi sono molti problemi di questo tipo; un semplice esempio: l'allungamento di un elastico o di una molla rilevato appendendovi oggetti di pesi diversi)
x: 12±1 17 ±1 24±1 33±1.5
y: 18±2 27±2 31±2.5 45±3
Guarda queste figure. La prima rappresenta la retta che meglio approssima
i punti senza tener conto delle loro precisioni. La seconda rappresenta le rette di minima e massima pendenza che passano per tutti i punti
dotati di precisione, che sono quindi in realtà dei rettangolini.
La prima retta si trova con un algoritmo non banale su cui si basa questo script; da esso si ricava che y = 1.225*x+3.875.
Le rette della seconda figura sono invece facili da trovare. Possiamo ricorrere a questo semplice programma:
NOTA.
Si potrebbero inserire negli script delle specifiche istruzioni di INPUT, ma ciò non comporterebbe dei miglioramenti nel caso di script semplici come questi, in cui si possono direttamente cambiare i valori assegnati alle variabili e vedere immediatamente i cambiamenti delle uscite. Chi è interessato veda qui.