问题描述
我正在尝试用Parker和Chua的C语言实现算法,如《混沌系统的实用数值算法》(第6章)所述。
在该章中,作者描述了一种绘制离散时间系统(也称为地图)流形的方法。我正在尝试将给定的伪代码转换为标准地图(Chirikov-Taylor)的C代码。我已经为Fortran做到了,现在C给出了与Fortran 90相同的问题。
这个想法是在(不稳定的)流形上显示点,使得它们之间的距离与给定的公差相距不远。如果是这样,则对点进行线性插值。正如作者所说,就像一个窗口在移动并露出歧管一样。
问题在于输出在流形上给出了一些点,但是在几个点之后,输出却挂在一个值上。
我被警告有关C和Fortran的问题,特别是关于数组索引的警告。但是我看不到该方法或伪代码的翻译有什么问题...
我知道有很多方法可以用于流形可视化和有关它的论文,但是如果我不能从给定的伪代码构造一个,我会怀疑我的其他实现方式是否正确……所以我更喜欢使它起作用。
好吧,让我展示一下我的代码的简化版本,该版本应该可以工作(在C语言中):
x_bar = alpha * vx;
y_bar = alpha * vy;
//choose linear approximation as initial condition
x[0] = x_bar;
p[0] = y_bar;
//iterate once
x[1] = map_x(x[0],p[0]);
p[1] = map_p(x[0],p[0]);
//iterate again
x[2] = map_x(x[1],p[1]);
p[2] = map_p(x[1],p[1]);
x_new = x[1];
y_new = p[1];
do
{
dist = sqrt( pow((x[2] - x[1]),2.) + pow((p[2] - p[1]),2.) );
if(dist < 0.001) //absolute criteria for while...
{
//accept the point and move the window
printf("%f\t %f\n",x[0],p[0]);
x[0] = x[1];
p[0] = p[1];
x[1] = x[2];
p[1] = p[2];
i++;
}
else
{
//linear interpolation required
x_new = (x[0] + x_new) / 2.;
y_new = (p[0] + y_new) / 2.;
x_aux = map_x(x_new,y_new);
y_aux = map_p(x_new,y_new);
x[2] = x_aux;
p[2] = y_aux;
}
}
while(i < 10);
在上面的代码中,vx和vy是雅可比矩阵的特征向量,在固定点(x,p)=(0,0)处求值。 我的函数“ map_x”和“ map_p”运行良好,并返回了Chirikov-Taylor地图的一步迭代。
Fig: first points produced by the algorithm
谢谢。
解决方法
似乎dist < 0.001
不是要更新x[2]
或p[2]
,而是要设置x[1]=x[2]
和p[1]=p[2]
。这意味着下次循环时,距离将为0
,因为您正在做x[2]-x[1]
和p[2]-p[1]
,但它们彼此相等,所以您将得到dist = 0
。还有0 < 0.001
,因此您将继续重复此操作并停留在同一点。
您可能会缺少以下内容:
if (dist < 0.001) {
// other stuff
x[2] = map_x(x[1],p[1]);
p[2] = map_p(x[1],p[1]);
} else { // ...