My Perlin noise function (which adds up 6 octaves of 3D simplex at 0.75 persistence) generates a 2D array array of doubles.
These numbers each come out normalized to [-1, 1], with mean at 0. I clamp them to avoid exceptions, which I think are due to floating-point accuracy issues, but I am fairly sure my scaling factor is good enough for restricting the noise output to exactly this neighborhood in the ideal case.
Anyway, that's all details. The point is, here is a 256-by-256 array of noise:
The histogram with a normal fit looks like this:
Matlab's lillietest is a function which applies the Lilliefors test to determine if a set of numbers comes from a normal distribution. My result was, repeatedly, 1, which means that these numbers are not normally distributed.
I would like a function f(x) such that, when applied to the list of values from my noise function, the results appear uniformly distributed.
I would like this function to be implementable in C# and not take minutes to run.
Once again, it shouldn't matter where the numbers come from (the question is about transforming one distribution into another, specifically a normal-like one to uniform). Nevertheless, my noise function implementation is based on this and this. You can find the above array of values here.
Oddly enough I just wrote an article on your very question:
http://ericlippert.com/2012/02/21/generating-random-non-uniform-data/
There I discuss how to turn a uniform distribution into some other distribution, but of course you can use similar techniques to transform other distributions.
You will probably be interested in one of the following (related) techniques:
Probability integral transform
Histogram equalization
Related
What I'm trying to do: I want to compress a 2D grey-scale map (2D array of float values between 0 and 1) into a DFT. I then want to be able to sample the value of points in continuous coordinates (i.e. arbitrary points in between the data points in the original 2D map).
What I've tried: So far I've looked at Exocortex and some similar libraries, but they seem to be missing functions for sampling a single point or performing lossy compression. Though the math is a bit above my level, I might be able to derive methods do do these things. Ideally someone can point me to a C# library that already has this functionality. I'm also concerned that libraries that use the row-column FFT algorithm don't produce sinusoid functions that can be easily sampled this way since they unwind the 2D array into a 1D array.
More detail on what I'm trying to do: The intended application for all this is an experiment in efficiently pre-computing, storing, and querying line of sight information. This is similar to the the way spherical harmonic light probes are used to approximate lighting on dynamic objects. A grid of visibility probes store compressed visibility data using a small number of float values each. From this grid, an observer position can calculate an interpolated probe, then use that probe to sample the estimated visibility of nearby positions. The results don't have to be perfectly accurate, this is intended as first pass that can cheaply identify objects that are almost certainly visible or obscured, and then maybe perform more expensive ray-casting on the few on-the-fence objects.
In Accord.net framework, two classes are used to construct a Gabor filter:
Accord.Math.Gabor
Accord.Imaging.Filters.GaborFilter
There are various implementations of Gabor filter elsewhere:
How to convolve an image with different Gabor filters adjusted according to the local orientation and density using FFT?
Gabor Filter – Image processing for scientists and engineers, Part 6
https://github.com/clumsy/gabor-filter/blob/master/src/main/java/GaborFilter.java
https://github.com/dominiklessel/opencv-gabor-filter/blob/master/gaborFilter.cpp
https://github.com/adriaant/Gabor-API
but, the source codes in Accord.net look very strange to me. They discuss 3 types of kernels:
Real
Imaginary
Magnitude
SquaredMagnitude
Can anyone either explain the latter 3 (Real is self-explanatory) types or refer me to some materials where I can study them?
The Gabor kernel g(t) is complex-valued. It is a quadrature filter, meaning that, in the frequency domain (G(f)), it has no negative frequencies. Thus, the even and odd parts of this frequency response are related by even(G(f)) = odd(G(f)) * sign(f). That is, the even and odd parts have the same values for positive frequencies, but inverse values for negative frequencies. Adding up the even and odd part leads thus to the negative frequencies canceling out, and the positive frequencies reinforcing each other.
The even part of the (real-valued) frequency response corresponds to an even and real-valued kernel. The odd part corresponds to an odd and imaginary-valued kernel. The even kernel is a windowed cosine, the odd kernel is a windowed sine.
The Gabor filer is applied by convolving the image with these two components, then taking the magnitude of the result.
The magnitude of the filter itself is just a Gaussian smoothing kernel (it's the window over the sine and cosine). Note that cos^2+sin^2=1, so the magnitude doesn't show the wave component of the kernel. The code you linked that computes the magnitude of the Gabor kernel does a whole lot of pointless computations... :)
I have read some tutorials on perlin noise (for example this one) for my terrain generation, and I wanted to make sure that I understood it and can correctly implement it.
I start with 1 Dimension:
amplitude = persistence^i
// persistence can have any value but mostly it is 1 or lower. It changes the amplitude of the graphs with higher frequency since:
frequency = 2^i
//the 2 effects, that each graph reflects one octave, wich is not 100% necessary but the example happens do do it like this
'i' is the octave we are looking at.
Here is my attempt:
private float[] generateGraph()
{
float[] graph = new float[output.Width];
for (int i = 0; i < output.Width; i += 1/frequency)
{
graph[i] = random.Next((int)(1000000000000*persistence))/1000000000000f;
}
return graph;
}
I imagined the array as a graph, where the index is X and the value is Y. I search for a value for every multiple of texture.Width/frequency until the end of the array.
I have some random values I am using for now, which I have to connect with either Linear Interpolation/Cosine Interpolation or Cubic Interpolation.
Which one should I use? Which is the most performant when I want to use the noise for terrain generation in 2D?
I would like to put the graphs in a 2D-array after this and then check for each value, if its higher than 0.5, it should get some material or texture.
Is this situation, how should I do it? Am I totally on the wrong track?
edit1: Before I put the graph in a 2D array, I would like to generate perhaps 5 other graphs with a higher 'i' and blend them (which shouldn't be too hard).
edit2: this implementation is nice and 'easy'.
Define "too much performance" any kind of interpolation should be fine for 2D data. If you are really worried about performance, you might try implementing Simplex Noise, but that is much harder to understand and implement and it really becomes better at 3D and higher. In 2D they are somehow comparable.
Also, perlin noise is usually implemented as function of x parameters, where x is number of dimensions and the function has internal array of random values, that is accessed based on integer values of the parameters. You should try studying the original source code.
I'm wanting to do some placement of objects like trees and the like based on noise for the terrain of a game/tech demo.
I've used value noise previously and I believe I understand perlin noise well enough. Simplex noise, however, escapes me quite well (just a tad over my head at present).
I have an implementation in C# of simplex noise, however, it's almost completely stolen from here. It works beautifully, but I just don't understand it well enough to modify it for my own purposes.
It is quite fast, but it also gives rather smooth results. I'm actually wanting something that is a little more jagged, like simple linear interpolation would give when I was doing value noise. My issue here is that due to the amount of calls I'd be doing for these object placements and using fractal Brownian motion, the speed of the algorithm becomes quite important.
Any suggestions on how to get more 'jagged' results like linear interpolation gives with value noise using a faster algorithm than value noise is?
if you are using a complex noise function to do a simple task like the placement of trees, your using completely the wrong type of maths function. It is a very specific function which is great for making textures and 3d shapes and irregular curves. Placing treas on 2d certainly doesn't need irregular curves! Unless you want to place trees along in lines that are irregular and curved!
unless you mean you want to place trees in areas of the noise which are a certain level, for example where the noise is larger than 0.98, which will give you nicely randomised zones that you can use as a central point saying some trees will be there.
it will be a lot faster and a lot easier to vary, if you just use any normal noise function, just program your placement code around the noise function. I mean a predictable pseudo-random noise function which is the same every time you use it.
use integers 0 to 10 and 20 to 30, multiplied by your level number, to select 10 X and 10 Y points on the same pseudo-random noise curve. this will give you 10 random spots on your map from where to do stuff using almost no calculations.
Once you have the central point where trees will be, use another 10 random points from the function to say how many trees will be there, another 10 to say how far apart they will be, for the distribution around the tree seed quite exceptional.
The other option, if you want to change the curve http://webstaff.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf is to read this paper and look at the polynomial function /whatever gradient function could be used in your code, looking the comments for the gradient function, commented out and do X equals Y, which should give you a straight interpolation curve.
if you vote this answer up, I should have enough points in order to comment on this forum:]
I realise this is a very old question, but I felt that the previous answer was entirely wrong, so I wanted to clarify how you should use a noise function to determine the placement of things like trees / rocks / bushes.
Basically, if you want to globally place items across a terrain, you're going to need some function which tells you where those are likely to occur. For instance, you might say "trees need to be on slopes of 45 degrees or less, and below 2000 meters". This gives you a map of possible places for trees. But now you need to choose random, but clustered locations for them.
The best way of doing this is to multiply your map of zeroes and ones by a fractal function (i.e. a Simplex noise function or one generated through subdivision and displacement - see https://fractal-landscapes.co.uk/maths).
This then gives you a probability density function, where the value at a point represents the relative probability of placing a tree at that location. Now you store the partial sum of that function for every location on the map. To place a new tree:
Choose a random number between 0 and the maximum of the summed function.
Do a binary search to find the location on the map in this range.
Place the tree there.
Rinse and repeat.
This allows you to place objects where they belong, according to their natural ranges and so on.
I have as small c# project that involves matrices. I am processing large amounts of data by splitting it into n-length chunks, treating the chucks as vectors, and multiplying by a Vandermonde** matrix. The problem is, depending on the conditions, the size of the chucks and corresponding Vandermonde** matrix can vary. I have a general solution which is easy to read, but way too slow:
public byte[] addBlockRedundancy(byte[] data) {
if (data.Length!=numGood) D.error("Expecting data to be just "+numGood+" bytes long");
aMatrix d=aMatrix.newColumnMatrix(this.mod, data);
var r=vandermonde.multiplyBy(d);
return r.ToByteArray();
}//method
This can process about 1/4 megabytes per second on my i5 U470 # 1.33GHz. I can make this faster by manually inlining the matrix multiplication:
int o=0;
int d=0;
for (d=0; d<data.Length-numGood; d+=numGood) {
for (int r=0; r<numGood+numRedundant; r++) {
Byte value=0;
for (int c=0; c<numGood; c++) {
value=mod.Add(value, mod.Multiply(vandermonde.get(r, c), data[d+c]));
}//for
output[r][o]=value;
}//for
o++;
}//for
This can process about 1 meg a second.
(Please note the "mod" is performing operations over GF(2^8) modulo my favorite irreducible polynomial.)
I know this can get a lot faster: After all, the Vandermonde** matrix is mostly zeros. I should be able to make a routine, or find a routine, that can take my matrix and return a optimized method which will effectively multiply vectors by the given matrix, but faster. Then, when I give this routine a 5x5 Vandermonde matrix (the identity matrix), there is simply no arithmetic to perform, and the original data is just copied.
** Please note: What I use the term "Vandermonde", I actually mean an Identity matrix with some number of rows from the Vandermonde matrix appended (see comments). This matrix is wonderful because of all the zeros, and because if you remove enough rows (of your choosing) to make it square, it is an invertible matrix. And, of course, I would like to use this same routine to convert any one of those inverted matrices into an optimized series of instructions.
How can I make this matrix multiplication faster?
Thanks!
(edited to correct my mistake with Vandermonde matrix)
Maybe you can define a matrix interface and build implementations at runtime using Reflection.Emit.
IMatrix m = MatrixGenerator.CreateMatrix(data);
m.multiplyBy(...)
Here, MatrixGenerator.CreateMatrix will create a tailored IMatrix implementation, with full loop unrolling, and further code pruning (0 cell, identity, etc). MatrixGenerator.CreateMatrix may cache matrices to avoid recreating it later for the same set of data.
I've seen solutions using Reflection.Emit, and I've seen solutions which involve TPL. The real answer here is, for most situations, that you want to use an existing unmanaged library such as Intel MKL via P/Invoke. Alternatively, if you are using the GPU, you can go with the GPGPU approach which would go a lot faster.
And yes, SSE together with multi-core processing is the fastest way to do it on a CPU. But I wouldn't recommend writing your own algorithm - instead, go look for something that's already out there. Most likely, it will end up being a C++ library, possibly with a C# wrapper.
While it won't speed up the math, you could at least use all your cores with the Parallel.For in .Net 4.0. Microsoft link
From the math perspective
You could look at Eigen Spaces, Eigen Vectors, Eigen Values. I'm not sure what your application does and if it will help.
You could look at LU Decomposition.
All of the above topics can be found at wikipedia
From a programming perspective
You could try SIMD, but they are designed for 4x4 matrices to do homogeneous transformations of 3D space, mostly for computer graphics.
You could write special algorithms for your most common dimensions.
Using SSE in c# is it possible?