Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
Project: cocalc-sagemath-dev-slelievre
Path: gap4r8 / pkg / NormalizInterface-1.0.2 / Normaliz.git / DST / include / libnormaliz / matrix.h
Views: 418451/*1* Normaliz2* Copyright (C) 2007-2014 Winfried Bruns, Bogdan Ichim, Christof Soeger3* This program is free software: you can redistribute it and/or modify4* it under the terms of the GNU General Public License as published by5* the Free Software Foundation, either version 3 of the License, or6* (at your option) any later version.7*8* This program is distributed in the hope that it will be useful,9* but WITHOUT ANY WARRANTY; without even the implied warranty of10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the11* GNU General Public License for more details.12*13* You should have received a copy of the GNU General Public License14* along with this program. If not, see <http://www.gnu.org/licenses/>.15*16* As an exception, when this program is distributed through (i) the App Store17* by Apple Inc.; (ii) the Mac App Store by Apple Inc.; or (iii) Google Play18* by Google Inc., then that store may impose any digital rights management,19* device limits and/or redistribution restrictions that are required by its20* terms of service.21*/2223//---------------------------------------------------------------------------24#ifndef MATRIX_HPP25#define MATRIX_HPP26//---------------------------------------------------------------------------272829#include <vector>30#include <list>31#include <iostream>32#include <string>3334#include <libnormaliz/libnormaliz.h>35#include <libnormaliz/integer.h>36#include <libnormaliz/convert.h>3738//---------------------------------------------------------------------------3940namespace libnormaliz {41using std::list;42using std::vector;43using std::string;4445template<typename Integer> class Matrix {4647template<typename> friend class Matrix;48template<typename> friend class Lineare_Transformation;49template<typename> friend class Sublattice_Representation;5051// public:5253size_t nr;54size_t nc;55vector< vector<Integer> > elem;5657//---------------------------------------------------------------------------58// Private routines, used in the public routines59//---------------------------------------------------------------------------6061//---------------------------------------------------------------------------62// Row and column reduction63//---------------------------------------------------------------------------64// return value false undicates failure because of overflow65// for all the routines below6667// reduction via integer division and elemntary transformations68bool reduce_row(size_t corner); //reduction by the corner-th row69bool reduce_row (size_t row, size_t col); // corner at position (row,col)7071// replaces two columns by linear combinations of them72bool linear_comb_columns(const size_t& col,const size_t& j,73const Integer& u,const Integer& w,const Integer& v,const Integer& z);7475// column reduction with gcd method76bool gcd_reduce_column (size_t corner, Matrix<Integer>& Right);7778//---------------------------------------------------------------------------79// Work horses80//---------------------------------------------------------------------------8182// takes |product of the diagonal elem|83Integer compute_vol(bool& success);8485// Solve system with coefficients and right hand side in one matrix, using elementary transformations86// solution replaces right hand side87bool solve_destructive_inner(bool ZZinvertible, Integer& denom);8889// asembles the matrix of the system (left side the submatrix of mother given by key90// right side from column vectors pointed to by RS91// both in a single matrix92void solve_system_submatrix_outer(const Matrix<Integer>& mother, const vector<key_t>& key, const vector<vector<Integer>* >& RS,93Integer& denom, bool ZZ_invertible, bool transpose, size_t red_col, size_t sign_col,94bool compute_denom=true, bool make_sol_prime=false);9596size_t row_echelon_inner_elem(bool& success); // does the work and checks for overflows97// size_t row_echelon_inner_bareiss(bool& success, Integer& det);98// NOTE: Bareiss cannot be used if z-invertible transformations are needed99100size_t row_echelon(bool& success); // transforms this into row echelon form and returns rank101size_t row_echelon(bool& success, Integer& det); // computes also |det|102size_t row_echelon(bool& success, bool do_compute_vol, Integer& det); // chooses elem (or bareiss in former time)103104// reduces the rows a matrix in row echelon form upwards, from left to right105bool reduce_rows_upwards();106size_t row_echelon_reduce(bool& success); // combines row_echelon and reduce_rows_upwards107108// computes rank and index simultaneously, returns rank109Integer full_rank_index(bool& success);110111vector<key_t> max_rank_submatrix_lex_inner(bool& success) const;112113// A version of invert that circumvents protection and leaves it to the calling routine114Matrix invert_unprotected(Integer& denom, bool& sucess) const;115116bool SmithNormalForm_inner(size_t& rk, Matrix<Integer>& Right);117118vector<Integer> optimal_subdivision_point_inner() const;119120121//---------------------------------------------------------------------------122// Pivots for rows/columns operations123//---------------------------------------------------------------------------124125vector<long> pivot(size_t corner); //Find the position of an element x with126//0<abs(x)<=abs(y) for all y!=0 in the right-lower submatrix of this127//described by an int corner128129long pivot_column(size_t col); //Find the position of an element x with130//0<abs(x)<=abs(y) for all y!=0 in the lower half of the column of this131//described by an int col132133long pivot_column(size_t row,size_t col); //in column col starting from row134135//---------------------------------------------------------------------------136// Helpers for linear systems137//---------------------------------------------------------------------------138139Matrix bundle_matrices(const Matrix<Integer>& Right_side)const;140Matrix extract_solution() const;141vector<vector<Integer>* > row_pointers();142void customize_solution(size_t dim, Integer& denom, size_t red_col,143size_t sign_col, bool make_sol_prime);144145public:146147size_t row_echelon_inner_bareiss(bool& success, Integer& det);148149vector<vector<Integer>* > submatrix_pointers(const vector<key_t>& key);150151//---------------------------------------------------------------------------152// Rows and columns exchange153//---------------------------------------------------------------------------154155void exchange_rows(const size_t& row1, const size_t& row2); //row1 is exchanged with row2156void exchange_columns(const size_t& col1, const size_t& col2); // col1 is exchanged with col2157158//---------------------------------------------------------------------------159160//---------------------------------------------------------------------------161// Construction and destruction162//---------------------------------------------------------------------------163164Matrix();165Matrix(size_t dim); //constructor of unit matrix166Matrix(size_t row, size_t col); //main constructor, all entries 0167Matrix(size_t row, size_t col, Integer value); //constructor, all entries set to value168Matrix(const vector< vector<Integer> >& elem); //constuctor, elem=elem169Matrix(const list< vector<Integer> >& elems);170171//---------------------------------------------------------------------------172// Data access173//---------------------------------------------------------------------------174175void write_column(size_t col, const vector<Integer>& data); //write a column176void print(const string& name, const string& suffix) const; // writes matrix into name.suffix177void print_append(const string& name,const string& suffix) const; // the same, but appends matrix178void print(std::ostream& out, bool with_format=false) const; // writes matrix to the stream179void pretty_print(std::ostream& out, bool with_row_nr=false) const; // writes matrix in a nice format to the stream // read a row180size_t nr_of_rows() const; // returns nr181size_t nr_of_columns() const; // returns nc182void set_nr_of_columns(size_t c);183/* generates a pseudo random matrix for tests, entries form 0 to mod-1 */184void random(int mod=3);185186void set_zero(); // sets all entries to 0187188/* returns a submatrix with rows corresponding to indices given by189* the entries of rows, Numbering from 0 to n-1 ! */190Matrix submatrix(const vector<key_t>& rows) const;191Matrix submatrix(const vector<int>& rows) const;192Matrix submatrix(const vector<bool>& rows) const;193194void swap (Matrix<Integer>& x);195196// returns the permutation created by sorting the rows with a grading function197// or by 1-norm if computed is false198vector<key_t> perm_sort_by_degree(const vector<key_t>& key, const vector<Integer>& grading, bool computed) const;199vector<key_t> perm_by_weights(const Matrix<Integer>& Weights, vector<bool> absolute);200201void select_submatrix(const Matrix<Integer>& mother, const vector<key_t>& rows);202void select_submatrix_trans(const Matrix<Integer>& mother, const vector<key_t>& rows);203204Matrix& remove_zero_rows(); // remove zero rows, modifies this205206// resizes the matrix to the given number of rows/columns207// if the size shrinks it will keep all its allocated memory208// useful when the size varies209void resize(size_t nr_rows);210void resize(size_t nr_rows, size_t nr_cols);211void resize_columns(size_t nr_cols);212void Shrink_nr_rows(size_t new_nr_rows);213214vector<Integer> diagonal() const; //returns the diagonale of this215//this should be a quadratic matrix216size_t maximal_decimal_length() const; //return the maximal number of decimals217//needed to write an entry218219vector<size_t> maximal_decimal_length_columnwise() const; // the same per column220221void append(const Matrix& M); // appends the rows of M to this222void append(const vector<vector<Integer> >& M); // the same, but for another type of matrix223void append(const vector<Integer>& v); // append the row v to this224void append_column(const vector<Integer>& v); // append the column v to this225void remove_row(const vector<Integer>& row); // removes all appearances of this row, not very efficient!226void remove_row(const size_t index);227vector<size_t> remove_duplicate_and_zero_rows();228void remove_duplicate(const Matrix& M);229230231inline const Integer& get_elem(size_t row, size_t col) const {232return elem[row][col];233}234inline const vector< vector<Integer> >& get_elements() const {235return elem;236}237inline vector<Integer> const& operator[] (size_t row) const {238return elem[row];239}240inline vector<Integer>& operator[] (size_t row) {241return elem[row];242}243void set_nc(size_t col){244nc=col;245}246void set_nr(size_t rows){247nc=rows;248}249250//---------------------------------------------------------------------------251// Basic matrices operations252//---------------------------------------------------------------------------253254Matrix add(const Matrix& A) const; // returns this+A255Matrix multiplication(const Matrix& A) const; // returns this*A256Matrix multiplication(const Matrix& A, long m) const;// returns this*A (mod m)257bool equal(const Matrix& A) const; // returns this==A258bool equal(const Matrix& A, long m) const; // returns this==A (mod m)259Matrix transpose() const; // returns the transpose of this260261bool is_diagonal() const;262263//---------------------------------------------------------------------------264// Scalar operations265//---------------------------------------------------------------------------266267void scalar_multiplication(const Integer& scalar); //this=this*scalar268void scalar_division(const Integer& scalar);269//this=this div scalar, all the elem of this must be divisible with the scalar270void reduction_modulo(const Integer& modulo); //this=this mod scalar271Integer matrix_gcd() const; //returns the gcd of all elem272vector<Integer> make_prime(); //each row of this is reduced by its gcd,273// vector of gcds returned274void make_cols_prime(size_t from_col, size_t to_col);275// the columns of this in the specified range are reduced by their gcd276277Matrix multiply_rows(const vector<Integer>& m) const; //returns matrix were row i is multiplied by m[i]278279//---------------------------------------------------------------------------280// Vector operations281//---------------------------------------------------------------------------282283void MxV(vector<Integer>& result, const vector<Integer>& v) const;//result = this*V284vector<Integer> MxV(const vector<Integer>& v) const;//returns this*V285vector<Integer> VxM(const vector<Integer>& v) const;//returns V*this286vector<Integer> VxM_div(const vector<Integer>& v, const Integer& divisor,bool& success) const; // additionally divides by divisor287288//---------------------------------------------------------------------------289// Matrix operations290// --- these are more complicated algorithms ---291//---------------------------------------------------------------------------292293// Normal forms294295// converts this to row echelon form over ZZ and returns rank, GMP protected, uses only elementary transformations over ZZ296size_t row_echelon();297298// public version of row_echelon_reduce, GMP protected, uses only elementary transformations over ZZ299size_t row_echelon_reduce();300301// transforms matrix into lower triangular form via column transformations302// assumes that rk is the rank and that the matrix is zero after the first rk rows303// Right = Right*(column transformation of this call)304bool column_trigonalize(size_t rk, Matrix<Integer>& Right);305306// combines row_echelon_reduce and column_trigonalize307// returns column transformation matrix308Matrix<Integer> row_column_trigonalize(size_t& rk, bool& success);309310// rank and determinant311312size_t rank() const; //returns rank313Integer full_rank_index() const; // returns index of full rank sublattice314size_t rank_submatrix(const vector<key_t>& key) const; //returns rank of submarix defined by key315316// returns rank of submatrix of mother. "this" is used as work space317size_t rank_submatrix(const Matrix<Integer>& mother, const vector<key_t>& key);318319// vol stands for |det|320Integer vol() const;321Integer vol_submatrix(const vector<key_t>& key) const;322Integer vol_submatrix(const Matrix<Integer>& mother, const vector<key_t>& key);323324// find linearly indepenpendent submatrix of maximal rank325326vector<key_t> max_rank_submatrix_lex() const; //returns a vector with entries327//the indices of the first rows in lexicographic order of this forming328//a submatrix of maximal rank.329330// Solution of linear systems with square matrix331332// In the following routines, denom is the absolute value of the determinant of the333// left side matrix.334// If the diagonal is asked for, ZZ-invertible transformations are used.335// Otherwise ther is no restriction on the used algorithm336337//The diagonal of left hand side after transformation into an upper triangular matrix338//is saved in diagonal, denom is |determinant|.339340// System with "this" as left side341Matrix solve(const Matrix& Right_side, Integer& denom) const;342Matrix solve(const Matrix& Right_side, vector< Integer >& diagonal, Integer& denom) const;343// solve the system this*Solution=denom*Right_side.344345// system is defined by submatrix of mother given by key (left side) and column vectors pointed to by RS (right side)346// NOTE: this is used as the matrix for the work347void solve_system_submatrix(const Matrix& mother, const vector<key_t>& key, const vector<vector<Integer>* >& RS,348vector< Integer >& diagonal, Integer& denom, size_t red_col, size_t sign_col);349void solve_system_submatrix(const Matrix& mother, const vector<key_t>& key, const vector<vector<Integer>* >& RS,350Integer& denom, size_t red_col, size_t sign_col, bool compute_denom=true, bool make_sol_prime=false);351// the left side gets transposed352void solve_system_submatrix_trans(const Matrix& mother, const vector<key_t>& key, const vector<vector<Integer>* >& RS,353Integer& denom, size_t red_col, size_t sign_col);354355356// For non-square matrices357358// The next two solve routines do not require the matrix to be square.359// However, we want rank = number of columns, ensuring unique solvability360361vector<Integer> solve_rectangular(const vector<Integer>& v, Integer& denom) const;362// computes solution vector for right side v, solution over the rationals363// matrix needs not be quadratic, but must have rank = number of columns364// with denominator denom.365// gcd of denom and solution is extracted !!!!!366367vector<Integer> solve_ZZ(const vector<Integer>& v) const;368// computes solution vector for right side v369// insists on integrality of the solution370371// homogenous linear systems372373Matrix<Integer> kernel () const;374// computes a ZZ-basis of the solutions of (*this)x=0375// the basis is formed by the ROWS of the returned matrix376377// inverse matrix378379//this*Solution=denom*I. "this" should be a quadratic matrix with nonzero determinant.380Matrix invert(Integer& denom) const;381382void invert_submatrix(const vector<key_t>& key, Integer& denom, Matrix<Integer>& Inv,383bool compute_denom=true, bool make_sol_prime=false) const;384385// find linear form that is constant on the rows386387vector<Integer> find_linear_form () const;388// Tries to find a linear form which gives the same value an all rows of this389// this should be a m x n matrix (m>=n) of maxinal rank390// returns an empty vector if there does not exist such a linear form391392vector<Integer> find_linear_form_low_dim () const;393//same as find_linear_form but also works with not maximal rank394//uses a linear transformation to get a full rank matrix395396// normal forms397398Matrix AlmostHermite(size_t& rk);399// Converts "this" into lower trigonal column Hermite normal form, returns column400// transformation matrix401// Almost: elements left of diagonal are not reduced mod diagonal402403// Computes Smith normal form and returns column transformation matrix404Matrix SmithNormalForm(size_t& rk);405406//for simplicial subcones407408// computes support hyperplanes and volume409void simplex_data(const vector<key_t>& key, Matrix<Integer>& Supp, Integer& vol, bool compute_vol) const;410// finds subdivision points411vector<Integer> optimal_subdivision_point() const;412413// Sorting of rows414415Matrix& sort_by_weights(const Matrix<Integer>& Weights, vector<bool> absolute);416Matrix& sort_lex();417void order_rows_by_perm(const vector<key_t>& perm);418419// solve homogeneous congruences420421Matrix<Integer> solve_congruences(bool& zero_modulus) const;422423// saturate sublattice424425void saturate();426427// find the indices of the rows in which the linear form L takes its max and min values428429vector<key_t> max_and_min(const vector<Integer>& L, const vector<Integer>& norm) const;430431// try to sort the rows in such a way that the extreme points of the polytope spanned by the rows come first432433size_t extreme_points_first(const vector<Integer> norm=vector<Integer>(0));434435// find an inner point in the cone spanned by the rows of the matrix436437vector<Integer> find_inner_point();438};439//class end *****************************************************************440441//---------------------------------------------------------------------------442// Utilities443//---------------------------------------------------------------------------444445template<typename Integer> class order_helper {446447public:448449vector<Integer> weight;450key_t index;451vector<Integer>* v;452};453454template<typename T>455vector<vector<T> > to_matrix(const vector<T>& v){456457vector<vector<T> > mat(1);458mat[0]=v;459return mat;460}461462template<typename Integer>463Matrix<Integer> readMatrix(const string project);464465//---------------------------------------------------------------------------466// Conversion between integer types467//---------------------------------------------------------------------------468469template<typename ToType, typename FromType>470void convert(Matrix<ToType>& to_mat, const Matrix<FromType>& from_mat);471472template<typename Integer>473void mat_to_mpz(const Matrix<Integer>& mat, Matrix<mpz_class>& mpz_mat);474475template<typename Integer>476void mat_to_Int(const Matrix<mpz_class>& mpz_mat, Matrix<Integer>& mat);477478template<typename Integer>479void mpz_submatrix(Matrix<mpz_class>& sub, const Matrix<Integer>& mother, const vector<key_t>& selection);480481template<typename Integer>482void mpz_submatrix_trans(Matrix<mpz_class>& sub, const Matrix<Integer>& mother, const vector<key_t>& selection);483484} // namespace485486//---------------------------------------------------------------------------487#endif488//---------------------------------------------------------------------------489490491