二次函数的基础数学
解一元二次方程式的根
如果 有2个实数根
如果 有1个实数根
如果 没有实数根
解下例一元二次方程式:
代码如下:
a = 1
b = -2
c = -8
r1 = (-b + (b**2-4*a*c)**0.5)/(2*a)
r2 = (-b - (b**2-4*a*c)**0.5)/(2*a)
print("r1 = %6.4f, r2 = %6.4f" % (r1, r2))
运行结果如下:
[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
r1 = 4.0000, r2 = -2.0000
[Done] exited with code=0 in 0.498 seconds
重新设计,使用sympy。
代码如下:
from sympy import *
x = Symbol('x')
f = Symbol('f')
f = x**2 - 2*x - 8
root = solve(f)
print(root)
运行结果如下:
[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
[-2, 4]
[Done] exited with code=0 in 2.457 seconds
使用sympy模块解下列一元二次方程式:
代码如下:
from sympy import *
x = Symbol('x')
f = Symbol('f')
f = 3*(x-2)**2 - 2
root = solve(f)
print(root)
运行结果如下:
[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
[2 - sqrt(6)/3, sqrt(6)/3 + 2]
[Done] exited with code=0 in 2.025 seconds
绘制一元二次方程式的图形
在一元二次方程式中,可以使用抛物线绘制此方程式图形:
如果,代表函数抛物线开口向上。
如果,代表函数曲线开口向下。
绘制的二次函数图形,同时标记和输出两个根:
代码如下:(代码没看懂)
import matplotlib.pyplot as plt
import numpy as np
def f(x):
''' 求解方程式 '''
return (3*x**2 - 12*x + 10)
a = 3
b = -12
c = 10
r1 = (-b + (b**2-4*a*c)**0.5)/(2*a) # r1
r1_y = f(r1) # f(r1)
plt.text(r1-0.2, r1_y+0.3, '('+str(round(r1,2))+','+str(0)+')')
plt.plot(r1, r1_y, '-o') # 标记
print('root1 = ', r1) # print(r1)
r2 = (-b - (b**2-4*a*c)**0.5)/(2*a) # r2
r2_y = f(r2) # f(r2)
plt.text(r2-0.2, r2_y+0.3, '('+str(round(r2,2))+','+str(0)+')')
plt.plot(r2, r2_y, '-o') # 标记
print('root2 = ', r2) # print(r2)
# 绘制此函数图形
x = np.linspace(0, 4, 50)
y = 3*x**2 - 12*x + 10
plt.plot(x, y)
plt.show()
运行结果如下:
[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
root1 = 2.8164965809277263
root2 = 1.183503419072274
[Done] exited with code=0 in 17.871 seconds
绘制的函数图形,同时标记和输出 两个根:
代码如下:
import matplotlib.pyplot as plt
import numpy as np
def f(x):
''' 求解方程式 '''
return (-3*x**2 + 12*x - 9)
a = -3
b = 12
c = -9
r1 = (-b + (b**2-4*a*c)**0.5)/(2*a) # r1
r1_y = f(r1) # f(r1)
plt.text(r1-0.2, r1_y+0.3, '('+str(round(r1,2))+','+str(0)+')')
plt.plot(r1, r1_y, '-o') # 标记
print('root1 = ', r1) # print(r1)
r2 = (-b - (b**2-4*a*c)**0.5)/(2*a) # r2
r2_y = f(r2) # f(r2)
plt.text(r2-0.3, r2_y+0.3, '('+str(round(r2,2))+','+str(0)+')')
plt.plot(r2, r2_y, '-o') # 标记
print('root2 = ', r2) # print(r2)
# 绘制此函数图形
x = np.linspace(0, 4, 50)
y = -3*x**2 + 12*x - 9
plt.plot(x, y)
plt.show()
运行结果如下:
[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
root1 = 1.0
root2 = 3.0
[Done] exited with code=0 in 24.578 seconds
一元二次方程式的最小值与最大值
当a>0时,因为抛物线开口向上,可以找到此抛物线函数f(x)的最小值。当a<0时,因为抛物线开口下向,可以找到此抛物线函数f(x)的最大值。
对于二次函数,不论是最大值或是最小值,坐标公式皆是:
scipy模块内的optimize模块内有minimize_scalar()方法可以找出f(x)函数的最小值,也可以由此导入函数找出最小值的坐标(x,y)。
使用scipy模块前需要安装此模块:
pip install scipy
然后程序前方需要导入此模块:
from scipy.optimeze import minize_scalar
语法如下:
minimize_scalar(fun)
上述fun是一元二次方程式。
增加列出最小值的坐标(x,y),下列是此二次函数:
由于a是3大于0,可以得到最小值。
import matplotlib.pyplot as plt
from scipy.optimize import minimize_scalar
import numpy as np
def f(x):
''' 求解方程式 '''
return (3*x**2 - 12*x + 10)
a = 3
b = -12
c = 10
r1 = (-b + (b**2-4*a*c)**0.5)/(2*a) # r1
r1_y = f(r1) # f(r1)
plt.text(r1+0.1, r1_y-0.2, '('+str(round(r1,2))+','+str(0)+')')
plt.plot(r1, r1_y, '-o') # 标记
print('root1 = ', r1) # print(r1)
r2 = (-b - (b**2-4*a*c)**0.5)/(2*a) # r2
r2_y = f(r2) # f(r2)
plt.text(r2-0.6, r2_y-0.2, '('+str(round(r2,2))+','+str(0)+')')
plt.plot(r2, r2_y, '-o') # 标记
print('root2 = ', r2) # print(r2)
# 计算最小值
r = minimize_scalar(f)
print("当x是 %4.2f 时, 有函数最小值 %4.2f" % (r.x, f(r.x)))
plt.text(r.x-0.25, f(r.x)+0.3, '('+str(round(r.x,2))+','+str(round(r.x,2))+')')
plt.plot(r.x, f(r.x), '-o') # 标记
# 绘制此函数图形
x = np.linspace(0, 4, 50)
y = 3*x**2 - 12*x + 10
plt.plot(x, y, color='b')
plt.show()
运行结果如下:
[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
root1 = 2.8164965809277263
root2 = 1.183503419072274
当x是 2.00 时, 有函数最小值 -2.00
[Done] exited with code=0 in 19.479 seconds
增加列出最大值的坐标(x,y),下列是此二次函数:
import matplotlib.pyplot as plt
from scipy.optimize import minimize_scalar
import numpy as np
def fmax(x):
''' 计算最大值 '''
return (-(-3*x**2 + 12*x - 9))
def f(x):
''' 求解方程式 '''
return (-3*x**2 + 12*x - 9)
a = -3
b = 12
c = -9
r1 = (-b + (b**2-4*a*c)**0.5)/(2*a) # r1
r1_y = f(r1) # f(r1)
plt.text(r1+0.1, r1_y+-0.2, '('+str(round(r1,2))+','+str(0)+')')
plt.plot(r1, r1_y, '-o') # 标记
print('root1 = ', r1) # print(r1)
r2 = (-b - (b**2-4*a*c)**0.5)/(2*a) # r2
r2_y = f(r2) # f(r2)
plt.text(r2-0.5, r2_y-0.2, '('+str(round(r2,2))+','+str(0)+')')
plt.plot(r2, r2_y, '-o') # 标记
print('root2 = ', r2) # print(r2)
# 计算最大值
r = minimize_scalar(fmax)
print("当x是 %4.2f 时, 有函数最大值 %4.2f" % (r.x, f(r.x)))
plt.text(r.x-0.25, f(r.x)-0.7, '('+str(round(r.x,2))+','+str(round(r.x,2))+')')
plt.plot(r.x, f(r.x), '-o') # 标记
# 绘制此函数图形
x = np.linspace(0, 4, 50)
y = -3*x**2 + 12*x - 9
plt.plot(x, y, color='b')
plt.show()
运行结果如下:
[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
root1 = 1.0
root2 = 3.0
当x是 2.00 时, 有函数最大值 3.00
[Done] exited with code=0 in 9.859 seconds
二次函数参数整理
对于下列二次函数:
参数a:
参数a决定抛物线的开口向上(a>0)或是向下(a<0).
参数a和b:
参数a和参数b会影响对称轴的位置,对称轴公式如下:
如果b=0,抛物线的对称轴是y轴。
如果a和b是同号,对称轴在y轴左边。
如果a和b是异号,对称轴在y轴右边。
参数c:
参数c可以决定抛物线和y轴的交叉点,如果x为0,表示y=c。
三次函数的图形特征
所谓的三次函数,是指x的最高项是三次方,基本概念如下:
#a不等于0
绘制x在-1.0~1.0的下列函数:
代码如下:
import matplotlib.pyplot as plt
import numpy as np
# 绘制此函数图形
x = np.linspace(-1, 1, 100)
y = x**3 - x
plt.plot(x, y)
plt.grid()
plt.show()
运行结果如下:
绘制x在-2.0~2.0的同上函数:
代码如下:
import matplotlib.pyplot as plt
import numpy as np
# 绘制此函数图形
x = np.linspace(-2, 2, 100)
y = x**3 - x
plt.plot(x, y)
plt.grid()
plt.show()
运行结果如下:
从一次到二次函数
呈现好的变化
真实业绩,在线性方程式预估业绩的上面
呈现坏的变化
真实业绩,在线性方程式预估业绩的下面。
认识二次函数的系数
在一次线性函数y=ax+b中,a是斜率,b是截距,二次函数可参考下列公式:
a、b、c就不称斜率或截距,而是直接称系数,a是x的二次方系数,b是x的一次方系数,c是常数。
呈现的是正向变化,表示 a>0,同时随着x的值增加,的值也会增加。呈现好的变化。
呈现的是负向变化,表示a<0,同时随着x的值增加,将加大负值。呈现坏的变化。
使用3个点求解二次函数
x代表拜访次数,以100为单位,y是实际业绩,得到下列3个二次方程式:
#第100次 x=1
#第200次 x=2
#第300次 x=3
由于有c,分别将第200次和第300次公式减去第100次公式,得到下列联立方程式:
#第200次公式减去第100次公式
#第300次公式减去第100次公式
简化后得到下列联立方程式:
#公式一
#公式二
a=250,b=-250,c=500
求解上述联立方程式。
代码如下:
import matplotlib.pyplot as plt
from sympy import Symbol, solve
import numpy as np
a = Symbol('a') # 定义公式中使用的变量
b = Symbol('b') # 定义公式中使用的变量
c = Symbol('c') # 定义公式中使用的变量
eq1 = a + b + c - 500 # 第100次公式
eq2 = 4*a + 2*b + c - 1000 # 第200次公式
eq3 = 9*a + 3*b + c - 2000 # 第300次公式
ans = solve((eq1, eq2, eq3))
print('a = {}'.format(ans[a]))
print('b = {}'.format(ans[b]))
print('c = {}'.format(ans[c]))
运行结果如下:
[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
a = 250
b = -250
c = 500
[Done] exited with code=0 in 5.451 seconds
先使用相同的数据找出此二次函数,然后绘制此二次函数图形,同时将先前拜访次数所创的业绩在图上标记出来,再用所计算的二次函数求解当拜访客户400次时,所产生的业绩,同时在坐标图内标记此坐标。
代码如下:
import matplotlib.pyplot as plt
from sympy import Symbol, solve
import numpy as np
a = Symbol('a') # 定义公式中使用的变量
b = Symbol('b') # 定义公式中使用的变量
c = Symbol('c') # 定义公式中使用的变量
eq1 = a + b + c - 500 # 第100次公式
eq2 = 4*a + 2*b + c - 1000 # 第200次公式
eq3 = 9*a + 3*b + c - 2000 # 第300次公式
ans = solve((eq1, eq2, eq3))
print('a = {}'.format(ans[a]))
print('b = {}'.format(ans[b]))
print('c = {}'.format(ans[c]))
x = np.linspace(0, 5, 50)
y = [(ans[a]*y**2 + ans[b]*y + ans[c]) for y in x]
plt.plot(x, y) # 绘二次函数
x4 = 4 # 第400次
y4 = ans[a]*x4**2 + ans[b]*x4 + ans[c] # 第400次的y值
plt.plot(x4, y4, '-o') # 绘交叉点
plt.text(x4-0.7, y4-50, '('+str(x4)+','+str(y4)+')')
plt.plot(1, 500, '-x', color='b') # 绘100次业绩点
plt.text(1-0.7, 500-50, '('+str(1)+','+str(500)+')')
plt.plot(2, 1000, '-x', color='b') # 绘200次业绩点
plt.text(2-0.7, 1000-50, '('+str(2)+','+str(1000)+')')
plt.plot(3, 2000, '-x', color='b') # 绘300次业绩点
plt.text(3-0.7, 2000-50, '('+str(3)+','+str(2000)+')')
plt.xlabel("Times(unit=100)")
plt.ylabel("Revenue")
plt.grid() # 加网格线
plt.show()
运行结果:
[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
a = 250
b = -250
c = 500
[Done] exited with code=0 in 18.406 seconds
计算要达到3000张考卷销售,需要多少拜访次数,在这个程序设计中因为拜访次数必须是正值,所以负数根将舍去。
代码如下:
a = 1
b = -1
c = -10
r1 = (-b + (b**2-4*a*c)**0.5)/(2*a)
r2 = (-b - (b**2-4*a*c)**0.5)/(2*a)
if r1 > 0:
times = int(r1 * 100)
else:
if r2 > 0:
times = int(r2 * 100)
print("拜访次数 = {}".format(times))
运行结果:
[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
拜访次数 = 370
[Done] exited with code=0 in 0.338 seconds
二次函数的配方法
二次函数的一般式:
二次函数的标准式:
在标准式中,可以清楚得到抛物线的顶点坐标是(h,k)。
这个概念在机器学习过程中使用最小平方法计算最小误差时会使用。
配方法是将两次函数从一般式推导到标准式。
从标准式计算二次函数的最大值
二次函数的标准式概念如下:
当a<0时抛物线开口向下,因为,所以可以得到:
当x=h时,会造成:
这时可以得到y=k是最大值,因为:
所以当二次函数存在最大值时,最大值的坐标如下:
从标准式计算二次函数的最小值
二次函数的标准式概念如下:
当a>0时抛物线开口向上,因为,所以可以得到:
当x=h时,会造成:
这时可以得到y=k是最小值,因为:
所以当二次函数存在最小值时,最小值的坐标如下:
二次函数与解答区间
公司内部的统计信息:
每月次数 | 增加业绩金额/万元 |
1 | 10 |
2 | 18 |
3 | 19 |
假设营销次数是x,增加业绩单位是万元、金额是y。将上述数据代入二次函数可以得到下列联立方程式:
经过计算可以得到下列a、b、c的值:
a=-3.5
b=18.5
c=-5
所以可以得到营销的二次函数:
二次函数的标准式:
绘制上述数据的图表,同时使用'x'标记此原始数据,并使用圆点标记极大值。
import matplotlib.pyplot as plt
from sympy import Symbol, solve
import numpy as np
a = Symbol('a') # 定义公式中使用的变量
b = Symbol('b') # 定义公式中使用的变量
c = Symbol('c') # 定义公式中使用的变量
eq1 = a + b + c - 10 # 第1次公式
eq2 = 4*a + 2*b + c - 18 # 第2次公式
eq3 = 9*a + 3*b + c - 19 # 第3次公式
ans = solve((eq1, eq2, eq3))
print('a = {}'.format(ans[a]))
print('b = {}'.format(ans[b]))
print('c = {}'.format(ans[c]))
x = np.linspace(0, 4, 50)
y = [(ans[a]*y**2 + ans[b]*y + ans[c]) for y in x]
plt.plot(x, y) # 绘二次函数
plt.plot(1, 10, '-x', color='b') # 绘1次业绩点
plt.plot(2, 18, '-x', color='b') # 绘2次业绩点
plt.plot(3, 19, '-x', color='b') # 绘3次业绩点
h = (-1 * ans[b] / (2 * ans[a]))
k = (4 * ans[a] * ans[c] - (ans[b] ** 2)) / (4 * ans[a])
plt.plot(h, k, '-o', color='b') # 绘最大值坐标
h = round(float(h), 1)
k = round(float(k), 1)
plt.text(h-0.25, k-1.5, '('+str(h)+','+str(k)+')')
plt.xlabel("Times")
plt.ylabel("Performance")
plt.grid() # 加网格线
plt.show()
执行结果:
假设改为想要达到销售增幅15万元(含)以上。
y值概率:
y是15,得到下列二次函数:
可以得到下列推导结果:
计算公式的值。
from sympy import *
x = Symbol('x')
eq = -3.5*x**2 + 18.5*x - 20
ans = solve(eq)
x1 = round(ans[0], 1)
x2 = round(ans[1], 1)
print('x1 = {}'.format(x1))
print('x2 = {}'.format(x2))
执行结果:
[Running] python -u "c:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\tempCodeRunnerFile.py"
x1 = 1.5
x2 = 3.8
[Done] exited with code=0 in 1.647 seconds