glumpy.gloo bind texture as GL_RGB32F - python

I'm using Glumpy and I'm trying to bind a texture as GL_RGB32F. It appears that it binds the texture as GL_RGB, even though my numpy array is of type np.float32. The values this array contains are outside the 0..1 range, and I need these values in a fragment shader unclipped.
compute = gloo.Program(compute_vertex, compute_fragment, count=4)
compute["matte"] = matte
compute["matte"].interpolation = gl.GL_NEAREST
compute["matte"].wrapping = gl.GL_CLAMP_TO_EDGE
compute["distanceField"] = alpha
compute["distanceField"].interpolation = gl.GL_NEAREST
compute["distanceField"].wrapping = gl.GL_CLAMP_TO_EDGE
compute["position"] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)]
compute["texcoord"] = [(0, 0), (0, 1), (1, 0), (1, 1)]
print(matte.dtype)
print(gl.GL_RGB32F)
print(compute["matte"].gpu_format)
print(compute["distanceField"].gpu_format)
The output is
float32
GL_RGB32F (34837)
GL_RGB (6407)
GL_RED (6403)
How can I bind the matte array as GL_RGB32F and the distanceField as GL_R32F?

Found the answer. Use view(gloo.TextureFloat2D) on the numpy array, otherwise, internally it would automatically call view(Texture2D).
compute = gloo.Program(compute_vertex, compute_fragment, count=4)
compute["matte"] = matte.view(gloo.TextureFloat2D)
compute["matte"].interpolation = gl.GL_NEAREST
compute["matte"].wrapping = gl.GL_CLAMP_TO_EDGE
compute["distanceField"] = alpha.view(gloo.TextureFloat2D)
compute["distanceField"].interpolation = gl.GL_NEAREST
compute["distanceField"].wrapping = gl.GL_CLAMP_TO_EDGE
compute["position"] = [(-1, -1), (-1, +1), (+1, -1), (+1, +1)]
compute["texcoord"] = [(0, 0), (0, 1), (1, 0), (1, 1)]

Related

How to handle return from recursion

I'm trying to make a polyomino generator of level N. I successfully made a function that connects a tile with a root in every possible way and returns all combinations. Now I need to extend this to level N. I've done my best, but still can't handle recursion the right way.
Here's my function:
def connect_n(tiles,root,n=1):
if not isinstance(tiles[0], list): tiles = [tiles]
result = []
if n == 1:
for tile in tiles:
result += connect(tile, root)
return result
else:
return connect_n(tiles, root,n-1)
This function successfully creates N nested functions and executes base case at n==1. But then with obtained result, it just goes up and up and exits with that result without any other iterations. I'm sure I'm missing something. I tried to move conditions and loops around without success.
I have following input:
root = (0,0)
N = 3 #for example, can be any number > 0
Function connect(root,root) returns:
[[(0, 0), (1, 0)]]
Then functionconnect([[(0, 0), (1, 0)]],root) returns
[[(0, 0), (1, 0), (2, 0), (3, 0)],
[(0, 0), (0, 1), (1, 0), (2, 0)],
[(0, 0), (0, 1), (1, 0), (1, 1)],
[(0, 0), (1, 0), (1, 1), (2, 1)]]
And so on.
Function connect_n output should be
[[(0, 0), (1, 0)]] for N=1
[[(0, 0), (1, 0), (2, 0), (3, 0)],
[(0, 0), (0, 1), (1, 0), (2, 0)],
[(0, 0), (0, 1), (1, 0), (1, 1)],
[(0, 0), (1, 0), (1, 1), (2, 1)]] for N=2
And so on.
I'm not sure I understand the algorithm, but I think this is what you want:
def connect_n(tiles, root, n=1):
if n == 1:
return connect(tiles, root)
else:
return connect_n(connect_n(tiles, root, n-1)), root)

Pythonic way to calculate pair wise dot product inside a list

I have a list that consists of all combinations of tuples that each elements can only be -1 or 1. The list can be generated as:
N=2
list0 = [p for p in itertools.product([-1, 1], repeat=N)]
For example, if the tuple has N=2 elements:
list0 = [(-1, -1), (-1, 1), (1, -1), (1, 1)]
Thus the total number of tuples is 2^2=4.
If the tuple has N=3 elements:
list0 = [(-1, -1, -1), (-1, -1, 1), (-1, 1, -1), (-1, 1, 1),
(1, -1, -1), (1, -1, 1), (1, 1, -1), (1, 1, 1)]
Here is my concern:
Now I would like to get all the results of dot products between any pair of tuples in the list(including ones a tuple with itself). So for N=2 there will be 6(pairs) + 4(itself) = 10 combinations; for N=3 there will be 28(pairs) + 8(itself) = 36 combinations.
For small N I can do something like:
for x in list0:
for y in list0:
print(np.dot(x,y))
However, assuming I already have list0, what is the optimal way to calculate all the possibilities of dot products, if N is large, like ~50?
You could use the np.dot itself:
import numpy as np
list0 = [(-1, -1, -1), (-1, -1, 1), (-1, 1, -1), (-1, 1, 1), (1, -1, -1), (1, -1, 1), (1, 1, -1), (1, 1, 1)]
# approach using np.dot
a = np.array(list0)
result = np.dot(a, a.T)
# brute force approach
brute = []
for x in list0:
brute.append([np.dot(x, y) for y in list0])
brute = np.array(brute)
print((brute == result).all())
Output
True
What you are asking is the matrix multiplication of a with itself, from the documentation:
if both a and b are 2-D arrays, it is matrix multiplication,
Note that the most pythonic solutio is to use the operator #:
import numpy as np
list0 = [(-1, -1, -1), (-1, -1, 1), (-1, 1, -1), (-1, 1, 1), (1, -1, -1), (1, -1, 1), (1, 1, -1), (1, 1, 1)]
# approach using np.dot
a = np.array(list0)
result = a # a.T
# brute force approach
brute = []
for x in list0:
brute.append([np.dot(x, y) for y in list0])
brute = np.array(brute)
print((brute == result).all())
Output
True
Note: The code was run in Python 3.5
You can stick with numpy
import numpy as np
import random
vals = []
num_vecs = 3
dimension = 4
for n in range(num_vecs):
val = []
for _ in range(dimension):
val.append(random.random())
vals.append(val)
# make into numpy array
vals = np.stack(vals)
print(vals.shape == (num_vecs, dimension))
# multiply every vector with every other using broadcastin
every_with_every_mult = vals[:, None] * vals[None, :]
print(every_with_every_mult.shape == (num_vecs, num_vecs, dimension))
# sum the final dimension
every_with_every_dot = np.sum(every_with_every_mult, axis=every_with_every_mult.ndim - 1)
print(every_with_every_dot.shape == (num_vecs, num_vecs))
# check it works
for i in range(num_vecs):
for j in range(num_vecs):
assert every_with_every_dot[i,j] == np.sum(vals[i]*vals[j])

Remove duplicate unordered tuples from list

In a list of tuples, I want to have just one copy of a tuple where it may be (x, y) or (y, x).
So, in:
# pairs = list(itertools.product(range(3), range(3)))
pairs = [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
the result should be:
result = [(0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2)] # updated pairs
This list of tuples is generated using itertools.product() but I want to remove the duplicates.
My working solution:
pairs = [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
result = []
for pair in pairs:
a, b = pair
# reordering in increasing order
temp = (a, b) if a < b else (b, a)
result.append(temp)
print(list(set(result))) # I could use sorted() but the order doesn't matter
How can this be improved?
You could use combinations_with_replacement
The code for combinations_with_replacement() can be also expressed as a subsequence of product() after filtering entries where the elements are not in sorted order (according to their position in the input pool)
import itertools
pairs = list(itertools.combinations_with_replacement(range(3), 2))
print(pairs)
>>> [(0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2)]
edit I just realized, your solution matches my solution. What you are doing is just fine. If you need to do this for a very large list, then there are some other options you may want to look into, like a key value store.
If you need to remove dupes more programatically, then you can use a function like this:
def set_reduce(pairs):
new_pairs = set([])
for x,y in pairs:
if x < y:
new_pairs.add((x,y))
else:
new_pairs.add((y,x))
return new_pairs
running this results in
>>>set_reduce(pairs)
set([(0, 1), (1, 2), (0, 0), (0, 2), (2, 2), (1, 1)])
This is one solution which relies on sparse matrices. This works for the following reasons:
An entry in a matrix cannot contain two values. Therefore, uniqueness is guaranteed.
Selecting the upper triangle ensures that (0, 1) is preferred above (1, 0), and inclusion of both is not possible.
import numpy as np
from scipy.sparse import csr_matrix, triu
lst = [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1),
(1, 2), (2, 0), (2, 1), (2, 2)]
# get row coords & col coords
d1, d2 = list(zip(*lst))
# set up sparse matrix inputs
row, col, data = np.array(d1), np.array(d2), np.array([1]*len(lst))
# get upper triangle of matrix including diagonal
m = triu(csr_matrix((data, (row, col))), 0)
# output coordinates
result = list(zip(*(m.row, m.col)))
# [(0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2)]

format and Print a list in a file

i have one list with some coordinates in it, when i am printing it like that:
for i in range(0,len(List)):
print("".join(["(%d, %d) \n" % (y[i], y[i+1]) for y in (List)]))
the output is this:
(0, 3)
(0, 2)
(0, 1)
(1, 1)
(1, 2)
(2, 2)
(2, 1)
(3, 1)
(3, 0)
(2, 0)
(1, 0)
(0, 0)
i want to save the output in a .txt, but that is not a problem, my problem is that the .txt must be formmated like this:
(0, 3), (0, 2)
(0, 2), (0, 1)
(0, 1),(1, 1)
(1, 1),(1, 2)
(1, 2),(2, 2)
.....
i've tried many things but nothing worked..
it must be easy, but i am new to python
thank you in advance
This does the trick:
l = [(0, 3), (0, 2), (0, 1), (1, 1), (1, 2), (2, 2)]
for i in range(0, len(l), 2):
print(', '.join([str(l[i]), str(l[i+1])]))
# (0, 3), (0, 2)
# (0, 1), (1, 1)
# (1, 2), (2, 2)
You can use zip.
mylist = [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
# That doesn't have to be the numbers though, you can use your own.
for a, b in zip(mylist, mylist[1:]):
print("{}, {}".format(a, b), file = myfile) # Will print to myfile.
That's assuming that you are printing to an open file. Leave the file argument out if you don't want to print anywhere else, but the default screen.
in myfile.txt:
(0, 0), (0, 1)
(0, 1), (0, 2)
(0, 2), (1, 0)
(1, 0), (1, 1)
(1, 1), (1, 2)
(1, 2), (2, 0)
(2, 0), (2, 1)
(2, 1), (2, 2)
The output is in tuples, not lists.
Well, besides other answers playing with indices, you can also use zip:
for a, b, c, d in zip(List, List[1:], List[2:], List[3:]):
print('({}, {}), ({}, {})'.format(a, b, c, d))
Regarding expected output:
l = [(0, 3), (0, 2), (0, 1), (1, 1), (1, 2), (2, 2)]
for i,j in zip(l,l[1:]):
print str(i) + "," + str(j) # or print ",".join([str(i),str(j)])
#output
(0, 3),(0, 2)
(0, 2),(0, 1)
(0, 1),(1, 1)
(1, 1),(1, 2)
(1, 2),(2, 2)
If you want list chunking with 2 elements,Try this
def chunks(l, n):
for i in xrange(0, len(l), n):
yield l[i:i+n]
for i,j in list(chunks(l,2)):
print ",".join([str(i),str(j)])
#output
(0, 3),(0, 2)
(0, 1),(1, 1)
(1, 2),(2, 2)
Your code:
for i in range(0,len(List)):
print("".join(["(%d, %d) \n" % (y[i], y[i+1]) for y in (List)]))
Turning this into a list comp.
t = ["".join(["(%d, %d) \n" % (y[i], y[i+1]) for y in (List)]) for i in range(0,len(List))]
(equivalent to)
s = []
for i in range(0,len(List)):
s.append("".join(["(%d, %d) \n" % (y[i], y[i+1]) for y in (List)]))
Then:
first = True
other = None
r = ""
for i in t:
if not first:
r += other+", "+i+"\n"
first = True
else:
other = i
first = False
f = open("out.txt","w")
f.write(t)
f.close() #go to notepad

Python itertools.product reorder the generation

I have this:
shape = (2, 4) # arbitrary, could be 3 dimensions such as (3, 5, 7), etc...
for i in itertools.product(*(range(x) for x in shape)):
print(i)
# output: (0, 0) (0, 1) (0, 2) (0, 3) (1, 0) (1, 1) (1, 2) (1, 3)
So far, so good, itertools.product advances the rightmost element on every iteration. But now I want to be able to specify the iteration order according to the following:
axes = (0, 1) # normal order
# output: (0, 0) (0, 1) (0, 2) (0, 3) (1, 0) (1, 1) (1, 2) (1, 3)
axes = (1, 0) # reversed order
# output: (0, 0) (1, 0) (2, 0) (3, 0) (0, 1) (1, 1) (2, 1) (3, 1)
If shapes had three dimensions, axes could have been for instance (0, 1, 2) or (2, 0, 1) etc, so it's not a matter of simply using reversed(). So I wrote some code that does that but seems very inefficient:
axes = (1, 0)
# transposed axes
tpaxes = [0]*len(axes)
for i in range(len(axes)):
tpaxes[axes[i]] = i
for i in itertools.product(*(range(x) for x in shape)):
# reorder the output of itertools.product
x = (i[y] for y in tpaxes)
print(tuple(x))
Any ideas on how to properly do this?
Well, this is in fact a manual specialised product. It should be faster since axes are reordered only once:
def gen_chain(dest, size, idx, parent):
# iterate over the axis once
# then trigger the previous dimension to update
# until everything is exhausted
while True:
if parent: next(parent) # StopIterator is propagated upwards
for i in xrange(size):
dest[idx] = i
yield
if not parent: break
def prod(shape, axes):
buf = [0] * len(shape)
gen = None
# EDIT: fixed the axes order to be compliant with the example in OP
for s, a in zip(shape, axes):
# iterate over the axis and put to transposed
gen = gen_chain(buf, s, a, gen)
for _ in gen:
yield tuple(buf)
print list(prod((2,4), (0,1)))
# [(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3)]
print list(prod((2,4), (1,0)))
# [(0, 0), (1, 0), (2, 0), (3, 0), (0, 1), (1, 1), (2, 1), (3, 1)]
print list(prod((4,3,2),(1,2,0)))
# [(0, 0, 0), (1, 0, 0), (0, 0, 1), (1, 0, 1), (0, 0, 2), (1, 0, 2), ...
If you can afford it memory-wise: Let itertools.product do the hard work, and use zip to switch the axes around.
import itertools
def product(shape, axes):
prod_trans = tuple(zip(*itertools.product(*(range(shape[axis]) for axis in axes))))
prod_trans_ordered = [None] * len(axes)
for i, axis in enumerate(axes):
prod_trans_ordered[axis] = prod_trans[i]
return zip(*prod_trans_ordered)
Small test:
>>> print(*product((2, 2, 4), (1, 2, 0)))
(0, 0, 0) (1, 0, 0) (0, 0, 1) (1, 0, 1) (0, 0, 2) (1, 0, 2) (0, 0, 3) (1, 0, 3) (0, 1, 0) (1, 1, 0) (0, 1, 1) (1, 1, 1) (0, 1, 2) (1, 1, 2) (0, 1, 3) (1, 1, 3)
The above version is fast if there are not too may products. For large result sets, the following is faster, but... uses eval (although in a rather safe way):
def product(shape, axes):
d = dict(("r%i" % axis, range(shape[axis])) for axis in axes)
text_tuple = "".join("x%i, " % i for i in range(len(axes)))
text_for = " ".join("for x%i in r%i" % (axis, axis) for axis in axes)
return eval("((%s) %s)" % (text_tuple, text_for), d)
Edit: If you want to not only change the order of iteration, but also the shape (as in the OP's example), small changes are needed:
import itertools
def product(shape, axes):
prod_trans = tuple(zip(*itertools.product(*(range(s) for s in shape))))
prod_trans_ordered = [None] * len(axes)
for i, axis in enumerate(axes):
prod_trans_ordered[axis] = prod_trans[i]
return zip(*prod_trans_ordered)
And the eval version:
def product(shape, axes):
d = dict(("r%i" % axis, range(s)) for axis, s in zip(axes, shape))
text_tuple = "".join("x%i, " % i for i in range(len(axes)))
text_for = " ".join("for x%i in r%i" % (axis, axis) for axis in axes)
return eval("((%s) %s)" % (text_tuple, text_for), d)
Test:
>>> print(*product((2, 2, 4), (1, 2, 0)))
(0, 0, 0) (1, 0, 0) (2, 0, 0) (3, 0, 0) (0, 0, 1) (1, 0, 1) (2, 0, 1) (3, 0, 1) (0, 1, 0) (1, 1, 0) (2, 1, 0) (3, 1, 0) (0, 1, 1) (1, 1, 1) (2, 1, 1) (3, 1, 1)
I don't know how efficient this is, but you should be able to do something like this...
shape = (2, 4, 3)
axes = (2, 0, 1)
# Needed to get the original ordering back
axes_undo = tuple(reversed(axes))
# Reorder the shape in a configuration so that .product will give you
# the order you want.
reordered = tuple(reversed(map(lambda x: shape[x], list(axes))))
# When printing out the results from .product, put the results back
# into the original order.
for i in itertools.product(*(range(x) for x in reordered)):
print(tuple(map(lambda x: i[x], list(axes_undo))))
I tried is up to 4 dimensions and it seems to work. ;)
I'm just swapping the dimensions around and then swapping them back.
Have you tried timing to see how much longer it takes? What you have shouldn't be much slower than without reordering.
You could try modify what you have to use in-place splice assignment.
tpaxes = tuple(tpaxes)
for i in itertools.product(*(range(x) for x in shape)):
# reorder the output of itertools.product
i[:] = (i[y] for y in tpaxes)
print(tuple(x))
Also you could get a speedup by making tpaxes a local variable of a function rather than a global variable (which has slower lookup times)
Otherwise my suggestion is somehow write your own product function..
for i in itertools.product(*(range(x) for x in reversed(shape))):
print tuple(reversed(i))
import itertools
normal = (0, 1)
reverse = (1, 0)
def axes_ordering(x):
a, b = x
return b - a
shape = (2, 4)
for each in itertools.product(*(range(x) for x in shape)):
print(each[::axes_ordering(normal)], each[::axes_ordering(reverse)])
result:
(0, 0) (0, 0)
(0, 1) (1, 0)
(0, 2) (2, 0)
(0, 3) (3, 0)
(1, 0) (0, 1)
(1, 1) (1, 1)
(1, 2) (2, 1)
(1, 3) (3, 1)

Categories

Resources