Perform Delta Function between elements in PyTorch tensor - python

I have a 1 dimensional pyTorch tensor (dtype: int32) and was wondering if there was a way to perform a Dirac Delta function on the elements in this tensor, i.e:
f = tensor[1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1]
f_after_dirac_delta = tensor[0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1]
Thanks for any help in advance!
EDIT: as #GirishDattatrayHegde mentioned, the term Dirac-Delta was misleading. The correct term should have been a Kronecker-Delta. My apologies.

If I understand correctly, you want to compare successive elemeents of your tensor. This should work :
import torch
f = torch.tensor([1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1])
f_dirac = (f[1:] == f[:-1]).to(torch.long)

Related

Performing bitwise operations on binary strings made from arrays

Basically I'm trying to grab 1's and 0's values from an array and perform bitwise operations on that.
board = np.array([1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
for x in board:
s += str(x)
s = int(s)
This is obviously not correct however. This has its own binary value and if I perform bitwise operations on it (eg. >>) I'm shifting the underlying binary.
So how can I dynamically create binary strings to perform bitwise operations on?
Any help appreciated.
board = np.array([1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
for x in board:
s += str(x)
s = int(s)
int automatically converts to base 10 but you could also use int(s,2) to convert it to base 2. You'd then get the base 10 representation of your base2 number. So int("110",2) would be 6 and 6<<2 would be 24 or 6>>2 would be 1.
Also in terms of making the stringyfication easier yon can use
s = "".join(map(str, board))

Program corresponding to Complete Boolean Lattice *Q_n*

I am first year student of Math faculty, and I didn't have programming class yet.
I am working on a project and to simplify my calculations it would be nice to implement a program that would calculate a matrix corresponding to the complete boolean lattice Q_n, which is a set of n integers from 1 to n and all of its possible subsets.
For example, when n=4 the matrix would be the following:
1;0;0;0;1;1;1;0;0;0;1;1;1;0;1
0;1;0;0;1;0;0;1;1;0;1;1;0;1;1
0;0;1;0;0;1;0;1;0;1;1;0;1;1;1
0;0;0;1;0;0;1;0;1;1;0;1;1;1;1
where first column correspond to the subset {1} of {1,2,3,4}, second column to subset {2} of {1,2,3,4}, column 5 for example to subset {1,2} of {1,2,3,4} and so on.
My idea was to create first all zero matrix of the corresponding size and then I do not know how to proceed. Please help me to get ideas.
The itertools module makes this easy. Here is one way:
import itertools
def subset_matrix(n):
A = [[0]*pow(2,n) for _ in range(n)]
j = 0
for k in range(n+1):
for c in itertools.combinations(range(n),k):
for i in c:
A[i][j] = 1
j += 1
return A
#for example:
A = subset_matrix(4)
for row in A:
print(row)
Output:
[0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1]
[0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1]
[0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1]
[0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1]

finding continuous signal in noisy binary time series

Suppose I have a time series such as:
[1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 , 1, 1, 1, 1]
and I know there is some noise in the signal. I want to remove the noise as best I can and still output a binary signal. The above example would turn into something like:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 1, 1, 1, 1]
I have implemented a naive rule-based approach where I iterate through the values and have some minimum amount of 1s or 0s I need to "swap" the signal.
It seems like there must be a better way to do it. A lot of the results from googling around give non-binary output. Is there some scipy function I could leverage for this?
There are two similar functions that can help you: scipy.signal.argrelmin and scipy.signal.argrelmax. There are search for local min/max in discrete arrays. You should pass your array and neighbours search radius as order. Your problem can be solved by their combination:
>>> a = np.asarray([1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 , 1, 1, 1, 1], int)
>>> signal.argrelmin(a, order=3)
(array([4], dtype=int32),)
>>> signal.argrelmax(a, order=3)
(array([15], dtype=int32),)
Then you can just replace these elements.

Python Image.fromarray() doesn't accept my ndarray input which is built from a list

I'm trying to visualize a list of 2048280 integers which are either 1's or 0's. There is a function that outputs this list from a (width=1515 height=1352) image file. The function
test_results = [(numpy.argmax(SomeFunctionReturningAnArrayForEachGivenPixel))
for y in xrange(1352) for x in range(1532)]
returns an array of size 2058280 (=1515x1352) = as expected. For each y, 1532 values of 1/0 are returned and stored in the array.
Now, when this "test_results" array is returned, I want to save it as an image. So I np.reshape() the array to size (1352,1515,1). All is fine. Logically, I should save this list as a grayscale image. I changed the ndarray data type to 'unit8' and multiplied the pixel values by 127 or 255.
But no matter what I do, the Image.fromarray() function keeps saying that either 'it cannot handle this data type' or 'too many dimensions' or simply gives an error. When I debug it into the Image functions, it looks like the Image library cannot retrieve the array's 'stride'!
All the examples on the net simply reshape the list into an array and save them as an image! Is there anything wrong with my list?
I have already tried various modes ('RGB' , 'L' , '1'). I also changed the data type of my array into uint8, int8, np.uint8(), uint32..
result=self.evaluate(test_data,box) #returns the array
re_array= np.asarray(result,dtype='uint8')
res2 = np.reshape(reray,(1352,1515,1))
res3 =(res2*255)
i = Image.fromarray(res3,'1') ## Raises the exception
i.save('me.png')
For a grayscale image, don't add the trivial third dimension to your array. Leave it as a two-dimensional array: res2 = np.reshape(reray, (1352, 1515)) (assuming reray is the one-dimensional array).
Here's a simple example that worked for me. data is a two-dimensional array with type np.uint8 containing 0s and 1s:
In [29]: data
Out[29]:
array([[0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1],
[0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0],
[1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1],
[1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0],
[1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1],
[1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0],
[0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0],
[1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0],
[1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1],
[0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0]], dtype=uint8)
Create an image from 255*data with mode 'L', and save it as a PNG file:
In [30]: img = Image.fromarray(255*data, mode='L')
In [31]: img.save('foo.png')
When I tried to create the image using mode='1', I wasn't able to get a correct PNG file. Pillow has some known problems with moving between numpy arrays and images with bit depth 1.
Another option is to use numpngw. (I'm the author numpngw.) It allows you to save the data to a PNG file with bit depth 1:
In [40]: import numpngw
In [41]: numpngw.write_png('foo.png', data, bitdepth=1)

How to make a NOR between 2 vectors in python

I have two vectors :
predictions = [0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1]
labels = [0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0]
and I need as an output (using python) the true negatives - NOR of these two vectors.
output = [1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0]
I tried with this command but it throw an error :
print not(predictions & labels)
>>>TypeError: unsupported operand type(s) for &: 'list' and 'list'
What is the correct syntax / command to do such a simple thing ?
Native python does not support vector operation. You have to nand individual element
>>> [int(not (p & l)) for p, l in zip(predictions, labels)]
[1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1]
Off -course if you are using numpy, you can achieve what you are envisaging
>>> np.logical_not(np.logical_and(predictions, labels)).astype(int)
array([1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1])
It is worth noting that your output is not Nand but actually Nor, so you have to apply the operations accordingly
>>> np.logical_not(np.logical_or(predictions, labels)).astype(int)
array([1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0])
Here You have to iterate to every item in the list
c=[int(not i&j) for i,j in zip(predictions,labels)]
The operator & is not defined for operands of type list.
The operator not will return True if len(list>0), if the list is empty it will return false.
Also you need to cast booleans to ints to achieve the required result.
With itertools.imap and the operator module:
from operator import eq,and_,or_,xor
from itertools import imap
predictions = [0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1]
labels = [0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0]
#Logical AND
print [int(e) for e in imap(and_,predictions,labels)]
#Logical NAND
print [int(not e) for e in imap(and_,predictions,labels)]
#Logical OR
print [int(e) for e in imap(or_,predictions,labels)]
#Logical NOR
print [int(not e) for e in imap(or_,predictions,labels)]
#Logical XOR
print [int(e) for e in imap(xor,predictions,labels)]
#Logical not XOR
print [int(not e) for e in imap(xor,predictions,labels)]

Categories