Quantum walk on 3D grid - quantum-computing

I am trying to apply the quantum coin walk on a 3D grid, with 3 Hadamard coins. However I can't seem to get symmetric results after 3 steps. Is it simply not possible to have a probability distribution which is symmetric with such a coin?
Thank you
ps the implementation is based on http://susan-stepney.blogspot.com/2014/02/mathjax.html and the position vector captures a 3D grid.
pps Has this been attempted on qiskit? I couldn't use the hard coded matrix to get result perfectly symmetric for some reasons...

Not sure I answered your question, but
from the code reference you mentioned, I only changed line 30 to:ax = fig.add_subplot(111, projection = '3d') and line 3 to:from mpl_toolkits.mplot3d import Axes3D
from numpy import *
from matplotlib.pyplot import *
from mpl_toolkits.mplot3d import Axes3D
N = 100 # number of random steps
P = 2*N+1 # number of positions
coin0 = array([1, 0]) # |0>
coin1 = array([0, 1]) # |1>
C00 = outer(coin0, coin0) # |0><0|
C01 = outer(coin0, coin1) # |0><1|
C10 = outer(coin1, coin0) # |1><0|
C11 = outer(coin1, coin1) # |1><1|
C_hat = (C00 + C01 + C10 - C11)/sqrt(2.)
ShiftPlus = roll(eye(P), 1, axis=0)
ShiftMinus = roll(eye(P), -1, axis=0)
S_hat = kron(ShiftPlus, C00) + kron(ShiftMinus, C11)
U = S_hat.dot(kron(eye(P), C_hat))
posn0 = zeros(P)
posn0[N] = 1 # array indexing starts from 0, so index N is the central posn
psi0 = kron(posn0,(coin0+coin1*1j)/sqrt(2.))
psiN = linalg.matrix_power(U, N).dot(psi0)
prob = empty(P)
for k in range(P):
posn = zeros(P)
posn[k] = 1
M_hat_k = kron( outer(posn,posn), eye(2))
proj = M_hat_k.dot(psiN)
prob[k] = proj.dot(proj.conjugate()).real
fig = figure()
ax = fig.add_subplot(111, projection = '3d')
plot(arange(P), prob)
plot(arange(P), prob, 'o')
loc = range(0, P, P // 10) #Location of ticks
xticks(loc)
xlim(0, P)
ax.set_xticklabels(range(-N, N+1, P // 10))
show()

Related

equivalent of numpy.c_ in julia

Hi I am going through the book https://nnfs.io/ but using JuliaLang (it's a self-challenge to get to know the language better and use it more often.. rather than doing the same old same in Python..)
I have come across a part of the book in which they have custom wrote some function and I need to recreate it in JuliaLang...
source: https://cs231n.github.io/neural-networks-case-study/
python
N = 100 # number of points per class
D = 2 # dimensionality
K = 3 # number of classes
X = np.zeros((N*K,D)) # data matrix (each row = single example)
y = np.zeros(N*K, dtype='uint8') # class labels
for j in range(K):
ix = range(N*j,N*(j+1))
r = np.linspace(0.0,1,N) # radius
t = np.linspace(j*4,(j+1)*4,N) + np.random.randn(N)*0.2 # theta
X[ix] = np.c_[r*np.sin(t), r*np.cos(t)]
y[ix] = j
# lets visualize the data:
plt.scatter(X[:, 0], X[:, 1], c=y, s=40, cmap=plt.cm.Spectral)
plt.show()
my julia version so far....
N = 100 # Number of points per class
D = 2 # Dimensionality
K = 3 # Number of classes
X = zeros((N*K, D))
y = zeros(UInt8, N*K)
# See https://docs.julialang.org/en/v1/base/math/#Base.range
for j in range(0,length=K)
ix = range(N*(j), length = N+1)
radius = LinRange(0.0, 1, N)
theta = LinRange(j*4, (j+1)*4, N) + randn(N)*0.2
X[ix] = ????????
end
notice the ??????? area because I am now trying to decipher if Julia has an equivalent for this numpy function
https://numpy.org/doc/stable/reference/generated/numpy.c_.html
Any help is appreciated.. or just tell me if I need to write something myself
This is a special object to provide nice syntax for column concatanation. In Julia this is just built into the language hence you can do:
julia> a=[1,2,3];
julia> b=[4,5,6];
julia> [a b]
3×2 Matrix{Int64}:
1 4
2 5
3 6
For your case the Julian equivalent of np.c_[r*np.sin(t), r*np.cos(t)] should be:
[r .* sin.(t) r .* cos.(t)]
To understand Python's motivation you can also have a look at :
numpy.r_ is not a function. What is it?
The equivalent of numpy.c_ would seem to be horizontal concatenation, which you can do with either the hcat function or with (e.g.) simply [a b]. Fixing a few other issues with the translation so far, we end up with
N = 100 # Number of points per class
D = 2 # Dimensionality
K = 3 # Number of classes
X = zeros(N*K, D)
y = zeros(UInt8, N*K)
for j in range(0,length=K)
ix = (N*j+1):(N*(j+1))
radius = LinRange(0.0, 1, N)
theta = LinRange(j*4, (j+1)*4, N) + randn(N)*0.2
X[ix,:] .= [radius.*sin.(theta) radius.*cos.(theta)]
y[ix] .= j
end
# visualize the data:
using Plots
scatter(X[:,1], X[:,2], zcolor=y, framestyle=:box)

How can i concatenate three 2D arrays which contain hue, saturation and intensity values in their respective arrays and display that as an image?

I am new to image processing and python. As you can see from my code, i managed to convert my RGB image to HSI by using the different formulas that i found.
I stored the values of hue, saturation and intensity in three different arrays. That is also in the code down below. How can i concatenate those three arrays and display the concatenated image as an image?
import math
from PIL import Image
img = Image.open("D:\\Texture analysis\\trees-clolorful-aerial-view-wallpaper.jpg")
rgb_img = img.convert('RGB')
row, col = img.size
print(row, col)
i = j = 0
satValue = 0
inValue = 0
hueValue = 0
squareValue = 0
hueArray = [[0 for x in range(row)] for y in range(col)]
satArray = [[0 for x in range(row)] for y in range(col)]
inArray = [[0 for x in range(row)] for y in range(col)]
division = 0
denominator = 0
numerator = 0
radAngle = 0
degAngle = 0
product = 0
sqr = 0
count = 0
uCount = 0
while i < row:
j = 0
while j < col:
red, green, blue = rgb_img.getpixel((i, j))
hRed = sRed = iRed = red
hGreen = sGreen = iGreen = green
hBlue = sBlue = iBlue = blue
# =========================Saturation Calculation==============================
if sRed == 0 and sGreen == 0 and sBlue == 0:
satValue = 0
satArray[i][j] = 0
else:
if (sRed < sGreen) and (sRed < sBlue):
satValue = 1 - (((3) * (sRed)) / (sRed + sGreen + sBlue))
satArray[i][j] = satValue
# print(satValue)
elif (sGreen < sRed) and (sGreen < sBlue):
satValue = 1 - (((3) * (sGreen)) / (sRed + sGreen + sBlue))
satArray[i][j] = satValue
# print(satValue)
else:
satValue = 1 - (((3) * (sBlue)) / (sRed + sGreen + sBlue))
satArray[i][j] = satValue
# print(satValue)
# =============================================================================
# ==========================Intensity Calculation==============================
inValue = (iRed + iGreen + iBlue) / 3
inArray[i][j] = inValue
count += 1
print(inValue, count)
# =============================================================================
# =============================Hue Calculation=================================
product = (hRed - hBlue) * (hGreen - hBlue)
sqr = (hRed - hGreen) * (hRed - hGreen)
denominator = math.sqrt(sqr + product)
if denominator != 0:
numerator = ((hRed - hGreen) + (hRed - hBlue)) / 2
division = numerator / denominator
radAngle = math.acos(division)
degAngle = math.degrees(radAngle)
if hBlue <= hGreen:
hueValue = degAngle
hueArray[i][j] = hueValue
elif hBlue > hGreen:
hueValue = 360 - degAngle
hueArray[i][j] = hueValue
elif denominator == 0:
hueValue = 0
hueArray[i][j] = hueValue
#print(hueValue, count)
# =============================================================================
j += 1
i += 1 print(i, j)
PS. You will be seeing a lot of my amateur code in the future as well :D
I can see what's going wrong now I am back at a computer. You probably tried this:
#!/usr/bin/env python3
from PIL import Image
img = Image.open('start.png')
hsvimg = img.convert('HSV')
hsvimg.save('result.png')
And if you do that, you actually get an error message:
OSError: cannot write mode HSV as PNG
because, PNG images are always in sRGB colourspace, so it correctly declines to write your HSV image. The thing is though, that the colourspace conversion actually worked and the values in the image actually are the HSV values that you want. You can check this with:
img.getpixel((X,Y))
and
hsvimg.getpixel((X,Y))
where X and Y are any random coordinates you like. You will see the the latter is always the correct HSV representation of the former's RGB colour.
I am not sure what you are trying to do overall, so I can't really advise properly, but one thing you could do is "lie through your teeth" and tell PIL/Pillow that the image is RGB even though you know it is HSV. So if you do:
hsvimg = img.convert('HSV')
hsvimg.mode='RGB' # Tell PIL image is RGB
hsvimg.save('result.png')
it will save an image but it, and all other viewers, will show your Hue as Blue, your Saturation as Green and your Value as Blue.
I am guessing you have other processing to do, and this is only an intermediate aspect of your processing, so it probably won't matter and you can probably carry on and do your processing and convert back at the end and save to an sRGB PNG file without needing to lie.
In answer to your actual question, you can split and merge channels like this with PIL/Pillow:
# Split and recombine with PIL
r,g,b = img.split()
merged = Image.merge(mode='RGB',bands=(r,g,b)))
Or, if you prefer Numpy which is often faster:
# Open image as Numpy array
img = np.array(Image.open('start.png'))
# Split into 3 channels/arrays/bands
r = img[:, :, 0]
g = img[:, :, 1]
b = img[:, :, 2]
# Recombine to single image
merged = np.dstack((r, g, b))

numpy binned mean, conserving extra axes

It seems I am stuck on the following problem with numpy.
I have an array X with shape: X.shape = (nexp, ntime, ndim, npart)
I need to compute binned statistics on this array along npart dimension, according to the values in binvals (and some bins), but keeping all the other dimensions there, because I have to use the binned statistic to remove some bias in the original array X. Binning values have shape binvals.shape = (nexp, ntime, npart).
A complete, minimal example, to explain what I am trying to do. Note that, in reality, I am working on large arrays and with several hunderds of bins (so this implementation takes forever):
import numpy as np
np.random.seed(12345)
X = np.random.randn(24).reshape(1,2,3,4)
binvals = np.random.randn(8).reshape(1,2,4)
bins = [-np.inf, 0, np.inf]
nexp, ntime, ndim, npart = X.shape
cleanX = np.zeros_like(X)
for ne in range(nexp):
for nt in range(ntime):
indices = np.digitize(binvals[ne, nt, :], bins)
for nd in range(ndim):
for nb in range(1, len(bins)):
inds = indices==nb
cleanX[ne, nt, nd, inds] = X[ne, nt, nd, inds] - \
np.mean(X[ne, nt, nd, inds], axis = -1)
Looking at the results of this may make it clearer?
In [8]: X
Out[8]:
array([[[[-0.20470766, 0.47894334, -0.51943872, -0.5557303 ],
[ 1.96578057, 1.39340583, 0.09290788, 0.28174615],
[ 0.76902257, 1.24643474, 1.00718936, -1.29622111]],
[[ 0.27499163, 0.22891288, 1.35291684, 0.88642934],
[-2.00163731, -0.37184254, 1.66902531, -0.43856974],
[-0.53974145, 0.47698501, 3.24894392, -1.02122752]]]])
In [10]: cleanX
Out[10]:
array([[[[ 0. , 0.67768523, -0.32069682, -0.35698841],
[ 0. , 0.80405255, -0.49644541, -0.30760713],
[ 0. , 0.92730041, 0.68805503, -1.61535544]],
[[ 0.02303938, -0.02303938, 0.23324375, -0.23324375],
[-0.81489739, 0.81489739, 1.05379752, -1.05379752],
[-0.50836323, 0.50836323, 2.13508572, -2.13508572]]]])
In [12]: binvals
Out[12]:
array([[[ -5.77087303e-01, 1.24121276e-01, 3.02613562e-01,
5.23772068e-01],
[ 9.40277775e-04, 1.34380979e+00, -7.13543985e-01,
-8.31153539e-01]]])
Is there a vectorized solution? I thought of using scipy.stats.binned_statistic, but I seem to be unable to understand how to use it for this aim. Thanks!
import numpy as np
np.random.seed(100)
nexp = 3
ntime = 4
ndim = 5
npart = 100
nbins = 4
binvals = np.random.rand(nexp, ntime, npart)
X = np.random.rand(nexp, ntime, ndim, npart)
bins = np.linspace(0, 1, nbins + 1)
d = np.digitize(binvals, bins)[:, :, np.newaxis, :]
r = np.arange(1, len(bins)).reshape((-1, 1, 1, 1, 1))
m = d[np.newaxis, ...] == r
counts = np.sum(m, axis=-1, keepdims=True).clip(min=1)
means = np.sum(X[np.newaxis, ...] * m, axis=-1, keepdims=True) / counts
cleanX = X - np.choose(d - 1, means)
Ok, I think I got it, mainly based on the answer by #jdehesa.
clean2 = np.zeros_like(X)
d = np.digitize(binvals, bins)
for i in range(1, len(bins)):
m = d == i
minds = np.where(m)
sl = [*minds[:2], slice(None), minds[2]]
msum = m.sum(axis=-1)
clean2[sl] = (X - \
(np.sum(X * m[...,np.newaxis,:], axis=-1) /
msum[..., np.newaxis])[..., np.newaxis])[sl]
Which gives the same results as my original code.
On the small arrays I have in the example here, this solution is approximately three times as fast as the original code. I expect it to be way faster on larger arrays.
Update:
Indeed it's faster on larger arrays (didn't do any formal test), but despite this, it just reaches the level of acceptable in terms of performance... any further suggestion on extra vectoriztaions would be very welcome.

Counting points in an array that meet certain conditions

I am having trouble getting my code to count the correct number of elements from three different arrays, with each array having its own parameter. I would like the element to be counted if its meets all three parameters this is what I have so far
import numpy as np
import random as rand
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
n = 10
x0 = np.zeros(n)
y0 = np.zeros(n)
z0 = np.zeros(n)
x1 = np.zeros(n)
y1 = np.zeros(n)
z1 = np.zeros(n)
hit = 0
for k in range (n):
theta = rand.uniform(0.0, np.pi)
phi = rand.uniform(0, (2 * np.pi))
x0[k] = np.sin(phi) * np.cos(theta)
y0[k] = np.sin(phi) * np.sin(theta)
z0[k] = np.cos(theta)
for j in range (n):
theta = rand.uniform(0.0, np.pi)
phi = rand.uniform(0, (2 * np.pi))
x1[j] = np.sin(phi) * np.cos(theta)
y1[j] = np.sin(phi) * np.sin(theta)
z1[j] = np.cos(theta)
for i in range(n):
if np.any(x1[j] > -0.3) and np.any(x1[j] < 0.7) and np.any(y1[j] > -0.3) and np.any(y1[j] <0.7) and np.any(z1[j] > -0.3) and np.any(z1[j] < 0.3):
hit += 1
ax.plot_wireframe([x0[k],x1[j]],[y0[k],y1[j]],[z0[k],z1[j]])
print (hit)
print (x1,y1,z1)
plt.show()
I would like for only the end points to be counted if they meet the three parameters.
Thank you

How to make softmax work with policy gradient?

I am trying to change Karpathy's code so that it works with softmax function so that I can use it for game with more than 2 actions. However, I cannot get it to work. Can someone help point me to the right direction please? Thanks. Below is my attempt.
""" Trains an agent with (stochastic) Policy Gradients on Pong. Uses OpenAI Gym. """
import numpy as np
import cPickle as pickle
import gym
# hyperparameters
H = 100 # number of hidden layer neurons
batch_size = 10 # every how many episodes to do a param update?
learning_rate = 1e-4
gamma = 0.9 # discount factor for reward
decay_rate = 0.9 # decay factor for RMSProp leaky sum of grad^2
resume = False # resume from previous checkpoint?
render = False
num_action = 2
# model initialization
D = 6 # input dimensionality: 80x80 grid
if resume:
model = pickle.load(open('save.p', 'rb'))
else:
model = {}
model['W1'] = np.random.randn(H,D) / np.sqrt(D) # "Xavier" initialization
model['W2'] = np.random.randn(num_action, H) / np.sqrt(H)
grad_buffer = { k : np.zeros_like(v) for k,v in model.iteritems() } # update buffers that add up gradients over a batch
rmsprop_cache = { k : np.zeros_like(v) for k,v in model.iteritems() } # rmsprop memory
def sigmoid(x):
return 1.0 / (1.0 + np.exp(-x)) # sigmoid "squashing" function to interval [0,1]
def softmax(w, t = 1.0):
e = np.exp(np.array(w) / t)
dist = e / np.sum(e)
return dist
def prepro(I):
""" prepro 210x160x3 uint8 frame into 6400 (80x80) 1D float vector """
I = I[35:195] # crop
I = I[::2,::2,0] # downsample by factor of 2
I[I == 144] = 0 # erase background (background type 1)
I[I == 109] = 0 # erase background (background type 2)
I[I != 0] = 1 # everything else (paddles, ball) just set to 1
return I.astype(np.float).ravel()
def discount_rewards(r):
""" take 1D float array of rewards and compute discounted reward """
discounted_r = np.zeros_like(r)
running_add = 0
for t in reversed(xrange(0, r.size)):
if r[t] != 0: running_add = 0 # reset the sum, since this was a game boundary (pong specific!)
running_add = running_add * gamma + r[t]
discounted_r[t] = running_add
return discounted_r
def policy_forward(x):
h = np.dot(model['W1'], x)
h[h<0] = 0 # ReLU nonlinearity
logp = np.dot(model['W2'], h)
p = softmax(logp)
return p, h # return probability of taking action 2, and hidden state
def policy_backward(eph, epdlogp):
""" backward pass. (eph is array of intermediate hidden states) """
# print eph.shape
# print epdlogp.shape
# print model['W2'].shape
# dW2 = np.dot(eph.T, epdlogp).ravel()
# dh = np.outer(epdlogp, model['W2'])
# dh[eph <= 0] = 0 # backpro prelu
# dW1 = np.dot(dh.T, epx)
# return {'W1':dW1, 'W2':dW2}
dW2 = np.dot(eph.T, epdlogp).T
# print dW2.shape
dh = np.dot(epdlogp, model['W2'])
# print dh.shape
dh[eph <= 0] = 0 # backpro prelu
dW1 = np.dot(dh.T, epx)
return {'W1':dW1, 'W2':dW2}
env = gym.make("Acrobot-v1")
observation = env.reset()
prev_x = None # used in computing the difference frame
xs,hs,dlogps,drs = [],[],[],[]
running_reward = None
reward_sum = 0
episode_number = 0
while True:
if render: env.render()
# preprocess the observation, set input to network to be difference image
cur_x = observation
x = cur_x - prev_x if prev_x is not None else np.zeros(D)
prev_x = cur_x
# forward the policy network and sample an action from the returned probability
aprob, h = policy_forward(x)
action = np.argmax(aprob)
if action == 1:
action = 2
# action = 2 if np.random.uniform() > aprob[1] else 0
# print aprob
# action = 2 if np.random.uniform() < aprob else 3 # roll the dice!
# record various intermediates (needed later for backprop)
xs.append(x) # observation
hs.append(h) # hidden state
# if action == 0:
# y = [1,0,0]
# elif action == 1:
# y = [0,1,0]
# else:
# y = [0,0,1]
y = [1,0] if action == 0 else [0,1] # a "fake label"
dlogps.append(aprob-y) # grad that encourages the action that was taken to be taken (see http://cs231n.github.io/neural-networks-2/#losses if confused)
# step the environment and get new measurements
observation, reward, done, info = env.step(action)
reward_sum += reward
drs.append(reward) # record reward (has to be done after we call step() to get reward for previous action)
if done: # an episode finished
episode_number += 1
# stack together all inputs, hidden states, action gradients, and rewards for this episode
epx = np.vstack(xs)
eph = np.vstack(hs)
epdlogp = np.vstack(dlogps)
epr = np.vstack(drs)
xs,hs,dlogps,drs = [],[],[],[] # reset array memory
# compute the discounted reward backwards through time
discounted_epr = discount_rewards(epr)
# standardize the rewards to be unit normal (helps control the gradient estimator variance)
discounted_epr -= np.mean(discounted_epr)
discounted_epr /= np.std(discounted_epr)
epdlogp *= discounted_epr # modulate the gradient with advantage (PG magic happens right here.)
grad = policy_backward(eph, epdlogp)
for k in model: grad_buffer[k] += grad[k] # accumulate grad over batch
# perform rmsprop parameter update every batch_size episodes
if episode_number % batch_size == 0:
for k,v in model.iteritems():
g = grad_buffer[k] # gradient
rmsprop_cache[k] = decay_rate * rmsprop_cache[k] + (1 - decay_rate) * g**2
model[k] += learning_rate * g / (np.sqrt(rmsprop_cache[k]) + 1e-5)
grad_buffer[k] = np.zeros_like(v) # reset batch gradient buffer
# boring book-keeping
running_reward = reward_sum if running_reward is None else running_reward * 0.99 + reward_sum * 0.01
print 'resetting env. episode reward total was %f. running mean: %f' % (reward_sum, running_reward)
if episode_number % 100 == 0: pickle.dump(model, open('save.p', 'wb'))
reward_sum = 0
observation = env.reset() # reset env
prev_x = None
When debugging, this code runs into a "nan" issue which I can't figure out how to fix.
I think the NaN problem that you mention in a comment is due to your Softmax function.
Softmax computes the exponential function, exp(x) which can easily exceed the range of single or double precision floats for moderate values of x. This would cause exp to return NaN.
Solution
The mathematical form of Softmax is:
s[i] = exp(x[i]) / (exp(x[0]) + exp(x[1]) + .. + exp(x[n-1]))
We can divide the numerator and denominator of this expression by an arbitrary value, say exp(a) without affecting the result.
s[i] = (exp(x[i])/exp(a)) / ((exp(x[0]) + exp(x[1]) + .. + exp(x[n-1])/exp(a)))
s[i] = exp(x[i]-a) / (exp(x[0]-a) + exp(x[1]-a) + .. + exp(x[n-1]-a))
If we let a = max(x) then all exponents will be zero or negative, so no call to exp will return NaN.
I don't use Python or numpy, but I imagine you could define softmax something like:
def softmax(w):
a = np.max(w)
e = np.exp(np.array(w) - a)
dist = e / np.sum(e)
return dist

Resources