Home > Blockchain >  Numpy function, adding the log of the exponential. Python
Numpy function, adding the log of the exponential. Python

Time:12-18

I am new user to Python.

I want to add many exponential functions, and then take (and store in memory) the logarithm of the result. (Side note : I am doing this because the sum of the exponential functions is very large so storing the log value of this result is a workaround). Can anyone help me use this numpy function https://numpy.org/doc/stable/reference/generated/numpy.logaddexp.html

In the below code I have a 2 x 2 matrix M and a 2 dimensional vector v. I want to first add v the columns of M. So in the below code the result should be

[[11, 22], [13, 24]]

Then I want to take the exponential of each value and sum across the rows (ending up with a vector of length 2), and storing the logarithm of the result. However the below code outputs a matrix and I cant work out how to use the "out=None" imput for the logaddexp function.

import numpy as np

M = np.array([[1, 2], [3, 4]])
v = np.array([10, 20])
result = np.logaddexp(M, v[None, :])

CodePudding user response:

The function np.logaddexp() performs an elementwise operation. In your case, you need the addition to be performed along a given axis. Using some basic functions, you can try the following.

import numpy as np

M = np.array([[1, 2], [3, 4]])  # '2 x 2' array
v = np.array([[10, 20]])        # '1 x 2' array
sum_Mv = M   v                  # '2 x 2' array
result = np.log(np.sum(np.exp(sum_Mv), axis=1))

Change the 'axis' parameter if needed.

If you still want to use np.logaddexp(), you can split the summed matrix into two halves and perform the operation as shown below.

result = np.logaddexp(sum_Mv[:, 0], sum_Mv[:, 1])

CodePudding user response:

TLDR:

import numpy as np

M = np.array([[1, 2], [3, 4]])
v = np.array([10, 20])

result = np.logaddexp.reduce(M   v, axis=___)

Fill in ___ depending on what "sum across the rows" means


Consider the difference between np.add and np.sum.

  • np.add, much like the operator, always takes in 2 arguments, x1 and x2, and adds them together. np.add is a numpy ufunc. If x1 or x2 is an array_like, then the arguments are broadcast together.

  • np.sum always takes in 1 argument, typically an array_like of items, and performs a summation of all of the elements in the array_like. This is essentially equivalent to iteratively taking an element from the array_like and repeatedly calling np.add with that element on a running result variable. The running result variable is initialized with 0.

Similarly, what np.sum is to np.add, np.prod is to np.multiply (with running result initalized as 1).

Every np.ufunc (such as np.add and np.multiply, but also np.logaddexp), comes with a reduce method and an accompanying identity property that is used as initialization for the running result.

np.add.reduce is exactly equivalent to np.sum. np.multiply.reduce is exactly equivalent to np.prod.

What you're looking to do is a log-sum-exp; but numpy only offers np.logaddexp. As such, you can use np.logaddexp.reduce to get the required functionality. Confusion arises from the fact that you're adding M and v as well as adding exponential terms together. You can simply perform the M v operation first, and pass the resulting array (the intermediate result in your question), to np.logaddexp.reduce. Note that M v is equivalent to M v[None, :] in this case due to numpy's broadcasting rules.

  • Related