0

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.

1 Answer 1

1

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)
Sign up to request clarification or add additional context in comments.

1 Comment

That works fine, upvoted (I wait with acceptance for a while to see whether something else shows up...)

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.