So like the title says I need help trying to map points from a 2d plane to a number line in such a way that each point is associated with a unique positive integer. Put another way, I need a function f:ZxZ->Z+ and I need f to be injective. Additionally I need to to run in a reasonable time.

So the way I've though about doing this is to basically just count points, starting at (1,1) and spiraling outwards.

Below I've written some python code to do this for some point (i,j)

def plot_to_int(i,j):

a=max(i,j) #we want to find which "square" we are in
b=(a-1)^2 #we can start the count from the last square
J=abs(j)
I=abs(i)
if i>0 and j>0: #the first quadrant 
    #we start counting anticlockwise
    if I>J: 
        b+=J
    #we start from the edge and count up along j
    else:
        b+=J+(J-i)
    #when we turn the corner, we add to the count, increasing as i decreases
elif i<0 and j>0: #the second quadrant
    b+=2a-1 #the total count from the first quadrant
    if J>I:
        b+=I
    else:
        b+=I+(I-J)
elif i<0 and j<0: #the third quadrant
    b+=(2a-1)2 #the count from the first two quadrants
    if I>J:
        b+=J
    else:
        b+=J+(J-I)
else:
    b+=(2a-1)3
    if J>I:
        b+=I
    else:
        b+=I+(I-J)

return b

I'm pretty sure this works, but as you can see it quite a bulky function. I'm trying to think of some way to simplify this "spiral counting" logic. Or possibly if there's another counting method that is simpler to code that would work too.

1

There are 1 best solutions below

0
On

Here's a half-baked idea:

  1. For every point, calculate f = x + (y-y_min)/(y_max-y_min)
  2. Find the smallest delta d between any given f_n and f_{n+1}. Multiply all the f values by 1/d so that all f values are at least 1 apart.
  3. Take the floor() of all the f values.

This is sort of like a projection onto the x-axis, but it tries to spread out the values so that it preserves uniqueness.

UPDATE:

If you don't know all the data and will need to feed in new data in the future, maybe there's a way to hardcode an arbitrarily large or small constant for y_max and y_min in step 1, and an arbitrary delta d for step 2 according the boundaries of the data values you expect. Or a way to calculate values for these according to the limits of the floating point arithmetic.