Скачиваний:
2
Добавлен:
12.01.2026
Размер:
2.24 Mб
Скачать

Программа

domains

real_list = real*

real_matrix = real_list*

file = infile

predicates

print_matrix(integer, integer, real_matrix)

print_matrix_rows(real_matrix)

print_row(real_list)

read_row(integer, real_list)

read_int(integer)

read_real(real)

load_matrix(integer, integer, real_matrix)

load_matrix_rows(integer, integer, real_matrix)

load_matrix_from_file(string, integer, integer, real_matrix)

load_matrix_from_file_st1(string)

load_matrix_from_file_st2(string)

load_matrix_from_file_st3(integer)

load_matrix_from_file_st4(integer)

extract_row_element(integer, real_list, real)

extract_row(integer, real_matrix, real_list)

extract_matrix_element(integer, integer, real_matrix, real)

mult_matrix_elem(integer,integer,integer,integer,integer,real_matrix,real_matrix,real)

mult_matrix_elem_iter(integer,integer,integer,integer,integer,integer,real_matrix,real_matrix,real,real)

mult_matrix(integer,integer,integer,real_matrix,real_matrix,real_matrix)

mult_matrix_iter(integer,integer,integer,real_matrix,real_matrix,integer,real_matrix)

mult_matrix_row(integer,integer,integer,real_matrix,real_matrix,integer,real_list)

mult_matrix_row_iter(integer,integer,integer,real_matrix,real_matrix,integer,integer,real_list)

mod_row_in_matrix(integer,real_matrix,integer,real_list,real_matrix)

exchange_rows_in_matrix(integer,real_matrix,integer,integer,real_matrix)

mult_row_num(real_list,real,real_list)

add_rows(real_list,real_list,real_list)

abs_elem(real,real)

is_real_zero(real)

is_reals_equal(real, real)

max_real(real,real,real)

min_real(real,real,real)

transpose_matrix(integer, integer, real_matrix, real_matrix)

transpose_matrix_iter(integer, integer, real_matrix, integer, real_matrix)

transpose_matrix_row(integer, integer, real_matrix, integer, real_list)

transpose_matrix_row_iter(integer, integer, real_matrix, integer, integer, real_list)

is_lists_equal(real_list, real_list)

is_matrixes_equal(real_matrix, real_matrix)

is_matrix_symmetric(integer, integer, real_matrix)

check_dimensions(integer, integer, integer, integer, integer)

find_max_abs_in_matrix_column(integer,real_matrix,integer,integer)

find_max_abs_in_matrix_column_iter(integer, real_matrix,integer,real,integer,integer,integer)

eye_matrix_row(integer, integer, integer, real_list)

eye_matrix_row_iter(integer, integer, integer, integer, real_list)

eye_matrix_iter(integer,integer,integer,real_matrix)

eye_matrix(integer,integer,real_matrix)

inv(integer,real_matrix,real_matrix)

inv_gauss(integer,real_matrix,real_matrix,real_matrix,real_matrix)

inv_gauss_iter(integer,real_matrix,real_matrix,real_matrix,real_matrix,integer)

inv_gauss_iter_div(integer,real_matrix,real_matrix,real_matrix,real_matrix,integer)

inv_gauss_iter_div_iter(integer,real_matrix,real_matrix,integer,integer,real_matrix,real_matrix)

dot_product(real_list,real_list,real)

vector_norma(real_list,real)

vector_normalization(real_list,real_list)

vector_normalization2(real_list,real,real_list)

remove_component(real_list,real_list,real_list)

remove_component_from_vectors(real_matrix,real_list,real_matrix)

gramm_shmidt(real_matrix,real_matrix)

min_element_of_vector(real_list,real)

min_element_of_vector2(real_list,real,real)

max_element_of_vector(real_list,real)

max_element_of_vector2(real_list,real,real)

div_real(real,real,real)

div_vectors(real_list,real_list,real_list)

is_eigenvector_stable(real_list,real_list)

is_eigenvectors_stable(real_matrix,real_matrix)

calc_eigenvalue(real_list,real_list,real)

calc_eigenvalues(real_matrix,real_matrix,real_list)

process_candidates(integer, integer, real_matrix, real_matrix, real_matrix)

find_eigenvectors(integer, integer, real_matrix, real_matrix, real_matrix)

find_eigenvectors2(integer, integer, real_matrix, real_matrix, real_matrix, real_matrix)

clauses

% Поиск набора стабильных кандидатов X по матрице M и результатам

% преобразования MX

find_eigenvectors2(_, _, _, X, MX, X):-

is_eigenvectors_stable(X, MX),

!.

find_eigenvectors2(N, K, M, _, MX, Eigenvectors):-!,

gramm_shmidt(MX, X1),

find_eigenvectors(N, K, M, X1, Eigenvectors).

% Поиск для матрицы M размерности N x N набора из K стабильных

% (в указанном выше смысле) кандидатов в собственные векторы

% где X - текущий набор кандидатов

find_eigenvectors(N, K, M, X, Eigenvectors):-!,

process_candidates(N, K, M, X, MX),

find_eigenvectors2(N, K, M, X, MX, Eigenvectors).

% Для матрицы M размерности N x N и набору из K строк X - кандидатам в

% собственные векторы M получаем набор строк MX,

% которые совпадают с преобразованными матрицей M векторами-кандидатами

process_candidates(N, K, M, X, MX):-

transpose_matrix(K, N, X, TX),

mult_matrix(N, N, K, M, TX, TMX),

transpose_matrix(N, K, TMX, MX).

% Вычисление набора собственных чисел по набору стабильных кандидатов

% в собственные векторы M и результатам их преобразований AM

calc_eigenvalues([], [], []):-!.

calc_eigenvalues([H|M], [AH|AM], [Lambda|Lambdas]):-

calc_eigenvalue(H, AH, Lambda),

calc_eigenvalues(M, AM, Lambdas).

% Вычисление собственного числа по стабильному кандидату в собственные векторы X

% и результату преобразования AX

calc_eigenvalue([X|_], [AX|_], Lambda):-

div_real(AX, X, Lambda).

% Проверка достаточной стабильности набора кандидатов в собственные векторы

% матрицы

is_eigenvectors_stable([], []):-!.

is_eigenvectors_stable([H|M], [AH|AM]):-

is_eigenvector_stable(H, AH),

is_eigenvectors_stable(M, AM).

% Проверка достаточной стабильности кандидата X в собственные векторы

is_eigenvector_stable(X, AX):-

div_vectors(X, AX, Divs),

min_element_of_vector(Divs, MinDiv),

max_element_of_vector(Divs, MaxDiv),

MaxDiv - MinDiv < 1e-6.

% Нахождение вектора из частных соответствующих элементов первого и второго векторов

div_vectors([], [], []):-!.

div_vectors([H1|T1], [H2|T2], [H3|T3]):-

div_real(H1, H2, H3),

div_vectors(T1, T2, T3).

div_real(_,X,0):-

is_real_zero(X), !.

div_real(X, Y, Z):-

Z = X / Y.

% Нахождение максимального элемента

max_element_of_vector2([], Min, Min):-!.

max_element_of_vector2([H|T], H1, Min):-

max_real(H, H1, H2),

max_element_of_vector2(T, H2, Min).

% Нахождение максимального элемента вектора

max_element_of_vector([H], H):-!.

max_element_of_vector([H|T], Min):-

max_element_of_vector2(T, H, Min).

% Нахождение минимального элемента

min_element_of_vector2([], Min, Min):-!.

min_element_of_vector2([H|T], H1, Min):-

min_real(H, H1, H2),

min_element_of_vector2(T, H2, Min).

% Нахождение минимального элемента вектора

min_element_of_vector([H], H):-!.

min_element_of_vector([H|T], Min):-

min_element_of_vector2(T, H, Min).

% Процедура (Грамма-Шмидта) ортонормирования набора векторов

gramm_shmidt([], []):-!.

gramm_shmidt([H|Vects], [NormH|Vects1]):-

vector_normalization(H, NormH),

remove_component_from_vectors(Vects, NormH, Vects2),

gramm_shmidt(Vects2, Vects1).

% Удаление из каждого из набора векторов компонентов

% вектора-второго аргумента

remove_component_from_vectors([], _, []):-!.

remove_component_from_vectors([V|T], NormVector, [V1|T1]):-

remove_component(V, NormVector, V1Temp),

vector_normalization(V1Temp, V1),

remove_component_from_vectors(T, NormVector, T1).

% Удаление из первого вектора компонентов второго вектора

remove_component(V1, V2, V3):-

dot_product(V1, V2, Prod),

Prod1 = -Prod,

mult_row_num(V2, Prod1, V2Mult),

add_rows(V1, V2Mult, V3).

% Деление вектора на его норму

vector_normalization2(V, Norm, V):-

is_real_zero(Norm), !.

vector_normalization2([], _, []):-!.

vector_normalization2([H|V], Norm, [NormH|NormV]):-

NormH = H / Norm,

vector_normalization2(V, Norm, NormV).

% Нормализация вектора согласно евклидовой норме

vector_normalization(V, NormV):-

vector_norma(V, Norm),

vector_normalization2(V, Norm, NormV).

% Подсчет евклидовой нормы вектора

vector_norma(V, Norm):-

dot_product(V,V,Norm2),

Norm = sqrt(Norm2).

% Подсчет скалярного произведения двух векторов

dot_product([], [], 0.0):-!.

dot_product([H1|T1], [H2|T2], Res):-

dot_product(T1, T2, Res1),

Res = Res1 + H1 * H2.

% Рекурсивная процедура обнуления элементов столбца ColIndex матрицы A ниже главной

% диагонали. В данной итерации обнуляется элемент строки RowIndex размерности матриц N x N

inv_gauss_iter_div_iter(N, A, B, _, RowIndex, A, B):-

RowIndex >= N, !.

inv_gauss_iter_div_iter(N, A, B, RowIndex, RowIndex, A1, B1):-!,

RowIndex1 = RowIndex + 1,

inv_gauss_iter_div_iter(N, A, B, RowIndex, RowIndex1, A1, B1).

inv_gauss_iter_div_iter(N, A, B, ColIndex, RowIndex, A1, B1):-

extract_matrix_element(RowIndex, ColIndex, A, Element),

extract_row(ColIndex, A, ARow_),

extract_row(ColIndex, B, BRow_),

Mult = -Element,

mult_row_num(ARow_, Mult, ARow_1),

mult_row_num(BRow_, Mult, BRow_1),

extract_row(RowIndex, A, ARow),

extract_row(RowIndex, B, BRow),

add_rows(ARow, ARow_1, ARow1),

add_rows(BRow, BRow_1, BRow1),

mod_row_in_matrix(N, A, RowIndex, ARow1, A2),

mod_row_in_matrix(N, B, RowIndex, BRow1, B2),

RowIndex1 = RowIndex + 1,

inv_gauss_iter_div_iter(N, A2, B2, ColIndex, RowIndex1, A1, B1).

% Деление строки матриц A, B с индексом RowIndex на диагональный элемент

% матрицы A этой строки и обнуление всех элементов матрицы A столбца RowIndex

% вне главной диагонали

inv_gauss_iter_div(_, A, _, _, _, RowIndex):-

extract_matrix_element(RowIndex, RowIndex, A, Element),

is_real_zero(Element), !,

write( "Matrix have no invert matrix. Fatal error" ), nl, fail.

inv_gauss_iter_div(N, A, B, A1, B1, RowIndex):-

extract_matrix_element(RowIndex, RowIndex, A, Element),

Mult = 1 / Element,

extract_row(RowIndex, A, ARow),

extract_row(RowIndex, B, BRow),

mult_row_num(ARow, Mult, ARow1),

mult_row_num(BRow, Mult, BRow1),

mod_row_in_matrix(N, A, RowIndex, ARow1, A2),

mod_row_in_matrix(N, B, RowIndex, BRow1, B2),

%RowIndex1 = RowIndex + 1,

%inv_gauss_iter_div_iter(N, A2, B2, RowIndex, RowIndex1, A1, B1).

inv_gauss_iter_div_iter(N, A2, B2, RowIndex, 0, A1, B1).

% Рекурсивная процедура поиска обратной матрицы

inv_gauss_iter(N, A, B, A, B, RowIndex):-

RowIndex >= N, !.

inv_gauss_iter(N, A, B, A1, B1, RowIndex):-

find_max_abs_in_matrix_column(N, A, RowIndex, SelIndex),

exchange_rows_in_matrix(N, A, RowIndex, SelIndex, A2),

exchange_rows_in_matrix(N, B, RowIndex, SelIndex, B2),

inv_gauss_iter_div(N, A2, B2, A3, B3, RowIndex),

RowIndex1 = RowIndex + 1,

inv_gauss_iter(N, A3, B3, A1, B1, RowIndex1).

% Метод Гаусса поиска обратной матрицы

inv_gauss(N, A, B, A1, B1):-

inv_gauss_iter(N, A, B, A1, B1, 0).

% Процедура поиска обратной матрицы InvA для матрицы A размерности N x N

inv(N, A, InvA):-

eye_matrix(N, N, B),

inv_gauss(N, A, B, _, InvA).

% Рекурсивная процедура формирования кусочка строки с индексом RowIndex единичной

% матрицы размерности N x N, состоящей из элементов из столбцов начиная с ColIndex

% и заканчивая C-1

eye_matrix_row_iter(_, C, _, ColIndex, []):-

ColIndex >= C, !.

eye_matrix_row_iter(N, C, RowIndex, RowIndex, [1.0 | Row]):-!,

ColIndex1 = RowIndex+1,

eye_matrix_row_iter(N, C, RowIndex, ColIndex1, Row).

eye_matrix_row_iter(N, C, RowIndex, ColIndex, [0.0 | Row]):-

ColIndex1 = ColIndex+1,

eye_matrix_row_iter(N, C, RowIndex, ColIndex1, Row).

% Формирование строки с индексом RowIndex единичной матрицы размерности N x N

% состоящей из C колонок

eye_matrix_row(N, C, RowIndex, Row):-

eye_matrix_row_iter(N, C, RowIndex, 0, Row).

% Рекурсивное формирование кусочка единичной матрицы M размерности N x N, состоящей из

% строк с индексами не меньше RowIndex и содержащей первые C колонок единичной

% матрицы

eye_matrix_iter(N, _, RowIndex, []):-

RowIndex >= N, !.

eye_matrix_iter(N, C, RowIndex, [Row|T]):-

eye_matrix_row(N, C, RowIndex, Row),

RowIndex1 = RowIndex + 1,

eye_matrix_iter(N, C, RowIndex1, T).

% Формирование единичной матрицы M размерности N x N

% состоящей из C первых колонок

eye_matrix(N, C, M):-

eye_matrix_iter(N, C, 0, M).

% Рекурсивный поиск максимального элемента матрицы M размерности N x N в столбце ColIndex

% среди элементов CurIndex, ..., N-1. Лучший элемент из просмотренных - MaxAbs, индекс

% его строки BestIndex. Найденный элемент расположен в строке RowIndex.

find_max_abs_in_matrix_column_iter(N, _, _, _, BestIndex, CurIndex, BestIndex):-

CurIndex>=N, !.

find_max_abs_in_matrix_column_iter(N, M, ColIndex, MaxAbs, _, CurIndex, RowIndex):-

extract_matrix_element(CurIndex, ColIndex, M, Element),

abs_elem(Element,AbsElement),

AbsElement > MaxAbs,!,

CurIndex1 = CurIndex+1,

find_max_abs_in_matrix_column_iter(N, M, ColIndex, AbsElement, CurIndex, CurIndex1, RowIndex).

find_max_abs_in_matrix_column_iter(N, M, ColIndex, MaxAbs, BestIndex, CurIndex, RowIndex):-

CurIndex1 = CurIndex+1,

find_max_abs_in_matrix_column_iter(N, M, ColIndex, MaxAbs, BestIndex, CurIndex1, RowIndex).

% Поиск в квадратной матрице M размерности N x N строки, в которой находится

% наибольший по модулю элемент столбца с индексом ColIndex, расположенный не

% выше главной диагонали (для метода Гаусса поиска обратной матрицы).

find_max_abs_in_matrix_column(N, M, ColIndex, RowIndex):-

extract_matrix_element(ColIndex, ColIndex, M, Element),

abs_elem(Element,MaxAbs),

find_max_abs_in_matrix_column_iter(N, M, ColIndex, MaxAbs, ColIndex, ColIndex, RowIndex).

% Проверка размерностей матриц A и B - матрицы должны быть квадратными, совпадающих размерностей

check_dimensions(ARows, ACols, _, _, _):-

ARows <> ACols,!,

write( "Matrix A is not square" ), nl, fail.

check_dimensions(_, _, BRows, BCols, _):-

BRows <> BCols,!,

write( "Matrix B is not square" ), nl, fail.

check_dimensions(ARows, _, BRows, _, _):-

ARows <> BRows,!,

write( "Matrix A and B have different dimensions" ), nl, fail.

check_dimensions(ARows, _, _, _, EigenvalsToFind):-

EigenvalsToFind > ARows, !,

write( "To find ", EigenvalsToFind, " eigenvalues dimensions of matrix must be >=", EigenvalsToFind ), nl, fail.

check_dimensions(_, _, _, _, _).

% Проверка симметричности матрицы размерности Rows x Cols с выводом сообщения об ошибке

% в случае ложности проверяемого утверждения

is_matrix_symmetric(Rows, Cols, Matrix):-

transpose_matrix(Rows, Cols, Matrix, Matrix2),

is_matrixes_equal(Matrix, Matrix2),!.

is_matrix_symmetric(_,_,_):-

write( "Matrix is not symmetric" ), nl, fail.

% Равны ли две матрицы в смысле совпадения размерностей и равенства

% соответствующих элементов

is_matrixes_equal([], []):-!.

is_matrixes_equal([H1|T1], [H2|T2]):-

is_lists_equal(H1, H2),

is_matrixes_equal(T1, T2).

% Равны ли два списка действительных чисел: совпадают ли их размерности и

% равны ли соответствующие элементы

is_lists_equal([], []):-!.

is_lists_equal([H1|T1], [H2|T2]):-

is_reals_equal(H1, H2), !,

is_lists_equal(T1, T2).

% Построение для матрицы M размерности Rows x Cols части строки с индексом RowIndex транспонированной

% матрицы. Строка содержит элементы из столбцов с индексами начиная с ColIndex

transpose_matrix_row_iter(Rows, _, _, _, ColIndex, [] ):-

ColIndex >= Rows, !.

transpose_matrix_row_iter(Rows, Cols, M, RowIndex, ColIndex, [H|T] ):-

extract_matrix_element(ColIndex, RowIndex, M, H ),

ColIndex1 = ColIndex + 1,

transpose_matrix_row_iter(Rows, Cols, M, RowIndex, ColIndex1, T ).

% Построение для матрицы M размерности Rows x Cols строки транспонированной

% матрицы с индексом RowIndex

transpose_matrix_row(Rows, Cols, M, RowIndex, Row ):-

transpose_matrix_row_iter(Rows, Cols, M, RowIndex, 0, Row ).

% Рекурсивное транспонирование матрицы M размерности Rows x Cols с образованием матрицы M1

% из всех строк транспонированной матрицы начиная со StrIndex

transpose_matrix_iter(_, Cols, _, StrIndex, []):-

StrIndex >= Cols, !.

transpose_matrix_iter(Rows, Cols, M, StrIndex, [H|T]):-

transpose_matrix_row(Rows, Cols, M, StrIndex, H ),

StrIndex1 = StrIndex + 1,

transpose_matrix_iter(Rows, Cols, M, StrIndex1, T).

% Транспонирование матрицы M размерности Rows x Cols с образованием матрицы M1

transpose_matrix(Rows, Cols, M, M1):-

transpose_matrix_iter(Rows, Cols, M, 0, M1).

% Поменять в матрице M из Rows строк строки с индексами RowIndex1, RowIndex2 с

% образованием матрицы M2

exchange_rows_in_matrix(Rows, M, RowIndex1, RowIndex2, M2):-

extract_row(RowIndex1, M, Row1),

extract_row(RowIndex2, M, Row2),

mod_row_in_matrix(Rows, M, RowIndex1, Row2, M1),

mod_row_in_matrix(Rows, M1, RowIndex2, Row1, M2).

% Нахождение максимума двух действительных чисел

max_real(X1, X2, X1):-

X1 > X2, !.

max_real(_, X2, X2).

% Нахождение минимума двех действительных чисел

min_real(X1, X2, X1):-

X1 < X2, !.

min_real(_, X2, X2).

% Равны дли два действильных числа

is_reals_equal(X1, X2):-

X3 = X1 - X2,

is_real_zero(X3).

% Равно ли число нулю

is_real_zero( X ):-

abs_elem( X, Mod ),

Mod < 1e-7.

% Модуль действительного числа

abs_elem( X, Mod ):-

Mod = abs( X ).

% Сложение элементов двух списков (равной длины) с образованием нового списка

add_rows([], [], []):-!.

add_rows([H1|T1], [H2|T2], [H3|T3]):-

H3 = H1 + H2,

add_rows(T1, T2, T3).

% Умножение элементов списка на число Mult с образованием нового списка

mult_row_num([], _, []):-!.

mult_row_num([H|T], Mult, [H1|T1]):-

H1 = H * Mult,

mult_row_num(T, Mult, T1).

% Замена в матрице M с количеством строк R с индексом RowIndex на строку Row.

% Результат операции - матрица M1

mod_row_in_matrix( _, [_|T], 0, Row, [Row|T]):-!.

mod_row_in_matrix(R, [H|T], RowIndex, Row, [H|T1]):-

R > 0,

RowIndex > 0,

R1 = R-1,

RowIndex1 = RowIndex-1,

mod_row_in_matrix(R1, T, RowIndex1, Row, T1).

% Рекурсивное вычисление строки произведения двух матриц

mult_matrix_row_iter(_, _, R3, _, _, _, ColIndex, [] ):-

ColIndex >= R3, !.

mult_matrix_row_iter(R1, R2, R3, M1, M2, RowIndex, ColIndex, [H|T]):-

mult_matrix_elem(RowIndex, ColIndex, R1, R2, R3, M1, M2, H),

ColIndex1 = ColIndex + 1,

mult_matrix_row_iter(R1, R2, R3, M1, M2, RowIndex, ColIndex1, T).

% Нахождение строки с индексом RowIndex от произведения матриц M1, M2

% размерностей R1 x R2, R2 x R3

mult_matrix_row(R1, R2, R3, M1, M2, RowIndex, Row):-

mult_matrix_row_iter(R1, R2, R3, M1, M2, RowIndex, 0, Row).

% Рекурсивное вычисление произведения двух матриц

mult_matrix_iter(R1, _, _, _, _, RowIndex, []):-

RowIndex >= R1, !.

mult_matrix_iter(R1, R2, R3, M1, M2, RowIndex, [H|T]):-

mult_matrix_row(R1, R2, R3, M1, M2, RowIndex, H),

RowIndex1 = RowIndex + 1,

mult_matrix_iter(R1, R2, R3, M1, M2, RowIndex1, T).

% Вычисление произведения двух матриц M1, M2 размерностей R1 x R2, R2 x R3

mult_matrix(R1, R2, R3, M1, M2, M3):-

mult_matrix_iter(R1, R2, R3, M1, M2, 0, M3).

% Итерационное вычисление элемента произведения матриц

mult_matrix_elem_iter(RowIndex, ColIndex, Index, R1, R2, R3, M1, M2, Sum, Result):-

Index < R2, !,

extract_matrix_element(RowIndex, Index, M1, ElemM1),

extract_matrix_element(Index, ColIndex, M2, ElemM2),

Sum1 = Sum + ElemM1*ElemM2,

Index1 = Index + 1,

mult_matrix_elem_iter(RowIndex, ColIndex, Index1, R1, R2, R3, M1, M2, Sum1, Result).

mult_matrix_elem_iter(_, _, _, _, _, _, _, _, Result, Result).

% Вычисление элемента произведения матриц M1, M2 размерностей R1xR2, R2xR3,

% расположенного в строке с индексом RowIndex и столбце с индексом ColIndex

mult_matrix_elem(RowIndex, ColIndex, R1, R2, R3, M1, M2, Elem):-

mult_matrix_elem_iter(RowIndex, ColIndex, 0, R1, R2, R3, M1, M2, 0.0, Elem).

% Извлечение элемента матрицы Matrix из строки индекса RowIndex и

% столбца индекса ColIndex

extract_matrix_element(RowIndex, ColIndex, Matrix, Element):-

extract_row(RowIndex,Matrix, Row),

extract_row_element(ColIndex, Row, Element).

% Извлечение элемента указанного индекса из списка

extract_row_element(0, [H|_], H):-!.

extract_row_element(Ind, [_|T], Elem):-

Ind > 0,

!,

Ind1 = Ind-1,

extract_row_element(Ind1, T, Elem).

% Извлечение строки указанного индекса из матрицы

extract_row(0, [H|_], H):-!.

extract_row(Ind, [_|T], Elem):-

Ind > 0,

!,

Ind1 = Ind-1,

extract_row(Ind1, T, Elem).

load_matrix_from_file(Filename, Rows, Cols, Matrix):-

load_matrix_from_file_st1(Filename),

load_matrix_from_file_st2(Filename),

load_matrix_from_file_st3(Rows),

load_matrix_from_file_st4(Cols),

load_matrix(Rows, Cols, Matrix),

closefile(infile).

load_matrix_from_file_st1(Filename):-

existfile(Filename),!,

write( "Found file '", Filename, "'" ), nl.

load_matrix_from_file_st1(Filename):-

write( "Cannot file file '", Filename, "'" ), nl, fail.

load_matrix_from_file_st2(Filename):-

openread(infile,Filename),!,

readdevice(infile).

load_matrix_from_file_st2(Filename):-

write( "Cannot open file '", Filename, "' for reading" ), nl,

fail.

load_matrix_from_file_st3(Rows):-

read_int(Rows),

Rows > 0, !.

load_matrix_from_file_st3(_):-

write( "Bad numbers of rows in input file" ), nl, fail.

load_matrix_from_file_st4(Cols):-

read_int(Cols),

Cols > 0, !.

load_matrix_from_file_st4(_):-

write( "Bad numbers of columns in input file" ), nl, fail.

% Загрузка матрицы указанной размерности из потока ввода

load_matrix(Rows, Cols, Matrix):-

load_matrix_rows(Rows, Cols, Matrix).

% Загрузка Rows строк длины Cols из потока ввода

load_matrix_rows(0, _, []):-!.

load_matrix_rows(Rows, Cols, [Row|Rest]):-

Rows>0,

read_row(Cols, Row),

Rows1 = Rows-1,

load_matrix_rows(Rows1, Cols, Rest).

% Загрузка строки длины Cols из потока ввода

read_row(0, []):-!.

read_row(Cols, [H|T]):-

Cols > 0,

read_real(H),

Cols1 = Cols-1,

read_row(Cols1, T).

% Чтение целого числа из потока ввода с выводом сообщения об ошибке

% в случае неудачи

read_int(Num):-

readint(Num),!.

read_int(_):-

write( "Failed to read integer. Error" ), nl,

fail.

% Чтение действительного числа из потока ввода с выводом сообщения об ошибке

% в случае неудачи

read_real(Num):-

readreal(Num),!.

read_real(_):-

write( "Failed to read real. Error" ), nl,

fail.

goal

% Число отыскиваемых собственных значений

EigenvalsToFind = 3,

load_matrix_from_file("A.TXT", ARows, ACols, A),

load_matrix_from_file("B.TXT", BRows, BCols, B),

check_dimensions(ARows, ACols, BRows, BCols, EigenvalsToFind),

% Поиск обратной матрицы к матрице B (или выясняем, что она вырождена)

inv(ARows,B,InvB),

mult_matrix(ARows, ARows, ARows, InvB, A, M),

% Проверка симметричности матрицы M

is_matrix_symmetric(ARows, ARows, M),

eye_matrix(ARows, EigenvalsToFind, E),

% TE матрица, строки которой - ортонормированные кандидаты в

% собственные векторы матрицы M

transpose_matrix(ARows, EigenvalsToFind, E, TE),

% Поиск набора собственных векторов

find_eigenvectors(ARows, EigenvalsToFind, M, TE, Eigenvectors),

% Результаты преобразования собственных векторов матрицей M

process_candidates(ARows, EigenvalsToFind, M, Eigenvectors, MEigenvectors),

% Вычисление собственных значений

calc_eigenvalues(Eigenvectors, MEigenvectors, Eigenvals),

write( "Found eigenvals: ", Eigenvals), nl.