Do you want to find out how many rabbits there are after x generations? Fibonacci found the mathematical number series that describes it. This series can be used for modeling other growth processes as well, e.g. plants. Besides this we learn its connection to Golden Ratio, and a lot about vectors handling.
- Objectives: vectors operations
- Requirements: none
Introduction
At first you should know how this series looks like and how it is calculated. The first six elements are
1, 1, 2, 3, 5, 8, …
Optional is the zero, that could be added at the beginning (we won’t). You might have realised already, that each number is the sum of its two predecessors. So you need to have two predecessors, which is why we define the first two elements. We define a variable name “fibonacci” and assign a vector to it. For this we use combine c() function. As parameters we pass the first two numbers: 1 and 1.
fibonacci <- c(1, 1)
fibonacci
## [1] 1 1
What structure has this object? We find out with str().
str(fibonacci)
## num [1:2] 1 1
It is a numerical vector with two elements. You could define two variable, for the predecessor and pre-predecessor. We follow a different approach and use just one vector. What we need is the last element and the next to last element of this vector.
The last element is the element, which index equals the length of the vector. The length of the vector can be determined with length().
length(fibonacci)
## [1] 2
Accessing a specific element is done with square-brackets “[]”. We access the last element:
fibonacci[length(fibonacci)]
## [1] 1
The index of next to last element is length minus 1. We use this and access the next to last element:
fibonacci[length(fibonacci)-1]
## [1] 1
So the next element is always defined as this.
fibonacci[length(fibonacci)-1] + fibonacci[length(fibonacci)]
## [1] 2
How can we extend a vector? With append()! We just need to pass the existing vector, followed by the next element.
next_element <- fibonacci[length(fibonacci)-1] + fibonacci[length(fibonacci)]
fibonacci <- append(fibonacci, next_element)
fibonacci
## [1] 1 1 2
We can run this code again and append another element.
next_element <- fibonacci[length(fibonacci)-1] + fibonacci[length(fibonacci)]
fibonacci <- append(fibonacci, next_element)
fibonacci
## [1] 1 1 2 3
We already have a working solution. But it can be more elegant. It also is a lot of effort, if you want to calculate, let’s say, the 50th element.
We define the generation to be calculated with “elementnr”, and initialise the first two elements of “fibonacci”. Now we calculate for the third to the fiftieth element each additional element. If the number of iterations is known in advance you should use a _for() loop. The parameter are a control variable “i”, which is varied from 3 to “element_nr”. In each loop our code for appending the next element is applied.
element_nr <- 50
fibonacci <- c(1, 1) # initialise first two elements
for (i in 3 : element_nr) {
next_element <- fibonacci[length(fibonacci)-1] + fibonacci[length(fibonacci)]
fibonacci <- append(fibonacci, next_element)
}
fibonacci
## [1] 1 1 2 3 5 ## [6] 8 13 21 34 55 ## [11] 89 144 233 377 610 ## [16] 987 1597 2584 4181 6765 ## [21] 10946 17711 28657 46368 75025 ## [26] 121393 196418 317811 514229 832040 ## [31] 1346269 2178309 3524578 5702887 9227465 ## [36] 14930352 24157817 39088169 63245986 102334155 ## [41] 165580141 267914296 433494437 701408733 1134903170 ## [46] 1836311903 2971215073 4807526976 7778742049 12586269025
This worked. Nice. You see the numbers get pretty fast pretty large.
Fibonacci and Golden Ratio
Golden ratio is a proportion which is supposed to be appealing to the viewer. Some artists like Dali used it in their work and you can also find it in nature.
Golden ratio is defined by (1 + square root of 2), divided by 2. Square root is calculated with sqrt().
golden_ratio <- (1 + sqrt(5)) / 2
golden_ratio
## [1] 1.618034
But how is this related to Fibonacci numbers? If you divide the last by the next to last number you get a ratio that equals golden ratio.
We create two vectors: one includes the elements from 1 to the next to last, the other includes elements from 2 to the next to the last element. Both vectors have the same length. The ratio of both is the golden ratio.
fib_next_to_ast <- fibonacci[1:length(fibonacci)-1]
fib_last <- fibonacci[2:length(fibonacci)]
fib_last / fib_next_to_ast
## [1] 1.000000 2.000000 1.500000 1.666667 1.600000 1.625000 1.615385 ## [8] 1.619048 1.617647 1.618182 1.617978 1.618056 1.618026 1.618037 ## [15] 1.618033 1.618034 1.618034 1.618034 1.618034 1.618034 1.618034 ## [22] 1.618034 1.618034 1.618034 1.618034 1.618034 1.618034 1.618034 ## [29] 1.618034 1.618034 1.618034 1.618034 1.618034 1.618034 1.618034 ## [36] 1.618034 1.618034 1.618034 1.618034 1.618034 1.618034 1.618034 ## [43] 1.618034 1.618034 1.618034 1.618034 1.618034 1.618034 1.618034
You see this are the same after a few elements.
More Information
- Fibonacci Numbers https://en.wikipedia.org/wiki/Fibonacci_number
- Golden Ratio https://en.wikipedia.org/wiki/Golden_ratio