Here is my code so far. There seems to be soemthing wrong since I keep getting an incorrect answer. I am writing in a text file that is formatted:
2
3.0 1.0
2 being the size of the array and then 3.0 and 1.0 being the coefficients. Hopefully I didnt miss much in my explanation. Any help would be greatly appreciated.
Thanks
double polyeval(double* polyarray, double x, int arraySize)
{
//int result = 0;
if(arraySize == 0)
{
return polyarray[arraySize];
}
//result += x*(polyarray[arraySize]+polyeval(polyarray,x,arraySize-1));
return polyarray[arraySize-1]+ (x* (polyeval(polyarray,x,arraySize-1)));
//return result;
}
int main ()
{
int arraySize;
double x;
double *polyarray;
ifstream input;
input.open("polynomial.txt");
input >> arraySize;
polyarray = new double [arraySize];
for (int a = arraySize - 1; a >= 0; a--)
{
input >> polyarray[a];
}
cout << "For what value x would you like to evaluate?" << endl;
cin >> x;
cout << "Polynomial Evaluation: " << polyeval(polyarray, x, arraySize);
delete [] polyarray;
}
the idea that if i read in a text file of that format varying in size that it will solve for any value x given by the user
Jut taking a wild guess
for (int a = arraySize - 1; a >= 0; a--)
// ^^
{
input >> polyarray[a];
}
One error is here:
for (int a = arraySize - 1; a > 0; a--)
{ //^^should be a >=0
input >> polyarray[a];
}
You are missing some entry this way.
The recursive function should look like the following:
int polyeval(double* polyarray, double x, int arraySize)
{
if(arraySize == 1)
{
return polyarray[arraySize-1];
}
return x*(polyarray[arraySize-1]+polyeval(polyarray,x,arraySize-1));
}
The problem is mainly with the definition of the polynomial coefficients.
Your code assumes a polynomial on the form:
x( p(n) + x( p(n-1) + x( p(n-2) + ... x(p(1) + p(0)))..))
This line:
result += x*(polyarray[arraySize]+polyeval(polyarray,x,arraySize-1));
Should become:
result += pow(x,arraySize)*polyarray[arraySize]+polyeval(polyarray,x,arraySize-1);
This way the polynomial is defined correctly as p(n)x^n + p(n-1)x^(n-1) ... + p1 x + p0
Couldn't work out exactly what you were trying to do, or why you were using recursion. So I whipped up a non-recursive version that seems to give the right results.
#include <iostream>
using namespace std;
double polyeval(const double* polyarray, double x, int arraySize) {
if(arraySize <= 0) { return 0; }
double value = 0;
const double * p = polyarray + (arraySize-1);
for(int i=0; i<arraySize; ++i) {
value *= x;
value += *p;
p--;
}
return value;
}
int main () {
const int arraySize = 3;
const double polyarrayA[3] = {0.0,0.0,1.0}; // 0 + 0 x + 1 x^2
const double polyarrayB[3] = {0.0,1.0,0.0}; // 0 + 1 x + 0 x^2
const double polyarrayC[3] = {1.0,0.0,0.0}; // 1 + 0 x + 0 x^2
cout << "Polynomial Evaluation A f(x) = " << polyeval(polyarrayA, 0.5, arraySize)<<std::endl;
cout << "Polynomial Evaluation B f(x) = " << polyeval(polyarrayB, 0.5, arraySize)<<std::endl;
cout << "Polynomial Evaluation C f(x) = " << polyeval(polyarrayC, 0.5, arraySize)<<std::endl;
}
You can see it running here:
http://ideone.com/HE4r6x
Related
Question:
Write C++ function to evaluate the following formula for a given x:
The following code was designed in C++ on Visual Studio to be a solution of the above mentioned problem. However whenever I run the code what I am returned is the value of x; or the same value I input.
I don't understand what the problem may be, so I would appreciate any help given.
#include <iostream>
using namespace std;
unsigned long fact(int n) {
if (n <= 1) {
return 1;
}
else {
return n * fact(n - 1);
}
}
unsigned long f(int x, int n) {
static unsigned long term;
static unsigned long sum = 0;
do {
term = pow(x, (2 * n + 1)) / fact((2 * n) + 1);
n++;
sum += term;
} while (term < 0.000001);
return sum;
}
int main() {
int y = 0;
int x;
cout << "enter x" << endl;
cin >> x;
cout << f(x, y) << endl;
system("pause");
}
I suggest you don't calculate powers and factorials on each iteration. Each next term can be generated by multiplying the previous one by x^2 / [n(n+1)]:
double sinh_in_disguise(const double x) {
const double x_sq = x * x;
double term = x;
double sum = 0;
double n = 2;
while (true) {
const double new_sum = sum + term;
if (new_sum == sum)
break;
sum = new_sum;
term *= x_sq / (n * (n + 1));
n += 2;
}
return sum;
}
int main() {
std::cout.precision(16);
double x = 2.019;
std::cout << sinh_in_disguise(x) << std::endl; // prints 3.699001094869803
std::cout << std::sinh(x) << std::endl; // prints 3.699001094869803
}
put double datatype in the whole code and it will work perfectly
In my code, I'm trying to prevent circles from overlapping so I specified it as a condition on the distance between the centres of the circles but it seems to not work all the time
as you can see :
could it be some kind of numerical precision rounding problem ?
Here is the relevant code (I can post the whole code if needed):
const double win_size = 800;
const double L = 50e-9; //box size (m)
const double k = 1.38e-23; // Boltzmann constant = 1.38e-23 J/K
const double R = 1.6e-10*30; //N2 radius = 1.6e-10 m
const double m = 4.65e-26; //N2 mass = 4.65e-26 kg
struct parameters{
double x;
double y;
double v_x;
double v_y;
};
bool empty_space(double x, double y, struct parameters gas[], int N, int i){
if (i == 0) return true;
for (int i = 0; i<N; i++){
if (pow(x-gas[i].x,2) + pow(y-gas[i].y,2) <= 4*R*R){
cout << gas[i].x << " " << gas[i].y << endl;
return false;
}
}
return true;
}
void initialize(struct parameters gas[], int N, double T){ // Sets initial conditions (velocity depends on temperature)
int tries = 0;
double x, y;
for (int i=0; i<N; i++){
if (tries == 10000){
cout << "Couldn't fit " << N << " molecules in the box, aborting simulation... " << endl;
exit(1);
}
x = R + (L - 2*R)*rand()/RAND_MAX;
y = R + (L - 2*R)*rand()/RAND_MAX;
if (empty_space(x,y,gas,N,i)){
gas[i].x = x;
gas[i].y = y;
}
else {
i--;
tries++;
}
gas[i].v_x = sqrt(2*k*T/m)*(1-2.0*rand()/RAND_MAX);
gas[i].v_y = (2*(rand()%2) - 1)*sqrt(2*k*T/m - pow(gas[i].v_x, 2));
}
}
void draw(int window, struct parameters gas[], int N, int automatic){
g2_pen(window,g2_ink(window,0.8,0.3,0.4));
for (int i=0; i<N; i++){
g2_circle(window,gas[i].x*win_size/L,gas[i].y*win_size/L,R*win_size/L);
}
g2_flush(window);
usleep(10000);
g2_pen(window,0);
g2_filled_rectangle(window,0,0,win_size,win_size);
if (!automatic) getchar();
}
The first debugging step is to print the coordinates of the circles that have clashed somehow, then see what the "distance" function is returning for their centers. My guess it it's somehow a rounding problem but this seems to be what you need to do next.
I am new too programming and am trying to pass an array of structures and an "option" to a function. I then want the function to be able to manipulate the data within the the array of the struct.
struct coordinates{
int x;
int y;
int z;
}COORD;
The option parameter is an integer that will specify which part of the structure to manipulate.
Manipulate x --- option = 0
Manipulate y --- option = 1
Manipulate z --- option = 2
An example of this is shown below. The function takes the array of structs and makes a 3 point moving average of the data-point specified data point. The issue I am having is that the program I am trying to build has 50+ members in each struct so writing out each if statement by hand is really tedious. What I am asking is if there is a more elegant solution???
#include <iostream>
struct coordinates{
int x;
int y;
int z;
}COORD;
int main() {
COORD points[10];
// Initialising points
for(int i = 0, i < 10, i++){
points[i].x = 1;
points[i].y = 2;
points[i].z = 3;
}
//(struct,startpoint,option)
std::cout << movingaverage(&points,3,1); // Output
}
int movingaverage(COORD *data, int start_point, int option){
if(option == 0) {
// Assigns the "start" value of the sum value.
sum = data[start_point]->x;
sum = sum + data[start_point - 1]->x;
sum = sum + data[start_point + 1]->x;
}
else if(option == 1) {
// Assigns the "start" value of the sum value.
sum = data[start_point]->y;
sum = sum + data[start_point - 1]->y;
sum = sum + data[start_point + 1]->y;
}
else if(option == 2) {
// Assigns the "start" value of the sum value.
sum = data[start_point]->z;
sum = sum + data[start_point - 1]->z;
sum = sum + data[start_point + 1]->z;
}
sum = sum / n;
return sum; //Sum is the moving average
}
Also pointer to members are a possible solution; in combination with a template function, the members can be of different type. But, yes, the syntax is something strange:
#include <iostream>
#include <vector>
using namespace std;
/// calculate the sum of a given structure member in a vector:
template <typename T, typename M>
M membersum(vector<T> array, M (T::*mptr)) {
M sum = 0;
for (int i=0; i<array.size(); i++) {
sum += (array[i].*mptr);
}
return sum;
}
struct Point {
Point(int x, int y, float z): x(x), y(y), z(z) {}
int x;
int y;
float z;
};
int main() {
vector<Point> points;
points.push_back(Point(1,2,3.8));
points.push_back(Point(1,2,4.5));
points.push_back(Point(1,2,1.7));
// your code goes here
cout << "sum x: " << membersum(points, &Point::x) << endl;
cout << "sum y: " << membersum(points, &Point::y) << endl;
cout << "sum z: " << membersum(points, &Point::z) << endl;
return 0;
}
This example I created on ideone.com.
C++ does not support reflection and therefore you cannot iterate over members of a struct. The way I would do this is with a getter function.
template<class Getter>
int movingaverage(COORD *data, int start_point, const Getter &get){
auto sum = get(data[start_point]);
sum = sum + get(data[start_point - 1]);
sum = sum + get(data[start_point + 1]);
return sum;
}
std::cout << "x: " << movingaverage(&points, 3, [](const COORD &coord){return coord.x;}) << '\n';
std::cout << "y: " << movingaverage(&points, 3, [](const COORD &coord){return coord.y;}) << '\n';
std::cout << "z: " << movingaverage(&points, 3, [](const COORD &coord){return coord.z;}) << '\n';
If you or your compiler are confused about the lambda part you can just write a regular function and pass that instead.
I would suggest to use a simple functor.
Class MovingAvg
{
MovingAvg(std::vector<Coordinate> *pSet);
void SetPointSet(std::vector<Coordinate> *p);
double operator()(int startPoint, int option)
{
//calculation here.
double sum = 0;
for(int i = -1; i <= 1; ++i)
{
switch(option)
case 0:
sum += pointSet[startPoint + i].x; //check for bounday conditions.
.................
}
return sum / 3;
}
private:
//container
std::vector<Coordinate> *pointSet;
}
Use it as.
MovAvg mvG(pointSet);
double sum = mvG(startP, option);
//change the private member if the point set must be changed.
Functors are pretty handy in cases like this.
You can try something along the lines of
class coordinates{
private:
int xyz[3]; //implementation detail(!)
public:
int x() const { return xyz[0]; }
int y() const { return xyz[1]; }
int z() const { return xyz[2]; }
//some relevant setters go here
static int movingaverage(COORD *data, int start_point, int option){
sum = data[start_point]->xyz[option];
sum = sum + data[start_point - 1]->xyz[option];
sum = sum + data[start_point + 1]->xyz[option];
}
};
I've been trying to get this solved but without luck.
All I want to do is to differentiate a polynomial like P(x) = 3x^3 + 2x^2 + 4x + 5
At the end of the code, the program should evaluate this function and gives me just the answer.
The derivative of P(x) is P'(x) = 3*3x^2 + 2*2x + 4*1. If x = 1, the answer is 17.
I just don't get that answer no matter how I alter my loop.
/*
x: value of x in the polynomial
c: array of coefficients
n: number of coefficients
*/
double derivePolynomial(double x, double c[], int n) {
double result = 0;
double p = 1;
int counter = 1;
for(int i=n-1; i>=0; i--) //backward loop
{
result = result + c[i]*p*counter;
counter++; // number of power
p = p*x;
}
return result;
}
//Output in main() looks like this
double x=1.5;
double coeffs[4]={3,2.2,-1,0.5};
int numCoeffs=4;
cout << " = " << derivePolynomial(x,coeffs,numCoeffs) << endl;
The derivative of x ^ n is n * x ^ (n - 1), but you are calculating something completely different.
double der(double x, double c[], int n)
{
double d = 0;
for (int i = 0; i < n; i++)
d += pow(x, i) * c[i];
return d;
}
This would work, assuming that your polinomial is in the form c0 + c1x + c2x ^ 2 + ...
Demonstration, with another function that does the derivation as well.
Edit: alternative solution avoiding the use of the pow() function, with simple summation and repeated multiplication:
double der2(double x, double c[], int n)
{
double d = 0;
for (int i = 0; i < n - 1; i++) {
d *= x;
d += (n - i - 1) * c[i];
}
return d;
}
This works too. Note that the functions that take the iterative approach (those which don't use pow()) expect their arguments (the coefficients) in reverse order.
You need to reverse the direction of the loop. Start at 0 and go to n.
At the moment when you compute the partial sum for the n-th power p is 1. For the last one x^0 you your p will contain x^n-1 th power.
double derivePolynomial(double x, double c[], int n) {
double result = 0;
double p = 1;
int counter = 1;
for(int i=1; i<n; i++) //start with 1 because the first element is constant.
{
result = result + c[i]*p*counter;
counter++; // number of power
p = p*x;
}
return result;
}
double x=1;
double coeffs[4]={5,4,2,3};
int numCoeffs=4;
cout << " = " << derivePolynomial(x,coeffs,numCoeffs) << endl;
I have this equation
and
then find the polynomial from
I am trying to implement it like this:
for (int n=0;n<order;n++){
df[n][0]=y[n];
for (int i=0;i<N;i++){ //N number of points
df[n][i]+=factorial(n,i)*y[i+n-1];
}
}
for (int i=0;i<N;i++){
term=factorial(s,i);
result*=df[0][i]*term;
sum+=result;
}
return sum;
1) I am not sure how to implement the sign of every argument in the function.As you can see it goes 'positive' , 'negative', 'positive' ...
2) I am not sure for any mistakes...
Thanks!
----------------------factorial-----------------------------
int fact(int n){
//3!=1*2*3
if (n==0) return 1;
else
return n*fact(n-1);
}
double factorial(double s,int n){
//(s 3)=s*(s-1)*(s-2)/6
if ((n==0) &&(s==0)) return 1;
else
return fact(s)/fact(n);
}
The simplest solution is probably to just keep the sign in
a variable, and multiply it in each time through the loop.
Something like:
sign = 1.0;
for ( int i = 0; i < N; ++ i ) {
term = factorial( s, i );
result *= df[0][i] * term;
sum += sign * result;
sign = - sign;
}
You cannot do pow( -1, m ).
You can write your own:
inline int minusOnePower( unsigned int m )
{
return (m & 1) ? -1 : 1;
}
You may want to build up some tables of calculated values.
Well, I understand you want to approximately calculate the value f(x) for a given x=X, using Newton Interpolation polynomial with equidistant points (more specifically Newton-Gregory forward difference interpolation polynomial).
Assuming s=(X-x0)/h, where x0 is the first x, and h the step to obtain the rest of the x for which you know the exact value of f :
Considere:
double coef (double s, int k)
{
double c(1);
for (int i=1; i<=k ; ++i)
c *= (s-i+1)/i ;
return c;
}
double P_interp_value(double s, int Num_of_intervals , double f[] /* values of f in these points */) // P_n_s
{
int N=Num_of_intervals ;
double *df0= new double[N+1]; // calculing df only for point 0
for (int n=0 ; n<=N ; ++n) // n here is the order
{
df0[n]=0;
for (int k=0, sig=-1; k<=n; ++k, sig=-sig) // k here is the "x point"
{
df0[n] += sig * coef(n,k) * f[n-k];
}
}
double P_n_s = 0;
for (int k=0; k<=N ; ++k ) // here k is the order
{
P_n_s += coef(s,k)* df0[k];
}
delete []df0;
return P_n_s;
}
int main()
{
double s=0.415, f[]={0.0 , 1.0986 , 1.6094 , 1.9459 , 2.1972 };
int n=1; // Num of interval to use during aproximacion. Max = 4 in these example
while (true)
{
std::cin >> n;
std::cout << std::endl << "P(n=" << n <<", s=" << s << ")= " << P_interp_value(s, n, f) << std::endl ;
}
}
it print:
1
P(n=1, s=0.415)= 0.455919
2
P(n=2, s=0.415)= 0.527271
3
P(n=3, s=0.415)= 0.55379
4
P(n=4, s=0.415)= 0.567235
compare with:
http://ecourses.vtu.ac.in/nptel/courses/Webcourse-contents/IIT-KANPUR/Numerical%20Analysis/numerical-analysis/Rathish-kumar/rathish-oct31/fratnode8.html
It works. Now we can start to optimize these code.
just for the sign ;-)
inline signed int minusOnePower( unsigned int m )
{
return 1-( (m & 1)<<1 );
}