- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
给定两个函数,我想找出两条曲线的公切线:
公切线的斜率可以通过以下方式获得:
slope of common tangent = (f(x1) - g(x2)) / (x1 - x2) = f'(x1) = g'(x2)
所以最后我们有一个包含 2 个方程和 2 个未知数的系统:
f'(x1) = g'(x2) # Eq. 1
(f(x1) - g(x2)) / (x1 - x2) = f'(x1) # Eq. 2
由于某种原因我不明白,python没有找到解决办法:
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
import sys
from sympy import *
import sympy as sym
# Intial candidates for fit
E0_init = -941.510817926696
V0_init = 63.54960592453
B0_init = 76.3746233515232
B0_prime_init = 4.05340727164527
# Data 1 (Red triangles):
V_C_I, E_C_I = np.loadtxt('./1.dat', skiprows = 1).T
# Data 14 (Empty grey triangles):
V_14, E_14 = np.loadtxt('./2.dat', skiprows = 1).T
def BM(x, a, b, c, d):
return (2.293710449E+17)*(1E-21)* (a + b*x + c*x**2 + d*x**3 )
def P(x, b, c, d):
return -b - 2*c*x - 3 *d*x**2
init_vals = [E0_init, V0_init, B0_init, B0_prime_init]
popt_C_I, pcov_C_I = curve_fit(BM, V_C_I, E_C_I, p0=init_vals)
popt_14, pcov_14 = curve_fit(BM, V_14, E_14, p0=init_vals)
x1 = var('x1')
x2 = var('x2')
E1 = P(x1, popt_C_I[1], popt_C_I[2], popt_C_I[3]) - P(x2, popt_14[1], popt_14[2], popt_14[3])
print 'E1 = ', E1
E2 = ((BM(x1, popt_C_I[0], popt_C_I[1], popt_C_I[2], popt_C_I[3]) - BM(x2, popt_14[0], popt_14[1], popt_14[2], popt_14[3])) / (x1 - x2)) - P(x1, popt_C_I[1], popt_C_I[2], popt_C_I[3])
sols = solve([E1, E2], [x1, x2])
print 'sols = ', sols
# Linspace for plotting the fitting curves:
V_C_I_lin = np.linspace(V_C_I[0], V_C_I[-1], 10000)
V_14_lin = np.linspace(V_14[0], V_14[-1], 10000)
plt.figure()
# Plotting the fitting curves:
p2, = plt.plot(V_C_I_lin, BM(V_C_I_lin, *popt_C_I), color='black', label='Cubic fit data 1' )
p6, = plt.plot(V_14_lin, BM(V_14_lin, *popt_14), 'b', label='Cubic fit data 2')
# Plotting the scattered points:
p1 = plt.scatter(V_C_I, E_C_I, color='red', marker="^", label='Data 1', s=100)
p5 = plt.scatter(V_14, E_14, color='grey', marker="^", facecolors='none', label='Data 2', s=100)
plt.ticklabel_format(useOffset=False)
plt.show()
1.dat
如下:
61.6634100000000 -941.2375622594436
62.3429030000000 -941.2377748739724
62.9226515000000 -941.2378903605746
63.0043440000000 -941.2378981684135
63.7160150000000 -941.2378864590100
64.4085050000000 -941.2377753645115
65.1046835000000 -941.2375332100225
65.8049585000000 -941.2372030376584
66.5093925000000 -941.2367456992965
67.2180970000000 -941.2361992239395
67.9311515000000 -941.2355493856510
2.dat
如下:
54.6569312500000 -941.2300821583739
55.3555152500000 -941.2312112888004
56.1392347500000 -941.2326135552780
56.9291575000000 -941.2338291772218
57.6992532500000 -941.2348135408652
58.4711572500000 -941.2356230099117
59.2666985000000 -941.2362715934311
60.0547935000000 -941.2367074271724
60.8626545000000 -941.2370273047416
更新:使用@if....方法:
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
# Intial candidates for fit, per FU: - thus, the E vs V input data has to be per FU
E0_init = -941.510817926696
V0_init = 63.54960592453
B0_init = 76.3746233515232
B0_prime_init = 4.05340727164527
def BM(x, a, b, c, d):
return a + b*x + c*x**2 + d*x**3
def devBM(x, b, c, d):
return b + 2*c*x + 3*d*x**2
# Data 1 (Red triangles):
V_C_I, E_C_I = np.loadtxt('./1.dat', skiprows = 1).T
# Data 14 (Empty grey triangles):
V_14, E_14 = np.loadtxt('./2.dat', skiprows = 1).T
init_vals = [E0_init, V0_init, B0_init, B0_prime_init]
popt_C_I, pcov_C_I = curve_fit(BM, V_C_I, E_C_I, p0=init_vals)
popt_14, pcov_14 = curve_fit(BM, V_14, E_14, p0=init_vals)
from scipy.optimize import fsolve
def equations(p):
x1, x2 = p
E1 = devBM(x1, popt_C_I[1], popt_C_I[2], popt_C_I[3]) - devBM(x2, popt_14[1], popt_14[2], popt_14[3])
E2 = ((BM(x1, popt_C_I[0], popt_C_I[1], popt_C_I[2], popt_C_I[3]) - BM(x2, popt_14[0], popt_14[1], popt_14[2], popt_14[3])) / (x1 - x2)) - devBM(x1, popt_C_I[1], popt_C_I[2], popt_C_I[3])
return (E1, E2)
x1, x2 = fsolve(equations, (50, 60))
print 'x1 = ', x1
print 'x2 = ', x2
slope_common_tangent = devBM(x1, popt_C_I[1], popt_C_I[2], popt_C_I[3])
print 'slope_common_tangent = ', slope_common_tangent
def comm_tangent(x, x1, slope_common_tangent):
return BM(x1, popt_C_I[0], popt_C_I[1], popt_C_I[2], popt_C_I[3]) - slope_common_tangent * x1 + slope_common_tangent * x
# Linspace for plotting the fitting curves:
V_C_I_lin = np.linspace(V_C_I[0], V_C_I[-1], 10000)
V_14_lin = np.linspace(V_14[0], V_14[-1], 10000)
plt.figure()
# Plotting the fitting curves:
p2, = plt.plot(V_C_I_lin, BM(V_C_I_lin, *popt_C_I), color='black', label='Cubic fit Calcite I' )
p6, = plt.plot(V_14_lin, BM(V_14_lin, *popt_14), 'b', label='Cubic fit Calcite II')
xp = np.linspace(54, 68, 100)
pcomm_tangent, = plt.plot(xp, comm_tangent(xp, x1, slope_common_tangent), 'green', label='Common tangent')
# Plotting the scattered points:
p1 = plt.scatter(V_C_I, E_C_I, color='red', marker="^", label='Calcite I', s=100)
p5 = plt.scatter(V_14, E_14, color='grey', marker="^", facecolors='none', label='Calcite II', s=100)
fontP = FontProperties()
fontP.set_size('13')
plt.legend((p1, p2, p5, p6, pcomm_tangent), ("1", "Cubic fit 1", "2", 'Cubic fit 2', 'Common tangent'), prop=fontP)
print 'devBM(x1, popt_C_I[1], popt_C_I[2], popt_C_I[3]) = ', devBM(x1, popt_C_I[1], popt_C_I[2], popt_C_I[3])
plt.ylim(-941.240, -941.225)
plt.ticklabel_format(useOffset=False)
plt.show()
我能够找到公切线,如下所示:
但是这个公切线对应的是数据范围之外的区域的公切线,即用
V_C_I_lin = np.linspace(V_C_I[0]-30, V_C_I[-1], 10000)
V_14_lin = np.linspace(V_14[0]-20, V_14[-1]+2, 10000)
xp = np.linspace(40, 70, 100)
plt.ylim(-941.25, -941.18)
可以看到以下内容:
是否可以将求解器限制在我们拥有数据的范围内,以便找到所需的公切线?
更新 2.1:使用 @if.... 范围约束方法,以下代码产生 x1 = 61.2569899
和 x2 = 59.7677843
。如果我们绘制它:
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
import sys
from sympy import *
import sympy as sym
import os
# Intial candidates for fit, per FU: - thus, the E vs V input data has to be per FU
E0_init = -941.510817926696 # -1882.50963222/2.0
V0_init = 63.54960592453 #125.8532/2.0
B0_init = 76.3746233515232 #74.49
B0_prime_init = 4.05340727164527 #4.15
def BM(x, a, b, c, d):
return a + b*x + c*x**2 + d*x**3
def devBM(x, b, c, d):
return b + 2*c*x + 3*d*x**2
# Data 1 (Red triangles):
V_C_I, E_C_I = np.loadtxt('./1.dat', skiprows = 1).T
# Data 14 (Empty grey triangles):
V_14, E_14 = np.loadtxt('./2.dat', skiprows = 1).T
init_vals = [E0_init, V0_init, B0_init, B0_prime_init]
popt_C_I, pcov_C_I = curve_fit(BM, V_C_I, E_C_I, p0=init_vals)
popt_14, pcov_14 = curve_fit(BM, V_14, E_14, p0=init_vals)
def equations(p):
x1, x2 = p
E1 = devBM(x1, popt_C_I[1], popt_C_I[2], popt_C_I[3]) - devBM(x2, popt_14[1], popt_14[2], popt_14[3])
E2 = ((BM(x1, popt_C_I[0], popt_C_I[1], popt_C_I[2], popt_C_I[3]) - BM(x2, popt_14[0], popt_14[1], popt_14[2], popt_14[3])) / (x1 - x2)) - devBM(x1, popt_C_I[1], popt_C_I[2], popt_C_I[3])
return (E1, E2)
from scipy.optimize import least_squares
lb = (61.0, 59.0) # lower bounds on x1, x2
ub = (62.0, 60.0) # upper bounds
result = least_squares(equations, [61, 59], bounds=(lb, ub))
print 'result = ', result
# The result obtained is:
# x1 = 61.2569899
# x2 = 59.7677843
slope_common_tangent = devBM(x1, popt_C_I[1], popt_C_I[2], popt_C_I[3])
print 'slope_common_tangent = ', slope_common_tangent
def comm_tangent(x, x1, slope_common_tangent):
return BM(x1, popt_C_I[0], popt_C_I[1], popt_C_I[2], popt_C_I[3]) - slope_common_tangent * x1 + slope_common_tangent * x
# Linspace for plotting the fitting curves:
V_C_I_lin = np.linspace(V_C_I[0]-2, V_C_I[-1], 10000)
V_14_lin = np.linspace(V_14[0], V_14[-1]+2, 10000)
fig_handle = plt.figure()
# Plotting the fitting curves:
p2, = plt.plot(V_C_I_lin, BM(V_C_I_lin, *popt_C_I), color='black' )
p6, = plt.plot(V_14_lin, BM(V_14_lin, *popt_14), 'b' )
xp = np.linspace(54, 68, 100)
pcomm_tangent, = plt.plot(xp, comm_tangent(xp, x1, slope_common_tangent), 'green', label='Common tangent')
# Plotting the scattered points:
p1 = plt.scatter(V_C_I, E_C_I, color='red', marker="^", label='1', s=100)
p5 = plt.scatter(V_14, E_14, color='grey', marker="^", facecolors='none', label='2', s=100)
fontP = FontProperties()
fontP.set_size('13')
plt.legend((p1, p2, p5, p6, pcomm_tangent), ("1", "Cubic fit 1", "2", 'Cubic fit 2', 'Common tangent'), prop=fontP)
plt.ticklabel_format(useOffset=False)
plt.show()
我们看到我们没有获得公切线:
最佳答案
您的方程组由一个二次方程和一个三次方程组成。这样的系统没有封闭形式的符号解。事实上,如果有的话,人们就可以通过引入 y = 将其应用于一般的 5 次方程
(二次)并将原始方程重写为 x**5 + a*x**4 + ... = 0
x**2x*y**2 + a*y**2 + ... = 0
(三次)。我们知道 can't be done .所以 SymPy 无法解决也就不足为奇了。您需要一个数值求解器(另一个原因是 SymPy 并不是真正设计用于求解充满浮点常数的方程式,它们对于符号操作来说很麻烦)。
SciPy fsolve是首先想到的。你可以这样做:
def F(x):
x1, x2 = x[0], x[1]
E1 = P(x1, popt_C_I[1], popt_C_I[2], popt_C_I[3]) - P(x2, popt_14[1], popt_14[2], popt_14[3])
E2 = ((BM(x1, popt_C_I[0], popt_C_I[1], popt_C_I[2], popt_C_I[3]) - BM(x2, popt_14[0], popt_14[1], popt_14[2], popt_14[3])) / (x1 - x2)) - P(x1, popt_C_I[1], popt_C_I[2], popt_C_I[3])
return [E1, E2]
print fsolve(F, [50, 60]) # some reasonable initial point
顺便说一句,我会将 (x1-x2) 从 E2 中的分母移开,将 E2 重写为
(...) - (x1 - x2) * P(x1, popt_C_I[1], popt_C_I[2], popt_C_I[3])
所以系统是多项式的。这可能会使 fsolve
的生活更轻松一些。
fsolve
及其类似的 root
都不支持对变量设置边界。但是您可以使用 least_squares
来寻找表达式 E1、E2 的平方和的最小值。它支持上限和下限,如果运气好的话,最小值(“成本”)将在机器精度内为 0,表明您找到了一个根。一个抽象的例子(因为我没有你的数据):
f1 = lambda x: 2*x**3 + 20
df1 = lambda x: 6*x**2 # derivative of f1.
f2 = lambda x: (x-3)**3 + x
df2 = lambda x: 3*(x-3)**2 + 1
def eqns(x):
x1, x2 = x[0], x[1]
eq1 = df1(x1) - df2(x2)
eq2 = df1(x1)*(x1 - x2) - (f1(x1) - f2(x2))
return [eq1, eq2]
from scipy.optimize import least_squares
lb = (2, -2) # lower bounds on x1, x2
ub = (5, 3) # upper bounds
least_squares(eqns, [3, 1], bounds=(lb, ub))
输出:
active_mask: array([0, 0])
cost: 2.524354896707238e-29
fun: array([7.10542736e-15, 0.00000000e+00])
grad: array([1.93525199e-13, 1.34611132e-13])
jac: array([[27.23625045, 18.94483256],
[66.10672633, -0. ]])
message: '`gtol` termination condition is satisfied.'
nfev: 8
njev: 8
optimality: 2.4802477446153134e-13
status: 1
success: True
x: array([ 2.26968753, -0.15747203])
成本很小,所以我们有一个解决方案,就是x。通常,将 least_squares
的输出分配给某个变量 res
并从那里访问 res.x
。
关于python - 找到两条三次曲线之间的公共(public)切线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48362180/
我正在处理一组标记为 160 个组的 173k 点。我想通过合并最接近的(到 9 或 10 个组)来减少组/集群的数量。我搜索过 sklearn 或类似的库,但没有成功。 我猜它只是通过 knn 聚类
我有一个扁平数字列表,这些数字逻辑上以 3 为一组,其中每个三元组是 (number, __ignored, flag[0 or 1]),例如: [7,56,1, 8,0,0, 2,0,0, 6,1,
我正在使用 pipenv 来管理我的包。我想编写一个 python 脚本来调用另一个使用不同虚拟环境(VE)的 python 脚本。 如何运行使用 VE1 的 python 脚本 1 并调用另一个 p
假设我有一个文件 script.py 位于 path = "foo/bar/script.py"。我正在寻找一种在 Python 中通过函数 execute_script() 从我的主要 Python
这听起来像是谜语或笑话,但实际上我还没有找到这个问题的答案。 问题到底是什么? 我想运行 2 个脚本。在第一个脚本中,我调用另一个脚本,但我希望它们继续并行,而不是在两个单独的线程中。主要是我不希望第
我有一个带有 python 2.5.5 的软件。我想发送一个命令,该命令将在 python 2.7.5 中启动一个脚本,然后继续执行该脚本。 我试过用 #!python2.7.5 和http://re
我在 python 命令行(使用 python 2.7)中,并尝试运行 Python 脚本。我的操作系统是 Windows 7。我已将我的目录设置为包含我所有脚本的文件夹,使用: os.chdir("
剧透:部分解决(见最后)。 以下是使用 Python 嵌入的代码示例: #include int main(int argc, char** argv) { Py_SetPythonHome
假设我有以下列表,对应于及时的股票价格: prices = [1, 3, 7, 10, 9, 8, 5, 3, 6, 8, 12, 9, 6, 10, 13, 8, 4, 11] 我想确定以下总体上最
所以我试图在选择某个单选按钮时更改此框架的背景。 我的框架位于一个类中,并且单选按钮的功能位于该类之外。 (这样我就可以在所有其他框架上调用它们。) 问题是每当我选择单选按钮时都会出现以下错误: co
我正在尝试将字符串与 python 中的正则表达式进行比较,如下所示, #!/usr/bin/env python3 import re str1 = "Expecting property name
考虑以下原型(prototype) Boost.Python 模块,该模块从单独的 C++ 头文件中引入类“D”。 /* file: a/b.cpp */ BOOST_PYTHON_MODULE(c)
如何编写一个程序来“识别函数调用的行号?” python 检查模块提供了定位行号的选项,但是, def di(): return inspect.currentframe().f_back.f_l
我已经使用 macports 安装了 Python 2.7,并且由于我的 $PATH 变量,这就是我输入 $ python 时得到的变量。然而,virtualenv 默认使用 Python 2.6,除
我只想问如何加快 python 上的 re.search 速度。 我有一个很长的字符串行,长度为 176861(即带有一些符号的字母数字字符),我使用此函数测试了该行以进行研究: def getExe
list1= [u'%app%%General%%Council%', u'%people%', u'%people%%Regional%%Council%%Mandate%', u'%ppp%%Ge
这个问题在这里已经有了答案: Is it Pythonic to use list comprehensions for just side effects? (7 个答案) 关闭 4 个月前。 告
我想用 Python 将两个列表组合成一个列表,方法如下: a = [1,1,1,2,2,2,3,3,3,3] b= ["Sun", "is", "bright", "June","and" ,"Ju
我正在运行带有最新 Boost 发行版 (1.55.0) 的 Mac OS X 10.8.4 (Darwin 12.4.0)。我正在按照说明 here构建包含在我的发行版中的教程 Boost-Pyth
学习 Python,我正在尝试制作一个没有任何第 3 方库的网络抓取工具,这样过程对我来说并没有简化,而且我知道我在做什么。我浏览了一些在线资源,但所有这些都让我对某些事情感到困惑。 html 看起来
我是一名优秀的程序员,十分优秀!