I'm trying to generate a set of numbers that would follow a 1/R density distribution function, where R is the distance from the origin in polar coordinates. Basically the number of points/concentration of points should fall of as 1/R away from the center. Since I'm still fairly new to Fortran 90, I've managed to make an array of random numbers but taking it to the next step to make it follow 1/R seems tough..The way I create the array of random numbers is below:
PROGRAM randomnumbers
REAL::mynum
REAL,DIMENSION(1,10)::matrix
call random_number(matrix)
write(*,*)matrix
END PROGRAM randomnumbers
The way I did this in Python is using the inverse CDF and then interpolating but i'm not sure how to go about doing that on Fortran 90. The way it was done in Python is as follows : Points that follow a 1/R density distribution in an XY grid?
Related
I need to obtain the 3D plot of the joint probability distribution of two random variables x and y. Whereas this plot can be easily obtained with Mathematica, I wasn't able to find any documentation in Python.
Can you help me out with that?
I am trying to merge point clouds from two frames into one bigger point cloud. I will use ICP for that but I understand I need to per-align the point clouds. I am trying to do it with PCL template_alignment code from:
https://pcl.readthedocs.io/projects/tutorials/en/latest/template_alignment.html#template-alignment
The program computes surface normals after loading pointcloud. It works fine for the sample data used in the code but for my own data the "norm_est.compute(*normals_)" statement on line 89 returns NaN values. I read on PCL library documention that if the function can't find the neighbouring points it will return NaN values. That is my question, why the program is unable to find neighbourung points and what do I do about it? I am using the same settings as in the code in the above link for radius search and other perimeters for normal estimation.My left Image and point cloud are given below. I have uploaded a coloured pointcloud for better visualization but for alignment purposes I am using point cloud without RGB and my pointcloud.ply file contains only xyz coordinates.
Simple fix: modify that line (89) as such
Old:
norm_est.setRadiusSearch (normal_radius_);
new:
norm_est.setKSearch(5);
What this does is instead of looking inside a particular size sphere (unknown number of entries) it looks for a specific number of nearest neighbors.
Note that 5 is a pretty arbitrary number. You could go faster by lowering to 3 (minimum required) or slower but more accurate by increasing that number. It is probably best to not actually drop a hardcoded value right there and as such I suggest you pipe it out similar to how normal_radius_ was before, but this should get you past this issue for now.
Other options:
1: remove nan from point cloud after calculating normals (pcl::removeNaNFromPointCloud)
2: Run a reprocess step where you do a statistical outlier removal filter. Or an outright minimum neighbor radius filter. This will remove points with too few neighbors (which are what is generating nan values in your normal calculation)
3: increase radius of normal calculation or perform a nearest neighbor (not radius based) normal calculation.
As my question states, I want to calculate the Fourier transform F(q) of a radial function f(r) (defined on [0,infinity[ and which decays like an exponential exp(-Ar +b) at large r) as accurately as possible in Fortran. The function values come from a data file (which I can easily interpolate through cubic interpolation for example and extrapolate since the behaviour at large r is known).
I'm using the "physics" definition of the Fourier transform in 3D, which gives (because f is radial) :
I first tried to calculate this integral for some chosen values of q by using Gauss-Legendre quadrature, by generating some 60 or 100 abscissas and weights via the NAG routine D01BCF (D01BCF link). In the case of Gauss Legendre quadrature, the problem is to choose the interval [0,B] on which to integrate. While the function f loses 4 to 5 orders of magnitude from r=10 to r=20 (example), the choice of B as a strong influence on the result of the calculation... When I compared the result I get to a "nearly exact" calculation (made with matlab but with a veeeery long computation time), I saw that in fact this was only valid for small values of q (of the order of 5, when I have to deal with values as large as 150). A Gauss-Laguerre quadrature does not give any better result, probably because of the oscillatory part of the integrand.
I then tried to compute this Fourier transform for some given values of q with the routine D01ASF (D01ASF link). It is a "one-dimensional quadrature, adaptive, semi-infinite interval, weight function cos(ωx) or sin(ωx) ", which is exactly what I need. The results are quite convincing for q up to 80 or 100 if I input absolute error tolerances of 10E-5. Problems are : I would need to go at larger q, and the Fourier transform F(q) oscillates with a magnitude of ~ 10E-6 at such q's. Lowering the tolerance to 10E-5 already takes some time and even makes the whole thing to output some error message from the subroutine so I don't know if 10E-6 would be feasible.
I'm thus currently wondering if trying to calculate this Fourier transform with FFT wouldn't be a good idea ? The problems I face are that I don't know how to calculate radial wave functions with FFT (and also that I don't even know how to use FFT properly either since the definition of the transform is not even the same (exponent sign and argument) and that I never used it before).
Would you have ideas ? :)
EDIT 2 : I tried by FFT (using the routine C06FAF from NAG library). It works quite well up to some large values of q. The problem I face is that there is always some constant normalising factor to account for. I don't get why. This normalising factor evolves with the number N of points used in the mesh. It has the for of a power law : Normalising Factor F = N^(-0.5) x exp(9.9) approximately (see figure where the black line is the "exact" Fourier Transform and the green, magenta, blue, red and yellow lines are the FFT calculated for different values of N)
EDIT3 : I found the factor to be A*N^(-0.5) where A is the length of the integration mesh
How to generate particles in 2D space using uniform random distribution such that there are triangular or diamond shaped holes within?
Acceptance/Rejection - define your cutout areas, generate points uniformly over the 2-d space, and if the result lands in a cutout reject it and try again. Probability of acceptance will be p(accept) = 1 - Area(cutouts) / Area(2-d_generating_space), and the expected number of attempts to generate will be the inverse of that. For example, if the holes make up 80% of your space then p(accept) = 0.2 for a given trial and on average it will take 5 attempts to get an acceptable point.
I would start off with the triangle case, since the diamond case is really the same as having two triangles.
Here is another explanation of pjs' algorithm:
Define your 2-d space in terms of x-min, x-max, y-min, y-max.
Define your a set of triangles you are cutting from in terms of triangle1[point1, point2, point3] ... triangle_n[point1, point2, point3].
Pick how many points you want to generate, call this numberOfPoints.
Iterate over the numberOfPoints.
Pick a random value within your x-range (from x-min to x-max)
Pick a random value within your y-range (from y-min to y-max).
This is your x,y position for your new random point.
Check to see if this fits within any of your cutting triangles (you will have another loop here) and can use this, or another containment test.
If it is within one of the cutting triangles, throw it away and do not increment your counter. Otherwise, you have successfully added a point.
There are ways to do this more efficiently, than checking every single point against every single cutting triangle. This is an OK first approach for not too many triangles.
I am trying to extract the curvature of a pulse along its profile (see the picture below). The pulse is calculated on a grid of length and height: 150 x 100 cells by using Finite Differences, implemented in C++.
I extracted all the points with the same value (contour/ level set) and marked them as the red continuous line in the picture below. The other colors are negligible.
Then I tried to find the curvature from this already noisy (due to grid discretization) contour line by the following means:
(moving average already applied)
1) Curvature via Tangents
The curvature of the line at point P is defined by:
So the curvature is the limes of angle delta over the arclength between P and N. Since my points have a certain distance between them, I could not approximate the limes enough, so that the curvature was not calculated correctly. I tested it with a circle, which naturally has a constant curvature. But I could not reproduce this (only 1 significant digit was correct).
2) Second derivative of the line parametrized by arclength
I calculated the first derivative of the line with respect to arclength, smoothed with a moving average and then took the derivative again (2nd derivative). But here I also got only 1 significant digit correct.
Unfortunately taking a derivative multiplies the already inherent noise to larger levels.
3) Approximating the line locally with a circle
Since the reciprocal of the circle radius is the curvature I used the following approach:
This worked best so far (2 correct significant digits), but I need to refine even further. So my new idea is the following:
Instead of using the values at the discrete points to determine the curvature, I want to approximate the pulse profile with a 3 dimensional spline surface. Then I extract the level set of a certain value from it to gain a smooth line of points, which I can find a nice curvature from.
So far I could not find a C++ library which can generate such a Bezier spline surface. Could you maybe point me to any?
Also do you think this approach is worth giving a shot, or will I lose too much accuracy in my curvature?
Do you know of any other approach?
With very kind regards,
Jan
edit: It seems I can not post pictures as a new user, so I removed all of them from my question, even though I find them important to explain my issue. Is there any way I can still show them?
edit2: ok, done :)
There is ALGLIB that supports various flavours of interpolation:
Polynomial interpolation
Rational interpolation
Spline interpolation
Least squares fitting (linear/nonlinear)
Bilinear and bicubic spline interpolation
Fast RBF interpolation/fitting
I don't know whether it meets all of your requirements. I personally have not worked with this library yet, but I believe cubic spline interpolation could be what you are looking for (two times differentiable).
In order to prevent an overfitting to your noisy input points you should apply some sort of smoothing mechanism, e.g. you could try if things like Moving Window Average/Gaussian/FIR filters are applicable. Also have a look at (Cubic) Smoothing Splines.