Fibonacci in Matlab
Write a function fibonacci(n) that, given a positive number n, returns a vector containing the first n+ 1 Fibonacci numbers f0,f1,...,fn. Program efficiently: it should, for example, not take longer than a couple ofseconds to calculate fibonacci(60)
Mi si chiede di scrivere in MatLab una funzione che dato un intero positivo \(n \) mi restituisca un vettore contendente i primi \(n+1\) numeri di fibonacci \(f_0 , \ldots , f_n \). E che sia un programma efficiente, ovvero non deve metterci più di un paio di secondi a calcolare fibonacci(60). Io ho fatto questo
Ma quando faccio run di fibonacci(60) mi esce questo:
Ora controllando con il debugger messo qui
mi aggiunge effettivamente
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986 102334155 165580141 267914296 433494437 701408733 1134903170.00000 1836311903.00000 2971215073.00000 4807526976.00000 7778742049.00000 12586269025.0000 20365011074.0000 32951280099.0000 53316291173.0000 86267571272.0000 139583862445.000 225851433717.000 365435296162.000 591286729879.000 956722026041.000 1548008755920.00
Questa differenza nel command window di Matlab?
C'è un modo più efficiente di farlo?
Mi si chiede di scrivere in MatLab una funzione che dato un intero positivo \(n \) mi restituisca un vettore contendente i primi \(n+1\) numeri di fibonacci \(f_0 , \ldots , f_n \). E che sia un programma efficiente, ovvero non deve metterci più di un paio di secondi a calcolare fibonacci(60). Io ho fatto questo
function fn = fibonacci(n) if n == 0 fn = 0; end if n == 1 fn = [0,1]; end if n >= 2 fn = [0,1]; for j=2:n fn = [fn,fn(j-1)+fn(j)]; end end end
Ma quando faccio run di fibonacci(60) mi esce questo:
ans = 1.0e+12 * Columns 1 through 13 0 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 Columns 14 through 26 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 Columns 27 through 39 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 Columns 40 through 52 0.0001 0.0001 0.0002 0.0003 0.0004 0.0007 0.0011 0.0018 0.0030 0.0048 0.0078 0.0126 0.0204 Columns 53 through 61 0.0330 0.0533 0.0863 0.1396 0.2259 0.3654 0.5913 0.9567 1.5480
Ora controllando con il debugger messo qui
fn = [fn,fn(j-1)+fn(j)];
mi aggiunge effettivamente
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986 102334155 165580141 267914296 433494437 701408733 1134903170.00000 1836311903.00000 2971215073.00000 4807526976.00000 7778742049.00000 12586269025.0000 20365011074.0000 32951280099.0000 53316291173.0000 86267571272.0000 139583862445.000 225851433717.000 365435296162.000 591286729879.000 956722026041.000 1548008755920.00
Questa differenza nel command window di Matlab?
C'è un modo più efficiente di farlo?
Risposte
Il tuo codice è corretto, per qualche motivo matlab stampa il risultato in quella maniera stupida [in Octave funziona bene invece].
Per quanto riguarda l'efficienza, non so come sia implementata la concatenazione in matlab, ma forse puoi guadagnare qualcosa sostituendo [inline]fn = [fn,fn(j-1)+fn(j)];[/inline] con [inline]fn(end+1) = fn(j-1)+fn(j);[/inline], o addirittura preallocando un vettore di zeri e poi sommando anziché assegnando i valori. Per vettori così piccoli il guadagno è sicuramente trascurabile.
Per quanto riguarda l'efficienza, non so come sia implementata la concatenazione in matlab, ma forse puoi guadagnare qualcosa sostituendo [inline]fn = [fn,fn(j-1)+fn(j)];[/inline] con [inline]fn(end+1) = fn(j-1)+fn(j);[/inline], o addirittura preallocando un vettore di zeri e poi sommando anziché assegnando i valori. Per vettori così piccoli il guadagno è sicuramente trascurabile.
Ok, grazie mille.