Reputation: 25997
I have an array x
of length n_x
, an array all_par1
of length n_par1
and a single parameter par2
. Furthermore, two functions func1
and func2
that take these parameters and x
as input.
I want to create an array with the dimensions n_x
x 2 * n_par1
, where the first half of the columns is populated with the values from func1
and the second half with values from func2
.
I currently do it like this:
import numpy as np
def func1(x, par1):
return x / (par1 + x)
def func2(x, par1, par2):
return -par1 * x / ((par2 + x) ** 2)
def populate_matrix(xvec, par1_vec, par2):
first_half = np.stack((func1(xvec, par1_i) for par1_i in par1_vec), axis=1)
second_half = np.stack((func2(xvec, par1_i, par2) for par1_i in par1_vec), axis=1)
return np.concatenate((first_half, second_half), axis=1)
np.random.seed(0)
all_par1 = [1., 2., 3.]
my_par2 = 5.
n_x = 2
x_variable_length = np.random.rand(n_x)
print x_variable_length
mat = populate_matrix(x_variable_length, all_par1, my_par2)
This gives me then e.g.
[[ 0.35434447 0.21532117 0.15464704 -0.01782479 -0.03564959 -0.05347438]
[ 0.416974 0.26340313 0.19250415 -0.02189575 -0.0437915 -0.06568725]]
As n_x
is 2, it has two rows, the first half of columns is generated with func1
which is always positive, the second half with values from func2
which are always negative.
I need to call this function a lot of times and I am wondering whether this is the most efficient way of doing it. Any ideas?
Not sure whether it is of interest but the actual dimensions are something like 300 x 100.
Upvotes: 0
Views: 259
Reputation: 18628
Here is the vectored way for a 10x improvement on big arrays (100x200 in the tests) :
def populate_matrix_v(xvec, par1_vec, par2):
n,m=xvec.size,par1_vec.size
res= np.empty((n,m+m))
res[:,:m]=func1(x_variable_length[:,None],par1_vec)
res[:,m:]=func2(x_variable_length[:,None], par1_vec, par2)
return res
In [377]: %timeit matv = populate_matrix_v(x_variable_length, all_par1, my_par2)
171 µs ± 6.13 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [378]: %timeit mat = populate_matrix(x_variable_length, all_par1, my_par2)
1.88 ms ± 61.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Upvotes: 1