помогите с поиском секущего корня C ++ - PullRequest
1 голос
/ 10 мая 2011

Может кто-нибудь объяснить мне, как я бы использовал секущий метод, чтобы найти корень уравнения? Уравнение: ( v / b ) ^2sin(alpha)= kr * Ts^4 +Uc *Ts -q и я должен найти Ts. У меня есть вся остальная информация, но я не совсем понимаю, что мне делать с методом секунта. Любая помощь будет принята с благодарностью.

Вот мой код:

#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)
{

}

Ответы [ 2 ]

0 голосов
/ 10 мая 2011

[На самом деле существует аналитический метод решения квартики (который, по общему признанию, довольно сложный), но, поскольку это домашнее задание, вы, вероятно, захотите секущий числовой метод.Для получения дополнительных оценок вы можете проверить соответствие аналитических результатов!]

Полагаю, вы уже проверили Википедия .Он показывает, что числовая итерация имеет вид:

x[n] = x[n-1] - f(x[n-1]) * (x[n-1] - x[n-2])/(f(x[n-1] - f(x[n-2]));

Начните с x[0], x[1] подходящим образом выбранным - например, используйте предположение из графиков в Excel.

Чтобы сделать итерацию правильно, вы, вероятно,аннотация f(x).Вы можете использовать указатель на функцию, функтор или просто абстрактный класс.

class Function
{
public:
    virtual double evaluate(double x) const = 0;  
};


double findRootUsingSecant(const Function& function, double x0, double x1);

Передача экземпляра класса, который реализует evaluate(), путем вычисления вашей формулы и реализации описанной выше итерации.Обязательно завершите итерацию при некоторых подходящих условиях.

0 голосов
/ 10 мая 2011

Статья в Википедии о Secant Method включает в себя хороший макет последовательных значений x_n, которые я здесь вырезал:

image
image
...
image

Вам необходим метод secant для итеративного вычисления этих значений x_n, пока либо (a) вы не поймете, что метод расходится, и выне может найти решение или (b) ваши последующие значения x_n изменяются на достаточно малые суммы, чтобы вы могли с радостью назвать результат корнем.

Поэтому вам понадобится функция f, которую можно вызвать для вычисленияВаше уравнение:

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;
}

Обязательно проверьте порядок операций.:) Написание уравнений в HTML всегда ненадежно.

Далее вам нужно написать цикл, который проверяет условия выхода:

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;
}

Вы могли бы рассмотреть возможность скрыть всеаргументы f(), которые не решаются с помощью макроса.Это поможет убедиться, что вы получите все аргументы в правильном порядке.

И определенно рассмотрите решение гораздо более простых функций, таких как x^2 - 17 == 0, прежде чем переходить к многомерной функции.(Это также уберет запутанный двойной внутренний цикл, который вы получили сейчас. Это всего лишь рецепт для умножения любых ошибок в несколько сотен раз.:)

...