Народ помогите пожалуйста по выч мату срочно нужно здавать задачу ссесия на носу
а я немогу додумать задачку
задача
решить уранение ctg(x)=a/x
методом хорд
в общем не для своего уравнения я написал
на какомто сайте нащел доку по этому методу и написал
там задача рассматривалась на немного изогнутой прямой левая граница которой ниже оси ох а правая выше ох
и точно известно что будет только один корень т.к эта загагулина пересекает ось ох один раз
вот код
Program METODHORD;
Uses Crt,Graph;
Var
a,b:Integer;{лево право}
N:Real;{Коафицент а}
Key:Char;
J:Real;{Координата пересечения хорды с ох}
acc:Real;{Точность}
Temp,Tempj:Real;
{ГР}
{Ввод информации}
Procedure GetAll;
Begin
ClrScr;
Write('Введите коэфицент а');
ReadLn(N);
WriteLn('Вводи а');
ReadLn(a);
WriteLn('Вводи b');
ReadLn(b);
WriteLn('Введи точность');
ReadLn(acc);
End;
{Уравнение}
Function Fx(x:real):Real;
Begin
Fx:=N/X — cos(x)/sin(x);
End;
{Вычисление Методом хорд}
Procedure Calculate;
Begin
J:=a-(Fx(a)*(b-a))/(Fx(b)-Fx(a));
Temp:=Fx(j);
While Temp>=acc do
Begin
TempJ:=j;
J:=(-1) * (Temp * (b-TempJ) / (Fx(b)-temp)+TempJ);
Temp:=Fx(j);
End;
Write('х = ');
WriteLn(Temp:10:8);
write('С точностью ');
WriteLn(acc:10:8);
End;
Begin
GetAll;
Calculate;
key:=ReadKey;
Until Key in ['Q','q'];
ReadKey;
End.
а в моём уравнение почти такаяже загагулина только их дахрена
и препод вводит промежуток а и б так как ему захочется
тоесть на этом промежутке будет несколько загагулин и значит несколько ответов
я уже голову сломал никак немогу предумать помогите а может код модифицырут кто нить
если надо могу описать метод
Заранее благадарен
Если препод вводит любые границы, то наверное вам надо сделать следующее:
1. Делите ваш отрезок [a;b] на N (нет, лучше M

) частей. Число это должно быть большим. Получаете нобор точек x[i]. Причем x[0] = a, x[M-1]=b
2. в каждой точке вычисляете значение функции. (Мы решаем уравнение f(x)=0, то есть вы вычисляете значение функции f(x)
3. Дальше все просто: если y[i]*y[i+1]<0, то на интервале [x[i];x[i + 1]] есть ОДИН корень. (На самом деле, это означает, что на это м интервале их нечетное количество, но если M вы возьмете большим, то этим фактом можно пренебречь.) И соответственно для этого отрезка вам надо запустить ваш метод.
Кода дать не могу, т.к. нет времени на его написание. (Да и кроме, того я плохо знаю PASCAL. (Все больше C++ и ASM))
Вот такие дела. Если будут вопросы, милости просим.
Здравствуйте, RaptuGava, Вы писали:
RG>задача
RG>решить уранение ctg(x)=a/x
RG>методом хорд
RG>в общем не для своего уравнения я написал
RG>на какомто сайте нащел доку по этому методу и написал
RG>там задача рассматривалась на немного изогнутой прямой левая граница которой ниже оси ох а правая выше ох
RG>и точно известно что будет только один корень т.к эта загагулина пересекает ось ох один раз
RG>вот код
По поводу кода — стилистические замечания.
Кстати, код нужно обрамлять в теги [pascal] / [/pascal] (см. панельку под полем ввода текста):
RG>Program METODHORD;
RG> Uses Crt,Graph;
RG> Var
RG> a,b:Integer;{лево право}
RG> N:Real;{Коафицент а}
{ очень мило. Кто тебе подсказал так называть величины - N это a, a,b - это x_min,x_max ??? }
{ и, кстати, почему границы - целочисленные? }
RG> Key:Char;
{ свалил в кучу все переменные }
RG> J:Real;{Координата пересечения хорды с ох}
RG> acc:Real;{Точность}
RG> Temp,Tempj:Real;
{ нет, чтобы назвать переменные x1, x2, x0, y1, y2, y0 }
{ кстати, у нас работал один товарищ,
после которого мы год вычищали такие Temp, Tempxxx и даже UncleBens :))) }
RG> {ГР}
RG> {Ввод информации}
RG> Procedure GetAll;
RG> Begin
RG> ClrScr;
RG> Write('Введите коэфицент а');
RG> ReadLn(N);
RG> WriteLn('Вводи а');
RG> ReadLn(a);
RG> WriteLn('Вводи b');
RG> ReadLn(b);
RG> WriteLn('Введи точность');
RG> ReadLn(acc);
RG> End;
RG> {Уравнение}
RG> Function Fx(x:real):Real;
RG> Begin
RG> Fx:=N/X - cos(x)/sin(x);
{ нет проверки на полюсы функции (x=0, sin(x)=0) }
{ при значениях, близких к полюсу, функция должна выдавать очень большие числа }
RG> End;
RG> {Вычисление Методом хорд}
RG> Procedure Calculate;
RG> Begin
RG> J:=a-(Fx(a)*(b-a))/(Fx(b)-Fx(a));
{ а не забодаешься по два раза вычислять одно и то же значение? }
{ тем более, что a остается неизменным на протяжении всей работы }
RG> Temp:=Fx(j);
RG> While Temp>=acc do
RG> Begin
RG> TempJ:=j;
RG> J:=(-1) * (Temp * (b-TempJ) / (Fx(b)-temp)+TempJ);
RG> Temp:=Fx(j);
RG> End;
RG> Write('х = ');
RG> WriteLn(Temp:10:8);
RG> write('С точностью ');
RG> WriteLn(acc:10:8);
RG> End;
RG> Begin
RG>
RG> GetAll;
RG> Calculate;
RG> key:=ReadKey;
RG> Until Key in ['Q','q'];
RG> ReadKey;
RG> End.
RG>а в моём уравнение почти такаяже загагулина только их дахрена
RG>и препод вводит промежуток а и б так как ему захочется
RG>тоесть на этом промежутке будет несколько загагулин и значит несколько ответов
RG>я уже голову сломал никак немогу предумать помогите а может код модифицырут кто нить
RG>если надо могу описать метод
Идея такая:
function NearZero(v: real): real;
const nz = 1.0e-5;
begin
if abs(v) <= nz then
if v < 0 then v := -nz;
else v := nz;
NearZero := v;
end;
function F(x: real): real; { уравнение } { надеемся, что у него нет корней четной степени }
begin
F := A / NearZero(x) - cos(x) / NearZero(sin(x));
end;
function IsThereOddRoots(x1,x2: real): boolean; { есть ли в диапазоне нечетное число корней? }
begin
IsThereOddRoots := sign(F(x1)) <> sign(F(x2));
end;
function FindRoot(x1,x2: real, var x0:real): boolean; { ищет любой корень в диапазоне x1..x2 }
{ при условии, что IsThereOddRoots(x1,x2) = true }
var y1,y2: real;
x_grows: boolean;
begin
{ методом хорд }
FindRoot := false;
x_grows := x1 < x2; { пригодится для проверки }
y1 := F(x1);
y2 := F(x2);
while true do
begin
x0 := x2;
y2 := F(x2);
if abs(y2) < y_accuracy then
break;
{ хорда x1,y1 -- x2,y2 имеет корень в точке x0,0 }
x2 := x1 + (y1-y2)/(x2-x1);
if x_grows and (x2 > x0)
or not x_grows and (x2 < x0) then
return; { хорда уехала за интервал }
end;
FindRoot := true;
{ вроде, ничего не перепутал }
end;
procedure FindRoots(x1,x2: real)
var x0: real;
begin
if FindRoot(x1,x2, x0) then
begin
{ вывести корень }
writeln("root = ", x0);
{ найти еще корни }
FindRoots(x1, x0-x_accuracy);
FindRoots(x0+x_accuracy, x2);
end;
end;
С четным числом корней бороться тяжело... Но можно исходить из априорной информации, что ctg x имеет период П.
Удачи!
Здравствуйте, Lonely Dog, Вы писали:
LD>Если препод вводит любые границы, то наверное вам надо сделать следующее:
LD>1. Делите ваш отрезок [a;b] на N (нет, лучше M
) частей. Число это должно быть большим. Получаете нобор точек x[i]. Причем x[0] = a, x[M-1]=b
Я даже уточню, насколько.
Нарубите интервал [a;b] на открытые (!) подинтервалы вида (kП, (k+1)П).
LD>2. в каждой точке вычисляете значение функции. (Мы решаем уравнение f(x)=0, то есть вы вычисляете значение функции f(x)
LD>3. Дальше все просто: если y[i]*y[i+1]<0, то на интервале [x[i];x[i + 1]] есть ОДИН корень. (На самом деле, это означает, что на это м интервале их нечетное количество, но если M вы возьмете большим, то этим фактом можно пренебречь.) И соответственно для этого отрезка вам надо запустить ваш метод.
Или даже корни четной степени (но в данном случае этого тоже нет).
Здравствуйте, RaptuGava, Вы писали:
RG>Народ ну рас все такие умные напишите а
RG>можно на с можно на дельфи или паскале очень нужно а то у меня изза этого задания щас вся сессия повиснет
Деньги заплатишь?
Тебе же всю задачу разбили на простые подзадачи.
Equation(x) = a/x - cos(x)/sin(x)
FindRoot(x1,x2) // в одном интервале (kП, (k+1)П)
y1 = Equation(x1)
if |y1| < y_accuracy
root is x1
x = x2
while not solved
y = Equation(x)
if(|y| < y_accuracy)
root is x
else
x = x1 + y1*(x-x1)/(y1-y)
FindAllRoots(x1,x2)
k1 = ]x1/П[
k2 = [x2/П]
FindRoot(x1, k*П-x_accuracy)
for k = k1 to k2
FindRoot(k*П+x_accuracy, (k+1)*П-x_accuracy)
FindRoot(k2*П+x_accuracy, x2)
Кодируй сам.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, RaptuGava, Вы писали:
RG>>Народ ну рас все такие умные напишите а
RG>>можно на с можно на дельфи или паскале очень нужно а то у меня изза этого задания щас вся сессия повиснет
К>Деньги заплатишь?
Правильно, так их, студентов-раздолбаев!
Как сессия — так сразу задачу им реши
(ц) "Ох уж эти (семестровые) цЫклы!"