Hessian Matrix for VBA coding - excel

Does Anyone have the VBA code written for the Hessian matrix to plug two functions? I have it for the jacboan matrix. I have it written using x and y slopes.
`Private Sub Hessian_Click()
Dim x, y, Step, z0, z1, xSlope, ySlope, yxSlope, xySlope
x = Val(InputBox("Input value of x to evaluate derivative at"))
y = Val(InputBox("Input value of y to evaluate derivative at"))
Step = 0.00001
'Step = Val(InputBox("Input step size"))
'Calculate Parital Central derivative of x in first function
z0 = f1xy(x - Step - Step, y)
z1 = f1xy(x + Step + Step, y)
xSlope = (z1 - z0) / (2 * Step)
'Calculate Parital Central derivative of y in first function
z0 = f1xy(x, y - Step - Step)
z1 = f1xy(x, y + Step + Step)
ySlope = (z1 - z0) / (2 * Step)
'Values for first row in Hessian Matrix
Cells(20, 1) = xSlope
Cells(20, 2) = ySlope
'Calculate Parital Central derivative of x in second function
z0 = f2xy(x - Step - Step, y)
z1 = f2xy(x + Step + Step, y)
xSlope = (z1 - z0) / (2 * Step)
'Calculate Parital Central derivative of y in second function
z0 = f2xy(x, y - Step - Step + Step)
z1 = f2xy(x, y + Step + Step - Step)
ySlope = (z1 - z0) / (2 * Step)
yxSlope = (ySlope - xSlope) / (2 * Step)
xySlope = (yxSlope - ySlope - xSlope) / (2 * Step)
'Values for second row in Hessian Matrix
Cells(21, 1) = xSlope
Cells(21, 2) = ySlope
End Sub''

Related

How to write this formula in VBA?

I have this formula to solve.
enter image description here
And here is my code that outputs an error in the formula.
Private Sub CommandButton6_Click()
Dim Z As String
Dim X As Double, Y As Double
Z = InputBox("Input number X!", "Inputing number X"): X = Val(Z)
Y = Sqr(2 * ((X - 2) ^ 2) * ((8 - X) - 1)^1/3
MsgBox ("Y =" + Str(Y))
End Sub
Taking into account when we get negative result under the root
Y = (2 * ((X - 2) ^ 2) * (8 - X) - 1)
If Y >= 0 Then
Y = Y ^ (1 / 3)
Else
Y = -(Abs(Y) ^ (1 / 3))
End If
This is the answer for your 2nd question in comments
Y = (2 * (X ^ 2) * (X - 6))
If Y >= 0 Then
Y = 1 + (Y ^ (1 / 3))
Else
Y = 1 - (Abs(Y) ^ (1 / 3))
End If
You can add round if you want, but haven't seen any rounding used in the image link.

Determening begin parameters 2D gaussian fit

I'm working on some code which needs to be able to preform a 2d gaussian fitting. I mostly based my code on following question: Fitting a 2D Gaussian function using scipy.optimize.curve_fit - ValueError and minpack.error . Now is problem that I don't really have an initial guess about the different parameters that need to be used.
I've tried this:
def twoD_Gaussian(x_data_tuple, amplitude, xo, yo, sigma_x, sigma_y, theta, offset):
(x,y) = x_data_tuple
xo = float(xo)
yo = float(yo)
a = (np.cos(theta)**2)/(2*sigma_x**2) + (np.sin(theta)**2)/(2*sigma_y**2)
b = -(np.sin(2*theta))/(4*sigma_x**2) + (np.sin(2*theta))/(4*sigma_y**2)
c = (np.sin(theta)**2)/(2*sigma_x**2) + (np.cos(theta)**2)/(2*sigma_y**2)
g = offset + amplitude*np.exp( - (a*((x-xo)**2) + 2*b*(x-xo)*(y-yo)
+ c*((y-yo)**2)))
return g.ravel()
The data.reshape(201,201) is just something I took from the aformentioned question.
mean_gauss_x = sum(x * data.reshape(201,201)) / sum(data.reshape(201,201))
sigma_gauss_x = np.sqrt(sum(data.reshape(201,201) * (x - mean_gauss_x)**2) / sum(data.reshape(201,201)))
mean_gauss_y = sum(y * data.reshape(201,201)) / sum(data.reshape(201,201))
sigma_gauss_y = np.sqrt(sum(data.reshape(201,201) * (y - mean_gauss_y)**2) / sum(data.reshape(201,201)))
initial_guess = (np.max(data), mean_gauss_x, mean_gauss_y, sigma_gauss_x, sigma_gauss_y,0,10)
popt, pcov = curve_fit(twoD_Gaussian, (x, y), data, p0=initial_guess)
data_fitted = twoD_Gaussian((x, y), *popt)
If I try this, I get following error message: ValueError: setting an array element with a sequence.
Is the reasoning about the begin parameters correct?
And why do I get this error?
If I use the runnable code from the linked question and substitute your definition of initial_guess:
mean_gauss_x = sum(x * data.reshape(201,201)) / sum(data.reshape(201,201))
sigma_gauss_x = np.sqrt(sum(data.reshape(201,201) * (x - mean_gauss_x)**2) / sum(data.reshape(201,201)))
mean_gauss_y = sum(y * data.reshape(201,201)) / sum(data.reshape(201,201))
sigma_gauss_y = np.sqrt(sum(data.reshape(201,201) * (y - mean_gauss_y)**2) / sum(data.reshape(201,201)))
initial_guess = (np.max(data), mean_gauss_x, mean_gauss_y, sigma_gauss_x, sigma_gauss_y,0,10)
Then
print(inital_guess)
yields
(13.0, array([...]), array([...]), array([...]), array([...]), 0, 10)
Notice that some of the values in initial_guess are arrays. The optimize.curve_fit function expects initial_guess to be a tuple of scalars. This is the source of the problem.
The error message
ValueError: setting an array element with a sequence
often arises when an array-like is supplied when a scalar value is expected. It is a hint that the source of the problem may have to do with an array having the wrong number of dimensions. For example, it might arise if you pass a 1D array to a function that expects a scalar.
Let's look at this piece of code taken from the linked question:
x = np.linspace(0, 200, 201)
y = np.linspace(0, 200, 201)
X, Y = np.meshgrid(x, y)
x and y are 1D arrays, while X and Y are 2D arrays. (I've capitalized all 2D arrays to help distinguish them from 1D arrays).
Now notice that Python sum and NumPy's sum method behave differently when applied to 2D arrays:
In [146]: sum(X)
Out[146]:
array([ 0., 201., 402., 603., 804., 1005., 1206., 1407.,
1608., 1809., 2010., 2211., 2412., 2613., 2814., 3015.,
...
38592., 38793., 38994., 39195., 39396., 39597., 39798., 39999.,
40200.])
In [147]: X.sum()
Out[147]: 4040100.0
The Python sum function is equivalent to
total = 0
for item in X:
total += item
Since X is a 2D array, the loop for item in X is iterating over the rows of X. Each item is therefore a 1D array representing a row of X. Thus, total ends up being a 1D array.
In contrast, X.sum() sums all the elements in X and returns a scalar.
Since initial_guess should be a tuple of scalars,
everywhere you use sum you should instead use the NumPy sum method. For example, replace
mean_gauss_x = sum(x * data) / sum(data)
with
mean_gauss_x = (X * DATA).sum() / (DATA.sum())
import numpy as np
import scipy.optimize as optimize
import matplotlib.pyplot as plt
# define model function and pass independant variables x and y as a list
def twoD_Gaussian(data, amplitude, xo, yo, sigma_x, sigma_y, theta, offset):
X, Y = data
xo = float(xo)
yo = float(yo)
a = (np.cos(theta) ** 2) / (2 * sigma_x ** 2) + (np.sin(theta) ** 2) / (
2 * sigma_y ** 2
)
b = -(np.sin(2 * theta)) / (4 * sigma_x ** 2) + (np.sin(2 * theta)) / (
4 * sigma_y ** 2
)
c = (np.sin(theta) ** 2) / (2 * sigma_x ** 2) + (np.cos(theta) ** 2) / (
2 * sigma_y ** 2
)
g = offset + amplitude * np.exp(
-(a * ((X - xo) ** 2) + 2 * b * (X - xo) * (Y - yo) + c * ((Y - yo) ** 2))
)
return g.ravel()
# Create x and y indices
x = np.linspace(0, 200, 201)
y = np.linspace(0, 200, 201)
X, Y = np.meshgrid(x, y)
# create data
data = twoD_Gaussian((X, Y), 3, 100, 100, 20, 40, 0, 10)
data_noisy = data + 0.2 * np.random.normal(size=data.shape)
DATA = data.reshape(201, 201)
# add some noise to the data and try to fit the data generated beforehand
mean_gauss_x = (X * DATA).sum() / (DATA.sum())
sigma_gauss_x = np.sqrt((DATA * (X - mean_gauss_x) ** 2).sum() / (DATA.sum()))
mean_gauss_y = (Y * DATA).sum() / (DATA.sum())
sigma_gauss_y = np.sqrt((DATA * (Y - mean_gauss_y) ** 2).sum() / (DATA.sum()))
initial_guess = (
np.max(data),
mean_gauss_x,
mean_gauss_y,
sigma_gauss_x,
sigma_gauss_y,
0,
10,
)
print(initial_guess)
# (13.0, 100.00000000000001, 100.00000000000001, 57.106515650488404, 57.43620227324201, 0, 10)
# initial_guess = (3,100,100,20,40,0,10)
popt, pcov = optimize.curve_fit(twoD_Gaussian, (X, Y), data_noisy, p0=initial_guess)
data_fitted = twoD_Gaussian((X, Y), *popt)
fig, ax = plt.subplots(1, 1)
ax.imshow(
data_noisy.reshape(201, 201),
cmap=plt.cm.jet,
origin="bottom",
extent=(X.min(), X.max(), Y.min(), Y.max()),
)
ax.contour(X, Y, data_fitted.reshape(201, 201), 8, colors="w")
plt.show()

How to find the third vertices of a triangle when lengths are unequal

I have two vertices of a triangle and the lengths are unequal. How to find the third vertex?
Translate all points so that P2 becomes the origin.
Then you solve
x² + y² = d2²
(x - x3)² + (y - y3)² = d3²
(mind the renumbering of d1).
By subtraction of the two equations,
(2x - x3).x3 + (2y - y3).y3 = d2² - d3²
which is a linear equation, of the form
a.x + b.y + c = 0
and in parametric form
x = x0 + b.t
y = y0 - a.t
where (x0, y0) is an arbitrary solution, for instance (- ac / (a² + b²), - bc / (a² + b²)).
Now solve the quadratic equation in t
(x0 + b.t)² + (y0 - a.t)² = d2²
which gives two solutions, and undo the initial translation.
function [vertex_1a, vertex_1b] = third_vertex(x2, y2, x3, y3, d1, d3)
d2 = sqrt((x3 - x2)^2 + (y3 - y2)^2); % distance between vertex 2 and 3
% Orthogonal projection of side 12 onto side 23, calculated unsing
% the Law of cosines:
k = (d2^2 + d1^2 - d3^2) / (2*d2);
% height from vertex 1 to side 23 calculated by Pythagoras' theorem:
h = sqrt(d1^2 - k^2);
% calculating the output: the coordinates of vertex 1, there are two solutions:
vertex_1a(1) = x2 + (k/d2)*(x3 - x2) - (h/d2)*(y3 - y2);
vertex_1a(2) = y2 + (k/d2)*(y3 - y2) + (h/d2)*(x3 - x2);
vertex_1b(1) = x2 + (k/d2)*(x3 - x2) + (h/d2)*(y3 - y2);
vertex_1b(2) = y2 + (k/d2)*(y3 - y2) - (h/d2)*(x3 - x2);
end

How to pass a differentiable function explicitly to T.grad?

Can you please tell, how can I pass various differentiable function to T.grad? I want something like this:
x = T.dscalar('x')
ellipic_paraboloid = x ** 2 + y ** 2
hyperbolic_paraboloid = x ** 2 - y ** 2
gradients = theano.function([function_of_xy, x, y], T.grad(function_of_xy, gx, gy))
gradients(ellipic_paraboloid, 1, 1)
gradients(hyperbolic_paraboloid, 1, 1)

calculating parallel lines in a circle

I am calculating lines (2 sets of coordinates ) ( the purple and green-blue lines ) that are n perpendicular distance from an original line. (original line is pink ) ( distance is the green arrow )
How do I get the coordinates of the four new points?
I have the coordinates of the 2 original points and their angles. ( pink line )
I need it to work if the lines are vertical, or any other orientation.
Right now I am trying to calculate it by:
1. get new point n distance perpendicular to the two old points
2. find where the circle intersects the new line I have defined.
I feel like there is an easier way.
Similarly to #MBo's answer, let's assume that the center is (0,0) and that your initial two points are:
P0 = (x0, y0) and P1 = (x1, y1)
A point on the line P0P1 has the form:
(x, y) = c(x1 - x0, y1 - y0) + (x0, y0)
for some constant c.
Let (u, v) be the normal to the line P0P1:
(u, v) = (y1 - y0, x1 - x0) / sqrt((x1 - x0)^2 + (y1 - y0)^2)
A point on any of the lines parallel to P0P1 has the form:
(x, y) = c(x1 - x0, y1 - y0) + (x0, y0) +/- (u, v)* n {eq 1}
where n is the perpendicular distance between lines and c is a constant.
What remains here is to find the values of c such that (x,y) is on the circle. But these can be calculated by solving the following two quadratic equations:
(c(x1 - x0) + x0 +/- u*n)^2 + (c(y1 - y0) + y0 +/- v*n)^2 = r^2
where r is the radius. Note that these equations can be written as:
c^2(x1 - x0)^2 + 2c(x1 - x0)*(x0 +/- u*n) + (x0 +/- u*n)^2
+ c^2(y1 - y0)^2 + 2c(y1 - y0)*(y0 +/- v*n) + (y0 +/- v*n)^2 = r^2
or
A*c^2 + B*c + D = 0
where
A = (x1 - x0)^2 + (y1 - y0)^2
B = 2(x1 - x0)*(x0 +/- u*n) + 2(y1 - y0)*(y0 +/- v*n)
D = (x0 +/- u*n)^2 + (y0 +/- v*n)^2 - r^2
which are actually two quadratic equations one for each selection of the +/- signs. The 4 solutions of these two equations will give you the four values of c from which you will get the four points using {eq 1}
UPDATE
Here are the two quadratic equations (I've reused the letters A, B and C but they are different in each case):
A*c^2 + B*c + D = 0 {eq 2}
where
A = (x1 - x0)^2 + (y1 - y0)^2
B = 2(x1 - x0)*(x0 + u*n) + 2(y1 - y0)*(y0 + v*n)
D = (x0 + u*n)^2 + (y0 + v*n)^2 - r^2
A*c^2 + B*c + D = 0 {eq 3}
where
A = (x1 - x0)^2 + (y1 - y0)^2
B = 2(x1 - x0)*(x0 - u*n) + 2(y1 - y0)*(y0 - v*n)
D = (x0 - u*n)^2 + (y0 - v*n)^2 - r^2
Let's circle radius is R, circle center is (0,0) (if not, shift all coordinates to simplify math), first chord end is P0=(x0, y0), second chord end is P1=(x1,y1), unknown new chord end is P=(x,y).
Chord length L is
L = Sqrt((x1-x0)^2 + (y1-y0)^2)
Chord ends lie on the circle, so
x^2 + y^2 = R^2 {1}
Doubled area of triangle PP0P1 might be expressed as product of the base and height and through absolute value of cross product of two edge vectors, so
+/- L * n = (x-x0)*(y-y1)-(x-x1)*(y-y0) = {2}
x*y - x*y1 - x0*y + x0*y1 - x*y + x*y0 + x1*y - x1*y0 =
x * (y0-y1) + y * (x1-x0) + (x0*y1-x1*y0)
Solve system of equation {1} and {2}, find coordinates of new chord ends.
(Up to 4 points - two for +L*n case, two for -L*n case)
I cannot claim though that this method is simpler - {2} is essentially an equation of parallel line, and substitution in {1} is intersection with circle.

Resources