Reply to: RE>vectors with mma
This is in response to Simon Benninga's query about numerical
vectors for financial problems...
> I'm trying to write a small program to do portfolio problems in
> finance. I want to both manipulate numbers and do analytics.
> Here's part of the program:
>
> Clear[S,X,Y,x,n,ER,ERp,Varp,Var,V]
> n=4;
> X=Array[x,n]; (* portfolio proportions *)
> Y=Array[ER,n]; (* vector of expected asset returns *)
> S=Array[V,{n,n}]; (* variance/covariance matrix *)
> ERp=X.Y; (* expected portfolio return *)
> Varp=X.S.X; (* portfolio variance *)
> D[ERp,x[1]]
> D[Varp,x[1]]
>
> This program produces the correct output: I.e., the last two
> lines produce the derviative of ERp wrt x[1] and the derivative
> of Varp wrt x[1].
>
> Now suppose I try to put numerical values in for X, Y, and S.
> For instance, the next cell of this program has the following:
>
> Y={6,7,8,9};
> S = {{10,2,4,5},{2,20,4,1},{4,4,40,10},{5,1,10,60}};
> X = {0.4919379941,0.2998194609,0.1116229845,0.0966195605};
> ERp
>
> I would have thought that this cell should produce a numerical
> answer. However, it only produces the following:
>
> ER[1] x[1] + ER[2] x[2] + ER[3] x[3] + ER[4] x[4]
>
> Can anyone tell me what I'm doing wrong?
The problem you're experiencing trips up many folks new to
Mathematica
and relates to the difference between immediate and delayed
evaluation
of function definitions. When the line
ERp = X.Y;
is executed, X and Y have been defined in terms of other symbols,
therefore
those symbols are substituted *in place* of X and Y during
evaluation.
You could have equivalently typed the following -- it's the first
transform-
ation that Mathematica will apply anyway:
ERp = ER[1] x[1] + ER[2] x[2] + ER[3] x[3] + ER[4] x[4]
While this is correct, per se, you'll notice that X and Y aren't
mentioned
at all -- this means that Mathematica won't be able to reduce things
if
the definitions of X and Y change later on -- the evaluation has
already
been performed, and the 'rules' for performing the calculation have
been
lost.
The 'proper' way to go about defining ERp and Varp is using a delayed
definition, which is done using the ':=' operator. Here's how I'd do
it (read sections 2.3 and 2.4 of the MMA book, 2nd edition, for more
background on how all of this stuff works, I'm also checking that the
arguments are vectors and matrices):
ERp[ x_?VectorQ, y_?VectorQ ] := x.y
(* expected portfolio return *)
Varp[ x_?VectorQ, s_?MatrixQ ] := x.s.x
(* portfolio variance *)
By doing things this way, different values of x and x can be plugged
through the calculations at different points, and they don't need to
be named x and y, either (I changed the arguments to lowercase to
follow convention -- variables tend to be in lowercase, while
functions
tend to be capitalized).
Here's how you'd perform the symbolic calculations you tried out:
n=4;
X=Array[x,n]; (* portfolio proportions *)
Y=Array[ER,n]; (* vector of expected asset returns *)
S=Array[V,{n,n}]; (* variance/covariance matrix *)
D[ERp[X,Y],x[1]] (* Note the syntax arguments must be *)
D[Varp[X,S],x[1]] (* supplied to ERp, as in ERp[X,Y]. *)
Now you can redefine X, Y and S and perform a new set of
calculations,
or supply anything you wish to ERp and Varp. Here's how you'd do the
numerical calculations, which will wipe out the X, Y and S values
from
before:
Y = {6,7,8,9};
S = {{10,2,4,5},{2,20,4,1},{4,4,40,10},{5,1,10,60}};
X = {0.4919379941,0.2998194609,0.1116229845,0.0966195605};
ERp[X,Y] (* Should evaluate to 6.81292 *)
Varp[X,S] (* Should evaluate to 7.32231 *)
While we're on the subject, there's an alternative way to do the
same thing using the '/.' operator, which allows one to evaluate
expressions using temporary values which are substituted in during
evaluation but not 'bound' to the expression in any way. Here's
how to do it:
ERp = X.Y; (* Define ERp operation *)
Varp = X.S.X; (* Define Varp operation *)
Note that this tells MMA how to evaluate ERp and Varp in terms of
X, Y and S, but doesn't plug in specific values for X, Y and S.
Now we can plug in symbolic values:
ERp /. {X->Array[x,4], Y->Array[ER,4], S->Array[V,{4,4}]}
D[%,x[1]]
Varp /. {X->Array[x,4], Y->Array[ER,4], S->Array[V,{4,4}]}
D[%,x[1]]
Here's we plug in numerical values:
Yvect = {6,7,8,9}
Svect = {{10,2,4,5},{2,20,4,1},{4,4,40,10},{5,1,10,60}}
Xvect = {0.4919379941,0.2998194609,0.1116229845,0.0966195605}
ERp /. {X->Xvect, Y->Yvect, S->Svect}
Varp /. {X->Xvect, Y->Yvect, S->Svect}
What's great about this technique is that the original definitions
for ERp and Varp haven't changed -- the 'operations' are intact and
can be reapplied endlessly:
ERp (* still equals X.Y *)
Varp (* still equals X.S.X *)
Obviously, there's more typing using this form, and it's a bit
dangerous
since you have to make sure not to set values for X, Y or S that will
change how ERp and Varp are reduced. The functional form, which
requires
*arguments* to ERp and Varp, might make more sense.
Hope this helps,
\\|//
- -
o o
J roberto sierra
O tempered microdesigns
\_/ 73557.2101 at compuserve.com
"Information gladly given, but safety requires
avoiding unnecessary conversation." -- MUNI