问题
Can someone explain to me how I would use the secant method to find the root of an equation?
The equation is: ( v / b ) ^2sin(alpha)= kr * Ts^4 +Uc *Ts -q
and I have to find Ts. I have all the other info but am confused on what I'm supposed to do with the seccant method. Any help would be greatly appreciated.
Here is my code so far:
#include <iostream>
#include <cmath>
#include <fstream>
#include <iomanip>
#include <cmath>
using namespace std;
void secant(double, double, double, double, double, double, double);
int main()
{
double kr, uc, q, b, radians;
const double PI = 4.0 * atan(1.0);
ifstream datain("shuttle.txt");
ofstream dataout("results.txt");
datain >> kr >> uc >> q >> b;
int velocity = 16000;
double angle = 10;
for (int velocity = 16000; velocity <= 17500; velocity += 500) {
for (int angle = 10; angle <= 70; angle += 15) {
radians = angle * PI / 180;
cout << velocity << endl;
cout << radians << endl;
cout << angle << endl;
secant(angle, radians, velocity, kr, uc, q, b);
}
}
getchar();
}
void secant(double angle, double radians, double velocity, double kr, double uc,
double q, double b)
{
}
回答1:
The Wikipedia article on the Secant Method includes a nice layout of successive x_n values, which I'm cut-n-pasting here:


...

You need your secant method to iteratively calculate these x_n values, until either (a) you realize the method is diverging, and you cannot find a solution or (b) your successive x_n values are changing by small enough amounts that you can happily call the result a root.
So you'll need a function f that you can call to calculate your equation:
double f(double Ts, double v, double b, double alpha, double kr, double Uc, double q) {
double first = pow(v/b, 2.0) * sin(alpha);
double second = kr * pow(Ts, 4.0) + Uc * Ts - q;
return first - second;
}
Be sure to check the order of operations. :) Writing equations in HTML is always iffy.
Next you need to write a loop that checks for the exit conditions:
x_0 = /* some guess */
x_1 = x_0 + .01 /* or similar */
while ( (fabs(x_0 - x_1) > EPSILON) && (fabs(x_0 - x_1) < DIVERGENCE) ) {
x_new = x_1 - f(x_1, /* rest */) * (x_1 - x_0) / (f(x_1, /* rest */) - f(x_0, /* rest */));
x_0 = x_1;
x_1 = x_new;
}
You might consider hiding all the arguments to f() that aren't being solved for via a macro. That would help make sure you get all the arguments in the correct order.
And definitely consider solving much simpler functions like x^2 - 17 == 0 before jumping into your multivariate function. (It'd also remove the confusing double-inner-loop you've got now. That's just a recipe for multiplying any errors by a few hundred times. :)
回答2:
[ There is actually an analytic method for solving the quartic (which is admittedly fairly involved), but as this is homework exercise, you presumably want the secant numerical method. For extra marks, you might want to check that the analytic results agree!]
I assume you have already checked Wikipedia. It shows that the numerical iteration is:
x[n] = x[n-1] - f(x[n-1]) * (x[n-1] - x[n-2])/(f(x[n-1] - f(x[n-2]));
Start with x[0], x[1] suitably chosen - e.g. use a guess from graphing in Excel.
To do the iteration nicely, you probably want to abstract f(x). You can use a function pointer, a functor or just an abstract class.
class Function
{
public:
virtual double evaluate(double x) const = 0;
};
double findRootUsingSecant(const Function& function, double x0, double x1);
Pass in an instance of a class which implements evaluate() by computing your formula, and implement the above iteration. Make sure to terminate the iteration on some suitable conditions.
来源:https://stackoverflow.com/questions/5944986/help-with-secant-root-finding-c