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坐标之和。

如果是一條直線的話計算就很容易了,于是便想辦法能不能用一條直線y=a*x+b來代替y=x^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;
}