Search code examples
pythonscipyrandom-walk

python- construction of lattice which traps molecules - doesn't work right


I have this problem :

Create a program which constructs a lattice of one (1) dimension and 100000 sites. In this lattice put at random positions a number of trap molecules, which will have concentration c. Put 1 particle in a random position on the lattice and let it perform a random walk. In this walk you will not place a time restriction, namely you will not declare a specific number of steps. The walk will stop when the particle falls on a trap.............................. ...Beware of boundary conditions. When the particle reaches the borders of the lattice it shouldn’t be allowed to escape from it but to remain in the lattice, either by returning on it former position or by being placed in the opposite site of the lattice........

My approach is shown in the code i created (i have comments in it).

def steps1d(self,pos,c):
    #pos: number of positions
    #c:   concentration of trap-particles

    # array full of traps (zeros)
    myzeros = sc.zeros(self.c*self.pos)

    # grid full of available positions(ones)
    grid = sc.ones(self.pos)

    # distribute c*pos zeros(traps) in random positions (number of positions is pos)
    traps = sc.random.permutation(pos)[:c*pos]

    # the grid in which the particle is moving which has traps inside it 
    grid[traps] = myzeros
    steps_count = []    # list which holds the number of steps
    free = 0
    for i in range(pos):
        # the step of the particle can be 0 or 1
        step=sc.random.random_integers(0,1)
        for step in grid[:]:
            if step == 1:
                free += 1
                steps_count.append(free)
            else:
                break
    return steps_count

I have 3 problems :

1) The results i am taking for example for pos=10 are sth like:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35...]

I would expect 10 numbers each for 1 run (variable pos).

2) I am not sure how to handle the boundary conditions. I am thinking something like:

if free > grid.size:
    free = free - 1

But I can't test it. Also,i am not sure if this applies for both borders of the grid.

3) If i want the first step to begin from the middle of the grid, how can I do it?

If someone has a hint on that, I'll be grateful.


Solution

  • On a smaller lattice, to see what is happening:

    import numpy
    
    # Populate the lattice
    lattice = numpy.concatenate([numpy.ones(90), numpy.zeros(10)])
    numpy.random.shuffle(lattice)
    
    # Intialize problem
    in_trap = False
    steps = 0
    pos = int(numpy.random.randint(0,len(lattice),1))
    history = []
    
    while in_trap == False:
        # Step of -1 is backward, 1 is forward
        step = numpy.random.permutation([-1,1])[0]
    
        # Check position for edges and fix if required
        if pos + step > len(lattice) - 1:
            pos = 0
        elif pos + step < 0:
            pos = len(lattice) - 1
        else:
            pos += step
    
        # Keep track of random walk
        history.append(pos)
    
        # Check if it's a trap
        if lattice[pos] == 0:
            in_trap = True
    
        # If not, continue
        steps += 1
    
    
    print steps
    print history
    print lattice
    

    I would encourage you to thrown in print statements throughout to see what values each variable is holding. Trying it out on smaller lattices will help you understand how this works.

    EDIT:

    I'm going to let you figure out the specifics, but I would wrap this in a function like follows. It sets up the function, then prepares empty steps and histories lists to hold the results of each run. We run the function, then append the results to those lists.

    def lattice():
        code
        return steps, history
    
    steps = []
    histories = []
    for i in range(0,10):
        num_steps, history = lattice()
        steps.append(num_steps)
        histories.append(history)