In [50]:
import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
import timeit

In [51]:
# object-oriented Approach:

class RandomWalker:
    def __init__(self):
        self.position = 0
    
    def walk(self, n):
        self.position = 0
        for i in range(n):
            yield self.position
            self.position += 2*np.random.randint(0,1) - 1

walker = RandomWalker()
walk = [pos for pos in walker.walk(1000)]
# print(walk)

# alternate-1
def random_walk(n):
    pos = 0
    walk = [pos]
    for i in range(n):
        pos += 2*np.random.randint(0,1) - 1
        walk.append(pos)
    return walk

walk = random_walk(1000)
# print(walk)


# Vectorized Code

def random_walk_faster(n=1000):
    from itertools import accumulate
    steps = np.random.choice([-1,1], n)
    return [0] + list(accumulate(steps))

# random_walk_faster(1000)

# Vectorized Numpy implementation
def random_walk_fastest(n=1000):
    steps = np.random.choice([-1,1], n)
    return np.cumsum(steps)

#random_walk_fastest()

In [55]:
z = np.ones(4*1000, dtype=np.float32)
z[...]=0
print(z.shape)


(4000,)

In [58]:
timeit.timeit("z.view(np.int8)[...] = 0", globals())


---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-58-e717fdffe5c9> in <module>()
----> 1 timeit.timeit("z.view(np.int8)[...] = 0", globals())

/usr/lib/python3.5/timeit.py in timeit(stmt, setup, timer, number, globals)
    211            number=default_number, globals=None):
    212     """Convenience function to create Timer object and call timeit method."""
--> 213     return Timer(stmt, setup, timer, globals).timeit(number)
    214 
    215 def repeat(stmt="pass", setup="pass", timer=default_timer,

/usr/lib/python3.5/timeit.py in __init__(self, stmt, setup, timer, globals)
    118             setup = '_setup()'
    119         else:
--> 120             raise ValueError("setup is neither a string nor callable")
    121         if isinstance(stmt, str):
    122             # Check that the code can be compiled outside a function

ValueError: setup is neither a string nor callable

In [59]:
z = np.arange(9)

In [60]:
z


Out[60]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8])

In [65]:
z = z.reshape(3,3)
z


Out[65]:
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

In [67]:
z = z.astype(np.float32)
z


Out[67]:
array([[0., 1., 2.],
       [3., 4., 5.],
       [6., 7., 8.]], dtype=float32)

In [73]:
z = np.arange(9).reshape(3,3).astype(np.int16)
print(z)
print('---------------')
print(z.shape)
print('---------------')
print(z.itemsize)
print('---------------')
print(z.ndim)


[[0 1 2]
 [3 4 5]
 [6 7 8]]
---------------
(3, 3)
---------------
2
---------------
2

In [80]:
print(z.strides)
strides = z.shape[1]*z.itemsize , z.itemsize
print(strides)


(6, 2)
(6, 2)

In [93]:
print(z)
print('---------------')
v = z[::1, ::1]
print(v)
print('--------------')

v = z[::1,::2]
print(v)
print('--------------')

v = z[1::2, :0:1]
print(v)
print('-------------')


[[0 1 2]
 [3 4 5]
 [6 7 8]]
---------------
[[0 1 2]
 [3 4 5]
 [6 7 8]]
--------------
[[0 2]
 [3 5]
 [6 8]]
--------------
[]
-------------

In [94]:



Out[94]:
array([0., 0., 0., 0., 0., 0., 0., 0., 0.])

In [115]:
z = np.zeros(9)
print('-------------')
print(z)
print(z.shape)

z_view = z[:3]
z_view[...] = 1

print('-------------')
print(z_view)
print('-------------')
print(z)
print('-------------\n------------')

zz = np.zeros(9)
zz_copy = zz[[0,1,2]]
zz_copy[...] = 2

print(zz)
print(zz.shape)
print('-----------')
print(zz_copy)
print('------------')
print(zz)


-------------
[0. 0. 0. 0. 0. 0. 0. 0. 0.]
(9,)
-------------
[1. 1. 1.]
-------------
[1. 1. 1. 0. 0. 0. 0. 0. 0.]
-------------
------------
[0. 0. 0. 0. 0. 0. 0. 0. 0.]
(9,)
-----------
[2. 2. 2.]
------------
[0. 0. 0. 0. 0. 0. 0. 0. 0.]

In [122]:
zzz = np.zeros(9)
indexes = [0,1,2]
zzz[indexes] = 3
zzz[7:-1] = 4
zzz[[4,5]] = 9
print(zzz)


[3. 3. 3. 0. 9. 9. 0. 4. 0.]

In [131]:
print(z_view.base is z)


True

In [133]:
print(zz_copy.base is zz)


False

In [135]:
print(zz_copy.base)


None

In [141]:
X = np.ones(10, dtype=np.int)
Y = np.ones(10, dtype=np.int)
Z = 2*X + 2*Y
Z


Out[141]:
array([4, 4, 4, 4, 4, 4, 4, 4, 4, 4])

In [140]:
# alternative implementaion
X = np.ones(10, dtype=np.int)
Y = np.ones(10, dtype=np.int)
np.multiply(X, 2, out=X)
np.multiply(Y, 2, out=Y)
np.add(X, Y, out=X)


Out[140]:
array([4, 4, 4, 4, 4, 4, 4, 4, 4, 4])

In [146]:
w = np.arange(10,dtype=np.int)
w1 = w[1:-1:2]
# print(w)
# print(w1)

In [147]:
# checking if w is the base of w1
print(w1.base is w)


True

In [167]:
# So, w1 is a view of w
# w1 = w[start:end:strides]
# need to find, start, end, strides

# finding strides
strides = w1.strides[0] // w.strides[0]
print(strides)


# finding start & end
offset_start = np.byte_bounds(w1)[0] - np.byte_bounds(w)[0]
offset_end = np.byte_bounds(w1)[-1] - np.byte_bounds(w)[-1]

print('offset_start = %d' % offset_start)
print('offset_end = %d' % offset_end)

start = offset_start // w.itemsize
end = (offset_end + w.size ) // w.itemsize

print('start = %d' % start)
print('end = %d' % end)
print('w1 = w[%d:%d:%d]' %(start,end,strides))

# sanity check

print(np.allclose(w[start:end:strides], w1))


2
offset_start = 8
offset_end = -16
start = 1
end = -1
w1 = w[1:-1:2]
True

In [2]:
########
import numpy as np

In [10]:
def add_python(z1,z2):
    return [z1+z2 for (z1,z2) in zip(z1,z2)]

def add_numpy(z1,z2):
    return np.add(z1,z2)

In [11]:
z1 = [[1,2],[3,4]]
z2 = [[5,6],[7,8]]

In [12]:
z1+z2


Out[12]:
[[1, 2], [3, 4], [5, 6], [7, 8]]

In [13]:
add_python(z1,z2)


Out[13]:
[[1, 2, 5, 6], [3, 4, 7, 8]]

In [15]:
add_numpy(z1,z2)


Out[15]:
array([[ 6,  8],
       [10, 12]])

Game of Life:

Rules:
1. DEATH happens: any live cell with fewer than 2 live neighbors (cause underpopulation
2. DEATH happens: any live cell with more than 3 live neighbors (overpopulation)
3. SURVIVAL happens: any live cell with 2 or 3 live neighbors survives for next generation.
4. RE-BIRTH happens: any dead cell with exactly 3 live neighbors become alive

SEED : Initial pattern

Births & Deaths happen simultaneously
TICK: the descrete moment when birth and death happens

In [71]:
# Python Implementation:
def compute_gen_score(Z):
    shape = len(Z), len(Z[0]) #(rows, cols) == (y,x)
    score = [[0,]*(shape[0]) for i in range(shape[1])]
    for x in range(1, shape[1]-1):
        for y in range(1, shape[0]-1):
            score[x][y] = Z[x-1][y-1] + Z[x][y-1] + Z[x+1][y-1] + \
                            Z[x-1][y] + Z[x+1][y] + \
                            Z[x-1][y+1] + Z[x][y+1] + Z[x+1][y+1]
    
#     print(score)
    return score

#---------------
def iterate(Z):
    score = compute_gen_score(Z)
    
    for x in range(len(Z[0])-1):
        for y in range(len(Z)-1):
            if Z[x][y] == 1 and (score[x][y] < 2 or score[x][y] > 3):
                ### death
                Z[x][y] = 0
            elif Z[x][y] == 0 and score[x][y] == 3:
                ### rebirth
                Z[x][y] = 1
    return Z
    
    
    
# Numpy Implementation
def game_of_life(Z):
    score_np = np.zeros(Z.shape, np.int)
    score_np += np.add(Z[:-2][:-2], Z[:-2, 1:-1], Z[:-2, 2:])

In [72]:
Z = [[0,0,0,0,0,0],
     [0,0,0,1,0,0],
     [0,1,0,1,0,0],
     [0,0,1,1,0,0],
     [0,0,0,0,0,0],
     [0,0,0,0,0,0]]
Z


Out[72]:
[[0, 0, 0, 0, 0, 0],
 [0, 0, 0, 1, 0, 0],
 [0, 1, 0, 1, 0, 0],
 [0, 0, 1, 1, 0, 0],
 [0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0]]

In [73]:
iterate(Z)


Out[73]:
[[0, 0, 0, 0, 0, 0],
 [0, 0, 1, 0, 0, 0],
 [0, 0, 0, 1, 1, 0],
 [0, 0, 1, 1, 0, 0],
 [0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0]]

In [88]:
arr = Z[:-2][:-2], Z[:-2][:-2], Z[:-2][:-2]
np.sum(arr, axis=0)


Out[88]:
array([[0, 0, 0, 0, 0, 0],
       [0, 0, 3, 0, 0, 0]])

In [99]:
a =Z[:-2][1:-1]
a
# a[:-2]?


Out[99]:
[[0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 1, 0]]

In [ ]:


In [ ]: