无敌拟合,有限数列的克星

地球人都知道,对于有限数列,找到一个通项公式是简单的。事实上,对于项数为 n 的数列,我们只需不超过 (n-1) 次的多项式。本文用 Wolfram 语言的代码求这个多项式。……恩,还有点拓展的玩法。

地球人都知道,对于有限数列,找到一个通项公式是简单的。事实上,对于项数为 n 的数列,我们只需不超过 (n-1) 次的多项式。

以下是 Wolfram 语言的代码。

num = 2048;
list = First[RealDigits[num, 10]];
len = Length[list];
fit = Fit[list, Table[y^k, {k, 0, len - 1}], y];
Print[list]; Print@TraditionalForm@fit /. y -> x;
Print@Show[Plot[fit /. y -> x, {x, 0, len + 1}], ListPlot[list]]

这段代码在 Wolfram Mathematica 10.0 将产生以下输出。

无敌拟合代码产生的输出

如果你想玩其他数列,你只需要修改代码第一行中的数字。如果你的数列以 0 开头或者出现了超出 0~9 范围的数,将前两行改为如下所示的一行即可。

list = {1, 9, 4, 9, 1, 0, 0, 1};

你同样能得到一条优美的曲线,精确地穿过你给定的每一个点。这自然得益于 Mathematica 不逊于人的数值功能,同时亦是因为我们有以下结论作为保证。文首曾经提及。

对任意项数为 n 的有限数列,可以找到一个不超过 (n-1) 次的多项式,作为它的通项公式。

……我承认表述得很蹩脚。下面我试着证明它。

设数列为 {a1,a2,a3,…,an},待定多项式 f(x)=b0 + b1x + b2x2 + … + bnxn。对于任意 i = 1,2,3,…,n ,应有 f(i)=ai,由此得方程组

$$\begin{cases}b_{0} + b_{1} + b_{2} + \cdots + b_{n}= a_{1} \\ b_{0} + 2b_{1} + 4b_{2} + \cdots + 2^{n}b_{n}= a_{2} \\ \vdots \quad \quad \quad \vdots \\ b_{0} + nb_{1} + n^{2}b_{2} + \cdots + n^{n}b_{n}= a_{n} \end{cases}$$

好了。数一数,我们有 n 个方程,b0,b1,b2,…,bn 一共 (n+1) 个未知数。当 bi 全为零(i = 0,1,2,…,n),自然万事大吉。否则是非齐次线性方程组,系数矩阵的行向量组线性无关,秩为 n,每个向量增加一个分量后仍线性无关,故增广矩阵秩也为 n,根据线性方程组和矩阵的相关理论,得知这个方程组一定有解。所以符合要求的 f 存在。证毕。

好极了!好开心,这是我首次把线性代数课程学的东西用起来………反正这个证明看起来没什么问题……

回顾一下证明过程,我们注意到, f 不一定要是一个 (n-1) 次多项式。只要它是 (n-1) 个线性无关的函数的线性组合,证明就成立。所以有以下的玩法。

Mathematica 提供的 Fit 函数是很强大滴,它可以接受各种各样的函数,用这些函数的线性组合给出最小二乘拟合。下面的例子,数列是 {1,9,9,6,1,0,0,1},第一组是六个三角函数加上指数、对数、线性函数,第二组是从 0 到 7 次的正弦函数,第三组是个 7 次多项式。效果就比较壮观了。

混入三角、指数对数之后的拟合结果更加壮观。

(完)

C语言新手笔记

新手上路,难免遇到各种各样的问题。本文所收录,就是我遇到的,容易忽视的一些问题。

新手上路,难免遇到各种各样的问题。本文所收录,就是我遇到的,容易忽视的一些问题。

1. 常数不可随便写。

int a=14; 
int b=014; //前导零,是八进制的14
float a=3/2;   //得到1
float b=3/2.0; //得到1.5

2. 不要随便移项……

unsigned int x=4;
if (x > 5)
    puts("x>5");
if (x - 5 > 0)
    puts("x-5>0");
//结果将是,输出 "x-5>0"

注意到 x 的类型是 unsigned,(x-5) 的值还是正数。

3. 多一个分号?

int i, sum;
for(i=0; i<=10; i++);
{
    sum += i;
}
printf("%d", sum);
//输出并不是设想中的55,而是11。

你发现了吗,for 一行后面多写了一个分号。有的编译器会对类似情况给出 warning 曰“空的受控语句”,有的则不会,火眼金睛才能发现问题所在。

4. 搞不懂的自增

int a=2;
a/=a++;
//问此时 a 的值

这绝不是 a++ 和 ++a 的区别那么简单。事实上不同编译器会给出不同结果:gcc 3.4 给出 a==1,Turbo C 3.0 和 VC++ 11.0 则给出 a==2。从汇编码中能看出些端倪,但更深入的研究就需要对编译器的理解了。

这个故事告诉我们,不要随意使用自增(自减)运算符,特别是当被执行自增(自减)的变量在表达式中多次出现的时候。

5. 更多编译器相关的代码

int a=0;
printf("%d %d %d", a++, a++, a++);

新手跨语言:C/VB:VB6写界面,VC11写算法

作为一个新手入门的示例程序,我们用 C 写一个求两数之和(A+B Problem)的函数,然后在 VB 程序中调用它。

作为一个新手入门的示例程序,我们用 C 写一个求两数之和(A+B Problem)的函数,然后在 VB 程序中调用它。

在Visual Studio 2012建立一个Win32项目,名为ProjectName。应用程序类型选择DLL。
然后在ProjectName.cpp中写如下代码。

// ProjectName.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"

#define FUNC(x) extern "C" __declspec(dllexport) x __stdcall 

FUNC(int) SUM_(int x, int y)
{
	return x+y;
}

你可以像写普通的标准C函数一样来写这里的函数,唯一的区别是函数头前面要有一大堆关键字。我在这里使用了宏定义 FUNC(返回值类型) 简化。

extern "C" __declspec(dllexport) int/*你的返回值类型*/ __stdcall SUM_/*你的函数名*/ (int x, int y)/*你的参数列表*/

按F7键,生成ProjectName.dll。

在VB6中,建立一个标准EXE工程,在Form1中写以下代码:

Private Declare Function _
    SUM_ _
    Lib _
    "ProjectName.dll" _
    Alias _
    "_SUM_@8" _
    (ByVal x As Long, ByVal y As Long) _
    As Long

Private Sub Form_Load()
    Dim x As Integer, y As Integer, sum As Integer
    x = InputBox("请输入 x")
    y = InputBox("请输入 y")
    z = SUM_(x, y)
    MsgBox x & " + " & y & " = " & z
End Sub

Lib "ProjectName.dll":指定dll文件。建议在这里使用相对路径,把你的dll和exe放在同一目录下。
Alias "_SUM_@8":需根据C中的函数名手动修改。在__stdcall下,VC编译时会在函数名前面加一个下划线,后面加@和参数的总长度(此处是2个int,即8字节)。
ByVal x As Long:ByVal是不可少的。对应C中4字节的int,VB里是Long。

在“文件”菜单中找“生成”,生成工程1.exe。将工程1.exe和ProjectName.dll放置于同一目录下即可。

I’m back!

时隔三年,重拾写博客的激情。鼓起勇气开起了独立博客。可以自定义整个站点的任何一个细节,不得不说,这种感觉真是太好了。

时隔三年,重拾写博客的激情。鼓起勇气开起了独立博客。可以自定义整个站点的任何一个细节,不得不说,这种感觉真是太好了。

200、404 都是 HTTP 状态码。博客名字 200-404,寓意为:成功地找到了未找到。创意来自 @Shirley 🙂

自豪地采用 WordPress。目前放在 SAE 上。更新 2016-9-26:已从新浪云迁出,目前用 VPS ,来自 Vultr。

欢迎大家来踩~~~~~~~

您可以在以下位置找到我以前的文章:

1. 2011年以前,百度空间。由于百度空间已彻底关闭,您可以参观我保留的备份镜像(仅文章正文)

2. 2011年到2014年,人人网(可能需要登录)

考虑过把以前别的地方写的东西都搬过来。甚至已经在用 PHP 写从百度空间到 WordPress 的搬家工具。中途放弃了,是因为麻烦,也是因为觉得以前写的东西有些确实幼稚。所以嘛,就不搬了。这个博客将是一个新的开始。

It’s a fresh start~