Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 2 056

/ вопрос открыт /

Здравствуйте, уважаемые эксперты!
Подскажите, есть ли компоненты (или процедуры, функции) для вычисления интегралов (разных - и неопределенных и определенных). Если нет , то как покдключить MathCAD (желательно привести фрагмент кода). Заранее благодарю всех откликнувшихся!

Драганов Василий Михайлович Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Драганов Василий Михайлович (статус: Посетитель)
Вопрос отправлен: 6 ноября 2008, 10:46
Состояние вопроса: открыт, ответов: 0.


Мини-форум вопроса

Всего сообщений: 5; последнее сообщение — 14 ноября 2008, 14:23; участников в обсуждении: 3.
Вадим К

Вадим К (статус: Академик), 6 ноября 2008, 11:56 [#1]:

Проще написать ручками код для нужного определённого интерграла. Мало того, для множества интегралов есть готовые алгоритмы.
Для неопределённых интегралов сложнее. Ведь результат обычно не число, а выражение.
Компонентов, которые умеют считать неопределённые интегралы я даже и не знаю, да и задача это часто слишком уж тяжёлая.
Маткад можно подключить к Делфи как олеобъект. (Есть в делфи такой компонент - OLEContainer. Он не только маткад умеет в себя подгружать, а и ворд, эксель. Правда немного специфически.) Но особо интересного этот способ не даст. Разве что отображение/редактирование.
Можно подключить маткад как ActiveX объект. В этом случае возможностей получиться больше. Но что это даст в плане доступа до маткада - не знаю.
В целом, я считаю, что легче написать готовый код на прямо на делфи. Это будет и быстрее работать, и не будет требовать установленного маткада. И контролируется легче.
Галочка "подтверждения прочтения" - вселенское зло.
Драганов Василий Михайлович

Драганов Василий Михайлович (статус: Посетитель), 6 ноября 2008, 12:22 [#2]:

Спасибо за подсказку, но к великому своему сожалению, я не нашел компонент OLEContainer и, естственно не знаю как воспользоваться. Нельзя ли дать ссылочку на источник примера применения??
Вадим К

Вадим К (статус: Академик), 6 ноября 2008, 12:45 [#3]:

Находиться на вкладке System. Гугл дает десятки ссылок. Двойной клик по нему (компоненту) уже наведёт на то, как его использовать.
Галочка "подтверждения прочтения" - вселенское зло.
Драганов Василий Михайлович

Драганов Василий Михайлович (статус: Посетитель), 6 ноября 2008, 12:58 [#4]:

Понял, ещё раз, СПАСИБО!
Feniks

Feniks (статус: Бакалавр), 14 ноября 2008, 14:23 [#5]:

Нашел несколько примеров для расчетов интеграллов:
1. Вычисление интеграла с заданной точностью алгоритмом Симпсона:
// (c) Copydown 2002, all left reserved. http://world.fpm.kubsu.ru.
 
{$APPTYPE CONSOLE}
 
{$F+} {разрешение передачи функций, как параметров}
 
type FunctionType = function(x: real): real;
 
{интегрируемая функция}
function f(x: real): real; begin f := x end;
 
{интегрирование от a до b функции f с точностью e}
function IntegralSimpson(a, b: real; f: FunctionType; e: real): real;
var
   h, x, s, s1, s2, s3, sign: real;
begin
 
if (a = b) then
   begin
     IntegralSimpson := 0; exit
   end;
 
if (a > b) then
   begin
     x := a; a := b; b := x; sign := -1
   end
  else sign:=1;
 
h := b - a; s := f(a) + f(b); s2 := s;
 
repeat
   s3 := s2; h := h/2; s1 := 0; x := a + h;
 
   repeat
     s1 := s1 + 2*f(x); x := x + 2*h;
   until (not(x < b));
 
   s := s + s1; s2 := (s + s1)*h/3; x := abs(s3 - s2)/15
until (not(x > e));
 
IntegralSimpson := s2*sign;
end;
 
begin
{вывод результата интегрирования от 0 до 1 функции f с точностью 0.001}
writeln(IntegralSimpson(0, 1, f, 0.001));
writeln; writeln('Press Enter'); readln;
end.

2. Взятие интеграла методом Симпсона:
{**** UBPFD *********** by kladovka.net.ru ****
>> Взятие интеграла методом Симпсона
 
Интеграл методом Симпсона
A, B - интервал интегрирования
N - число точек на интервале
Func - функция, от которой берется интеграл.
 
Возвращаемое значение - значение интеграла
 
Зависимости: System
Автор:       Mystic, mystic2000@newmail.ru, ICQ:125905046, Харьков
Copyright:   Mystic
Дата:        25 апреля 2002 г.
********************************************** }
 
type
TFunction = function(X: Extended; Arg: Pointer): Extended;
 
function Simpson(A, B: Extended; N: Cardinal; Func: TFunction; Arg: Pointer): Extended;
var
h: Extended;
X: Extended;
K: Extended;
I: Integer;
begin
Assert(N>0);
h := 0.5 * (B-A) / N;
Result := Func(A, Arg);
X := A + h;
for I := 1 to 2*N-1 do
begin
   if I mod 2 = 0
     then K := 2
     else K := 4;
   Result := Result + K*Func(X, Arg);
   X := X + h;
end;
Result := Result + Func(B, Arg);
Result := h * Result / 3;
end;

3. Вычисление определённого интеграла методом Симпсона:
{ **** UBPFD *********** by kladovka.net.ru ****
>> Вычисление определённого интеграла методом Симпсона
 
A, B - границы интегрирования
Eps - заданная относительная точность вычисления
F - подинтегральная функция
 
Зависимости: нет
Автор:       Dimka Maslov, mainbox@endimus.ru
Copyright:   Dimka Maslov
Дата:        26 ноября 2003 г.
********************************************** }
 
type
TDoubleFunc = function (X: Double): Double;
 
function Integral(A, B, Eps: Double; F: TDoubleFunc): Double;
 
function InternalCalc(A, B: Double; F: TDoubleFunc; N: Integer): Double;
var
x, dx: Double;
i: Integer;
begin
dx := (B - A) / N;
Result := 0;
x := A;
for i := 1 to N do begin
  Result := Result + dx * (F(x) + 4*F(x+dx/2) + F(x+dx)) / 6;
  x := x + dx;
end; 
end;
 
var
N: Integer;
Prev: Double;
begin
Result := InternalCalc(A, B, F, 4);
N := 4;
repeat
Prev := Result;
N := N shl 1;
Result:= InternalCalc(A, B, F, N);
until (Result = 0) or (Abs((Result-Prev) / Result) < Eps);
end;
Пример использования:
function F(X: Double): Double;
begin
Result := X * X * X;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := FloatToStr(Integral(-10, 10, 0.00001, F));
end;

4. Вычисление определенного интеграла методом левых и правых прямоугольников с заданной точностью:
{ **** UBPFD *********** by kladovka.net.ru ****
>> Вычисление определенного интеграла методом левых и правых прямоугольников с заданной точностью
 
"Просто расчет площади под функцией, параметры: a,b - пределы интегрирования, a<=b
eps - допустимая погрешность, практически гарантируется, что расхождение результата с истинным значением интеграла не
превосходит по модулю указанную величину. Только не переборщите :-))
intF - подинтегральная функция. Естественно, желательно задавать функции, интегрируемые в смысле Римана. Объявление
смотри в примере.
Примечание: Несобственные интегралы не считаем :-)
Проверок на переполнение нет, да и вообще нет проверок..."
(Romkin (Москва))
 
Модуль сделан на основе функции вычисления опред. интеграла методом трапеций от Romkin'а (Москва).
 
Зависимости: Нет
Автор:       Алексей Глеб, noodlesf@mail.ru, Чернигов
Copyright:   с подачи Romkin'а (Москва)
Дата:        18 мая 2003 г.
********************************************** }
 
Unit IntPram;
 
Interface
 
Type
TIntFunc=Function(X: Double): Double;
 
Function LeftPramInt(a, b: Double; eps: Double; IntF: TIntFunc): Double;
Function RightPramInt(a, b: Double; eps: Double; IntF: TIntFunc): Double;
 
Implementation
 
Function LeftPramInt(a, b: Double; eps: Double; IntF: TIntFunc): Double;
Var
//S - площадь на предыдущей итерации,
//step - "толщина" прямоугольника
//gran - передвигаемая от a до b граница
//n - число прямоугольников, удваивается на каждой итерации
S, step, gran: Double;
n: integer;
Begin
//Сначала приближение одного прямоугольника
step:=b-a;
Result:=IntF(a)*step;
n:=1;
Repeat
   S:=Result;
   n:=n*2;
   step:=(b-a)/n;
   Gran:=a;
   Result:=0;
   //Ниже - просто вычисляем площади новых прямоугольников
   while gran<b do
   Begin
     Result:=Result+IntF(gran)*step;
     gran:=gran+step;
   End;
Until abs(S-Result)<=eps;
End;
 
Function RightPramInt(a, b: Double; eps: Double; IntF: TIntFunc): Double;
Var
//S - площадь на предыдущей итерации,
//step - "толщина" прямоугольника
//gran - передвигаемая от a до b граница
//n - число прямоугольников, удваивается на каждой итерации
S, step, gran: Double;
n: integer;
Begin
//Сначала приближение одного прямоугольника
step:=b-a;
Result:=IntF(b)*step;
n:=1;
Repeat
   S:=Result;
   n:=n*2;
   step:=(b-a)/n;
   Gran:=b;
   Result:=0;
   //Ниже - просто вычисляем площади новых прямоугольников
   while a<gran do
   Begin
     Result:=Result+IntF(gran)*step;
     gran:=gran-step;
   End;
Until abs(S-Result)<=eps;
End;
 
End.
Пример использования:
uses IntPram;
 
function IntSqrt(x: Double): Double;
begin
Result:=Sqrt(x);
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
label1.Caption:=FloatToStr(LeftPramInt(0, Pi, 0.00001, S));
label2.Caption:=FloatToStr(RightPramInt(0, Pi, 0.00001, S));
end;

5. Вычисление определенного интеграла методом трапеций с заданной точностью:
{ **** UBPFD *********** by kladovka.net.ru ****
>> Вычисление определенного интеграла методом трапеций с заданной точностью
 
Просто расчет площади под функцией, параметры: a,b - пределы интегрирования, a<=b
eps - допустимая погрешность, практически гарантируется, что расхождение результата с истинным значением интеграла не
превосходит по модулю указанную величину. Только не переборщите :-))
intF - подинтегральная функция. Естественно, желательно задавать функции, интегрируемые в смысле Римана. Объявление
смотри в примере.
Примечание: Несобственные интегралы не считаем :-)
Проверок на переполнение нет, да и вообще нет проверок...
 
Зависимости: Ну какие могут быть зависимости?
Автор:       Romkin, romkin@pochtamt.ru, Москва
Copyright:   Romkin 2002
Дата:        19 ноября 2002 г.
********************************************** }
 
unit intfunc;
 
interface
 
type
TIntFunc = function(X: Double):Double;
 
function TrapezeInt(a,b:Double; eps: Double; IntF: TIntFunc): Double;
 
implementation
 
function TrapezeInt(a,b:Double; eps: Double; IntF: TIntFunc): Double;
var
//S - площадь на предыдущей итерации,
//x - текущее значение аргумента
//base - высота трапеции
//n - число трапеций, удваивается на каждой итерации
S, x, base: Double;
i, n: Integer;
begin
//Сначала приближение одной трапецией
base := b-a; 
Result := (IntF(a) + IntF(b))/2 * base;
eps := eps / 10; //Вообще говоря, величина делителя зависит от функции
n := 1;
repeat
   S := Result; 
   base := base / 2;
   n := n * 2;
   //Новая площадь вычисляется на основе старой
   Result := Result / 2;
   //Ниже - просто вычисляем площади новых трапеций
   for i := 1 to n div 2 do
   begin
     x := a + base * (i * 2 - 1);
     Result := Result + IntF(x) * base;
   end;
until abs(S-Result) <= eps;
end;
 
end.
Пример использования:
uses intFunc;
 
function intSin(x: Double): Double;
begin
Result := sin(x);
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
Edit1.Text := FloatToStr(TrapezeInt(0,Pi, 0.00001, intSin));
//результат у меня получился 1.99999990195429 - с запасом
//Точный ответ - 2.0
end;

P.S. Желаю удачи.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:34
Выполнено за 0.04 сек.