I have a problem when I execute the program,the results that I have got is "nan" for the values of vector.I do not exactly where is the mistake. the method distancias generates a correct value but the method variogram does not generate the expected value instead of that generates a value "nan".Sorry for my english.
#include <iostream>
#include <math.h>
//this program is to calculate the kriging puntual
using namespace std;
////
class Points{
private:
float x;
float y;
public:
Points(float a,float b);
Points();
float distancia(float x_1,float y_1);
float variogram(float h);
float valor_1();
float valor_2();
void show(void);
};
Points::Points(){
}
Points::Points(float a,float b){
x=a;
y=b;
}
float Points::distancia(float x_1,float y_1){
float d;
d=pow(pow((x-x_1),2)+pow((y-y_1),2),0.5);
return d;
}
float Points::variogram(float h){
float v,c_0,c_1,a_1;
v=c_0+c_1*(1.5*(h/a_1)-0.5*pow((h/a_1),3));
return v;
}
void Points::show(void){
printf("%.2f,%.2f\n",x,y);
}
float Points::valor_1(){
return x;
}
float Points::valor_2(){
return y;
}
///////
int main(int argc, char** argv) {
float a_1,c_0,c_1; //parameters of variogram
float c,d; // position of point to determinate
float a,b; //positions of all points except the point to determinate
int i=0,n;
int j,k;
Points final; //point to determinate
//this part is to enter the values of function sphere variogram
printf("Enter the paramters of sphere variogram\n");
printf("Enter the value of c_0: ");
scanf("%f",&c_0);
printf("Enter the value of c_1: ");
scanf("%f",&c_1);
printf("Enter the value of a: ");
scanf("%f",&a_1);
//determinating the postion of final point
printf("Enter the position of the point to determinate: ");
scanf("%f,%f",&c,&d);
final=Points(c,d);
final.show();
printf("Enter the name of points for the krigeage: ");
scanf("%i",&n);
Points punto[n];
float vector[n];
do{
printf("Enter the position x,y of the point %i: ",i+1);
scanf("%f,%f",&a,&b);
punto[i]=Points(a,b);
punto[i].show();
vector[i]=punto[i].variogram(punto[i].distancia(c,d));
cout<<vector[i]<<endl;
i=i+1;
}while(i<n);
return 0;
}
The problem is in the following function:
float Points::variogram(float h){
float v,c_0,c_1,a_1;
v=c_0+c_1*(1.5*(h/a_1)-0.5*pow((h/a_1),3));
return v;
}
Here, you are declaring the local variables v, c_0, c_1 and a_1. These values are not initialized, they can contain anything. However, it is not unlikely they actually are equal to zero. So when you calculate h/a_1, the result of that is probably plus or minus infinity. When you subtract two infinities with the same sign from each other, the result will be NaN.
What you should do is pass the values for c_0, c_1 and a_1 from main() to the function:
float Points::variogram(float h, float c_0, float c_1, float a_1){
return c_0+c_1*(1.5*(h/a_1)-0.5*pow((h/a_1),3));
}
...
vector[i]=punto[i].variogram(punto[i].distancia(c,d), c_0, c_1, a_1);
Please compile your code with warnings enabled (if you use GCC, then use the -Wall command line option). Your compiler should then warn you about these uninitialized variables.
Related
I have the following code which says that 'distance' is used uninitialized in this function.
This is a code that accepts two coordinates from a cartesian plane and uses the distance between them as radius to find the area of a circle. This is the code
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct Point {
int x, y;
};
double getDistance(struct Point a, struct Point b)
{
double distance;
distance = sqrt((a.x - b.x) * (a.x - b.x) + (a.y-b.y) *(a.y-b.y));
return distance;
}
int main()
{
float Area;
double distance;
struct Point a, b;
printf("Enter coordinate of point a: ");
scanf("%d %d", &a.x, &a.y);
printf("Enter coordinate of point b: ");
scanf("%d %d", &b.x, &b.y);
printf("Distance between a and b: %lf\n", getDistance(a, b));
Area= 3.14 * distance * distance;
printf("\nArea of Circle : %f", Area);
return 0;
}
This is correct: variable distance inside getDistance and variable distance inside main are two different variables.
When you write this
printf("Distance between a and b: %lf\n", getDistance(a, b));
distance inside main does not get set.
You can fix it by adding an assignment
distance = getDistance(a, b);
printf("Distance between a and b: %lf\n", distance);
Implementation note: Since you need distance squared, you can avoid taking square root by defining a function getDistanceSquared, and using it instead.
You should read more carefully the compiler warning, because it is refering to the variable distance in your main function not the one in getDistance.
I think, what you actually wanted to do was this:
distance = getDistance(a, b);
printf("Distance between a and b: %lf\n", distance);
Then, you can use the result of getDistance anywhere in your main function. ;)
You forgot to assign distance variable, try something like:
int main()
{
float Area;
double distance;
struct Point a, b;
printf("Enter coordinate of point a: ");
scanf("%d %d", &a.x, &a.y);
printf("Enter coordinate of point b: ");
scanf("%d %d", &b.x, &b.y);
distance = getDistance(a, b);
printf("Distance between a and b: %lf\n", distance);
Area= 3.14 * distance * distance;
printf("\nArea of Circle : %f", Area);
return 0;
}
I am trying to solve differential heat equation using Thomas algorithm.
Physical problem: We have plug, left side is having temperature 0, right side temperature is 1.
For Thomas algorithm I have written a function, which accept three QVector and int value amount of equations.
This is my code:
#include <QCoreApplication>
#include <QVector>
#include <QDebug>
#include <iostream>
using std::cin;
void enterIn(QVector<float> &Array, int Amount_of_elements){
int transit;
for(int i=0;i<Amount_of_elements;i++){
cin>>transit;
Array.push_back(transit);
}
}
QVector<float> shuttle_method(const QVector<float> &below_main_diagonal,
QVector<float> &main_diagonal,
const QVector<float> &beyond_main_diagonal,
const QVector<float> &free_term,
const int N){
QVector <float> c;
QVector <float> d;
for(int i=0;i<N;i++){
main_diagonal[i]*=(-1);
}
QVector<float> x; //result
c.push_back(beyond_main_diagonal[0]/main_diagonal[0]);
d.push_back(-free_term[0]/main_diagonal[0]);
for(int i=1;i<=N-2;i++){
c.push_back(beyond_main_diagonal[i]/(main_diagonal[i]-below_main_diagonal[i]*c[i-1]));
d.push_back( (below_main_diagonal[i]*d[i-1] - free_term[i]) / (main_diagonal[i]- below_main_diagonal[i]*c[i-1]) );
}
x.resize(N);
//qDebug()<<x.size()<<endl;
int n=N-1;
x[n]=(below_main_diagonal[n]*d[n-1]-free_term[n])/(main_diagonal[n]-below_main_diagonal[n]*c[n-1]);
for(int i=n-1;i>=0;i--){
x[i]=c[i]*x[i+1]+d[i];
// qDebug()<<x[i]<<endl;
}
return x;
}
int main()
{
QVector <float> alpha; // below
QVector <float> beta; // main diagonal * (-1)
QVector <float> gamma; // beyond
QVector <float> b; // free term
QVector<float> T;
int cells_x=40; //amount of equations
alpha.resize(cells_x);
beta.resize(cells_x);
gamma.resize(cells_x);
b.resize(cells_x);
T.resize(cells_x);
float dt=0.2,h=0.1;
alpha[0]=0;
for(int i=1;i<cells_x;i++){
alpha[i]= -dt/(h*h);
}
for(int i=0;i<cells_x;i++){
beta[i] = (2*dt)/(h*h)+1;
}
for(int i=0;i<cells_x-1;i++){
gamma[i]= -dt/(h*h);
}
gamma[cells_x-1]=0;
qDebug()<<"alpha= "<<endl<<alpha.size()<<alpha<<endl<<"beta = "<<endl<<beta.size()<<beta<<endl<<"gamma= "<<gamma.size()<<gamma<<endl;
for(int i=0;i<cells_x-1;i++){
T[i]=0;
}
T[cells_x-1]=1;
qDebug()<<endl<<endl<<T<<endl;
//qDebug()<< shuttle_method(alpha,beta,gamma,b,N);
QVector<float> Tn;
Tn.resize(cells_x);
Tn = shuttle_method(alpha,beta,gamma,T,cells_x);
Tn[0]=0;Tn[cells_x-1]=1;
for(int stepTime = 0; stepTime < 50; stepTime++){
Tn = shuttle_method(alpha,beta,gamma,Tn,cells_x);
Tn[0]=0;
Tn[cells_x-1]=1;
qDebug()<<Tn<<endl;
}
return 0;
}
My problem is:
when I compile and run it I am getting this:
Tn <20 items> QVector<float>
0 float
0.000425464 float
0.000664658 float
0.000937085 float
0.00125637 float
0.00163846 float
0.00210249 float
0.00267163 float
0.00337436 float
0.00424581 float
0.00532955 float
0.00667976 float
0.00836396 float
0.0104664 float
0.0130921 float
0.0163724 float
0.0204714 float
0.0255939 float
0.0319961 float
Tn <20 items> QVector<float>
0 float
-0.000425464 float
0.000643385 float
-0.000926707 float
0.00120951 float
-0.00161561 float
0.00202056 float
-0.00263167 float
0.00324078 float
-0.00418065 float
0.00511726 float
-0.00657621 float
0.00802998 float
-0.0103034 float
0.0125688 float
-0.0161171 float
0.0196527 float
-0.0251945 float
0.0307164 float
1 float
Tn <20 items> QVector<float>
0 float
0.000425464 float
0.000664658 float
0.000937085 float
0.00125637 float
0.00163846 float
0.00210249 float
0.00267163 float
0.00337436 float
0.00424581 float
0.00532955 float
0.00667976 float
0.00836396 float
0.0104664 float
0.0130921 float
0.0163724 float
0.0204714 float
0.0255939 float
0.0319961 float
Tn <20 items> QVector<float>
0 float
-0.000425464 float
0.000643385 float
-0.000926707 float
0.00120951 float
-0.00161561 float
0.00202056 float
-0.00263167 float
0.00324078 float
-0.00418065 float
0.00511726 float
-0.00657621 float
0.00802998 float
-0.0103034 float
0.0125688 float
-0.0161171 float
0.0196527 float
-0.0251945 float
0.0307164 float
1 float
Again and again in loop.
I have no idea why I am getting this.
Maybe my mistake is in assign Tn result of my Thomas-method-function?
or in realization of Thomas method? or in boundary conditions?
I got it!
Boundary conditions must be acting to vectors
QVector<float> below_main_diagonal,
QVector<float> main_diagonal,
QVector<float> beyond_main_diagonal
so that T[0] must be 0 and T[N-1] must be 1. We can do it this way:
main_diagonal.first()=1;
main_diagonal.last()=1;
beyond_main_diagonal.first()=0;
below_main_diagonal.last()=0;
and due to this T[0] will be always equal to zero and T[N-1] will be equal to 1;
And in the article where I read about Thomas method the first step was to negate main diagonal, I have done it, but then in the end of the function I must do reverse thing, so:
for(int i(0);i<N;++i){
main_diagonal[i]*=(-1);
}
and we can use this function again, this is not absolutely optimal, but it is working stable.
Then, the whole code will be look like this:
#include <QCoreApplication>
#include <QVector>
#include <QDebug>
#include <iostream>
QVector<float> Thomas_Algorithm( QVector<float> &below_main_diagonal ,
QVector<float> &main_diagonal ,
QVector<float> &beyond_main_diagonal ,
QVector<float> &free_term,
const int N){
QVector<float> x; //vector of result
// checking of input data
if(below_main_diagonal.size()!=main_diagonal.size()||
main_diagonal.size()!=beyond_main_diagonal.size()||
free_term.size()!=main_diagonal.size())
{ qDebug()<<"Error!\n"
"Error with accepting Arrays! Dimensities are different!"<<endl;
x.resize(0);
return x;
}
if(below_main_diagonal[0]!=0){
qDebug()<< "Error!\n"
"First element of below_main_diagonal must be equal to zero!"<<endl;
x.resize(0);
return x;
}
if(beyond_main_diagonal.last()!=0){
qDebug()<< "Error!\n"
"Last element of beyond_main_diagonal must be equal to zero!"<<endl;
x.resize(0);
return x;
}
// end of checking
QVector <float> c;
QVector <float> d;
for(int i=0;i<N;i++){
main_diagonal[i]*=(-1);
}
c.push_back(beyond_main_diagonal[0]/main_diagonal[0]);
d.push_back(-free_term[0]/main_diagonal[0]);
for(int i=1;i<=N-2;i++){
c.push_back(beyond_main_diagonal[i]/(main_diagonal[i]-below_main_diagonal[i]*c[i-1]));
d.push_back( (below_main_diagonal[i]*d[i-1] - free_term[i]) /
(main_diagonal[i]- below_main_diagonal[i]*c[i-1]) );
}
x.resize(N);
int n=N-1;
x[n]=(below_main_diagonal[n]*d[n-1]-free_term[n])/(main_diagonal[n]-below_main_diagonal[n]*c[n-1]);
for(int i=n-1;i>=0;i--){
x[i]=c[i]*x[i+1]+d[i];
}
for(int i(0);i<N;++i){
main_diagonal[i]*=(-1);
}
return x;
}
int main()
{
QVector <float> alpha; // below
QVector <float> beta; // main diagonal * (-1)
QVector <float> gamma; // beyond
QVector <float> b; // free term
QVector<float> T;
int cells_x=30; // amount of steps
alpha.resize(cells_x);
beta.resize(cells_x);
gamma.resize(cells_x);
T.resize(cells_x );
float dt=0.2,h=0.1;
alpha[0]=0;
for(int i=1;i<cells_x-1;i++){
alpha[i]= -dt/(h*h);
}
alpha[cells_x-1]=0;
beta[0]=1;
for(int i=1;i<cells_x-1;i++){
beta[i] = (2*dt)/(h*h)+1;
}
beta[cells_x-1]=1;
gamma[0]=0;
for(int i=1;i<cells_x-1;i++){
gamma[i]= -dt/(h*h);
}
gamma[cells_x-1]=0;
for(int i=0;i<cells_x-1;i++){
T[i]=0;
}
T[cells_x-1]=1;
QVector<float>Tn;
Tn.resize(cells_x);
Tn= Thomas_Algorithm(alpha,beta,gamma,T,cells_x);
// boundary conditions!
beta.first()=1;
beta.last()=1;
gamma.first()=0;
alpha.last()=0;
// and then due to bc we always have T[0]=0 and T[n]=1
for(int stepTime=0;stepTime<100;stepTime++){
Tn = Thomas_Algorithm(alpha,beta,gamma,Tn,cells_x);
qDebug()<<"stepTime = "<<stepTime<<endl<<endl;
qDebug()<<Tn<<endl;
// boundary conditions!
beta.first()=1;
beta.last()=1;
gamma.first()=0;
alpha.last()=0;
// and then due to bc we always have T[0]=0 and T[n]=1
}
return 0;
}
and in the last step we are going to get absolutely "physical" results:
Tn <30 items> QVector<float>
0 float
0.0344828 float
0.0689656 float
0.103448 float
0.137931 float
0.172414 float
0.206897 float
0.24138 float
0.275862 float
0.310345 float
0.344828 float
0.379311 float
0.413793 float
0.448276 float
0.482759 float
0.517242 float
0.551724 float
0.586207 float
0.62069 float
0.655173 float
0.689655 float
0.724138 float
0.758621 float
0.793104 float
0.827586 float
0.862069 float
0.896552 float
0.931035 float
0.965517 float
1 float
i need to gain a better understanding of function definition, declarations and proper calls using this program. I really need the understanding of how to use them. Could you show me the proper way to write this program with all three correct and explained?
#include <stdio.h>
#include <math.h>
quad_equation(float a, float b, float c);
int main()
{
float a, b, c, determinant, r1,r2;
printf("Enter coefficients a, b and c: ");
scanf("%f%f%f",&a,&b,&c);
determinant=b*b-4*a*c;
if (determinant>0)
{
r1= (-b+sqrt(determinant))/(2*a);
r2= (-b-sqrt(determinant))/(2*a);
printf("Roots are: %.2f and %.2f",r1 , r2);
}
else if (determinant==0) { r1 = r2 = -b/(2*a);
printf("Roots are: %.2f and %.2f", r1, r2);
}
else (determinant<0);
{
printf("Both roots are complex");
}
return 0;
I just solved this exact question here : (I guess this is a part of an assignment )
https://stackoverflow.com/a/19826495/1253932
Also looking at your code .. you never use the function quad equation .. also you haven't defined the type of the function ( int/void/float/char) etc.
For ease: ( here is the entire code ) -- ask me if you don't understand anything
#include <stdio.h>
#include <math.h>
// function declarations
void twoRoots (float a,float b,float delta);
void oneRoot (float a,float b,float delta);
int main (void)
{
//Local Declarations
float a;
float b;
float c;
float delta;
// float solution;
printf("Input coefficient a.\n");
scanf("%f", &a);
printf("Input coefficient b.\n");
scanf("%f", &b);
printf("Input coefficient c.\n");
scanf("%f", &c);
printf("%0.2fx^2 + %0.2fx + %0.2f\n", a, b, c);
delta = (float)(b*b) - (float)(4.0 * a * c);
printf("delta = %0.2f\n",delta);
if (delta > 0){
twoRoots(a,b,delta);
}else if (delta == 0) {
oneRoot(a,b,delta);
}else if (delta < 0.0){
printf("There are no real roots\n");
}
return 0;
}
void twoRoots (float a,float b,float delta)
{
float xOne;
float xTwo;
float deltaRoot;
printf("There are two distinct roots.\n");
deltaRoot = sqrt(delta);
xOne = (-b + deltaRoot) / (2*a);
xTwo = (-b - deltaRoot) / (2*a);
printf("%.2f", xOne);
printf("%.2f", xTwo);
}
void oneRoot(float a,float b,float delta)
{
float xOne;
// float xTwo;
// float deltaRoot;
printf("There is exactly one distinct root\n");
xOne = -b / (2*a);
printf("%.2f", xOne);
}
EDIT:
A slightly more optimized and better functioning code that I made from the above mentioned code:
http://pastebin.com/GS65PvH6
Edit2:
From your comments you try to do this:
printf("Enter coefficients a, b and c: ");
scanf("%f%f%f",&a,&b,&c);
This will fail if you input something like this: 121
Beacuse scanf will read the whole 121 into a and it will have nothing for b,c ( rather it will put \n(enter) into b and undefined into c )
So use the scanf the way I have used it in my code
OK - this is full of problems! I attempt to point them out, and show what "better" looks like. I hope this helps.
quad_equation(float a, float b, float c);
This is probably intended to be a "function prototype". A prototype tells the compiler "I am going to use this function later, and this is how it needs to be called, and the type it returns". You did not specify a return type; probably you want to use int to say whether you found roots or not, and print out the result in the function. Better would be to pass space for two return values as a parameter:
int quad_equation(float a, float b, float c, float* x1, float* x2);
Now we can use the main program to get input/output, and let the function solve the problem:
int main(void) {
{
float a, b, c, r1, r2;
int n;
// here you get the inputs; that seems OK
printf("Enter coefficients a, b and c: ");
scanf("%f %f %f",&a,&b,&c);
// now you have to "call your function"
// note that I make sure to follow the prototype: I assign the return value to an int
// and I pass five parameters: the coefficients a, b, c and the address of two variables
// x1 and x2. These addresses will be where the function puts the roots
n = quad_equation(a, b, c, &r1, &r2);
// when the function returns, I can print the results:
printf("There are %d roots:\n", n);
// based on the value of n, I change what I want to print out:
if (n == 2) printf(" %f and ", r1); // when there are two roots I print "root 1 and"
if (n > 0) printf("%f\n", r2); // when there is at least one root, I print it
// note that if n == 0, I would skip both print statements
// and all you would have gotten was "There are 0 roots" in the output
}
int quad_equation(float a, float b, float c, float* x1, float* x2) {
// function that computes roots of quadratic equation
// and returns result in x1 and x2
// it returns the number of roots as the return value of the function
float determinant;
determinant=b*b-4*a*c;
if (determinant>0)
{
*x1 = (-b+sqrt(determinant))/(2*a);
*x2= (-b-sqrt(determinant))/(2*a);
return 2;
}
if (determinant==0) {
*x1 = *x2 = -b/(2*a);
return 1;
}
return 0;
}
I want to round big double number (>1e6) to the closest but bigger float using c/c++.
I tried this but I'm not sure it is always correct and there is maybe a fastest way to do that :
int main() {
// x is the double we want to round
double x = 100000000005.0;
double y = log10(x) - 7.0;
float a = pow(10.0, y);
float b = (float)x;
//c the closest round up float
float c = a + b;
printf("%.12f %.12f %.12f\n", c, b, x);
return 0;
}
Thank you.
Simply assigning a double to float and back should tell, if the float is larger. If it's not, one should simply increment the float by one unit. (for positive floats). If this doesn't still produce expected result, then the double is larger than supported by a float, in which case float should be assigned to Inf.
float next(double a) {
float b=a;
if ((double)b > a) return b;
return std::nextafter(b, std::numeric_limits<float>::infinity());
}
[Hack] C-version of next_after (on selected architectures would be)
float next_after(float a) {
*(int*)&a += a < 0 ? -1 : 1;
return a;
}
Better way to do it is:
float next_after(float a) {
union { float a; int b; } c = { .a = a };
c.b += a < 0 ? -1 : 1;
return c.a;
}
Both of these self-made hacks ignore Infs and NaNs (and work on non-negative floats only). The math is based on the fact, that the binary representations of floats are ordered. To get to next representable float, one simply increments the binary representation by one.
If you use c99, you can use the nextafterf function.
#include <stdio.h>
#include <math.h>
#include <float.h>
int main(){
// x is the double we want to round
double x=100000000005.0;
float c = x;
if ((double)c <= x)
c = nextafterf(c, FLT_MAX);
//c the closest round up float
printf("%.12f %.12f\n",c,x);
return 0;
}
C has a nice nextafter function which will help here;
float toBiggerFloat( const double a ) {
const float test = (float) a;
return ((double) test < a) ? nextafterf( test, INFINITY ) : test;
}
Here's a test script which shows it on all classes of number (positive/negative, normal/subnormal, infinite, nan, -0): http://codepad.org/BQ3aqbae (it works fine on anything is the result)
I am trying to get area of circle using my program. But area is not coming in decimals.
#include<iostream>
using namespace std;
float AreaOfCircle(float r);
int AreaOfCircle(int r);
int main()
{int rad;
cout<<"Enter the Radius of Crircle: ";
cin>>rad;
cout<<"The Are of the Cirlcle: "<<AreaOfCircle(rad);
}
float AreaOfCircle(float r)
{
int area=0;
area=2*3.1456*r*r;
return area;
}
int AreaOfCircle(int r)
{
int area=0;
area=2*3.1456*r*r;
return area;
}
But I need answer to some decimal point.
You're not calling the float version of the method.
Either declare your variable as float
float rad;
or cast it to float before you call the method.
AreaOfCircle((float)rad);
You also need to use float instead of int inside the overloaded method:
float AreaOfCircle(float r)
{
float area=0; // <--- float here
area=2*3.1456*r*r;
return area;
}
Also:
area = pi * r * r
length = 2 * pi * r
pi ~= 3.1415
In addition to answer by #Luchian, you need to change the returned value to a float:
float AreaOfCircle(float r)
{
int area=0; // <<----- float area = 0;
area=2*3.1456*r*r;
return area;
}
change to:
float AreaOfCircle(float r)
{
float area=0;
area=2*3.1456*r*r;
return area;
}
or just:
float AreaOfCircle(float r) { return 2*3.1456*r*r; }
The compiler will call the overload it feels is the best match to the types of parameters it is passed. Because you passed an int, it assumed you wanted the int version.
By casting to a float as Luchian suggested (or using a float in the first place) you are telling the compiler that you intend the parameter to be a float type - thus, it picks the float version.