How to fix the difference in precision between double data type and uint64 - matlab

I'm in the process of implementing Three Fish block cipher using MATLAB. At first, I implemented the algorithm on uint8 numbers to validate my code. Every thing was OK and the decryption was successful. But when I replaced the numbers to uint64 the plain text did not retrieved correctly.
I traced the rounds results again and over again to find the reason, but I couldn't find it so far. There is difference in the first four digits between encryption and decryption, that is, along the rounds x encrypted as 9824265115183455531, but it decrypts as 9824265115183455488.
I think the reason behind this difference is in the functions AddMod64 and SubMod64 to find arithmetic modulo 2 to the power 64. but really I could not fix it so far.
I know that
double(2^64) = 18446744073709552000
and
uint64(2^64) = 18446744073709551615 % z = ( x + y ) % 2^64
function z = AddMod64(x , y)
m = uint64(2^64);
z = double(mod(mod(double(x),m)+mod(double(y),m),m));
end
% z = (x - y ) % 2^64
function z = SubMod64(x , y)
m = uint64(2^64);
z = double(mod(mod(double(x),m) - mod(double(y),m),m));
end

double(2^64) is already the wrong result, the double type can hold only up to 2^52-1 as an integer without rounding.
Also, when you do uint64(2^64), the power is computed using double, giving the wrong result, which you then cast to uint64. And because the maximum value that a uint64 van hold is 2^64-1, that whole operation is wrong.
Use maxint instead:
m = maxint('uint64');
To do modulo addition in MATLAB is rather tricky, because MATLAB does saturated arithmetic with integers. You need to test for overflow before doing the computation.
if x > m - y
x = y - (m - x + 1);
else
x = x + y
end

Related

Finding the maximum value from an expression using a loop in Matlab

I want to find the maximum value using the second derivative of the the expression when x is between 0 and 1. In other words I am taking the derivative of cox(x^2) twice to get the second derivative resulting in - 2*sin(x^2) - 4*x^2*cos(x^2), then I want to evaluate this second derivative at x = 0 to x = 1, and display the maximum value of the populated values.
I have:
syms x
f = cos(x^2);
secondD = diff(diff(f));
for i = 0:1
y = max(secondD(i))
end
Can someone help?
You can do it easily by subs and double:
syms x
f = cos(x^2);
secondD = diff(diff(f));
% instead of the for loop
epsilon = 0.01;
specified_range = 0:epsilon:1;
[max_val, max_ind] = max(double(subs(secondD, specified_range)));
Please note that it is a numerical approach to find the maximum and the returned answer is not completely correct all the time. However, by increasing the epsilon, you can expect a better result in general (again in some cases it is not completely correct).

how can I show more than 15 significant digits for each entry in matlab?

I want to calculate numbers in Matlab.
how can I show more than 15 significant digits for each entry in Matlab?
a = 1:10;
x = (773712524553590618513 + (a * 8864385670));
Using the vpa function in the Symbolic Math Toolbox more than 16 digits can be shown.
format long e
a=1:10;
x = (773712524553590618513+(a*8864385670));
vpa(x)
Edit: Any clarification between the implications of using syms against variable-point-precision (vpa) for a, 773712524553590618513 and 8864385670 in this case is much appreciated. Seems that using vpa() on each item would have some error propagation.
a = sym(1:10);
f = sym(773712524553590618513)+(a*sym(8864385670));
Significant_Digits = 32;
x = vpa(f,Significant_Digits)

Implementing my own FFT in MATLAB giving wrong results

I'm trying to implement my own fft in MATLAB the following way:
function z=FastFourierTransform(x)
N=length(x);
if N <= 1
z = x;
else
range = (0:N/2-1);
e = exp(-2i*pi/N).^range;
odd = FastFourierTransform(x(1:2:N-1));
even = e.*FastFourierTransform(x(2:2:N));
z = [even + odd, even - odd];
end
return
Turns out, there seems to be somthing wrong with it since it does not give the same result as the built in function provided by MATLAB.
I'm calling the function the following way:
N = 128;
x = 32*pi*(1:N)'/N;
u = cos(x/16).*(1+sin(x/16));
actualSolution = fft(u);
actualSolution
mySolution = FastFourierTransform(u)';
mySolution
actualSolution
mySolution
The numbers are always the same but they sometimes differ in their sign.
You have swapped odd and even.
Using this line to compute z will produce the correct FFT:
z = [odd + even, odd - even];
My guess is that the source of confusion is that Matlab uses 1-based indices, and the pseudocode you used to implement the function uses 0-based indices.

integers can only be combined with integers of same class or scalar doubles error

I do not know what this error means or how to fix it. I am trying to perform an image rotation in a separate space of coordinates. When defining the reference space of the matrix to be at zero, I am getting the error that integers can only be comibined with integers of the same class or scalar doubles. the line is
WZcentered = WZ - [x0;yo]*ones(1,Ncols);
WZ is classified as a 400x299x3 unit 8, in the workspace. It is an image. x0 and y0 are set to 0 when the function is called. How can I fix this issue/what exactly is happening here?
Also, when I do the same thing yet make WZ to be equal to double(WZ) I get the error that 'matrix dimensions must agree.' I am not sure what the double function does however. Here is the whole code.
function [out_flag, WZout, x_final, y_final] = adopted_moveWZ(WZ, x0, y0);
%Initial Test of plot
[Nrows,Ncols]=size(WZ);
if Nrows ~= 2
if Ncols ==2
WZ=transpose(WZ); %take transpose
[Nrows,Ncols]=size(WZ); %reset the number of rows and columns
else
fprintf('ERROR: Input file should have 2-vectors for the input points.\n');
end
end
plot(WZ(1,:),WZ(2,:),'.')
title('These are the original points in the image');
pause(2.0)
%WZorig = WZ;
%centering
WZcentered = WZ - ([x0;y0] * ones(1,Ncols));
FigScale=400;
axis([-FigScale 2*FigScale -FigScale 2*FigScale])
disp('Hit any key to start the animation');
pause;
SceneCenter = zeros(Nrows,Ncols);
WZnew = WZcentered;
for ii=0:20
%rotate
R = [cos(pi/ii) -sin(pi/ii) 0; sin(pi/ii) cos(pi/ii) 0; 0 0 1];
WZnew = R * WZnew;
plot(WZnew(1,:),WZnew(2,:),'.')
%place WZnew at a different place in the scene
SceneCenter = (ii*[30;40])*ones(1,Ncols);
plot(SceneCenter(1,:) + WZnew(1,:), SceneCenter(2,:) + WZnew(2,:),'.')
axis([-FigScale 2*FigScale -FigScale 2*FigScale])
pause(1.0);
end
%Set final values for output at end of program
x_final = SceneCenter(1,1);
y_final = SceneCenter(2,1);
PPout = PPnew + SceneCenter;
This happens due to WZ and ([x0;y0] * ones(1,Ncols)) being of different data types. You might think MATLAB is loosely typed, and hence should do the right thing when you have a floating point type operated with an integer type, but this rule breaks every once in a while. A simpler example to demonstrate this is here:
X = uint8(magic(5))
Y = zeros(5)
X - Y
This breaks with the same error that you are reporting. One way to fix this is to force cast one of the operands to the other, typically up-casted to make sure the math works. When you do this, both the numbers you are working on are floating point (double precision), and so they are represented in the same byte formatting sequence in memory. This way, the '-' sign is valid, in the same way that you can say 3 apples + 4 apples = 7 apples, but 3 oranges (uint8) + 4 apples (double) = ?. The double(X) makes it clear that you really mean to use double precision arithmetic, and hence fixes the error. This is how it looks now:
double(X) - Y
After having identified this, the new error is 'matrix dimensions do not match'. This means exactly what it says. WZ is a 400x299x3 matrix, and the right hand side matrix is 2xnCols. Now can you subtract a 2D matrix from a 3D matrix of different sizes meaningfully?
Depending on what your code is really intending to do, you can pad the RHS matrix, or find out other ways to make the sizes equal.
All of this is why MATLAB includes routines to do image rotation, namely http://www.mathworks.com/help/images/ref/imrotate.html . This is part of the Image Processing Toolbox, though.

Using the 'solve' function

I would like to solve an equation for x, and i know that there are atleast two solutions,which means that jj will be a vector. I need the largest of those solutions - that is were max(jj) comes into play. However z = max(jj)
will give me the biggest number, but it does not evaluate it. for example z could be = 2*3^4 + 1 . In this form i can't send this "number" to another function which I want to do. the 'k' is a given number not a variable. (say k=10 or any other number)
syms x
eqn = x + (k/6)*(x^2 -1) ==0
jj = solve(eqn,x)
z = max(jj)
You are looking for a way to convert from symbolic to numeric form. There is a standard symbolic toolbox function for that: double.
z1=double(z)
should return the value of the expression in a double format array.