RE>vectors with mma

*To*: mathgroup <mathgroup at yoda.physics.unc.edu>*Subject*: RE>vectors with mma*From*: Roberto Sierra <73557.2101 at compuserve.com>*Date*: 26 Oct 92 09:35:06 EST

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