0

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.

user1726633
  • 356
  • 2
  • 10
  • The answer to this question should help: [Tensorflow unsorted_segment_sum dimension](https://stackoverflow.com/questions/43210033/tensorflow-unsorted-segment-sum-dimension/43210889). – jdehesa Jan 18 '18 at 11:52
  • Thanks - it helps with the first part. Bit I'm not sure how it applies to the second. – user1726633 Jan 18 '18 at 12:06
  • Yes that's why I didn't just mark it as duplicate... I don't understand very well the second half though. In any case, [`tf.scatter_add`](https://www.tensorflow.org/api_docs/python/tf/scatter_add) works by updating a given mutable tensor (i.e. a variable), which `total` is not. – jdehesa Jan 18 '18 at 12:22
  • I'm trying to compound a list of 34 numbers using groups of either 2 or 3 compounding rates. The workaround I've found is to pad the C tensor with zeros at the end and change the offst variable to point to the end of C whenever we go past the end of a group. Which seems to work. – user1726633 Jan 18 '18 at 13:33

0 Answers0