Tutorial Video
A Process with 100 % Return
For a process with 100 % return during a single growth period the rateofgrowth will equal to:
In other words after 1 growth period with 100 % growth you get your starting investment value of 1 plus an additional value of 1 return. This gives 1+1=2.
For a process with 100 % return split during two growth periods the rateofgrowth will equal to:
In the first of the two growth periods you will have your initial investment of 1, plus an additional value of 0.5 return. This means you start the second growth period with 1.5 and then after the second growth period you gain an additional value of 0.75 return. Thus you end up with your starting investment of 1 plus an additional value of 1.25. In other words, we have the additional terms here which make the value greater than 2:
After three growth periods:
If instead you get an investment of 100 % growth over three growth periods, in the first of the three growth periods you will have your initial investment of 1, plus an addition value of 0.3333 return. In the second growth period you thus start with 1.3333 and get 0.4444 return and this means in the third growth period, you start with 1.7778 and get 0.5926 in return. Thus you end up with your starting investment of 1 plus an additional value of 1.3704.
In the lines above, what we have typed in is:
rate=(1+1/i)^i
Where i=1,2,3
For Loops
We can incorporate this into a for loop.
As a Scalar
findingev1
for i=1:3
rate=(1+1/i).^i
end
If we do not suppress the output using ;
then we can display the output of the loop in the Command Window to help us understand how the loop works.
In the first iteration i=1
our Scalar variable rate
gets assigned to the calculated value of 2
. In the second iteration i=2
our Scalar variable rate
gets reassigned to the calculated value of 2.25
and on the third iteration i=3
our Scalar variable rate
gets reassigned to the calculated value of2.3704
.
In other words as we specify the output of the Loop to be a Scalar, our variable gets overwritten during each cycle of the loop and if we had suppressed the output we would only have got the following as shown in the Variable Editor.
As an Unallocated Row Vector
If we index the value of i
into the output variable, we will instead create a Row Vector.
findingev2
for i=1:3
rate(i)=(1+1/i).^i
end
Once again if we do not suppress the output using ;
then we can display the output of the loop in the Command Window to help us understand how the loop works.
Here we can see that the output row vector rate
gets updated as the loop iterates. For the first iteration i=1
we get a 1 by 1 row vector, for the second iteration i=2
we get a 1 by 2 row vector and for the third iteration i=3
we get a 1 by 3 row vector. i.e. the variable rate changes it's value for every iteration of the loop. This creates a substantial loss in speed as the size of the output variable needs to be calculated and reassigned to memory during each iteration. In the script editor we get the following warnings:
As an Allocated Row Vector
Because we are going to iterate the loop between 1 and 3 we know we will obtain a Row Vector that has dimensions 1 by 3. We can thus preallocate the variable rate
by using these as inputs to the zeros function before beginning the for loop.
findingev3
rate=zeros(1,3)
for i=1:3
rate(i)=(1+1/i).^i
end
As an Allocated Column Vector
Because we are going to iterate the loop between 1 and 3 we know we will obtain a Row Vector that has dimensions 1 by 3… We can however use zeros to preallocate a Column Vector opposed to a Row Vector. Doing so will result in the loop to write the output data as a Column.
findingev4
rate=zeros(3,1)
for i=1:3
rate(i)=(1+1/i).^i
end
As a Column of a Variable
Often it is useful to have the data generated by the for loop to be a Column of a Variable. We might for instance want a two column variable, with the first column being the order, which the loop takes as i
and the second column being the rate for each value of i
. First we will create the variable data
as a single Column consisting of the values of i
which will be the same values used in the for loop. In this case it is useful to measure the size of data to get m
, the number of rows and n
the number of columns. When preallocating the output using the zeros
function we know we want the input dimensions to have the same number of rows i.e. m
rows and 1
column. We also know that we want to append the preallocated data to a new column at the end of this variable which has n
columns i.e. we want to preallocate all rows :
and create the n+1
column. Now in the loop we can index each value as the row i
and column n+1
of the variable data
.
findingev5
data=[1:3]'
[m,n]=size(data)
data(:,n+1)=zeros(m,1)
for i=1:m
data(i,n+1)=(1+1/i).^i
end
As a Variable in a Table
We could also follow a similar procedure and use a table opposed to a variable. The advantage being that the results may have a better layout, easier for the user to follow. However there is a substantial drawback in using a table for a for loop. Tables are more complicated than numeric arrays and take up substantially more memory. For the small calculation given we don't need to worry but as we will see later for larger datasets this will become problematic.
findingev6
order=[1:3]'
data=table(order)
clear order
[m,n]=size(data.order)
data.rate(:)=zeros(m,1)
for i=1:m
data.rate(i)=(1+1/i).^i
end
Since each variable (column) in the table is a the same size. We don't require the line for preallcoation.
% data.rate(:)=zeros(m,1)
Larger Datasets: Finding the Value of exp
The exponential is defined as the rate of continuous growth for a process with 100 % return.
rate=(1+1/i)^i
In other words as i→∞
. We cannot numerically compute ∞
but we can use a for loop to look at the rate when i
is much larger. We can modify the unallocated code to iterate to a much higher value of i
, say for example 1000000
and we can suppress the output so it doesn't fill up the Command Window. To time how long this code takes we can enclose it within a timer using the functions tic
and toc
findingev2a
tic
for i=1:1000000
rate(i)=(1+1/i).^i;
end
toc
We can make the same modifications to the other lines of code. Note how the time taken for the lines of code that were not preallocated takes about twice as long then the lines of code that weren't preallocated:
We can also compare how inefficient the for loop is when it involves a table. It took 5506.33 s to run to create a table.
The Command Window never showed an elapsed time.
findingev7a
data=[1:1000000]';
[m,n]=size(data);
data(:,n+1)=zeros(m,1);
for i=1:m
data(i,n+1)=(1+1/i).^i;
end
data2=table(data(:,1),data(:,2),'VariableNames',{'order','rate'})
This takes only 0.69 s and gives a table of the same form as that found in findingev6a:
We can examine the table:
As we can see for higher orders, the value converges.
This value 2.7183 is the value:
exp(1)
If we don't want all values in steps of 1 but rather want to check every order of magnitude, we can do the following:
findingev7a
data=[1;10;100;1000;10000;100000;1000000];
[m,n]=size(data);
data(:,n+1)=zeros(m,1);
for i=1:m
data(i,n+1)=(1+1/data(i)).^data(i);
end
data2=table(data(:,1),data(:,2),'VariableNames',{'order','rate'})
This will give us the following table: