Код не работает с большими значениями для циклов - PullRequest
0 голосов
/ 29 сентября 2018

Я реализую функцию сопряжения Шудика в Matlab, где я объединяю 2 значения, поступающие из 2 разных матриц X и Y, в уникальное значение, заданное функцией 'CantorPairing2D(X,Y), После этого я обращаюсь к процессу, чтобы проверить егообратимость, заданная функцией 'InverseCantorPairing2( X )'.Но я, кажется, получаю необычную проблему, когда я проверяю эту функцию для небольших матриц размера, скажем 10 * 10, она работает нормально, но для моего кода мне нужно использовать 256 * 256 матриц A и B, а затем кодидет не так, на самом деле то, что он дает, немного странно, потому что когда я инвертирую процесс, значения в матрице A в некоторых местах совпадают со значениями B, например, A (1,1) = B (1,1) и A (1,2) = B (1,2).Может ли кто-нибудь помочь.

VRNEW=CantorPairing2D(VRPRO,BLOCK3);

function [ Z ] = CantorPairing2D( X,Y )
[a,~] =(size(X));

Z=zeros(a,a);
for i=1:a
    for j=1:a
        if( X(i,j)~= (max(X(i,j),Y(i,j))) )
            Z(i,j)= X(i,j)+(Y(i,j))^2;
        else
            Z(i,j)= (X(i,j))^2+X(i,j)+Y(i,j);
        end
    end
end
Z=Z./1000;
end

function [ A,B ] = InverseCantorPairing2( X )
[a, ~] =(size(X));
Rfinal=X.*1000;
A=zeros(a,a);
B=zeros(a,a);
for i=1:a
    for j=1:a
        if(  ( Rfinal(i,j)- (floor( sqrt(Rfinal(i,j))))^2) < floor(sqrt(Rfinal(i,j))) )
            T=floor(sqrt(Rfinal(i,j)));
            B(i,j)=T;
            A(i,j)=Rfinal(i,j)-T^2;
        else
            T=floor(    (-1+sqrt(1+4*Rfinal(i,j)))/2      );
            A(i,j)=T;
            B(i,j)=Rfinal(i,j)-T^2-T;
        end
    end
end
end
      Example if     A= 45    16     7    17 
                         7    22    11    25
                        11    12     9    17                       
                         2    11     3     5                        

                      B=   0     0     0     1
                           0     0     0     1
                           1     1     1     1
                           1     3     0     0

          Then after pairing i get 
                      C =2.0700    0.2720    0.0560    0.3070
                         1.4060    0.5060    0.1320    0.6510
                         0.1330    0.1570    0.0910    0.3070
                         0.0070    0.1350    0.0120    0.0300    

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

1 Ответ

0 голосов
/ 30 сентября 2018

Если возможно, это очень помогло бы в качестве контрпримера, когда ваш код не работает.

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

Я не знаком с конкретным алгоритмом, но наблюдаю несоответствие в определении CantorPairing.

для элементов, где Y = X, если ваш оператор if будет ложным, поскольку X = max (X, X);поэтому для этих элементов ваш Z будет X ^ 2 + X + Y, но для гипотезы X = Y, следовательно, ваш будет иметь: X ^ 2 + X + X = X ^ 2 + 2 * X;

теперь, если мы слегка возмущаем уравнение и предполагаем, что Y = X + 10 * eps, ваше утверждение if будет истинным (так как Y> X), а ваш Z будет X + Y ^ 2;поскольку X ~ = Y, мы можем приблизиться к X + X ^ 2

, поэтому ваше уравнение очень темпераментно для числового приближения (и у вас определенно есть разрыв в Z).Опять же, я не знаком с алгоритмом, и вполне может быть, что вы хотите такое поведение, но это маловероятно: поэтому я указываю на это.

Ниже приводится моя версия вашего кода, я также сообщаю об этомпотому что я надеюсь, что он поможет вам познакомиться с логическим индексированием и векторизованным кодом (это идиоматическая форма для MATLAB, не говоря уже о том, что она гораздо быстрее, чем вложенная в циклы).

function [ Z ] = CantorPairing2D( X,Y )
[a,~] =(size(X));

Z=zeros(a,a);

firstConditionIndeces = Y  >  X;  % if  Y > X then X is not the max between Y and X 
% update elements on which to apply first equation 
Z(firstConditionIndeces) = X(firstConditionIndeces) + Y(firstConditionIndeces).^2;

% update elements on the remaining elements
Z(~firstConditionIndeces) = X(~firstConditionIndeces).^2 + X(~firstConditionIndeces) + Y(~firstConditionIndeces) ; 

Z=Z./1000;
end


function [ A,B ] = InverseCantorPairing2( X )
[a, ~] =(size(X));
Rfinal=X.*1000;
A=zeros(a,a);
B=zeros(a,a);
T = zeros(a,a) ; 
% condition deciding which updates to be applied
indecesToWhichApplyFstFcn =  Rfinal- (floor( sqrt(Rfinal )))^2   < floor(sqrt(Rfinal)) ; 

% elements on which to apply the first update
T(indecesToWhichApplyFstFcn) = floor(sqrt(Rfinal )) ; 
B(indecesToWhichApplyFstFcn) = floor(Rfinal(indecesToWhichApplyFstFcn)) ;
A(indecesToWhichApplyFstFcn) = Rfinal(indecesToWhichApplyFstFcn) - T(indecesToWhichApplyFstFcn).^2;

% updates on which to apply the remaining elements
A(~indecesToWhichApplyFstFcn) = floor(    (-1+sqrt(1+4*Rfinal(~indecesToWhichApplyFstFcn  )))/2      ) ; 
B(~indecesToWhichApplyFstFcn) = Rfinal(~indecesToWhichApplyFstFcn) - T(~indecesToWhichApplyFstFcn).^2 - T(~indecesToWhichApplyFstFcn) ; 

end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...