Let's say I have a tensor C of shape (T,78,S). The 78 floats along axis 1 represent groups of 34 payments P with shape (T,34,S). T>=1, S>=1.
The exact grouping and its start index is known e.g.
group = array([3, 2, 3, 2, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 2, 2, 2, 2, 3, 2, 3, 2], dtype=int64)
cash_index = array([ 0, 3, 5, 8, 10, 12, 14, 16, 18, 21, 23, 26, 28, 31, 33, 35, 37, 39, 41, 43, 45, 48, 50, 53, 55, 58, 60, 62, 64, 66, 68, 71, 73, 76], dtype=int64)
Using this grouping it's relatively easy to work out how to use tf.segment_sum to sum these payments i.e.
cash_group = array([ 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7,
7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 14,
14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 20, 21, 21, 22,
22, 22, 23, 23, 24, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29,
30, 30, 30, 31, 31, 32, 32, 32, 33, 33], dtype=int64)
But since tf.segment_sum only works on the first axis, I have to transpose C first, take the segment_sum, and then transpose it back. Is there a faster way to do this? An axis= parameter to segment_sum would really help.
Also, let's say I need to accumulate a value for each payment.
total = tf.zeros_like(P, dtype=tf.float32)
min_group = group.min()
for i in range(min_group):
offst = cash_index+i
int_i = tf.gather(C,offst,axis=1)
total += (total+Nominal[offst])*int_i
Here Nominal is just a simple numpy array of size 78. This works perfectly when all the groups are the same size (e.g. 2) but will be wrong with the example given. To fix this, I've tried the following:
offst = min_group+cash_index[group>min_group]
dest = np.arange(cash_index.size)[group>min_group]
int_i = tf.gather(C,offst,axis=1)
total = tf.scatter_add(total, dest, (tf.gather(total,dest,axis=1)+Nominal[offst])*int_i)
Which fails with
TypeError: 'ScatterAdd' Op requires that input 'ref' be a mutable tensor (e.g.: a tf.Variable)
How do I fix this? Is there a better way to perform the accumulation? Thanks.