How can i input this formula into my c++ program? - c++

Wind Chill = 35.74 + 0.6215T - 35.75(V^0.16) + 0.4275T(V^0.16)
I need the correct way to input the above formula into my program. I currently have the following and it's giving me a crazy number:
WindChill = ((35.74 + (0.6215 * temperature))
- (35.75 * pow(windSpeed, 0.16))
+ (0.4275 * temperature * pow(windSpeed, 0.16)));
I am a beginner programmer, C++ is my first language I am learning so I would appreciate any and all help. Thank you.

You can simplify by removing parenthesis.
double wind_chill = 35.74 + 0.6215 * T - 35.75 * pow(V, 0.16) + 0.4275 * T * pow(V, 0.16);
But in this case you calculate the power two times. A better way is :
double pow_v = pow(V, 0.16);
double wind_chill = 35.74 + 0.6215 * T - 35.75 * pow_v + 0.4275 * T * pow_v;

Try this. And if you are using your own power function then rather then again and againcalling that method you can store it in some variable. That will be good for efficiency as well as readability.
double windPower = pow(windspeed, 0.16);
WindChill = (35.74 + (0.6215 * temp) - (35.75 * windPower ) + (0.4275 * temp * windPower ))
And your power function ( if you want to define it ) goes like this:-
int pow(int x, unsigned int y)
{
if( y == 0)
return 1;
else if (y%2 == 0)
return power(x, y/2)*power(x, y/2);
else
return x*power(x, y/2)*power(x, y/2);
}
This is for integers ( As I was able to test it quickly ).

If you compute by hand, using the same data, does it give you the same crazy number, or the correct answer? If you get the same crazy number, maybe you need to convert some of your numbers to the correct units, eg temperature should probably be in Kelvin rather than Celsius or Farhenheit.
(This should have been a comment, but I don't have enough rep yet...)

Related

Performance issues with simple calculations

EDIT 2: 16% decrease in program computation time! See bottom for calculation
I have written a N-body simulator, implementing the Barnes-Hut algorithm. Now I have a innocent looking function called CheckNode. Its simple and doesn't take long to compute, but the issue is, it gets called millions of times, so it takes up most of the calculation time between each frame.
I profiled the code, and this function is responsible for 84.58% of the total calculation time, and this is with only 10K particles, when I do it with up to 10x this, this function uses a greater and greater percentage.
Now here is the function, with percentage of time spent on the right in the red.
Now there are some alarming things here, Like a simple if statement taking 9.17% and another if statement accounting for over 20% of computation time! Is there any, even the slightest optimisation that can be done here, that would be multiplied over millions of function calls to allow my program to run faster?
EDIT:
Here is the CalculateForceNode function:
void CalculateForceNode(Body* bi, Node* bj) //bi is being attracted to bj. 15 flops of calculation
{
//vector from the body to the center of mass
double vectorx = bj->CenterOfMassx - bi->posX;
double vectory = bj->CenterOfMassy - bi->posY;
//c^2 = a^2 + b^2 + softener^2
double distSqr = vectorx * vectorx + vectory * vectory + Softener * Softener;
// ivnDistCube = 1/distSqr^(3/2)
double distSixth = distSqr * distSqr * distSqr;
double invDistCube = 1.0f / (sqrt(distSixth));
double Accel = (bj->TotalMass * invDistCube * _GRAV_CONST);
bi->AccelX += vectorx * Accel;
bi->AccelY += vectory * Accel;
}
EDIT 2:
Results of optimisations
The CheckNode function now takes up 82.03% of the total computation time (measured over a 1 min 37 sec sample), as opposed to previously it took up 84.58%.
Now logic tells that the remaining 15% of calculation time, took the same as the remaining 18% calculation time of the second program. So these identical periods (Its the same code) took 15% of the first program, and 18% of the second program. Letting the time to complete this other code be x the 1st program took 1/0.15 = 6.666x and the second took 1/0.18 = 5.555x. Then you can find the fraction that 5.555x is of 6.666x which calculates to be ~0.83 and therefor there was a (1 - 0.83 = 0.16) 16% decrease in program computation time!
First thing I would try is to reverse the elements in one of your conditions, replace:
if(withSqr / distanceSqr < nodeThresholdSqr || pNode->HasChildren == false)
with:
if(pNode->HasChildren == false || (withSqr / distanceSqr < nodeThresholdSqr))
If the first part of the condition is true pNode->HasChildren == false than the second one (withSqr / distanceSqr < nodeThresholdSqr) will never be executed (read: evaluated). Checking simple condition is much faster than operations on floating point numbers (division in your case). You can even take it to the next level: *do you need to compute the distanceSqr AT ALL when pNode->HasChildren == false ?
EDIT: even better:
if(pNode->HasChildren == false)
{
CalculateForceNode(pBody,pNode);
}
else
{
double distanceSqr = ((diffX * diffX) + (diffY * diffY));
double withSqr = pNode->width * pNode->width;
if(withSqr / distanceSqr < nodeThresholdSqr)
{
CalculateForceNode(pBody,pNode);
}
else
{//if not, repeat function with child
if(pNode->Child[0]->Bodies.size() > 0)
CheckNode(pNode->Child[0],pBody);
//..... - all the rest of your code
}
}
Profiling based on time spent is not enough, you need to know what was this time spent in - in other words use a more advanced profiler.
Also you don't mention any information about compiler or platform you are using.
For the if statement that is using 9% of the time, I don't think it is spent in the comparison, it is spent in fetching data. You have multiple levels of indirection (accessing data using pointer that takes you to another pointer and so on). This is bad for caching and branch prediction, and I guess you are spending time fetching data from memory or doing useless calculations because of branch miss prediction, not doing the actual comparison.
another note that I noticed: if (pNode->HasChildren == false) then you don't need all the calculations you made to find widthSqr. I think you should restructure your logic to check for this first, if the condition is false then you can can calculate widthSqr and continue your logic.
Since the function is called a lot of times you should get rid of the overhead of calling CalculateForceNode(...) by manually inlining the code. One you do this you will notice other tricks to apply:
void CheckNode(Node* pNode, Body* pBody)
{
double diffX = (pNode->CenterOfMass - pBody->posX);
double diffY = (pNode->CenterOfMass - pBody->posY);
double distanceSqr = ((diffX * diffX) + (diffY * diffY));
double widthSqr = pNode->width * pNode->width;
if (widthSqr / distanceSqr < NodeThresholdSqr || pNode->hasChildren == false)
{
//vector from the body to the center of mass
double vectorx = pNode->CenterOfMassx - pBody->posX;
double vectory = pNode->CenterOfMassy - pBody->posY;
//c^2 = a^2 + b^2 + softener^2
double distSqr = vectorx * vectorx + vectory * vectory + Softener * Softener;
// ivnDistCube = 1/distSqr^(3/2)
double distSixth = distSqr * distSqr * distSqr;
double invDistCube = 1.0f / (sqrt(distSixth));
double Accel = (pNode->TotalMass * invDistCube * _GRAV_CONST);
pBody->AccelX += vectorx * Accel;
pBody->AccelY += vectory * Accel;
}
else
{
CheckChildren(pNode, pBody);
}
}
Now you can see that diffX = vectorx, diffY = vectory, distSqr = distanceSqr*Softner*Softner. Reusing some of the calculation already made and precomputing whatever is possible should save you some cycles:
void CheckNode(Node* pNode, Body* pBody)
{
double diffX = (pNode->CenterOfMass - pBody->posX);
double diffY = (pNode->CenterOfMass - pBody->posY);
double distanceSqr = ((diffX * diffX) + (diffY * diffY));
double widthSqr = pNode->width * pNode->width;
double SoftnerSq = Softener * Softener; //precompute this value
if (widthSqr / distanceSqr < NodeThresholdSqr || pNode->hasChildren == false)
{
//c^2 = a^2 + b^2 + softener^2
double distSqr = distanceSqr + SoftnerSq;
// ivnDistCube = 1/distSqr^(3/2)
double distSixth = distSqr * distSqr * distSqr;
double invDistCube = 1.0f / (sqrt(distSixth));
double Accel = (pNode->TotalMass * invDistCube * _GRAV_CONST);
pBody->AccelX += diffX * Accel;
pBody->AccelY += diffY * Accel;
}
else
{
CheckChildren(pNode, pBody);
}
}
Hope this works for you.
First you should inline function Bodies.size() or access size directly so there is no overhead with function calling (it takes time to push all needed information to stack and pop it off).
I don't see all the code, but it looks like you can precalculate widthSqr. It can be calculated when the width is assigned not in the function.
You are using a lot of pointers here and it looks like your structures are scattered all over the memory. This will generate a lot CPU cache misses. Make sure that all the data needed for computation are in one, long, continuous and compact memory area.
In CalculateForceNode check if Softener*Softener can be precalculated. sqrt function is very time consuming. sqrt algorithm is iterative so you can sacrifice accuracy for speed by doing less iterations or you can use Look up tables.
You are doing the same calculations twice in CalculateForceNode.
void CalculateForceNode(Body* bi, Node* bj)
{
//vector from the body to the center of mass
double vectorx = bj->CenterOfMassx - bi->posX;
double vectory = bj->CenterOfMassy - bi->posY;
//c^2 = a^2 + b^2 + softener^2
double distSqr = vectorx * vectorx + vectory * vectory...
vectorx,vectory and distSqr were already calulated in CheckNode as diffX, diffY and distanceSqr. Manually inline whole function CalculateForceNode.
Swap your if statement around and move all your calculations inside the pNode->hasChildren == false part:
void CheckChildren(Node* pNode, Body* pBody)
{
if (pNode->Child[0]->Bodies.size() > 0)
CheckNode(...
}
void CheckNode(Node* pNode, Body* pBody)
{
if (pNode->hasChildren != false)
{
double diffX = (pNode->CenterOfMass - pBody->posX);
double diffY = (pNode->CenterOfMass - pBody->posY);
double distanceSqr = ((diffX * diffX) + (diffY * diffY));
double widthSqr = pNode->width * pNode->width;
if (widthSqr / distanceSqr < NodeThresholdSqr)
{
CalculateForceNode(pBody, pNode);
}
else
{
CheckChildren(pNode, pBody);
}
}
else
{
CheckChildren(pNode, pBody);
}
}

bandpass FIR filter

I need to make a simple bandpass audio filter.
Now I've used this simple C++ class: http://www.cardinalpeak.com/blog/a-c-class-to-implement-low-pass-high-pass-and-band-pass-filters
It works well and cut off the desired bands. But when I try to change upper or lower limit with small steps, on some values of limit I hear the wrong result - attenuated or shifted in frequency (not corresponding to current limits) sound.
Function for calculating impulse response:
void Filter::designBPF()
{
int n;
float mm;
for(n = 0; n < m_num_taps; n++){
mm = n - (m_num_taps - 1.0) / 2.0;
if( mm == 0.0 ) m_taps[n] = (m_phi - m_lambda) / M_PI;
else m_taps[n] = ( sin( mm * m_phi ) -
sin( mm * m_lambda ) ) / (mm * M_PI);
}
return;
}
where
m_lambda = M_PI * Fl / (Fs/2);
m_phi = M_PI * Fu / (Fs/2);
Fs - sample rate (44.100)
Fl - lower limit
Fu - upper limit
And simple filtering function:
float Filter::do_sample(float data_sample)
{
int i;
float result;
if( m_error_flag != 0 ) return(0);
for(i = m_num_taps - 1; i >= 1; i--){
m_sr[i] = m_sr[i-1];
}
m_sr[0] = data_sample;
result = 0;
for(i = 0; i < m_num_taps; i++) result += m_sr[i] * m_taps[i];
return result;
}
Do I need to use any window function (Blackman, etc.)? If yes, how do I do this?
I have tried to multiply my impulse response to Blackman window:
m_taps[n] *= 0.42 - 0.5 * cos(2.0 * M_PI * n / double(N - 1)) +
0.08 * cos(4.0 * M_PI * n / double(N - 1));
but the result was wrong.
And do I need to normalize taps?
I found a good free implementation of FIR filter:
http://www.iowahills.com/A7ExampleCodePage.html
...This Windowed FIR Filter C Code has two parts, the first is the
calculation of the impulse response for a rectangular window (low
pass, high pass, band pass, or notch). Then a window (Kaiser, Hanning,
etc) is applied to the impulse response. There are several windows to
choose from...
y[i] = waveform[i] × (0.42659071 – 0.49656062cos(w) + 0.07684867cos(2w))
where w = (2)i/n and n is the number of elements in the waveform
Try this I got the code from:
http://zone.ni.com/reference/en-XX/help/370592P-01/digitizers/blackman_window/
I hope this helps.

Step Independent Smoothing

I often smooth values by blending percentages and inverse percentages with the below:
current_value = (current_value * 0.95f) + (goal_value * 0.05f)
I'm running into a situation where I would like to perform this action n times, and n is a floating point value.
What would be the proper way of performing the above, say 12.5 times for example?
One way of doing this would be to handle the integer amount, and then approximate the remaining amount. For example (I assume valid inputs, you would want to check for those):
void Smooth(float& current, float goal, float times, float factor){
// Handle the integer steps;
int numberIterations = (int)times;
for (int i = 0; i < numberIterations; ++i){
current = (factor * current) + (goal * (1 - factor));
}
// Aproximate the rest of the step
float remainingIteration = times - numberIterations;
float adjusted_factor = factor + ((1 - factor) * (1 - remainingIteration));
current = (adjusted_factor * current) + (goal * (1 - adjusted_factor));
}
Running for the following values I get:
current=1 goal=2 factor=0.95
12.0 times - 1.45964
12.5 times - 1.47315
13.0 times - 1.48666
I appreciate the help! I have been trying several things related to compound interest, and I believe I may have solved this with the following. My ultimate goal in mind (which was actually unstated here) was to actually do this with very little iterative processing. powf() may be the most time consuming piece here.
float blend_n(float c, float g, float f, float n)
{
if (g != 0.0f)
return c + ((g - c) / g) * (g - g * powf(1.0f - f, n));
else
return c * powf(1.0 - f, n);
}
It's late here, and my redbull is wearing off so there may be some parts that could be factored out.
Usage would be setting c to the return value of blend_n ...
Thanks again!
[EDIT]
I should explain here that c is the (current) value, g is the (goal) value, f is the (factor), and n is the (number of steps)
[/EDIT]
[EDIT2]
An exception has to be made for goal values of 0, as it will result in a NaN (Not a Number) ... Change done to the code above
[/EDIT2]

Magic numbers in C++ implementation of Excel NORMDIST function

Whilst looking for a C++ implementation of Excel's NORMDIST (cumulative)
function I found this on a website:
static double normdist(double x, double mean, double standard_dev)
{
double res;
double x=(x - mean) / standard_dev;
if (x == 0)
{
res=0.5;
}
else
{
double oor2pi = 1/(sqrt(double(2) * 3.14159265358979323846));
double t = 1 / (double(1) + 0.2316419 * fabs(x));
t *= oor2pi * exp(-0.5 * x * x)
* (0.31938153 + t
* (-0.356563782 + t
* (1.781477937 + t
* (-1.821255978 + t * 1.330274429))));
if (x >= 0)
{
res = double(1) - t;
}
else
{
res = t;
}
}
return res;
}
My limited maths knowledge made me think about Taylor series, but I am unable to determine where these numbers come from:
0.2316419,
0.31938153,
-0.356563782,
1.781477937,
-1.821255978,
1.330274429
Can anyone suggest where they come from, and how they can be derived?
Check out Numerical Recipes, chapter 6.2.2. The approximation is standard. Recall that
NormCdf(x) = 0.5 * (1 + erf(x / sqrt(2)))
erf(x) = 2 / (sqrt(pi)) integral(e^(-t^2) dt, t = 0..x)
and write erf as
1 - erf x ~= t * exp(-x^2 + P(t))
for positive x, where
t = 2 / (2 + x)
and since t is between 0 and 1, you can find P by Chebyshev approximation once and for all (Numerical Recipes, section 5.8). You don't use Taylor expansion: you want the approximation to be good in the whole real line, what Taylor expansion cannot guarantee. Chebyshev approximation is the best polynomial approximation in the L^2 norm, which is a good substitute to the very difficult to find minimax polynomial (= best polynomial approximation in the sup norm).
The version here is slightly different. Instead, one writes
1 - erf x = t * exp(-x^2) * P(t)
but the procedure is similar, and normCdf is computed directly, instead of erf.
In particular and very similarly 'the implementation' that you are using differs somewhat from the one that handles in the text, because it is of the form b*exp(-a*z^2)*y(t) but it´s also a Chevishev approx. to the erfc(x) function as you can see in this paper of Schonfelder(1978)[http://www.ams.org/journals/mcom/1978-32-144/S0025-5718-1978-0494846-8/S0025-5718-1978-0494846-8.pdf ]
Also in Numerical Recipes 3rd edition, at the final of the chapter 6.2.2 they provide a C implementation very accurate of the type t*exp(-z^2 + c0 + c1*t+ c2t^2 + c3*t^3 + ... + c9t^9)

C++ Question on the pow function

I'm trying to get this expression to work, I'm pretty sure its not the parenthesis because I counted all of them. Perhaps there something I'm doing wrong involving the parameter pow (x,y).
double calculatePeriodicPayment()
{
periodicPaymentcalc = (loan * ((interestRate / yearlyPayment))) / (1-((pow ((1+(interestRate / yearlyPayment)))),(-(yearlyPayment * numOfYearLoan))));
return periodicPaymentcalc;
}
Notice how much easier it is to figure out what the function is doing if you break each step up into pieces:
(I find it even easier if your variables match the source material, so I'll name my variables after the ones Wikipedia uses.)
// amortization calculator
// uses annuity formula (http://en.wikipedia.org/wiki/Amortization_calculator)
// A = (P x i) / (1 - pow(1 + i,-n))
// Where:
// A = periodic payment amount
// P = amount of principal
// i = periodic interest rate
// n = total number of payments
double calculatePeriodicPayment()
{
const double P = loan;
const double i = interestRate / yearlyPayment;
const double n = yearlyPayment * numOfYearLoan;
const double A = (P * i) / (1 - pow(1.0 + i, -n));
return A;
}
It's much easier to confirm that the logic of this function does what it should this way.
If you're curious, substituting my variable names in, your parenthises problem is as follows:
const double A = (P * i) / (1 - pow(1 + i)), -n; // <- this is how you have it
const double A = (P * i) / (1 - pow(1 + i, -n)); // <- this is how it should be
With this grouping, you're only passing one argument to pow, which is why the compiler says no overloaded function takes 1 arguments.
Edit: You mentioned I used more variables. However, your compiler will use temporary variables much like I did. Your complex statement will be broken up into pieces, and may look something like this:
double calculatePeriodicPayment()
{
const double temp1 = interestRate / yearlyPayment;
const double temp2 = loan * temp1;
const double temp3 = interestRate / yearlyPayment;
const double temp4 = 1.0 + temp3;
const double temp5 = yearlyPayment * numOfYearLoan;
const double temp6 = -temp5;
const double temp7 = pow(temp4, temp5);
const double temp8 = 1 - temp7;
const double temp9 = temp2 / temp8;
periodicPaymentcalc = temp9;
return periodicPaymentcalc;
}
Mine will also be broken up, and will look like:
double calculatePeriodicPayment()
{
const double P = loan;
const double i = interestRate / yearlyPayment;
const double n = yearlyPayment * numOfYearLoan;
const double temp1 = P * i;
const double temp2 = 1.0 + i;
const double temp3 = -n;
const double temp4 = pow(temp2, temp3);
const double temp5 = 1 - temp4;
const double temp6 = temp1 / temp5;
const double A = temp6;
return A;
}
Perhaps there are some optimizations that the compiler will use, such as noticing that it uses interestRate / yearlyPayment twice in your function, and use the same temporary for both places, but there's no gurantee this will happen. Notice that we use pretty much the same number of variables in both of our functions. I just used more named variables, and fewer unnamed temporaries.
There's a misplaced bracket. Here's a fixed version:
periodicPaymentcalc = (loan * ((interestRate / yearlyPayment))) / (1 - ((pow ((1+(interestRate / yearlyPayment)),(-(yearlyPayment * numOfYearLoan))))));
Use an editor that highlights matching brackets to avoid this kind of errors. Or simply create temporary variables to hold intermediate values.
periodicPaymentcalc = (loan * interestRate / yearlyPayment) /
(1.0 - pow (1.0 + interestRate / yearlyPayment, -yearlyPayment * numOfYearLoan));
Try that. I removed all the redundant parentheses too, as well as changing all literals to doubles, just for good measure.