hey i'm working with streamlit application and i have a problem on the part of optimisation function, I got as a results of the function the initial guess i don't know what the problem here is my function
def cons1(k):
y1 = k[0]
y2 = k[1]
return y2 - y1 - 0.0000000000000000000000000000000000000000000001
def cons2(k):
y1 = k[0]
y2 = k[1]
return y2 - s - 0.0000000000000000000000000000000000000000000001
def cons3(k):
y1 = k[0]
y2 = k[1]
return s - y1 - 0.0000000000000000000000000000000000000000000001
def arrivé(k):
y1 = k[0]
y2 = k[1]
return (BS_PUT(s, y2, T1, rd, rf, sigma1) - BS_CALL(s, y1, T1, rd, rf, sigma1)) ** 2
guess = [s, s]
cons3 = ({'type': 'ineq', 'fun': cons1,'type':'ineq','fun': cons2, 'type':'ineq','fun': cons3})
optimize2 = sci_opt.minimize(arrivé, guess, method='SLSQP', constraints=cons3, options={'disp': True})
this = optimize2.x[0]
that = optimize2.x[1]
#st.markdown(this)
#st.markdown(that)
g = BS_CALL(s, this, T1, rd, rf, sigma1)
#st.markdown(g)
f = BS_PUT(s, that, T1, rd, rf, sigma1)
Related
I have a function with 4 inputs (x1, x2, x3, x4) and 2 outputs (y1, y2) using Tensorflow. I would like to specify the gradients, since I perform some non-autodiff operations inside the function.
I need to specify the derivatives of the outputs with respect to the inputs. We can see these derivatives as a Jacobian of size (2,4). Regarding this, I have 8 derivatives: dy1_dx1, dy1_dx2, dy1_dx3, dy1_dx4, dy2_dx1, dy2_dx2, dy2_dx3 and dy2_dx4.
However, the grad function used in this tf.custom.gradient needs to have the same length as the inputs, this is 4. So, I do not know how to express 8 derivatives using just 4 elements. I tried to include them as lists, but it gives the error. Here is a general code to reproduce the error:
import tensorflow as tf
#tf.custom_gradient
def bar(x1, x2, x3, x4):
def grad(dy1, dy2):
dy1_dx1 = x2**2 * x3**3 * x4**4 #360000
dy1_dx2 = x1 * 2*x2 * x3**3 * x4**4 #480000
dy1_dx3 = x1 * x2**2 * 3*x3**2 * x4**4 #540000
dy1_dx4 = x1 * x2**2 * x3**3 * 4*x4**3 #576000
dy2_dx1 = x2**2 + x3**3 + x4**4 #698
dy2_dx2 = x1 + 2*x2 + x3**3 + x4**4 #697
dy2_dx3 = x1 + x2**2 + 3*x3**2 + x4**4 #684
dy2_dx4 = x1 + x2**2 + x3**3 + 4*x4**3 #575
return [dy1_dx1, dy2_dx1], [dy1_dx2, dy2_dx2], [dy1_dx3, dy2_dx3], [dy1_dx4, dy2_dx4]
y1 = x1 * x2**2 * x3**3 * x4**4
y2 = x1 + x2**2 + x3**3 + x4**4
return [y1, y2], grad
x1 = tf.constant(2.0, dtype=tf.float32)
x2 = tf.constant(3.0, dtype=tf.float32)
x3 = tf.constant(4.0, dtype=tf.float32)
x4 = tf.constant(5.0, dtype=tf.float32)
with tf.GradientTape(persistent=True) as tape:
tape.watch(x1)
tape.watch(x2)
tape.watch(x3)
tape.watch(x4)
z = bar(x1, x2, x3, x4)
print(tape.gradient(z, x1)) #[dy1_dx1, dy2_dx1]
print(tape.gradient(z, x2)) #[dy1_dx2, dy2_dx2]
print(tape.gradient(z, x3)) #[dy1_dx3, dy2_dx3]
print(tape.gradient(z, x4)) #[dy1_dx4, dy2_dx4]
The error says: "custom_gradient function expected to return 4 gradients, but returned 8 instead".
I expect someway to specify the correspondent 8 derivatives. Thank you in advance!
In Code A, the parameters x1 and x2 use the same vaule, it works well.
I think I can improve Code A, so I write Code B, but it failed.
How can I assign x2 with the value of x1 ?
Code A
val stepWidth = step * index
it.drawChildnAxis(
x1 = stepWidth.toX, y1 = 0f.toY,
x2 = stepWidth.toX, y2 = yAxisLength.toY
)
fun Canvas.drawChildnAxis(x1:Float, y1:Float,x2:Float,y2:Float){
drawLine(
Offset(x = x1, y = y1),
Offset(x = x2, y = y2),
paintTableAxisChild
)
}
Code B
it.drawChildnAxis(
x1 = step * index.toX, y1 = 0f.toY,
x2 = x1, y2 = yAxisLength.toY
)
//The same
The x1 = ..., x2 = ... etc in your code are not actually assignment statements! They are named arguments.
There is no variable x1, x2 etc that becomes suddenly in scope at the function call, allowing you to assign values to it. This is just a bit of a syntax that lets you say the names of your parameters to make your code more readable, and sometimes resolve overload resolution ambiguities.
The syntax just so happened to be designed to look similar to assignments, making the left hand side look like a new variable just got declared. Would you still have this confusion if the syntax used : instead of =?
it.drawChildnAxis(
x1: stepWidth.toX, y1: 0f.toY,
x2: stepWidth.toX, y2: yAxisLength.toY
)
So x2 = x1 doesn't make sense - there is no such variable as x1 at that position. x1 is only the name of a parameter, which is only in scope when you are inside drawChildnAxis.
If you want to avoid repetition, just create a new variable yourself!
val x = stepWidth.toX
it.drawChildnAxis(
x1 = x, y1 = 0f.toY,
x2 = x, y2 = yAxisLength.toY
)
If you don't want x to be accessible afterwards, use a scope function:
stepWidth.toX.let { x ->
it.drawChildnAxis(
x1 = x, y1 = 0f.toY,
x2 = x, y2 = yAxisLength.toY
)
}
All of this is of course assuming that toX doesn't have side effects - calling its getter twice on the same thing gives the same value.
I am fitting the following function (variables A, D, μ and τ) and x and E are fixed:
I created some example data using the equation and added some noise. The fit looks very good and has a low chi-squared however the errors from the covariance matrix are odd; some are very large whereas others are smaller. What am I doing wrong?
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
# Constants
E_field = 1
x = 1
def function(t, A, D, μ, τ):
return A/np.sqrt(4*np.pi*D*t) * np.exp(-pow(x-μ*E_field*t, 2)/(4*D*t) - t/τ)
def chi(E, O):
return np.sum(np.ma.masked_invalid(pow(O-E, 2)/E))
def fit(t, n, m, p0):
ddof = n.size - m
popt, pcov = curve_fit(function, t, n, p0=p0)
fitted_n = function(t, *popt)
reduced_χ_squared = chi(n, fitted_n) / ddof
σ = np.sqrt(np.diag(pcov))
return popt, σ, reduced_χ_squared
# Choose random variables to generate data
x, t = 1, np.linspace(0.01, 5, num=100)
A, D, μ, τ = 1, 0.2, 1, 1
n = function(t, A, D, μ, τ)
n_noise = n + 0.005 * np.random.normal(size=n.size)
n_noise += abs(min(n_noise)) # Shift data to lie on y = 0
p0 = [1, 0.25, 1, 1]
vars, σ, reduced_χ_squared = fit(t, n_noise, 4, p0)
fitted_A, fitted_D, fitted_μ, fitted_τ = vars
σ_A, σ_D, σ_μ, σ_τ = σ
fitted_n = function(t, *vars)
fig, ax = plt.subplots()
ax.plot(t, n_noise)
ax.plot(t, fitted_n)
#ax.text(0.82, 0.75, "χᵣ²={:.4f}".format(reduced_χ_squared), transform = ax.transAxes)
ax.legend(["Observed n", "Expected n"])
print("Fitted parameters: A = {:.4f}, D = {:.4f}, μ = {:.4f}, τ = {:.4f}".format(*vars))
print("Fitted parameter errors: σ_A = {:.4f}, σ_D = {:.4f}, σ_μ = {:.4f}, σ_τ = {:.4f}".format(*σ))
print("Reduced χ² = {:.4f}".format(reduced_χ_squared))
Running this code gives me the following output
As mentioned in my comment above, correlation is a big problem here. Biggest problem though is that you fit more parameters than required.
Let us transform:
A = exp( alpha) i.e alpha = log(A)
delta = 4 * D
epsilon = mu * E
We then get:
1 / sqrt( pi* delta ) * exp( -( x**2 + epsilon**2 * t**2 -2*x*epsilon t) / ( delta * t ) -t / tau + alpha )
= 1 / sqrt( pi* delta ) * exp( -( x**2 + epsilon**2 * t**2 -2*x*epsilon t) / ( delta * t ) -delta / tau * t**2/( delta * t) + delta * alpha * t/ ( delta * t ) )
= 1 / sqrt( pi* delta ) * exp( -( x**2 + epsilon**2 * t**2 -2*x*epsilon t + delta / tau * t**2 - delta * alpha * t ) / ( delta * t ) )
= 1 / sqrt( pi* delta ) * exp( -( x**2 + ( epsilon**2 + delta / tau ) * t**2 -x * ( 2 * epsilon + delta * alpha ) * t ) / ( delta * t ) )
now renaming:
( epsilon**2 + delta / tau ) -> gamma**2
( 2 * epsilon + delta * alpha ) -> eta
we get
= 1 / sqrt( pi * delta ) * exp( -( x**2 + gamma**2 * t**2 - x * eta * t ) / ( delta * t ) )
So there are actually only 3 parameters to fit and it looks like this:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
# Constants
E_field = 1
x = 1
def function(t, A, D, μ, τ):
return A/np.sqrt(4*np.pi*D*t) * np.exp(-pow(x-μ*E_field*t, 2)/(4*D*t) - t/τ)
def alt_func( t, gamma, eta, delta ):
return np.exp( -( x**2 + gamma**2 * t**2 - eta * t ) / ( delta * t ) ) / np.sqrt( np.pi * delta * t )
# Choose random variables to generate data
x, t = 1, np.linspace(0.01, 5, num=100)
A, D, μ, τ = 1, 0.2, 1, 1
n = function(t, A, D, μ, τ)
n_noise = n + 0.005 * np.random.normal(size=n.size)
n_noise += abs(min(n_noise)) # Shift data to lie on y = 0
guess=[1.34, 2, .8]
palt, covalt = curve_fit( alt_func, t, n_noise)
print( covalt )
print( palt )
yt = alt_func( t, *palt )
yg = alt_func( t, *guess )
yorg = function( t, A, D, μ, τ )
fig, ax = plt.subplots()
ax.plot(t, n_noise)
ax.plot(t, yg )
ax.plot(t, yt, ls="--")
ax.plot(t, yorg, ls=":" )
plt.show()
This has a reasonable covariance matrix. One can get the original parameters easily via error propagation.
Altzernatively, it should be enough to fix A=1 and only fit the three left parameters in the original function.
Concerning the transformation and back calculation one has to keep in mind that this is of course from R³ to R⁴, so it is naturally not unique either. Again one can just fix one value, or one might to try to spread the error evenly between the parameters or who knows....
Long story short: I'm writing script, which should move mouse and do clicks like human (it's a bot, actually), using SikuliX. SikuliX uses Jython 2.7 as lang for scritps.
I found nice lib for my purposes (moving mouse like human): mouse.simba written in Pascal-like lang, and rewrite function _humanWindMouse() in jython. It works, but not like I expected it would be.
Test run of my script, drawing rectangle:
https://prtscr.cx.ua/storage/5b/5b2203.jpg
Result of using original function with same coords:
https://prtscr.cx.ua/storage/bb/bb3ff5.jpg
sorry for links, I can't post images yet (
My code:
import random
import time
import math
from time import sleep
from math import sqrt
from math import ceil
from math import hypot
from java.awt import Robot
def distance(x1, y1, x2, y2):
return math.hypot(x2 - x1, y2 - y1)
def myrandom(x):
return random.randint(0, x-1)
def myround(x):
return int(round(x))
# function MMouseMove (MyMouseMove) for moving mouse using only coord
def MMouseMove(x,y):
robot = Robot()
robot.mouseMove(x,y)
# function HumanWindMouse by BenLand100 & Flight, python implementation
def humanWindMouse(xs, ys, xe, ye, gravity, wind):
veloX = veloY = windX=windY=veloMag=dist=randomDist=lastDist=D=0
lastX=lastY=MSP=W=TDist=0
mouseSpeed = 20
MSP = mouseSpeed
sqrt2 = sqrt(2)
sqrt3 = sqrt(3)
sqrt5 = sqrt(5)
TDist = distance(myround(xs), myround(ys), myround(xe), myround(ye))
t = time.time() + 10000
while True:
if time.time() > t:
break
dist = hypot(xs - xe, ys - ye)
wind = min(wind, dist)
if dist < 1:
dist = 1
D = (myround((myround(TDist)*0.3))/7)
if D > 25:
D = 25
if D < 5:
D = 5
rCnc = myrandom(6)
if rCnc == 1:
D = random.randint(2,3)
if D <= myround(dist):
maxStep = D
else:
maxStep = myround(dist)
windX= windX / sqrt2
windY= windY / sqrt2
veloX= veloX + windX
veloY= veloY + windY
veloX= veloX + gravity * (xe - xs) / dist
veloY= veloY + gravity * (ye - ys) / dist
if hypot(veloX, veloY) > maxStep:
temp = int(myround(maxStep) // 2)
if temp == 0:
temp = 1
randomDist= maxStep / 2.0 + myrandom(temp)
veloMag= sqrt(veloX * veloX + veloY * veloY)
veloX= (veloX / veloMag) * randomDist
veloY= (veloY / veloMag) * randomDist
lastX= myround(xs)
lastY= myround(ys)
xs= xs + veloX
ys= ys + veloY
if lastX <> myround(xs) or lastY <> myround(ys):
MMouseMove(myround(xs), myround(ys))
W = (myrandom((myround(100/MSP)))*6)
if W < 5:
W = 5
W = myround(W*0.9)
sleep(W/1000.0)
lastdist= dist
if hypot(xs - xe, ys - ye) < 1:
break
if myround(xe) <> myround(xs) or myround(ye) <> myround(ys):
MMouseMove(myround(xe), myround(ye))
mouseSpeed = MSP
return;
def MMouse(x,y):
mouseSpeed = 20
randSpeed = (myrandom(mouseSpeed) / 2.0 + mouseSpeed) / 10.0
curPos = Mouse.at()
x1 = curPos.x
y1 = curPos.y
humanWindMouse(x1, y1, x, y, 5, 10.0/randSpeed)
return;
And I used this in such a way:
MMouseMove(227, 146)
mouseDown(Button.LEFT)
MMouse(396, 146)
MMouse(396, 252)
MMouse(227, 252)
MMouse(227, 146)
mouseUp(Button.LEFT)
exit()
mouseDown() and mouseUp() are built-in functions in SikuliX
And I didn't use built-in mouseMove(), because with it going from A to B is too slow.
Any help would be appreciated
After few hours of debugging i figured out the problem: in source code for unknowing reason author passed constant called MOUSE_HUMAN to variable named gravity when caling his function _humanWindMouse(), this looks like an error to me. Thats why I decided to fix this in my code, and throw out one argument of the function and a few lines of code (and that was wrong move). After re-adding needed code my function working, as I expected.
So, here's the working code:
# function HumanWindMouse by BenLand100 & Flight,
# python implementation by Nokse
def humanWindMouse(xs, ys, xe, ye, gravity, wind, targetArea):
veloX = veloY = windX=windY=veloMag=dist=randomDist=lastDist=D=0
lastX=lastY=MSP=W=TDist=0
mouseSpeed = 20
MSP = mouseSpeed
sqrt2 = sqrt(2)
sqrt3 = sqrt(3)
sqrt5 = sqrt(5)
TDist = distance(myround(xs), myround(ys), myround(xe), myround(ye))
t = time.time() + 10000
while True:
if time.time() > t:
break
dist = hypot(xs - xe, ys - ye)
wind = min(wind, dist)
if dist < 1:
dist = 1
D = (myround((myround(TDist)*0.3))/7)
if D > 25:
D = 25
if D < 5:
D = 5
rCnc = myrandom(6)
if rCnc == 1:
D = random.randint(2,3)
if D <= myround(dist):
maxStep = D
else:
maxStep = myround(dist)
if dist >= targetArea:
windX = windX / sqrt3 + (myrandom(myround(wind) * 2 + 1) - wind) / sqrt5
windY = windY / sqrt3 + (myrandom(myround(wind) * 2 + 1) - wind) / sqrt5
else:
windX = windX / sqrt2
windY = windY / sqrt2
veloX = veloX + windX
veloY = veloY + windY
veloX = veloX + gravity * (xe - xs) / dist
veloY = veloY + gravity * (ye - ys) / dist
if hypot(veloX, veloY) > maxStep:
halfSteps = int(myround(maxStep) // 2)
if halfSteps == 0:
halfSteps = 1
randomDist = maxStep / 2.0 + myrandom(halfSteps)
veloMag = sqrt(veloX * veloX + veloY * veloY)
veloX = (veloX / veloMag) * randomDist
veloY = (veloY / veloMag) * randomDist
lastX = myround(xs)
lastY = myround(ys)
xs = xs + veloX
ys = ys + veloY
if lastX <> myround(xs) or lastY <> myround(ys):
MMouseMove(myround(xs), myround(ys))
W = (myrandom((myround(100/MSP)))*6)
if W < 5:
W = 5
W = myround(W*0.9)
sleep(W/1000.0)
lastdist = dist
#condition for exiting while loop
if hypot(xs - xe, ys - ye) < 1:
break
if myround(xe) <> myround(xs) or myround(ye) <> myround(ys):
MMouseMove(myround(xe), myround(ye))
mouseSpeed = MSP
return;
I tested it with different parameters, and choose this one:
humanWindMouse(xs, ys, x, y, 9, 10.0/randSpeed, 10.0*randSpeed)
but I recommend to play with parameters first, to understand, how do they affect the behavior of the mouse.
How to calc randSpeed, what should be imported, and sub-functions, such as myround(), could be found at my first post.
Hope, this code will help somebody someday)
My program works with matplotlib and calculates envelopes in y-z-section. This can be done for several sections and will be plotted as a 3dplot in a diagram. It is also quite easy to show an envelopes with a wireframe design.
Now i want to write a stl-file. For this i need to have a mesh. I have found a module its named numpy-stl that provides these functionality but i need to create the mesh.
Now i have found out that matplotlib has already included the functionality of creation a mesh.
Has someone experiences with this? Here is my code so far. Data comes from dictionary in the form: {'X' : {'Y' : [], 'Z' : []}}.
def lines_draw(self):
self.plot_data.clear()
self.plot_data = publish('3D_DATA_PLOT')
self.plot_Handling = []
a = []
x_keys = []
x_keys_collect1 = []
x_keys_collect2 = []
#print(self.plot_data)
_big_list_X = []
_big_list_Y = []
_big_list_Z = []
big_list_X = []
big_list_Y = []
big_list_Z = []
# Draw the section-lines
for key,val in self.plot_data.items():
a.clear()
for i in range(len(self.plot_data[key]['Y'])):
a.append(key)
x = np.array(a)
y = np.array(self.plot_data[key]['Y'])
z = np.array(self.plot_data[key]['Z'])
x = x.astype(np.float)
y = y.astype(np.float)
z = z.astype(np.float)
linesdraw, = self.ax.plot(x,y,z)
self.plot_Handling.append(linesdraw)
x_keys = list(self.plot_data)
dict_length = len(x_keys)
a=1
# Draw the wireframes
for i in range(dict_length-1):
x_keys_collect1.clear()
x_keys_collect2.clear()
for xi in self.plot_data[x_keys[i]]['Y']:
x_keys_collect1.append(x_keys[i])
a = a + 1
for xi in self.plot_data[x_keys[i+1]]['Y']:
x_keys_collect2.append(x_keys[i+1])
x1 = np.array(x_keys_collect1)
y1 = np.array(self.plot_data[x_keys[i]]['Y'])
z1 = np.array(self.plot_data[x_keys[i]]['Z'])
x2 = np.array(x_keys_collect2)
y2 = np.array(self.plot_data[x_keys[i+1]]['Y'])
z2 = np.array(self.plot_data[x_keys[i+1]]['Z'])
x1 = x1.astype(np.float)
y1 = y1.astype(np.float)
z1 = z1.astype(np.float)
x2 = x2.astype(np.float)
y2 = y2.astype(np.float)
z2 = z2.astype(np.float)
# i1, h1 = np.meshgrid(np.arange(a-1), np.linspace(x1[0],x2[0],5))
# print(np.linspace(x1[0],x2[0],5))
# i1 = i1.astype(np.int)
# h1 = h1.astype(np.int)
# X = (y2[i1] - y1[i1]) / (x2 - x1) * (h1 - x1) + y1[i1]
# Y = (z2[i1] - z1[i1]) / (x2 - x1) * (h1 - x1) + z1[i1]
# self.ax.plot_surface(h1,X, Y, color='m', alpha=0.3, linewidth=0)
# y1 = -y1.astype(np.float)
# y2 = -y2.astype(np.float)
# i1, h1 = np.meshgrid(np.arange(a-1), np.linspace(x1[0],x2[0],5))
# i1 = i1.astype(np.int)
# h1 = h1.astype(np.int)
# X = (y2[i1] - y1[i1]) / (x2 - x1) * (h1 - x1) + y1[i1]
# Y = (z2[i1] - z1[i1]) / (x2 - x1) * (h1 - x1) + z1[i1]
# self.ax.plot_surface(h1,X, Y, color='m', alpha=0.3, linewidth=0)
big_list_X = np.array(x_keys_collect1 + x_keys_collect2)
big_list_Y = np.array(self.plot_data[x_keys[i]]['Y'] + self.plot_data[x_keys[i+1]]['Y'])
big_list_Z = np.array(self.plot_data[x_keys[i]]['Z'] + self.plot_data[x_keys[i+1]]['Z'])
big_list_X = big_list_X.astype(np.float)
big_list_Y = big_list_Y.astype(np.float)
big_list_Z = big_list_Z.astype(np.float)
print(big_list_X)
# print(big_list_Y)
# print(big_list_Z)
# big_list_X, big_list_Z = np.meshgrid(big_list_X,big_list_Z)
# big_list_X, big_list_Z = big_list_X.flatten(), big_list_Z.flatten()
# tri = mtri.Triangulation(_big_list_X,_big_list_Z)
print(big_list_X)
# print(big_list_Y)
# print(big_list_Z)
self.ax.plot_trisurf(big_list_X,big_list_Y,big_list_Z, cmap=cm.jet, linewidth=0)#,triangles=tri.triangles)#,cmap=plt.cm.Spectral)
a = 1
# tri = mtri.Triangulation(X,Y)
# self.ax.plot_trisurf(h1,X,Y,triangles=tri.triangles,cmap=plt.cm.Spectral)
self.canvas.draw()