Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursive Return Statement Does Not Return Variable Correctly

Tags:

c++

c++11

I am having trouble getting my function to return a variable properly.

I print the variable that I want to return above the return statement, and it looks fine. Once I attempt to return the value and print it onto the console though it instead prints -nan(ind). I do not understand why this is happening.

I am programming in C++, using Visual Studio. I am using this library to parse strings into expressions: http://www.partow.net/programming/exprtk/index.html

Here is the function and the statement that prints its results:

#include "stdafx.h"
#include "exprtk.hpp"
#include <iostream>
#include <string>
#include <algorithm>
#include <cmath>

typedef double T; // numeric type (float, double, mpfr etc...)
typedef exprtk::expression<T>     expression_t;
typedef exprtk::parser<T>             parser_t;
expression_t expression;
parser_t parser;

bool closeEnough(std::string value1, std::string value2, double levelOfSimilarity) {

    if (abs( std::stod(value1) ) - abs (std::stod(value2) ) > levelOfSimilarity) {
        return false;
    }
    else {
        return true;
    }
}

std::string replaceChars2Strings(std::string string, const std::string& start, const std::string& end) {

    size_t init_pos = 0;

    while ((init_pos = string.find(start, init_pos)) != std::string::npos) {
        string.replace(init_pos, start.length(), end);
    }
    return string;
}

double FofX(std::string function, std::string value) {

    std::string newfunction = replaceChars2Strings(function, std::string("x"), value);


    if (!parser.compile(newfunction, expression))
    {
        printf("Something went wrong when the expression was being parsed");
    }

    T result = expression.value();

    return result;
}

double DofFofX(std::string function, std::string value) {

    std::string SDplus = replaceChars2Strings(function, std::string("x"), "(" + value + "+" + "0.00001" + ")");
    std::string SDminus = replaceChars2Strings(function, std::string("x"), "(" + value + "-" + "0.00001" + ")");

    if (!parser.compile(SDplus, expression))
    {
        printf("Something went wrong when Dplus was being parsed");
    }
    T Dplus = expression.value();

    if (!parser.compile(SDminus, expression))
    {
        printf("Something went wrong when Dminus was being parsed");
    }
    T Dminus = expression.value();

    return (Dplus - Dminus) / 0.00002;
}

double newton(std::string function, std::string guess) {
    double guess2;
    //std::cout << "guess:" << guess << std::endl;

    //in here () are taken off so that the compiler can calculate the value of guess 2 easier
    guess2 = std::stod(guess.substr(1, guess.size() - 2)) - FofX(function, guess) / DofFofX(function, guess);

    //std::cout << "guess 2:" << guess2 << std::endl;

    //take the () off of guess before we give it away
    if (closeEnough(guess.substr(1, guess.size() - 2), std::to_string(guess2), 0.001)) {
        std::cout << "final guess  = " << guess2 << std::endl;
        return guess2;
    }
    else {
        //put the () back on before we give it away so that the parser can read things as multiplication right
        newton(function, "(" + std::to_string(guess2) + ")");
    }
}

int main()
{
    std::string function = "x*x";
    //remember to put () around guess
    std::string guess = "(5)";

    double answer = newton(function, guess);

    return 0;
}

When this program runs it prints this:

final guess  = 0.0006105
solution = -nan(ind)

Does anyone have an idea as to what is happening between when I print the final guess and when I print the solution?

like image 922
Zeke Medley Avatar asked Apr 06 '26 11:04

Zeke Medley


1 Answers

The issue was that I wasn't returning the recursive function in my else statement.

The final code looks like this:

// Newtons Method V1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "exprtk.hpp"
#include <iostream>
#include <string>
#include <algorithm>
#include <cmath>

typedef double T; // numeric type (float, double, mpfr etc...)
typedef exprtk::expression<T>     expression_t;
typedef exprtk::parser<T>             parser_t;
expression_t expression;
parser_t parser;

bool closeEnough(std::string value1, std::string value2, double levelOfSimilarity) {

    if (abs( std::stod(value1) ) - abs (std::stod(value2) ) > levelOfSimilarity) {
        return false;
    }
    else {
        return true;
    }
}

std::string replaceChars2Strings(std::string string, const std::string& start, const std::string& end) {

    size_t init_pos = 0;

    while ((init_pos = string.find(start, init_pos)) != std::string::npos) {
        string.replace(init_pos, start.length(), end);
    }
    return string;
}

double FofX(std::string function, std::string value) {

    std::string newfunction = replaceChars2Strings(function, std::string("x"), value);


    if (!parser.compile(newfunction, expression))
    {
        printf("Something went wrong when the expression was being parsed");
    }

    T result = expression.value();

    return result;
}

double DofFofX(std::string function, std::string value) {

    std::string SDplus = replaceChars2Strings(function, std::string("x"), "(" + value + "+" + "0.00001" + ")");
    std::string SDminus = replaceChars2Strings(function, std::string("x"), "(" + value + "-" + "0.00001" + ")");

    if (!parser.compile(SDplus, expression))
    {
        printf("Something went wrong when Dplus was being parsed");
    }
    T Dplus = expression.value();

    if (!parser.compile(SDminus, expression))
    {
        printf("Something went wrong when Dminus was being parsed");
    }
    T Dminus = expression.value();

    return (Dplus - Dminus) / 0.00002;
}

double newton(std::string function, std::string guess) {
    double guess2;
    //std::cout << "guess:" << guess << std::endl;

    //in here () are taken off so that the compiler can calculate the value of guess 2 easier
    guess2 = std::stod(guess.substr(1, guess.size() - 2)) - FofX(function, guess) / DofFofX(function, guess);

    //std::cout << "guess 2:" << guess2 << std::endl;

    //take the () off of guess before we give it away
    if (closeEnough(guess.substr(1, guess.size() - 2), std::to_string(guess2), 0.00001)) {
        std::cout << "final guess  = " << guess2 << std::endl;
        return guess2;
    }
    else {
        return newton(function, "(" + std::to_string(guess2) + ")");
    }
}

int main()
{
    std::string function = "2^x - x^2";
    //remember to put () around guess
    std::string guess = "(-2)";

    double answer = newton(function, guess);
    std::cout << answer << std::endl;

    return 0;
}
like image 102
Zeke Medley Avatar answered Apr 08 '26 23:04

Zeke Medley



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!