PyMC3 Conditioning Random Variable on Multiple Discrete Parents - probability

I recently started doing probabilistic programming using PyMC3. In my scenario, I have 3 random variables: On, Triangle, and X, such that X depends on Triangle and On. Triangle and On both follow Bernoulli distributions, and depending on which value they take, the value of X, which follows a Normal, changes.
I wrote up some mock code to test this concept and the code is not good, mainly because you can't call numpy.isnan() on PyMC3 distributions. I just started working in this framework, and I know I'm not writing code that will run, but I'm posting this here so you can see what I've done.
with pymc3.Model() as model:
on = pymc3.distributions.discrete.Bernoulli('on', p=.7)
x_on = pymc3.distributions.continuous.Normal('x_on', 10, .4)
pTriangle_given_on = 1
pTriangle_given_not_on = .7
pTriangle = pymc3.math.switch(on, pTriangle_given_on, pTriangle_given_not_on)
triangle = pymc3.distributions.discrete.Bernoulli('triangle', p=pTriangle)
name = None
x_triangle = None
if triangle:
name = pymc3.distributions.discrete.Categorical('name', p=[.3, .2, .1, .1, .2, .1])
else:
name = pymc3.distributions.discrete.Categorical('name', p=[.1, .5, .4])
if on:
x_triangle = pymc3.Deterministic('x_triangle', x_on)
elif triangle:
x_triangle = pymc3.Normal('x_triangle', 5, 1)
else:
x_triangle = numpy.nan
trace = pymc3.sample()
pymc3.plot_posterior(trace)
I'm not sure how to specify the conditional dependence of X on Triangle and On. Any thoughts from you all would be much appreciated.

Related

How to generate a gaussian map with an effective y for an Equator Bias weighing?

I'm trying to add an Equator Bias weighing to an image, for that I'm using a Gaussian distribution and generate a weighing map to fuse it with the image. The following code is used to generate the weights map:
function map = gaussian_map(height, width)
if (width>8000)
density = 8*height;
elseif (width>4000 & width<=8000)
density = 8*height;
elseif (width>2000 & width<=4000)
density = 4*height;
else
density = 2*height;
end
beta = height/2;
for x = 1:height
for y = 1:width
map(x,y) = exp(-(x-beta)*(x-beta)/density);
end
end
end
Which gives something like this :
Update:
As we can see the distribution starts with y = 0. What I need is that this later starts let say y = 0.3 and all weights must be within [0, 1], something that should look like this:
I've done some googling but I couldn't find much information.
Thanks in advance.

Why is Python's Laplacian method different from Research Paper?

I found a Python library for Laplacian Score Feature Selection. But the implementation is seemingly different from the research paper.
I implemented the selection method according to the algorithm from the paper (https://papers.nips.cc/paper/2909-laplacian-score-for-feature-selection.pdf), which is as follows:
However, I found a Python library that implements the Laplacian method (https://github.com/jundongl/scikit-feature/blob/master/skfeature/function/similarity_based/lap_score.py).
So to check that my implementation was correct, I ran both versions on my dataset, and got different answers. In the process of debugging, I saw that the library used different formulas when calculating the affinity matrix (The S matrix from the paper).
The paper uses this formula:
, While the library uses
W_ij = exp(-norm(x_i - x_j)/2t^2)
Further investigation revealed that the library calculates the affinity matrix as follows:
t = kwargs['t']
# compute pairwise euclidean distances
D = pairwise_distances(X)
D **= 2
# sort the distance matrix D in ascending order
dump = np.sort(D, axis=1)
idx = np.argsort(D, axis=1)
idx_new = idx[:, 0:k+1]
dump_new = dump[:, 0:k+1]
# compute the pairwise heat kernel distances
dump_heat_kernel = np.exp(-dump_new/(2*t*t))
G = np.zeros((n_samples*(k+1), 3))
G[:, 0] = np.tile(np.arange(n_samples), (k+1, 1)).reshape(-1)
G[:, 1] = np.ravel(idx_new, order='F')
G[:, 2] = np.ravel(dump_heat_kernel, order='F')
# build the sparse affinity matrix W
W = csc_matrix((G[:, 2], (G[:, 0], G[:, 1])), shape=
n_samples,n_samples))
bigger = np.transpose(W) > W
W = W - W.multiply(bigger) + np.transpose(W).multiply(bigger)
return W
I'm not sure why the library squares each value in the distance matrix. I see that they also do some reordering, and they use a different heat kernel formula.
So I'd just like to know if any of the resources (The paper or the library) are wrong, or if they're somehow equivalent, or if anyone knows why they differ.

cv2 pose estimation using homography matrix

I am trying to calculate the pose of image Y, given image X. Image Y is the same as image X rotated 90ยบ degrees.
1 -So, for starters i find the matches between both images.
2 -Then i store all the good matches.
3 -The homography between the the matches from both images is calculated using cv2.RANSAC.
4 -Then for the X image, i transform the 2d matching points into 3d, adding 0 as the Z axis.
5 -Object points contain all points from matches of original image, while image points contain matches from the training image. Both array of points are filtered using the mask returned by homography.
6 -After that, i use cv2.calibrateCamera with these object points and image points.
7 -Finnaly i use cv2.projectPoints to get the projections of the axis
I know with that until step 5, the results are correct because i use cv2.drawMatches to see the matches. However this may not be the way to get what i want to achieve.
matches = flann.knnMatch(query_image.descriptors, descriptors, k=2)
good = []
for m, n in matches:
if m.distance < 0.70 * n.distance:
good.append(m)
current_good = good
src_pts = np.float32([selected_image.keypoints[m.queryIdx].pt for m in current_good]).reshape(-1, 1, 2)
dst_pts = np.float32([keypoints[m.trainIdx].pt for m in current_good]).reshape(-1, 1, 2)
homography, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
test = np.zeros(((mask.ravel() > 0).sum(), 3),np.float32) #obj points
test1 = np.zeros(((mask.ravel() > 0).sum(), 2), np.float32) #img points
i=0
counter=0
for m in current_good:
if mask.ravel()[i] == 1:
test[counter][0] = selected_image.keypoints[m.queryIdx].pt[0]
test[counter][1] = selected_image.keypoints[m.queryIdx].pt[1]
test1[counter][0] = selected_image.keypoints[m.trainIdx].pt[0]
test1[counter][1] = selected_image.keypoints[m.trainIdx].pt[1]
counter+=1
i+=1
gray = cv2.cvtColor(self.train_image, cv2.COLOR_BGR2GRAY)
gray = np.float32(gray)
#here start my doubts about what i want to do and if it is possible to do it this way
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera([test], [test1], gray.shape[::-1], None, None)
axis = np.float32([[3, 0, 0], [0, 3, 0], [0, 0, -3]]).reshape(-1, 3)
rvecs = np.array(rvecs, np.float32)
tvecs = np.array(tvecs, np.float32)
imgpts, jac = cv2.projectPoints(axis, rvecs, tvecs, mtx, dist)
However after all this, imgpts returned by cv2.projectPoints give results that don't make much sense to me, like :
[[[857.3185 109.317406]]
[[857.2196 108.360954]]
[[857.2846 107.579605]]]
I would like to have a normal to my image like it is shown here https://docs.opencv.org/trunk/d7/d53/tutorial_py_pose.html and i successfully got it to work using the chessboard image. But trying to adapt to a general image is giving me strange results.

Creating graphics for euclidean instances of TSP

I'm currently working on research centring around the Travelling Salesman Problem. More precisely I'm working with sample data using the EUC_2D edge weight type. Like the following:
1 11003.611100 42102.500000
2 11108.611100 42373.888900
3 11133.333300 42885.833300
I am able to produce a tour order. For example, 2-3-1.
I'd like to be able to create some simple graphics which represent a point set for a given problem, and then a point set with a tour over the top. Could anyone recommend a simple method of achieving this - what software should I be looking at to achieve this.
Thanks
Just to give you a quick demo on how the usual scientific plotting-tools would work (assuming i understood your task correctly):
Plot-only code using python & matplotlib:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2, sharex=True, sharey=True) # Prepare 2 plots
ax[0].set_title('Raw nodes')
ax[1].set_title('Optimized tour')
ax[0].scatter(positions[:, 0], positions[:, 1]) # plot A
ax[1].scatter(positions[:, 0], positions[:, 1]) # plot B
start_node = 0
distance = 0.
for i in range(N):
start_pos = positions[start_node]
next_node = np.argmax(x_sol[start_node]) # needed because of MIP-approach used for TSP
end_pos = positions[next_node]
ax[1].annotate("",
xy=start_pos, xycoords='data',
xytext=end_pos, textcoords='data',
arrowprops=dict(arrowstyle="->",
connectionstyle="arc3"))
distance += np.linalg.norm(end_pos - start_pos)
start_node = next_node
textstr = "N nodes: %d\nTotal length: %.3f" % (N, distance)
props = dict(boxstyle='round', facecolor='wheat', alpha=0.5)
ax[1].text(0.05, 0.95, textstr, transform=ax[1].transAxes, fontsize=14, # Textbox
verticalalignment='top', bbox=props)
plt.tight_layout()
plt.show()
Output:
This code is based on data of the following form:
A 2d-array positions of shape (n_points, n_dimension) like:
[[ 4.17022005e-01 7.20324493e-01]
[ 1.14374817e-04 3.02332573e-01]
[ 1.46755891e-01 9.23385948e-02]
[ 1.86260211e-01 3.45560727e-01]
[ 3.96767474e-01 5.38816734e-01]]
A 2d-array x_sol which is our MIP-solution marking ~1 when node x is followed by y in our solution-tour, like:
[[ 0.00000000e+00 1.00000000e+00 -3.01195977e-11 2.00760084e-11
2.41495095e-11]
[ -2.32741108e-11 1.00000000e+00 1.00000000e+00 5.31351363e-12
-6.12644932e-12]
[ 1.18655962e-11 6.52816609e-12 0.00000000e+00 1.00000000e+00
1.42473796e-11]
[ -4.19937042e-12 3.40039727e-11 2.47921345e-12 0.00000000e+00
1.00000000e+00]
[ 1.00000000e+00 -2.65096995e-11 3.55630808e-12 7.24755899e-12
1.00000000e+00]]
Bigger example, solved with MIP-gap = 5%; meaning: the solution is guaranteed to be at most 5% worse than the optimum (one could see the sub-optimal part in the right where some crossing is happening):
Complete code including fake TSP-data and solving available here.
I going to recommend Baby X. (It's my own windowing system).
It's a windows system that runs on either Linux or MS Windows, and is designed for exactly this type of problem - quickly prototyping a program with a few simple graphics.
Baby X exposes rgba surfaces. You then draw into the buffer, either using your own routines, the Baby X basic routines (lines and polygons), or the Baby X graphics context (fully fledged Bezier-based 2D graphics). It's very quick to set up. You'll obviously have to scale your graph to pixel space, plot symbols for the cities, then draw lines between them to represent the tour.
https://github.com/MalcolmMcLean/babyx
However there are several graphics systems out there. You just have to choose one that runs on your hardware pltform.

Equation to calculate different speeds for fade animation

I'm trying to add a fade effect to my form by manually changing the opacity of the form but I'm having some trouble calculating the correct value to increment by the Opacity value of the form.
I know I could use the AnimateWindow API but it's showing some unexpected behavior and I'd rather do it manually anyways as to avoid any p/invoke so I could use it in Mono later on.
My application supports speeds ranging from 1 to 10. And I've manually calculated that for a speed of 1 (slowest) I should increment the opacity by 0.005 and for a speed of 10 (fastest) I should increment by 0.1. As for the speeds between 1 and 10, I used the following expression to calculate the correct value:
double opSpeed = (((0.1 - 0.005) * (10 - X)) / (1 - 10)) + 0.1; // X = [1, 10]
I though this could give me a linear value and that that would be OK. However, for X equal 4 and above, it's already too fast. More than it should be. I mean, speeds between 7, and 10, I barely see a difference and the animation speed with these values should be a little more spaced
Note that I still want the fastest increment to be 0.1 and the slowest 0.005. But I need all the others to be linear between them.
What I'm doing wrong?
It actually makes sense why it works like this, for instance, for a fixed interval between increments, say a few milliseconds, and with the equation above, if X = 10, then opSpeed = 0.1 and if X = 5, then opSpeed = 0.47. If we think about this, a value of 0.1 will loop 10 times and a value of 0.47 will loop just the double. For such a small interval of just a few milliseconds, the difference between these values is not that much as to differentiate speeds from 5 to 10.
I think what you want is:
0.005 + ((0.1-0.005)/9)*(X-1)
for X ranging from 1-10
This gives a linear scale corresponding to 0.005 when X = 1 and 0.1 when X = 10
After the comments below, I'm also including my answer fit for a geometric series instead of a linear scale.
0.005 * (20^((X-1)/9)))
Results in a geometric variation corresponding to 0.005 when X = 1 and 0.1 when X = 10
After much more discussion, as seen in the comments below, the updates are as follows.
#Nazgulled found the following relation between my geometric series and the manual values he actually needed to ensure smooth fade animation.
The relationship was as follows:
Which means a geometric/exponential series is the way to go.
After my hours of trying to come up with the appropriate curve fitting to the right hand side graph and derive a proper equation, #Nazgulled informed me that Wolfram|Alpha does that. Seriously amazing. :)
Wolfram Alpha link
He should have what he wants now, barring very high error from the equation above.
Your problem stems from the fact that the human eye is not linear in its response; to be precise, the eye does not register the difference between a luminosity of 0.05 to 0.10 to be the same as the luminosity difference between 0.80 and 0.85. The whole topic is complicated; you may want to search for the phrase "gamma correction" for some additional information. In general, you'll probably want to find an equation which effectively "gamma corrects" for human ocular response, and use that as your fading function.
It's not really an answer, but I'll just point out that everyone who's posted so far, including the original question, are all posting the same equation. So with four independent derivations, maybe we should assume that the equation was probably correct.
I did the algebra, but here's the code to verify (in Python, btw, with offsets added to separate the curves:
from pylab import *
X = arange(1, 10, .1)
opSpeed0 = (((0.1 - 0.005) * (10 - X)) / (1 - 10)) + 0.1 # original
opSpeed1 = 0.005 + ((0.1-0.005)/9)*(X-1) # Suvesh
opSpeed2 = 0.005*((10-X)/9.) + 0.1*(X-1)/9. # duffymo
a = (0.1 - 0.005) / 9 #= 0.010555555555... # Roger
b = 0.005 - a #= -0.00555555555...
opSpeed3 = a*X+b
nonlinear01 = 0.005*2**((2*(-1 + X))/9.)*5**((-1 + X)/9.)
plot(X, opSpeed0)
plot(X, opSpeed1+.001)
plot(X, opSpeed2+.002)
plot(X, opSpeed3+.003)
plot(X, nonlinear01)
show()
Also, at Nazgulled's request, I've included the non-linear curve suggested by Suvesh (which also, btw, looks quite alot like a gamma correction curve, as suggested by McWafflestix). The Suvesh's nonlinear equation is in the code as nonlinear01.
Here's how I'd program that linear relationship. But first I'd like to make clear what I think you're doing.
You want the rate of change in opacity to be a linear function of speed:
o(v) = o1*N1(v) + o2*N2(v) so that 0 <= v <=1 and o(v1) = o1 and o(v2) = o2.
If we choose N1(v) to equal 1-v and N2(v) = v we end up with what you want:
o(v) = o1*(1-v) + o2*v
So, plugging in your values:
v = (u-1)/(10-1) = (u-1)/9
o1 = 0.005 and o2 = 0.1
So the function should look like this:
o(u) = 0.005*{1-(u-1)/9} + 0.1*(u-1)/9
o(u) = 0.005*{(9-u+1)/9} + 0.1*(u-1)/9
o(u) = 0.005*{(10-u)/9} + 0.1(u-1)/9
You can simplify this until you get a simple formula for o(u) where 1 <= u <= 10. Should work fine.
If I understand what you're after, you want the equation of a line which passes through these two points in the plane: (1, 0.005) and (10, 0.1). The general equation for such a line (as long as it is not vertical) is y = ax+b. Plug the two points into this equation and solve the resulting set of two linear equations to get
a = (0.1 - 0.005) / 9 = 0.010555555555...
b = 0.005 - a = -0.00555555555...
Then, for each integer x = 1, 2, 3, ..., 10, plug x into y = ax+b to compute y, the value you want.

Resources