Выч мат
От: RaptuGava Россия  
Дата: 04.12.02 09:53
Оценка:
Народ помогите пожалуйста по выч мату срочно нужно здавать задачу ссесия на носу
а я немогу додумать задачку

задача
решить уранение 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.
а в моём уравнение почти такаяже загагулина только их дахрена
и препод вводит промежуток а и б так как ему захочется
тоесть на этом промежутке будет несколько загагулин и значит несколько ответов
я уже голову сломал никак немогу предумать помогите а может код модифицырут кто нить
если надо могу описать метод
Заранее благадарен
Re: Выч мат
От: Lonely Dog Россия  
Дата: 04.12.02 11:38
Оценка:
Если препод вводит любые границы, то наверное вам надо сделать следующее:

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

Вот такие дела. Если будут вопросы, милости просим.
Re: Выч мат
От: Кодт Россия  
Дата: 04.12.02 12:12
Оценка:
Здравствуйте, 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 имеет период П.

Удачи!
Перекуём баги на фичи!
Re[2]: Выч мат
От: Кодт Россия  
Дата: 04.12.02 12:17
Оценка:
Здравствуйте, 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 вы возьмете большим, то этим фактом можно пренебречь.) И соответственно для этого отрезка вам надо запустить ваш метод.

Или даже корни четной степени (но в данном случае этого тоже нет).
Перекуём баги на фичи!
Re[3]: Выч мат
От: Lonely Dog Россия  
Дата: 04.12.02 12:20
Оценка:
Здравствуйте, Кодт, Вы писали:

-----покусано---------------

Наверное вы правы. Просто я не обратил внимание на тот факт, что требуется решить одно конкретное уравнение, обладающее столь специфичным видом...
Да вы точно правы.
Re: Выч мат
От: RaptuGava Россия  
Дата: 04.12.02 22:21
Оценка:
Народ ну рас все такие умные напишите а
можно на с можно на дельфи или паскале очень нужно а то у меня изза этого задания щас вся сессия повиснет
Re[2]: Выч мат
От: Кодт Россия  
Дата: 05.12.02 09:26
Оценка:
Здравствуйте, 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)

Кодируй сам.
Перекуём баги на фичи!
Re[3]: Выч мат
От: Atilla Россия  
Дата: 05.12.02 09:55
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, RaptuGava, Вы писали:


RG>>Народ ну рас все такие умные напишите а

RG>>можно на с можно на дельфи или паскале очень нужно а то у меня изза этого задания щас вся сессия повиснет

К>Деньги заплатишь?



Правильно, так их, студентов-раздолбаев!

Как сессия — так сразу задачу им реши

(ц) "Ох уж эти (семестровые) цЫклы!"

Кр-ть — с.т.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.