2D to 1D transformation without dimensions - math

Suppose I want to track the state of cells in a grid. Let's assume that the grid has dimensions m x n. I can simply create a vector of length m*n and track cell state using the vector. In this case, each point in the grid (which is 2D) would map to an element in the vector (1D).
One method I've used before is something like this:
defun 2d->1d (x, y, m, n):
return m*y + x;
defun 1d->2d (i, m, n):
return [i%m, i/m];
My problem is this:
Is there a way to have a 2D->1D mapping as above when grid dimensions are not known or when grid is infinite?

Yes, there are mappings from 2D to 1D for natural numbers, known as Pairing functions.
For example, the Cantor pairing function:
defun 2d->1d (x, y):
return (1 / 2) * (x + y) * (x + y + 1) + y;
For the reverse function see the link above, it is a little more complex.

Related

Using dot-product instead of multiplying with transpose

We have the following equation, that we want to implement into our code with arrays/matrices
h(x, y, z) = ax + by + cz
pseudeo code:
X = [a, b, c]
A = [x, y, z]
Often I see the equation being implemented like this:
h = transpose(A) * T
Is there any difference of just using the dot product?
h = dotproduct(A, X)
Is there a specific reason why the transpose is used over the dotproduct?
Mathematically, there's no difference. In implementation- dotproduct(...) may actually be faster, since transpose(...) may eagerly move the elements around prior to the matrix multiplication, doing "unnecessary" work.

F# recursive function that takes single point and index

How do you write a F# recursive function 'something' that takes a single point (x, y) and index i as
an arguments and returns an ๐‘–๐‘กโ„Ž element of the infinite list corresponding to S(x, y).
ex: let something (x,y) i =
F# function F(๐‘ฅ,๐‘ฆ) should be defined as:
F(x,y)(u, v) = (u2 โˆ’ v2 + x, 2uv + y)
F# function 'something' ๐‘‚(x, y) of a point (x, y) should be an infinite list of items:
S(x, y) = {(0, 0), F(x,y)(0, 0), F(๐‘ฅ,y)(F(x,y)(0, 0)), F(x,y)(F(x,y)(F(x,y)(0, 0))), โ€ฆ}
This looks like an assignment to me. I don't mind helping out but at the same time I don't want to give the full solution.
The exercise itself looks like generating the series:
Z' = Z*Z + C
For a complex number Z and C. This is commonly done when generating the mandelbrot or julia set.
The function F can be written almost like the definition in F#:
let f (x, y) (u, v) = (u*u - v*v + x, 2.*u*v + y)
The infinite set S is generated from a starting point (0,0) and applying the output of f on itself over and over again.
An infinite set in F# can be represented using seq and you can create them using seq comprehesions
Once you have an infinite seq with the right values you can pick the ith value by using Seq.item

Differentiating a scalar with respect to matrix

I have a scalar function which is obtained by iterative calculations. I wish to differentiate(find the directional derivative) of the values with respect to a matrix elementwise. How should I employ the finite difference approximation in this case. Does diff or gradient help in this case. Note that I only want numerical derivatives.
The typical code that I would work on is:
n=4;
for i=1:n
for x(i)=-2:0.04:4;
for y(i)=-2:0.04:4;
A(:,:,i)=[sin(x(i)), cos(y(i));2sin(x(i)),sin(x(i)+y(i)).^2];
B(:,:,i)=[sin(x(i)), cos(x(i));3sin(y(i)),cos(x(i))];
R(:,:,i)=horzcat(A(:,:,i),B(:,:,i));
L(i)=det(B(:,:,i)'*A(:,:,i)B)(:,:,i));
%how to find gradient of L with respect to x(i), y(i)
grad_L=tr((diff(L)/diff(R)')*(gradient(R))
endfor;
endfor;
endfor;
I know that the last part for grad_L would syntax error saying the dimensions don't match. How do I proceed to solve this. Note that gradient or directional derivative of a scalar functionf of a matrix variable X is given by nabla(f)=trace((partial f/patial(x_{ij})*X_dot where x_{ij} denotes elements of matrix and X_dot denotes gradient of the matrix X
Both your code and explanation are very confusing. You're using an iteration of n = 4, but you don't do anything with your inputs or outputs, and you overwrite everything. So I will ignore the n aspect for now since you don't seem to be making any use of it. Furthermore you have many syntactical mistakes which look more like maths or pseudocode, rather than any attempt to write valid Matlab / Octave.
But, essentially, you seem to be asking, "I have a function which for each (x,y) coordinate on a 2D grid, it calculates a scalar output L(x,y)", where the calculation leading to L involves multiplying two matrices and then getting their determinant. Here's how to produce such an array L:
X = -2 : 0.04 : 4;
Y = -2 : 0.04 : 4;
X_indices = 1 : length(X);
Y_indices = 1 : length(Y);
for Ind_x = X_indices
for Ind_y = Y_indices
x = X(Ind_x); y = Y(Ind_y);
A = [sin(x), cos(y); 2 * sin(x), sin(x+y)^2];
B = [sin(x), cos(x); 3 * sin(y), cos(x) ];
L(Ind_x, Ind_y) = det (B.' * A * B);
end
end
You then want to obtain the gradient of L, which, of course, is a vector output. Now, to obtain this, ignoring the maths you mentioned for a second, if you're basically trying to use the gradient function correctly, then you just use it directly onto L, and specify the grid X Y used for it to specify the spacings between the different elements in L, and collect its output as a two-element array, so that you capture both the x and y vector-components of the gradient:
[gLx, gLy] = gradient(L, X, Y);

Hash Value for 3D Vector

Is there a way to represent a 3D Vector as a definite number? I mean that two vectors with different values can't ever have the same hash value. I'm sure there already is a question about this but I haven't found it unfortunately. Thanks for your help.
EDIT:
I know this algorithm for 2D vectors which is pretty good (I think): (x + y) * (x + y + 1) / 2 + y
The best approach to get a hash for a vector of floats is to convert it to a string of bytes or characters and calculate a hash on it. An example of this is given using numpy and python in the following answer:
Most efficient property to hash for numpy array.
This will work efficiently for large numbers of vectors, but you cannot guarantee that you will not get collisions due to the simple fact of mapping three floats onto an integer. However there are a number of hashing algorithms available in the python hashlib library to choose from, you might need to experiment. An option in C++ is Boost::Hash.
See the pigeon-hole principle - in the same way you can't fit you can't 100 pigeons into 10 holes, you can't uniquely convert 3 values into 1 value (with all values of the same size). There will have to be duplicates.
Now, if you could have a number with 3x as many bits as the vector values, the problem becomes fairly easy:
// convert x, y and z to the range 0-...
x -= minimum possible value
y -= minimum possible value
z -= minimum possible value
mult = maximum possible value + 1
hash = x * mult * mult + y * mult + z
If you're having trouble understanding the above, just take the example of the range of the values being 0-99. We'd multiple x by 100*100 = 10000 and y by 100, so the hash would be a decimal value with (at most) 6 digits with x, y and z all next to each other, guaranteed to not overlap:
x = 12
y = 34
z = 56
hash = 123456
Now this same idea will hold for any maximum value by just changing the base / radix.
If there isn't any overlap in some base, each unique combination of values of x, y and z will result in a unique hash.
This is by far the simplest approach, although it doesn't produce a particularly good hash, so it depends what you want to use it for - there might be a way to uniquely convert this number to another number which will be a good hash.
Responding to this post a little late, and perhaps this isn't what you're looking for, but I figured I would chime in with another answer.
You could use the function you mentioned, (x + y) * (x + y + 1) / 2 + y , and do it recursively, ex. f( f(x,y) , z).
You can also use other pairing functions as well and use the same method (https://en.wikipedia.org/wiki/Pairing_function).
For my problem, I wanted a function that would order vectors based on their location. The order itself didn't matter, only that a close value means a similar vector. What I ended up doing was:
double get_pairing(double x, double y, double z) {
double normalizer = 0.0;
if(x < 0) {
normalizer += (3.0 * MAX_COORD_VAL);
}
if (y < 0) {
normalizer += (6.0 * MAX_COORD_VAL);
}
if (z < 0) {
normalizer += (9.0 * MAX_COORD_VAL);
}
double g = x + y + z - normalizer + (21 * MAX_COORD_VAL);
return g;
}
This orders vectors based on whether they have negative coordinate values and whether they have large coordinate values.
This works assuming you have a max coordinate value.

Efficient way to store 3D normal vector using two floats

I need to store 3D normal vectors, that is vectors (x, y, z) such that x^2 + y^2 + z^2 = 1. But due to space constraints I can only use 2 floats to store it.
So by storing only x and y, the third component can be computed as sqrt(1 - x^2 - y^2), i.e. one square root, two products and two subtractions.
What would be the most efficient way to store the vectors, so that reading them is as fast as possible, and if possible without bias towards one spatial direction?
Edit
Now using the values (a, b) with a = x - y and b = x + y.
You could satisfy your space constraint by storing the vectors via spherical coordinates. As is well known, each point on the unit sphere, i.e., each unit vector, has at least one pair of spherical coordinates characterizing it.
Or if you want something convoluted: The complex square function maps the unit disk to a double cover of it. So you could use the left half-disk for the upper half-sphere and the right half-disk for the lower half-sphere.
SphereFromDisk(a,b)
a2=a*a; b2=b*b; r2=a2+b2; // assert r2 <= 1
x = a2 - b2;
y = 2*a*b
z = sqrt(1-r2*r2)
if(a<0 or (a=0 and b<0) z=-z
return (x,y,z)

Resources