scipy 求两条三次曲线的公切线

sdnqo3pr  于 2022-12-18  发布在  其他
关注(0)|答案(2)|浏览(221)

给定两个函数,我想找出两条曲线的公切线:

公切线的斜率可通过下式获得:

  1. slope of common tangent = (f(x1) - g(x2)) / (x1 - x2) = f'(x1) = g'(x2)

因此,最终我们得到一个包含两个未知数的两个方程组:

  1. f'(x1) = g'(x2) # Eq. 1
  2. (f(x1) - g(x2)) / (x1 - x2) = f'(x1) # Eq. 2

出于某种我不明白的原因,python没有找到解决方案:

  1. import numpy as np
  2. from scipy.optimize import curve_fit
  3. import matplotlib.pyplot as plt
  4. import sys
  5. from sympy import *
  6. import sympy as sym
  7. # Intial candidates for fit
  8. E0_init = -941.510817926696
  9. V0_init = 63.54960592453
  10. B0_init = 76.3746233515232
  11. B0_prime_init = 4.05340727164527
  12. # Data 1 (Red triangles):
  13. V_C_I, E_C_I = np.loadtxt('./1.dat', skiprows = 1).T
  14. # Data 14 (Empty grey triangles):
  15. V_14, E_14 = np.loadtxt('./2.dat', skiprows = 1).T
  16. def BM(x, a, b, c, d):
  17. return (2.293710449E+17)*(1E-21)* (a + b*x + c*x**2 + d*x**3 )
  18. def P(x, b, c, d):
  19. return -b - 2*c*x - 3 *d*x**2
  20. init_vals = [E0_init, V0_init, B0_init, B0_prime_init]
  21. popt_C_I, pcov_C_I = curve_fit(BM, V_C_I, E_C_I, p0=init_vals)
  22. popt_14, pcov_14 = curve_fit(BM, V_14, E_14, p0=init_vals)
  23. x1 = var('x1')
  24. x2 = var('x2')
  25. 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])
  26. print 'E1 = ', E1
  27. 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])
  28. sols = solve([E1, E2], [x1, x2])
  29. print 'sols = ', sols
  30. # Linspace for plotting the fitting curves:
  31. V_C_I_lin = np.linspace(V_C_I[0], V_C_I[-1], 10000)
  32. V_14_lin = np.linspace(V_14[0], V_14[-1], 10000)
  33. plt.figure()
  34. # Plotting the fitting curves:
  35. p2, = plt.plot(V_C_I_lin, BM(V_C_I_lin, *popt_C_I), color='black', label='Cubic fit data 1' )
  36. p6, = plt.plot(V_14_lin, BM(V_14_lin, *popt_14), 'b', label='Cubic fit data 2')
  37. # Plotting the scattered points:
  38. p1 = plt.scatter(V_C_I, E_C_I, color='red', marker="^", label='Data 1', s=100)
  39. p5 = plt.scatter(V_14, E_14, color='grey', marker="^", facecolors='none', label='Data 2', s=100)
  40. plt.ticklabel_format(useOffset=False)
  41. plt.show()

1.dat为以下值:

  1. 61.6634100000000 -941.2375622594436
  2. 62.3429030000000 -941.2377748739724
  3. 62.9226515000000 -941.2378903605746
  4. 63.0043440000000 -941.2378981684135
  5. 63.7160150000000 -941.2378864590100
  6. 64.4085050000000 -941.2377753645115
  7. 65.1046835000000 -941.2375332100225
  8. 65.8049585000000 -941.2372030376584
  9. 66.5093925000000 -941.2367456992965
  10. 67.2180970000000 -941.2361992239395
  11. 67.9311515000000 -941.2355493856510

2.dat为以下值:

  1. 54.6569312500000 -941.2300821583739
  2. 55.3555152500000 -941.2312112888004
  3. 56.1392347500000 -941.2326135552780
  4. 56.9291575000000 -941.2338291772218
  5. 57.6992532500000 -941.2348135408652
  6. 58.4711572500000 -941.2356230099117
  7. 59.2666985000000 -941.2362715934311
  8. 60.0547935000000 -941.2367074271724
  9. 60.8626545000000 -941.2370273047416

**更新:**使用@if.方法:

  1. import numpy as np
  2. from scipy.optimize import curve_fit
  3. import matplotlib.pyplot as plt
  4. from matplotlib.font_manager import FontProperties
  5. # Intial candidates for fit, per FU: - thus, the E vs V input data has to be per FU
  6. E0_init = -941.510817926696
  7. V0_init = 63.54960592453
  8. B0_init = 76.3746233515232
  9. B0_prime_init = 4.05340727164527
  10. def BM(x, a, b, c, d):
  11. return a + b*x + c*x**2 + d*x**3
  12. def devBM(x, b, c, d):
  13. return b + 2*c*x + 3*d*x**2
  14. # Data 1 (Red triangles):
  15. V_C_I, E_C_I = np.loadtxt('./1.dat', skiprows = 1).T
  16. # Data 14 (Empty grey triangles):
  17. V_14, E_14 = np.loadtxt('./2.dat', skiprows = 1).T
  18. init_vals = [E0_init, V0_init, B0_init, B0_prime_init]
  19. popt_C_I, pcov_C_I = curve_fit(BM, V_C_I, E_C_I, p0=init_vals)
  20. popt_14, pcov_14 = curve_fit(BM, V_14, E_14, p0=init_vals)
  21. from scipy.optimize import fsolve
  22. def equations(p):
  23. x1, x2 = p
  24. 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])
  25. 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])
  26. return (E1, E2)
  27. x1, x2 = fsolve(equations, (50, 60))
  28. print 'x1 = ', x1
  29. print 'x2 = ', x2
  30. slope_common_tangent = devBM(x1, popt_C_I[1], popt_C_I[2], popt_C_I[3])
  31. print 'slope_common_tangent = ', slope_common_tangent
  32. def comm_tangent(x, x1, slope_common_tangent):
  33. 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
  34. # Linspace for plotting the fitting curves:
  35. V_C_I_lin = np.linspace(V_C_I[0], V_C_I[-1], 10000)
  36. V_14_lin = np.linspace(V_14[0], V_14[-1], 10000)
  37. plt.figure()
  38. # Plotting the fitting curves:
  39. p2, = plt.plot(V_C_I_lin, BM(V_C_I_lin, *popt_C_I), color='black', label='Cubic fit Calcite I' )
  40. p6, = plt.plot(V_14_lin, BM(V_14_lin, *popt_14), 'b', label='Cubic fit Calcite II')
  41. xp = np.linspace(54, 68, 100)
  42. pcomm_tangent, = plt.plot(xp, comm_tangent(xp, x1, slope_common_tangent), 'green', label='Common tangent')
  43. # Plotting the scattered points:
  44. p1 = plt.scatter(V_C_I, E_C_I, color='red', marker="^", label='Calcite I', s=100)
  45. p5 = plt.scatter(V_14, E_14, color='grey', marker="^", facecolors='none', label='Calcite II', s=100)
  46. fontP = FontProperties()
  47. fontP.set_size('13')
  48. plt.legend((p1, p2, p5, p6, pcomm_tangent), ("1", "Cubic fit 1", "2", 'Cubic fit 2', 'Common tangent'), prop=fontP)
  49. 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])
  50. plt.ylim(-941.240, -941.225)
  51. plt.ticklabel_format(useOffset=False)
  52. plt.show()

我可以找到公切线,如下所示:

但是,该公切线对应于数据范围外区域的公切线,即使用

  1. V_C_I_lin = np.linspace(V_C_I[0]-30, V_C_I[-1], 10000)
  2. V_14_lin = np.linspace(V_14[0]-20, V_14[-1]+2, 10000)
  3. xp = np.linspace(40, 70, 100)
  4. plt.ylim(-941.25, -941.18)

可以看到以下内容:

为了找到所需的公切线,是否可以将求解器限制在我们拥有数据的范围内?

更新2.1:使用@if.... Range约束方法,下面的代码将生成x1 = 61.2569899x2 = 59.7677843

  1. import numpy as np
  2. from scipy.optimize import curve_fit
  3. import matplotlib.pyplot as plt
  4. from matplotlib.font_manager import FontProperties
  5. import sys
  6. from sympy import *
  7. import sympy as sym
  8. import os
  9. # Intial candidates for fit, per FU: - thus, the E vs V input data has to be per FU
  10. E0_init = -941.510817926696 # -1882.50963222/2.0
  11. V0_init = 63.54960592453 #125.8532/2.0
  12. B0_init = 76.3746233515232 #74.49
  13. B0_prime_init = 4.05340727164527 #4.15
  14. def BM(x, a, b, c, d):
  15. return a + b*x + c*x**2 + d*x**3
  16. def devBM(x, b, c, d):
  17. return b + 2*c*x + 3*d*x**2
  18. # Data 1 (Red triangles):
  19. V_C_I, E_C_I = np.loadtxt('./1.dat', skiprows = 1).T
  20. # Data 14 (Empty grey triangles):
  21. V_14, E_14 = np.loadtxt('./2.dat', skiprows = 1).T
  22. init_vals = [E0_init, V0_init, B0_init, B0_prime_init]
  23. popt_C_I, pcov_C_I = curve_fit(BM, V_C_I, E_C_I, p0=init_vals)
  24. popt_14, pcov_14 = curve_fit(BM, V_14, E_14, p0=init_vals)
  25. def equations(p):
  26. x1, x2 = p
  27. 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])
  28. 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])
  29. return (E1, E2)
  30. from scipy.optimize import least_squares
  31. lb = (61.0, 59.0) # lower bounds on x1, x2
  32. ub = (62.0, 60.0) # upper bounds
  33. result = least_squares(equations, [61, 59], bounds=(lb, ub))
  34. print 'result = ', result
  35. # The result obtained is:
  36. # x1 = 61.2569899
  37. # x2 = 59.7677843
  38. slope_common_tangent = devBM(x1, popt_C_I[1], popt_C_I[2], popt_C_I[3])
  39. print 'slope_common_tangent = ', slope_common_tangent
  40. def comm_tangent(x, x1, slope_common_tangent):
  41. 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
  42. # Linspace for plotting the fitting curves:
  43. V_C_I_lin = np.linspace(V_C_I[0]-2, V_C_I[-1], 10000)
  44. V_14_lin = np.linspace(V_14[0], V_14[-1]+2, 10000)
  45. fig_handle = plt.figure()
  46. # Plotting the fitting curves:
  47. p2, = plt.plot(V_C_I_lin, BM(V_C_I_lin, *popt_C_I), color='black' )
  48. p6, = plt.plot(V_14_lin, BM(V_14_lin, *popt_14), 'b' )
  49. xp = np.linspace(54, 68, 100)
  50. pcomm_tangent, = plt.plot(xp, comm_tangent(xp, x1, slope_common_tangent), 'green', label='Common tangent')
  51. # Plotting the scattered points:
  52. p1 = plt.scatter(V_C_I, E_C_I, color='red', marker="^", label='1', s=100)
  53. p5 = plt.scatter(V_14, E_14, color='grey', marker="^", facecolors='none', label='2', s=100)
  54. fontP = FontProperties()
  55. fontP.set_size('13')
  56. plt.legend((p1, p2, p5, p6, pcomm_tangent), ("1", "Cubic fit 1", "2", 'Cubic fit 2', 'Common tangent'), prop=fontP)
  57. plt.ticklabel_format(useOffset=False)
  58. plt.show()

我们看到,我们没有得到一条公切线:

yshpjwxd

yshpjwxd1#

符号根查找

你的方程组由一个二次方程和一个三次方程组成,这样的方程组没有封闭形式的符号解,如果有的话,可以通过引入y = x**2将其应用于一般的5次方程x**5 + a*x**4 + ... = 0(二次)并将原始方程重写为x*y**2 + a*y**2 + ... = 0(立方)。我们知道can't be done。所以SymPy解不出来也就不足为奇了。你需要一个数值解算器(另一个原因是SymPy并不是真正设计用来求解充满浮点常数的方程的,它们对于符号操作来说是个麻烦)。

数值根查找

SciPy fsolve是第一个出现在脑海中的东西。您可以这样做:

  1. def F(x):
  2. x1, x2 = x[0], x[1]
  3. 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])
  4. 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])
  5. return [E1, E2]
  6. print fsolve(F, [50, 60]) # some reasonable initial point

顺便说一句,我会将E2中的分母(x1-x2)移动,将E2重写为

  1. (...) - (x1 - x2) * P(x1, popt_C_I[1], popt_C_I[2], popt_C_I[3])

所以这个系统是多项式的。这可能会让fsolve的寿命更容易一点。

范围约束:极小化

fsolve和它的同类root都不支持给变量上界,但是你可以使用least_squares来寻找表达式E1、E2的平方和的最小值,它支持上界和下界,如果幸运的话,还可以找到最小值(“cost”)在机器精度范围内将为0,表示您找到了根。举个抽象的例子(因为我没有您的数据):

  1. f1 = lambda x: 2*x**3 + 20
  2. df1 = lambda x: 6*x**2 # derivative of f1.
  3. f2 = lambda x: (x-3)**3 + x
  4. df2 = lambda x: 3*(x-3)**2 + 1
  5. def eqns(x):
  6. x1, x2 = x[0], x[1]
  7. eq1 = df1(x1) - df2(x2)
  8. eq2 = df1(x1)*(x1 - x2) - (f1(x1) - f2(x2))
  9. return [eq1, eq2]
  10. from scipy.optimize import least_squares
  11. lb = (2, -2) # lower bounds on x1, x2
  12. ub = (5, 3) # upper bounds
  13. least_squares(eqns, [3, 1], bounds=(lb, ub))


输出:

  1. active_mask: array([0, 0])
  2. cost: 2.524354896707238e-29
  3. fun: array([7.10542736e-15, 0.00000000e+00])
  4. grad: array([1.93525199e-13, 1.34611132e-13])
  5. jac: array([[27.23625045, 18.94483256],
  6. [66.10672633, -0. ]])
  7. message: '`gtol` termination condition is satisfied.'
  8. nfev: 8
  9. njev: 8
  10. optimality: 2.4802477446153134e-13
  11. status: 1
  12. success: True
  13. x: array([ 2.26968753, -0.15747203])

代价非常小,所以我们有一个解,它是x。通常,我们将least_squares的输出赋值给某个变量res,然后从那里访问res.x

展开查看全部
vnzz0bqm

vnzz0bqm2#

感谢all @if.... help,通过运行本答案末尾的以下代码,讨论了3种途径的结果:

1)least_squares,具有默认公差:

  1. #### ftol=1e-08, xtol=1e-08, gtol=1e-08 #####
  2. result = active_mask: array([0, 0])
  3. cost: 4.7190963603923405e-10
  4. fun: array([ 1.60076424e-05, 2.62216448e-05])
  5. grad: array([ -3.22762954e-09, -4.72137063e-09])
  6. jac: array([[ 2.70753295e-04, -3.41257603e-04],
  7. [ -2.88378229e-04, 2.82727898e-05]])
  8. message: '`gtol` termination condition is satisfied.'
  9. nfev: 4
  10. njev: 4
  11. optimality: 2.398161337354571e-09
  12. status: 1
  13. success: True
  14. x: array([ 61.2569899, 59.7677843])
  15. result.x = [ 61.2569899 59.7677843]
  16. slope_common_tangent = -0.000533908881355

成本为零,找到的公切线非常接近,但不理想:

2)least_squares,公差更严格:

  1. #### ftol=1e-12, xtol=1e-12, gtol=1e-12 #####
  2. result_tight_tols = active_mask: array([0, 0])
  3. cost: 4.3861335617475759e-20
  4. fun: array([ 2.08437035e-10, 2.10420231e-10])
  5. grad: array([ -5.40980234e-16, -7.19344843e-14])
  6. jac: array([[ 2.69431398e-04, -3.45167744e-04],
  7. [ -2.69462978e-04, 5.34965061e-08]])
  8. message: '`gtol` termination condition is satisfied.'
  9. nfev: 8
  10. njev: 8
  11. optimality: 7.6628451334260651e-15
  12. status: 1
  13. success: True
  14. x: array([ 61.35744106, 59.89347466])
  15. result_tight_tols.x = [ 61.35744106 59.89347466]
  16. slope_common_tangent = -0.000506777791299

我本来预计成本会更高,但不知什么原因,成本更低了,找到的公切线要近得多:

**3)**使用fsolve但限制区域

我们在文章中看到,当使用x1, x2 = fsolve(equations, (50, 60))时,找到的公切线不正确(第2和第3张图片)。但是,如果我们使用x1, x2 = fsolve(equations, (61.5, 62))

  1. #### Using `fsolve`, but restricting the region: ####
  2. x1 = 61.3574418449
  3. x2 = 59.8934758773
  4. slope_common_tangent = -0.000506777580856


我们可以看到,得到的斜率与公差更小的least_squares非常相似,因此,得到的公切线也非常接近:

下表总结了结果:

产生这三种途径的代码:

  1. import numpy as np
  2. from scipy.optimize import curve_fit
  3. import matplotlib.pyplot as plt
  4. from matplotlib.font_manager import FontProperties
  5. import sys
  6. from sympy import *
  7. import sympy as sym
  8. import os
  9. import pickle as pl
  10. # Intial candidates for fit, per FU: - thus, the E vs V input data has to be per FU
  11. E0_init = -941.510817926696 # -1882.50963222/2.0
  12. V0_init = 63.54960592453 #125.8532/2.0
  13. B0_init = 76.3746233515232 #74.49
  14. B0_prime_init = 4.05340727164527 #4.15
  15. def BM(x, a, b, c, d):
  16. return a + b*x + c*x**2 + d*x**3
  17. def devBM(x, b, c, d):
  18. return b + 2*c*x + 3*d*x**2
  19. # Data 1 (Red triangles):
  20. V_C_I, E_C_I = np.loadtxt('./1.dat', skiprows = 1).T
  21. # Data 14 (Empty grey triangles):
  22. V_14, E_14 = np.loadtxt('./2.dat', skiprows = 1).T
  23. init_vals = [E0_init, V0_init, B0_init, B0_prime_init]
  24. popt_C_I, pcov_C_I = curve_fit(BM, V_C_I, E_C_I, p0=init_vals)
  25. popt_14, pcov_14 = curve_fit(BM, V_14, E_14, p0=init_vals)
  26. def equations(p):
  27. x1, x2 = p
  28. 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])
  29. 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])
  30. return (E1, E2)
  31. from scipy.optimize import least_squares
  32. lb = (61.0, 59.0) # lower bounds on x1, x2
  33. ub = (62.0, 60.0) # upper bounds
  34. result = least_squares(equations, [61, 59], bounds=(lb, ub))
  35. result_tight_tols = least_squares(equations, [61, 59], ftol=1e-12, xtol=1e-12, gtol=1e-12, bounds=(lb, ub))
  36. print """
  37. #### ftol=1e-08, xtol=1e-08, gtol=1e-08 #####
  38. """
  39. print 'result = ', result
  40. print 'result.x = ', result.x
  41. print """
  42. """
  43. x1 = result.x[0]
  44. x2 = result.x[1]
  45. slope_common_tangent = devBM(x1, popt_C_I[1], popt_C_I[2], popt_C_I[3])
  46. print 'slope_common_tangent = ', slope_common_tangent
  47. def comm_tangent(x, x1, slope_common_tangent):
  48. 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
  49. # Linspace for plotting the fitting curves:
  50. V_C_I_lin = np.linspace(V_C_I[0]-2, V_C_I[-1], 10000)
  51. V_14_lin = np.linspace(V_14[0], V_14[-1]+2, 10000)
  52. plt.figure()
  53. # Plotting the fitting curves:
  54. p2, = plt.plot(V_C_I_lin, BM(V_C_I_lin, *popt_C_I), color='black' )
  55. p6, = plt.plot(V_14_lin, BM(V_14_lin, *popt_14), 'b' )
  56. xp = np.linspace(54, 68, 100)
  57. pcomm_tangent, = plt.plot(xp, comm_tangent(xp, x1, slope_common_tangent), 'green', label='Common tangent')
  58. # Plotting the scattered points:
  59. p1 = plt.scatter(V_C_I, E_C_I, color='red', marker="^", label='1', s=100)
  60. p5 = plt.scatter(V_14, E_14, color='grey', marker="^", facecolors='none', label='2', s=100)
  61. fontP = FontProperties()
  62. fontP.set_size('13')
  63. plt.legend((p1, p2, p5, p6, pcomm_tangent), ("1", "Cubic fit 1", "2", 'Cubic fit 2', 'Common tangent'), prop=fontP)
  64. plt.title('Least squares. Default tolerances: ftol=1e-08, xtol=1e-08, gtol=1e-08')
  65. plt.ticklabel_format(useOffset=False)
  66. ### Tighter tolerances:
  67. print """
  68. #### ftol=1e-12, xtol=1e-12, gtol=1e-12 #####
  69. """
  70. print 'result_tight_tols = ', result_tight_tols
  71. print 'result_tight_tols.x = ', result_tight_tols.x
  72. print """
  73. """
  74. x1 = result_tight_tols.x[0]
  75. x2 = result_tight_tols.x[1]
  76. slope_common_tangent = devBM(x1, popt_C_I[1], popt_C_I[2], popt_C_I[3])
  77. print 'slope_common_tangent = ', slope_common_tangent
  78. def comm_tangent(x, x1, slope_common_tangent):
  79. 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
  80. # Linspace for plotting the fitting curves:
  81. V_C_I_lin = np.linspace(V_C_I[0]-2, V_C_I[-1], 10000)
  82. V_14_lin = np.linspace(V_14[0], V_14[-1]+2, 10000)
  83. plt.figure()
  84. # Plotting the fitting curves:
  85. p2, = plt.plot(V_C_I_lin, BM(V_C_I_lin, *popt_C_I), color='black' )
  86. p6, = plt.plot(V_14_lin, BM(V_14_lin, *popt_14), 'b' )
  87. xp = np.linspace(54, 68, 100)
  88. pcomm_tangent, = plt.plot(xp, comm_tangent(xp, x1, slope_common_tangent), 'green', label='Common tangent')
  89. # Plotting the scattered points:
  90. p1 = plt.scatter(V_C_I, E_C_I, color='red', marker="^", label='1', s=100)
  91. p5 = plt.scatter(V_14, E_14, color='grey', marker="^", facecolors='none', label='2', s=100)
  92. fontP = FontProperties()
  93. fontP.set_size('13')
  94. plt.legend((p1, p2, p5, p6, pcomm_tangent), ("1", "Cubic fit 1", "2", 'Cubic fit 2', 'Common tangent'), prop=fontP)
  95. plt.title('ftol=1e-08, xtol=1e-08, gtol=1e-08')
  96. plt.ticklabel_format(useOffset=False)
  97. plt.title('Lest Squares. Tightening tolerances: ftol=1e-12, xtol=1e-12, gtol=1e-12')
  98. print """
  99. #### Using `fsolve`, but restricting the region: ####
  100. """
  101. from scipy.optimize import fsolve
  102. x1, x2 = fsolve(equations, (61.5, 62))
  103. print 'x1 = ', x1
  104. print 'x2 = ', x2
  105. slope_common_tangent = devBM(x1, popt_C_I[1], popt_C_I[2], popt_C_I[3])
  106. print 'slope_common_tangent = ', slope_common_tangent
  107. plt.figure()
  108. # Plotting the fitting curves:
  109. p2, = plt.plot(V_C_I_lin, BM(V_C_I_lin, *popt_C_I), color='black' )
  110. p6, = plt.plot(V_14_lin, BM(V_14_lin, *popt_14), 'b' )
  111. xp = np.linspace(54, 68, 100)
  112. pcomm_tangent, = plt.plot(xp, comm_tangent(xp, x1, slope_common_tangent), 'green', label='Common tangent')
  113. # Plotting the scattered points:
  114. p1 = plt.scatter(V_C_I, E_C_I, color='red', marker="^", label='1', s=100)
  115. p5 = plt.scatter(V_14, E_14, color='grey', marker="^", facecolors='none', label='2', s=100)
  116. fontP = FontProperties()
  117. fontP.set_size('13')
  118. plt.legend((p1, p2, p5, p6, pcomm_tangent), ("1", "Cubic fit 1", "2", 'Cubic fit 2', 'Common tangent'), prop=fontP)
  119. plt.ticklabel_format(useOffset=False)
  120. plt.title('Using `fsolve`, but restricting the region')
  121. plt.show()
展开查看全部

相关问题