I am trying to write a for loop in the second version which produce the same result in the original code but i am not sure how to get -400,-200,-400 in sequential order.
original code:
p->m_p[0] = randFloat(-400.0f, 400.0);
p->m_p[1] = randFloat(-200.0f, 200.0);
p->m_p[2] = randFloat(-400.0f, 400.0);
second version:
float x = -800;
float y = 800;
for(int i = 0; i < 4; i++)
{
plNew->m_fPosition[i] = randFloat(x / 2,y / 2);
}
If you need it to work in C (or in C++ before C++11), this would work:
#define NUMBER_OF_VALUES 3
float bounds[NUMBER_OF_VALUES] = { 400.0f, 200.0f, 400.0f };
for (int i = 0; i < NUMBER_OF_VALUES; i++)
{
plNew->m_fPosition[i] = randFloat(-bounds[i], bounds[i]);
}
You can extend this to make NUMBER_OF_VALUES be 4 or a larger number as long as you initialize all the members of bounds[NUMBER_OF_VALUES] with the desired constants.
A nice feature of this is that the sequence of constants can be anything you like,
not limited to alternating 400, 200, 400 or any other regular sequence.
Something like this?
for (int i = 0; i < 4; i++) {
float x, y;
if (i % 2) {
x = -400.0f;
y = 400.0f;
} else {
x = -200.0f;
y = 200.0f;
}
p->m_p[i] = randFloat(x, y);
}
What about?
float x = -800;
float y = 800;
for(int i = 0; i < 4; i++)
{
float z = 2.0 * ((float)((i + 1) % 2 + 1));
plNew->m_fPosition[i] = randFloat(x / z, y / z);
}
I would suggest keeping it simple, using something like the following :
const float arr3[] = {-400.0f, -200.0f, -400.0f};
for(int i = 0; i < 3; i++)
{
plNew->m_fPosition[i] = arr3[i];
}
float x = -400;
float y = 400;
for(int i = 0; i < 3; i++)
{
plNew->m_fPosition[i] = randFloat(x / (1 + (i & 1)), y / (1 + (i & 1)));
}
Related
Given the code below, is it possible to modify it so that there's a single set of M "random" numbers for x and y that will "restart" at the beginning of the set for every iteration of i?
What I know I can do is pre-generate an array for x and y of length M but I cannot use arrays because of limited memory. I was thinking of using random numbers with seeds somehow but haven't been able to figure it out.
double sampleNormal()
{
double u = ((double) rand() / (RAND_MAX)) * 2 - 1;
double v = ((double) rand() / (RAND_MAX)) * 2 - 1;
double r = u * u + v * v;
if (r == 0 || r > 1) return sampleNormal();
double c = sqrt(-2 * log(r) / r);
return u * c;
}
...
double x = 0;
double y = 0;
double a = 0;
double f = 100e6;
double t = 0;
double fsamp = 2e9;
for(int i = 0; i < N; i++)
{
for(int j = 0; j < M; j++)
{
x = sampleNormal();
y = sampleNormal();
t = j/fsamp;
a = x*cos(2*pi*f*t)+y*sin(2*pi*f*t);
}
}
that will "restart" at the beginning of the set for every iteration of i
was thinking of using random numbers with seeds somehow but haven't been able to figure it out.
Code could abuse srand()
// Get some state info from rand() for later.
unsigned start = rand();
start = start*(RAND_MAX + 1u) + rand();
for(int i = 0; i < N; i++) {
// Initialize the random number generator to produce the same sequence.
srand(42); // Use your favorite constant.
for(int j = 0; j < M; j++) {
x = sampleNormal();
y = sampleNormal();
t = j/fsamp;
a = x*cos(2*pi*f*t)+y*sin(2*pi*f*t);
}
}
// Re-seed so other calls to `rand()` are not so predictable.
srand(start);
void collision_f()
{
int x;
long double feq[Q], feq_R[Q], feq_B[Q], feq_force[Q];
long double mR[Q], mB[Q], meq_R[Q], meq_B[Q];
long double col_R[Q], col_B[Q];
forces_f();
#pragma omp parallel
{
#pragma omp for
for (x =0; x <NX; x++)
{
for (int y =0; y <NY; y++)
{
if ( (bnode[x][y] ==0) || (bnode[x][y] ==1) || (bnode[x][y] ==2) )
{
long double uxeq = ux_f[x][y] + Force_x_f[x][y]/rho_f[x][y];
long double uyeq = uy_f[x][y] + Force_y_f[x][y]/rho_f[x][y];
for (int i =0; i <Q; i++)
{
feq[i] = feq_R[i] = feq_B[i] = feq_force[i] = 0.0;
//equilibrium distribution
long double udotc_f = ux_f[x][y]*cx[i] + uy_f[x][y]*cy[i];
long double u2_f = pow(ux_f[x][y], 2) + pow(uy_f[x][y], 2);
feq[i] = wt[i]*rho_f[x][y]*(1.0 + 3.0*udotc_f + 4.5*pow(udotc_f, 2) - 1.5*u2_f);
feq_R[i] = wt[i]*rho_R_f[x][y]*(1.0 + 3.0*udotc_f + 4.5*pow(udotc_f, 2) - 1.5*u2_f);
feq_B[i] = wt[i]*rho_B_f[x][y]*(1.0 + 3.0*udotc_f + 4.5*pow(udotc_f, 2) - 1.5*u2_f);
long double udotc_force = uxeq*cx[i] + uyeq*cy[i];
long double u2_force = pow(uxeq, 2) + pow(uyeq, 2);
feq_force[i] = wt[i]*rho_f[x][y]*(1.0 + 3.0*udotc_force + 4.5*pow(udotc_force, 2) - 1.5*u2_force);
//printf("%d\t%d\t%d\t%Lf\t%Lf\t%Lf\t%Lf\n", x, y, i, feq[i], feq_R[i], feq_B[i], feq_force[i]);
}
//Calculating moments and meq
for (int i =0; i <Q; i++)
{
meq_R[i] = meq_B[i] = mR[i] = mB[i] = 0.0;
for (int j =0; j <Q; j++)
{
mR[i] += M[i][j]*r1[x][y][j];
meq_R[i] += M[i][j]*feq_R[j];
mB[i] += M[i][j]*b1[x][y][j];
meq_B[i] += M[i][j]*feq_B[j];
//printf("%d,%d\t%d,%d\t%Lf\t%Lf\t%Lf\t%Lf\n", x, y, i, j, mR[i], meq_R[i], mB[i], meq_B[i]);
}
//printf("%d\t%d\t%d\t%Lf\t%Lf\t%Lf\t%Lf\n", x, y, i, mR[i], meq_R[i], mB[i], meq_B[i]);
}
//Collision equation
for (int i =0; i <Q; i++)
{
col_R[i] = col_B[i] = 0.0;
for (int j =0; j <Q; j++)
{
col_R[i] += stmiv_f[x][y][i][j]*(mR[j] - meq_R[j]);
col_B[i] += stmiv_f[x][y][i][j]*(mB[j] - meq_B[j]);
}
long double force = feq_force[i] - feq[i];
r2[x][y][i] = r1[x][y][i] - col_R[i];
b2[x][y][i] = b1[x][y][i] - col_B[i];
f1[x][y][i] = r2[x][y][i] + b2[x][y][i] + force;
//Recoloring using d'Ortona's segregation method
r2[x][y][i] = (rho_R_f[x][y]/rho_f[x][y]) * (f1[x][y][i] + BETA_LKR*wt[i]*(rho_f[x][y] - rho_R_f[x][y])*(n_x[x][y]*cx[i] + n_y[x][y]*cy[i]));
b2[x][y][i] = f1[x][y][i] - r2[x][y][i];
}
if (rho_R_f[x][y] <=EVAP_LIM*rho_r_f)
{
for (int i =0; i <Q; i++)
{
b2[x][y][i] = f1[x][y][i];
r2[x][y][i] = 0.0;
}
}
if (rho_B_f[x][y] <=EVAP_LIM*rho_r_f)
{
for (int i =0; i <Q; i++)
{
r2[x][y][i] = f1[x][y][i];
b2[x][y][i] = 0.0;
}
}
}
}
}
}
return;
}
I am trying to implement OpenMP in this function. But I am getting nan for feq_R[Q] and -nan for meq_R[Q], meq_B[Q] only for a few combination of x, y. Also for each run, the values of x, y are different where I get -nan kind of solution. I have also checked that rho_f[x][y] is not zero for those x, y. I have also tried omp for reduction for meq_R[Q], meq_B[Q] only to be unsuccessful. FYI, the serial code runs without any problem. Any help is greatly appreciated.
I'm trying to add a quadruatic sequence in an array of integers (in C), instead of typing it manually.
#include <stdio.h>
int main ()
{
int x [100] = {0, 50, 150, 300, 500, 750, 1050, 1400};
//+0, +50, +100, +150, +200, +250, +300, +350, etc.
return 0;
}
Is there any way to do that?
num_add add 50 in each loop.
#include <stdio.h>
int main() {
int x[100];
int num_add = 50;
x[0] = 0;
for (int i = 1; i < 100; i++) {
x[i] = x[i - 1] + num_add;
num_add += 50;
}
for (int i = 0; i < 100; i++) {
printf("%d ", x[i]);
}
return 0;
}
for change main difference change the value of variable increment.
#include <stdio.h>
int main() {
int x[100];
int increment = 50;
for (int i = 0; i < 100; i++) {
x[i] = increment * i * (i+1) / 2
}
for (int i = 0; i < 100; i++) {
printf("%d ", x[i]);
}
return 0;
}
first time you add D difference,
but later difference continuously change.
change of that difference is in arithmetic progression
increment of main difference D is C constant
In your case both D & C are same, 50.
#include <stdio.h>
int main() {
int x[100];
int D = 50;
int C = 50;
for (int i = 0; i < 100; i++) {
x[i] = (D*i) + (C*i*(i - 1))/2
}
for (int i = 0; i < 100; i++) {
printf("%d ", x[i]);
}
return 0;
}
if C == D (as your case), replace one variable
x[i] = (D*i) + (C*i*(i - 1))/2
= (D*i) + (D*i*(i - 1))/2
= D * i * ( 1 + (i - 1)/2 )
= D * i * (2 + (i - 1)) / 2
= D * i * (i + 1) / 2
x[i] = D * i * (i+1) / 2
I have a question regarding FFT. I already manage to do FFT forward and backward using FFTW in C. Now, I want to apply high pass filter for edge detection, some of my source said that just zeroing the centre of the magnitude.
This is my input image
http://i62.tinypic.com/2wnxvfl.jpg
Basically what I do are :
Forward FFT
Convert the output to 2D array
Do forward FFT shifting
Make the real and imag value to 0 when the distance from the centre is 25% of the height
Generate the magnitude
Do backward FFT shifting
Convert into 1D array
Do Backward FFT.
This is the original magnitude, the processed magnitude, and the result
http://i58.tinypic.com/aysx9s.png
can someone help me, to tell me which part is wrong and how to do the high pass filtering using FFTW in C.
Thank You.
The Source Code:
unsigned char **FFT2(int width,int height, unsigned char **pixel, char line1[100],char line2[100], char line3[100],char filename[100])
{
fftw_complex* in, * dft, * idft, * dft2;
//fftw_complex tmp1,tmp2;
fftw_plan plan_f,plan_i;
int i,j,k,w,h,N,w2,h2;
w = width;
h = height;
N = w*h;
unsigned char **pixel_out;
pixel_out = malloc(h*sizeof(unsigned char*));
for(i = 0 ; i<h;i++)
pixel_out[i]=malloc(w*sizeof(unsigned char));
in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) *N);
dft = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) *N);
dft2 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) *N);
idft = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) *N);
/*run forward FFT*/
plan_f = fftw_plan_dft_2d(w,h,in,dft,FFTW_FORWARD,FFTW_ESTIMATE);
for(i = 0,k = 0 ; i < h ; i++)
{
for(j = 0 ; j < w ; j++,k++)
{
in[k][0] = pixel[i][j];
in[k][1] = 0.0;
}
}
fftw_execute(plan_f);
double maxReal = 0.0;
for(i = 0 ; i < N ; i++)
maxReal = dft[i][0] > maxReal ? dft[i][0] : maxReal;
printf("MAX REAL : %f\n",maxReal);
/*fftshift*/
//convert to 2d
double ***temp1;
temp1 = malloc(h * sizeof (double**));
for (i = 0;i < h; i++){
temp1[i] = malloc(w*sizeof (double*));
for (j = 0; j < w; j++){
temp1[i][j] = malloc(2*sizeof(double));
}
}
double ***temp2;
temp2 = malloc(h * sizeof (double**));
for (i = 0;i < h; i++){
temp2[i] = malloc(w*sizeof (double*));
for (j = 0; j < w; j++){
temp2[i][j] = malloc(2*sizeof(double));
}
}
for (i = 0;i < h; i++){
for (j = 0; j < w; j++){
temp1[i][j][0] = dft[i*w+j][0];
temp1[i][j][1] = dft[i*w+j][1];
}
}
int m2 = h/2;
int n2 = w/2;
//forward shifting
for (i = 0; i < m2; i++)
{
for (k = 0; k < n2; k++)
{
double tmp13[2] = {temp1[i][k][0],temp1[i][k][1]};
temp1[i][k][0] = temp1[i+m2][k+n2][0];
temp1[i][k][1] = temp1[i+m2][k+n2][1];
temp1[i+m2][k+n2][0] = tmp13[0];
temp1[i+m2][k+n2][1] = tmp13[1];
double tmp24[2] = {temp1[i+m2][k][0],temp1[i+m2][k][1]};
temp1[i+m2][k][0] = temp1[i][k+n2][0];
temp1[i+m2][k][1] = temp1[i][k+n2][1];
temp1[i][k+n2][0] = tmp24[0];
temp1[i][k+n2][1] = tmp24[1];
}
}
//process
for (i = 0;i < h; i++){
for (j = 0; j < w; j++){
if(distance_to_center(i,j,m2,n2) < 0.25*h)
{
temp1[i][j][0] = (double)0.0;
temp1[i][j][1] = (double)0.0;
}
}
}
/* copy for magnitude */
for (i = 0;i < h; i++){
for (j = 0; j < w; j++){
temp2[i][j][0] = temp1[i][j][0];
temp2[i][j][1] = temp1[i][j][1];
}
}
//backward shifting
for (i = 0; i < m2; i++)
{
for (k = 0; k < n2; k++)
{
double tmp13[2] = {temp1[i][k][0],temp1[i][k][1]};
temp1[i][k][0] = temp1[i+m2][k+n2][0];
temp1[i][k][1] = temp1[i+m2][k+n2][1];
temp1[i+m2][k+n2][0] = tmp13[0];
temp1[i+m2][k+n2][1] = tmp13[1];
double tmp24[2] = {temp1[i+m2][k][0],temp1[i+m2][k][1]};
temp1[i+m2][k][0] = temp1[i][k+n2][0];
temp1[i+m2][k][1] = temp1[i][k+n2][1];
temp1[i][k+n2][0] = tmp24[0];
temp1[i][k+n2][1] = tmp24[1];
}
}
//convert back to 1d
for (i = 0;i < h; i++){
for (j = 0; j < w; j++){
dft[i*w+j][0] = temp1[i][j][0];
dft[i*w+j][1] = temp1[i][j][1];
dft2[i*w+j][0] = temp2[i][j][0];
dft2[i*w+j][1] = temp2[i][j][1];
}
}
/* magnitude */
double max = 0;
double min = 0;
double mag=0;
for (i = 0, k = 1; i < h; i++){
for (j = 0; j < w; j++, k++){
mag = sqrt(pow(dft2[i*w+j][0],2) + pow(dft2[i*w+j][1],2));
if (max < mag)
max = mag;
}
}
double **magTemp;
magTemp = malloc(h * sizeof (double*));
for (i = 0;i < h; i++){
magTemp[i] = malloc(w*sizeof (double));
}
for(i = 0,k = 0 ; i < h ; i++)
{
for(j = 0 ; j < w ; j++,k++)
{
double mag = sqrt(pow(dft2[i*w+j][0],2) + pow(dft2[i*w+j][1],2));
mag = 255*(mag/max);
//magTemp[i][j] = 255-mag; //Putih
magTemp[i][j] = mag; //Item
}
}
/* brightening magnitude*/
for(i = 0,k = 0 ; i < h ; i++)
{
for(j = 0 ; j < w ; j++,k++)
{
//double temp = magTemp[i][j];
double temp = (double)(255/(log(1+255)))*log(1+magTemp[i][j]);
pixel_out[i][j] = (unsigned char)temp;
}
}
generateImage(width,height,pixel_out,line1,line2,line3,filename,"magnitude");
/* backward fft */
plan_i = fftw_plan_dft_2d(w,h,dft,idft,FFTW_BACKWARD,FFTW_ESTIMATE);
fftw_execute(plan_i);
for(i = 0,k = 0 ; i < h ; i++)
{
for(j = 0 ; j < w ; j++,k++)
{
double temp = idft[i*w+j][0]/N;
pixel_out[i][j] = (unsigned char)temp; //+ pixel[i][j];
}
}
generateImage(width,height,pixel_out,line1,line2,line3,filename,"backward");
return pixel_out;
}
EDIT new source code
I add this part before the forward shifting, the result is as expected also.
//proses
//create filter
unsigned char **pixel_filter;
pixel_filter = malloc(h*sizeof(unsigned char*));
for(i = 0 ; i<h;i++)
pixel_filter[i]=malloc(w*sizeof(unsigned char));
for (i = 0;i < h; i++){
for (j = 0; j < w; j++){
if(distance_to_center(i,j,m2,n2) < 20)
{
pixel_filter[i][j] = 0;
}
else
{
pixel_filter[i][j] = 255;
}
}
}
generateImage(width,height,pixel_filter,line1,line2,line3,filename,"filter1");
for (i = 0; i < m2; i++)
{
for (k = 0; k < n2; k++)
{
unsigned char tmp13 = pixel_filter[i][k];
pixel_filter[i][k] = pixel_filter[i+m2][k+n2];
pixel_filter[i+m2][k+n2] = tmp13;
unsigned char tmp24 = pixel_filter[i+m2][k];
pixel_filter[i+m2][k] = pixel_filter[i][k+n2];
pixel_filter[i][k+n2] = tmp24;
}
}
generateImage(width,height,pixel_filter,line1,line2,line3,filename,"filter2");
for (i = 0;i < h; i++){
for (j = 0; j < w; j++){
temp1[i][j][0] *= pixel_filter[i][j];
temp1[i][j][1] *= pixel_filter[i][j];
}
}
Your general idea is OK. From the output, it's hard to tell whether there's simply an accounting problem in your program, or whether this is perhaps the expected result. Try padding the source image with much more empty space, and filter out a smaller area in the frequency domain.
As a side note, doing this in C appears incredibly painful. Here is an equivalent implementation in Matlab. Not including plotting, it's around 10 lines of code. You might also try Numerical Python (NumPy).
% Demonstrate frequency-domain image filtering in Matlab
% Define the grid
x = linspace(-1, 1, 1001);
y = x;
[X, Y] = meshgrid(x, y);
% Make a square (source image)
rect = (abs(X) < 0.1) & (abs(Y) < 0.1);
% Compute the transform
rect_hat = fft2(rect);
% Make the high-pass filter
R = sqrt(X.^2 + Y.^2);
filt = (R > 0.05);
% Apply the filter
rect_hat_filtered = rect_hat .* ifftshift(filt);
% Compute the inverse transform
rect_filtered = ifft2(rect_hat_filtered);
%% Plot everything
figure(1)
imagesc(rect);
title('source');
axis square
saveas(gcf, 'fig1.png');
figure(2)
imagesc(abs(fftshift(rect_hat)));
title('fft(source)');
axis square
saveas(gcf, 'fig2.png');
figure(3)
imagesc(filt);
title('filter (frequency domain)');
axis square
saveas(gcf, 'fig3.png');
figure(4)
imagesc(fftshift(abs(rect_hat_filtered)));
title('fft(source) .* filter');
axis square
saveas(gcf, 'fig4.png');
figure(5)
imagesc(abs(rect_filtered))
title('result');
axis square
saveas(gcf, 'fig5.png');
The source image:
Fourier transform of the source image:
The filter:
Result of applying (multiplying) the filter with the fourier transform of the source image:
Taking the inverse transform gives the final result:
I'm trying to make a simple blur effect in c. I have an image loaded in an 512*512 array of RGB pixels and I'm using 3x3 kernel to blur that image
here is the kernel
float matrix[9] = {1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f};
and here is the code that is doing the bluring
void useBlur(){
for(int i = 0; i < ARRAY_SIZE; i++){
float r = 0;
float g = 0;
float b = 0;
int m, n;
for(int y = -1, m = 0; y <= 1; y++, m++){
for(int z = -1, n = 0; z <= 1; z++, n++){
r += (float)orig_image[i + 512 * y + z].r * (float)matrix[m*3+n];
g += (float)orig_image[i + 512 * y + z].g * (float)matrix[m*3+n];
b += (float)orig_image[i + 512 * y + z].b * (float)matrix[m*3+n];
}
}
image[i].r = r;
image[i].g = g;
image[i].b = b;
}
}
I'm not sure what is wrong with that code, but it is producing result:
Any ideas why the colors are wrong? And how to fix it?
EDIT:
fixed matrix[7] from 9.0/9.0 to 1.0/9.0 and uploaded new image
I tried your code with some changes, the images I have are BGRA and I am using opencv for my image container but the structure of the code is the same and it works perfectly.
for (int i = 2*image.cols; i < image.rows*image.cols-2*image.cols; i++)
{
float r = 0;
float g = 0;
float b = 0;
for (int y = -1; y <=1; y++)
{
for (int z = -1; z <=1; z++)
{
b += (float)image.at<cv::Vec4b>(i + image.cols*y+z)(0)*(1.0/9);
g += (float)image.at<cv::Vec4b>(i + image.cols*y+z)(1)*(1.0/9);
r += (float)image.at<cv::Vec4b>(i + image.cols*y+z)(2)*(1.0/9);
}
}
image.at<cv::Vec4b>(i)(0) = b;
image.at<cv::Vec4b>(i)(1) = g;
image.at<cv::Vec4b>(i)(2) = r;
}
I would assume that means the problem is either not in the code you posted, or somehow the opencv cv::Mat class is handling something your image container is not. The obvious candidate for that would be that you seem to be implicitly converting from float to uchar at the end of your code. Could you test running this loop over your image but without modifying it? It could look like this, or any number of other ways. This is ugly, but a quick conversion.
void useBlur(){
for(int i = 0; i < ARRAY_SIZE; i++){
float r = 0;
float g = 0;
float b = 0;
int m, n;
for(int y = -1, m = 0; y <= 1; y++, m++){
for(int z = -1, n = 0; z <= 1; z++, n++){
if(y == 0 && z == 0)
{
r += (float)orig_image[i + 512 * y + z].r * (float)matrix[m*3+n]*9;
g += (float)orig_image[i + 512 * y + z].g * (float)matrix[m*3+n]*9;
b += (float)orig_image[i + 512 * y + z].b * (float)matrix[m*3+n]*9;
}
}
}
image[i].r = r;
image[i].g = g;
image[i].b = b;
}
}
Theoretically nothing should change about the image when you do that, so if the image is changing it is because of some conversion error. I admit the theory is unlikely but the structure of your code seems sound so I don't know what else to suggest.