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

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

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

Delphi.int.ru Expert

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

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

#   

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


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

Подробнее »



Вопрос # 5 714

/ вопрос решён /

Приветствую, уважаемые эксперты!
Передо мной стоит задача подсчета частных производных от шести функций по шести переменным. Итого 36 раз я должен вызвать процедуру. Напрашивается решение: запихнуть в некий массив ссылки на заданные ф-ии y1,y2,y3,y4,y5 и y6 и затем в цикле перебирать эти ф-ии и переменные по номерам. Вот что получилось, но скорее всего здесь ошибка. Пример для 3-х мерного в-ра:

Заранее спасибо

Приложение:
  1. unit NutonUnit;
  2.  
  3. interface
  4.  
  5. uses
  6. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7. Dialogs, math, StdCtrls;
  8.  
  9. type
  10.  
  11. vec3 = array [1..3] of real;
  12.  
  13. mat33 = array [1..3,1..3] of real;
  14.  
  15.  
  16. TForm1 = class(TForm)
  17. Button1: TButton;
  18. Edit1: TEdit;
  19.  
  20.  
  21. function y2(M:vec3):real;
  22. function y3(M:vec3):real;
  23.  
  24.  
  25. private
  26. { Private declarations }
  27. public
  28.  
  29.  
  30. { Public declarations }
  31. end;
  32.  
  33. var
  34. Form1: TForm1;
  35.  
  36. implementation
  37.  
  38. {$R *.dfm}
  39. Type
  40. Func = function(M:vec3):real;
  41.  
  42. function TForm1.y1(M:vec3):real;
  43. begin
  44. result:=M[1]*M[1];
  45. end;
  46.  
  47. function TForm1.y2(M:vec3):real;
  48. begin
  49. result:=M[2]*M[2];
  50. end;
  51.  
  52. function TForm1.y3(M:vec3):real;
  53. begin
  54. result:=M[3]*M[3];
  55. end;
  56.  
  57.  
  58. type
  59. vecF = array[1..3] of Func;
  60.  
  61.  
  62.  
  63.  
  64. F[1]:=y1;
  65. F[2]:=y2;
  66. F[3]:=y3;
  67.  
  68.  
  69. function TForm1.proizv(M:vec3):mat33;
  70. var f_start,f_finish:real;
  71. i,j:integer;
  72. e,d:real;
  73. M1:vec3;
  74. matr_proizv:mat33;
  75.  
  76. begin
  77.  
  78. e:=0.0001;
  79.  
  80. d:=0.01;
  81.  
  82. for i:=1 to 3 do
  83. begin
  84.  
  85. for j:=1 to 3 do
  86. begin
  87. M1:=M;
  88. f_finish:=100;
  89. repeat
  90.  
  91. f_start:=f_finish;
  92. M1[j]:=M[j]+d;
  93. f_finish:=(F[i](M1)-F[i](M)/d;
  94.  
  95. d:=d/2;
  96.  
  97. until (abs(f_start-f_finish)<e);
  98.  
  99. matr_proizv[i,j]:= f_finish;
  100.  
  101. end;
  102. end;
  103.  
  104. end;
  105.  
  106. end.
  107.  


porchet Вопрос решён, но можно продолжить его обсуждение в мини-форуме

Вопрос задал: porchet (статус: Посетитель)
Вопрос отправлен: 3 ноября 2011, 23:12
Состояние вопроса: решён, ответов: 1.

Ответ #1. Отвечает эксперт: min@y™

Ну, в первом приближении, как-то так (найди 100500 отличий):

unit NutonUnit;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, math, StdCtrls;
 
type
  // советую, всё же, имена типов начинать с буквы "Т".
  vec3  = array [1..3] of real;
  mat33 = array [1..3,1..3] of real;
  vecF = array[1..3] of Func;
  Func = function(M:vec3):real of object; // <--- для методов класса обязательно of object
 
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
 
    function y1(M:vec3):real; //ф-ия считает значение в точке (x,y,z) x=M[1] y=M[2] z=M[3]
    function y2(M:vec3):real;
    function y3(M:vec3):real;
    function proizv(M:vec3):mat33;// ф-ия взятия производной
  private
    F:vecF;    // вектор ссылок на ф-ии
  public
    M:vec3;//точка(x,y,z), в которой ищутся частные производные
    constructor Create(AOwner: TComponent); override;
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
function TForm1.y1(M:vec3):real;
begin
  result:=M[1]*M[1];
end;
 
function TForm1.y2(M:vec3):real;
begin
  result:=M[2]*M[2];
end;
 
function TForm1.y3(M:vec3):real;
begin
  result:=M[3]*M[3];
end;
 
constructor TForm1.Create(AOwner: TComponent);
begin
  inherited;
  F[1]:=y1;
  F[2]:=y2;
  F[3]:=y3;
end;
 
function TForm1.proizv(M:vec3):mat33;
var f_start,f_finish:real;
    i,j:integer;
    e,d:real;
    M1:vec3;
matr_proizv:mat33;
 
begin
 
  e:=0.0001;
 
  d:=0.01;
 
  for i:=1 to 3 do
    begin
 
      for j:=1 to 3 do
        begin
          M1:=M;
          f_finish:=100;
          repeat
 
            f_start:=f_finish;
            M1[j]:=M[j]+d;
            f_finish:=(F[i](M1)-F[i](M)/d;
 
            d:=d/2;
 
          until (abs(f_start-f_finish)<e);
 
          matr_proizv[i,j]:= f_finish;
 
        end;
    end;
 
end;
 
end.

АХТУНГ! Код не отлаживал, писал на коленке!

Ответ отправил: min@y™ (статус: Доктор наук)
Время отправки: 4 ноября 2011, 09:33


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

Всего сообщений: 2; последнее сообщение — 4 ноября 2011, 18:12; участников в обсуждении: 2.

4 ноября 2011, 17:20: Статус вопроса изменён на решённый (изменил автор вопроса — porchet): получил замечательный ответ. Большое спасибо эксперту min@y™.

porchet

porchet (статус: Посетитель), 4 ноября 2011, 17:27 [#1]:

Все здорово, спасибо.

Я плохо знаком с классами и с почти не имею опыта создания своих собственных типов. Вызвала непонимание вот эта строка

constructor Create(AOwner: TComponent); override;
.....
constructor TForm1.Create(AOwner: TComponent);
begin
inherited;
F[1]:=y1;
F[2]:=y2;
F[3]:=y3;
end;

И где можно почитать просто и понятно "на пальцах" про эту тему с простыми примерами?
min@y™

min@y™ (статус: Доктор наук), 4 ноября 2011, 18:12 [#2]:

Цитата (porchet):

Все здорово, спасибо.

А где моё +5?

Цитата (porchet):

constructor Create(AOwner: TComponent); override;

Это просто переопределение конструктора.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!

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

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