List [0-1] to binary representation fast - python-3.x

I am trying to convert the rows [0-1] of a matrix to representation in number (binary equivalent), the code I have is the following:
import numpy as np
def generate_binary_matrix(matrix):
result = []
for i in matrix:
val = '0b' + ''.join([str(x) for x in i])
result.append(int(val, 2))
result = np.array(result)
return result
initial_matrix = np.array([[0, 1, 0], [1, 0, 0], [0, 0, 1]])
result = generate_binary_matrix(initial_matrix )
print(result)
This code works but it is very slow, does anyone know how to do it in a faster way?

You can convert a 0/1 list to binary using just arithmetic, which should be faster:
from functools import reduce
b = reduce(lambda r, x: 2*r + x, i)

Suppose you matrix numpy array is A with m rows and n columns.
Create a b vector with nelements by:
b = np.power(2, np.arange(n))[::-1]
then your answer is A # b
Example:
import numpy as np
A = np.array([[0, 0, 1], [1, 0, 1]])
n = A.shape[1]
b = np.power(2, np.arange(n))[::-1]
print(A # b) # --> [1 5]
update - I reversed b as the MSB (2^n-1) is A[:,0] + power arguments were mistakenly flipped + add an example.

Related

IPython: Audio: concating list to add chords results in one single chord not several played one-by-one: `+=` vs `append`

I am completetly new to IPython hence I am sorry in case this is totally obvious:
import IPython.display as ipd
import scipy
from scipy import signal as sp
import math
import numpy as np
I defined two functions which should help me generate chords:
def f_k(f_0, k):
return f_0*2**((k%12)/12)
def h_k(k, f0, t):
return math.sin(2*math.pi*f_k(f0, k)*t)
F = 44000
T = 2
f0 = 440
N = F*T
I define H0:
H0 = []
for k in [0,4,7]:
H0.append([h_k(k, f0, t) for t in np.linspace(0, T, N)])
ipd.Audio(H0, rate=F)
and it plays 2 seconds as expected because of the discretization through linspace.
I defined a few several chords and I wanted to concat the lists to get several chords (I expected the sound to be 8 secs long)
H5 = []
for k in [5,9,12]:
H5.append([h_k(k, f0, t) for t in np.linspace(0, T, N)])
H7 = []
for k in [7, 11, 14]:
H7.append([h_k(k, f0, t) for t in np.linspace(0, T, N)])
H9 = []
for k in [5,9,16]:
H9.append([h_k(k, f0, t) for t in np.linspace(0, T, N)])
added_sample = []
for h in [H0, H7, H9, H5]:
added_sample += h
ipd.Audio(added_sample, rate=F)
Yet the sound is somehow 2secs long. Could someone explain how to add chords insted of 'layering' them? Any hint would be greatly appreciated!
Maybe this small example will help you see the different between append and +=:
For each we run:
In [54]: alist = [1,2,3]; blist = [4,5]
append adds one item to the list:
In [55]: alist.append(blist); alist
Out[55]: [1, 2, 3, [4, 5]]
+= is a list join:
In [57]: alist += blist; alist
Out[57]: [1, 2, 3, 4, 5]
and is the equivalent of extend:
In [59]: alist.extend(blist); alist
Out[59]: [1, 2, 3, 4, 5]
The non-in-place version of extend:
In [61]: alist + blist
Out[61]: [1, 2, 3, 4, 5]

Efficient method to compute the row-wise dot product of two square matrices of the same size in PyTorch

Supposing I have two square matrices A, B of the same size
A = torch.tensor([[1, 2], [3, 4]])
B = torch.tensor([[1, 1], [1, 1]])
And I want a resulting tensor that consists of the row-wise dot product, say
tensor([3, 7]) # i.e. (1*1 + 2*1, 3*1 + 4*1)
What is an efficient means of achieving this in PyTorch?
As you said you can use torch.bmm but you first need to broadcast your inputs:
>>> torch.bmm(A[..., None, :], B[..., None])
tensor([[[3]],
[[7]]])
Alternatively you can use torch.einsum:
>>> torch.einsum('ij,ij->i', A, B)
tensor([3, 7])
import torch
import numpy as np
def row_wise_product(A, B):
num_rows, num_cols = A.shape[0], A.shape[1]
prod = torch.bmm(A.view(num_rows, 1, num_cols), B.view(num_rows, num_cols, 1))
return prod
A = torch.tensor(np.array([[1, 2], [3, 4]]))
B = torch.tensor(np.array([[1, 1], [1, 1]]))
C = row_wise_product(A, B)

How to generate multi class test dataset using numpy?

I want to generate a multi class test dataset using numpy only for a classification problem.
For example X is a numpy array of dimension(mxn), y of dimension(mx1) and let's say there are k no. of classes. Please help me with the code.
[Here X represents the features and y represents the labels]
You can use np.random.randint like:
import numpy as np
m = 4
n = 4
k = 5
X = np.random.randint(0,2,(m,n))
X
array([[1, 1, 1, 1],
[1, 0, 0, 1],
[1, 1, 0, 0],
[1, 1, 1, 1]])
y = np.random.randint(0,k,m)
y
array([3, 3, 0, 4])
You can create multi class dataset using numpy as follows -
def generate_dataset(size, classes=2, noise=0.5):
# Generate random datapoints
labels = np.random.randint(0, classes, size)
x = (np.random.rand(size) + labels) / classes
y = x + np.random.rand(size) * noise
# Reshape data in order to merge them
x = x.reshape(size, 1)
y = y.reshape(size, 1)
labels = labels.reshape(size, 1)
# Merge the data
data = np.hstack((x, y, labels))
return data
When visualised with matplotlib generated data will look like following -
You can change the number of classes and spread of data using classes and noise parameter. Here I have kept linear relation between x-axis and y-axis values which can also be changed as per requirement.

Clip parts of a tensor

I have a theano tensor and I would like to clip its values, but each index to a different range.
For example, if I have a vector [a,b,c] , I want to clip a to [0,1] , clip b to [2,3] and c to [3,5].
How can I do that efficiently?
Thanks!
The theano.tensor.clip operation supports symbolic minimum and maximum values so you can pass three tensors, all of the same shape, and it will perform an element-wise clip of the first with respect to the second (minimum) and third (maximum).
This code shows two variations on this theme. v1 requires the minimum and maximum values to be passed as separate vectors while v2 allows the minimum and maximum values to be passed more like a list of pairs, represented as a two column matrix.
import theano
import theano.tensor as tt
def v1():
x = tt.vector()
min_x = tt.vector()
max_x = tt.vector()
y = tt.clip(x, min_x, max_x)
f = theano.function([x, min_x, max_x], outputs=y)
print f([2, 1, 4], [0, 2, 3], [1, 3, 5])
def v2():
x = tt.vector()
min_max = tt.matrix()
y = tt.clip(x, min_max[:, 0], min_max[:, 1])
f = theano.function([x, min_max], outputs=y)
print f([2, 1, 4], [[0, 1], [2, 3], [3, 5]])
def main():
v1()
v2()
main()

Unable to create lambda function in hierarchical pymc3 model

I'm trying to create the model shown below with PyMC 3 but can't figure out how to properly map probabilities to the observed data with a lambda function.
import numpy as np
import pymc as pm
data = np.array([[0, 0, 1, 1, 2],
[0, 1, 2, 2, 2],
[2, 2, 1, 1, 0],
[1, 1, 2, 0, 1]])
(D, W) = data.shape
V = len(set(data.ravel()))
T = 3
a = np.ones(T)
b = np.ones(V)
with pm.Model() as model:
theta = [pm.Dirichlet('theta_%s' % i, a, shape=T) for i in range(D)]
z = [pm.Categorical('z_%i' % i, theta[i], shape=W) for i in range(D)]
phi = [pm.Dirichlet('phi_%i' % i, b, shape=V) for i in range(T)]
w = [pm.Categorical('w_%i_%i' % (i, j),
p=lambda z=z[i][j], phi_=phi: phi_[z], # Error is here
observed=data[i, j])
for i in range(D) for j in range(W)]
The error I get is
AttributeError: 'function' object has no attribute 'shape'
In the model I'm attempting to build, the elements of z indicate which element in phi gives the probability of the corresponding observed value in data (placed in RV w). In other words,
P(data[i,j]) <- phi[z[i,j]][data[i,j]]
I'm guessing I need to define the probability with a Theano expression or use Theano as_op but I don't see how it can be done for this model.
You should specify your categorical p values as Deterministic objects before passing them on to w. Otherwise, the as_op implementation would look something like this:
#theano.compile.ops.as_op(itypes=[t.lscalar, t.dscalar, t.dscalar],otypes=[t.dvector])
def p(z=z, phi=phi):
return [phi[z[i,j]] for i in range(D) for j in range(W)]

Resources