The code below uses a recursive function called interp, but I cannot find a way to avoid using global variables for iter and fxInterpolated. The full code listing (that performs N-dimensional linear interpolation) compiles straightforwardly with:
gcc NDimensionalInterpolation.c -o NDimensionalInterpolation -Wall -lm
The output for the example given is 2.05. The code works fine but I want to find alternatives for the global variables. Any help with this would be greatly appreciated. Thanks.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int linearInterpolation(double *, double **, double *, int);
double ** allocateDoubleMatrix(int, int);
double * allocateDoubleVector(int);
void interp(int, int, double *, double *, double *);
double mult(int, double, double *, double *);
/* The objectionable global
variables that I want to get rid of! */
int iter=0;
double fxInterpolated=0;
int main(int argc, char *argv[]){
double *fx, **a, *x;
int dims=2;
x=allocateDoubleVector(dims);
a=allocateDoubleMatrix(dims,2);
fx=allocateDoubleVector(dims*2);
x[0]=0.25;
x[1]=0.4;
a[0][0]=0;
a[0][1]=1;
a[1][0]=0;
a[1][1]=1;
fx[0]=1;
fx[1]=3;
fx[2]=2;
fx[3]=4;
linearInterpolation(fx, a, x, dims);
printf("%f\n",fxInterpolated);
return (EXIT_SUCCESS);
}
int linearInterpolation(double *fx, double **a, double *x, int dims){
double *b, *pos;
int i;
b=allocateDoubleVector(dims);
pos=allocateDoubleVector(dims);
for (i=0; i<dims;i++)
b[i] = (x[i] - a[i][0]) / (a[i][1] - a[i][0]);
interp(0,dims,pos,fx,b);
return (EXIT_SUCCESS);
}
void interp(int j, int dims, double *pos, double *fx, double *b) {
int i;
if (j == dims){
fxInterpolated+=mult(dims,fx[iter],pos,b);
iter++;
return;
}
for (i = 0; i < 2; i++){
pos[j]=(double)i;
interp(j+1,dims,pos,fx,b);
}
}
double mult(int dims, double fx, double *pos, double *b){
int i;
double val=1.0;
for (i = 0; i < dims; i++){
val *= fabs(1.0-pos[i]-b[i]);
}
val *= fx;
printf("mult val= %f fx=%f\n",val, fx);
return val;
}
double ** allocateDoubleMatrix(int i, int j){
int k;
double ** matrix;
matrix = (double **) calloc(i, sizeof(double *));
for (k=0; k< i; k++)matrix[k] = allocateDoubleVector(j);
return matrix;
}
double * allocateDoubleVector(int i){
double *vector;
vector = (double *) calloc(i,sizeof(double));
return vector;
}
Thanks for the comments so far. I want to avoid the use of static. I have removed the global variable and as suggested tried parsing with the iter variable. But no joy. In addition I am getting a compile warning: "value computed is not used" with reference to *iter++; What am I doing wrong?
void interp(int j, int dims, double *pos, double *fx, double *b, int *iter) {
int i;
if (j == dims){
fxInterpolated+=mult(dims,fx[*iter],pos,b);
*iter++;
return;
}
for (i = 0; i < 2; i++){
pos[j]=(double)i;
interp(j+1,dims,pos,fx,b,iter);
}
}
There are two approaches I would consider when looking at this problem:
Keep the state in a parameter
You could use one or more variables that you pass to the function (as a pointer, if necessary) to keep the state across function calls.
For instance,
int global = 0;
int recursive(int argument) {
// ... recursive stuff
return recursive(new_argument);
}
could become
int recursive(int argument, int *global) {
// ... recursive stuff
return recursive(new_argument, global);
}
or sometimes even
int recursive(int argument, int global) {
// ... recursive stuff
return recursive(new_argument, global);
}
Use static variables
You can also declare a variable in a function to be preserved across function calls by using the static keyword:
int recursive(int argument) {
static int global = 0;
// ... recursive stuff
return recursive(argument);
}
Note that because of the static keyword, global = 0 is only set when the program starts, not every time the function is called, as it would be without the keyword. This means that if you alter the value of global, it would keep this value the next time the function is called.
This method can be used if you only use your recursive function once during your program; if you need to use it multiple times, I recommend that you use the alternative method above.
A solution is to use statics and then to reset the variables on the first call, via a flag that I call initialise. That way you can choose to have the variables reset or not.
double interp(int j, int dims, double *pos, double *fx, double *b, int initialise) {
static double fxInterpolated = 0.0;
static int iter = 0;
int i;
if (initialise){
fxInterpolated = 0.0;
iter = 0;
}
.....
......
}
Related
I'm trying to write a program that multiplies two different complex numbers (b*c), stores the result in a prints out the result. For the purposes of keeping it simple here I've only decided to use 10 numbers and set all the imaginary and real values for b and c to the numbers 0 through 9.
First I create arrays that will contain the real and imaginary parts of the complex numbers a, b and c. Next I declare the real and imaginary part of a to be zero since I don't know these yet. To find these, I have a function named multiply that computes the real and imaginary parts of a.
Finally, in my main method I loop through all the arrays, generate values 0-9, use multiply to populate the arrays of a (as_re and as_im) containing the real and imaginary values of a, then simply printing all of these entries out.
However I only get: The product is 0 + 0i on every iteration. This has to mean that my multiply function does not update the values of a_re and a_im. Can anyone help me understand why?
My code is below:
#include <stdio.h>
#include <stdlib.h>
void multiply(int c_re, int c_im, int a_re, int a_im, int b_re, int b_im);
int as_re[10];
int as_im[10];
int bs_re[10];
int bs_im[10];
int cs_re[10];
int cs_im[10];
int a_re = 0;
int a_im = 0;
int main(){
for (int i = 0; i < 10; i++){
bs_re[i] = i;
bs_im[i] = i;
cs_re[i] = i;
cs_re[i] = i;
multiply(cs_re[i], cs_im[i], as_re[i], as_im[i], bs_re[i], bs_im[i]);
as_re[i] = a_re;
as_im[i] = a_im;
printf("The product is %d + %di\n", as_re[i], as_im[i]);
}
}
void multiply(int c_re, int c_im, int a_re, int a_im, int b_re, int b_im){
a_re = c_re * b_re - c_im * b_im;
a_im = c_re * b_im + c_im * b_re;
}
You don't need to pass global variables as parameters. If you declare a parameter or local variable with the same name as the global variable then it will hide the global variable in that function.
Removed the global variables which were included as parameters for your function.
#include <stdio.h>
#include <stdlib.h>
void multiply(int c_re, int c_im, int b_re, int b_im);
int as_re[10];
int as_im[10];
int bs_re[10];
int bs_im[10];
int cs_re[10];
int cs_im[10];
int a_re = 0;
int a_im = 0;
int main(){
for (int i = 0; i < 10; i++){
bs_re[i] = i;
bs_im[i] = i;
cs_re[i] = i;
cs_re[i] = i;
multiply(cs_re[i], cs_im[i], bs_re[i], bs_im[i]);
as_re[i] = a_re;
as_im[i] = a_im;
printf("The product is %d + %di\n", as_re[i], as_im[i]);
}
}
void multiply(int c_re, int c_im, int b_re, int b_im){
a_re = c_re * b_re - c_im * b_im;
a_im = c_re * b_im + c_im * b_re;
}
I am a beginner for R extensions. I have problems in understanding the usage of .C interface. Take this code as an example:
void cconv(int *l, double *x, int *n, double *s)
{
double *y = x + (*n - *l), *z = x + *l, *u = x;
while ( u < y)
*s += *u++ * *z++;
}
In this code, I think the arguments should be called as *l and *x probably because l and x are defined in R environment and are transferred to the .C interface, and please correct it if I am wrong. However, inside the function cconv, why double *y are defined rather than double y, and why pointer and int variable are mixed in defining *y. At last, I saw in other codes that if R need call .C(...) to return a vector result s, then double *y is defined as an argument in the C function, but calculated as s inside the C function, like:
void xfunc(int *l, double *x, double *s){
int i,j;
for (i = 0, i < *l, i ++){
s[i] = x;
}
}
I'm trying to implement some elementary linear algebra routines in MEX files in C for practice, and I'm stuck with dot products. Here's what I have so far:
#define char16_t UINT16_T //shenanigans with the compiler
#include "mex.h"
void dotProd(double *a, double *b, double z, mwSize n)
{
mwSize i;
for(i=0;i<n;i++){
z+=a[i] * b[i];
}
}
/* The gateway function */
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
double z=0; //Output scalar
double *b, *a; //Input vectors
int n;
a = mxGetPr(prhs[0]); //pointer to a
b = mxGetPr(prhs[1]); //pointer to b
n = mxGetM(prhs[0]);
// Create output
plhs[0] = mxCreateDoubleScalar(z);
dotProd(a,b,z,(mwSize)n);
}
The problem is that when I test this code:
a=rand(2,1);
b=rand(2,1);
z=dotProd(a,b);
I get:
z=0
even though a and b are not orthogonal. I verified this with the MATLAB dot() function. I've picked over the code and can't quite seem to find where I'm going awry. Some suggestions would be appreciated.
Thank you.
That's because you're not returning the result of the dot product. z makes a local copy of itself in your dotProd function. Even though you are making modifications to z, those changes are not reflected because the scope of z inside dotProd is of local scope. You need to update your function that computes the dot product to return something. In addition, you are setting the output of the function before computing the dot product.
As such, do this:
// Change - Remove z as input
double dotProd(double *a, double *b, mwSize n)
{
mwSize i;
double z = 0.0; // Initialize z to 0.0
for(i=0;i<n;i++){
z+=a[i] * b[i];
}
return z; // Return z
}
Then simply do:
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
double z; //Output scalar - Change - don't need to initialize
double *b, *a; //Input vectors
int n;
a = mxGetPr(prhs[0]); //pointer to a
b = mxGetPr(prhs[1]); //pointer to b
n = mxGetM(prhs[0]);
// Create output
z = dotProd(a,b, (mwSize)n); // Change - returning output
plhs[0] = mxCreateDoubleScalar(z);
}
If you insist on changing z in the function and not letting the function return anything, you'll need to pass a pointer to z and change what z refers to. In other words, you would do this:
// Change - Make z point to a double
void dotProd(double *a, double *b, double *z, mwSize n)
{
mwSize i;
for(i=0;i<n;i++){
*z+=a[i] * b[i]; // Change - Refer to pointer
}
}
Now, do:
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
double z = 0.0;
double *b, *a; //Input vectors
int n;
a = mxGetPr(prhs[0]); //pointer to a
b = mxGetPr(prhs[1]); //pointer to b
n = mxGetM(prhs[0]);
// Create output
dotProd(a,b, &z, (mwSize)n); // Change - Pass pointer of z to function
plhs[0] = mxCreateDoubleScalar(z);
}
BTW, you still need to call dotProd before you set the output. That's why you kept getting 0 because z was 0 before you set the output, then you called dotProd after.
I wish to do exactly what rcond does in MATLAB/Octave using LAPACK from C.
The MATLAB manual tells me dgecon is used, and that is uses a 1-based norm.
I wrote a simple test program for an extremely simple case; [1,1; 1,0]
For this input matlab and octave gives me 0.25 using rcond and 1/cond(x,1), but in the case using LAPACK, this sample program prints 0.0. For other cases, such as identity, it prints the correct value.
Since MATLAB is supposely actually using this routine with success, what am I doing wrong?
I'm trying to decipher what Octave does, with little success as its wrapped in
#include <stdio.h>
extern void dgecon_(const char *norm, const int *n, const double *a,
const int *lda, const double *anorm, double *rcond, double *work,
int *iwork, int *info, int len_norm);
int main()
{
int i, info, n, lda;
double anorm, rcond;
double w[8] = { 0,0,0,0,0,0,0,0 };
int iw[2] = { 0,0 };
double x[4] = { 1, 1, 1, 0 };
anorm = 2.0; /* maximum column sum, computed manually */
n = 2;
lda = 2;
dgecon_("1", &n, x, &lda, &anorm, &rcond, w, iw, &info, 1);
if (info != 0) fprintf(stderr, "failure with error %d\n", info);
printf("%.5e\n", rcond);
return 0;
}
Compiled with cc testdgecon.c -o testdgecon -llapack; ./testdgecon
I found the answer to me own question.
The matrix is must be LU-decomposed before it is sent to dgecon. This seems very logical since one often wants to solve the system after checking the condition, in which case there is no need to decompose the matrix twice. The same idea goes for the norm which is computed separately.
The following code is all the necessary parts the compute the reciprocal condition number with LAPACK.
#include "stdio.h"
extern int dgecon_(const char *norm, const int *n, double *a, const int *lda, const double *anorm, double *rcond, double *work, int *iwork, int *info, int len);
extern int dgetrf_(const int *m, const int *n, double *a, const int *lda, int *lpiv, int *info);
extern double dlange_(const char *norm, const int *m, const int *n, const double *a, const int *lda, double *work, const int norm_len);
int main()
{
int i, info, n, lda;
double anorm, rcond;
int iw[2];
double w[8];
double x[4] = {7,3,-9,2 };
n = 2;
lda = 2;
/* Computes the norm of x */
anorm = dlange_("1", &n, &n, x, &lda, w, 1);
/* Modifies x in place with a LU decomposition */
dgetrf_(&n, &n, x, &lda, iw, &info);
if (info != 0) fprintf(stderr, "failure with error %d\n", info);
/* Computes the reciprocal norm */
dgecon_("1", &n, x, &lda, &anorm, &rcond, w, iw, &info, 1);
if (info != 0) fprintf(stderr, "failure with error %d\n", info);
printf("%.5e\n", rcond);
return 0;
}
I am trying to calculate the exponent of a number. When I do everything as int I get the correct result, but the output must be float, when I try to convert with %f in printf() I get 0, when I use %d I get the correct result. I cannot change the main() portion of the program, I can only alter the *powerArgs() function. The program input is 3, 5.
Full disclosure, this is part of a school assignment. I am not asking for complete code. I would appreciate a more general answer showing me what I am forgetting, possibly what area I should study more to find the answer myself.
#include <stdio.h>
#include <stdlib.h>
int *powerArgs(int *pA, int *pB);
/* MAIN */
int main(int argc, char **argv)
{
if (argc != 3)
{
printf("?Invalid number of arguments\n");
system("pause");
exit(1);
}
int parmA = atoi(argv[1]);
int parmB = atoi(argv[2]);
int idx;
/* Part C: Raise parmA to the power of parmB. Return pointer to the result */
/* Reset the original values after we print the result */
printf("%d raised to the %d power is %0.1f\n", parmA, parmB, *powerArgs(&parmA, &parmB));
printf("\n");
system("pause");
exit(0);
}
int *powerArgs(int *pA, int *pB)
{
int idx, result = *pA;
for (idx = 1; idx < *pB; idx++)
{
result *= *pA;
}
return &result;
}
float and int convert automatically in C - you can assign either one to the other, and the only thing to watch out for is that if you assign too large a float to an int, then you get undefined behavior (or possibly an unspecified result, I forget. Either way it's not good).
So, your powerArgs function can just be:
float powerArgs(float a, int b) {
// do some stuff and return a value
}
Then you can call it as powerArgs(parmA, parmB), even though parmA is an int.
Edit: if you can't change the call parameters, you can do this instead
float powerArgs(int *a, int *b) {
float base = *a;
int exponent = *b;
...
}
If your professor has really set you code where the function is called as *powerArgs(int *a, int *b), then your professor is a menace. There is no earthly reason why an exponentiation function should return a pointer to a float. There's an ugly workaround you could use:
float *powerArgs(int *a, int *b) {
static float result;
...
result = /* the result of the calculation */;
return &result;
}
The problem with this is, all calls to powerArgs share the same object result. static stops it from ceasing to exist at the end of the call, but the sharing will introduce problems in the long run. It is not good practice to do this, but it might be the best solution to the problem you've been set.
C++ sneaky solution:
struct FloatWrapper {
float value;
float operator*() {
return value;
}
FloatWrapper(float f) : value(f) {}
};
FloatWrapper powerArgs(int *a, int *b) {
...
float result = /* whatever */;
...
return result;
}
This returns an object of class FloatWrapper, by value, and FloatWrapper overloads the * operator. This means that *powerArgs(...) evaluates to the float that the function should have returned by value in the first place, without needing a pointer to any special storage place.
By the way, you might want to check what your function does when parmB is 0.
First, your int *powerArgs(int *pA, int *pB) function returns the address of a local variable, which results in undefined behavior. Use the following instead:
int powerArgs(int *pA, int *pB)
{
int idx, result = *pA;
for (idx = 1; idx < *pB; idx++)
{
result *= *pA;
}
return result;
}
Next, if you want to convert to float, you shouldn't do that in the call to printf(), but rather convert the value to float before the call like so:
printf("%d raised to the %d power is %0.1f\n", parmA, parmB, (float)powerArgs(&parmA, &parmB));
When a function terminates, all its local variables cease to exist (and their addresses point to garbage). To please your teacher who came up with that very awkward interface, you have to find a way to keep an object alive after the function exists.
You have, at least, 3 options:
a) reuse one of the input parameters
b) use a global variable
c) use a static variable
option a)
int *powerArgs(int *pA, int *pB) {
/* calculate */
*pA = CALCULATED_VALUE;
return pA;
}
option b)
int global_power;
int *powerArgs(int *pA, int *pB) {
/* calculate */
global_power = CALCULATED_VALUE;
return &global_power;
}
option c)
int *powerArgs(int *pA, int *pB) {
static int static_power;
/* calculate */
static_power = CALCULATED_VALUE;
return &static_power;
}
Neither of these "solutions" is good; the least bad is option c)