Code not working with bigger values of for loops - image

I am implementing a Szudik's pairing function in Matlab, where i pair 2 values coming from 2 different matrices X and Y, into a unique value given by the function 'CantorPairing2D(X,Y), After this i reverse the process to check for it's invertibility given by the function 'InverseCantorPairing2( X )'. But I seem to get an unusual problem, when i check this function for small matrices of size say 10*10, it works fine, but the for my code i have to use a 256 *256 matrices A and B, and then the code goes wrong, actually what it gives is a bit strange, because when i invert the process, the values in the matrix A, are same as cvalues of B in some places, for instance A(1,1)=B(1,1), and A(1,2)=B(1,2). Can somebody help.
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
after the inverse pairing i should get the same A and same B. But for bigger matrices it is giving unusual behaviour, because some elements of A are same as B.

If possible it would help immensely a counter example where your code does fail.
I got to reproduce your code behaviour and I have rewritten your code in a vectorised fashion. You should get the bug, but hopefully it is a first step to uncover the underlying logic and find the bug itself.
I am not familiar with the specific algorithm, but I observe a discrepancy in the CantorPairing definition.
for elements where Y = X your if statement would be false, since X = max(X,X); so for those elements your Z would be X^2+X+Y, but for hypothesis X =Y, therefore your would have:
X^2+X+X = X^2+2*X;
now, if we perturb slightly the equation and suppose Y = X + 10*eps, your if statement would be true (since Y > X) and your Z would be X + Y ^2; since X ~=Y we can approximate to X + X^2
therefore your equation is very temperamental to numerical approximation ( and you definitely have a discontinuity in Z). Again, I am not familiar with the algorithm and it may very well be the behaviour you want, but it is unlikely: so I am pointing this out.
Following is my version of your code, I report it also because I hope it will be pedagogical in getting you acquainted with logical indexing and vectorized code (which is the idiomatic form for MATLAB, let alone much faster than nested for loops).
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

Related

Loop invariant proof on multiply algorithm

I'm currently stuck on a loop invariant proof in my home assignment. The algorithm that I need to prove correctness of, is:
Multiply(a,b)
x=a
y=0
WHILE x>=b DO
x=x-b
y=y+1
IF x=0 THEN
RETURN(y)
ELSE
RETURN(-1)
I've tried to look at several examples of loop invariants and I have some sense of idea of how its supposed to work out. However in this algorithm above, I have two exit conditions, and I'm a bit lost on how to approach this in a loop invariant proof. In particular its the termination part I'm struggling with, around the IF and ELSE statements.
So far what I've constructed is simply by looking at the termination of the algorithm in which case if x = 0 then it returns the value of y containing the value of n (number of iterations in the while loop), where as if x is not 0, and x < b then it returns -1. I just have a feeling I need to prove this some how.
I hope someone can help share some light on this for me, as the similar cases I've found in here, have not been sufficient.
Thanks alot in advance for your time.
Provided that the algorithm terminates (for this let's assume a>0 and b>0, which is sufficient), one invariant is that at every iteration of your while loop, you have x + by = a.
Proof:
at first, x = a and y = 0 so that's ok
If x + by = a, then (x - b) + (y + 1)b = a, which are the values of x and y for your next iteration
Illustration:
Multiply(a,b)
x=a
y=0
// x + by = a, is true
WHILE x>=b DO
// x + by = a, is true
x=x-b // X = x - b
y=y+1 // Y = y + 1
// x + by = a
// x - b + by + b = a
// (x-b) + (y+1)b = a
// X + bY = a, is still true
// x + by = a, will remain true when you exit the loop
// since we exited the loop, x < b
IF x=0 THEN
// 0 + by = a, and 0 < b
// y = a/b
RETURN(y)
ELSE
RETURN(-1)
This algorithm returns a/b when b divides a, and -1 otherwise. Multiply does not quite sound like an appropriate name for it...
We can't prove correctness without a specification of exactly what the function is supposed to do, which I can't find in your question. Even the name of the function doesn't help: as noted already, your function returns a/b most of the time when b divides a, and -1 otherwise. Multiply is an inappropriate name for it.
Furthermore, if b=0 and a>=b the "algorithm" doesn't terminate so it isn't even an algorithm.
As Alex M noted, a loop invariant for the loop is x + by = a. At the moment the loop exits, we also have x < b. There are no other guarantees on x because (presumably) a could be negative. If we had a guarantee that a and b are positive, then we could guarantee that 0<=x<b at the moment the loop exits, which would mean that it implements the division with remainder algorithm (at the end of the loop, y is quotient and x is remainder, and it terminates by an "infinite descent" type argument: a decreasing sequence of positive integers x must terminate). Then you could conclude that if x=0, b divides a evenly, and the quotient is returned, otherwise -1 is returned.
But that is not a proof, because we are lacking a specification for what the algorithm is supposed to do, and a specification on restrictions on its inputs. (Are a and b any positive integers? Negative and 0 not allowed?)

Procedural/imperative programming - Algorithm

Can you please help me understand what ports in r if x = 0,1,2,3
y <-- 0
z <-- 1
r <-- z
while y < x {
Multiply z by 2;
Add z to r;
Increase y; }
In every looping step z is multiplied by 2, so you have the values 2,4,8,16... (or generally 2^n).
r is initially 1, and if you add z, you get 3,7,15,31 (generally 2^(n+1) - 1)
For x = 0 the loop will be skipped, so r stays 1
For x = 1 the loop will... uhm... loop one time, so you get 3
etc.
Apparently, the algorithm computes the sum of the powers of two from 0 to x and uses r as an accumulator for this. On termination, r holds the value 2^(x+1)-1.

Division Algorithm

I've just started with a Design Analysis and Algorithms course and we've begin with simple algorithms.
There is a division algorithm which I can't make any sense of.
function divide(x,)
Input: 2 integers x and y where y>=1
Output: quotient and remainder of x divided by y
if x=0: return (q,r)=(0,0)
(q,r)=divide(floor (x/2), y)
q=2q, r=2r
if x is odd: r=r+1
if r>=y: r=r-y, q=q+1
return(q,r)
* floor is lower bound
We were supposed to try this algo for 110011%101 ( binary values )...I tried something and I got a weird answer...converted into decimal values and it was wrong.
So I tried it using simple decimal values instead of binary first.
x=25, y=5
This is what I'm doing
1st: q=x,r= 12,5
2nd: q=x,r= 6,5
3rd: q=x,r= 3,5
4th: q=x,r= 1,5
5th: q=x,r= 0,5
How will this thing work? Everytime I will run it, the last value of last x will be 0(condition) it will stop and return q=0,r=0
Can someone guide me where I'm going wrong...
Thanks
I implemented your algorithm (with obvious correction in the arg list) in Ruby:
$ irb
irb(main):001:0> def div(x,y)
irb(main):002:1> return [0,0] if x == 0
irb(main):003:1> q,r = div(x >> 1, y)
irb(main):004:1> q *= 2
irb(main):005:1> r *= 2
irb(main):006:1> r += 1 if x & 1 == 1
irb(main):007:1> if r >= y
irb(main):008:2> r -= y
irb(main):009:2> q += 1
irb(main):010:2> end
irb(main):011:1> [q,r]
irb(main):012:1> end
=> nil
irb(main):013:0> div(25, 5)
=> [5, 0]
irb(main):014:0> div(25, 2)
=> [12, 1]
irb(main):015:0> div(144,12)
=> [12, 0]
irb(main):016:0> div(144,11)
=> [13, 1]
It's working, so you must not be tracking the recursion properly when you're trying to hand-trace it. I find it helpful to write the logic out on a new sheet of paper for each recursive call and place the old sheet of paper on top of a stack of prior calls. When I get to a return statement on the current sheet, wad it up, throw it away, and write the return value in place of the recursive call on the piece of paper on top of the stack. Carry through with the logic on this sheet until you get to another recursive call or a return. Keep repeating this until you run out of sheets on the stack - the return from the last piece of paper is the final answer.
The function has a recursive structure, which might be why it's a bit tricky. I'm assuming there's a typo in your function declaration where divide(x,) should be divide(x, y). Given that the desired result is x/y with the remainder, let's continue. The first line in the function definition claims that IF the numerator is 0, return 0 with a remainder of 0. This makes sense: while b != 0 and a = 0, a / b = 0 for all integers. Then we set the result to a recursive call with half the original numerator and the current denominator. At some point, "half the original numerator" turns into 0 and the base case is reached. There's a bit of computation at the end of each recursive call in what seems to be tail recursion. Because we divided by 2 on each deepning, multiply by 2 to get the original result and add 1 to the remainder if it's odd. It's hard to visualize in text alone so step through it on paper with a given problem.
Mathematically, the division algorithm (it's called that) states that the remainder must be less than or equal to 5 when you input 25,5.
The algorithm gives 0, 5. This might mean to NOT consider the remainder when the quotient is 0 or there needs to be a check on the size of the remainder.
function divide(x,) Input: 2 integers x and y where y>=1 Output: quotient and remainder of x divided by y
if x=0: return (q,r)=(0,0)
(q,r)=divide(floor (x/2), y)
q=2q, r=2r
if x is odd: r=r+1
if r>=y: r=r-y, q=q+1
return(q,r)
* floor is lower bound
If I remember correctly, this is one of the most basic ways of doing integral division in a simple ALU. It's nice because you can run all the recursive divisions in parallel, since each division is based on just looking at one less bit of the binary.
To understand what this does, simply walk through it on paper, as Chris Zhang suggested. Here's what divide(25,5) looks like:
(x,y)=(25,5)
divide(12, 5)
divide(6,5)
divide(3,5)
divide(1,5)
divide(0,5) // x = 0!
return(0,0)
(q,r)=(2*0,2*0)
x is odd, so (q,r)=(0,1)
r < y
return(0,1)
(q,r)=(2*0,2*1)
x is odd, so (q,r)=(0,3)
r < y
return(0,3)
(q,r)=(2*0,2*3)
x is even
r >= y, so (q,r)=(1,1)
return(1,1)
(q,r)=(2*1,2*1)
x is even
r < y
return(2,2)
(q,r)=(2*2,2*2)
x is odd, so (q,r)=(4,5)
r >= y, so (q,r)=(5,0)
return(5,0)
As you can see, it work - it gives you a q of 5 and an r of 0. The part you noticed, that you'll always eventually have a 0 term is what Chris properly calls "the base case" - the case that makes the recursive call unfold.
This algorithm works with any base number for the division and the multiplication. It uses the same principle as the following: "123 / 5 = (100 + 20 + 3) / 5 = 20 + 4 + r3 = 24r3", just done in binary.

factorial algorithm in pseudo code

I've been given the following algorithm, that takes a positive integer K and returns a value:
X = 1
Y = 1
while X ≠ K do
X = X + 1
Y = Y * x
return Y
I'm supposed to figure out what it returns.
As it happens, I know the answer — it returns the factorial of K — but I don't understand why.
How do you go about figuring out what this pseudocode does?
X = 1 <- this is counter which you gonna multiply in every step
Y = 1 <- this is to store the cumulative product after each step
while X ≠ K do <- until you reach K
X = X + 1 <- increase X
Y = Y * X <- multiply with increased X
return Y <- return the product
So in the loop the cumulative product goes like this 1 -> 1*2 - > 2*3 -> 6*4 -> ... -> 1*2*..*(K-1)*K which is K!
Now let's assume that K is 5. Therefore the factorial of 5 is 120.
Then as you enter the loop X value is 2 and y gets the value 2.(1*2)
Then the value of X is 3 after getting into loop, which then makes the value of Y 6 because (3*2).
Then the value of X is 4 after getting into loop, which then makes the value of Y 24 because (4*6).
Then the value of X is 5 after getting into loop, which then makes the value of Y 120.
Then since X==Y the while loop exits and Y value which is the factorial is returned.
this piece of code can be simply rewritten as (in C/C++/Java),
for(X=1;X<=K;X++){
Y=Y*X;
}
Now it describes it self :-)

How do you build a ratings implementation?

We have need for a "rating" system in a project we are working on, similar to the one in SO. However, in ours there are multiple entities that need to be "tagged" with a vote up (only up, never down, like an increment). Sometimes we will need to show all of the entities in order of what is rated highest, regardless of entity type, basically mixing the result sets, I guess. What data structures / algorithms do you use to implement this so that is flexible and still scalable?
Since reddit's ranking algorithm rocks, it makes very much sense to have a look at it, if not copy it:
Given the time the entry was posted A and the time of 7:46:43 a.m. December 8, 2005 B we have ts as their difference in seconds:
ts = A - B
and x as the difference between the number of up votes U and the number of down votes D:
x = U - D
Where
y = 1 if x > 0
y = 0 if x = 0
y = -1 if x < 0
and z as the maximal value of the absolute value of x and 1:
z = |x| if |x| >= 1
z = 1 if |x| < 1
we have the rating as a function ƒ(ts, y, z):
ƒ(ts, y, z) = log10 z + (y • ts)/45000

Resources