I am trying to execute the following code
static double** updateA(double f_x0,double f_x1,double f_x2){
double a[3][3] = {{f_x0*f_x0, f_x0, 1},{f_x1*f_x1, f_x1, 1},{f_x2*f_x2, f_x2, 1}};
return a;
}
static double** updateAc (double f_x0,double f_x1,double f_x2, double x0,double x1,double x2){
double ac[3][3] = {{f_x0*f_x0, f_x0, x0},{f_x1*f_x1, f_x1, x1},{f_x2*f_x2, f_x2, x2}};
return ac;
}
static double det3x3 (double** a){
return (a[0][0]*((a[1][1]*a[2][2]) - (a[2][1]*a[1][2])) - a[0][1]*(a[1][0]
* a[2][2] - a[2][0]*a[1][2]) + a[0][2]*(a[1][0]*a[2][1] - a[2][0]*a[1][1]));
}
static double newx2 (double f_x0,double f_x1,double f_x2, double x0,double x1,double x2){
double **ac = updateAc(f_x0, f_x1, f_x2, x0, x1, x2);
double **a = updateA(f_x0, f_x1, f_x2);
double c = det3x3(ac)/det3x3(a);
return c;
}
However it is not working, it compiles with the following warning:
incompatible pointer types returning 'double [3][3]' from
a function with result type 'double **'
But when I try to execute the code it doesn't work. I am using gcc as compiler.
Anyone can help me?
Thank you in advance,
Lucas
This is the struct method.
Only works for fixed sizes (in this case : 3*3)
the sizes are hard-coded
the caller (in this case main() allocates, and passes a pointer.
#include <stdio.h>
struct nine {
double data[3][3];
};
void do_it(struct nine *p)
{
p->data[0][0] = 0.0;
// ..
}
int main(void)
{
struct nine this9 = {{{1,2,3},{4,5,6},{7,8,9}}};
do_it( &this9 );
printf("%lf\n", this9.data[0][0] );
return 0;
}
Related
I wrote a function pointer that has all void* so that it can be used for any numeric value
int
float
double.
But it is working only for the int addition function
For float and double addition functions, it throws compile time error.
Why is that so ?
If you uncomment the last two printf lines, you would receive error
#include<stdio.h>
int int_add(int x, int y) {
return x + y;
}
float float_add(float x, float y) {
return x + y;
}
double double_add(double x, double y) {
return x + y;
}
void* do_operation(void* (*op)(void*, void*), void* x, void* y) {
return op(x, y);
}
void main(void) {
printf("Sum= %d\n",(int*) do_operation(int_add, 1, 2));
/*printf("Sum= %f\n",(float*) do_operation(float_add, 1.20, 2.50));*/
/*printf("Sum= %lf\n",(double*) do_operation(double_add, 1.20, 2.50));*/
}
void * is a pointer type. You're not passing pointers, you're passing values, so that's not going to compile. It accidentally "works" for int because pointers themselves are represented as integers by most C compilers.
If you pass pointers to int, float, and double instead of the int, float, and double themselves, you will avoid that compiler error. You'd also need to change int_add and friends to take pointers, and you'd have to make sure you dereferenced the pointers before using them. You'll also have to return pointers, which means you'll have to malloc some memory on the heap, because the stack memory assigned to your local variables will be invalid once your function exits. You'll then have to free it all later... in the end, this is going to result in something considerably more complicated than the problem it appears you are trying to solve.
I have to ask why you are trying to do this? C is really not the best language for this type of pattern. I'd suggest just calling the int_add, float_add, etc. functions directly instead of trying to abstract them in this way.
So as per #charles-srstka suggestion I rewrote the code and then it worked as I wanted
#include<stdio.h>
#include<stdlib.h>
int* int_add(int *x, int *y) {
int *c = (int *)malloc(sizeof(int));
*c = *(int*)x + *(int*)y;
return c;
}
float* float_add(float *x, float *y) {
float *c = (float*)malloc(sizeof(float));
*c = *(float*)x + *(float*)y;
return c;
}
void* do_operation(void* (*op)(void*, void*), void* x, void* y) {
return op(x, y);
}
void main(void) {
int a = 1;
int b = 2;
int *c;
c = do_operation(int_add, &a, &b);
printf("%d\n",*c);
free(c);
float x = 1.1;
float y = 2.2;
float *z;
z = do_operation(float_add, &x, &y);
printf("%f\n",*z);
free(z);
}
I'm getting two errors :
Initializer element is not constant in the 2nd last line below in the code
Expected declaration specifiers '...' before string constant in the last line
#define K 10.0
typedef double (*TFunc)(double);
double alpha,x;
double f(double x)
{
return x*x;
}
double derive(TFunc f, const double x0)
{
const double dx = 1.0e-6; // or similar
double dy = f(x0+dx)-f(x0-dx);
return dy/(2.*dx);
}
double fp = derive(f, K);
printf("%lf\n",fp);
You should add any block of code you want to run first during the execution in to a main function. In your case, you should put the code:
double fp = derive(f, K);
printf("%lf\n",fp);
into a main function
int main() {
double fp = derive(f, K);
printf("%lf\n",fp);
}
Make sure you include the stdio.h library at the beginning of file since you are using printf function. Also, make sure you define constant K somewhere. I updated your code according to my suggestion above and it compiled without errors or warnings:
#include <stdio.h>
typedef double (*TFunc)(double);
double alpha,x;
double f(double x)
{
return x*x;
}
double derive(TFunc f, const double x0)
{
const double dx = 1.0e-6; // or similar
double dy = f(x0+dx)-f(x0-dx);
return dy/(2.*dx);
}
int main() {
const double K = 1.0;
double fp = derive(f, K);
printf("%lf\n",fp);
}
I'm trying to use GCC's vector extensions, the exact code that I tried is:
typedef float Vector4 __attribute__ ((vector_size (16)));
void defVector(Vector4* v, float x,float y,float z,float w){
v[0] = x;
v[1] = y;
v[2] = z;
v[3] = w;
}
int main(int argc, char* argv){
Vector4 a;
defVector(&a, 1, 2, 3, 4);
}
and keep getting errors:
incompatible types when assigning to type ‘Vector4 {aka __vector(4) float}’ from type ‘float’
v[0] = x;
Can't dereference it too or I get another error.
I would like to not copy the entire thing to the function stack every time I use it, and it's a necessity to make pointers to the return values like
int someFunc(Vector4 v, Vector4* r){
...
r[0] = return_value;
return 0;
}
I tried everything I know to access the values inside the funtion.
What I'm missing here?
Based on the OP's example in which a local function gets a "vector-extension" pointer:
#include <stdio.h>
#include <stdint.h>
typedef float Vector4 __attribute__ ((vector_size (16)));
void defVector(Vector4 *v,float a, float b);
void defVector(Vector4 *v,float a, float b){
v[0] = *(Vector4*)&a;
v[1] = *(Vector4*)&b;
a = *(float*)&v[0] + 1.2;
b = *(float*)&v[1] + 2.1;
printf("%f,%f,%u",a,b,\
(uint32_t)sizeof(Vector4)/(uint32_t)sizeof(float));
}
int main(void) {
static Vector4 vectorA;
static float x1 = 3.4;
static float x2 = 4.3;
defVector(&vectorA,x1,x2);
}
This code will print (demo): 4.6,6.4,4 , so the value of two float were assigned to two units (being the number of units sizeof(Vector4)/sizeof(float)) of a Vector4 type variable.
I doing integration of a complex function using gsl library in C programming language. In this code I had to declare two variables using pointer that I have done successfully. But I am facing a problem when I pass these variables in main function.
Please help me out.
My code is being written here:
struct har{
double t;
double k;
double x;
};
#include"str.h"
struct har H1( void * params, float q , int p )
{
struct har *p_params = (void *)params;
float mu=2;
double x =p_params ->x ;
double t = p_params -> t;
double k = p_params -> k;
//printf("%d",k);
struct har H1 = {x*cos(t*x)/(pow((mu*t*k),2)+pow(x,2))};
return H1;
}
double H (double x,void * params )
{
double e;
double t = *(double *) params;
//printf("%f\n",t);
//struct har t1,z;
//double t = z.params ->t1;
double H = (pow(e,-x)/x) ;//I(x,&t)*(sin(x*t));
return H;
}
#include<stdio.h>
#include <math.h>
#include <gsl/gsl_integration.h>
#include"H.h"
#include"H1.h"
int
main (void)
{
gsl_integration_workspace * w
= gsl_integration_workspace_alloc (10000);
struct har t,k;
double x, qtr, qbartr, qdottr, qddotr,q7r, qatr, qbtr, qt1r, error;
double expected = -4.0;
double a1 = 1e-14;
double a= 150;//150;
double pi = 3.141;
double b = 1.05263;
double mu = (2*pi)/b;
double q0=0;
double p0=6.5;
double om=7.07;
double tau=0.141;
double gamma = 0.180;
for(int m=2; m<4; m++)
{
float t = 4.14937*(m-1);
gsl_function qt;
qt.function = &H;
qt.params =&t;
gsl_integration_qags (&qt, a1, a, 0,1e-7, 10000, w, &qtr, &error);
// printf ("qtresult = % .18f\n\n", qtr);
for(int k=1; k<=2; k++)
{
{
struct har item = {x,t,k};
struct har *p_params = &item;
double gama=gamma/((mu*k*tau)+1);
// printf("gama = % .18f\n", gama);
gsl_function qt1;
qt1.function = &H1;
qt1.params = &p_params;
// qt1.params = &k;
gsl_integration_qags (&qt1, a1, a, 0,1e-7, 10000, w, &qt1r, &error);
printf("qt1result= % .18f\n", qt1r);
}
}
gsl_integration_workspace_free (w);
return 0;
}
In above code I had four file by namely code.c, str.h, H1.h and H.h. Where H1 and H contains two user defined functions and str is a file for structure and code.c is my main to compile.
Thanks for your time and observation.
Regards
Ramesh
The field qt1.function has type double (*)(double, void *). The function H1 which you attempt to assign to this field has type struct har (*)( void *, float, int).
These types are incompatible as the number of arguments, the types of the arguments, and the return type are all different. As it is right now, you have two parameters called p and q that are never being used. Also, the struct har you construct as a return value doesn't even set all the fields, just the first one, so why are you even returning a struct?
In order for H1 to work with gsl_function, is must accept a double and a void * and return a double. The x value corresponds to the double that is passed in, so you don't need that in your struct. Since you're also only building a single value to return, that's what you return.
struct har{
double t;
double k;
};
double H1( double x, void *params)
{
struct har *p_params = params; // no need to cast to/from void *
float mu=2;
double t = p_params->t;
double k = p_params->k;
return x*cos(t*x)/(pow((mu*t*k),2)+pow(x,2));
}
Also, you're not setting the values of qt1 properly:
qt1.params = &p_params;
Since p_params is a struct har *, its address is a struct har **. Your function however is expecting a struct har * to be passed in. So change this to the address of the struct, not the address of a pointer pointing to it:
qt1.params = &item;
You also have a mismatch when you set qt.params. You're giving it a float *, but your function H is expecting a double *. Just change the type of t to match:
double t = 4.14937*(m-1);
We got this typedef in a homework program. As a programmer noob, I didn't see anything like this before. Does this mean that any DoubleFunction2D is actually a 2-tuple of (double, double)?
Program:
typedefs:
typedef double (*DoubleFunction) (double);
typedef double (*DoubleFunction2D) (double, double);
typedef double (*DoubleFunction3D) (double, double, double);
Example usage
(my WIP solution to a task, not yet complied/tested. Inside):
double expf2D(double x, double y)
{
double r = sqrt(pow(x,2) + pow(y,2));
return my_expf(r);
}
double DiskMonteCarloIntegrator(DoubleFunction2D f, double r1, double r2, int N)
{
bool is_inside_ring(double x, double y){
return is_inside_ellipse(x, y, r2/2, r2/2) && !(is_inside_ellipse(x, y, r1/2, r1/2));
}
int i=0;
double x, y, sum = 0;
while(i < N)
{
x = RandomDouble(-1*r1, r1);
y = RandomDouble(-1*r1, r1);
if(is_inside_ring(x, y))
{
sum += f(x, y);
i++;
}
}
double avg = sum / N;
double integral = avg * (pow(r2, 2) - pow(r1, 2)) * M_PI;
return integral;
}
//extract
void main(int argc, char *argv[]){
DiskMonteCarloIntegrator(expf2D, 1.0, 2.0, 1000000);
}
There are no tuples here (in fact, there are no "tuples" in the C programming language).
typedef double (*DoubleFunction) (double);
means DoubleFunction is a pointer to a function that takes a double and returns a double.
typedef double (*DoubleFunction2D) (double, double);
means DoubleFunction2D is a pointer to a function that takes two double values and returns a double.
typedef double (*DoubleFunction3D) (double, double, double);
means DoubleFunction3D is a pointer to a function that takes three double values and returns a double.