Консультация № 161709
01.03.2009, 16:39
0.00 руб.
0 3 2
Уважаемые Эксперты обращаюсь к вам за поддержкой,в надежде на вашу помощь.
Помогите пожалуйста в решении задачки:


Решить при помощи численных методов уравнение (найти действительные корни)указанным методом:

2x-lgx-7=0 метод хорд, Ньютона (lgx - логорифм от x )

Заранее огромное спасибо.

Обсуждение

давно
Профессор
401888
1232
01.03.2009, 17:46
общий
это ответ
Здравствуйте, Fan1111!
Решение уравнения обоими методами в приложении. Теорию не расписываю, добро пожаловать в учебники или в интернет, информации куча.
Для метода Ньютона первое приближение берите не очень далеко от 3,8.



Приложение:
Метод хорд.
uses Crt;

function f(x:real):real;
begin
f:=2*x-ln(x)/ln(10)-7;
end;

function Chord(a,b:real):real;
begin
Chord:=(f(b)*a - f(a)*b)/(f(b) - f(a))
end;

var x,eps,a,b,c:real;
begin
clrscr;
repeat
writeln('Введите значения  a и b');
readln(a,b);
until (a>0)and(b>a);{логарифм при х<=0 не определен}
repeat
writeLn('Введите точность eps');
readln(eps);
until (eps>0)and(eps<1);
clrscr;
repeat
c:=Chord(a,b);
if f(a)*f(c) > 0 then a := c
else b := c;
until abs(Chord(a, b) - c) < eps;
x := c;
writeLn('Корень x=', x:10:7);
readkey
end.

Метод Ньютона
uses crt;
function F(x:real):real;
begin
F:=2*x-ln(x)/ln(10)-7;
end;
function F1(x:real):real;
begin
F1:=2-1/(x*ln(10)); {первая производная}
end;
function Newton(x1,e:real):real;
var x2,b:real;
begin
x2:=x1;
repeat
b:=x2;
x2:=b-F(b)/F1(b);
until abs(x2-b)>e;
Newton:=x2;
end;
var a,eps:real;
begin
Неизвестный
02.03.2009, 12:21
общий
это ответ
Здравствуйте, Fan1111!
Я представляю несколько другой вариант, более "автоматизированный", в котором учтена быстрота изменения функции

Приложение:
{$N+,E+}
{буду передавать подпрограммам функции как параметры.
Нужно такое определение нового типа}

{Есть два варианта метода хорд. Я не буду использовать тот, что описан
http://machinelearning.ru/wiki/index.php?title=Методы_дихотомии
Использую второй вариант, где применяются два значения xk и xk-1
чуть быстрее}
type
float = extended; {так можно менять точность вычисления - Real, Double}
TFunction = function (x: float): float;
CONST
maxSteps: longint = 100000;

{Глобальные переменные}
var
ln10: float;
eps : float;

function f(s: float): float; far;
{Для передаваемой функции обзаательно определить ее как дальний тип
иначе будет сформирован адрес только в виде смещения в памяти
А механизм передачи требует полный адрес}
begin
f := 2*s -ln(s)/ln10 - 7;
end;

function df(s: float): float; far;
begin
df := 2 - 1/(s*ln10)
end;

function chord(func: TFunction; a, xk: float; tol: float): float;
{Для начала работы нужны две точки - вот их и передаем как параметры}
{В качестве критерия окончания поиска решения всегда принимается
ордината
И еще ограничим максимальное число шагов - не всегда сходится
В данном-то случае сойдется, но ...}
var dx, f_k, f_k1: float;
steps: Longint;
begin
steps := 1;
tol := tol + eps;
f_k := func(a);
f_k1:= func(xk);
dx := 4*tol; {чтоб сразу не окончился, а потом будет вычисляться}
repeat
write(steps:8); { выключи, если не хочешь смотреть, за сколько шагов)
{dx = x_k+1 - x_k. То есть потом будет x_k+1 = x_k + dx}
dx := - f_k/((f_k - f_k1)/(xk - a));
a := xk;
{заданная функция очень быстро изменяется. По это причине,
если неудачно задать начальные точки, легко получить отрицательное
число. По этой причине ввел ограничение}
while (xk + dx) <= 0 do dx := dx/10;
xk := xk + dx;

f_k1 := f_k;
f_k := func(xk);
inc(steps);
until (steps > maxSteps) or (abs(dx) < tol);
WriteLn;
chord := xk;
end;

function Newton(func: TFunction; a: float; tol: float): float;
var fk, dx : float;
steps : Longint;
begin
tol := tol + eps;
steps := 1;
repeat
write(steps:8);
dx := - f(a)/df(a);
while (a + dx) <= 0 do dx := dx/10;
a := a + dx;
inc(steps);
until abs(dx) < tol;
Writeln;
Newton := a
end;



BEGIN
{тонкость = машинная точность = минимальное число, уже воспринимаемое
машиной как ноль. То есть самая маленькая точность, которая может быть
задана. Нужно для того, чтобы пользователь не заморачивался такими
вещами}
eps := 1; while 1 + eps > 1 do eps := eps/2;
eps:=eps*4; {один раз деление было произведено зря. И двойку накидываю
еще для верности}
ln10 := ln(10);

{Вычисление методом хорд с максимальной точностью}
WriteLn(chord(f, 7e-6, 2e-6, 0));
{Вычисление методом Ньютона или касательных}
WriteLn(Newton(f, 7e-6, 0));
END.
Неизвестный
02.03.2009, 12:23
общий
Да уж, то ни одного ответа, то сразу два. И не ясно, получите ли? Из-за блокирования
Форма ответа