简体   繁体   中英

Compute weighted summation of matrix power (matrix polynomial) in Matlab

Given an nxn matrix A_k and a nx1 vector x, is there any smart way to compute

在此处输入图片说明

using Matlab? x_i are the elements of the vector x, therefore J is a sum of matrices. So far I have used a for loop, but I was wondering if there was a smarter way.

Short answer : you can use the builtin matlab function polyvalm for matrix polynomial evaluation as follows:

x = x(end:-1:1); % flip the order of the elements
x(end+1) = 0; % append 0
J = polyvalm(x, A);

Long answer : Matlab uses a loop internally. So, you didn't gain that much or you perform even worse if you optimise your own implementation (see my calcJ_loopOptimised function):

% construct random input
n = 100;
A = rand(n);
x = rand(n, 1);

% calculate the result using different methods
Jbuiltin = calcJ_builtin(A, x);
Jloop = calcJ_loop(A, x);
JloopOptimised = calcJ_loopOptimised(A, x);

% check if the functions are mathematically equivalent (should be in the order of `eps`)
relativeError1 = max(max(abs(Jbuiltin - Jloop)))/max(max(Jbuiltin))
relativeError2 = max(max(abs(Jloop - JloopOptimised)))/max(max(Jloop))

% measure the execution time
t_loopOptimised = timeit(@() calcJ_loopOptimised(A, x))
t_builtin = timeit(@() calcJ_builtin(A, x))
t_loop = timeit(@() calcJ_loop(A, x))

% check if builtin function is faster
builtinFaster = t_builtin < t_loopOptimised

% calculate J using Matlab builtin function
function J = calcJ_builtin(A, x)
  x = x(end:-1:1);
  x(end+1) = 0;
  J = polyvalm(x, A);
end

% naive loop implementation
function J = calcJ_loop(A, x)
  n = size(A, 1);
  J = zeros(n,n);
  for i=1:n
    J = J + A^i * x(i);
  end
end

% optimised loop implementation (cache result of matrix power)
function J = calcJ_loopOptimised(A, x)
  n = size(A, 1);
  J = zeros(n,n);
  A_ = eye(n);
  for i=1:n
    A_ = A_*A;
    J = J + A_ * x(i);
  end
end

For n=100 , I get the following:

t_loopOptimised = 0.0077
t_builtin       = 0.0084
t_loop          = 0.0295

For n=5 , I get the following:

t_loopOptimised = 7.4425e-06
t_builtin       = 4.7399e-05
t_loop          = 1.0496e-04 

Note that my timings fluctuates somewhat between different runs, but the optimised loop is almost always faster (up to 6x for small n ) than the builtin function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM