Градиент (набла) вектора / массива в Delphi - PullRequest
1 голос
/ 21 февраля 2011

Я должен реализовать следующую формулу в Delphi:

enter image description here

Понимание формулы:

Y_k - число с плавающей запятойкоторый мы назовем просто Y.

w [i] [j] - также массив, содержащий числа с плавающей запятой (1 <= i <= 43 и 1 <= j <= 30). </p>

Согласно моего исходного документа (стр. 12) набла (w) * Y_k является частной производной вектора (столбца) w по отношениюк значению Y ". Это правильно?

Кодирование в Delphi (реализация):

Так как мне реализовать это в Delphi?

Заранее большое спасибо!

1 Ответ

3 голосов
/ 22 февраля 2011

Я предполагаю, что проблема заключается в следующем: «Как я могу вычислить градиент скалярной функции в Delphi?» [Я все еще думаю, что приведенный выше символ больше похож на производную от соединения / коварианты, так какизвестна из дифференциальной геометрии / тензорного исчисления!]

Вам необходимо указать полученные данные.Самый простой случай - когда вы получили функцию f , градиент которой вы хотите вычислить.По определению, если f является функцией k переменных x 1 , x 2, ..., x k , то есть если вы напишите

f ( x 1 , x 2 , ..., x k )

, которое является скалярным полем в ℝ k , тогда градиент составляет

f = (∂ f / ∂ x 1 , ∂ f / ∂ x 2 , ..., ∂ f / ∂ x k )

, то есть векторное поле в10 k (в каждой точке 10 k вы получаете k -мерный вектор).

Это довольно легко реализовать в Delphi.Ниже приведен пример для случая, когда k = 3.

type
  TVector = record
    x, y, z: real;
    constructor Create(ax, ay, az: real);
  end;
  TRealValuedFunction = function(v: TVector): real;

function gradient(f: TRealValuedFunction; v: TVector): TVector;
const
  h = 0.001;
begin
  result.x := (f(TVector.Create(v.x + h, v.y, v.z)) - f(TVector.Create(v.x - h, v.y, v.z))) / (2*h);
  result.y := (f(TVector.Create(v.x, v.y + h, v.z)) - f(TVector.Create(v.x, v.y - h, v.z))) / (2*h);
  result.z := (f(TVector.Create(v.x, v.y, v.z + h)) - f(TVector.Create(v.x, v.y, v.z - h))) / (2*h);
end;

, где, конечно,

constructor TVector.Create(ax, ay, az: real);
begin
  x := ax;
  y := ay;
  z := az;
end;

Пример использования:

function SampleFunction(v: TVector): real;
begin
  result := 5*v.x + 7*v.y;
end;

procedure TForm4.FormCreate(Sender: TObject);
begin
  with gradient(SampleFunction, TVector.Create(2, 6, 3)) do
    ShowMessage(FloatToStr(x) + ', ' + FloatToStr(y) + ', ' + FloatToStr(z))
end;

Результат - 5.00000000000256, 7.000000000005, 0, что является очень хорошим приближением к градиенту SampleFunction при v (в этом случае градиент постоянен в пространстве, то есть не зависит от того, какая точка v в выбранном вами месте).

Конечно, если вы пишете что-то серьезное, вы, вероятно, будете использовать свою собственную библиотеку векторной алгебры.

Кроме того, h = 0.001 может быть не лучшимзначение в вашем случае.

...