помощь в поиске секущего корня C

#c #root

#c #root

Вопрос:

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

Вот мой код на данный момент:

 #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. Можете ли вы привести пример на бумаге? Попробуйте это для начала. Подсказка: сначала измените уравнение так, чтобы вы получили Ts с одной стороны, а другой материал — с другой. Вы не сможете решить такого рода задачки по программированию, если не умеете решать алгебру…

Ответ №1:

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

Ответ №2:

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

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

 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 Functionamp; function, double x0, double x1);
  

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