C++ Bisection Algorithm for a Quadratic Equation - c++

I had a prior snag with this problem that was resolved but I felt that since the nature of my new issue is not related to successful compiling, rather to actual logic of the code, that it would be acceptable to make a new topic. Here is my code so far:
#include "assign4.h"
#include <iostream>
using namespace std;
int main(int argc, char * argv[]){
solution s;
double root;
cout << "Enter interval endpoints: ";
cin >> s.xLeft >> s.xRight;
cout << "Enter tolerance: ";
cin >> s.epsilon;
root = s.bisect (s.xLeft, s.xRight, s.epsilon, &solution::f, s.error);
if (!(s.error))
cout << "Root found at " << root << "\nValue of f(x) at root is: " << s.f(root) << "\n";
else {
cout << "The solution of a quadratic equation with coefficients: " << endl;
// cout << "a = " << a << ", b = " << b << ", c = " << c << endl;
cout << "has not been found." << endl;
}
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "assign4.h"
#include <iostream>
#include <math.h>
using namespace std;
double solution::bisect (double xLeft, double xRight, double epsilon, double (solution::*f)(double), bool& error) {
double xMid;
double fLeft, fRight;
double fMid;
fLeft = (this->*f)(xLeft);
fRight = (this->*f)(xRight);
error = (fLeft * fRight) < 0;
if (error)
return -999.0;
for (double i = 0; i < 20; i++) {
xMid = (xLeft + (xLeft + 1.0)) / 2.0;
fMid = (this->*f)(xMid);
if (fLeft * fMid > 0.0) {
xLeft = xMid + 0.5;
xRight = xLeft + 1.0;
fLeft = fMid;
}
else if (fLeft * fMid < 0.0){
xRight = xMid;
fRight = fMid;
}
else {
return xMid;
}
cout << "New Interval is [" << xLeft << ", " << xRight << "]" << endl;
}
return (xLeft + xRight) / 2.0;
}
double solution::f (double x) {
return ((1 * pow(x,2.0)) + (5 * x) + 2);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef ASSIGN4_H
#define ASSIGN4_H
class solution {
public:
double xLeft, xRight;
double epsilon;
bool error;
double bisect(double, double, double, double (solution::*f)(double), bool&);
double f(double);
};
#endif // ASSIGN4_H
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
My goal with this assignment is to find any roots should they exist. My issue is that every bisection example I have found only talks about how to find a single root at once. The interval I am to use is [-10.0, 10.0] and eventually I am going to receive coefficients of the equation passed via an array encapsulated in a structure, but for now I have hard coded the coefficients.
So my problem is that I can currently get with 0.2 of the first root for the equation I have hard coded (x^2 + 5x + 2) but I am uncertain of how to step past that root and keep searching for another root up until the end of my interval. I am also unsure of how to accurately hit the root and not be marginally off.
Apologies for the wall of text and any help is appreciated! :)

You can input the interval such that it includes both the roots. Then call bisect twice -- once for the lower root and once for the higher root.
int main(int argc, char * argv[]){
solution s;
double root;
cout << "Enter interval endpoints: ";
cin >> s.xLeft >> s.xRight;
cout << "Enter tolerance: ";
cin >> s.epsilon;
double xMid = 0.5*(s.xLeft + s.xRight);
root = s.bisect (s.xLeft, xMid, s.epsilon, &solution::f, s.error);
if (!(s.error))
cout << "Root found at " << root << "\nValue of f(x) at root is: " << s.f(root) << endl;
else
{
cout << "The solution of a quadratic equation with coefficients: " << endl;
cout << "has not been found." << endl;
}
root = s.bisect (xMid, s.xRight, s.epsilon, &solution::f, s.error);
if (!(s.error))
cout << "Root found at " << root << "\nValue of f(x) at root is: " << s.f(root) << endl;
else
{
cout << "The solution of a quadratic equation with coefficients: " << endl;
cout << "has not been found." << endl;
}
return 0;
}

Related

C++ Variables not updating in loop

For some reason the values in the loop do not update. Instead of taking the new values they are assigned in the loop they stay the same as when first assigned. Why is this?
using namespace std;
int main() {
int town_A_Pop;
int town_A_Growth;
int town_B_Pop;
int town_B_Growth;
int years = 0;
cout << "Enter the polulation of town A and of town B:" << endl;
cin >> town_A_Pop >> town_B_Pop;
cout << "Enter the growth rate of town A and of town B:" << endl;
cin >> town_A_Growth >> town_B_Growth;
do {
town_A_Pop = town_A_Pop * (1 + (town_A_Growth / 100));
cout << town_A_Pop << endl;
town_B_Pop = town_B_Pop * (1 + (town_B_Growth / 100));
cout << town_B_Pop << endl;
years++;
}
while (town_A_Pop < town_B_pop);
cout << "It took " << years << " years for Town A to overtake Town B." << endl;
cout << "Town A Population: " << town_A_Pop << endl;
cout << "Town B Population: " << town_B_Pop << endl;
return 0;
}
I assume that town_A_Pop and town_B_Pop don't update.
If town_A_Growth is less than 100(and greater or same than 0) then (town_A_Growth / 100) will evaluate to 0 and (1 + (town_A_Growth / 100)) will evaluate to 1.
In that case, town_A_Pop = town_A_Pop * 1 so it will stay same.
Same goes to town_B_Pop.
To fix the problem, you can change variables into float or double, or multiply first then divide by 100 like below:
do {
town_A_Pop = (town_A_Pop * (100 + town_A_Growth)) / 100;
cout << town_A_Pop << endl;
town_B_Pop = (town_B_Pop * (100 + town_B_Growth)) / 100;
cout << town_B_Pop << endl;
years++;
}
while (town_A_Pop < town_B_pop);
It will still won't get bigger if both population and growth are too small, though.
Your problem is Type Variables Error
int town_A_Pop;
int town_A_Growth;
int town_B_Pop;
int town_B_Growth;
int years = 0;
change to
double town_A_Pop;
double town_A_Growth;
double town_B_Pop;
double town_B_Growth;
double years;
This should be ok. Because if using int to do division it not able return decimal number.
Like:
int tmp = 1;
int division = tmp / 5; //This result will return 0 , not return 0.2

C++ program doesn't output when I run on cmd or VScode (but on repl.it it does)

I have this C++ program I wrote that sums vectors:
#include <cmath>
#include <iostream>
using namespace std;
const float half_Pi = acos(0.0);
double *vectorSum(double *lengths, double *angels, int size, bool cartazian) {
double Cx, Cy, *res;
for (int i = 0; i < size; i++) {
Cx += cos(angels[i] / 90 * half_Pi) * lengths[i];
Cy += sin(angels[i] / 90 * half_Pi) * lengths[i];
}
if (cartazian) {
res[0] = Cx;
res[1] = Cy;
} else {
res[0] = sqrt(Cx * Cx + Cy * Cy);
res[1] = atan(Cy / Cx) * 90 / half_Pi;
}
return res;
}
int main() {
int numVectors, i = 0, carta;
bool cartazian;
cout << "enter number of vectors to sum: ";
cin >> numVectors;
double *lengths = new double[numVectors];
double *angels = new double[numVectors];
while (i < numVectors) {
cout << "enter length " << i + 1 << ": ";
cin >> lengths[i];
cout << "enter angel " << i + 1 << ": ";
cin >> angels[i];
i++;
}
cout << "would you like the sum presented in x and y? enter 1 for yes and 0 "
"for no: ";
cin >> carta;
if (carta == 0)
cartazian = false;
else if (carta == 1)
cartazian = true;
else
throw("must enter either 0 or 1");
double *totalVector = vectorSum(lengths, angels, numVectors, cartazian);
if (cartazian)
cout << "Vx = " << totalVector[0] << endl
<< "Vy = " << totalVector[1] << endl;
else
cout << "length = " << totalVector[0] << endl
<< "angle = " << totalVector[1] << "\u00B0" << endl;
return 0;
}
I've been able to run it completely fine on repl.it but when I try to run it on VScode (with minGW) or cmd it runs fine until I'm done with the input (doesn't show the result). Why doesn't it show the result? Is it because the throw (tried without and still not)? I don't think it's because the math functions because I ran them fine on another test file. How do I fix this?
The function vectorSum has undefined behavior due to the uninitialized pointer res which you are assigning data to as if it points to valid memory.
Note that you also have undefined behavior because you don't initialize the values Cx and Cy, but then start adding to them.
A naive fix for the first issue would be to allocate memory and then make the caller responsible for freeing it, or use smart pointers or a std::vector<double>, but really all you need is something like std::pair<double, double> instead. As for the second issue, it's as simple as initializing your values to zero.
Note that std::pair is defined in <utility> so you will need to include that.
std::pair<double, double> vectorSum(double *lengths, double *angels, int size, bool cartazian)
{
std::pair<double, double> res;
double Cx = 0, Cy = 0;
for (int i = 0; i < size; i++) {
Cx += cos(angels[i] / 90 * half_Pi) * lengths[i];
Cy += sin(angels[i] / 90 * half_Pi) * lengths[i];
}
if (cartazian) {
res.first = Cx;
res.second = Cy;
} else {
res.first = sqrt(Cx * Cx + Cy * Cy);
res.second = atan(Cy / Cx) * 90 / half_Pi;
}
return res;
}
The call:
std::pair<double, double> totalVector = vectorSum(lengths, angels, numVectors, cartazian);
if (cartazian)
cout << "Vx = " << totalVector.first << endl
<< "Vy = " << totalVector.second << endl;
else
cout << "length = " << totalVector.first << endl
<< "angle = " << totalVector.second << "\u00B0" << endl;
One last point is to take care of spelling things correctly in code. For instance, the correct spellings are:
angles
cartesian

Functions should be correct, but why is the final output 0 here?

#include <iostream>
#include <iomanip>
using namespace std;
//Power function
float power (float base, int exp)
{
if (exp < 0)
{
if (base == 0)
{
cout << "Base cannot be 0.";
return -1;
}
}
if (exp == 0)
return 1;
if (exp == 1)
return base;
return base * power (base, exp - 1);
}
//Factorial function
int facto (int n)
{
return n <= 0 ? 1 : n * facto (n - 1);
}
//Cos function
float cosCalc (float rad)
{
float cos = 0;
int x;
for (x = 0; x < 10; x++)
{
cos += power (-1, x) * power (rad, 2 * x) / facto (2 * x);
}
return cos;
}
//Sin function
float sinCalc (float rad)
{
float sin = 0;
int x;
for (x = 0; x < 10; x++)
{
sin += power (-1, x) * power (rad, 2 * x + 1) / facto (2 * x + 1);
}
return sin;
}
//Main function
int main()
{
int choice;
//Title and Menu
cout << endl << "==============" << endl << " TRIGONOMETRY " << endl << "==============";
cout << endl << "Select:";
cout << endl << "1. Calculate Cos and Sin";
cout << endl << "9. Exit";
while (true)
{
//User Prompt
cout << endl << endl << "Please enter your choice. => ";
cin >> choice;
if (choice == 1)
{
int angle, anglePh;
float rad;
float pi = 3.14159265358979323846264338327950288419716;
char angleType;
float cos = 0;
float sin = 0;
cout << endl << "Please enter an angle. => ";
cin >> angle;
anglePh = angle;
angle %= 360;
rad = angle * pi / 180;
cout << anglePh << " degrees = " << rad << " radian";
cout << endl << "Calculating Cos...";
cosCalc (rad);
cout << endl << "Cos = " << fixed << cos;
cout << endl << "Calculating Sin...";
sinCalc (rad);
cout << endl << "Sin = " << fixed << sin;
}
if (choice == 9)
{
break;
}
}
}
I am building a program that calculates Sin and Cos off an angle input, and when I run it, it outputs 0.000000 for both Sin and Cos. I suspect there is something to do with me declaring float cos = 0 and float sin = 0 in the if loop for choice == 1, and I tried messing around with it but it either results in the program straight out giving me errors on launch, or I get the same outputs.
Any idea where I went wrong?
Thanks for your insight in advance, cheers!
Your cosin and sine function return a float, but in order to get that result you still have to store it in a variable.
So instead of:
cosCalc (rad);
Do:
rad = cosCalc (rad);
and the same for your sine function.

Why does the error keep returning "variable has incomplete type void"?

I'm trying to write a code that will solve Coulomb's Law equation for force between two charged particles (using void) and I keep getting
error: variable has incomplete type 'void'.
The code should measure for r=1 and then loop (adding 3 to r every time) and finishing when r < 60. It will output all of these results.
int main() {
float Q_one;
float Q_two;
int rad = 1;
double const k = 8990000000;
cout << "Enter the charge of particle 1." << endl;
cin >> Q_one;
cout << "Enter the charge of particle 2." << endl;
cin >> Q_two;
void force (float Q_one, float Q_two, int rad);
void force = ((k * ((Q_one * .000001) * (Q_two * .000001))) / (rad * rad));
while (rad <= 60) {
{
force (Q_one, Q_two, rad);
cout << "Radius " << (rad) << " ";
cout << "Force " << (force) << endl;
rad += 3;
}
}
}
I've tried rearranging this numerous ways and changing how I define 'force' but nothing seems to work. Any ideas as to how I can fix this?
I am not sure what you trying to do.
After fixing some mistake I got this :
#include <iostream>
#include <type_traits>
#include <vector>
using namespace std;
int main() {
float Q_one;
float Q_two;
int rad = 1;
double const k = 8990000000;
cout << "Enter the charge of particle 1." << endl;
cin >> Q_one;
cout << "Enter the charge of particle 2." << endl;
cin >> Q_two;
auto force = [k](float Q_one, float Q_two, int rad) { return (k * Q_one * .000001 * Q_two * .000001) / (rad * rad); };
while (rad <= 60)
{
auto result = force (Q_one, Q_two, rad);
cout << "Radius " << (rad) << " ";
cout << "Force " << (result) << endl;
rad += 3;
}
}
Demo : wandbox
Does it look like what you want ?
I assume you are trying to make a function to calculate force with. You can, for example make it a lambda function:
auto force = [=](float Q_one, float Q_two, int rad)
{ return ((k * ((Q_one * .000001) * (Q_two * .000001))) / (rad * rad)); };
And then you call it in the loop and assign it to let's say F like this:
while (rad <= 60) {
double F = force(Q_one, Q_two, rad);
cout << "Radius " << (rad) << " ";
cout << "Force " << (F) << endl;
rad += 3;
}

Quadratic Formula c++ - user-defined function

I wrote this code with a user-defined function, but it seems not to work. I've trying to find out where the mistake is for hours. But couldn't find anything. it looks like the problem is in passing the parameter. But I don't know, I'm pretty new to this!
#include <iostream>
#include <cmath>
using namespace std;
double solutionFun (double a, double b, double c) {
double delta, solution1, solution2;
delta = b*b - 4*a*c;
if (delta > 0 ){
solution1 = (-b + sqrt(delta)) / (2*a);
solution2 = (-b - sqrt(delta)) / (2*a);
cout << "There are 2 solutions." << endl;
cout << "The solutions are:";
return solution1, solution2;
}
else if (delta == 0){
solution1 = (-b) / (2*a);
cout << "There is 1 solution." << endl;
cout << "The solution is:";
return solution1;
}
else {
cout << "There is no solution.";
return 0;
}
}
int main(){
double a ,b ,c;
cout << "Please enter the values of a, b, and c respectively:";
cin >> a ,b ,c;
solutionFun(a ,b ,c);
return 0;
}
A few issues with regards to code validity and desired behavior (coding practice/design aside):
See how to return multiple values from your solutionFun() (currently defined to return double) by using std::vector -- even though you are not using anything returned in this piece of code.
You didn't print (cout <<) the solution values themselves, and it seemed like you were going for it.
See how to use std::cin for multiple inputs in one line of code.
A fixed version -- with respect to the above points:
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
std::vector<double> solutionFun (double a, double b, double c) {
double delta, solution1, solution2;
delta = b*b - 4*a*c;
if (delta > 0 ){
solution1 = (-b + sqrt(delta)) / (2*a);
solution2 = (-b - sqrt(delta)) / (2*a);
cout << "There are 2 solutions." << endl;
cout << "The solutions are: " << solution1 << " and " << solution2;
return {solution1, solution2};
}
else if (delta == 0){
solution1 = (-b) / (2*a);
cout << "There is 1 solution." << endl;
cout << "The solution is: " << solution1;
return {solution1};
}
else {
cout << "There is no solution.";
return {};
}
}
int main(){
double a ,b ,c;
cout << "Please enter the values of a, b, and c respectively:";
cin >> a >> b >> c;
auto result = solutionFun(a ,b ,c);
for (auto scalar : result)
{
// Do something with a component, or don't return anything from the function : )
}
return 0;
}
This code is not how you get multiple inputs:
cin >> a ,b ,c;
Instead, you want:
cin >> a >> b >> c;
This code is not how you display answers:
cout << "The solutions are:";
return solution1, solution2;
Instead you want:
cout << "The solutions are:" << solution1 << " and also " << solution2;
Another method is pass your solution variables on the command line:
void solutionFun (double a, double b, double c,
double& solution1, double& solution2, size_t& solution_count) {
double delta;
delta = b*b - 4*a*c;
solution2 = 0.0;
if (delta > 0 ){
solution1 = (-b + sqrt(delta)) / (2*a);
solution2 = (-b - sqrt(delta)) / (2*a);
solution_count = 2;
cout << "There are 2 solutions." << endl;
cout << "The solutions are: " << solution1 << " and " << solution2;
return;
}
else if (delta == 0){
solution1 = (-b) / (2*a);
solution_count = 1;
cout << "There is 1 solution." << endl;
cout << "The solution is: " << solution1;
return;
}
else {
cout << "There is no solution.";
solution_count = 0;
return;
}
}
The solution1, solution2 and solution_count are passed by reference which means that the function can modify the caller's variables.