I'm trying to use FFTPACK converted from Fortran to C that I downloaded from Netlib (http://www.netlib.org/fftpack/). Unfortunately it seems to not really documented, and very cryptic (as I imagine most FFT codes are). Apparently it should follow a similar structure to the original Fortran code, so that's what I tried.
Here's what I have so far:
void main()
{
int n = 10;
float* wsave;
forward_transform(function1, wsave, n);
}
void forward_transform(float (*f)(float), float* wsave, int n)
{
int *ifac;
int i;
float r[n];
for (i = 0; i< n; i++)//set function values
{
r[i] = f((float)(-M_PI + i*2*M_PI/(n-1)));
}
__ogg_fdrffti(n, *wsave, *ifac);//initialize
__ogg_fdrfftf(n, *r, *wsave, *ifac);//forward transform
}
This code manages to compile, but gives a segfault when I call __ogg_fdrffti. I tried entering via gbd into fft.c to see exactly where the error is, but I can't seem to do that (the code still segfaults at the same line in my forward_transform function) leading me to believe that I'm somehow making an error in how I'm passing the various arrays.
Does anyone have any experience with or examples of the C version of FFTPACK?
The variables initialized in these functions have to exist somewhere in memory. You are passing pointers instead.
Try
void main()
{
int n = 10;
float wsave;
forward_transform(function1, wsave, n);
}
void forward_transform(float (*f)(float), float wsave, int n)
{
int ifac;
int i;
float r[n];
for (i = 0; i< n; i++)//set function values
{
r[i] = f((float)(-M_PI + i*2*M_PI/(n-1)));
}
__ogg_fdrffti(n, &wsave, &ifac);//initialize
__ogg_fdrfftf(n, r, &wsave, &ifac);//forward transform
}
Notice that the pointers are created using the address operator & on actual variables.
Related
I was trying to remind how pointers worked in c and c++ and I found this very interesting video (Pointers in C/C++). In minute 3:14:00, he begins to talk about pointer functions and callbacks, and I ended a bit confused about the real application of them.
The example case he provides consists of a sorting algorithm that takes a function pointer as argument, which defines the comparison "rule" to follow (order from geater to smaller, order from smaller to greater, from greater to smaller given the absolute values...). He eventually ends with something like this:
#include<stdio.h>
int compare(int a, int b){
if(a > b) return -1;
return 1;
}
void MyBubbleSort(int A[], int n, int (*compare)(int,int)){
int i,j,temp;
for(i=0; i<n; i++){
for(j=0; j<n-1; j++){
if(compare(A[j], A[j+1]) > 0{
temp = A[j];
A[j] = A[j+1];
A[j+1] = temp;
}
}
}
}
int main(){
int i, A[] = {3,2,1,5,6,4};
MyBubbleSort(A,6,compare);
for(i=0; i<6; i++) printf("%d ",A[i]);
}
When he wants to change the comparison rule, he changes the compare(int, int) content and that's all. My question is, why would he do that, instead of just having a separate function called compare(int, int) that just does the same as the one showed in the code snippet, and just call that function from within MyBubbleSort(int[], int). Wouldn't it just have the same behaviour? What are the benefits then? Are there any other interesting use cases?
Thank you very much for answers!
If I understand your question correctly, the main point is something that he mentions in the narration but does not include in the sample code: you could have several different comparison functions in your program, and use them at different times as appropriate, while still having just one MyBubbleSort function.
An example might look like:
int compare_increasing(int a, int b){
if(a > b) return -1;
return 1;
}
int compare_decreasing(int a, int b){
if(a < b) return -1;
return 1;
}
void MyBubbleSort(int A[], int n, int (*compare)(int,int));
}
int main(){
// ...
// sort in increasing order
MyBubbleSort(A,6,compare_increasing);
// sort in decreasing order
MyBubbleSort(A,6,compare_decreasing);
}
Calling a function by a pointer in this case makes the sorting function universal.
If you hardcode the comparison in that function it will work only for that condition.
C does not have lambda expressions and anonymous functions so the compare function has to be written separately and the pointer passed.
I wrote a simple method to calculate an arithmetic mean like so:
float arithmetic_mean(int a[], int n)
{
float sum = 0;
int i;
for (i = 0; i < n; i++)
{
sum += a[i];
}
sum = sum / (float)n;
return sum;
}
I wanted to check it in main:
int main()
{
int a[] = { 1,3,5,1,6,7 };
float check = arithmetic_mean(a, 6);
printf("%f", check);
return 0;
}
even though the value the method returns is correct (=3.833333 as checked by printing it before returning it), when I try to print it in main I get 9 as the output.
I'm really new to C language and stuff like this always seems to happen with floats - I'll write a method that works and return a float - and the returned value would be something seemingly random. What am I missing here? What am I doing wrong?
The problem (which I can reproduce with MSVC) is that you are calling the arithmetic_mean function (from main) before you have defined it. Thus, the compiler uses a default definition of the function, which is that it returns an int type ... and the actual (float) value returned just happens to have a bit pattern that represents 9 when interpreted as an int.
You can leave the definition of the function where it is (after main) so long as you provide a forward declaration of the function, so that the compiler knows what the return type is:
float arithmetic_mean(int a[], int n); // Forward declaration of the function!
int main()
{
int a[] = { 1,3,5,1,6,7 };
float check = arithmetic_mean(a, 6);
printf("%f\n", check);
return 0;
}
// The actual DEFINITION (including the body) of the function can follow...
Turning on compiler warnings would have helped you spot this! For example, without the forward declaration, MSVC gives this:
warning C4013: 'arithmetic_mean' undefined; assuming extern returning
int
I new to C, and I just can't figure out how to modify a 2D array in a function.
Here's the code I tried:
void init_matrix(int **M) {
M[0][0] = 1;
}
int main(void) {
int M[3][3];
init_matrix(M, 3);
return 0;
}
(Please note that this code is voluntarily stripped down in order to focus on the issue, I need my function to be able to work on arrays of a globally unknown size (though it could be a parameter of the function))
When I try to run this, it just gets stuck... The debugger says it's a problem of right to write in this memory slot.
How would you write the init_matrix function in the C spirit ?
Why can't I write in my matrix ?
I would like to use as few "advanced" concepts and function as possible.
Thanks in advance =)
An array is not a pointer. You need to give the dimensions of the array when you pass it as a function parameter.
void init_matrix(size_t x, size_t y, int matrix[x][y])
{
for (size_t i = 0 ; i < x ; ++i)
{
for (size_t j = 0 ; j < y ; ++j)
matrix[i][j] = 1;
}
}
int main(void)
{
int matrix[5][3];
init_matrix(5, 3, matrix);
return (0);
}
The function init_matrix() takes as parameters the dimensions, then the array (this order is important here). The "double loop" is a classic for running through a "2D memory area" like our array.
(Note that you can forget the first dimension,
void init_matrix(size_t x, size_t y, int matrix[][y])
also works)
I am having an issue with double arguments for a probability function in C.
I have a function that takes a double as an argument:
int binomrand(double p, int n)
{
int i;
int numevents = 0;
for(i = 0; i < n; i++)
{
numevents += bernoullirand(p);
}
return numevents;
}
I pass .85:
int numcoach = binomrand(.85,COACH_SEATS);
but the minute I step into this function, Xcode shows p as such:
p double 5.2511106800094658E-315
Which is off by a factor of at least 10^314. This occurs even before calling bernoullirand, so I haven't included that code here.
E:
Since it was relevant, here was the .h declaration of binomrand:
int binomrand(float p, int n);
This was clearly wrong, but I didn't think to look at it. Note that's "float" and not "double".
When I updated the function from float to double in its .c file, I neglected to do so in its .h file. Multiple answerers realized this quickly.
This can happen if you have not declared the function binomrand before first use or declared it incorrectly. Declare the function on the top of file where you actually use it or use proper header files.
int binomrand(double p, int n); /* Declaration */
I have a written a C program to find the k nearest neighbors of all the points in a given set of points (randomly generated). The problem is when I increase the number of points(and consequently the array size) to 10000 the program gives segment violation error as soon as I call the function to find out the nearest neighbors. I am not able to get inside the function using the debugger. As soon as I do a "Step Into" the program crashes.
I have used code-blocks and Eclipse CDT (on Windows 7) and both give the error at the same point. In case of code-blocks it gives segment violation and in case of Eclipse it first shows - "No source available for __chkstk_ms() at 0x4039a7" and then the error comes from the OS itself - "KNN.exe has stopped working"
However the program runs fine on Linux(Ubuntu 32bit).
Here is the code snippet :
#define MAX_SIZE 10000
int main()
{
int n = MAX_SIZE;
int k = 3;
int i;
double points[MAX_SIZE*2]; //2-D array in row-major order
double result[MAX_SIZE*3*2];
srand(time(NULL));
for(i=0; i < n; i++)
{
points[i*2] = (double)rand()/(double)RAND_MAX;
points[i*2 + 1] = (double)rand()/(double)RAND_MAX;
}
seek(points,n,k,result); //<---------- ERROR
seek(points,n,k,result); //<------------ NO ERROR
....
}
void seek(const double * const points, int n, int k, double *result)
{
TreeNode qtree[MAX_SIZE];
int order_array[MAX_SIZE];
int num_nodes = build_quadtree(a, n, k, qtree,order_array);
......
}
struct tree_node
{
int id;
int num_points;
int start_order;
int end_order;
int parent;
int child[4];
struct rectangle rect;
enum boolean is_leaf;
};
struct point
{
double x;
double y;
};
struct rectangle
{
int id;
double xmin,xmax,ymin, ymax;
struct point midpt;
};
What is more confusing is that I have another function with the same arguments which is running without any problem.
Please provide suggestions on how to debug this.
EDIT:- . I have posted the first few lines of seek() function. As the replies have pointed out I am actually allocating a lot of memory on the seek function but I am wondering why it is not a problem in linux.
I think you're exceeding your available stack (see the MSDN docs on _chkstk). Try allocating the arrays dynamically instead
int main()
{
double* points = malloc(sizeof(double) * MAX_SIZE*2];
double* result = malloc(sizeof(double) * MAX_SIZE*3*2];
...
free(points);
free(result);
}
The stack overflow is happening when you call seek. You haven't posted code for it but may have to rework it also to reduce its stack use.
Perhaps following code is the real culprit. both qtree and orderarray are also stack allocated. I would change the MAX_SIZE to a lower value and see the issue re-proes.
TreeNode qtree[MAX_SIZE];
int order_array[MAX_SIZE];