0

I was curious if there was a quick way of calculating the cumulative product sum for a given array in Python. I understand that numpy has both the cumsum and cumprod functions, but neither seems to work in conjunction with my case. My iterative sequence is as follows, where t is a time index:

X_{t+1} = X_{t} * (B_{t+1} - B_{t}) + X_t

Any suggestions would be greatly appreciated.

4
  • Your question is to make X given B and initial value of X (X_1). Is this right? Commented Apr 8, 2020 at 2:48
  • Given an initial value of X at time t, the sequence for every term thereafter is defined as the product of the X at time t and the difference of two terms B, plus the X value at time t Commented Apr 8, 2020 at 2:53
  • Is the entire B vector known? If not, there isn't enough information to compute X_t. Commented Apr 8, 2020 at 2:54
  • the entire B vector is known, the X vector is only known from initialization t=0 Commented Apr 8, 2020 at 2:55

3 Answers 3

4

In this solution, I will assume the vector B is known. The equation for X can be simplified as follows

X_(t+1) = (B_(t+1) - B_t) X_t + X_t
X_(t+1) = ((B_(t+1) - B_t) + 1) X_t

let C = B[1:] - B[:-1] + 1.

Now the dynamic equation is

X_(t+1) = C_t X_t

Observe the behaviour of the equation

X_1 = C_0 X_0
X_2 = C_1 C_0 X_0
X_3 = C_2 C_1 C_0 X_0

From the pattern above, we get

X_n = C_(n-1) ... C_0 X_0

This means, if you are just after a particular state, you do not need to explicitly compute every preceding state. To get the product of elements in a numpy array, simply use numpy.prod. The snippet below shows how to compute X for a given point and how to compute X at all values for t

import numpy as np

# provide for B and X_0 yourself.

C = B[1:] - B[:-1] + 1
X = np.cumprod(C) * X_0   # compute the entire X vector at once.
X_5 = np.prod(C[:5]) * X_0 # compute X_5 only

That's it! no explicit looping or recursion.

Sign up to request clarification or add additional context in comments.

2 Comments

Well seen . + 1
It should be C = B[1:] - B[:-1] + 1. B[:-2] will drop last 2 elements
0

Try this. Since X_2, X_3, .... should be calculated in each time, loop should be used, but B_diff ([B_2-B_1, B_3-B_2, ...]) is calculated efficiently in advances.

def make_X(initial_X, B):
    B_diff = B[1:] - B[:-1] + 1
    X = [initial_X]
    for t in range(len(B_diff)):
        next_X = B_diff[t] * X[-1]
        X.append(next_X)
    return X

# Test 
make_X(1, np.array([1, 2, 3, 4]))

1 Comment

I already had something similar to this, was hoping there was a quick array method to implement. Thanks, anyway tho
0

Ultimately decided to work with a numpy apply custom function, since I need to use this across a matrix:

# for calculating the series
def myFunc(arr:np.array, initial:int, size:int):
    temp = initial
    new_arr = [0]*size
    for i in range(size):
        new_arr[i] = temp + (temp * arr[i])
        temp += temp * arr[i]
    return np.array(new_arr) 

# for implementing it across my matrix 
np.apply_along_axis(myFunc, 0, arr, initial, size)

1 Comment

apply_along_axis may be handy in this case, but it isn't a speed improvement (over a more explicit loop).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.