-1

First of all, I am a physics student, not a programmer so please forgive this trivial problem. I am trying to create a function to find the roots of a cubic equation using the Newton Raphson method. I have created code that pretty much works just fine but the point of the exercise is to have this code in 'function' form, i.e return type, parameters then code block. When I try to put it into this form my code will compile but when i input into it the results (roots which it returns) are jibberish. Here is my code.

#include<iostream>
#include<cmath>

double roots(double,double,double,double);

int main()
{
    double x3,x2,x,con;
    std::cin>>x3,x2,x,con;

    double result=roots(x3,x2,x,con);
    std::cout<<result<<std::endl;
    system("pause");
}

double roots(double xcubecoeff, double xsquarecoeff, double xcoeff, double constant)
{
    int j=0;
    int k=0;
    int l=0;
    int m=0;
    double seedvalue1=-10;
    double seedvalue2=10;
    double seedvalue3=0.3;
    double seedvalue4=-0.3;
    double xnplus1;
    double xnplus2;
    double xnplus3;

    while(j <= 100)
    {
        //func is just the structure of the cubic equation in terms of the 
        // parameters of the function
        //derfunc is just the structure of the gneral derivitive of a cuic
        // function, again in terms of the parameters
        //seedvalues are just the initial values for x in the general cubic
        // equation. 
        //Seedvalue one goes into the loop to find the negative x root, 
        // seedvalue 2 finds the positive one, seedvalue three attempts to
        // find the one in the middle of those, however if it just finds
        // either of those again then an IF statement and seedvalue 4 are
        //used to find it.

        double func = xcubecoeff * (seedvalue1 * seedvalue1 * seedvalue1) +
                      xsquarecoeff * (seedvalue1 * seedvalue1) + 
                      xcoeff * seedvalue1 + 
                      constant;

        double derfunc = 3 * xcubecoeff * (seedvalue1 * seedvalue1) +
                         2 * xsquarecoeff * seedvalue1 + 
                         xcoeff;


        double xnplus1 = seedvalue1 - (func / derfunc);

        seedvalue1=xnplus1;
        j++;
    }


    while(k <= 100)
    {
        double func = xcubecoeff * (seedvalue2 * seedvalue2 * seedvalue2) + 
                      xsquarecoeff * (seedvalue2 * seedvalue2) + 
                      xcoeff * seedvalue2 +
                      constant;

        double derfunc = 3 * xcubecoeff * (seedvalue2 * seedvalue2) + 
                         2 * xsquarecoeff * seedvalue2 +
                         xcoeff;

        double xnplus2 = seedvalue2 - (func / derfunc);

        seedvalue2 = xnplus2;
        k++;
    }

    while(l<=100)
    {
        double func = xcubecoeff * (seedvalue3 * seedvalue3 * seedvalue3) + 
                      xsquarecoeff * (seedvalue3 * seedvalue3) +
                      xcoeff * seedvalue3 +
                      constant;

        double derfunc = 3 * xcubecoeff * (seedvalue3 * seedvalue3) + 
                         2 * xsquarecoeff * seedvalue3 + 
                         xcoeff;

        double xnplus3 = seedvalue3 - (func / derfunc);

        seedvalue3=xnplus3;
        l++;
    }

    if(seedvalue3 == seedvalue1 || seedvalue3 == seedvalue2)
    {
        while(m<=100)
        {
            double func = xcubecoeff * (seedvalue4 * seedvalue4 * seedvalue4) +
                          xsquarecoeff * (seedvalue4 * seedvalue4) + 
                          xcoeff * seedvalue4 +
                          constant;

            double derfunc = 3 * xcubecoeff * (seedvalue4 * seedvalue4) +
                             2 * xsquarecoeff * seedvalue4 + xcoeff;

            double xnplus4 = seedvalue4 - (func / derfunc);

            seedvalue4=xnplus4;
            m++;
        }

        std::cout<<seedvalue1<<std::endl;
        std::cout<<seedvalue2<<std::endl;
        std::cout<<seedvalue4<<std::endl;
    }
    else
    {

        std::cout<<seedvalue1<<std::endl;
        std::cout<<seedvalue2<<std::endl;
        std::cout<<seedvalue3<<std::endl;
    }
}

This is probably a really clunky and cumbersome code and I'm sure there is a better way to perform the Newton Raphson method. So to be clear, I start by including the standard iostream and math. Then I declare my function, the name followed by the parameter types that can be passed to it. Next I begin my code. I initialise the variables x3, x2, x and con as doubles and use the import 'cin' to allow users to input values for these, which will be the coefficients of the cubic equation. Next I call the function and put the variable names initialised above which I believe then means that the users inputted values will be passed into the function for use within the function. Below this I programme it to print the output of the function. Under that is the definition of the function which apart from the function name and parameters is how I wrote it in a different cpp which worked just fine, it was only when I wrote this code, trying to put the original code into function form that the problems occurred.

As I say this code is probably very ugly and inefficient but it does work to some extent, I just cant work out why it doesnt work in this form.

I hope you can help,

I will try and clarify if you have any further questions.

Nik Bougalis
  • 10,495
  • 1
  • 21
  • 37

3 Answers3

3

Your function needs to return a value, you are missing a return statement at the end:

return value; // instead of "value", pick the variable you want to return
Daniel Frey
  • 55,810
  • 13
  • 122
  • 180
2

The following is wrong:

double x3,x2,x,con;
std::cin>>x3,x2,x,con;

This invokes the comma operator which doesn't do what you think it does.

You should do this:

std::cout << "Enter x3: ";
std::cin >> x3;
std::cout << "Enter x2: ";
std::cin >> x2;
std::cout << "Enter x: ";
std::cin >> x;
std::cout << "Enter c: ";
std::cin >> con;

If you want to combine them into a single line:

std::cin >> x3 >> x2 >> x >> con;
Nik Bougalis
  • 10,495
  • 1
  • 21
  • 37
2

One problem is with this line

std::cin>>x3,x2,x,con;

This isn't doing what you think it is! The commas here are actually the "comma operator" which evaluates both its operands and takes on the value of the rightmost one. It has lower precedence than >> so your line means the same as

((((std::cin>>x3), x2), x), con);

which reads from cin into x3 and then goes on to evaluate the variables x2, x and con - this doesn't do anything because evaluating a variable has no side-effects. To read into all 4 variables you can use:

std::cin >> x3 >> x2 >> x >> con;

It's a good idea to turn on as many compiler warnings as possible because it will often pick up on things like this. For example if I compile those lines of your code with gcc -Wall -Wextra it gives these warnings:

test.cpp: In function 'int main()':
test.cpp:5:17: warning: right operand of comma operator has no effect [-Wunused-value]
test.cpp:5:19: warning: right operand of comma operator has no effect [-Wunused-value]
test.cpp:5:22: warning: right operand of comma operator has no effect [-Wunused-value]
Mike Dinsdale
  • 1,491
  • 9
  • 8