天天看點

1^3 +2^3+3^3+...+n^3

1^3 +2^3+3^3+...+n^3=?

高一時,有個同學說要計算半圓的面積,需要先計算1^2 +2^2+3^2+...+n^2的值,讓我幫忙算一下。下面是計算1^3 +2^3+3^3+...+n^3的過程,和計算1^2 +2^2+3^2+...+n^2類似

y=x^3的函數圖像如下,1^3 +2^3+3^3+...+n^3的值就是各個x 的y坐标之和。

1^3 +2^3+3^3+...+n^3

如果是一條直線的話計算就很容易了,于是便想辦法能不能用一條直線y=a*x+b來代替y=x^3,于是想到了回歸直線。下面先求回歸直線

回歸直線計算  

 回歸直線計算公式如下:

1^3 +2^3+3^3+...+n^3
1^3 +2^3+3^3+...+n^3

根據如上公式,算得過(1,1)、(2,8)這兩點的回歸直線系數 a(^)=-6 , b(^)=7

過(1,1)、(2,8)、(3,27)點的回歸直線系數 a(^)=-14 , b(^)=13

過(1,1)、(2,8)、(3,27)、(4,64)點的回歸直線系數 a(^)=-27, b(^)=20.8

過(1,1)、(2,8)、(3,27)、(4,64)、(5,125)點的回歸直線系數 a(^)=-46.2, b(^)=30.4

過(1,1)、(2,8)...... (6,216)點的回歸直線系數 a(^)=-72.8, b(^)=41.8

過(1,1)、(2,8)...... (7,343)點的回歸直線系數 a(^)=-108, b(^)=55

過(1,1)、(2,8)...... (8,512)點的回歸直線系數 a(^)=-153, b(^)=70

......

我們得到了如下兩組值

a(^) -6 -14 -27 -46.2 -72.8 -108 -153 ...
b(^) 7 13 20.8 30.4 41.8 55 70 ...

如果能用一個函數表示a(^)或b(^)就可以得到y=x^3(x=1,2,3,4...)的回歸直線了,得到回歸直線就可以計算出1^3 +2^3+3^3+...+n^3了,接下來就是求這兩個函數了。

Young定理 

  如果有一個數列,依次求相鄰兩數的差,得到新的數列,繼續對新數列求相鄰兩數之差。重複以上操作,若得出的數列中每個數字都相等則停止計算,若得到的新數列數量是n,則原數列是一個(n-1) 次函數

根據以上定理,我們先來計算b(^) 

7 13 20.8 30.4 41.8 55 70

求差得到

6 7.8 9.6 11.4 13.2 15

繼續對新數列相鄰兩數求差得到

1.8 1.8 1.8 1.8 1.8

最終結果全是1.8 , 是以

Yb 7 13 20.8 30.4 41.8 55 70
x 2 3 4 5 6 7 8

是一個二次函數,我們設 Yb=a*x^2+b*x+c,分别帶入求得

a=0.9   b= 1.5  c=0.4,

是以 Yb=0.9*x^2 + 1.5*x  +  0.4,

同理算得a(^)對應的函數是 Ya= -0.2 * x^3 -0.7 * x^2 -0.7 * x -0.2

是以y=x^3 (x=1,2,3,4,5...)的回歸直線是

 f(x) = Yb  *  x  +  Ya 

是以1^3 +2^3+3^3+...+n^3 = f(1)+f(2)+f(3)+...+f(n)

           = (Yb+Ya)+(Yb*2+Ya)+(Yb*3+Ya)+...+(Yb*n+Ya)

           =Yb*(1+2+3+...+n) + Ya*n

           =Yb*(  (1+n)*n/2  )+ Ya*n

=( 0.9*n^2 + 1.5*n + 0.4 ) *( (1+n)*n/2) +( -0.2 * n^3 -0.7 * n^2 -0.7 * n -0.2)  *  n

化簡得:

   0.25*n^4 + 0.5* n^3 + 0.25* n = ( n * (n+1) / 2)^2

附a尖b尖計算代碼

public class M {

	public static void main(String[] args) {
		
		ab();
	}
 
	/**
	 * 求 a尖  b尖
	 */
	private static void ab() {
		for (int i = 3; i < 10; i++) {
			int x[]=new int[i-1];
			int y[]=new int [i-1];
			for (int j = 1; j < i; j++) {
				x[j-1]=j;
				y[j-1]=j*j*j;
				
			}
			
			double[]ab=get(x,y);
			System.out.println(ab[0]+" "+ab[1]);
			
		}
	}

	private static double[] get(int[] x, int[] y) {
		double sumXY = 0;
		double averX;
		double averY;
		double sumXX = 0;
		
		for (int i = 0; i < y.length; i++) {
			sumXY=sumXY+x[i]*y[i];
		}
		
		double temp=0;
		for (int i = 0; i < x.length; i++) {
			temp+=x[i];
		}
		averX=temp/x.length;
		
		temp=0;
		for (int i = 0; i < y.length; i++) {
			temp+=y[i];
		}
		averY=temp/y.length;
		
		
		for (int i = 0; i < x.length; i++) {
			sumXX=sumXX+x[i]*x[i];
		}
		
		
		double b=1.0*(sumXY-x.length*averX*averY)/( sumXX-x.length*averX*averX   );
		
		double a=averY-b*averX;
		
		return new double[]{a,b};
	}
	

}
           

函數次數計算代碼

public static void main(String[] args) {

//		double values[]={-6.0,
//				-14.0,
//				-27.0,
//				-46.2,
//				-72.8,
//				-108.0,
//				-153.0
//		};
		
		
		double values[]={7,
				13	,
				20.8,
				30.4	,
				41.8,	
				55	,
				70,
		};
		
		int end=values.length;
		int k=0;
		while(!isAllEquals(values,end)){
			if (end<3) {
				throw new RuntimeException("too little param");
			}
			for (int i = 1; i < end; i++) {
				values[i-1]=values[i]-values[i-1];
			}
			end--;
			k++;
		}
		
		System.out.println(k+"次");
		
	}
 
	/**
	 * 
	 * @param values
	 * @param end
	 * @return
	 */
	private static boolean isAllEquals(double[] values, int end) {
		for (int i = 1; i <end; i++) {
			if (Math.abs(values[i]-values[i-1])>1e-6) {
				return false;
			}
		}
		return true;
	}
           

計算函數系數

public static void main(String[] args) {

		double x[]={ 2,	3,	4,5};
		
//		double y[]={7,	13,	20.8 };
		double y[]={-6	,-14,	-27	,-46.2, };
		double []v=getAbcd(x,y,3);
		
		System.out.print("y= ");
		
		for (int i = v.length-1; i>-1; i--) {
			if (v[i]>1e-6) {
				System.out.print("  +");
			}
			String val=String.format("%.5f", v[i]);
			if (i>1) {
				System.out.print( "  "+ val+"*x^"+i );
			}else if(i==1){
				System.out.print(   "  "+val+"*x" );
			}else{
				System.out.print(   "  "+val );
			}
				
		} //列印内容  y=   -0.20000*x^3  -0.70000*x^2  -0.70000*x  -0.20000
	}

	/**
	 * 
	 * @param x x值
	 * @param y y值
	 * @param degree 次數
	 * @return
	 */
	private static double[] getAbcd(double[] x, double[] y, int degree) {
		if (x.length!=y.length|| x.length!=degree+1 ) {
			throw new RuntimeException("param error");
		}

		double factors[]=new double[degree+1];
		double ysCopy[]=new double[y.length];
		double factorsCol[]=new double[y.length];
		for (int i = degree; i >-1; i--) {
			System.arraycopy(y, 0, ysCopy, 0, i+1);
			for (int j = 0; j<=i; j++) {
				factorsCol[j]=Math.pow(x[j], i);
			}
			
			int k=i;
			while (k>-1) {
				for (int j = 0; j < k; j++) {
					ysCopy[j]=ysCopy[j+1]-ysCopy[j];
					factorsCol[j]=factorsCol[j+1]-factorsCol[j];
				}
				
				k--;
			}
			
			
			factors[i]=ysCopy[0]/factorsCol[0];
			for (int j = 0; j <= i; j++) {
				y[j]=y[j]-factors[i]*Math.pow(x[j], i);
			}
			
		}
		
	
		
		return factors;
	}
           

繼續閱讀