Текст подпрограммы и версий
aln1r_p.zip
Тексты тестовых примеров
taln1r_p.zip

Подпрограмма:  ALN1R (модуль ALN1R_p)

Назначение

Вычисление приближения к псевдорешению системы линейных алгебраических уравнений на множестве неотрицательных векторов.

Математическое описание

Для системы линейных алгебраических уравнений:

                         A * X  =  B 

ищется вектор X с неотрицательными компонентами, минимизирующий невязку

                         || A * X - B || 

Подробное описание алгоритма смотри в [1] (алгоритм NNLS).

1.  Lawson C.L., Hanson R.J. "Solving Least Squares Problem", Prentice - Hall Inc., Englewood Cliffs, New Jersey, 1974.

Использование

procedure ALN1R(var A :Array of Real; MDA :Integer;
                M :Integer; N :Integer; var B :Array of Real;
                var X :Array of Real; var RNORM :Real;
                var W :Array of Real; var ZZ :Array of Real;
                var INDEX :Array of Integer; var IERR :Integer);

Параметры

A - вещественный двумерный массив размера MDA на N, содержащий при входе в подпрограмму в первых M строках матрицу A (I, J) размерности M на N. По окончании работы подпрограммы содержит произведение матриц Q * A, где Q - ортогональная матрица, размера M на M, вычисленная данной подпрограммой;
MDA - число строк массива A (тип: целый);
M, N - число строк и столбцов матрицы A, соответственно (тип: целый);
B - при входе в подпрограмму содержит вещественный вектор длины M - правую часть уравнения. В результате работы подпрограммы содержит вектор Q * B;
X - вещественный вектор длины N - в результате работы подпрограммы содержит решение;
RNORM - вещественная переменная, содержащая по окончании работы подпрограммы евклидову норму вектора невязки;
W - вещественный рабочий вектор длины N; по окончании работы подпрограммы содержит вектор двойственного решения, удовлетворяющего следующим соотношениям (см.[1]):
W(I) = 0. - для всех I из множества P;
W(I) ≤ 0. - для всех I из множества Z;
ZZ - вещественный рабочий вектор длины M;
INDEX - целый рабочий вектор длины N; по окончании работы подпрограммы определяет множества P и Z следующим образом (см.[1]):
INDEX(1) до INDEX(NSETZ) = множество P
INDEX(IZ1) до INDEX(N) = множество Z
IZ1 = NSETZ + 1 = NPP1;
IERR - диагностический параметр - код завершения программы со значениями:
IERR= 0 - решение получено успешно;
IERR=65 - неправильная размерность параметров;
IERR=66 - требуется более чем 3*N итераций.

Версии: нет

Вызываемые подпрограммы: нет

Замечания по использованию

  1.  Подпрограмма ALN1R обращается к вспомогательным подпрограммам с именами: ALN1R1, ALN1R2, ALN1R3, ALN1R4.

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


Unit TALN1R_p;
interface
uses
SysUtils, Math, { Delphi }
Lstruct, Lfunc, UtRes_p, ALN1R_p;

function TALN1R: String;

implementation

function TALN1R: String;
var
_i,IERR :Integer;
RNORM :Real;
X :Array [0..2] of Real;
W :Array [0..2] of Real;
ZZ :Array [0..1] of Real;
INDЕХ :Array [0..2] of Integer;
const
A :Array [0..5] of Real = ( 1.0,2.0,1.0,2.0,1.0,1.0 );
B :Array [0..1] of Real = ( 2.0,4.0 );
A1 :Array [0..5] of Real = ( 1.0,1.0,1.0,-1.0,0.0,0.0 );
B1 :Array [0..1] of Real = ( 1.0,3.0 );
begin
Result := '';  { результат функции }
ALN1R(A,2,2,3,B,X,RNORM,W,ZZ,INDEX,IERR);
Result := Result + Format('%s',['                ТЕСТ ПОДПРОГРАММЫ ALN1R' + #$0D#$0A]) + #$0D#$0A; 
Result := Result + Format('%s',[' СИСТЕМА УРАВНЕНИЙ: ' + #$0D#$0A]) + #$0D#$0A; 
Result := Result + Format('%s',['    X +   Y + Z = 2' + #$0D#$0A +
 '  2*X + 2*Y + Z = 4' + #$0D#$0A]) + #$0D#$0A; 
Result := Result + Format('%s',['   IERR: ']);
Result := Result + Format('%15d ',[IERR]) + #$0D#$0A;
Result := Result + Format('%s',[' РЕШЕНИЕ: ']);
Result := Result + #$0D#$0A;
for _i:=0 to 2 do
 begin
  Result := Result + Format('%15.5f ',[X[_i]]);
  if ( ((_i+1) mod 3)=0 )
   then Result := Result + #$0D#$0A;
 end;
Result := Result + #$0D#$0A;
Result := Result + Format('%s',[' НЕВЯЗКА: ']);
Result := Result + Format('%15.5f ',[RNORM]) + #$0D#$0A;
Result := Result + Format('%s',['       W: ']);
Result := Result + #$0D#$0A;
for _i:=0 to 2 do
 begin
  Result := Result + Format('%15.5f ',[W[_i]]);
  if ( ((_i+1) mod 3)=0 )
   then Result := Result + #$0D#$0A;
 end;
Result := Result + #$0D#$0A;
Result := Result + Format('%s',['   INDEX: ']);
Result := Result + #$0D#$0A;
for _i:=0 to 2 do
 begin
  Result := Result + Format('%15d ',[INDEX[_i]]);
  if ( ((_i+1) mod 3)=0 )
   then Result := Result + #$0D#$0A;
 end;
Result := Result + #$0D#$0A;
ALN1R(A1,2,2,3,B1,X,RNORM,W,ZZ,INDEX,IERR);
Result := Result + Format('%s',[' СИСТЕМА УРАВНЕНИЙ:' + #$0D#$0A]) + #$0D#$0A; 

Result := Result + Format('%s',['   IERR: ']);
Result := Result + Format('%15d ',[IERR]) + #$0D#$0A;
Result := Result + Format('%s',[' РЕШЕНИЕ: ']);
Result := Result + #$0D#$0A;
for _i:=0 to 2 do
 begin
  Result := Result + Format('%15.5f ',[X[_i]]);
  if ( ((_i+1) mod 3)=0 )
   then Result := Result + #$0D#$0A;
 end;
Result := Result + #$0D#$0A;
Result := Result + Format('%s',[' НЕВЯЗКА: ']);
Result := Result + Format('%15.5f ',[RNORM]) + #$0D#$0A;
Result := Result + Format('%s',['       W: ']);
Result := Result + #$0D#$0A;
for _i:=0 to 2 do
 begin
  Result := Result + Format('%15.5f ',[W[_i]]);
  if ( ((_i+1) mod 3)=0 )
   then Result := Result + #$0D#$0A;
 end;
Result := Result + #$0D#$0A;
Result := Result + Format('%s',['   INDEX: ']);
Result := Result + #$0D#$0A;
for _i:=0 to 2 do
 begin
  Result := Result + Format('%15d ',[INDEX[_i]]);
  if ( ((_i+1) mod 3)=0 )
   then Result := Result + #$0D#$0A;
 end;
Result := Result + #$0D#$0A;
UtRes('TALN1R',Result);  { вывод результатов в файл TALN1R.res }
exit;
end;

end.


  Рассмотрим решение системы уравнений: 

                   x +     y + z = 2 
                   2*x + 2*y + z = 4 

Результаты:

      IERR:                0
      решение:   2.00000e+00       .00000e+00      .00000e+00
      невязка:   8.11612e-08
      w:             0.00000e + 00       .00000e + 00    -3.62964e-08
      INDEX:                         1                         2                        3

  Рассмотрим решение системы уравнений:

                     x + y + 0 * z = 1 
                     x - y + 0 * z = 3 
   
Результаты:

      IERR:      0
      решение:   2.00000e+00       .00000e+00      .00000e+00
      невязка:   1.41421e+00
      W:              .00000e + 00     -2.00000e + 00      .00000e + 00
      INDEX:                       1                           2                         3