سؤال

Something of a follow-up question to my last one about writing efficient python programs. I have been playing with writing my own physics simulations, and want to get away from using a billion classes and methods.

So I want to be able to perform calculations on sets of data. This is my latest attempt:

particles = np.array([ #position, last position, velocity, mass, size
                 [[200,0],[200,200],[5,5],10,15], \
                 [[210,210],[210,210],[8,2],20,25],\
                 [[215,215],[195,195],[5,3],5,15], \
                 [[192,186],[160,160],[10,-4],30,30]])

def moveParticles(part, dt):
    part[0] = part[1]
    part[1] += np.multiply(part[2],dt)

I am trying to store each of the properties of each particle in an array, and then update them in-place. Here I am trying to multiply the velocity vector by the time step, and then add that to the position vector. This seems like a natural way to express this to me, but it gives me the error:

TypeError: can't multiply sequence by non-int of type 'float'

Can I write data back into the same array, and how would I go about doing so?

I have been reading around, and looked at things like numpy's vectorize function, itertools, map(), etc... but how would I go about placing the results back into the original array?

Or is using an intermediate array to store the results before overwriting the original the only way to go?

هل كانت مفيدة؟

المحلول

I think, you just invoke your routine the wrong way (probably passing it the entire particle array instead of the array for only one particle.

Anyway, on other possible solution would be to split your array in individual arrays:

import numpy as np
pos = np.array([[200,0], [210,210], [215,215], [192,186]], dtype=float)
lastpos = np.array([[200,2000], [ 210,210], [195, 195], [160,160]], dtype=float)
velocity = np.array([[ 5,5], [8,2], [5,3], [10,-4]], dtype=float)
mass = np.array([ 10, 20, 5, 30 ], dtype=float)
size = np.array([ 15, 25, 15, 30 ], dtype=float)

def moveParticles(pos, lastpos, velocity, dt):
    lastpos[:] = pos[:]
    pos[:] += velocity * dt

This would make in-place replacement for pos and lastpos. In order to move your particles, you would have to invoke the function as:

moveParticles(pos, lastpos, velocity, 1)

where I set dt = 1. I also assumed, that you want to have floating point coordinates, if not, you should generate integer arrays instead.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top