Complex Data Type in C Producing Trouble in Algorithm - c

I'm trying to perform a calculation which involves the following C-function:
long double complex* tridiag_thomas(long double complex *a, long double complex *b, long double complex *c, long double complex *f, int N) {
long double complex *v; v = (long double complex *)malloc(sizeof(long double complex) * N);
long double complex *y; y = (long double complex *)malloc(sizeof(long double complex) * N);
long double complex w;
int k;
for (k = 0; k < N; k++) {
y[k] = 0;
v[k] = 0;
}
w = a[0];
y[0] = f[0] / w;
for (k = 1; k < N; k++) {
v[k - 1] = c[k - 1] / w;
w = a[k] - b[k] * v[k - 1];
y[k] = (f[k] - b[k] * y[k - 1]) / w;
}
for (k = N - 2; k >= 0; k--) {
y[k] = y[k] - v[k] * y[k + 1];
}
return y;
}
I pass a matrix through this function (f), find y, modify f with y, and pass the new f through the function again. I do this on the order of 1000 times. When working with real values (and making the necessary change of long double complex -> long double), this function works as expected. When using it in the above form with complex arguments, however, the result diverges to infinity very quickly.
Can anybody enlighten me as to why that might be? I'm not new to programming, but I am new to C.

I do see a problem where it is leaking 'v'. This makes me suspect that you are not following the c style assignment at the upper level. We don't have the upper level code.
When is y freed? Does the assignment loop through all the values or are you doing a c++ style assignment? Remember that allocation, assignment, and deallocation do not come for free in c, except for the types built in to the compiler.

Related

creating a floating point power function in c

So here's the current implementation of my power function.
pow(x, n) int x, n;
{
int r = 1;
int i;
for (i = 0; i < n; i++)
r *= x;
return (r);
}
The problem is how it only works for whole numbers & doesn't work with floats like pow(4, .5).
Of course, I've already tried changing everything to double & I know how a standard library function exists. Also I've seen Floating point exponentiation without power-function, but none of the solutions were working nor what I wanted.
Here is the version, where I used doubles.
double pow(x, n)
double x, n;
{
double r = 1.;
int i;
for (i = 0; i < n; i++)
r *= x;
return (r);
}
It returns 1., when I use it as pow(4., .5).

How to code the summation of a function in C?

EDIT: I've added the main, factorial, and trapGamma function to give the full picture but I am specifically talking about the for loop for iSum in the I function.
Basically I've run out of ideas and exhausted everywhere I know of to find an answer to this. I need to code a program that will compute a complex function which represents an M/M/1 queue.
The function includes sub functions such as calculating the integral of a gamma function and computing factorials. I've written all the code for the computations but my sum is giving me huge numbers when I would expect nothing higher than about .35
#include <math.h>
#include <stdio.h>
double I(int k, double t);
double trapGamma(double z);
unsigned long long int factorial(unsigned int n);
int main()
{
int k;
int i = 0;
double dt = 0.1;
printf("Ikx = [ \n");
for (t = 14.0 ; t <= 15.0; t += dt)
{
printf("%f " , t);
for (k = 1 ; k <= 10 ; k++)
{
I(k, t);
printf("%f " , I(k, t));
}
printf("\n");
}
printf(" ];\n");
return (0);
}
double I(int k, double t)
{
unsigned long long int x;
unsigned int n = 20;
double numerator, y, pow1, c;
double iSum;
double Ix;
int i = 0;
iSum = 0.0;
Ix = 0.0;
a = .25 * pow(t , 2);
b = pow(a, i);
x = factorial(n);
y = trapGamma(k + i + 1);
iSum = (b / (x * y));
//This is the sum loop that I'm having trouble with, I've broke the iSum equation down for my own readability while coding right above this comment
for (i = 0; i <= 100 ; i++)
{
iSum += i;
}
Ix = (pow((.5 * t), k) ) * iSum;
return Ix;
}
/*
I've checked both the factorial and trapGamma functions and they are giving me the expected results.
*/
unsigned long long int factorial(unsigned int n)
{
if(n <= 1)
return 1;
else
return (n * factorial(n - 1));
}
double trapGamma (double z)
{
int i , N = 100;
double gamma;
double a = 0.0;
double b = 15.0;
double x1, x2, y1, y2;
double areai;
double w = (b - a) / N;
gamma = 0.0;
for (i = 1; i < N; i++)
{
x1 = a + ((i - 1) * w); //the left bound point
x2 = a + (i*w); //the right bound point
y1 = pow(x1,z - 1)*exp(-x1); //the height of our left bound
y2 = pow(x2, z - 1)*exp(-x2); //the height of our right bound
areai = ((y1 + y2) / 2.0) * (x2 - x1);
gamma += areai;
}
return gamma;
}
This is building upon another project where I used a bessel function to create the M/M/1 queue over a 60 second span so I can see what this one is supposed to be. I've checked both my trapGamma and factorial functions results on there own and they are both working as expected.
How are summations supposed to be coded?
If the intent of the posted code is to calculate the modified Bessel function I, there are some pitfalls and useful semplifications to be aware of. Given
Trying to calculate the factorial, the value of the Gamma function, their product and the powers separately for each term of the sum leads to integer overflow sooner than later.
It's better to update the value of each addend of the sum instead.
Also, given that k is a whole, we have Γ(n) = (n - 1)!
The addends are increasingly smaller and, after some iterations, too small to be added to the sum, given the limited precision of type double.
// Evaluates x^k / k! trying not to overflow
double power_over_factorial(double x, int k)
{
double result = 1.0;
for ( int i = 1; i <= k; ++i )
{
result *= x / i;
}
return result;
}
#define MAX_ITERS 20
double modified_Bessel_I(int k, double x)
{
x /= 2;
const double xx = x * x;
double partial = power_over_factorial(x, k);
double old_sum, sum = partial;
int m = 1;
do
{
old_sum = sum;
partial *= xx / ((m + k) * m);
sum += partial;
}
while ( old_sum != sum && ++m < MAX_ITERS );
return sum;
}
Testable here.

I found where the segmentation fault occurs, but I don't know what to do now

Basically, I'm taking a course called parallel programming. However, I have no experience programming in C and am not too knowledgeable in computer architecture.
I know that cache is faster than memory... However, I have no idea how these concepts relate to C programming.
anyways my task is to make a fast version of matrix multiplication. From what I've googled online I should be using SIMD SSE, which is a interface that allows you to execute multiple operations at once and use loop unrolling.
However, when I try it, I keep getting a segmentaiton fault. I used printf() to find where it occurs, but I still don't understand why or what to do afterward.
#include <emmintrin.h>
const char* dgemm_desc = "Simple blocked dgemm.";
#if !defined(BLOCK_SIZE)
#define BLOCK_SIZE 41
#endif
#define min(a,b) (((a)<(b))?(a):(b))
void do_block_fast (int lda, int M, int N, int K, double* A, double* B, double* C)
{
static double a[BLOCK_SIZE*BLOCK_SIZE] __attribute__ ((aligned (16)));
static double temp[1] __attribute__ ((aligned (16)));
__m128d vec1;
__m128d vec2;
__m128d vec3;
__m128d vec4;
// make a local aligned copy of A's block
for( int j = 0; j < K; j++ )
for( int i = 0; i < M; i++ )
a[i+j*BLOCK_SIZE] = A[i+j*lda];
/* For each row i of A */
for (int i = 0; i < M; ++i)
/* For each column j of B */
for (int j = 0; j < N; ++j)
{
/* Compute C(i,j) */
double cij = C[i+j*lda];
for (int k = 0; k < K; k += 2){
printf("0");
vec1 = _mm_load_pd(&a[i+k*BLOCK_SIZE]);
printf("1");
vec2 = _mm_loadu_pd (&B[k+j*lda]);
printf("2");
vec3 = _mm_mul_pd(vec1, vec2);
printf("3");
_mm_storeu_pd(&temp[0], vec3);
printf("4"); // SEGMENTATION fault occurs right after 4 is printed
cij += temp[0];
printf("5");
}
printf("5");
C[i+j*lda] = cij;
}
}
The error occurs after printf("4"); However I'm unsure why. I've tried different (alligned (x))) versions of the temp[] array. I even tried replacing it with a regular variable. But the segmentation fault still happens.
i
Here's the main routine that calls do_block_fast()
/* This routine performs a dgemm operation
* * C := C + A * B
* * where A, B, and C are lda-by-lda matrices stored in column-major format.
* * On exit, A and B maintain their input values. */
void square_dgemm (int lda, double* A, double* B, double* C)
{
/* For each block-row of A */
for (int i = 0; i < lda; i += BLOCK_SIZE)
/* For each block-column of B */
for (int j = 0; j < lda; j += BLOCK_SIZE)
/* Accumulate block dgemms into block of C */
for (int k = 0; k < lda; k += BLOCK_SIZE)
{
/* Correct block dimensions if block "goes off edge of" the matrix */
int M = min (BLOCK_SIZE, lda-i);
int N = min (BLOCK_SIZE, lda-j);
int K = min (BLOCK_SIZE, lda-k);
/* Perform individual block dgemm */
if((M % BLOCK_SIZE == 0) && (N % BLOCK_SIZE == 0) && (K % BLOCK_SIZE == 0))
{
do_block_fast(lda, M, N, K, A + i + k*lda, B + k + j*lda, C + i + j*lda);
}else{
do_block(lda, M, N, K, A + i + k*lda, B + k + j*lda, C + i + j*lda);
}
}
}

Dealing with big sized array in c programming

I am working on nonlinear differential equation.
What I was doing is to average up the positions over 100 different values of initial conditions.
I used odeiv in gsl. For each initial values, the time range is 4*10^7. However, the program kills, once ever I set 10 different initial conditions and the time range 10^6. This is kind of limit.
My computer has 8 cores and 16GB memory. I don't think this is that much big.
I'll put a part of the coding. Anybody help me on this?
Thank you.
long long int i, j, k;
double const y_i = 0, dydt_i = 0;
double n = 10;
long long int tmax = 1000000;
double A[tmax];
for (j=0; j < n; j++)
{
double y_j = y_i + 0.001*j;
double dydt_j = dydt_i;
t = 0.0;
double y[2] = {y_j, dydt_j};
gsl_odeiv2_system sys = {func, jac, 2, &params};
gsl_odeiv2_driver * d = gsl_odeiv2_driver_alloc_y_new (&sys, gsl_odeiv2_step_rk8pd, 1e-6, 1e-6, 0.0);
for (i=0; i< tmax; i++)
{
double ti = (double) i;
int status = gsl_odeiv2_driver_apply (d, &t, ti, y);
if (status != GSL_SUCCESS)
{
printf("error, return value%d\n", status);
break;
}
A[i] = A[i] +y[0];
}
gsl_odeiv2_driver_free (d);
}
for (k=0; k < tmax; k++)
{
A[k] = A[k]/n;
printf("%lld %e\n", k, A[k]);
}
return 0;
}
}
Local variables are allocated on the stack; the stack is not particularly huge, which means it's a bad place to allocate very large arrays. You need to make A a pointer and allocate it dynamically (or better, make it std::vector<double> if C++ is an option).

pointer to function in c code

i am very new in c programming. i am using a c code from the book 'numerical recipes in C' for polynomial regression. in this program i need to replace (*funcs) function with fpoly function.but i dont know how to do that and how to make changes in fpoly function to become like (*fpoly).could you please help me with that?
I really appreciate any help.
void fpoly(float x, float p[], int np)
//Fitting routine for a polynomial of degree np-1, with coefficients in the array p[1..np].
{
int j;
p[1]=1.0;
for (j=2;j<=np;j++) p[j]=p[j-1]*x;
}
void lfit( float x[], float y[], float sig[], int ndat, float a[], int ia[], int ma, float **covar, float *chisq, void (*funcs)(float, float [], int))
and here is the complete program:
void lfit(float x[], float y[], float sig[], int ndat, float a[], int ia[],
int ma, float **covar, float *chisq, void (*funcs) (float,float[], int))
/*Given a set of data points x[1..ndat], y[1..ndat] with individual standard deviations
sig[1..ndat], use χ2 minimization to fit for some or all of the coefficients a[1..ma] of
a function that depends linearly on a, y =sum(i)( ai × afunci(x)). The input array ia[1..ma]
indicates by nonzero entries those components of a that should be fitted for, and by zero entries
those components that should be held fixed at their input values. The program returns values
for a[1..ma], χ2 = chisq, and the covariance matrix covar[1..ma][1..ma]. (Parameters
held fixed will return zero covariances.)Th e user supplies a routine funcs(x,afunc,ma) that
returns the ma basis functions evaluated at x = x in the array afunc[1..ma].*/
{
void covsrt(float **covar, int ma, int ia[], int mfit);
void gaussj(float **a, int n, float **b, int m);
int i, j, k, l, m, mfit = 0;
float ym, wt, sum, sig2i, **beta, *afunc;
beta = matrix(1, ma, 1, 1);
afunc = vector(1, ma);
for (j = 1; j <= ma; j++)
if (ia[j])
mfit++;
if (mfit == 0)
nrerror("lfit: no parameters to be fitted");
for (j = 1; j <= mfit; j++) { //Initialize the (symmetric)mat rix.
for (k = 1; k <= mfit; k++)
covar[j][k] = 0.0;
beta[j][1] = 0.0;
}
for (i = 1; i <= ndat; i++) {
(*funcs) (x[i], afunc, ma);
ym = y[i];
if (mfit < ma) { //Subtract off dependences on known pieces
for (j = 1; j <= ma; j++) //of the fitting function.
if (!ia[j])
ym -= a[j] * afunc[j];
}
sig2i = 1.0 / SQR(sig[i]);
for (j = 0, l = 1; l <= ma; l++) {
if (ia[l]) {
wt = afunc[l] * sig2i;
for (j++, k = 0, m = 1; m <= l; m++)
if (ia[m])
covar[j][++k] += wt * afunc[m];
beta[j][1] += ym * wt;
}
}
}
for (j = 2; j <= mfit; j++) //Fill in above the diagonal from symmetry.
for (k = 1; k < j; k++)
covar[k][j] = covar[j][k];
gaussj(covar, mfit, beta, 1); //Matrix solution.
for (j = 0, l = 1; l <= ma; l++)
if (ia[l])
a[l] = beta[++j][1]; //Partition solution to appropriate coefficients
*chisq = 0.0;
for (i = 1; i <= ndat; i++) { //Evaluate χ2 of the fit.
(*funcs) (x[i], afunc, ma);
for (sum = 0.0, j = 1; j <= ma; j++)
sum += a[j] * afunc[j];
*chisq += SQR((y[i] - sum) / sig[i]);
}
covsrt(covar, ma, ia, mfit); //Sort covariance matrix to true order of fittin
free_vector(afunc, 1, ma); //coefficients.
free_matrix(beta, 1, ma, 1, 1);
}
In
void lfit( float [], float [], float [], int, float [], int [], int, float**, float*, void (*funcs)(float, float [], int))
"void (*funcs)(float, float [], int)" is the type signature of the function pointer.
If it is in-scope, you can just pass the name of your function (fpoly) in place of "void (*funcs)(float, float [], int)", without parentheses or anything. You can also take its address with the & operator but I believe it's equivalent:
lfit( all_the_other_args, ..., fpoly);
You could also have a local function pointer which holds fpoly:
void (*local_function_pointer_variable)(float, float [], int) = fpoly;
lfit( all_the_other_args, ..., local_function_pointer_variable);
In C the syntax of function pointer types is somehow inconvenient but hopefully you can define a type to hide this to some extent
typedef void (*poly_fitter)(float, float [], int);
poly_fitter function_pointer_var_of_type_poly_fitter = fpoly;
lfit( all_the_other_args, ..., function_pointer_var_of_type_poly_fitter)
If I understand correctly, you want to pass the function poly if so, then just pass the name of the function:
lfit(x, y,...., poly);
the lfit function has many input parameter.
1 of the parameter is address to a function. and that's why we have added * in the definition of that input parameter.
void (*funcs) (float, float[], int))
so when you calling lfit() function you can mention the address the address of your fpoly() function as the input of your lfit() function
the address of void fpoly(float x, float p[], int np) is fpoly or &fpoly
so when you call your function lfit() you can do it in this way:
lfit(x,y,...,fpoly)
or in this way:
lfit(x,y,...,&fpoly)

Resources