I am trying to use the function Delaynay of scipy to generate a tetrahedral mesh. From the source code provided here, I have make something as followed:
import math
import random
import numpy as np
from scipy.spatial import Delaunay
# geometry
height = 2.0
depth = 2.0
width = 2.0
# random transformations of the original mesh
random.seed(1234)
variation = .00 # as a decimal for a percent
h = 0.4
x_layer = int(width / h)+1
y_layer = int(depth / h)+1
z_layer = int(height / h)+1
points = np.zeros([x_layer*y_layer*z_layer,3])
count = 0
for orig_x in range(x_layer):
for orig_y in range(y_layer):
for orig_z in range(z_layer):
rand_pert_x = random.uniform(-variation, variation)
rand_pert_y = random.uniform(-variation, variation)
rand_pert_z = random.uniform(-variation, variation)
x = orig_x*h
y = orig_y*h
z = orig_z*h
if (x==0 or orig_x==x_layer-1) or (y==0 or orig_y==y_layer-1) or (z==0 or orig_z==z_layer-1):
points[count,:] = np.array([x,y,z])
else:
points[count,:] = np.array([x+h*rand_pert_x,y+h*rand_pert_y, z+h*rand_pert_z])
count += 1
tet = Delaunay(points, qhull_options="Qt")
i.e. the plan would be to have the points being randomly perturbed to create a low-quality mesh. For now, the variation is set as 0.0 so the code will generate a 3D rectangular grid.
I want to test the quality of the mesh, so one thing I am looking at is the Jacobian of each element. Is there a way to compute that from the output of the Delaunay function?
The following code computes an array
Assuming a tetrahedron with points pj=(xj, yj, zj) for j=0, 1, 2, 3, the Jacobian matrix corresponding to it is (see for example here):
[[x1-x0, x2-x0, x3-x0],
J = [y1-y0, y2-y0, y3-y0],
[z1-z0, z2-z0, z3-z0]]
The following function returns an array of Jacobian matrices corresponding to each of the tetrahedra and the determinant value of each matrix.
def compute_delaunay_tetra_jacobians(dt):
"""
Compute the Jacobian matrix and its determinant for each tetrahedron in the Delaunay triangulation.
:param dt: the Delaunay triangulation
:return: array of shape (n, 3, 3) of jacobian matrices such that jacoboian_array[i, :, :] is the 3x3 Jacobian matrix
array of n values of the determinant of the jacobian matrix
"""
simp_pts = dt.points[dt.simplices]
# (n, 4, 3) array of tetrahedra points where simp_pts[i, j, k] holds the k'th coordinate (x, y or z)
# of the j'th 3D point (of four) of the i'th tetrahedron
assert simp_pts.shape[1] == 4 and simp_pts.shape[2] == 3
# building the 3x3 jacobian matrix with entries:
# [[x1-x0, x2-x0, x3-x0],
# [y1-y0, y2-y0, y3-y0],
# [z1-z0, z2-z0, z3-z0]]
#
a = simp_pts[:, 1, 0] - simp_pts[:, 0, 0] # x1-x0
b = simp_pts[:, 1, 1] - simp_pts[:, 0, 1] # y1-y0
c = simp_pts[:, 1, 2] - simp_pts[:, 0, 2] # z1-z0
d = simp_pts[:, 2, 0] - simp_pts[:, 0, 0] # x2-x0
e = simp_pts[:, 2, 1] - simp_pts[:, 0, 1] # y2-y0
f = simp_pts[:, 2, 2] - simp_pts[:, 0, 2] # z2-z0
g = simp_pts[:, 3, 0] - simp_pts[:, 0, 0] # x3-x0
h = simp_pts[:, 3, 1] - simp_pts[:, 0, 1] # y3-y0
i = simp_pts[:, 3, 2] - simp_pts[:, 0, 2] # z3-z0
determinants = a*(e*i - f*h) - b*(d*i - f*g) + c*(d*h - e*g)
n = simp_pts.shape[0]
jacobian_array = np.empty((n, 3, 3))
jacobian_array[:, 0, 0] = a
jacobian_array[:, 0, 1] = b
jacobian_array[:, 0, 2] = c
jacobian_array[:, 1, 0] = d
jacobian_array[:, 1, 1] = e
jacobian_array[:, 1, 2] = f
jacobian_array[:, 2, 0] = g
jacobian_array[:, 2, 1] = h
jacobian_array[:, 2, 2] = i
return jacobian_array, determinants
I would like to compute all possible pairwise differences (without repetition) between the columns of a matrix. What's an efficient / pythonic way to do this?
mat = np.random.normal(size=(10, 3))
mat
array([[ 1.57921282, 0.76743473, -0.46947439],
[ 0.54256004, -0.46341769, -0.46572975],
[ 0.24196227, -1.91328024, -1.72491783],
[-0.56228753, -1.01283112, 0.31424733],
[-0.90802408, -1.4123037 , 1.46564877],
[-0.2257763 , 0.0675282 , -1.42474819],
[-0.54438272, 0.11092259, -1.15099358],
[ 0.37569802, -0.60063869, -0.29169375],
[-0.60170661, 1.85227818, -0.01349722],
[-1.05771093, 0.82254491, -1.22084365]])
In this matrix there are 3 pairwise differences (N choose k unique combinations, where order doesn't matter).
pair_a = mat[:, 0] - mat[:, 1]
pair_b = mat[:, 0] - mat[:, 2]
pair_c = mat[:, 1] - mat[:, 2]
is one (ugly) way. You can easily imagine using nested for loops for larger matrices, but I am hoping there's a nicer way.
I would like the result to be another matrix, with scipy.misc.comb(mat.shape[1], 2) columns and mat.shape[0] rows.
Combinations of length 2 can be found using the following trick:
N = mat.shape[1]
I, J = np.triu_indices(N, 1)
result = mat[:,I] - mat[:,J]
In [7]: arr = np.arange(m*n).reshape((m, n))
In [8]: arr
Out[8]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19]])
In [9]: from itertools import combinations
In [10]: def diffs(arr):
....: arr = np.asarray(arr)
....: n = arr.shape[1]
....: for i, j in combinations(range(n), 2):
....: yield arr[:, i] - arr[:, j]
....:
In [11]: for x in diffs(arr): print x
[-1 -1 -1 -1 -1]
[-2 -2 -2 -2 -2]
[-3 -3 -3 -3 -3]
[-1 -1 -1 -1 -1]
[-2 -2 -2 -2 -2]
[-1 -1 -1 -1 -1]
If you need them in an array, then just preallocate the array and assign the rows (or columns, as desired).
Incidentally, here is the solution I came up with. Much less elegant than moarningsun's.
def pair_diffs(mat):
n_pairs = int(sp.misc.comb(mat.shape[1], 2))
pairs = np.empty([mat.shape[0], n_pairs])
this_pair = 0
# compute all differences:
for i in np.arange(mat.shape[1]-1):
for j in np.arange(i+1, mat.shape[1]):
pairs[:, this_pair] = mat[:, i] - mat[:, j]
this_pair += 1
return pairs
I'm using numpy to initialize a pixel array to a gray checkerboard (the classic representation for "no pixels", or transparent). It seems like there ought to be a whizzy way to do it with numpy's amazing array assignment/slicing/dicing operations, but this is the best I've come up with:
w, h = 600, 800
sq = 15 # width of each checker-square
self.pix = numpy.zeros((w, h, 3), dtype=numpy.uint8)
# Make a checkerboard
row = [[(0x99,0x99,0x99),(0xAA,0xAA,0xAA)][(i//sq)%2] for i in range(w)]
self.pix[[i for i in range(h) if (i//sq)%2 == 0]] = row
row = [[(0xAA,0xAA,0xAA),(0x99,0x99,0x99)][(i//sq)%2] for i in range(w)]
self.pix[[i for i in range(h) if (i//sq)%2 == 1]] = row
It works, but I was hoping for something simpler.
def checkerboard(shape):
return np.indices(shape).sum(axis=0) % 2
Most compact, probably the fastest, and also the only solution posted that generalizes to n-dimensions.
I'd use the Kronecker product kron:
np.kron([[1, 0] * 4, [0, 1] * 4] * 4, np.ones((10, 10)))
The checkerboard in this example has 2*4=8 fields of size 10x10 in each direction.
this ought to do it
any size checkerboard you want (just pass in width and height, as w, h); also i have hard-coded cell height/width to 1, though of course this could also be parameterized so that an arbitrary value is passed in:
>>> import numpy as NP
>>> def build_checkerboard(w, h) :
re = NP.r_[ w*[0,1] ] # even-numbered rows
ro = NP.r_[ w*[1,0] ] # odd-numbered rows
return NP.row_stack(h*(re, ro))
>>> checkerboard = build_checkerboard(5, 5)
>>> checkerboard
Out[3]: array([[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0]])
with this 2D array, it's simple to render an image of a checkerboard, like so:
>>> import matplotlib.pyplot as PLT
>>> fig, ax = PLT.subplots()
>>> ax.imshow(checkerboard, cmap=PLT.cm.gray, interpolation='nearest')
>>> PLT.show()
Here's another way to do it using ogrid which is a bit faster:
import numpy as np
import Image
w, h = 600, 800
sq = 15
color1 = (0xFF, 0x80, 0x00)
color2 = (0x80, 0xFF, 0x00)
def use_ogrid():
coords = np.ogrid[0:w, 0:h]
idx = (coords[0] // sq + coords[1] // sq) % 2
vals = np.array([color1, color2], dtype=np.uint8)
img = vals[idx]
return img
def use_fromfunction():
img = np.zeros((w, h, 3), dtype=np.uint8)
c = np.fromfunction(lambda x, y: ((x // sq) + (y // sq)) % 2, (w, h))
img[c == 0] = color1
img[c == 1] = color2
return img
if __name__ == '__main__':
for f in (use_ogrid, use_fromfunction):
img = f()
pilImage = Image.fromarray(img, 'RGB')
pilImage.save('{0}.png'.format(f.func_name))
Here are the timeit results:
% python -mtimeit -s"import test" "test.use_fromfunction()"
10 loops, best of 3: 307 msec per loop
% python -mtimeit -s"import test" "test.use_ogrid()"
10 loops, best of 3: 129 msec per loop
You can use Numpy's tile function to get checkerboard array of size n*m where n and m should be even numbers for the right result...
def CreateCheckboard(n,m):
list_0_1 = np.array([ [ 0, 1], [ 1, 0] ])
checkerboard = np.tile(list_0_1, ( n//2, m//2))
print(checkerboard.shape)
return checkerboard
CreateCheckboard(4,6)
which gives the output:
(4, 6)
array([[0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0]])
You can use the step of start:stop:step for slicing method to update a matrix horizontally and vertically:
Here x[1::2, ::2] picks every other element starting from the first element on the row and for every second row of the matrix.
import numpy as np
print("Checkerboard pattern:")
x = np.zeros((8,8),dtype=int)
# (odd_rows, even_columns)
x[1::2,::2] = 1
# (even_rows, odd_columns)
x[::2,1::2] = 1
print(x)
Late, but for posterity:
def check(w, h, c0, c1, blocksize):
tile = np.array([[c0,c1],[c1,c0]]).repeat(blocksize, axis=0).repeat(blocksize, axis=1)
grid = np.tile(tile, ( h/(2*blocksize)+1, w/(2*blocksize)+1, 1))
return grid[:h,:w]
I'm not sure if this is better than what I had:
c = numpy.fromfunction(lambda x,y: ((x//sq) + (y//sq)) % 2, (w,h))
self.chex = numpy.array((w,h,3))
self.chex[c == 0] = (0xAA, 0xAA, 0xAA)
self.chex[c == 1] = (0x99, 0x99, 0x99)
A perfplot analysis shows that the best (fastest, most readable, memory-efficient) solution is via slicing,
def slicing(n):
A = np.zeros((n, n), dtype=int)
A[1::2, ::2] = 1
A[::2, 1::2] = 1
return A
The stacking solution is a bit faster large matrices, but arguably less well readable. The top-voted answer is also the slowest.
Code to reproduce the plot:
import numpy as np
import perfplot
def indices(n):
return np.indices((n, n)).sum(axis=0) % 2
def slicing(n):
A = np.zeros((n, n), dtype=int)
A[1::2, ::2] = 1
A[::2, 1::2] = 1
return A
def tile(n):
return np.tile([[0, 1], [1, 0]], (n // 2, n // 2))
def stacking(n):
row0 = np.array(n // 2 * [0, 1] + (n % 2) * [0])
row1 = row0 ^ 1
return np.array(n // 2 * [row0, row1] + (n % 2) * [row0])
def ogrid(n):
coords = np.ogrid[0:n, 0:n]
return (coords[0] + coords[1]) % 2
b = perfplot.bench(
setup=lambda n: n,
kernels=[slicing, indices, tile, stacking, ogrid],
n_range=[2 ** k for k in range(14)],
xlabel="n",
)
b.save("out.png")
b.show()
Can't you use hstack and vstack? See here.
Like this:
>>> import numpy as np
>>> b = np.array([0]*4)
>>> b.shape = (2,2)
>>> w = b + 0xAA
>>> r1 = np.hstack((b,w,b,w,b,w,b))
>>> r2 = np.hstack((w,b,w,b,w,b,w))
>>> board = np.vstack((r1,r2,r1,r2,r1,r2,r1))
import numpy as np
a=np.array(([1,0]*4+[0,1]*4)*4).reshape((8,8))
print(a)
[[1 0 1 0 1 0 1 0]
[0 1 0 1 0 1 0 1]
[1 0 1 0 1 0 1 0]
[0 1 0 1 0 1 0 1]
[1 0 1 0 1 0 1 0]
[0 1 0 1 0 1 0 1]
[1 0 1 0 1 0 1 0]
[0 1 0 1 0 1 0 1]]
For those wanting arbitrarily sized squares/rectangles:
import numpy as np
# if you want X squares per axis, do squaresize=[i//X for i in boardsize]
def checkerboard(boardsize, squaresize):
return np.fromfunction(lambda i, j: (i//squaresize[0])%2 != (j//squaresize[1])%2, boardsize).astype(int)
print(checkerboard((10,15), (2,3)))
[[0 0 0 1 1 1 0 0 0 1 1 1 0 0 0]
[0 0 0 1 1 1 0 0 0 1 1 1 0 0 0]
[1 1 1 0 0 0 1 1 1 0 0 0 1 1 1]
[1 1 1 0 0 0 1 1 1 0 0 0 1 1 1]
[0 0 0 1 1 1 0 0 0 1 1 1 0 0 0]
[0 0 0 1 1 1 0 0 0 1 1 1 0 0 0]
[1 1 1 0 0 0 1 1 1 0 0 0 1 1 1]
[1 1 1 0 0 0 1 1 1 0 0 0 1 1 1]
[0 0 0 1 1 1 0 0 0 1 1 1 0 0 0]
[0 0 0 1 1 1 0 0 0 1 1 1 0 0 0]]
Replace n with an even number and you will get the answer.
import numpy as np
b = np.array([[0,1],[1,0]])
np.tile(b,(n, n))
Based on Eelco Hoogendoorn's answer, if you want a checkerboard with various tile sizes you can use this:
def checkerboard(shape, tile_size):
return (np.indices(shape) // tile_size).sum(axis=0) % 2
I modified hass's answer as follows.
import math
import numpy as np
def checkerboard(w, h, c0, c1, blocksize):
tile = np.array([[c0,c1],[c1,c0]]).repeat(blocksize, axis=0).repeat(blocksize, axis=1)
grid = np.tile(tile,(int(math.ceil((h+0.0)/(2*blocksize))),int(math.ceil((w+0.0)/(2*blocksize)))))
return grid[:h,:w]
Using tile function :
import numpy as np
n = int(input())
x = np.tile(arr,(n,n//2))
x[1::2, 0::2] = 1
x[0::2, 1::2] = 1
print(x)
Very very late, but I needed a solution that allows for a non-unit checker size on an arbitrarily sized checkerboard. Here's a simple and fast solution:
import numpy as np
def checkerboard(shape, dw):
"""Create checkerboard pattern, each square having width ``dw``.
Returns a numpy boolean array.
"""
# Create individual block
block = np.zeros((dw * 2, dw * 2), dtype=bool)
block[dw:, :dw] = 1
block[:dw, dw:] = 1
# Tile until we exceed the size of the mask, then trim
repeat = (np.array(shape) + dw * 2) // np.array(block.shape)
trim = tuple(slice(None, s) for s in shape)
checkers = np.tile(block, repeat)[trim]
assert checkers.shape == shape
return checkers
To convert the checkerboard squares to colors, you could do:
checkers = checkerboard(shape, dw)
img = np.empty_like(checkers, dtype=np.uint8)
img[checkers] = 0xAA
img[~checkers] = 0x99
import numpy as np
n = int(input())
arr = ([0, 1], [1,0])
print(np.tile(arr, (n//2,n//2)))
For input 6, output:
[[0 1 0 1 0 1]
[1 0 1 0 1 0]
[0 1 0 1 0 1]
[1 0 1 0 1 0]
[0 1 0 1 0 1]
[1 0 1 0 1 0]]
I recently want the same function and i modified doug's answer a little bit as follows:
def gen_checkerboard(grid_num, grid_size):
row_even = grid_num/2 * [0,1]
row_odd = grid_num/2 * [1,0]
checkerboard = numpy.row_stack(grid_num/2*(row_even, row_odd))
return checkerboard.repeat(grid_size, axis = 0).repeat(grid_size, axis = 1)
Simplest implementation of the same.
import numpy as np
n = int(input())
checkerboard = np.tile(np.array([[0,1],[1,0]]), (n//2, n//2))
print(checkerboard)
n = int(input())
import numpy as np
m=int(n/2)
a=np.array(([0,1]*m+[1,0]*m)*m).reshape((n,n))
print (a)
So if input is n = 4 then output would be like:
[[0 1 0 1]
[1 0 1 0]
[0 1 0 1]
[1 0 1 0]]
Simplest way to write checkboard matrix using tile()
array = np.tile([0,1],n//2)
array1 = np.tile([1,0],n//2)
finalArray = np.array([array, array1], np.int32)
finalArray = np.tile(finalArray,(n//2,1))
Suppose we need a patter with length and breadth (even number) as l, b.
base_matrix = np.array([[0,1],[1,0]])
As this base matrix, which would be used as a tile already has length and breadth of 2 X 2, we would need to divide by 2.
print np.tile(base_matrix, (l / 2, b / 2))
print (np.tile(base,(4/2,6/2)))
[[0 1 0 1 0 1]
[1 0 1 0 1 0]
[0 1 0 1 0 1]
[1 0 1 0 1 0]]
n = int(input())
import numpy as np
a = np.array([0])
x = np.tile(a,(n,n))
x[1::2, ::2] = 1
x[::2, 1::2] = 1
print(x)
I guess this works perfectly well using numpy.tile( ) function.
Here is the solution using tile function in numpy.
import numpy as np
x = np.array([[0, 1], [1, 0]])
check = np.tile(x, (n//2, n//2))
# Print the created matrix
print(check)
for input 2, the Output is
[[0 1]
[1 0]]
for input 4, the Output is
[[0 1 0 1]
[1 0 1 0]
[0 1 0 1]
[1 0 1 0]]
Given odd or even 'n', below approach generates "arr" in the checkerboard pattern and does not use loops. If n is odd, this is extremely straightforward to use. If n is even, we generate the checkerboard for n-1 and then add an extra row and column.
rows = n-1 if n%2 == 0 else n
arr=(rows*rows)//2*[0,1]
arr.extend([0])
arr = np.reshape(arr, (rows,rows))
if n%2 == 0:
extra = (n//2*[1,0])
arr = np.concatenate((arr, np.reshape(extra[:-1], (1,n-1))))
arr = np.concatenate((arr, np.reshape(extra, (n,1))), 1)
Here is a generalisation to falko's answer
import numpy as np
def checkerboard(width,sq):
'''
width --> the checkerboard will be of size width x width
sq ---> each square inside the checkerboard will be of size sq x sq
'''
rep = int(width/(2*sq))
return np.kron([[1, 0] * rep, [0, 1] * rep] * rep, np.ones((sq, sq))).astype(np.uint8)
x = checkerboard(width=8,sq=4)
print(x)
print('checkerboard is of size ',x.shape)
which gives the following output
[[1 1 1 1 0 0 0 0]
[1 1 1 1 0 0 0 0]
[1 1 1 1 0 0 0 0]
[1 1 1 1 0 0 0 0]
[0 0 0 0 1 1 1 1]
[0 0 0 0 1 1 1 1]
[0 0 0 0 1 1 1 1]
[0 0 0 0 1 1 1 1]]
checkerboard is of size (8, 8)
Here's a numpy solution with some checking to make sure that the width and height are evenly divisible by the square size.
def make_checkerboard(w, h, sq, fore_color, back_color):
"""
Creates a checkerboard pattern image
:param w: The width of the image desired
:param h: The height of the image desired
:param sq: The size of the square for the checker pattern
:param fore_color: The foreground color
:param back_color: The background color
:return:
"""
w_rem = np.mod(w, sq)
h_rem = np.mod(w, sq)
if w_rem != 0 or h_rem != 0:
raise ValueError('Width or height is not evenly divisible by square '
'size.')
img = np.zeros((h, w, 3), dtype='uint8')
x_divs = w // sq
y_divs = h // sq
fore_tile = np.ones((sq, sq, 3), dtype='uint8')
fore_tile *= np.array([[fore_color]], dtype='uint8')
back_tile = np.ones((sq, sq, 3), dtype='uint8')
back_tile *= np.array([[back_color]], dtype='uint8')
for y in np.arange(y_divs):
if np.mod(y, 2):
b = back_tile
f = fore_tile
else:
b = fore_tile
f = back_tile
for x in np.arange(x_divs):
if np.mod(x, 2) == 0:
img[y * sq:y * sq + sq, x * sq:x * sq + sq] = f
else:
img[y * sq:y * sq + sq, x * sq:x * sq + sq] = b
return img