Matlab: как представить вещественное число как двоичное

: как использовать непрерывную карту -Link1: Бернулли Сдвиг Карты для моделирования двоичной последовательности?

концепция : Диадическая карта, также называемая картой сдвига Бернулли, выражается как x(k+1) = 2x(k) mod 1. В Link2: Символическая Динамика, объясняет, что карта Бернулли является непрерывной картой и используется в качестве Карты сдвига. Это объясняется ниже.

числовая траектория может быть обозначена разбиение на соответствующие области и присвоение ей символа. Символическая орбита получается путем записи последовательности символов, соответствующих последовательным элементам разбиения, посещаемым точкой на ее орбите. Можно многое узнать о динамике системы, изучая ее символические орбиты. Эта ссылка также говорит, что карта сдвига Бернулли используется для представления символической динамики.

вопрос :

как карта сдвига Бернулли используется для создания двоичная последовательность? Я пробовал так, но это не то, что объясняет документ в Link2. Итак, я взял числовой вывод карты и преобразовал в символы путем порога следующим образом:

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 - пороговое значение, называемое критическим значением карты Бернулли.

мне нужно представить реальное число в виде дробей, как описано здесь на странице 2 Link2.

может кто-нибудь показать, как я могу применить карту сдвига Бернулли к генерировать символическую траекторию (также называемую временным рядом)?

пожалуйста, поправьте меня, если мое понимание неправильно.

как преобразовать реальный числовой временной ряд в символический, т. е. как использовать карту Бернулли для моделирования бинарных орбит / временных рядов?

2 ответов


вы можете, конечно, вычислить это в реальном пространстве чисел, но вы рискуете столкнуться с проблемами точности (в зависимости от начальной точки). Если вы заинтересованы в изучении орбит, Вы можете предпочесть работать в рациональном представлении дробей. Существуют более эффективные способы сделать это, но следующий код иллюстрирует один из способов вычисления ряда, полученного из этой карты. Вы увидите определение period-n на странице 2 Вашей ссылки 2. Вы должны иметь возможность видеть из этого кода, как вы могли бы легко работать в реальное пространство чисел в качестве альтернативы (в этом случае функция matlab rat восстановит рациональное приближение от вашего реального числа).

[EDIT] теперь с двоичной последовательностью, сделанной явной!

% 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

Ach... для полноты, вот реальная версия. Математиков отвернулся.

% 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-скрипте). Это всегда стоит помнить filter в Matlab я постоянно удивляюсь, как его можно использовать для приложений, которые не похожи на проблемы фильтрации. filter не может выполнять условную обработку, однако, и не поддерживает арифметику по модулю, так как нам это сойдет с рук? Просто потому, что эта карта имеет свойство, что целые периоды на входной карте целые периоды на выходе (потому что операция карты умножается на целое число).

это глупо, потому что он очень быстро попадает в вышеупомянутые проблемы с точностью. Set num_steps до 50 и смотреть, как он начинает получать неправильные ответы. Что происходит-это число внутри фильтра операция становится настолько большой (порядок 10^14), что бит, о котором мы действительно заботимся (дробная часть), больше не представляется в той же переменной двойной точности.

этот последний бит является чем - то вроде диверсии, которая больше связана с вычислениями, чем с математикой-придерживайтесь первой реализации, если ваш интерес заключается в последовательностях символов.


если вы хотите иметь дело только с рациональным типом вывода, вам сначала нужно преобразовать начальный член вашего ряда в рациональное число, если это не так. Вы можете сделать это с:

[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

если я начну с примера, приведенного в вашей ссылке на вики (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