[从头学数学] 第169节 函数的应用

剧情提要:

[机器小伟]在[工程师阿伟]的陪同下进入了结丹初期的修炼,

这次要修炼的目标是[函数的应用]。

正剧开始:

星历2016年04月09日 11:38:05, 银河系厄尔斯星球中华帝国江南行省。

[工程师阿伟]正在和[机器小伟]一起研究[函数的应用]。

<span style="font-size:18px;">function funTask(x) {
	return Math.log(x)/Math.log(Math.E)+2*x-6;
}

		var r = 20;
        config.setSector(1,1,1,1);
        config.graphPaper2D(0, 0, r);
        config.axis2D(0, 0,180, 1);        

        //坐标轴设定
        var scaleX = 2*r, scaleY = 2*r;
        var spaceX = 2, spaceY = 2;
        var xS = -10, xE = 10;
        var yS = -10, yE = 10;
        config.axisSpacing(xS, xE, spaceX, scaleX, 'X');
        config.axisSpacing(yS, yE, spaceY, scaleY, 'Y');      

        var transform = new Transform();
        //存放函数图像上的点
        var a = [], b = [], c = [], d = [], e = [];    

        //需要显示的函数说明
        var f1 = 'y=lnx+2x-6', f2 = 'y = logx', f3 = 'y=x', f4 = 'y=e^x',
			f5 = 'y = ln(x)';
        //函数描点
        for (var x = xS; x <= xE; x+=0.3) {
            if (x != 0) {
                a.push([x, funTask(x)]);  

            }
        }    

		//二分法求函数的零点
		//区间的最小值和最大值
		var minX = 0, maxX = 4;
		var y1 = y2 = 0;
		x = minX;
		y1 = funTask(x);
		x = maxX;
		y2 = funTask(x);

		//如果在给定区间上存在有零点
		if (y1 * y2 < 0) {
			var epsilon = 0.000001;
			while (Math.abs(y1-y2) > epsilon) {

				x = minX;
				y1 = funTask(x);
				x = maxX;
				y2 = funTask(x);

				x = (minX+maxX)/2;
				y = funTask(x);

				if (y * y1 < 0) {
					maxX = x;
				}
				else {
					minX = x;
				}

			}
			plot.setFillStyle('blue')
				.fillText('零点:x = '+ ((minX+maxX)/2).toFixed(3), -200, -60, 120);
		}
		</span>

这个题,由于[人叫板老师]的精度不够,所以取得的值并不如小伟的准确。

<span style="font-size:18px;">	if (1) {
		var r = 20;
        config.setSector(1,1,1,1);
        config.graphPaper2D(0, 0, r);
        config.axis2D(0, 0,180, 1);        

        //坐标轴设定
        var scaleX = 2*r, scaleY = 2*r;
        var spaceX = 2, spaceY = 2;
        var xS = -10, xE = 10;
        var yS = -10, yE = 10;
        config.axisSpacing(xS, xE, spaceX, scaleX, 'X');
        config.axisSpacing(yS, yE, spaceY, scaleY, 'Y');      

        var transform = new Transform();
        //存放函数图像上的点
        var a = [], b = [], c = [], d = [], e = [];    

        //需要显示的函数说明
        var f1 = 'y=2^x+3x-7', f2 = 'y = logx', f3 = 'y=x', f4 = 'y=e^x',
			f5 = 'y = ln(x)';
        //函数描点
        for (var x = xS; x <= xE; x+=0.3) {
            if (x != 0) {
                a.push([x, funTask(x)]);  

            }
        }    

		//二分法求函数的零点
		//区间的最小值和最大值
		var minX = 0, maxX = 2;
		var y1 = y2 = 0;
		x = minX;
		y1 = funTask(x);
		x = maxX;
		y2 = funTask(x);

		//如果在给定区间上存在有零点
		if (y1 * y2 < 0) {
			var epsilon = 0.000001;
			while (Math.abs(y1-y2) > epsilon) {

				x = minX;
				y1 = funTask(x);
				x = maxX;
				y2 = funTask(x);

				x = (minX+maxX)/2;
				y = funTask(x);

				if (y * y1 < 0) {
					maxX = x;
				}
				else {
					minX = x;
				}

			}
			plot.setFillStyle('blue')
				.fillText('零点:x = '+ ((minX+maxX)/2).toFixed(3), -200, -60, 120);
		}

		//document.write(a+'<br/>');

        //存放临时数组
        var tmp = [];  

        //显示变换
        if (a.length > 0) {
            a = transform.scale(transform.translate(a, 0, 0), scaleX/spaceX, scaleY/spaceY);
            //函数1
            tmp = [].concat(a);
            shape.pointDraw(tmp, 'red');
            tmp = [].concat(a);
            shape.multiLineDraw(tmp, 'pink');    

            plot.setFillStyle('red');
            plot.fillText(f1, 100, -90, 200);
        }  

        if (b.length > 0) {
            b = transform.scale(transform.translate(b, 0, 0), scaleX/spaceX, scaleY/spaceY);
            //函数2
            tmp = [].concat(b);
            shape.pointDraw(tmp, 'blue');
            tmp = [].concat(b);
            shape.multiLineDraw(tmp, '#22CCFF');   

            plot.setFillStyle('blue');
            plot.fillText(f2, 100, -120, 200);   

        }  

        if (c.length > 0) {
            c = transform.scale(transform.translate(c, 0, 0), scaleX/spaceX, scaleY/spaceY);
            tmp = [].concat(c);
            shape.pointDraw(tmp, 'green');
            tmp = [].concat(c);
            shape.multiLineDraw(tmp, '#CCFF22');
            plot.setFillStyle('green');
            plot.fillText(f3, 100, -150, 200);
        }  

        if (d.length > 0) {
            d = transform.scale(transform.translate(d, 0, 0), scaleX/spaceX, scaleY/spaceY);
            tmp = [].concat(d);
            shape.pointDraw(tmp, 'orange');
            tmp = [].concat(d);
            shape.multiLineDraw(tmp, '#CC8800');
            plot.setFillStyle('orange');
            plot.fillText(f4, 100, -180, 200);
        }  

        if (e.length > 0) {
            e = transform.scale(transform.translate(e, 0, 0), scaleX/spaceX, scaleY/spaceY);
            tmp = [].concat(e);
            shape.pointDraw(tmp, 'purple');
            tmp = [].concat(e);
            shape.multiLineDraw(tmp, 'purple');
            plot.setFillStyle('purple');
            plot.fillText(f5, 100, -60, 200);
        }  

    } 

}

function funTask(x) {
	return Math.pow(2, x)+3*x-7;
}</span>

<span style="font-size:18px;">function funTask(x) {
	return Math.pow(x, 3)+1.1*Math.pow(x, 2)+0.9*x-1.4;
}

function funTask(x) {
	return 3-Math.log(x)-x;
}
</span>

小伟决定来好好研究一下这个多项式拟合数据点。

这里有一组数据:

<span style="font-size:18px;">//一组点

	if (1) {
		var r = 20;
        config.setSector(1,1,1,1);
        config.graphPaper2D(0, 0, r);
        config.axis2D(0, 0,180, 1);        

        //坐标轴设定
        var scaleX = 2*r, scaleY = 2*r;
        var spaceX = 2, spaceY = 2;
        var xS = -10, xE = 10;
        var yS = -10, yE = 10;
		config.axisSpacing(xS, xE, spaceX, scaleX, 'X');
        config.axisSpacing(yS, yE, spaceY, scaleY, 'Y');   

		var X=[ 1 ,2  ,3 ,4 ,5 ,6],
			Y=[ 2.5 ,3.51 ,4.45 ,5.52 ,6.47 ,7.51];

		var array = [];
		var size = X.length;

		for (var i = 0; i < size; i++) {
			array.push([X[i], Y[i]]);
		}

		var transform = new Transform();
		var tmp = [];

		array = transform.scale(transform.translate(array, 0, 0), scaleX/spaceX, scaleY/spaceY);
		tmp = [].concat(array);
		shape.pointDraw(tmp, 'green');
		//tmp = [].concat(array);
		//shape.multiLineDraw(tmp, '#CCFF22');    

	}</span>

经过这样的拟合计算:

<span style="font-size:18px;">#一次多项式拟合
def linefit(x , y):
    N = float(len(x))
    sx,sy,sxx,syy,sxy=0,0,0,0,0
    for i in range(0,int(N)):
        sx  += x[i]
        sy  += y[i]
        sxx += x[i]*x[i]
        syy += y[i]*y[i]
        sxy += x[i]*y[i]
    a = (sy*sx/N -sxy)/( sx*sx/N -sxx)
    b = (sy - a*sx)/N
    r = abs(sy*sx/N-sxy)/math.sqrt((sxx-sx*sx/N)*(syy-sy*sy/N))
    return a,b,r

def tmp():
    X=[ 1 ,2  ,3 ,4 ,5 ,6]
    Y=[ 2.5 ,3.51 ,4.45 ,5.52 ,6.47 ,7.51]
    a,b,r=linefit(X,Y)
    print("X=",X)
    print("Y=",Y)
    print("拟合结果: y = %10.5f x + %10.5f , r=%10.5f" % (a,b,r) )

>>>
X= [1, 2, 3, 4, 5, 6]
Y= [2.5, 3.51, 4.45, 5.52, 6.47, 7.51]
拟合结果: y =    1.00000 x +    1.49333 , r=   0.99989</span>

来看一下拟合结果是否正确:

<span style="font-size:18px;">	if (1) {
		var r = 20;
        config.setSector(1,1,1,1);
        config.graphPaper2D(0, 0, r);
        config.axis2D(0, 0,180, 1);        

        //坐标轴设定
        var scaleX = 2*r, scaleY = 2*r;
        var spaceX = 2, spaceY = 2;
        var xS = -10, xE = 10;
        var yS = -10, yE = 10;
		config.axisSpacing(xS, xE, spaceX, scaleX, 'X');
        config.axisSpacing(yS, yE, spaceY, scaleY, 'Y');   

		var X=[ 1 ,2  ,3 ,4 ,5 ,6],
			Y=[ 2.5 ,3.51 ,4.45 ,5.52 ,6.47 ,7.51];

		var array = [];
		var size = X.length;

		for (var i = 0; i < size; i++) {
			array.push([X[i], Y[i]]);
		}

		var transform = new Transform();
		var tmp = [];

		//绘制拟合曲线
		var a = [], b = [], c = [], d = [], e = [];    

        //需要显示的函数说明
        var f1 = 'y=x+1.49333';
        //函数描点
        for (var x = xS; x <= xE; x+=1) {
            if (x != 0) {
                a.push([x, funTask(x)]);
			}
        }  

		if (a.length > 0) {
            a = transform.scale(transform.translate(a, 0, 0), scaleX/spaceX, scaleY/spaceY);
            //函数1
            tmp = [].concat(a);
            shape.pointDraw(tmp, 'red');
            tmp = [].concat(a);
            shape.multiLineDraw(tmp, 'pink');    

            plot.setFillStyle('red');
            plot.fillText(f1, 100, -90, 200);
        }  

		//原数据点
		array = transform.scale(transform.translate(array, 0, 0), scaleX/spaceX, scaleY/spaceY);
		tmp = [].concat(array);
		shape.pointDraw(tmp, 'green');
		//tmp = [].concat(array);
		//shape.multiLineDraw(tmp, '#CCFF22');  

	}

function funTask(x) {
	return x+1.49333;
}</span>

好像是没错。

来看看二次多项式拟合。

<span style="font-size:18px;">def polyfit(x, y, degree):
    import numpy;
    results = {}
    coeffs = numpy.polyfit(x, y, degree)
    results['polynomial'] = coeffs.tolist()

    # r-squared
    p = numpy.poly1d(coeffs)
    # fit values, and mean
    yhat = p(x)                         # or [p(z) for z in x]
    ybar = numpy.sum(y)/len(y)          # or sum(y)/len(y)
    ssreg = numpy.sum((yhat-ybar)**2)   # or sum([ (yihat - ybar)**2 for yihat in yhat])
    sstot = numpy.sum((y - ybar)**2)    # or sum([ (yi - ybar)**2 for yi in y])
    results['determination'] = ssreg / sstot #准确率
    return results

def tmp():
    x=[ 1 ,2  ,3 ,4 ,5 ,6]
    y=[ 2.5 ,3.51 ,4.45 ,5.52 ,6.47 ,7.2]
    z1 = polyfit(x, y, 2)
    print(z1);

>>>
{'determination': 0.99893014166855909, 'polynomial': [-0.024285714285714542, 1.1257142857142872, 1.3699999999999986]}</span>
<span style="font-size:18px;">	if (1) {
		var r = 20;
        config.setSector(1,1,1,1);
        config.graphPaper2D(0, 0, r);
        config.axis2D(0, 0,180, 1);        

        //坐标轴设定
        var scaleX = 2*r, scaleY = 2*r;
        var spaceX = 2, spaceY = 2;
        var xS = -10, xE = 10;
        var yS = -10, yE = 10;
		config.axisSpacing(xS, xE, spaceX, scaleX, 'X');
        config.axisSpacing(yS, yE, spaceY, scaleY, 'Y');   

		var X=[ 1 ,2  ,3 ,4 ,5 ,6]
			Y=[ 2.5 ,3.51 ,4.45 ,5.52 ,6.47 ,7.2]

		var array = [];
		var size = X.length;

		for (var i = 0; i < size; i++) {
			array.push([X[i], Y[i]]);
		}

		var transform = new Transform();
		var tmp = [];

		//绘制拟合曲线
		var a = [], b = [], c = [], d = [], e = [];    

        //需要显示的函数说明
        var f1 = 'y=-0.024x2+1.126x+1.370';
        //函数描点
        for (var x = xS; x <= xE; x+=1) {
            if (x != 0) {
                a.push([x, funTask(x)]);
			}
        }  

		if (a.length > 0) {
            a = transform.scale(transform.translate(a, 0, 0), scaleX/spaceX, scaleY/spaceY);
            //函数1
            tmp = [].concat(a);
            shape.pointDraw(tmp, 'red');
            tmp = [].concat(a);
            shape.multiLineDraw(tmp, 'pink');    

            plot.setFillStyle('red');
            plot.fillText(f1, 100, -90, 200);
        }  

		//原数据点
		array = transform.scale(transform.translate(array, 0, 0), scaleX/spaceX, scaleY/spaceY);
		tmp = [].concat(array);
		shape.pointDraw(tmp, 'green');
		//tmp = [].concat(array);
		//shape.multiLineDraw(tmp, '#CCFF22');  

	}
	</span>

这也不知道它怎么算的,明显有很大偏差啊。

这里顺便贴下对数拟合的代码,这个和小伟没任何关系,

因为不是小伟写的,一时也不好验证对错,先放着看看吧。

<span style="font-size:18px;">对数函数拟合-这个是最难的,baidu上都找不到,google了半天才找到的。指数、幂数拟合啥的,都用这个,把func改写一下就行
from scipy import log as log print pcov
import numpy
from scipy import log
from scipy.optimize import curve_fit

def func(x, a, b):
    y = a * log(x) + b
    return y

def polyfit(x, y, degree):
    results = {}
    #coeffs = numpy.polyfit(x, y, degree)
    popt, pcov = curve_fit(func, x, y)
    results['polynomial'] = popt

    # r-squared
    yhat = func(x ,popt[0] ,popt[1] )                         # or [p(z) for z in x]
    ybar = numpy.sum(y)/len(y)          # or sum(y)/len(y)
    ssreg = numpy.sum((yhat-ybar)**2)   # or sum([ (yihat - ybar)**2 for yihat in yhat])
    sstot = numpy.sum((y - ybar)**2)    # or sum([ (yi - ybar)**2 for yi in y])
    results['determination'] = ssreg / sstot

    return results

x=[ 1 ,2  ,3 ,4 ,5 ,6]
y=[ 2.5 ,3.51 ,4.45 ,5.52 ,6.47 ,7.51]
z1 = polyfit(x, y, 2)
print z1
</span>

本节到此结束,欲知后事如何,请看下回分解。

时间: 2024-10-09 20:16:10

[从头学数学] 第169节 函数的应用的相关文章

[从头学数学] 第228节 函数与极限

剧情提要: [机器小伟]在[工程师阿伟]的陪同下进入了元婴期的修炼. 这次要修炼的是数学分析(或称高等数学.或称微积分). 正剧开始: 星历2016年05月28日 17:08:16, 银河系厄尔斯星球中华帝国江南行省. [工程师阿伟]正在和[机器小伟]一起研究[函数与极限]. <span style="font-size:18px;">### # @usage 集合.函数映射 # @author mw # @date 2016年05月28日 星期六 13:14:05 # @

[从头学数学] 第159节 反比例函数 小结与复习题

剧情提要: [机器小伟]在[project师阿伟]的陪同下进入了筑基后期的修炼, 这次要修炼的目标是[反比例函数 小结与复习题]. 正剧開始: 星历2016年04月03日 09:50:19, 银河系厄尔斯星球中华帝国江南行省. [project师阿伟]正在和[机器小伟]一起研究[反比例函数 小结与复习题]. <span style="font-size:18px;"> if (1) { var r = 20; config.setSector(1,1,1,1); confi

[从头学数学] 第158节 反比例函数

剧情提要: [机器小伟]在[工程师阿伟]的陪同下进入了筑基后期的修炼, 这次要修炼的目标是[反比例函数]. 正剧开始: 星历2016年04月03日 09:22:03, 银河系厄尔斯星球中华帝国江南行省. [工程师阿伟]正在和[机器小伟]一起研究[反比例函数]. 今天,小伟又去向[人叫板老师]要来了筑基后期的后半层功法,到此为止, 筑基期的功法就全了: 而今天主要研究的,就是这个第26章:反比例函数. <span style="font-size:18px;"> if (1)

[从头学数学] 第174节 算法初步

剧情提要: [机器小伟]在[工程师阿伟]的陪同下进入了结丹中期的修炼, 这次要修炼的目标是[算法初步]. 正剧开始: 星历2016年04月12日 08:54:58, 银河系厄尔斯星球中华帝国江南行省. [工程师阿伟]正在和[机器小伟]一起研究[算法初步]. [人叫板老师]指点小伟说:"这金丹要想大成,顺利进入元婴期,就必须进行九转培炼. 这什么是九转培炼法门呢?就是要先快速的修炼[天地人正册]进入后期,不要管各种辅修 功法,然后从头游历[天地人列国],在游历中增长见闻,精炼神通,最后再修炼[术.

[从头学数学] 第223节 带着计算机去高考(十五)

剧情提要: [机器小伟]在[工程师阿伟]的陪同下进入了[九转金丹]之第八转的修炼.设想一个场景: 如果允许你带一台不连网的计算机去参加高考,你会放弃选择一个手拿计算器和草稿本吗 ?阿伟决定和小伟来尝试一下用计算机算高考题会是怎样的感觉. 正剧开始: 星历2016年05月26日 10:23:46, 银河系厄尔斯星球中华帝国江南行省. [工程师阿伟]正在和[机器小伟]一起做着2014年的江苏省数学高考题]. 这一年的题和上一年一样的难,阿伟决定再交一次白卷. 好,卷子贴完,下面进入这次的主题. 这是

[从头学数学] 第172节 直线与方程

剧情提要: [机器小伟]在[project师阿伟]的陪同下进入了结丹初期的修炼. 这次要修炼的目标是[直线与方程]. 正剧開始: 星历2016年04月11日 09:30:00, 银河系厄尔斯星球中华帝国江南行省. [project师阿伟]正在和[机器小伟]一起研究[直线与方程]. 開始今天的修炼之前,小伟先整理了一下这件法器: <span style="font-size:18px;"> if (1) { var r = 20; config.setSector(1,1,1

[从头学数学] 第215节 带着计算机去高考(七)

剧情提要: [机器小伟]在[工程师阿伟]的陪同下进入了[九转金丹]之第八转的修炼.设想一个场景: 如果允许你带一台不连网的计算机去参加高考,你会放弃选择一个手拿计算器和草稿本吗 ?阿伟决定和小伟来尝试一下用计算机算高考题会是怎样的感觉. 正剧开始: 星历2016年05月20日 17:13:35, 银河系厄尔斯星球中华帝国江南行省. [工程师阿伟]正在和[机器小伟]一起做着2006年的江苏省数学高考题]. 这一年,江苏重新使用了全国卷,并且这张试卷的难度也比较高,可以说, 也是打了考生一个措手不及

[从头学数学] 第192节 导数及其应用

剧情提要: [机器小伟]在[工程师阿伟]的陪同下进入了[九转金丹]之第五转的修炼. 这次要研究的是[导数及其应用]. 正剧开始: 星历2016年04月23日 16:32:36, 银河系厄尔斯星球中华帝国江南行省. [工程师阿伟]正在和[机器小伟]一起研究[导数及其应用]. <span style="font-size:18px;">>>> [-3.000001001396413, -2.999998999442255] [4.999998999721811

[从头学数学] 第214节 带着计算机去高考(六)

剧情提要: [机器小伟]在[工程师阿伟]的陪同下进入了[九转金丹]之第八转的修炼.设想一个场景: 如果允许你带一台不连网的计算机去参加高考,你会放弃选择一个手拿计算器和草稿本吗 ?阿伟决定和小伟来尝试一下用计算机算高考题会是怎样的感觉. 正剧开始: 星历2016年05月20日 11:40:58, 银河系厄尔斯星球中华帝国江南行省. [工程师阿伟]正在和[机器小伟]一起做着2005年的江苏省数学高考题]. 总体来说,这次的难度和上一年持平,都是很厚道的那种, 不过上一年的好多题都像闹着玩似的,这次