помогите найти секущий корень C++

Может ли кто-нибудь объяснить мне, как я буду использовать метод секущих, чтобы найти корень уравнения? Уравнение: ( 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)
{

}

person Brian    schedule 10.05.2011    source источник
comment
Можете ли вы разработать пример на бумаге? Попробуйте это, во-первых. Подсказка: во-первых, перестройте уравнение так, чтобы в одной его части было Ts, а в другой — все остальное. Вы не можете решить такую ​​программную головоломку, если вы не можете заниматься алгеброй...   -  person Karl Knechtel    schedule 10.05.2011


Ответы (2)


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



...

Вам нужен метод secant для итеративного вычисления этих значений x_n до тех пор, пока либо (а) вы не поймете, что метод расходится и не сможете найти решение, либо (б) ваши последовательные значения 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, прежде чем переходить к своей многомерной функции. (Это также устранит сбивающий с толку двойной внутренний цикл, который у вас есть сейчас. Это просто рецепт умножения любых ошибок в несколько сотен раз. :)

person sarnold    schedule 10.05.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(), вычислив вашу формулу, и реализуйте описанную выше итерацию. Обязательно завершите итерацию на некоторых подходящих условиях.

person Keith    schedule 10.05.2011