FFTW transform of a real and symmetric image is not real and symmetric? - fftw

I have an issue regarding the FFT implementation in FFTW. Or maybe the problem is my knowledge on FFT. The point is, as far as I know,
if I transform forward a symmetric and real signal, I should get a symmetric and real signal also. However, this is not what I am finding
in FFTW. I am working in 2d, with the fftwf_plan_dft_r2c_2d routine.
I leave here a simple piece of code that creates a matrix that stores in each pixel
(x,y) the result of computing 1/(sqrt(x^2+y^2)), which is a symmetric signal. There is also a loop that prints out these values, just to check
that I built the matrix properly.
#include <fftw3.h>
int main(int argc, char* argv[]){
width=5;height=5;
float *omega;
omega = (float *) malloc(sizeof(float)*width*height);
float *omegasym = (float *) malloc(sizeof(float)*2*width*2*height);
int y, x;
//Build a symmetric real signal
for(y = 0, i = 0; y < height; y++) /* omega = 1/sqrt(x^2 + y^2) */
for(x = 0; x < width; x++, i++)
omega[i] = (x == 0 && y == 0) ? 0 : 1.0f/(float) std::sqrt((float) x*x + y*y);
//Just check if we did well
for(int i=0; i<5; i++){
for(int j=0; j<5; j++){
std::cout<<" " << omega[j+5*i] << " ";
}
std::cout<<endl;
}
fftwf_complex *omega_trans_complexx;
omega_trans_complexx = (fftwf_complex *) fftwf_malloc(sizeof(fftwf_complex)*2*height*(2*width/2+1));
fftwf_plan plan;
plan=fftwf_plan_dft_r2c_2d(height, width, omega, omega_trans_complexx, FFTW_ESTIMATE);
//Should not this has imaginary part = 0??? :S
for(int i=0; i<25; i++){
std::cout<<"Real part of omega_trans is :" << omega_trans_complexx[i][0] << endl;
std::cout<<"Imaginary part of omega_trans is :" << omega_trans_complexx[i][1] << endl;
}
return 0;
}
After computing the forward transform with FFTW, i am getting a non-zero imaginary part. At first I thought it could be the fact that the signal is not
symmetric, but for a symmetrized version of it, it does not work, neither. I wonder if I am doing something wrong, or FFTW requires some kind of zero-padding,
or I am missing something else..

This question seems to be partly about fft's properties
x,y-> 1/(sqrt(x^2+y^2)) is neither even nor odd. It is normal that you get a non-zero imaginary part. You could expect a zero imaginary part if you try :
omega[i]=sin(2.0*M_PI/height*y)*sin(2.0*M_PI/width*x);
or :
omega[i]=cos(2.0*M_PI/height*y)*cos(2.0*M_PI/width*x);
And something purely imaginary if you try :
omega[i]=cos(2.0*M_PI/height*y)*sin(2.0*M_PI/width*x);
The effect of using real as input is that you don't have to compute the fft for negative frequencies since it is the conjugate of the corresponding positive frequency : \hat{f}(-k)=(\hat{f}(k))*
On the code itself :
You won't get anything useful if you don't call fftwf_execute(plan); somewhere !
sizeof(fftwf_complex)*2*height*(2*width/2+1) is too large. You can save some memory by using sizeof(fftwf_complex)*2*height*(width/2+1) instead.
you are right about padding. In fact, fftw stores an "extra" frequency in the x direction. That why you should allocate width/2+1 complex numbers in the x direction. As soon as you correct the printing operations, you will get symetric values between x and y
Here is the result :
#include <fftw3.h>
#include <iostream>
#include <cmath>
#include <stdlib.h>
int main(int argc, char* argv[]){
int width=5;int height=5;
float *omega;
omega = (float *) fftwf_malloc(sizeof(float)*width*height);
float *omegasym = (float *) malloc(sizeof(float)*2*width*2*height);
int y, x;
//Build a symmetric real signal
int i;
for(y = 0, i = 0; y < height; y++) /* omega = 1/sqrt(x^2 + y^2) */
for(x = 0; x < width; x++, i++)
//omega[i]=sin(2.0*M_PI/height*y)*cos(2.0*M_PI/width*x);
omega[i] = (x == 0 && y == 0) ? 0 : 1.0f/(float) std::sqrt((float) x*x + y*y);
//Just check if we did well
for(i=0; i<5; i++){
for(int j=0; j<5; j++){
std::cout<<" " << omega[j+5*i] << " ";
}
std::cout<<std::endl;
}
fftwf_complex *omega_trans_complexx;
omega_trans_complexx = (fftwf_complex *) fftwf_malloc(sizeof(fftwf_complex)*2*height*(width/2+1));
fftwf_plan plan;
plan=fftwf_plan_dft_r2c_2d(height, width, omega, omega_trans_complexx, FFTW_ESTIMATE);
fftwf_execute(plan);
//Should not this has imaginary part = 0??? :S : imaginary part is ok :)
for(y = 0, i = 0; y < height; y++) /* omega = 1/sqrt(x^2 + y^2) */
for(x = 0; x < width/2+1; x++, i++)
std::cout<<"freqx "<<x<<" freqy "<<y<<" real "<<omega_trans_complexx[i][0]<< " imag "<<omega_trans_complexx[i][1]<<std::endl;
return 0;
}
Bye,
Francis

Related

How can I place n circles randomly inside a rectangle without overlapping?

Suppose I have n circles of radius r. I want to place them randomly inside a rectangle of size AxA.
It is guaranteed that they fit. One can suppose that the sum of the area of all circles is about 60% of the area of the rectangle.
I can try it by doing a backtracking, trying to place, going back, etc., but there should be a better way to do it.
One possibility is to generate random points inside the rectangle without further constraints, and then move the points/centres iteratively (by little steps) such that avoiding overlapping. If two points are too near one from each other, each point can bring pressure to the other, to make it going away a little bit. The higher the pressure, the higher the move.
This process was implemented in C++. In the following simple code, to facilitate implementation, points and vectors are represented par std::complex type.
Note that I used srandand rand for test purpose. You may used better random algorithms, depending on your constraints.
According to the tests that I have performed, convergence seems guaranteed for a density of 60%. I also made some tests with a density of 70%: sometimes convergence, sometimes not.
Complexity is O(n^2 n_iter), where nis the number of circles and n_iterthe number of iterations.
n_iteris generally between 100 and 300, for a density of 60%. It could be decreased with relaxing the convergence criteria.
It could be seems high complexity, compared to other proposals in comments. In practice, for n = 15, the work is performed in less than 30ms on my PC. Huge time or fast enough, depending on the context. I have included a figure to illustrate the algorithm.
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <ctime>
#include <complex>
#include <cmath>
#include <tuple>
#include <ios>
#include <iomanip>
using dcomplex = std::complex<double>;
void print (const std::vector<dcomplex>& centers) {
std::cout << std::setprecision (9);
std::cout << "\ncenters:\n";
for (auto& z: centers) {
std::cout << real(z) << ", " << imag(z) << "\n";
}
}
std::tuple<bool, int, double> process (double A, double R, std::vector<dcomplex>& centers, int n_iter_max = 100) {
bool check = true;
int n = centers.size();
std::vector<dcomplex> moves (n, 0.0);
double acceleration = 1.0001; // to accelerate the convergence, if density not too large
// could be made dependent of the iteration index
double dmin;
auto limit = [&] (dcomplex& z) {
double zx = real(z);
double zi = imag(z);
if (zx < R) zx = R;
if (zx > A-R) zx = A-R;
if (zi < R) zi = R;
if (zi > A-R) zi = A-R;
return dcomplex(zx, zi);
};
int iter;
for (iter = 0; iter < n_iter_max; ++iter) {
for (int i = 0; i < n; ++i) moves[i] = 0.0;
dmin = A;
for (int i = 0; i < n; ++i) {
for (int j = i+1; j < n; ++j) {
auto vect = centers[i] - centers[j];
double dist = std::abs(vect);
if (dist < dmin) dmin = dist;
double x = std::max (0.0, 2*R*acceleration - dist) / 2.0;
double coef = x / (dist + R/10000);
moves[i] += coef * vect;
moves[j] -= coef * vect;
}
}
std::cout << "iteration " << iter << " dmin = " << dmin << "\n";
if (dmin/R >= 2.0 - 1.0e-6) break;
for (int i = 0; i < n; ++i) {
centers[i] += moves[i];
centers[i] = limit (centers[i]);
}
}
dmin = A;
for (int i = 0; i < n; ++i) {
for (int j = i+1; j < n; ++j) {
auto vect = centers[i] - centers[j];
double dist = std::abs(vect);
if (dist < dmin) dmin = dist;
}
}
std::cout << "Final: dmin/R = " << dmin/R << "\n";
check = dmin/R >= 2.0 - 1.0e-6;
return {check, iter, dmin};
}
int main() {
int n = 15; // number of circles
double R = 1.0; // ray of each circle
double density = 0.6; // area of all circles over total area A*A
double A; // side of the square
int n_iter = 1000;
A = sqrt (n*M_PI*R*R/density);
std::cout << "number of circles = " << n << "\n";
std::cout << "density = " << density << "\n";
std::cout << "A = " << A << std::endl;
std::vector<dcomplex> centers (n);
std::srand(std::time(0));
for (int i = 0; i < n; ++i) {
double x = R + (A - 2*R) * (double) std::rand()/RAND_MAX;
double y = R + (A - 2*R) * (double) std::rand()/RAND_MAX;
centers[i] = {x, y};
}
auto [check, n_iter_eff, dmin] = process (A, R, centers, n_iter);
std::cout << "check = " << check << "\n";
std::cout << "Relative min distance = " << std::setprecision (9) << dmin/R << "\n";
std::cout << "nb iterations = " << n_iter_eff << "\n";
print (centers);
return 0;
}

How to expand the product of a sequence of binomials efficiently?

The product of the sequence of binomials reads
where {a_i} and {b_i} are coefficients in binomials.
I need to expand it to a polynomial
and use all coefficients {c_k} in the polynomial afterwards.
How to expand it efficiently? The speed has priority over the memory occupation because the expansion will be used many times.
What I tried
At present I just come up with an update scheme, which expands the polynomial right after absorbing one binomial.
This scheme needs two arrays — one for results up to i-1 and the other for results up to i.
Here is the C++ code for my naive scheme, but I think this question is irrelevant to what language is used.
#include <iostream>
#include <vector>
int main()
{
using namespace std;
// just an example, the coefficients are actually real numbers in [0,1]
unsigned d = 3;
vector<double> a;
vector<double> b;
a.resize(d, 1); b.resize(d, 1);
// given two arrays, a[] and b[], of length d
vector< vector<double> > coefficients(2);
coefficients[0].resize(d + 1);
coefficients[1].resize(d + 1);
if (d > 0) {
auto &coeff = coefficients[0]; // i = 0
coeff[0] = a[0];
coeff[1] = b[0];
for (unsigned i = 1; i < d; ++i) {// i : [1, d-1]
const auto ai = a[i];
const auto bi = b[i];
const auto &oldCoeff = coefficients[(i-1)%2];
auto &coeff = coefficients[i%2];
coeff[0] = oldCoeff[0] * ai; // j = 0
for (unsigned j = 1; j <= i; ++j) { // j : [1, i]
coeff[j] = oldCoeff[j] * ai + oldCoeff[j-1] * bi;
}
coeff[i+1] = oldCoeff[i] * bi; // j = i
}
}
const auto &coeff = coefficients[(d-1)%2];
for (unsigned i = 0; i < d; ++i) {
cout << coeff[i] << "\t";
}
cout << coeff[d] << '\n';
}

Why inner product of same size matrix in Eigen cost quite different time?

I used Eigen to calculate inner product of two matrix, the first one is A=(BC).eval() and second one is D=(EF).eval(). Here B,C,E,F are the same size (1500 * 1500) but with different values. I find the first one cost about 200 ms while the second one cost about 6000 ms, I have no idea why this happened.
#include <iostream>
#include <time.h>
#include "Eigen/Dense"
int main() {
clock_t start, stop;
Eigen::MatrixXf mat_a(1200, 1500);
Eigen::MatrixXf mat_b(1500, 1500);
Eigen::MatrixXf mat_r(1000, 1300);
int i, j;
float c = 0;
for (i = 0; i < 1200; i++) {
for (j = 0; j < 1500; j++) {
mat_a(i, j) = (float)(c/3 * 1.0e-40);
//if (i % 2 == 0 && j % 2 == 0) mat_a(i, j);
c++;
}
}
//std::cout << mat_a.row(0) << std::endl;
c = 100;
for (i = 0; i < 1500; i++) {
for (j = 0; j < 1500; j++) {
mat_b(i, j) = (float)(c/3 * 0.5e-10);
c++;
}
}
//std::cout << mat_b.row(0) << std::endl;
start = clock();
mat_r = mat_a * mat_b;
stop = clock();
std::cout << stop - start << std::endl;
getchar();
return 0;
}
as show in above example code. I find this is caused by the value of the matrix, when mat_a has value about e-40 and mat_b has value about e-10, this problem occurs stably.
Is there anyone who can explain it?
This is because your matrix contains denormal numbers that are slow to deal with for the CPU. You should make sure that you are using reasonable units so that those can be considered as zeros, and then enable the flush-to-zero (FTZ) and denormals-as-zero flags (DAZ), for instance using the fast-math mode of your compiler or at runtime, see this SO question.

Repeated Squaring - Matrix Multiplication using NEWMAT

I'm trying to use the repeated squaring algorithm (using recursion) to perform matrix exponentiation. I've included header files from the NEWMAT library instead of using arrays. The original matrix has elements in the range (-5,5), all numbers being of type float.
# include "C:\User\newmat10\newmat.h"
# include "C:\User\newmat10\newmatio.h"
# include "C:\User\newmat10\newmatap.h"
# include <iostream>
# include <time.h>
# include <ctime>
# include <cstdlib>
# include <iomanip>
using namespace std;
Matrix repeated_squaring(Matrix A, int exponent, int n) //Recursive function
{
A(n,n);
IdentityMatrix I(n);
if (exponent == 0) //Matrix raised to zero returns an Identity Matrix
return I;
else
{
if ( exponent%2 == 1 ) // if exponent is odd
return (A * repeated_squaring (A*A, (exponent-1)/2, n));
else //if exponent is even
return (A * repeated_squaring( A*A, exponent/2, n));
}
}
Matrix direct_squaring(Matrix B, int k, int no) //Brute Force Multiplication
{
B(no,no);
Matrix C = B;
for (int i = 1; i <= k; i++)
C = B*C;
return C;
}
//----Creating a matrix with elements b/w (-5,5)----
float unifRandom()
{
int a = -5;
int b = 5;
float temp = (float)((b-a)*( rand()/RAND_MAX) + a);
return temp;
}
Matrix initialize_mat(Matrix H, int ord)
{
H(ord,ord);
for (int y = 1; y <= ord; y++)
for(int z = 1; z<= ord; z++)
H(y,z) = unifRandom();
return(H);
}
//---------------------------------------------------
void main()
{
int exponent, dimension;
cout<<"Insert exponent:"<<endl;
cin>>exponent;
cout<< "Insert dimension:"<<endl;
cin>>dimension;
cout<<"The number of rows/columns in the square matrix is: "<<dimension<<endl;
cout<<"The exponent is: "<<exponent<<endl;
Matrix A(dimension,dimension),B(dimension,dimension);
Matrix C(dimension,dimension),D(dimension,dimension);
B= initialize_mat(A,dimension);
cout<<"Initial Matrix: "<<endl;
cout<<setw(5)<<setprecision(2)<<B<<endl;
//-----------------------------------------------------------------------------
cout<<"Repeated Squaring Result: "<<endl;
clock_t time_before1 = clock();
C = repeated_squaring (B, exponent , dimension);
cout<< setw(5) <<setprecision(2) <<C;
clock_t time_after1 = clock();
float diff1 = ((float) time_after1 - (float) time_before1);
cout << "It took " << diff1/CLOCKS_PER_SEC << " seconds to complete" << endl<<endl;
//---------------------------------------------------------------------------------
cout<<"Direct Squaring Result:"<<endl;
clock_t time_before2 = clock();
D = direct_squaring (B, exponent , dimension);
cout<<setw(5)<<setprecision(2)<<D;
clock_t time_after2 = clock();
float diff2 = ((float) time_after2 - (float) time_before2);
cout << "It took " << diff2/CLOCKS_PER_SEC << " seconds to complete" << endl<<endl;
}
I face the following problems:
The random number generator returns only "-5" as each element in the output.
The Matrix multiplication yield different results with brute force multiplication and using the repeated squaring algorithm.
I'm timing the execution time of my code to compare the times taken by brute force multiplication and by repeated squaring.
Could someone please find out what's wrong with the recursion and with the matrix initialization?
NOTE: While compiling this program, make sure you've imported the NEWMAT library.
Thanks in advance!
rand() returns an int so rand()/RAND_MAX will truncate to an integer = 0. Try your
repeated square algorithm by hand with n = 1, 2 and 3 and you'll find a surplus A *
and a gross inefficiency.
Final Working code has the following improvements:
Matrix repeated_squaring(Matrix A, int exponent, int n) //Recursive function
{
A(n,n);
IdentityMatrix I(n);
if (exponent == 0) //Matrix raised to zero returns an Identity Matrix
return I;
if (exponent == 1)
return A;
{
if (exponent % 2 == 1) // if exponent is odd
return (A*repeated_squaring (A*A, (exponent-1)/2, n));
else //if exponent is even
return (repeated_squaring(A*A, exponent/2, n));
}
}
Matrix direct_squaring(Matrix B, int k, int no) //Brute Force Multiplication
{
B(no,no);
Matrix C(no,no);
C=B;
for (int i = 0; i < k-1; i++)
C = B*C;
return C;
}
//----Creating a matrix with elements b/w (-5,5)----
float unifRandom()
{
int a = -5;
int b = 5;
float temp = (float) ((b-a)*((float) rand()/RAND_MAX) + a);
return temp;
}

determining points from set of pairwise distances

given a matrix of distances between points is there an algorithm for determining a set of n-dimensional points that has these distances? (or at least minimises the error)
sort of like a n-dimensional version of the turnpike problem.
The best I can come up with is using multidimensional scaling.
You are on the right track with multi-dimensional scaling (MDS), but MDS is impractical for large datasets, as its time complexity is quadratic in the number of points. You may want to look at FastMap, which has linear time complexity and is better suited to indexing. See:
Christos Faloutsos and King-Ip Lin:
"FastMap: a Fast Algorithm for
Indexing, Data-Mining and
Visualization of Traditional and
Multimedia Datasets, in Proc.
SIGMOD, 1995, doi:10.1145/223784.223812
You can "cheat" and use an iterative numerical method for this. Take all of the points to be in some "random" positions initially, and then loop through them, moving them away from each other proportionally to the required distance. This will prefer some points, but taking an average of the moves before applying them, then applying the average will remove this problem. This is an O(n²) algorithm, but very simple to implement and understand. In the 2-d example below the error is << 10%, though it may not behave so well if the distances given are unrealistic.
C++ Example:
#include <conio.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define DAMPING_FACTOR 0.99f
class point
{
public:
float x;
float y;
public:
point() : x(0), y(0) {}
};
// symmetric matrix with distances
float matrix[5][5] = {
{ 0.0f, 4.5f, 1.5f, 2.0f, 4.0f },
{ 4.5f, 0.0f, 4.0f, 3.0f, 3.5f },
{ 1.5f, 4.0f, 0.0f, 1.0f, 5.0f },
{ 2.0f, 3.0f, 1.0f, 0.0f, 4.5f },
{ 4.0f, 3.5f, 5.0f, 4.5f, 0.0f }
};
int main(int argc, char** argv)
{
point p[5];
for(unsigned int i = 0; i < 5; ++i)
{
p[i].x = (float)(rand()%100)*0.1f;
p[i].y = (float)(rand()%100)*0.1f;
}
// do 1000 iterations
float dx = 0.0f, dy = 0.0f, d = 0.0f;
float xmoves[5], ymoves[5];
for(unsigned int c = 0; c < 1000; ++c)
{
for(unsigned int i = 0; i < 5; ++i) xmoves[i] = ymoves[i] = 0.0f;
// iterate across each point x each point to work out the results of all of the constraints in the matrix
// collect moves together which are slightly less than enough (DAMPING_FACTOR) to correct half the distance between each pair of points
for(unsigned int i = 0; i < 5; ++i)
for(unsigned int j = 0; j < 5; ++j)
{
if(i==j) continue;
dx = p[i].x - p[j].x;
dy = p[i].y - p[j].y;
d = sqrt(dx*dx + dy*dy);
dx /= d;
dy /= d;
d = (d - matrix[i][j])*DAMPING_FACTOR*0.5f*0.2f;
xmoves[i] -= d*dx;
ymoves[i] -= d*dy;
xmoves[j] += d*dx;
ymoves[j] += d*dy;
}
// apply all at once
for(unsigned int i = 0; i < 5; ++i)
{
p[i].x += xmoves[i];
p[i].y += ymoves[i];
}
}
// output results
printf("Result:\r\n");
for(unsigned int i = 0; i < 5; ++i)
{
for(unsigned int j = 0; j < 5; ++j)
{
dx = p[i].x - p[j].x;
dy = p[i].y - p[j].y;
printf("%f ", sqrt(dx*dx + dy*dy));
}
printf("\r\n");
}
printf("\r\nDesired:\r\n");
for(unsigned int i = 0; i < 5; ++i)
{
for(unsigned int j = 0; j < 5; ++j)
{
printf("%f ", matrix[i][j]);
}
printf("\r\n");
}
printf("Absolute difference:\r\n");
for(unsigned int i = 0; i < 5; ++i)
{
for(unsigned int j = 0; j < 5; ++j)
{
dx = p[i].x - p[j].x;
dy = p[i].y - p[j].y;
printf("%f ", abs(sqrt(dx*dx + dy*dy) - matrix[i][j]));
}
printf("\r\n");
}
printf("Press any key to continue...");
while(!_kbhit());
return 0;
}
There is an algorithm for doing this in Programming Collective Intelligence, p. 49, "Viewing Data in Two Dimensions", which could be adapted for n-dimensions.
Hey -- it's multidimensional scaling -- so I guess you are on the right track.
I can't edit the original, because I don't have enough rep, but I've tried to restate the problem here.
The OP has an input NxN matrix of distances. He wants to create an output array, size N, of N-dimensional coordinates representing points, where the distance between each point is stored in the input matrix.
Note that this is not solvable in the general case:
Suppose I have a matrix like this
A B C
A x 1 2
B x 0
C x
A is 1 unit of distance (say 1 metre) away from B, and A is one metre away from C. But B and C are in the same spot.
In this particular case the minimal sum of errors is 1 metre, and there are an infinite variety of solutions which achieve that result

Resources