MATLAB金融风险管理师FRM(高阶实战)
上QQ阅读APP看书,第一时间看更新

1.5 符号矩阵与运算

符号运算也应用于矩阵中。下例先用MATLAB的hilb() 函数返回Hilbert矩阵A,产生数值矩阵。接着通过sym()函数,把A变成符号数值矩阵。第二个例子先用magic(4)生成4 × 4方阵,然后用sym() 将其转化为符号数值矩阵。

format long

A = hilb(3)
% A =
%
%    1.000000000000000  0.500000000000000  0.333333333333333
%    0.500000000000000  0.333333333333333  0.250000000000000
%    0.333333333333333  0.250000000000000  0.200000000000000

A_sym = sym(A)
% A_sym =
%
% [   1, 1/2, 1/3]
% [ 1/2, 1/3, 1/4]
% [ 1/3, 1/4, 1/5]

A_magic = magic(4)/10
% A_magic =
%
%    1.600000000000000  0.200000000000000  0.300000000000000
1.300000000000000
%    0.500000000000000  1.100000000000000  1.000000000000000
0.800000000000000
%    0.900000000000000  0.700000000000000  0.600000000000000
1.200000000000000
%    0.400000000000000  1.400000000000000  1.500000000000000
0.100000000000000

A_magic_sym = sym(A_magic)
% A_magic_sym =
%
% [  8/5,   1/5, 3/10, 13/10]
% [  1/2, 11/10,    1,   4/5]
% [ 9/10,  7/10,  3/5,   6/5]
% [  2/5,   7/5,  3/2,  1/10]

使用sym() 也可以定义向量和矩阵。下例用sym() 的符号变量构造向量:

array_an = sym('a',[1 4])
% 1 row, 4 columns

% array_an =
% [ a1, a2, a3, a4]

array_x_n = sym('x_%d',[1 4])
% 1 row, 4 columns
% array_x_n =
% [ x_1, x_2, x_3, x_4]

如下代码用sym() 函数定义一定形状的矩阵:

matrix_A34 = sym('A',[3 4])
% 3 rows, 4 columns
% matrix_A34 =
% [ A1_1, A1_2, A1_3, A1_4]
% [ A2_1, A2_2, A2_3, A2_4]
% [ A3_1, A3_2, A3_3, A3_4]

matrix_x44 = sym('x_%d_%d',4)
% 4 rows, 4 columns
% matrix_x44 =
% [ x_1_1, x_1_2, x_1_3, x_1_4]
% [ x_2_1, x_2_2, x_2_3, x_2_4]
% [ x_3_1, x_3_2, x_3_3, x_3_4]
% [ x_4_1, x_4_2, x_4_3, x_4_4]

sym() 函数也能构造三维符号矩阵,比如下例:

matrix_B222 = sym('B',[2 2 2])

% matrix_B222(:,:,1) =
% [ B1_1_1, B1_2_1]
% [ B2_1_1, B2_2_1]
%
% matrix_B222(:,:,2) =
% [ B1_1_2, B1_2_2]
% [ B2_1_2, B2_2_2]

sym() 还可以通过匿名函数产生符号矩阵,比如下例:

h_matrix = @(x)(x*hilb(3));
sym_matrix = sym(h_matrix)
% sym_matrix =
%
% [   x, x/2, x/3]
% [ x/2, x/3, x/4]
% [ x/3, x/4, x/5]

此外,sym() 也可以给符号矩阵设定前提条件,比如下例:

matrix_A = sym('A%d%d',[2 2],'positive')
% matrix_A =
% [ A11, A12]
% [ A21, A22]

assumptions(matrix_A)
% ans =
% [ 0 < A11, 0 < A12, 0 < A21, 0 < A22]

请读者注意,新版本MATLAB中的sym() 不再支持如下操作:

A = sym('[a, b; c, d]')

符号矩阵有助于公式推导。符号矩阵的运算规则与数值矩阵相同,比如以下运算:

syms a b c d

A = [a, b; c, d]
% A =
% [ a, b]
% [ c, d]

B = [d, c; b, a]
% B =
% [ d, c]
% [ b, a]

A + B
% ans =
% [ a + d, b + c]
% [ b + c, a + d]

A - B
% ans =
% [ a - d, b - c]
% [ c - b, d - a]

transpose(A)
% ans =
% [ a, c]
% [ b, d]

inv(A)
% ans =
% [  d/(a*d - b*c), -b/(a*d - b*c)]
% [ -c/(a*d - b*c),  a/(a*d - b*c)]

A^2 %A*A
% ans =
% [ a^2 + b*c, a*b + b*d]
% [ a*c + c*d, d^2 + b*c]

A*B
% ans =
% [ b^2 + a*d, a*b + a*c]
% [ b*d + c*d, c^2 + a*d]

A/B
% ans =
% [ (a^2 - b^2)/(a*d - b*c), -(a*c - b*d)/(a*d - b*c)]
% [ (a*c - b*d)/(a*d - b*c), -(c^2 - d^2)/(a*d - b*c)]

A\B
% ans =
% [ -(b^2 - d^2)/(a*d - b*c), -(a*b - c*d)/(a*d - b*c)]
% [  (a*b - c*d)/(a*d - b*c),  (a^2 - c^2)/(a*d - b*c)]

A.*B
% ans =
% [ a*d, b*c]
% [ b*c, a*d]

A./B
% ans =
% [ a/d, b/c]
% [ c/b, d/a]

A.\B
% ans =
% [ d/a, c/b]
% [ b/c, a/d]

A.^2
% ans =
% [ a^2, b^2]
% [ c^2, d^2]

det(A)
% ans =
% a*d - b*c

diag(A)
% ans =
%  a
%  d

eig(A)
% ans =
%  a/2 + d/2 - (a^2 - 2*a*d + d^2 + 4*b*c)^(1/2)/2
%  a/2 + d/2 + (a^2 - 2*a*d + d^2 + 4*b*c)^(1/2)/2

可以把具体数值代入由符号定义的矩阵,比如下例:

syms x

M_x = [x x^2; 1/x cos(x)];
f(x) = M_x;
f(2)
% ans =
% [   2,      4]
% [ 1/2, cos(2)]

另外,MATLAB有专门整理和求解线性方程组的函数equationsToMatrix() 和linsolve()。

syms x y z
eqns = [x+y-2*z == 0,
         x+y+z == 1,
         2*y-z == -5];
[A,b] = e quationsToMatrix(eqns)
% A =
% [ 1, 1, -2]
% [ 1, 1,  1]
% [ 0, 2, -1]
%
% b =
%   0
%   1
%  -5

X = linsolve(A,b)
% X =
%     3
%  -7/3
%   1/3

diff() 也可以用在矩阵函数上。比如要求解如下的f偏导数:

具体代码如下:

syms a x n t

f = [a*x^2 t^3*x^3; t*sin(x) log(x)*t];

dfdx = diff(f,x) % diff(f)

% dfdx =
% [    2*a*x, 3*t^3*x^2]
% [ t*cos(x),       t/x]

dfdt2 = diff(f,t,2)
% dfdt2 =
% [ 0, 6*t*x^3]
% [ 0,       0]

dfdxdt = diff(diff(f,x),t)
% dfdxdt =
% [      0, 9*t^2*x^2]
% [ cos(x),       1/x]

gradient() 函数可用于求取函数梯度。多元函数fx)对于向量x的梯度定义如下:

如下代码用gradient() 函数计算f梯度向量。

syms x y z
f = 2*y*z*sin(x) + 3*x*sin(z)*cos(y);
gradient(f, [x, y, z])
% ans =
%  3*cos(y)*sin(z) + 2*y*z*cos(x)
%  2*z*sin(x) - 3*x*sin(y)*sin(z)
%  2*y*sin(x) + 3*x*cos(y)*cos(z)

jacobian() 函数可计算多元函数向量的Jacobian矩阵。若f定义如下:

则其Jacobian矩阵为:

如何使用jacobian() 函数请参考下例。

syms x y
jacobian([x^2*y, x*sin(y)])
% ans =
% [  2*x*y,      x^2]
% [ sin(y), x*cos(y)]

此外,hessian()函数用于获得Hessian矩阵,例如:

syms x1 x2 x3
f = x1*x2 + 2*x3*x1;
hessian(f,[x1,x2,x3])

% ans =
%
% [ 0, 1, 2]
% [ 1, 0, 0]
% [ 2, 0, 0]