What could be the expression "double (f)(double)" in C mean - c

Like I already wrote in the title I have the problem that I need to understand what double (f)(double) could mean in C. The whole methode header looks like this:
Bmp* drawGraph(double (f)(double),double minX,double maxX)
It's for a university project an my professor likes to be absent or not reachable through email or other ways of communication.
I think the name and so the propose of the methode is pretty much self-explaining.
In the letter of information to this method was said that "f" should be a function but I don't know what kind of parameter I should give the method in that case.
Bmp* drawGraph(double (f)(double),double minX,double maxX)
{
double height = f(maxX);
Bmp* bmp = newBmp(maxX, f(maxX) * 2);
background(bmp, BLACK);
//Hier zeichne ich das Koordinatensystem
//in seiner minimalistischten Form
drawLine(bmp, GREEN, 0, f(maxX), maxX, f(maxX));
drawLine(bmp, GREEN, 0, 0, 0, f(maxX) * 2);
for(double d = minX; d < maxX; d += 0.1)
{
drawLine(bmp, RED, d, f(d) + height, d + 0.1, f(d + 0.1) + height);
}
return bmp;
}

double (f)(double)
f is a parameter of function type: a function that has a double parameter and that returns a double value.
For example:
double foo(double a)
{
return a + 42.0;
}
The parameter is adjusted (and therefore the declaration is equivalent) to a pointer to a function that has a double parameter and that returns a double value.
double (*f)(double)
So these declarations are all equivalent:
void bla(double (f)(double));
void bla(double f(double));
void bla(double (*f)(double));

Related

unused result error, if condition c

I hope this is not a banal question but I just can't find the problem in my code. I keep getting the error message "expression result unused" and "relational comparison result unused" when trying to compile my code.
The problem is with the following function:
bool is_inside(double x, double y){
if(sqrt(pow((x-0,5),2)+pow((y-0,5),2))<0,5){
return true;
}
return false;
}
which gets called in this function:
void estimate_func(unsigned long nsteps, unsigned long nstep_print){
unsigned long i;
unsigned long in_circle=0;
double x,y;
double curr_pi,curr_s;
for(i=0;i<nsteps;i++){
x=drand48();
y=drand48();
if(is_inside(x,y)){ // call!!!
in_circle++;
}
if(!(i%(nstep_print+1))){
curr_pi=(double) 4*(in_circle/(i+1));
curr_s=4*(sqrt((curr_pi/4)*(1-curr_pi/4)/(double)(i+1)));
printf("\t%lu\t%.6lf\t%.6lf\t%.6lf\n", i+1, curr_pi ,
curr_pi-M_PI, curr_s);
}
}
}
Has anyone an idea what I am doing wrong?
The problem is, essentially, that C source code is not locale-aware. Clearly, in your locale, the comma is used as the decimal separator, so you write &half; as 0,5. C doesn't do it that way. It always uses the period as the decimal separator, so &half; is always 0.5.
The comma does something different in C. It's actually a distinct operator known as the comma operator. It evaluates both its operands, discards the result of the first, and returns the result of the second. So, taking into account the operator precedence, what you currently have is seen by the compiler as:
if((sqrt(pow(((x-0),5),2)+pow(((y-0),5),2))<0),5){
which, evaulating the inner comma operators, gives:
if((sqrt(pow(5,2)+pow(5,2))<0),5){
and evaluating the outer comma operator reduces to:
if(5){
which the compiler can tell is trivially true, and is therefore warning you about it. The return false block will never be reached.
The correct way to write the code would be:
bool is_inside(double x, double y){
return (sqrt(pow((x - 0.5), 2) + pow((y - 0.5), 2)) < 0.5);
}
Notice that I have also elided the pointless if statement. This does exactly the same thing, and is easier to read. A comparison always returns either 1 (true) or 0 (false) in C, so its result can be used directly as a Boolean.
I've also added spaces, because let that code breathe!
What maybe you want to do is this:
bool is_inside(double x, double y){
if(sqrt(pow((x-0.5),2)+pow((y-0.5),2))<0.5){
return true;
}
return false;
}
Change the , to . if you want to represent floating point numbers (real numbers)
Just refactoring your code a little bit:
bool is_inside(double x, double y){
return sqrt(pow((x-0.5),2) + pow((y-0.5),2)) < 0.5); // changing , to .
}
void estimate_func(unsigned long nsteps, unsigned long nstep_print){
unsigned long i, in_circle=0;
double x, y, curr_pi, curr_s;
for(i = 0; i < nsteps; i++){
x = drand48();
y = drand48();
if(is_inside(x,y)) in_circle++;
if(!(i % (nstep_print + 1))){
curr_pi = (double) 4 * (in_circle / (i + 1));
curr_s = 4 * (sqrt((curr_pi / 4) * (1 - curr_pi / 4) / (double)(i + 1)));
printf("\t%lu\t%.6lf\t%.6lf\t%.6lf\n", i + 1, curr_pi ,
curr_pi - M_PI, curr_s);
}
}
}
Always try as much as possible to reduce the number of lines in your code. Beautiful code is short and concise. Check out these exercises http://divostar.com/learn-c

Removing a switch-case in a function called from a loop

I have a function called blend_pixels() whose task is to blend a single pixel onto another pixel according to the specified blending mode. That function is in turn called by pretty much any function that wants to draw anything.
The problem is that function is called for every single pixel, that means it's called tens of millions of times a second, and it contains a switch-case statement going through all possible blending modes until it finds the right one.
Obviously this is somewhat slower than calling a function that directly does the desired operations, and that's the problem I'm trying to fix. The parent functions that call blend_pixels() usually just pass on the blending mode that they themselves received as an argument once called, so I can't just have them called a small function that would only do one blending mode. But the choice only needs to be done once for every call of the parent function (the parent functions operate on a lot of pixels per call whereas blend_pixels() is called for every single pixel, in a loop going through all the necessary pixels).
The function looks like this:
void blend_pixels(lrgb_t *bg, lrgb_t fg, int32_t p, const int mode)
{
int32_t r, g, b;
switch (mode)
{
case SOLID:
*bg = fg;
break;
case ADD:
r = (fg.r * p >> 15) + bg->r; if (r>ONE) bg->r = ONE; else bg->r = r;
g = (fg.g * p >> 15) + bg->g; if (g>ONE) bg->g = ONE; else bg->g = g;
b = (fg.b * p >> 15) + bg->b; if (b>ONE) bg->b = ONE; else bg->b = b;
break;
case SUB:
r = -(fg.r * p >> 15) + bg->r; if (r<0) bg->r = 0; else bg->r = r;
g = -(fg.g * p >> 15) + bg->g; if (g<0) bg->g = 0; else bg->g = g;
b = -(fg.b * p >> 15) + bg->b; if (b<0) bg->b = 0; else bg->b = b;
break;
case MUL:
... // you get the idea
}
}
and is called in this kind of way:
void parent_function(lrgb_t *fb, int w, int h, lrgb_t colour, ... int blendingmode)
{
...
for (iy=y0; iy<y1; iy++)
for (ix=x0; ix<x1; ix++)
{
p = some_weighting_formula();
blend_pixels(&fb[iy*w+ix], colour, p, blendingmode);
}
}
which itself might be called like:
parent_function(fb, w, h, orange, ... /*whatever*/, ADD);
"ADD" being an integer from an enum
So clearly any switch-case to pick the blending algorithm should be done outside of parent_function's loops. But how?
You can do this with function pointers.
First define a typedef for your function pointer:
typedef void (*blend_function)(lrgb_t *, lrgb_t, int32_t);
Then break out each part of blend_pixels into its own function, each with identical parameters and return type as the typedef:
void blend_pixels_add(lrgb_t *bg, lrgb_t fg, int32_t p)
...
void blend_pixels_sub(lrgb_t *bg, lrgb_t fg, int32_t p)
...
void blend_pixels_mult(lrgb_t *bg, lrgb_t fg, int32_t p)
...
Then in your parent function, you can assign a variable of the function pointer type, and assign it the address of the function you want to use:
void parent_function(lrgb_t *fb, int w, int h, lrgb_t colour, ... int blendingmode)
{
...
blend_function blend;
switch (blendingmode)
{
case ADD:
blend = blend_pixels_add;
break;
case SUB:
blend = blend_pixels_sub;
break;
...
}
for (iy=y0; iy<y1; iy++)
for (ix=x0; ix<x1; ix++)
{
p = some_weighting_formula();
blend(&fb[iy*w+ix], colour, p);
}
}
Addressing your concern that "and it contains a switch-case statement going through all possible blending modes until it finds the right one.", this is probably not what really happens.
Switch statements are generally compiled into what is called a jump table. In a jump table, the code does not step through all of the cases looking for the correct one, instead the argument of the switch() statement is used as the index in an array of addresses. Something like:
jump_table[SOLID] -> case SOLID address
jump_table[ADD] -> case ADD address
...
So, in this sort of implementation, a switch statement that is considering many, many values should be just as fast as a hand-coded function pointer solution because that is essentially what the compiler builds.

C - Haversine formula slightly off

My output seems to be slightly off when calculating the distance between two lat/lon coordinates and I can't seem to work out why. Below is my code (implementation of Haversine formula)
float calcDistance(double latHome, double lonHome, double latDest, double lonDest) {
double pi = 3.141592653589793;
int R = 6371; //Radius of the Earth
latHome = (pi/180)*(latHome);
latDest = (pi/180)*(latDest);
double differenceLon = (pi/180)*(lonDest - lonHome);
double differenceLat = (pi/180)*(latDest - latHome);
double a = sin(differenceLat/2) * sin(differenceLat/2) +
cos(latHome) * cos(latDest) *
sin(differenceLon/2) * sin(differenceLon/2);
double c = 2 * atan2(sqrt(a), sqrt(1-a));
double distance = R * c;
printf("%f\n", distance);
return distance;
}
Input: 38.898556 -77.037852 38.897147 -77.043934
Output: 0.526339
Supposed to get 0.5492
The only thing I can think of (and if fixed gives the expected result) is the fact that you overwrite the local parameters latHome and latDest (but probably should use the original ones when calculating differenceLon and differenceLat above a). Use a different name for those, like latHomeTmp, then calculate a with the new ones, and it will work, like:
double latHomeTmp = (pi/180)*(latHome);
double latDestTmp = (pi/180)*(latDest);
double a = sin(differenceLat/2.) * sin(differenceLat/2.) +
cos(latHomeTmp) * cos(latDestTmp) *
sin(differenceLon/2.) * sin(differenceLon/2.);
In general it is a good idea to keep the parameters passed to a function immutable, to avoid situations like this one (of course, not a set in stone rule, but I usually obey it).

C array of functions

I have a problem with a series of functions. I have an array of 'return values' (i compute them through matrices) from a single function sys which depends on a integer variable, lets say, j, and I want to return them according to this j , i mean, if i want the equation number j, for example, i just write sys(j)
For this, i used a for loop but i don't know if it's well defined, because when i run my code, i don't get the right values.
Is there a better way to have an array of functions and call them in a easy way? That would make easier to work with a function in a Runge Kutta method to solve a diff equation.
I let this part of the code here: (c is just the j integer i used to explain before)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int N=3;
double s=10.;
//float r=28.;
double b=8.0/3.0;
/ * Define functions * /
double sys(int c,double r,double y[])
{
int l,m,n,p=0;
double tmp;
double t[3][3]={0};
double j[3][3]={{-s,s,0},{r-y[2],-1,-y[0]},{y[1],y[0],-b}}; //Jacobiano
double id[3][3] = { {y[3],y[6],y[9]} , {y[4],y[7],y[10]} , {y[5],y[8],y[11]} };
double flat[N*(N+1)];
// Multiplication of matrices J * Y
for(l=0;l<N;l++)
{
for(m=0;m<N;m++)
{
for(n=0;n<N;n++)
{
t[l][m] += j[l][n] * id[n][m];
}
}
}
// Transpose the matrix (J * Y) -> () t
for(l=0;l<N;l++)
{
for(m=l+1;m<N;m++)
{
tmp = t[l][m];
t[l][m] = t[m][l];
t[m][l] = tmp;
}
}
// We flatten the array to be left in one array
for(l=0;l<N;l++)
{
for(m=0;m<N;m++)
{
flat[p+N] = t[l][m];
}
}
flat[0] = s*(y[1]-y[0]);
flat[1] = y[0]*(r-y[2])-y[1];
flat[2] = y[0]*y[1]-b*y[2];
for(l=0;l<(N*(N+1));l++)
{
if(c==l)
{
return flat[c];
}
}
}
EDIT ----------------------------------------------------------------
Ok, this is the part of the code where i use the function
int main(){
output = fopen("lyapcoef.dat","w");
int j,k;
int N2 = N*N;
int NN = N*(N+1);
double r;
double rmax = 29;
double t = 0;
double dt = 0.05;
double tf = 50;
double z[NN]; // Temporary matrix for RK4
double k1[N2],k2[N2],k3[N2],k4[N2];
double y[NN]; // Matrix for all variables
/* Initial conditions */
double u[N];
double phi[N][N];
double phiu[N];
double norm;
double lyap;
//Here we integrate the system using Runge-Kutta of fourth order
for(r=28;r<rmax;r++){
y[0]=19;
y[1]=20;
y[2]=50;
for(j=N;j<NN;j++) y[j]=0;
for(j=N;j<NN;j=j+3) y[j]=1; // Identity matrix for y from 3 to 11
while(t<tf){
/* RK4 step 1 */
for(j=0;j<NN;j++){
k1[j] = sys(j,r,y)*dt;
z[j] = y[j] + k1[j]*0.5;
}
/* RK4 step 2 */
for(j=0;j<NN;j++){
k2[j] = sys(j,r,z)*dt;
z[j] = y[j] + k2[j]*0.5;
}
/* RK4 step 3 */
for(j=0;j<NN;j++){
k3[j] = sys(j,r,z)*dt;
z[j] = y[j] + k3[j];
}
/* RK4 step 4 */
for(j=0;j<NN;j++){
k4[j] = sys(j,r,z)*dt;
}
/* Updating y matrix with new values */
for(j=0;j<NN;j++){
y[j] += (k1[j]/6.0 + k2[j]/3.0 + k3[j]/3.0 + k4[j]/6.0);
}
printf("%lf %lf %lf \n",y[0],y[1],y[2]);
t += dt;
}
Since you're actually computing all these values at the same time, what you really want is for the function to return them all together. The easiest way to do this is to pass in a pointer to an array, into which the function will write the values. Or perhaps two arrays; it looks to me as if the output of your function is (conceptually) a 3x3 matrix together with a length-3 vector.
So the declaration of sys would look something like this:
void sys(double v[3], double JYt[3][3], double r, const double y[12]);
where v would end up containing the first three elements of your flat and JYt would contain the rest. (More informative names are probably possible.)
Incidentally, the for loop at the end of your code is exactly equivalent to just saying return flat[c]; except that if c happens not to be >=0 and <N*(N+1) then control will just fall off the end of your function, which in practice means that it will return some random number that almost certainly isn't what you want.
Your function sys() does an O(N3) calculation to multiply two matrices, then does a couple of O(N2) operations, and finally selects a single number to return. Then it is called the next time and goes through most of the same processing. It feels a tad wasteful unless (even if?) the matrices are really small.
The final loop in the function is a little odd, too:
for(l=0;l<(N*(N+1));l++)
{
if(c==l)
{
return flat[c];
}
}
Isn't that more simply written as:
return flat[c];
Or, perhaps:
if (c < N * (N+1))
return flat[c];
else
...do something on disastrous error other than fall off the end of the
...function without returning a value as the code currently does...
I don't see where you are selecting an algorithm by the value of j. If that's what you're trying to describe, in C you can have an array of pointers to functions; you could use a numerical index to choose a function from the array, but you can also pass a pointer-to-a-function to another function that will call it.
That said: Judging from your code, you should keep it simple. If you want to use a number to control which code gets executed, just use an if or switch statement.
switch (c) {
case 0:
/* Algorithm 0 */
break;
case 1:
/* Algorithm 1 */
etc.

C function calling

So this program is supposed to estimate hourly temperatures throughout a day after being given the daily high, low and the hour which the low is expected. I am having problems calling up my functions inside the main function. I don't really understand how I am supposed to get specific information from the functions, and use it in place of a variable in my main function. I'm also having trouble grasping the idea of parameters and arguments. I'm sure I've messed up in more than one place here, but I'm mostly concerned about the functions right now. Any help would be appreciated.
#include <stdio.h>
#include <math.h>
#define PI 3.14159
double getFahrTemp(double high, double low, int hour);
double fahr2cels( double fahr );
double cels2kelv( double cels );
double fahr2rank( double fahr );
double getDailyHigh()
{
int high;
printf("Enter the daily high temperature <F>:\n");
scanf("%d",&high);
return high;
}
double getDailyLow()
{
int low;
printf("Enter the daily low temperature <F>:\n");
scanf("%d",&low);
return low;
}
int getLowHour()
{
int lowHour;
printf("Enter the time of the daily low temperature:\n");
scanf("%d",&lowHour);
return lowHour;
}
double getFahrTemp(double high, double low, int hour)
{
return (high-low)/2 * sin(2*PI/24 * hour + 3.0/2.0 * PI) + (high+low)/2;
}
double fahr2cels( double fahr )
{
double cels;
cels = fahr - 32 / 1.8;
}
double cels2kelv( double cels )
{
double kelv;
kelv = cels + 273;
}
double fahr2rank ( double fahr )
{
double rank;
rank = fahr + 459.67;
}
int main(getDailyHigh, getDailyLow, getLowHour, getFahrTemp)
{
int hour, time;
printf ("Temperature Scale Conversion Chart:\n")
printf ("TIME FAHR CELSIUS KELVIN RANKINE")
getDailyHigh();
getDailyLow();
getLowHour();
do
{
int time, hour=1;
time = (hour + lowHour) % 12;
getFahrTemp(getDailyHigh(), getDailyLow(), hour)
fahr2cels
cels2kelv
fahr2rank
printf ("%d:00 %2.2d %2.2d %3.2d %3.2d\n", time, fahr, cels, kelv, rank;
hour = hour++;
}
while (hour <= 24);
}
I don't really understand how I am
supposed to get specific information
from the functions, and use it in
place of a variable in my main
function. I'm also having trouble
grasping the idea of parameters and
arguments.
Do you understand the concept of a function in mathematics? For example, the equation to convert celcius to fahrenheit is:
°C = (°F − 32) × 5⁄9
One can write this as a mathematical function:
f(x) = (x - 32) × 5⁄9
The function f accepts a single argument called x and returns (x - 32) × 5⁄9. To "use" the function, you would write:
y = f(x)
Given a variable x, you can assign the result of function f to a variable y.
Once you understand this, you can easily see how it transfers to programming:
double fahr2cels(double f)
{
return (f - 32) * 5 / 9;
}
Calling the function even looks like "how math is done":
double celcius = fahr2cels(fahrenheit);
In the same way you can have multivariable functions in math, you can have functions that accept multiple parameters. You can even have functions that accept no parameters!
double getFahrTemp(double high, double low, int hour)
{
return (high-low)/2 * sin(2*PI/24 * hour + 3.0/2.0 * PI) + (high+low)/2;
}
The syntax for calling a function is fairly consistent:
// Call the function getFahrTemp(), passing three parameters.
// The variable fahrtemp receives the result of the function call.
double fahrtemp = getFahrTemp(high, low, hour);
There are some important differences I must take note of in this math analogy - functions in C can have side effects (they affect program state in some way outside the function). Also, parameters that you pass are always copied.
The problem is in this section:
fahr2cels
cels2kelv
fahr2rank
You need to pass the parameter specified:
degCel = fahr2cels(degF);
Some basic rules to help you understand:
All C statements end in a semicolon (;).
(none of your functions in the block cited had a semicolon at the end...)
Look to the function definition for information on what to pass
double fahr2cels( double fahr );
Says that the function takes 1 variable, which must be a double (floating point number)
Look to the function definition for information on what the function returns
All functions return only 1 (or zero) values. But the type of that one value is important.
double fahr2cels( double fahr );
Says that the function returns a value that is a double.
Take that information together, and make some changes to your code:
double dailyHighF, dailyHighC, dailyHighK;
double dailyLowF;
int lowHour;
dailyHighF = getDailyHigh();
dailyLowF = getDailyLow();
lowHour = getLowHour();
dailyHighC = farh2cels(dailyHighF);
dailyHighK = cels2kelv(dailyHighC);
Another thing to note: your functions are declared to return double, but they declare, scanf, and return ints. Its not a huge problem as the integers will get automatically changed into doubles. But you will be much better off if you are consistent in your types. If the function will return a double, it should have a double variable inside it.
e.g.
double fahr2cels( double fahr );
...
double fahr = 101.0;
double celsius = fahr2cels( fahr );
the return statment in the function returns the value to the caller.

Resources