6

问题:如何使用连续映射 - Link1:伯努利位移映射来建模二进制序列?

概念: 二元映射也称为伯努利位移映射,表示为x(k+1) = 2x(k) mod 1。在Link2: Symbolic Dynamics中,解释了 Bernoulli Map 是一个连续的 Map 并用作 Shift Map。这将在下面进一步解释。

数字轨迹可以通过划分为适当的区域并为其分配符号来进行符号化。通过写下对应于其轨道上的点访问的连续分区元素的符号序列来获得符号轨道。人们可以通过研究其符号轨道来了解系统的动力学。该链接还说伯努利位移图用于表示符号动力学。

问题 :

Bernoulli Shift Map如何用于生成二进制序列?我试过这样,但这不是Link2中的文档解释的。因此,我采用了 Map 的数字输出并通过以下方式通过阈值转换为符号:

x = rand();
 y = mod(2* x,1)  % generate the next value after one iteration

y =

    0.3295 
if y >= 0.5 then s = 1
else s = 0

其中0.5是阈值,称为伯努利图的临界值。

我需要将实数表示为分数,如 Link2 第 2 页所述。

有人可以展示我如何应用伯努利位移图来生成符号化轨迹(也称为时间序列)吗?

如果我的理解有误,请纠正我。

如何将实数值时间序列转换为符号化,即如何使用伯努利图对二元轨道/时间序列进行建模?

4

2 回答 2

6

您当然可以在实数空间中计算它,但您可能会遇到精度问题(取决于起点)。如果您对研究轨道感兴趣,您可能更喜欢使用有理分数表示。有更有效的方法可以做到这一点,但以下代码说明了一种计算从该映射派生的序列的方法。您将在 Link 2 的第 2 页上看到 period-n 定义。您应该能够从此代码中看到如何轻松地在实数空间中工作作为替代方案(在这种情况下,matlab 函数rat将恢复一个有理从你的实数近似)。

[编辑] 现在用二进制序列明确!

% start at some point on period-n orbit
period = 6;
num = 3;
den = 2^period-1;

% compute for this many steps of the sequence
num_steps = 20;

% for each step
for n = 1:num_steps

    % * 2
    num = num * 2;

    % mod 1
    if num >= den
        num = num - den;
    end

    % simplify rational fraction
    g = gcd(num, den);
    if g > 1
        num = num / g;
        den = den / g;
    end

    % recover 8-bit binary representation
    bits = 8;
    q = 2^bits;
    x = num / den * q;
    b = dec2bin(x, bits);

    % display
    fprintf('%4i / %4i  ==  0.%s\n', num, den, b);

end

啊……为了完整起见,这里是实值版本。纯数学家现在应该把目光移开。

% start at some point on period-n orbit
period = 6;
num = 3;
den = 2^period-1;

% use floating point approximation
x = num / den;

% compute for this many steps of the sequence
num_steps = 20;

% for each step
for n = 1:num_steps

    % apply map
    x = mod(x*2, 1);

    % display
    [num, den] = rat(x);
    fprintf('%i / %i\n', num, den);

end

而且,为了额外的功劳,为什么这个实现快速但愚蠢?(提示:尝试将 num_steps 设置为 50)...

% matlab vectorised version
period = 6;
num = 3;
den = 2^period-1;
x = zeros(1, num_steps);
x(1) = num / den;
y = filter(1, [1 -2], x);
[a, b] = rat(mod(y, 1));
disp([a' b']);

好的,这应该是一个答案,而不是一个问题,所以让我们回答我自己的问题......

它很快,因为它使用 Matlab 的内置(和高度优化filter的)函数来处理迭代(也就是说,在实践中,迭代是在 C 中完成的,而不是在 M 脚本中)。在 Matlab 中总是值得记住filter的,我经常惊讶于它如何能很好地用于看起来不像过滤问题的应用程序。filter但是,不能进行条件处理,也不支持模运算,那么我们如何摆脱它呢?仅仅是因为此映射具有将输入处的整个周期映射到输出处的整个周期的属性(因为映射操作乘以一个整数)。

这很愚蠢,因为它很快就遇到了上述精度问题。设置num_steps为 50 并观察它开始得到错误的答案。发生的事情是过滤器操作中的数字变得如此之大(10^14 阶),以至于我们真正关心的位(小数部分)不再可以在同一个双精度变量中表示。

最后一点是一种转移,它更多地与计算而不是数学有关 - 如果您的兴趣在于符号序列,请坚持第一个实现。

于 2015-05-12T12:15:38.950 回答
4

如果您只想处理有理类型的输出,则首先必须将系列的起始项转换为有理数(如果不是)。你可以这样做:

[N,D] = rat(x0) ;

一旦有了分子N和分母D,计算级数就很容易了x(k+1)=mod(2*x(k), 1),甚至不需要循环。

对于部分2*x(k),这意味着所有的Numerator(k)都将乘以2的连续幂,这可以通过矩阵乘法来完成(或者bsxfun对于函数的爱好者):
所以2*x(k)=>在Matlab中N.*(2.^(0:n-1))(N是标量,x0的分子,n是您要计算的项数)。

Mod1操作也很容易转换为有理数:mod(x,1)=mod(Nx,Dx)/Dx(Nx并且Dx是 的分子和分母x

如果您不需要简化分母,您可以在一行中获得该系列的所有分子:

xn = mod( N.*(2.^(0:n-1).'),D) ;

但为了视觉舒适,有时简化会更好,所以考虑以下函数:

function y = dyadic_rat(x0,n)

   [N,D] = rat(x0) ;                   %// get Numerator and Denominator of first element
   xn = mod( N.*(2.^(0:n-1).'),D) ;    %'// calculate all Numerators
   G = gcd( xn , D ) ;                 %// list all "Greatest common divisor"
   y = [xn./G D./G].' ;                %'// output simplified Numerators and Denominators

如果我从您的 wiki 链接 ( x0=11/24) 中给出的示例开始,我会得到:

>> y = dyadic_rat(11/24,8)
y =
    11    11     5     2     1     2     1     2
    24    12     6     3     3     3     3     3

如果我从Rattus Ex Machina ( )给出的示例开始x0=3/(2^6-1),我也会得到相同的结果:

>> y = dyadic_rat(3/63,8)
y =
     1     2     4     8    16    11     1     2
    21    21    21    21    21    21    21    21
于 2015-05-12T17:30:57.637 回答