Transform two numbers until they equal each other - math

Given two different positive integers, a and b, can they ever equal each other given the following rules for transforming them (written in python-esque pseudocode):
if a < b:
a = 2a
b = b-a
elif a > b:
b = 2b
a = a-b
else:
return True
Example of a pair that will equal:
11,21
22,10
12,20
24,8
16,16
And an example of a pair that will never equal each other:
1,4
2,3
4,1
3,2
1,4
repeating...
So my question is, can you tell that two numbers will equal without running through a function
similar to the one above and looking for equality or an infinite loop? Is there any way to tell just by looking at the two numbers?
It kind of reminds me of the Collatz conjecture but with two numbers instead of one.
Having graphed all combinations of two numbers (a on the y-axis and b on the x-axis) we get a repeating pattern. The yellow indicating pairs that will equal each other. The lower triangle is missing because it's a mirror of the upper triangle. This was computed with a modification of the above function. But it would be great not to have to do this because it quickly becomes intractable.

Related

Constraining numbers to a range based on a MASK and a COMPARE register

Recently, I stumbled over the following problem in an embedded software project. I cannot yet figure out, under which conditions there is a unique solution and how it can be found.
Let us assume that we have a 16-bit MASK and a 16-bit COMPARE value and we want to set them, such that for a defined range of consecutive IDs {a, ..., b} (e.g. {0x78, 0x79, ..., 0x97}) those IDs satisfy bitwise
ID & MASK == COMPARE
while IDs outside that range do not satisfy the above equation.
As an example: If a=0x100 and b=0x1FF, the MASK is set as 0x700 and the COMPARE as 0x100.
I have the following questions:
What are the conditions for the minimal and maximal ID, so that uniquely defined MASK and COMPARE values exist?
How can they be calculated?
Looking forward to your answers!
The combination of MASK and COMPARE can be described as a string of 0 and 1 with wildcards (*) to indicate "don't care" positions. If there's a * left of a 0 or 1, the string does not describe a continuous range. Thus, the strings that represent ranges are exactly those where all the * are at the right end. The combinations of a and b that can be checked this way are then those where we can divide the 16 bits into a left part and a right part such that a and b are equal in the left part and the right part is all zero for a and all ones for b. We can test this as follows:
((((a ^ b) + 1) | a) & b) == a

Number based on Adjacent nodes

Let's assume I have a directed graph with 5 nodes and 6 edges:
1,2
2,3
4,3
2,4
4,1
5,4
Is there a way to generate a unique number to each of the edges(between 1 and |E|) combining the numbers of its adjacent nodes?
For example, for edge <4,3> if we can assign this edge with the absolute difference 2. But this way the numbering won't be unique.
Any suggestions?
EDIT: I found what is known as a pairing function which generates a unique number.But it doesn't ensure its between 1 and |E|
If |E| = 6 and the unique id must be between 1 and |E|, that means there can only be 6 unique ids.
It wouldn't be possible to have a unique id for every edge because there is way more than |E| combinations of edge verticie pairs in a directed graph. So you wouldnt be able to use integers.
One approach would be to take the fraction of the nodes. The fractions would range from 1/5 to 5. add 1 to your fraction and now you are between 6/5 and 6. Im not sure if the id need to be integers.
You could also have one number as a the ones place and the other as the tenths place. TLDR: if your using floats or doubles you have lots of options for unique ids otherwise you have none.

how do I generate 2 random prime numbers that when multiplied, yield a number with X bits? (X given as argument))

I lack the math skills to make this function.
basically, i want to return 2 random prime numbers that when multiplied, yield a number of bits X given as argument.
for example:
if I say my X is 3 then a possible solution would be:
p = 2 and q = 3 becouse 2 * 3 = 6 (110 has 3 bits).
A problem with this statement is that it starts by asking for two "random" prime numbers. Without any explicit statement of the distribution of the required random primes, we are already stuck. (This is the beginning of a classic paradox, where we are asked to generate a "random" integer.)
But suppose that we change the statement to finding any two arbitrary primes, that yield the desired product with a given number of bits x. The answer is trivial.
The set of numbers that have exactly x bits in their binary representation is the half open set of integers [2^(x-1),2^x-1].
Choose an arbitrary prime number that is less than or equal to (2^x-1)/2. Call it p1.
Next, choose a second prime number that lies in the interval (2^(x-1)/p1,(2^x-1)/p1). Call it p2.
It must be true that p1*p2 will be in the desired interval.
For example, given x = 10, so the product must lie in the interval [512,1023], the set of integers with exactly 10 bits. (Note, there are apparently 147 such numbers in that interval, with exactly two prime factors.)
Step 1:
Choose p1 as any prime no larger than 1023/2 = 511.5. I'll pick p1 = 137. Then the second prime factor must be a prime that lies in the interval
[512 1023]/137
ans =
3.7372 7.4672
thus either 5 or 7.
dec2bin(137*[5 7])
ans =
1010101101
1110111111
If you know the number of bits, you can generate a number 2^(x-2) < x < 2^(x-1). Then take the square root and find the closest primes on either side of it. Multiplying them together will, in most cases, get you a number in the correct range. If it's too high, you can take the two primes directly on the lower side of it.
pseudocode:
x = bits
primelist[] = makeprimelist()
rand = randnum between 2^(x-2) and 2^(x-1)
n = findposition(primelist, rand)
do
result = primelist[n]*primelist[n+1]
n--
while result > 2^(x-1)
Note that numbers generated this way will allways have '1' as the highest significant bit, so would be possible to generate a number of x-1 bits and just tack the 1 onto the end.

Determine how different are some vectors

I want to differentiate data vectors to find those that are similar. For example:
A=[4,5,6,7,8];
B=[4,5,6,6,8];
C=[4,5,6,7,7];
D=[1,2,3,9,9];
E=[1,2,3,9,8];
In the previous example I want to distinguish that A,B,C vectors are similar (not the same) to each other and D,E are similiar to each other. The result should be something like: A,B,C are similar and D,E are similar, but the group A,B,C is not similar to the group of D,E. Matlab can do this?
I was thinking using some classification algorithm or Kmeans,ROC,etc.. but I'm not sure which one will be the best one.
Any suggestion? Thanks in advance
One of my new favourite methods for this sort of thing is agglomerate clustering.
First, concatenate all your vectors into a matrix, where each row is a separate vector. This makes such methods much easier to use:
F = [A; B; C; D; E];
Then the linkages can be found:
Z = linkage(F, 'ward', 'euclidean');
This can be plotted using:
dendrogram(Z);
This shows a tree, where each leaf at the bottom is one of the original vectors. Lengths of the branches show similarities and dissimilarities.
As you can see, 1, 2 and 3 are shown to be very close, as are 4 and 5. This even gives a measure of closeness, and shows that vectors 1 and 3 are deemed to be closer than vectors 2 and 3 (in the sense that, percentagewise, 7 is closer to 8 than 6 is to 7).
If all the vectors you are comparing are of the same length, a suitable norm on pairwise differences may well be enough. The norm to choose will depend on your particular criteria of closeness, of course, but with the examples you show, simply summing the absolute values of the components of the pairwise differences gives:
A B C D E
A 0 1 1 12 11
B 0 2 13 12
C 0 13 12
D 0 1
E 0
which doesn't need a particularly well-tuned threshold to work.
You can use pdist(), this function gives you the pairwise distances.
Various distance (opposite of similarity) metrics are already implemented, 'euclidean' seems appropriate for your situation, although you may want to try out the effect of different metrics.
Here it goes the solution I propose based on your results:
Z = [A;B;C;D;E];
Y = pdist(Z);
matrix = SQUAREFORM(Y);
matrix_round = round(matrix);
Now that we have the vector we can set the threshold based on the maximun value and decide with which theshold is the most appropriate.
It would be nice to create some cluster plot showing the differences between them.
Best regards

Horizontal and Vertical Parity check codes

I was reading about horizontal and vertical parity check codes. One of the properties of these codes is that the final parity check (the lower right bit) is equal to modulo 2 sum of horizontal parity checks and also equal to modulo 2 of sum of vertical parity checks.
I did not understand, why this is true. I can see them in the examples but i really cant come up with any formal/intuitive proof about the same.
Any help/hints will be appreciated.
Thanks,
Chander
Each row and column is sum modulo 2. And result is sum of all numbers mod 2. It does not matter how you count.
Rule is:
((a mod c) + (b mod c)) mod c == (a+b) mod c
This is because every wrong bit propagates the parity either horizontally either vertically..
think about having your matrix of bits:
A B C D
E F G H
I J K L
M N O P
now some of these bits are wrongly transmitted, so you have a total of y errors that are layed around but you don't know where inside the matrix.
If you go by rows (so you calculate horizontal parity) you will be sure that the sum of every row parity modulo 2 will be 0 if you have an even number of errors in that row, 1 otherwise. You will be also sure of the fact that you are considering all of them since you do this work for every row.
Finally if you suppose to correct a bit from a row and alter another one in another one the final result won't change, since you basically remove 1 from a rows to add it elsewhere.
Then think about doing it by columns, you will end up with the same exact behaviour, the only difference is that errors can be distribuited in a different way but adding vertical parity together modulo 2 will take into account same considerations. Since the number of total errors is the same it will be an even number or an odd number either for rows and columns.

Resources