So I've got an interesting issue. I've got a code snippet below of a function that accepts two integers and returns two integers (x y coordinates). I generate 5 objects for it in a loop. On a Mac it returns two random numbers that are different from the others. On a PC it always returns the two exact numbers, even though I'm seeding it every time. Any ideas?
local randomSeed = 60
randomCoord = function(bufferX,bufferY)
-- randomCoord
-- int, int - get a buffer from the edge
-- returns two random coordinates that are within background Plane space
print( randomSeed )
math.randomseed(randomSeed + os.time())
randomSeed = randomSeed + os.time()
local x = math.random(backgroundBounds.xMin + bufferX,backgroundBounds.xMax - bufferX)
local y = math.random(backgroundBounds.yMin + bufferY,backgroundBounds.yMax - bufferY)
print('random x '..x..' random y '..y)
return x, y
end
backgroundBounds is just a table with integers (being the size of the backgroundBox).
Most of the time, in most languages out there, the random number facilities expect to be seeded only once. Seeding them again can produce unexpected results like returning the same sequence of numbers.
Related
Have a twodimensional grid and need a reproducible, random value for every integer coordinate on this grid. This value should be as unique as possible. In a grid of, let's say 1000 x 1000 it shouldn't occur twice.
To put it more mathematical: I'd need a function f(x, y) which gives an unique number no matter what x and y are as long as they are each in the range [0, 1000]
f(x, y) has to be reproducible and not have side-effects.
Probably there is some trivial solution but everything that comes to my mind, like multiplying x and y, adding some salt, etc. does not lead anywhere because the resulting number can easily occur multiple times.
One working solution I got is to use a randomizer and simply compute ALL values in the grid, but that is too computationally heavy (to do every time a value is needed) or requires too much memory in my case (I want to avoid pre-computing all the values).
Any suggestions?
Huge thanks in advance.
I would use the zero-padded concatenation of your x and y as a seed for a built-in random generator. I'm actually using something like this in some of my current experiments.
I.e. x = 13, y = 42 would become int('0013' + '0042') = 130042 to use as random seed. Then you can use the random generator of your choice to get the kind (float, int, etc) and range of values you need:
Example in Python 3.6+:
import numpy as np
from itertools import product
X = np.zeros((1000, 1000))
for x, y in product(range(1000), range(1000)):
np.random.seed(int(f'{x:04}{y:04}'))
X[x, y] = np.random.random()
Each value in the grid is randomly generated, but independently reproducible.
I'm just getting started with Julia, and I'm trying to read an unformatted FORTRAN file and store the data in arrays that are shaped in a particular way. I'm not sure how to accomplish this using Julia.
I've found the Julia package FortranFiles, which provides a direct way to read unformatted FORTRAN files using Julia. The file I'm trying to read looks like:
1 integer:
[nzones]
nzones*3 integers (brackets indicate one record):
[idim1,jdim1,kdim1,idim2,jdim2,kdim2,...,
idim_nzones,jdim_nzones,kdim_nzones]
series of nzones datasets:
[xvalues1,yvalues1,zvalues1](floating point values) for 1st zone
[xvalues1,yvalues1,zvalues1](floating point values) for 2nd zone
...,
[xvalues1,yvalues1,zvalues1](floating point values) for last zone
where the first line represents the number of zones and the lines that follow represent a grid dimension in each i, j, and k directions. Following these first two records are the x, y, and z coordinates, which are Float64s, for each i, j, and k point in a zone, and I would like to shape the arrays as x(1:im,1:jm,1:km,m), y(1:im,1:jm,1:km,m), and z(1:im,1:jm,1:km,m) where im, jm, and km are the imax,jmax, and kmax extents listed for each zone. Here's what I have so far:
using FortranFiles
fname = "my_file"
fid = FortranFile(fname)
#fread fid nblks::Int32
#fread fid ni::(Int32,nblks) nj::(Int32,nblks) nk::(Int32,nblks)
Here's where I'm getting hung up. For each zone I have x, y, and z coordinate arrays which should all be rank 4 arrays. For the x array, I want to store all of the x coordinates where x[1,1,1,1] refers to an x coordinate value at i=1, j=1, k=1, and zone =1 and x[end, end, end, end] refers to an x coordinate value at i = imax, j=jmax, k=kmax, and for the last zone listed (i.,e. zone = nblks). Then I want to create similar arrays for the y and z coordinate values.
Something like:
for m = 1:nblks
im = ni[m]
jm = nj[m]
km = nk[m]
#fread fid x::(Float64,im,jm,km,m) y::(Float64,im,jm,km,m) z::(Float64,im,jm,km,m)
end
However, I get a FortranFilesError: attempting to read beyond record end when trying this approach.
It appears that my issue is somewhat related to how Julia reads unformatted binary data, which is different from how FORTRAN's read works on the same data.
In FORTRAN, I could do something like:
integer, dimension (:), allocatable :: idim, jdim, kdim
integer :: nblks, fid, ios
fid = 10
open(unit=fid,form='unformatted', file='my_file',status='old',iostat=ios)
if( ios /= 0 ) then
write(*,*) '*** Error reading file ***'
stop
end if
read(fid) nblks
allocate( idim(nblks), jdim(nblks), kdim(nblks) )
read(fid) ( idim(m), jdim(m), kdim(m), m = 1, nblks )
close(fid)
...
However in Julia, I need to keep track of the file pointer's position, and realize that each record is preceded and followed by a 4-byte integer. I haven't been able to find a way to read each zone's i, j, & k extents directly into three separate arrays like can be done in FORTRAN (since the record is probably parsed line by line), but an alternative in Julia is to just read the entire record into a single nblk*3 element vector, and then reshape this vector afterwards:
fid = open("my_file")
skip(fid,4)
nblks = read(fid,Int32)
skip(fid,8)
dims = Array{Int32}(undef,3*nblks)
read!(fid,dims)
ni, nj, nk = [Array{Int32}(undef,nblks) for i in 1:3]
for m in 1:nblks
ni[m] = dims[3*m-2]
nj[m] = dims[3*m-1]
nk[m] = dims[3*m]
end
I have a problem and try to solve it for hours. Here is a pseudocode:
x = 30
if x > 100 then max(function_1(x), function_2(x))
elseif x > 50 then max(function_3(x), function_4(x))
elseif x > 20 then max(function_5(x), function_6(x))
elseif x < 10 then function_7(x)
else function_8(x)
This was a code I run with different values of x. Then functions are mathematical formulas. Now, I have the result of the above for each x and I want to revert and go back to x again.
I found all the reversed mathematical formulas of functions. For example for function_1(x), I have a rev_function_1(y) that will get the result and will give me the initial x.
But, since the original code has a lot of cases, plus the MAX, I am not sure how I can run one code, for every value and return the original one.
Edit: All the functions are one-to-one
Edit2: It seems that the whole function is not one-to-one while each of them individually are. As a result, I have two x for every y and I cannot revert it.
You need to study the result space (or domain) of you functions.
There exists an inverse only if each x results in a unique f(x) that cannot be obtained for any other value of x. This property is called one-to-one
Let me give you an example:
Let's say that f(1) == 8 and that also f(10) == 8.
Then you don't know if the inverse of 8 is 1 or 10.
If the function is one-to-one the inverse will be a unique value. If it is not one-to-one the inverse may be more than one value.
The next step is to figure out which inverse to call.
One way to do it is to call the inverse of all subfunctions.
For each x value you get, calculate f(x). If f(x) gets back the value you wanted to inverse, then keep that x, otherwise throw it away.
When you have gone through all values you will have one (or more) matching x value.
Edit:
Another way is to pre-compute which function that corresponds to a certain interval of output values. You can store these in a database as the tuples:
lowerbound, upperbound, inverse_function
You can then find which function to use (assuming SQL):
SELECT inverse_function FROM lookup_table
WHERE :fx > lowerbound and :fx < upperbound
:fx is the value you want to inverse.
You have an output y for each x. If two xs produce the same y then you can't undo the mapping since y could have come from either x. If no two xs produce the same y then you know it came from that y's x.
NOTE: Since a reverse algorithm is required and OP have not made mandatory to use the original functions or their corresponding reverse functions so following method can be used.
"Now, I have the result of the above for each x and I want to revert and go back to x again.". Its seems that its a case of [Key] => [Value].
//one-to-many case.
if x > 100 then max(function_1(x), function_2(x))
elseif x > 50 then max(function_3(x), function_4(x))
Above piece of code tells that multiple different inputs "x" can produce same output "y".
So you can use std::multimap if you are using C++.
Now multimap can be directly used at input output level, that is, if given a input "x" and it produces an output "y" after running all the formulas then multimap.insert(std::pair<int,int>(y,x));
Therefore, now given an output "y" you can find all the prospective input "x" which could produce an output "y" as follows:
std::pair <std::multimap<int,int>::iterator, std::multimap<int,int>::iterator> ret;
ret = multimap.equal_range(y);
for (std::multimap<int,int>::iterator it=ret.first; it!=ret.second; ++it)
std::cout << ' ' << it->second;
If the relation between input "x" and its corresponding "y" is one-to-one then, std::map can be used.
I think that this is not possible, let's take this example
function_1(x) = x - 200
function_2(x) = x - 201
function_7(x) = x - 5
then for x = 200 => y =0 and for x = 5 => y =0
So for a given value of y we can have multiple values of x
There is no solution in the general case. Think about this set of formulas:
function_1(x) { return x }
function_2(x) { return x }
function_3(x) { return x }
....
I guess it's obvious why it can't work.
I'm looking for a way of getting X points in a fixed sized grid of let's say M by N, where the points are not returned multiple times and all points have a similar chance of getting chosen and the amount of points returned is always X.
I had the idea of looping over all the grid points and giving each point a random chance of X/(N*M) yet I felt like that it would give more priority to the first points in the grid. Also this didn't meet the requirement of always returning X amount of points.
Also I could go with a way of using increments with a prime number to get kind of a shuffle without repeat functionality, but I'd rather have it behave more random than that.
Essentially, you need to keep track of the points you already chose, and make use of a random number generator to get a pseudo-uniformly distributed answer. Each "choice" should be independent of the previous one.
With your first idea, you're right, the first ones would have more chance of getting picked. Consider a one-dimensional array with two elements. With the strategy you mention, the chance of getting the first one is:
P[x=0] = 1/2 = 0.5
The chance of getting the second one is the chance of NOT getting the first one 0.5, times 1/2:
P[x=1] = 1/2 * 1/2 = 0.25
You don't mention which programming language you're using, so I'll assume you have at your disposal random number generator rand() which results in a random float in the range [0, 1), a Hashmap (or similar) data structure, and a Point data structure. I'll further assume that a point in the grid can be any floating point x,y, where 0 <= x < M and 0 <= y < N. (If this is a NxM array, then the same applies, but in integers, and up to (M-1,N-1)).
Hashmap points = new Hashmap();
Point p;
while (items.size() < X) {
p = new Point(rand()*M, rand()*N);
if (!points.containsKey(p)) {
items.add(p, 1);
}
}
Note: Two Point objects of equal x and y should be themselves considered equal and generate equal hash codes, etc.
I'm trying to generate some random numbers with simple non-uniform probability to mimic lifelike data for testing purposes. I'm looking for a function that accepts mu and sigma as parameters and returns x where the probably of x being within certain ranges follows a standard bell curve, or thereabouts. It needn't be super precise or even efficient. The resulting dataset needn't match the exact mu and sigma that I set. I'm just looking for a relatively simple non-uniform random number generator. Limiting the set of possible return values to ints would be fine. I've seen many suggestions out there, but none that seem to fit this simple case.
Box-Muller transform in a nutshell:
First, get two independent, uniform random numbers from the interval (0, 1], call them U and V.
Then you can get two independent, unit-normal distributed random numbers from the formulae
X = sqrt(-2 * log(U)) * cos(2 * pi * V);
Y = sqrt(-2 * log(U)) * sin(2 * pi * V);
This gives you iid random numbers for mu = 0, sigma = 1; to set sigma = s, multiply your random numbers by s; to set mu = m, add m to your random numbers.
My first thought is why can't you use an existing library? I'm sure that most languages already have a library for generating Normal random numbers.
If for some reason you can't use an existing library, then the method outlined by #ellisbben is fairly simple to program. An even simpler (approximate) algorithm is just to sum 12 uniform numbers:
X = -6 ## We set X to be -mean value of 12 uniforms
for i in 1 to 12:
X += U
The value of X is approximately normal. The following figure shows 10^5 draws from this algorithm compared to the Normal distribution.