Sizing down the value of 'g' for projectile motion - c++

For my school project, my team is doing a paper toss game. You get the input for angle and velocity manually from the user. For calculating the X & Y co-ordinates of the projectile I use the formula
y= x * tan(a) - (g * X * X/2 * U * cos(a))
When is run this , after a certain point of time i start getting absurd values, such as -500 or -1000 for Y. Sometimes it reaches -60000. I suspect that this is because of 'g'. Please help me out with this problem.
I forgot to say that i am running a loop , for x=0 to some value (co-ordinate which corresponds to range , specifically). Also we are supposed to code using MD-DOS IDE'S(like turbo c++; our textbooks are old) and i code using Turbo c++.
I have tried setting different values for 'g' like 0.01 and 1, but nothing seems to work.
#include <iostream.h>
#include <conio.h>
#include <math.h>
{clrscr();
void projectile(int u , int a) //function which calculates values of X&Y
{int vcos=cos(a),vtan=tan(a),x,y,int g=10;
for(x=0;x<200;x++)
{ int p=((g*x*x)/(2*u*vcos*vcos));
y=(x*vtan)-p;
cout<<x<<","<<y; //cout statement to check the co-ordinates.
}
}
As values of X increase, I get really crazy outputs for Y like -32500 or -17000. I really suspect this due to the value of 'g' being used. Else it is a problem in calculating the angle value for each and every stage in the projectile. If anything else, please point out. Also please answer with functions or header files that are used in MD-DOS IDE'S (turbo c++ to be specific)

The main error seems to be using int variables for floating point quantities.
int vcos=cos(a),vtan=tan(a);
int p = ...;
In the calculation these are clearly continuously varying quantities which should be represented in a C++ program by a double.
double vcos=cos(a),vtan=tan(a);
double g = 0.01;
double p = ...;
etc.

Related

Confusion about formula for Linear regression with gradient descent, (Pseudocode)

I'm made a program that calculates the line of best fit of a set of data points using gradient descent. I generate a 1000 random points and then it calculates the line of best fit training on these 1000 points. My confusion lies in the theory of my code.
In the part of my code where the training function is, by using the current m and b values for y= mx +b, the function makes a guess of the y values when it goes through the training points x values. This is supervised learning, so I know what the actual y value is, the function calculates the error and using that error adjusts the m and b values. <-- What is happening in the program when adjusting the line of best fit
I get everything above ^. what I'm confused about is the part of the code that calculates how to adjust these m and b values. Here it is:
guess = m * x + b;
error = y - guess;
m = m + (error * x) * learningrate;
b = b + error * learningrate;
Im confused about why we add instead of subtract that delta m (the (error * x) *learningrate)) part. Ignoring the learningrate, the error * x part is the partial derivative of the error with respect to m. But if we took the partial derivative of something with respect to something, wouldn't it give us the direction of the steepest ascent? Shouldn't we go the opposite direction (subtract the delta m) to get the proper m value? Isn't our goal to reduce the error?
Surprisingly to me, the above code works, if you add the delta m, it adjusts the m and b values in the right direction. So basically my question is: Why aren't we subtracting the delta m part (error *x) as it is pointing in the direction of steepest ascent, and we want to get the opposite of that?
Thanks!

Physics simulation gives (very) inaccurate positions for simple trajectories calculus

I want to implement a physics engine in a game in order to compute trajectories of bodies with forces applied to them.
This engine would calculate each state of the object based on its previous state. Of course this means a lot of calculation between two units of time to be sufficiently precise.
To do that properly, I wanted first to know how big are the differences between this method of getting positions, and with kinematic equations.
So I made this code which stores the positions (x, y, z) given by the simulations and by the equations in a file.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "header.h"
Body nouveauCorps(Body body, Vector3 force, double deltaT){
double m = body.mass;
double t = deltaT;
//Newton's second law:
double ax = force.x/m;
double ay = force.y/m;
double az = force.z/m;
body.speedx += ax*t;
body.speedy += ay*t;
body.speedz += az*t;
body.x +=t*body.speedx;
body.y +=t*body.speedy;
body.z +=t*body.speedz;
return body;
}
int main()
{
//Initial conditions:
double posX = 1.4568899;
double posY = 5.6584225;
double posZ = -8.8944444;
double speedX = 0.232323;
double speedY = -1.6565656;
double speedZ = -8.6565656;
double mass = 558.74;
//Force applied:
Vector3 force = {5.8745554, -97887.568, 543.5875};
Body body = {posX, posY, posZ, speedX, speedY, speedZ, mass};
double duration = 10.0;
double pointsPS = 100.0; //Points Per Second
double pointsTot = duration * pointsPS;
char name[20];
sprintf(name, "BN_%fs-%fpts.txt", duration, pointsPS);
remove(name);
FILE* fichier = NULL;
fichier = fopen(name, "w");
for(int i=1; i<=pointsTot; i++){
body = nouveauCorps(body, force, duration/pointsTot);
double t = i/pointsPS;
//Make a table: TIME | POS_X, Y, Z by simulation | POS_X, Y, Z by modele (reference)
fprintf(fichier, "%e \t %e \t %e \t %e \t %e \t %e \t %e\n", t, body.x, body.y, body.z, force.x*(t*t)/2.0/mass + speedX*t + posX, force.y*(t*t)/2.0/mass + speedY*t + posY, force.z*(t*t)/2.0/mass + speedZ*t + posZ);
}
return 0;
}
The problem is that with simple numbers (like with a simple fall in a -9.81 gravity field) I got nice positions, but with bigger (and quite random) numbers, I get inaccurate positions.
Is that a floating point issue?
Here are the results, with relative errors. (Note: label axes are in French, Temps = Time).
Graphs
Black+dashed : values from kinematic equations
Red : 100 points per second
Orange : 1000 points per second
Green : 10000 points per second
This is not a floating point issue. In fact, even if you were using exact arithmetic you'd see the same problem.
This error is really fundamental to numerical integration itself and the particular method you're using and the ODE you're solving.
In this case you're using an integration scheme known as Forward Euler. This is probably the simplest approach to solving a first-order ODE. Of course, this leaves it with some undesirable features.
For one, it introduces error at each step. The size of the error is O(Δt²). That means the error over a single time step is roughly proportional to the square of the size of the time step. So if you cut the size of the time step in half, roughly you drop the incremental error to 1/4 the value.
But since you decrease the time step, you have to make more steps to simulate the same amount of time. So you're adding up more but smaller errors. This is why the cumulative error is O(Δt). So really over the whole simulated time if you take time steps that are half as big, you get half as much cumulative error.
Ultimately this cumulative error is what you're seeing. And you can see in your error plot that the ultimate error ends up decreasing by about a factor of 10 each time you increase the number of time steps by a factor of 10: because the time step is 10 times smaller, so the total error ends up about 10 times smaller.
The other issue is that Forward Euler exhibits what's known as conditional stability. This means it's possible for the cumulative error to grow without bound in certain cases. To see why, let's look at a simple ODE:
x' = -k * x
Where k is some constant. The exact solution of this ODE is x(t) = x(0) * exp( -k * t ). So as long as k is positive, x should tend to 0 as time increases.
However, if we try to approximate this using Forward Euler, we get something that looks like this:
x(t + Δt) = x(t) + Δt * ( -k * x[n] )
= ( 1 - k * Δt ) * x(t)
This is a simple recurrence relation that we can solve:
x(t) = ( 1 - k * Δt )^(t / Δt) * x(0)
Now, we know the exact solution tens to 0 as t gets larger. But the Forward Euler solution only does that if |1 - k * Δt| < 1. Notice how that expression depends on the step size as well as the k term from our ODE. If k is really really big, we need a really really tiny time step to keep the solution from blowing up. This is why it possesses what's known as conditional stability: the stability of the solution is conditional on the time step.
There are also a number of other issues, but this is a broad topic and I can't cover everything in a single answer.

Solving equation for y

When testing out the equation I get a -1.#IND00 as an answer when it solves for y. I'm basically trying to create a program that solves for y give the equation below
y=y/(3/17)-z+x/(a%2)+PI
#include <stdio.h>
#include <math.h>
#define PI 3.14
int main (void)
{
int a=0;
double z=0,x=0,y=0;
printf("Values for x, z, and a:");
scanf("%lf%lf%d", &x,&z,&a);
y = (((y/(double)(3/17)))-z + (x/(a%2))+PI);
printf("y = %lf\n", y);
return 0;
}
Since there are no questionmarks, I assume the question is "How do you write a C++ program that solves this equation?"
C++ is a programming language and by itself is not able to solve your equation, i.e. C++ won't do any transformation to your equation to get it into a form where y occurs only on the lefthand side and all parameters on the righthand side. You have to transform it yourself, manually or by using a solver.
What happens in the posted code?
Lets start at the leftmost part of the equation y/(double)(3/17) from inside out according to the parentheses:
3/17 is interpreted as integer division, which results in 0;
(double)(0) casts the integer 0 into a double of 0.0;
y/0.0 is a division by 0 as explained in this post which results in your error.
You could fix this as pointed out in the comments by either casting the first integer like (double)3/17 or turning the integer 3 into a double 3.0 or using static_cast.
However, y is still initialized to 0, so y/(double)3/17 is 0 and the equation calculated is basically -z + x/(a%2) + PI.
So, unless you transform the equation and put the transformed equation into the code, you won't get the results you expect.

Curvature Scale Space corner detection algorithm. Arc Length Parameter?

I'm studying about the CSS algorithm and I don't get the hang of the concept of 'Arc Length Parameter'.
According to the literature, planar curve Gamma(u)=(x(u),y(u)) and they say this u is the arc length parameter and apparently, Gaussian Kernel g is also parameterized by this u here.
Stop me if I got something wrong but, aren't x and y location of the pixel? How is it represented by another parameter?
I had no idea when I first saw it on the literature so, I looked up the code. and apparently, I got puzzled even more.
here is the portion of the code
void getGaussianDerivs(double sigma, int M, vector<double>& gaussian,
vector<double>& dg, vector<double>& d2g) {
int L = (M - 1) / 2;
double sigma_sq = sigma * sigma;
double sigma_quad = sigma_sq*sigma_sq;
dg.resize(M); d2g.resize(M); gaussian.resize(M);
Mat_<double> g = getGaussianKernel(M, sigma, CV_64F);
for (double i = -L; i < L+1.0; i += 1.0) {
int idx = (int)(i+L);
gaussian[idx] = g(idx);
// from http://www.cedar.buffalo.edu/~srihari/CSE555/Normal2.pdf
dg[idx] = (-i/sigma_sq) * g(idx);
d2g[idx] = (-sigma_sq + i*i)/sigma_quad * g(idx);
}
}
so, it seems the code uses simple 1D Gaussian Kernel Aperture size of M and it is trying to compute its 1st and 2nd derivatives. As far as I know, 1D Gaussian kernel has parameter of x which is a horizontal coordinate and sigma which is scale. it seems like that 'arc length parameter u' is equivalent to the variable of x. That doesn't make any sense because later in the code, it directly convolutes the set of x and y on the contour.
what is this u?
PS. since I replied to the fellow who tried to answer my question, I think I should modify my question, so, here we go.
What I'm confusing is, how is this parameter 'u' implemented in codes? I think I understood the full code above -of course, I inserted only a portion of the code- but the problem is, I have no idea about what it would be for the 'improved' version of the algorithm. It says it's using 'affine length parameter' instead of this 'arc length parameter' and I'm not so sure how I implement the concept into the code.
According to the literature, the main difference between arc length parameter and affine length parameter is it's sampling interval and arc length parameter uses 1 for the vertical and horizontal direction and root of 2 for the diagonal direction. It makes sense since the portion of the code above is using for loop to compute 1st and 2nd derivatives of the 1d Gaussian and it directly inserts the value of interval 1 but, how is it gonna be with different interval with different variable? Is it possible that I'm not able to use 'for loop' for it?

lagrange approximation -c++

I updated the code.
What i am trying to do is to hold every lagrange's coefficient values in pointer d.(for example for L1(x) d[0] would be "x-x2/x1-x2" ,d1 would be (x-x2/x1-x2)*(x-x3/x1-x3) etc.
My problem is
1) how to initialize d ( i did d[0]=(z-x[i])/(x[k]-x[i]) but i think it's not right the "d[0]"
2) how to initialize L_coeff. ( i am using L_coeff=new double[0] but am not sure if it's right.
The exercise is:
Find Lagrange's polynomial approximation for y(x)=cos(π x), x ∈−1,1 using 5 points
(x = -1, -0.5, 0, 0.5, and 1).
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;
const double pi=3.14159265358979323846264338327950288;
// my function
double f(double x){
return (cos(pi*x));
}
//function to compute lagrange polynomial
double lagrange_polynomial(int N,double *x){
//N = degree of polynomial
double z,y;
double *L_coeff=new double [0];//L_coefficients of every Lagrange L_coefficient
double *d;//hold the polynomials values for every Lagrange coefficient
int k,i;
//computations for finding lagrange polynomial
//double sum=0;
for (k=0;k<N+1;k++){
for ( i=0;i<N+1;i++){
if (i==0) continue;
d[0]=(z-x[i])/(x[k]-x[i]);//initialization
if (i==k) L_coeff[k]=1.0;
else if (i!=k){
L_coeff[k]*=d[i];
}
}
cout <<"\nL("<<k<<") = "<<d[i]<<"\t\t\tf(x)= "<<f(x[k])<<endl;
}
}
int main()
{
double deg,result;
double *x;
cout <<"Give the degree of the polynomial :"<<endl;
cin >>deg;
for (int i=0;i<deg+1;i++){
cout <<"\nGive the points of interpolation : "<<endl;
cin >> x[i];
}
cout <<"\nThe Lagrange L_coefficients are: "<<endl;
result=lagrange_polynomial(deg,x);
return 0;
}
Here is an example of lagrange polynomial
As this seems to be homework, I am not going to give you an exhaustive answer, but rather try to send you on the right track.
How do you represent polynomials in a computer software? The intuitive version you want to archive as a symbolic expression like 3x^3+5x^2-4 is very unpractical for further computations.
The polynomial is defined fully by saving (and outputting) it's coefficients.
What you are doing above is hoping that C++ does some algebraic manipulations for you and simplify your product with a symbolic variable. This is nothing C++ can do without quite a lot of effort.
You have two options:
Either use a proper computer algebra system that can do symbolic manipulations (Maple or Mathematica are some examples)
If you are bound to C++ you have to think a bit more how the single coefficients of the polynomial can be computed. You programs output can only be a list of numbers (which you could, of course, format as a nice looking string according to a symbolic expression).
Hope this gives you some ideas how to start.
Edit 1
You still have an undefined expression in your code, as you never set any value to y. This leaves prod*=(y-x[i])/(x[k]-x[i]) as an expression that will not return meaningful data. C++ can only work with numbers, and y is no number for you right now, but you think of it as symbol.
You could evaluate the lagrange approximation at, say the value 1, if you would set y=1 in your code. This would give you the (as far as I can see right now) correct function value, but no description of the function itself.
Maybe you should take a pen and a piece of paper first and try to write down the expression as precise Math. Try to get a real grip on what you want to compute. If you did that, maybe you come back here and tell us your thoughts. This should help you to understand what is going on in there.
And always remember: C++ needs numbers, not symbols. Whenever you have a symbol in an expression on your piece of paper that you do not know the value of you can either find a way how to compute the value out of the known values or you have to eliminate the need to compute using this symbol.
P.S.: It is not considered good style to post identical questions in multiple discussion boards at once...
Edit 2
Now you evaluate the function at point y=0.3. This is the way to go if you want to evaluate the polynomial. However, as you stated, you want all coefficients of the polynomial.
Again, I still feel you did not understand the math behind the problem. Maybe I will give you a small example. I am going to use the notation as it is used in the wikipedia article.
Suppose we had k=2 and x=-1, 1. Furthermore, let my just name your cos-Function f, for simplicity. (The notation will get rather ugly without latex...) Then the lagrangian polynomial is defined as
f(x_0) * l_0(x) + f(x_1)*l_1(x)
where (by doing the simplifications again symbolically)
l_0(x)= (x - x_1)/(x_0 - x_1) = -1/2 * (x-1) = -1/2 *x + 1/2
l_1(x)= (x - x_0)/(x_1 - x_0) = 1/2 * (x+1) = 1/2 * x + 1/2
So, you lagrangian polynomial is
f(x_0) * (-1/2 *x + 1/2) + f(x_1) * 1/2 * x + 1/2
= 1/2 * (f(x_1) - f(x_0)) * x + 1/2 * (f(x_0) + f(x_1))
So, the coefficients you want to compute would be 1/2 * (f(x_1) - f(x_0)) and 1/2 * (f(x_0) + f(x_1)).
Your task is now to find an algorithm that does the simplification I did, but without using symbols. If you know how to compute the coefficients of the l_j, you are basically done, as you then just can add up those multiplied with the corresponding value of f.
So, even further broken down, you have to find a way to multiply the quotients in the l_j with each other on a component-by-component basis. Figure out how this is done and you are a nearly done.
Edit 3
Okay, lets get a little bit less vague.
We first want to compute the L_i(x). Those are just products of linear functions. As said before, we have to represent each polynomial as an array of coefficients. For good style, I will use std::vector instead of this array. Then, we could define the data structure holding the coefficients of L_1(x) like this:
std::vector L1 = std::vector(5);
// Lets assume our polynomial would then have the form
// L1[0] + L2[1]*x^1 + L2[2]*x^2 + L2[3]*x^3 + L2[4]*x^4
Now we want to fill this polynomial with values.
// First we have start with the polynomial 1 (which is of degree 0)
// Therefore set L1 accordingly:
L1[0] = 1;
L1[1] = 0; L1[2] = 0; L1[3] = 0; L1[4] = 0;
// Of course you could do this more elegant (using std::vectors constructor, for example)
for (int i = 0; i < N+1; ++i) {
if (i==0) continue; /// For i=0, there will be no polynomial multiplication
// Otherwise, we have to multiply L1 with the polynomial
// (x - x[i]) / (x[0] - x[i])
// First, note that (x[0] - x[i]) ist just a scalar; we will save it:
double c = (x[0] - x[i]);
// Now we multiply L_1 first with (x-x[1]). How does this multiplication change our
// coefficients? Easy enough: The coefficient of x^1 for example is just
// L1[0] - L1[1] * x[1]. Other coefficients are done similary. Futhermore, we have
// to divide by c, which leaves our coefficient as
// (L1[0] - L1[1] * x[1])/c. Let's apply this to the vector:
L1[4] = (L1[3] - L1[4] * x[1])/c;
L1[3] = (L1[2] - L1[3] * x[1])/c;
L1[2] = (L1[1] - L1[2] * x[1])/c;
L1[1] = (L1[0] - L1[1] * x[1])/c;
L1[0] = ( - L1[0] * x[1])/c;
// There we are, polynomial updated.
}
This, of course, has to be done for all L_i Afterwards, the L_i have to be added and multiplied with the function. That is for you to figure out. (Note that I made quite a lot of inefficient stuff up there, but I hope this helps you understanding the details better.)
Hopefully this gives you some idea how you could proceed.
The variable y is actually not a variable in your code but represents the variable P(y) of your lagrange approximation.
Thus, you have to understand the calculations prod*=(y-x[i])/(x[k]-x[i]) and sum+=prod*f not directly but symbolically.
You may get around this by defining your approximation by a series
c[0] * y^0 + c[1] * y^1 + ...
represented by an array c[] within the code. Then you can e.g. implement multiplication
d = c * (y-x[i])/(x[k]-x[i])
coefficient-wise like
d[i] = -c[i]*x[i]/(x[k]-x[i]) + c[i-1]/(x[k]-x[i])
The same way you have to implement addition and assignments on a component basis.
The result will then always be the coefficients of your series representation in the variable y.
Just a few comments in addition to the existing responses.
The exercise is: Find Lagrange's polynomial approximation for y(x)=cos(π x), x ∈ [-1,1] using 5 points (x = -1, -0.5, 0, 0.5, and 1).
The first thing that your main() does is to ask for the degree of the polynomial. You should not be doing that. The degree of the polynomial is fully specified by the number of control points. In this case you should be constructing the unique fourth-order Lagrange polynomial that passes through the five points (xi, cos(π xi)), where the xi values are those five specified points.
const double pi=3.1415;
This value is not good for a float, let alone a double. You should be using something like const double pi=3.14159265358979323846264338327950288;
Or better yet, don't use pi at all. You should know exactly what the y values are that correspond to the given x values. What are cos(-π), cos(-π/2), cos(0), cos(π/2), and cos(π)?