0

I have a very simple code to compute the vertical movement. I have set some initial conditions (in this case v0s). Instead to run a for loop over each one of the v0s, is that any way to "apply" each v0 to the x linspace and have a array of numpy arrays.

import numpy as np

v0s = [1, 2, 3]
g = 9.81

def VerticalPosition(v0,g,t):
    return(v0*t - 0.5 * g * t**2)

def Solution(v0,g):
    return(2*v0/g)

def Apex(v0,g):
    return(VerticalPosition(v0,g,v0/g))

x=np.linspace(0,Solution(max(v0s),g),101)

y=[]
for v0 in v0s:
    y.append(VerticalPosition(v0,g,x))
Lin
  • 1,145
  • 11
  • 28
  • `frompyfunc` is probably what you want to try here – Paul Panzer Mar 09 '17 at 18:28
  • `array of arrays` is ambiguous. Do you mean a 2d numpy array (of floats)? Or a 1d object array with array elements? `VerticalPosition` works with broadcastable arrays. Going the object array route is trickier and slower. – hpaulj Mar 09 '17 at 19:25

2 Answers2

1

You just need to use all vectors, and, in your case, that's quite simple.

Try having v0s as a vector with:

v0s = np.array([[1], [2], [3]])

note that it's a 3x1 vector, v0s.shape should be (3, 1)

Your x linspace is already a vector x.shape is (101,)

Now you can just multiply them. Or, call VerticalPosition straight with your new v0s vector, i.e.

y = VerticalPosition(v0s, g, x)
pekapa
  • 881
  • 1
  • 11
  • 25
  • Tachnically, that doesn't yield an array of arrays as OP asked for. – Paul Panzer Mar 09 '17 at 18:57
  • Actually, it does. A python matrix is nothing more than an array of arrays. You can even check by printing the results where it states: `array([[ ... ], [ ... ], [ ... ]])` – pekapa Mar 09 '17 at 19:14
  • In case you want to understand the difference between a 2d array of scalars and a 1d array of 1d arrays of scalars: Look at this simple example [[1,2],[3,4,5]]. Not representable as an array of scalars without destroying its structure. Perfectly straightforward to represent as an array of arrays. – Paul Panzer Mar 09 '17 at 20:29
  • `np.split` or even `list(y)` can be used to create a list of arrays. – hpaulj Mar 09 '17 at 22:11
1

While @pekapa's answer (which returns a 2d array of floats) is what most would recommend, here is a method that produces an array of arrays.

y = np.frompyfunc(lambda a, b: VerticalPosition(a, b, x), 2, 1)(v0s, g)

Arrays of arrays are useful when the inner arrays have different shapes. (Not the case in the present example).

Re the use of x in the above expression. It is taken from the enclosing (not necessarily global) scope but that can with a bit of care be managed. The easiest is to just pack it in a function and make it explicit. Since the inner functions are evaluated immedately and then discarded x being mutable poses no problem here.

def capsule(v0s, g, x):
    return np.frompyfunc(lambda a, b: VerticalPosition(a, b, x), 2, 1)(v0s, g)

Here is an example that essentially only works with an array of arrays:

a,b = np.ogrid[1:4, 5:9:2]
np.frompyfunc(np.arange, 2, 1)(a, b)
# array([[array([1, 2, 3, 4]), array([1, 2, 3, 4, 5, 6])],
#        [array([2, 3, 4]), array([2, 3, 4, 5, 6])],
#        [array([3, 4]), array([3, 4, 5, 6])]], dtype=object)
Paul Panzer
  • 51,835
  • 3
  • 54
  • 99
  • But you had to treat `x` as a global. You couldn't pass it through the `frompyfunc` because it would try to broadcast it against `v0s`, and produce an object array of float values. Here I don't think it offers much of an advantage over the original list iteration. Usually a list of arrays is better than an array of arrays. – hpaulj Mar 09 '17 at 20:55
  • @hpaulj Agreed. I think the only advantage -- if you really want an array of arrays -- is that it makes it comparatively easy to control the depth of the new array. Actually, I have been wondering since there is an `ndmin` kw in the array constructor; why is there no `ndmax`? Do you happen to know? Should I make an SO question of that? Found it http://stackoverflow.com/questions/38774922/prevent-numpy-from-creating-a-multidimensional-array – Paul Panzer Mar 09 '17 at 21:07
  • Indeed, my example doesn't show any need of array of arrays, since my second level array has equal dimensions (that could not be the case), but in fact this needs X as global and that I have to avoid (trying to go functional in some point in future). – Lin Mar 09 '17 at 21:23