2

I have a 2x3 matrix m = [1.1, 2.0, 0.5 ; 0.9, 1.5, 1.1];. I need to compute a cumulative geometric mean along the second dimension, i.e. the resulting matrix results must also have the same dimension (2x3). It's basically comparable to using cumprod with the extensions that I need to take the 1/n power where n is the column number.

results must look like this:

[(1.1)^(1/1), (1.1 * 2.0)^(1/2), (1.1 * 2.0 * 0.5)^(1/3) ;
 (0.9)^(1/1), (0.9 * 1.5)^(1/2), (0.9 * 1.5 * 1.1)^(1/3)]

results = cumprod(m,2) delivers the multiplication components. However, what's the most clever way in order to take the appropriate powers?

Andi
  • 3,196
  • 2
  • 24
  • 44

1 Answers1

7

Use the power of bsxfun -

bsxfun(@power, cumprod(m,2), 1./(1:size(m,2)))

Sample run -

>> m
m =
    1.1000    2.0000    0.5000
    0.9000    1.5000    1.1000
>> bsxfun(@power, cumprod(m,2), 1./(1:size(m,2)))
ans =
    1.1000    1.4832    1.0323
    0.9000    1.1619    1.1409
>> [(1.1)^(1/1), (1.1 * 2.0)^(1/2), (1.1 * 2.0 * 0.5)^(1/3) ;
    (0.9)^(1/1), (0.9 * 1.5)^(1/2), (0.9 * 1.5 * 1.1)^(1/3)]
ans =
    1.1000    1.4832    1.0323
    0.9000    1.1619    1.1409

On newer MATLAB versions, with implicit-expansion, the expression would simplify to -

cumprod(m,2).^ (1./(1:size(m,2)))
Divakar
  • 218,885
  • 19
  • 262
  • 358
  • Follow-up question: What if I need to take the cumulated geometric mean along the first dimension, i.e. bsxfun(@power, cumprod(m,1), 1./(1:size(m,1)))? However, this results in a dimension error: "Error using bsxfun Non-singleton dimensions of the two input arrays must match each other." – Andi May 17 '17 at 11:20
  • @Andi Try : `bsxfun(@power, cumprod(m,1), [1./(1:size(m,1))]' )`. – Divakar May 17 '17 at 11:25