Программа
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.
