{ procedimientos auxiliares de FORMAECn }
unit cprocs;
interface
uses
	xMatDefs, CYTipos;

{ Retorna el índice de la fila de la submatriz formadas por las filas
desde la pf1 hasta pf2 inclusive de mayor valor absoluto del máximo en
la columna pcol }
function PointMaxCol(var m:TMatSistema;pf1,pf2, pcol:word):word;

{ Suma a la fila f1 la fila f2 multiplicada por Fac en el subrango de
columnas desde col1 hasta col2 inclusive }
procedure SumFilaFac(var f1,f2:TVectFila; col1,col2:word; Fac:NReal);

{ Intercambia los elementos de las filas f1 y f2 entre si en el subrango
de columnas de col1 hasta col2 inclusive}
procedure IntercaFila(var f1,f2:TVectFila; col1,col2:word);

{ Intercambia los elementos de las columnas col1, col2 de la matriz a
en el rango de filas de f1 hasta f2 inclusive }
procedure IntercaCol(var a:TMatSistema; col1,col2,f1,f2:word);

{ Divide los elementos de la fila f en el rango de columnas de col1 a col2
inclusive por el número divisor }
procedure DivFila(var f:TVectFila; col1,col2:word; divisor:NReal);

{ Procede a la eliminicación Gaussiana (directa) de la variable asociada
a la columna piv. La fila piv es convinada con las inferiores (hasta pf1 inclusive )
para eliminar la variable.
 Las combinaciones se realizan en las columnas de piv+1 hasta
pc1 inclusive. Se sobreentiende que los elementos de las filas de indice
superior a piv de la coluna piv quedan nulos en el sistema de ecuaciones
pero en la operacion NO se anulan pues se sobreentiende que son nulos.
RESULTADO: El resultado es 0 si fue posible realizar la eliminación,
y 1 si no fue posible encontrar un pivote no nulo }
procedure Eliminacion1( var a: TMatSistema; piv, pf1, pc1: integer);



{---------------------------------
 Realiza el producto escalar del vector v1 comenzando desde
el elemento v1e1 por el vector comenzando en el elemento v2e1
para el producto se consideram ne elementos a partir de las
posiciones indicadas inclusive }
procedure proesc(var res:NReal; var v1;v1e1:integer;
					  var v2; v2e1,ne:integer);


{--------------------------
"Producto Escalar Indexado". En res se calacula el producto
escalar del vector v1 comenzando en el elemento v1e1 por el
vector v2[indx[.]] es decir el vector v2, pero accediendo a
sus elementos por intermedio de una tabla de indices. Para
el producto se consideran ne elementos.}

procedure proescindex(var res:NReal; var v1;v1e1:integer;
					  var v2; v2e1,ne:integer; var indx: TVectEstRealIdx);

{ Codificación de un vector de varibles logicas en bytes. }
procedure CodEstLog( var ResCod: TCodLog; var xlog: TVectEstLog);

{ devuelve -1 si c1<c2, 0 si c1=c2 y 1 si c1>c2 }
function CompareCodLog( var c1, c2: TCodLog): integer;


implementation

{ Retorna el índice de la fila de la submatriz formadas por las filas
desde la pf1 hasta pf2 inclusive de mayor valor absoluto del máximo en
la columna pcol }
function PointMaxCol(var m:TMatSistema;pf1,pf2,pcol:word):word;
(*------------------
m[PointMaxCol,pcol] = maximo( abs( m[pf1..pf2,pcol]) )
------------------*)
var
	temp:NReal;
   k:word;
begin
	temp:=abs(m[pf1,pcol]); PointMaxCol:=pf1;
	for k:= pf1+1 to pf2 do
   	if temp< abs(m[k,pcol]) then
      begin
      	temp:=abs(m[k,pcol]);
       	PointMaxCol:=k
      end
end;



{ Suma a la fila f1 la fila f2 multiplicada por Fac en el subrango de
columnas desde col1 hasta col2 inclusive }
procedure SumFilaFac(var f1,f2:TVectFila; col1,col2:word; Fac:NReal);
(*--------------
f1[col1..col2]:= f1[col1..col2] + Fac * f2[col1..col2];
---------------*)
var j:word;
begin
for j:= col1 to col2 do
    f1[j]:=f1[j]+Fac*f2[j];
end;

procedure IntercaFila(var f1,f2:TVectFila; col1,col2:word);
(*-----------------------
f1[col1..col2] <--> f2[col1..col2]
----------------------*)
var
	temp:NReal;
   j:word;
begin
for j:=col1 to col2 do
    begin
    temp:=f1[j];
    f1[j]:=f2[j];
    f2[j]:=temp
    end;
end;


procedure IntercaCol(var a:TMatSistema; col1,col2,f1,f2:word);
(*-----------------------
a[f1..f2,col1] <----> a[f1..f2,col2]
-----------------------*)
var
	temp:NReal;
	k:word;
begin
for k:=f1 to f2 do
	begin
	temp:=a[k,col1];
	a[k,col1]:=a[k,col2];
	a[k,col2]:=temp
	end
end;


procedure DivFila(var f:TVectFila; col1,col2:word; divisor:NReal);
(*-------------------
f[j] := f[j]/divisor , j : [col1..col2]
-----------------------------------------*)
var
	j:word;
begin
for j:=col1 to col2 do
	f[j]:=f[j]/divisor;
end;



procedure Eliminacion1( var a: TMatSistema; piv, pf1, pc1: integer);
var
	pm:integer;
   temp: NReal;
begin
	temp:= a[piv, piv];
	for pm:=piv+1 to pf1 do
		if Not EsCero(a[pm,piv]) then
			SumFilaFac(a[pm],a[piv],piv+1,pc1,-a[pm,piv]/temp);
end;



{---------------------------------
 Realiza el producto escalar del vector v1 comenzando desde
el elemento v1e1 por el vector comenzando en el elemento v2e1
para el producto se consideram ne elementos a partir de las
posiciones indicadas inclusive }

procedure proesc(var res:NReal; var v1;v1e1:integer;
					  var v2; v2e1,ne:integer);
var
j:integer;

begin
if ne>0 then
	for j:= 0 to ne-1 do
		res:=res+TVectFila(v1)[v1e1+j]*TVectFila(v2)[v2e1+j];
end;


{--------------------------
"Producto Escalar Indexado". En res se calacula el producto
escalar del vector v1 comenzando en el elemento v1e1 por el
vector v2[indx[.]] es decir el vector v2, pero accediendo a
sus elementos por intermedio de una tabla de indices. Para
el producto se consideran ne elementos.}

procedure proescindex(var res:NReal; var v1;v1e1:integer;
					  var v2; v2e1,ne:integer; var indx: TVectEstRealIdx);
var
	j:integer;

begin
if ne>0 then
	for j:= 0 to ne-1 do
		res:=res+TVectFila(v1)[v1e1+j]*TVectFila(v2)[indx[v2e1+j]];
end;



procedure CodEstLog( var ResCod: TCodLog; var xlog: TVectEstLog);
var
	tmp: byte;
	kbyte, jbit:integer;
   shi: integer;
begin
	shi:=1;

	for kbyte:= 1 to NByteCodLog-1 do
	begin
		tmp:=0;
      if xlog[shi] then tmp:=1
   	else tmp:=0;
		for jbit:=2 to 8 do
   	begin
			tmp:= tmp shl 1;
			if xlog[shi] then inc(tmp);
			inc(shi);
		end;
      ResCod[kbyte]:= tmp; 
	end;


	tmp:=0;
   if xlog[shi] then tmp:=1
   else tmp:=0;
	for jbit:=2 to NBitsUltimoByteCodLog do
   begin
		tmp:= tmp shl 1;
		if xlog[shi] then inc(tmp);
		inc(shi);
	end;
   ResCod[NByteCodLog]:= tmp; 
end;


function CompareCodLog( var c1, c2: TCodLog): integer;
var
	k: integer;

begin
	for k:= NByteCodLog downto 1 do
		if c1[k]<c2[k] then
		begin
			CompareCodLog:= -1;
			exit;
		end
		else
		if c1[k]>c2[k] then
		begin
			CompareCodLog:= 1;
			exit;
		end;

	{ Si llegamos hasta aquí coinciden todos los bytes }
	CompareCodLog:= 0;
end;

	


end.