I would use diag
and cumprod
to help you accomplish this. First use diag
to extract the diagonals of your matrix Q
. After, use cumprod
to generate a vector of cumulative products.
How cumprod
works on a vector is that for each element in the vector, the i'th element collects products from 1 up to the i'th element. As an example, if we had a vector V = [1 2 3 4 5]
, cumprod(V)
would produce [1 2 6 24 120]
. The 4th element (as an example) would be 1*2*3*4
, representing the products from the 1st to the 4th element.
As such, this is the code that I would do:
qdiag = diag(Q);
xMinusZ = x - z; % Takes z and does x - z for every element in z
cumProdRes = cumprod(xMinusZ);
P = sum(qdiag .* [1;cumProdRes(1:end-1)]);
P
should give you P(x)
that you desired. Make sure that z
is a column vector to make it compatible with the diagonals extracted from Q
.
NB: I believe there is a typo in your equation. The last term of your equation (going with your convention) should have (x-z(2n-1))
and not (x-z(2n))
. This is because the first term in your equation does not have z
.
Here's an example. Let's suppose Q
is defined
Q = [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16];
The vector z
is:
z = [4;3;2;1];
Let's evaluate the function at x = 2
Extracting the diagonals of Q
should give us Q = [1;6;11;16]
. Subtract x
from every element of z
should give us:
xMinusZ = [-2;-1;0;1];
Using the equation that you have above, we have:
P = 1 + 6*(-2) + 11*(-2)*(-1) + 16*(-2)*(-1)*(0) = 11
This is what the code should give.
What if we want to do this for more than one value of x?
As you have stated in your post, you want to evaluate this for a series of x
values. As such, you need to modify the code so that it looks like this (make sure that x
is a column vector):
qdiag = diag(Q);
xMinusZ = repmat(x,1,length(z)) - repmat(z',length(z),1);
cumProdRes = cumprod(xMinusZ,2);
P = sum(repmat(qdiag',length(z),1).*[ones(length(z),1) cumProdRes(:,1:end-1)],2);
P
should now give you a vector of outputs, and so if you want to plot this, simply do plot(x,P);