I defined these two functions:
function = lambda x: np.array([x, np.sin(x) 0.01 * x ** 2]) # function
function_der_1 = lambda x: np.array([1, np.cos(x) 0.02 * x]) # first derivative
#Defining range of x
x = np.arange(0, 10, 0.01)
#Plotting
plt.plot(*function(x))
This all works fine. But calling
x_1, y_1 = function_der_1(x)
does not work.
It returns an array of the form [1, array([...])].
Why does it not return an array of ones? I guess the reason is because the 1 is constant but it should work nevertheless, shouldn't it?
The wanted output looks like this (called with [1, 3, 4]):
[array([1. , 0.56030231]),
array([ 1. , -0.9299925]),
array([ 1. , -0.57364362])]
CodePudding user response:
In function
, the input x
is an array and np.array
is called with two array in parameter so Numpy concatenates the arrays. In function_der_1
, np.array
is called with a list of two completely different object: an integer 1
and an array. Numpy do not know what to do with that and decide to create an array of object which contains the two objects. This is not great to do that. In fact Numpy show a warning to say that this is likely an issue:
VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
To create an array of 1
with a type/shape similar to x
like in function
, you need to use for example np.ones_like
. Note that this is better to use function like np.vstack
, np.hstack
or np.concatenate
in such case to specify you intent to Numpy (it helps readers and produces a faster code too). Here is the resulting code:
function_der_1 = lambda x: np.vstack([np.ones_like(x), np.cos(x) 0.02 * x])
CodePudding user response:
The set up was probably not good. I rearranged to
function = lambda x: np.sin(x) 0.01 * x ** 2
function_der_1 = lambda x: np.cos(x) 0.02 * x
function_der_2 = lambda x: - np.sin(x) 0.02
The derivatives of the function f(t) = (t, np.sin(t) 0.01 * t ** 2) will alway be of the form (1, ...) so I guess as long as I don't use another parametrization it should work.