Наиболее быстрый способ реализации метода — вывести его путем наследования из заранее заготовленного стандартного класса TStdMethodDef. Следующий код показывает реализацию метода вычисления для алгоритма наименьших квадратов.
type
TLSMCalc = class(TmaStdMethodDef)
public
function GetDescription(out descr: PWideChar): HResult; override; stdcall;
// Вернуть структуру метода
function CalcDef: HResult; override; stdcall;
// Вычисление выходной матрицы целиком
function CalcCellDef(argno: integer; index: maIndex;
out Cell: ImaCell): HResult; override; stdcall;
// Вычисление одной ячейки выходной матрицы
// если функция не используется, не описывайте ее
end;
// Структура метода
function TLSMCalc.GetDescription(out descr: PWideChar): HRESULT;
begin
descr := 'Calc St|F ->St|{y}';
result := MA_NOERROR;
end;
// Вычисление выходной матрицы целиком
function TLSMCalc.CalcDef: HRESULT;
var
A, y, coeff: TmaMatrix;
N, F, i, j: integer;
sum: double;
begin
result := MA_NOERROR;
try
try
A := Input['Sc|F'].AsMatrix;
y := Output['Sc|{y}'].AsMatrix;
coeff := Param['Coeff'].AsMatrix;
// собственно вычисление
N := A.Size[0]; // число строк матрицы A=Sc|F
F := A.Size[1]; // число столбцов матрицы A=Sc|F
for i := 0 to N - 1 do begin
sum := 0;
for j := 0 to F - 1 do
sum := sum + A[i][j].AsDouble * coeff[j].AsDouble;
y[i].AsDouble := sum;
ProgressExc((i + 1) / N, 'Calculating LSM');
// полезно, если вычисления длитеьные
end;
finally
A.Free; y.Free; coeff.Free;
end; except
on E: EUserInterrupt do result := MA_ERR_INTERRUPT;
// если выполнение прервано пользователем
else result := MA_ERR_CLIENTFAIL;
end;
end;
// Вычисление одной ячейки выходной матрицы
function TLSMCalc.CalcCellDef(argno: integer; index: maIndex;
out Cell: ImaCell): HResult; stdcall;
var
A, coeff: TmaMatrix;
N, F, i, j: integer;
sum: double;
begin
result := MA_NOERROR;
try
try
A := Input['Sc|F'].AsMatrix;
coeff := Param['Coeff'].AsMatrix;
// собственно вычисление
F := A.Size[1]; // число столбцов матрицы A=Sc|F
i := index.idx[0];
sum := 0;
for j := 0 to F - 1 do
sum := sum + A[i][j].AsDouble * coeff[j].AsDouble;
Cell - > SetasDouble(sum);
finally
A.Free; coeff.Free;
end; except
result := MA_ERR_CLIENTFAIL;
end;
end;