#
# = Matrices
# Contents:
# 1. {Class methods}[link:matrix_rdoc.html#label-Class+methods]
# 1. {Instance methods}[link:matrix_rdoc.html#label-Instance+Methods]
#    1. {Accessing matrix elements}[link:matrix_rdoc.html#label-Accessing+matrix+elements]
#    1. {Initializing matrix elements}[link:matrix_rdoc.html#label-Initializing+matrix+elements]
#    1. {IO}[link:matrix_rdoc.html#label-IO]
#    1. {Matrix views}[link:matrix_rdoc.html#label-Matrix+views]
#    1. {Creating row and column views}[link:matrix_rdoc.html#label-Creating+row+and+column+views]
#    1. {Iterators}[link:matrix_rdoc.html#label-Iterators]
#    1. {Copying matrices}[link:matrix_rdoc.html#label-Copying+matrices]
#    1. {Copying rows and columns}[link:matrix_rdoc.html#label-Copying+rows+and+columns]
#    1. {Exchanging rows and columns}[link:matrix_rdoc.html#label-Exchanging+rows+and+columns]
#    1. {Matrix operations}[link:matrix_rdoc.html#label-Matrix+operations]
#    1. {Finding maximum and minimum elements of matrices}[link:matrix_rdoc.html#label-Finding+maximum+and+minimum+elements+of+matrices]
#    1. {Matrix properties}[link:matrix_rdoc.html#label-Matrix+properties]
# 1. {NArray}[link:matrix_rdoc.html#label-NArray]
# 1. {Special matrices}[link:matrix_rdoc.html#label-Special+matrices]
#
# == Class methods
#
# ---
# * GSL::Matrix.alloc(n)
# * GSL::Matrix.alloc(size1, size2)
# * GSL::Matrix.alloc(array)
# * GSL::Matrix.alloc(arrays)
# * GSL::Matrix.alloc( ... )
# * GSL::Matrix[ ... ]
#
#   These methods create a <tt>GSL::Matrix</tt> object.
#
# 1. From arrays
#        >> m = GSL::Matrix[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
#        => GSL::Matrix
#        [ 1.000e+00 2.000e+00 3.000e+00
#          4.000e+00 5.000e+00 6.000e+00
#          7.000e+00 8.000e+00 9.000e+00 ]
#
# 1. With an array and rows&cols,
#           m = GSL::Matrix.alloc([1, 2, 3, 4, 5, 6, 7, 8, 9], 3, 3)
#
# 1. With Range objects,
#           >> m = GSL::Matrix.alloc(1..3, 4..6, 7..9)
#           [ 1.000e+00 2.000e+00 3.000e+00
#             4.000e+00 5.000e+00 6.000e+00
#             7.000e+00 8.000e+00 9.000e+00 ]
#           >> m2 = GSL::Matrix[1..6, 2, 3]
#           [ 1.000e+00 2.000e+00 3.000e+00
#             4.000e+00 5.000e+00 6.000e+00 ]
#
# ---
# * GSL::Matrix.eye(n)
# * GSL::Matrix.eye(n1, n2)
#
#   Examples:
#     >> m = GSL::Matrix::Int.eye(3)
#     => GSL::Matrix::Int
#     [ 1 0 0
#       0 1 0
#       0 0 1 ]
#     >> m = GSL::Matrix::Int.eye(2, 4)
#     => GSL::Matrix::Int
#     [ 1 0 0 0
#       0 1 0 0 ]
#
# ---
# * GSL::Matrix.identity(n)
# * GSL::Matrix.scalar(n)
# * GSL::Matrix.unit(n)
# * GSL::Matrix.I(n)
#
#   Create diagonal matrices of dimensions n*n, of values 1.0.
#
# ---
# * GSL::Matrix.diagonal(a, b, c, ...)
# * GSL::Matrix.diagonal(Ary)
# * GSL::Matrix.diagonal(Range)
# * GSL::Matrix.diagonal(Vector)
#
#   Creates a diagonal matrix of given elements.
#
#   Example:
#     >> GSL::Matrix::Int.diagonal(1..4)
#     => GSL::Matrix::Int
#     [ 1 0 0 0
#       0 2 0 0
#       0 0 3 0
#       0 0 0 4 ]
#     >> GSL::Matrix::Int.diagonal(2, 5, 3)
#     => GSL::Matrix::Int
#     [ 2 0 0
#       0 5 0
#       0 0 3 ]
#
# ---
# * GSL::Matrix.ones(n)
# * GSL::Matrix.ones(n1, n2)
#
#   Create a matrix of all the elements 1.
#
# ---
# * GSL::Matrix.zeros(n)
# * GSL::Matrix.zeros(n1, n2)
#
#   Create a matrix of all the elements 1.
#
# ---
# * GSL::Matrix.indgen(n1, n2, start=0, step=1)
#
#   Example:
#
#     >> m = GSL::Matrix::Int.indgen(3, 5)
#     => GSL::Matrix::Int
#     [  0  1  2  3  4
#        5  6  7  8  9
#       10 11 12 13 14 ]
#     >> m = GSL::Matrix::Int.indgen(3, 5, 2)
#     => GSL::Matrix::Int
#     [  2  3  4  5  6
#        7  8  9 10 11
#       12 13 14 15 16 ]
#     >> m = GSL::Matrix.indgen(2, 3, 4.5, 6.7)
#     => GSL::Matrix
#     [  4.500e+00  1.120e+01  1.790e+01
#        2.460e+01  3.130e+01  3.800e+01 ]
#
# === NOTE:
# Matrix dimensions are limited within the range of Fixnum.
# For 32-bit CPU, the maximum of matrix dimension is 2^30 ~ 1e9.
#
# == Instance Methods
# === Accessing matrix elements
#
# ---
# * GSL::Matrix#size1
#
#   Returns the number of rows of matrix <tt>self</tt>.
# ---
# * GSL::Matrix#size2
#
#   Returns the number of columns of matrix <tt>self</tt>.
# ---
# * GSL::Matrix#shape
#
#   Returns the number of rows and columns as an array.
#
#   Ex:
#
#      >> m.size1
#      => 3
#      >> m.size2
#      => 5
#      >> m.shape
#      => [3, 5]
#
# ---
# * GSL::Matrix#set(args, val)
# * \GSL::Matrix#[args]=val
#
#   If <tt>args</tt> is empty and <tt>val</tt> is an Array (i.e. called with just a
#   single Array argument), the Array's elements are taken as row contents.
#   Each given row must have exactly the same number of elements as the Matrix
#   has columns, but the number of rows given need not match the Matrix's row
#   count.  Extra given rows are ignored, while Matrix rows beyond those given
#   are not affected.  Otherwise, if <tt>args</tt> is empty, behaves as
#   <tt>#set_all(<tt>val</tt>)</tt>.
#
#   If <tt>args</tt> is an Array and val is not, the first two elements of
#   <tt>args</tt> must be Fixnums which specify the row and column of the element
#   that will be set to the value of <tt>val</tt>.  This special case exists to
#   allow values returned by Matrix#max_index and Matrix#min_index to be used
#   as indexes.
#
#   If <tt>args</tt> are two <tt>Fixnums</tt>, <tt>i</tt> and <tt>j</tt>, this method
#   sets the <tt>(i,j)</tt>-th element of the matrix <tt>self</tt> to <tt>val</tt>.
#
#   If <tt>args</tt> is a single <tt>Fixnum</tt>, <tt>i</tt>, this method sets the
#   element at row <tt>i</tt>/<tt>size2</tt>, column <tt>i</tt>%<tt>size2</tt> to
#   <tt>val</tt>.
#
#   For <tt>#set</tt>, if <tt>args</tt> is empty and <tt>val</tt> is an <tt>Array</tt> of
#   <tt>Arrays</tt>, the contents of <tt>self</tt> are set row by row from the
#   elements (i.e. <tt>Arrays</tt>) of <tt>val</tt>.
#
#   All other <tt>args</tt> specify a submatrix (as with <tt>#submatrix</tt>) whose
#   elements are assigned from <tt>val</tt>.  In this case, <tt>val</tt> can be an
#   <tt>Array</tt> whose elements will be assigned to the rows of the submatrix,
#   <tt>Range</tt> whose elements will be assigned to the elements of the
#   submatrix, <tt>GSL::Matrix</tt> whose elements will be assigned to the
#   elements of the submatrix, or <tt>Numeric</tt> that will be assigned to all
#   elements of the submatrix.
#
#   NOTE: GSL does not provide a matrix copy function that properly copies data
#   across overlapping memory regions, so watch out if assigning to part of a
#   Matrix from another part of itself (see <tt>#set</tt> example of
#   {GSL::Vector}[link:vector_rdoc.html]).
#
# ---
# * GSL::Matrix#get(args)
# * \GSL::Matrix#[args]
#
#   If <tt>args</tt> are two <tt>Fixnums</tt>, <tt>i</tt> and <tt>j</tt>, this method
#   returns the <tt>(i,j)</tt>-th element of the matrix <tt>self</tt>.
#
#   If <tt>args</tt> is a single <tt>Fixnum</tt>, <tt>i</tt>, this method returns the
#   element at row <tt>i</tt>/<tt>size2</tt>, column <tt>i</tt>%<tt>size2</tt>.
#
#   All other forms of <tt>args</tt> are treated as with <tt>Matrix#submatrix</tt>
#   and a View object is returned.
#
#   NOTE: The behavior of the single <tt>Fixnum</tt> argument case is different
#   from earlier versions (< 1.11.2) of Ruby/GSL.  These earlier versions
#   returned a <tt>Vector::View</tt> in this case, thereby allowing element
#   (<tt>i</tt>,<tt>j</tt>) to be accessed as <tt>m[<tt>i</tt>][<tt>j</tt>]</tt>.  THIS FORM
#   IS NO LONGER SUPPORTED as of Ruby/GSL 1.11.2.  Existing occurences of this
#   construct will need to be replaced with the backwards compatible and more
#   efficient <tt>m[<tt>i</tt>,<tt>j</tt>]</tt> or, equivalent to the old and less
#   efficient form, <tt>m[<tt>i</tt>,nil][<tt>j</tt>]</tt>.  For GSL::Matrix, the old
#   form will now raise a <tt>NoMethodError</tt> because <tt>Float</tt> has no
#   <tt>#[]</tt> method.  For GSL::Matrix::Int, however, the old form will return
#   a single bit from an element of the matrix because <tt>Fixnum</tt> and
#   <tt>Bignum</tt> have a <tt>#[]</tt> method that allows access to the number's
#   individual bits.
#
#   Examples:
#     >> m = GSL::Matrix[1..9, 3, 3]
#     => GSL::Matrix
#     [ 1.000e+00 2.000e+00 3.000e+00
#       4.000e+00 5.000e+00 6.000e+00
#       7.000e+00 8.000e+00 9.000e+00 ]
#     >> m[1, 2]
#     => 6.0
#     >> m[1, 2] = 123     # m.set(1, 2, 123)
#     => 123
#     >> m
#     => GSL::Matrix
#     [ 1.000e+00 2.000e+00 3.000e+00
#       4.000e+00 5.000e+00 1.230e+02
#       7.000e+00 8.000e+00 9.000e+00 ]
#     >> m[1]
#     => 2.0
#     >> m.set([3, 5, 2], [4, 5, 3], [7, 1, 5])
#     => GSL::Matrix
#     [ 3.000e+00 5.000e+00 2.000e+00
#       4.000e+00 5.000e+00 3.000e+00
#       7.000e+00 1.000e+00 5.000e+00 ]
#     >> m[1][1]   # old/unsupported form
#     NoMethodError: undefined method `[]' for 2.0:Float
#             from (irb):8
#     >> m = GSL::Matrix::Int[1..9, 3, 3]
#     => GSL::Matrix::Int
#     [ 1 2 3
#       4 5 6
#       7 8 9 ]
#     >> m[1]      # m[0,1]
#     => 2
#     >> m[1][0]   # Bit 0 of m[0,1]
#     => 0
#     >> m[1][1]   # Bit 1 of m[0,1]
#     => 1
#     >> m[1][2]   # Bit 2 of m[0,1]
#     => 0
#     >> m[1][3]   # Bit 3 of m[0,1]
#     => 0
#
#
# ---
# * GSL::Matrix#to_a
#
#   Converts the <tt>Matrix</tt> <tt>self</tt> to a Ruby <tt>Array</tt> of <tt>Arrays</tt>.
#
#   Example:
#     >> GSL::Matrix.eye(3).to_a
#     => [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]
#
# === Initializing matrix elements
# ---
# * GSL::Matrix#set_all(x)
#
#   This method sets all the elements of the matrix <tt>self</tt> to the value x.
#
# ---
# * GSL::Matrix#set_zero
#
#   This method sets all the elements of the matrix to zero.
#
# ---
# * GSL::Matrix#set_identity
#
#   This method sets the elements of the matrix to the corresponding
#   elements of the identity matrix, i.e. a unit diagonal with all off-diagonal
#   elements zero. This applies to both square and rectangular matrices.
#
# === IO
# ---
# * GSL::Matrix#fwrite(io)
# * GSL::Matrix#fwrite(filename)
# * GSL::Matrix#fread(io)
# * GSL::Matrix#fread(filename)
# * GSL::Matrix#fprintf(io, format = "%e")
# * GSL::Matrix#fprintf(filename, format = "%e")
# * GSL::Matrix#fscanf(io)
# * GSL::Matrix#fscanf(filename)
#
#
# === Matrix views
# The <tt>GSL::Matrix::View</tt> class is defined to be used as "references" to
# matrices. The <tt>Matrix::View</tt> class is a subclass of <tt>Matrix</tt>, and an
# instance of the <tt>View</tt> class created by slicing a <tt>Matrix</tt> object can
# be used same as the original matrix. The <tt>View</tt> object shares the data with
# the original matrix, i.e. any changes in the elements of the <tt>View</tt> object
# affect to the original.
#
# The primary means of generating <tt>Matrix::View</tt> objects is with
# <tt>GSL::Matrix#submatrix</tt> (or its alias <tt>GSL::Matrix#view</tt>).  Many forms
# are supported and they are documented here individually.  All forms return a
# <tt>Matrix::View</tt> unless otherwise documented.  In the list below, the
# parameter name indicates the type of the parameter: <tt>i</tt>, <tt>row</tt>,
# <tt>col</tt>, <tt>len</tt>, <tt>len1</tt>, and <tt>len2</tt> are <tt>Fixnums</tt>; <tt>rows</tt> and
# <tt>cols</tt> are <tt>Ranges</tt>.
#
# ---
# * GSL::Matrix#submatrix()
#
#   View covers all rows and all columns.
# ---
# * GSL::Matrix#submatrix(i)
#
#   View covers single element at row <tt>i</tt>/<tt>size2</tt>, column
#   <tt>i</tt>%<tt>size2</tt>.
# ---
# * GSL::Matrix#submatrix(nil,nil)
#
#   View covers all rows and all columns.
# ---
# * GSL::Matrix#submatrix(nil,cols)
#
#   View covers all rows with columns specified by <tt>cols</tt>.
# ---
# * GSL::Matrix#submatrix(nil,col)
#
#   Returns a <tt>Vector::Col::View</tt> for the column <tt>col</tt>.
# ---
# * GSL::Matrix#submatrix(rows, nil)
#
#   View covers rows specified by <tt>rows</tt> and all columns.
# ---
# * GSL::Matrix#submatrix(rows, cols)
#
#   View covers rows specified by <tt>rows</tt>, columns specified by <tt>cols</tt>.
# ---
# * GSL::Matrix#submatrix(rows, col)
#
#   Returns a <tt>Vector::Col::View</tt> for column <tt>col</tt>, rows <tt>rows</tt>.
# ---
# * GSL::Matrix#submatrix(row, nil)
#
#   Returns a <tt>Vector::View</tt> for row <tt>row</tt>.
# ---
# * GSL::Matrix#submatrix(row, cols)
#
#   Returns a <tt>Vector::View</tt> for row <tt>row</tt>, columns <tt>cols</tt>.
# ---
# * GSL::Matrix#submatrix(row, col)
#
#   View covers a single element at row <tt>row</tt>, column <tt>col</tt>.
# ---
# * GSL::Matrix#submatrix(nil, col, len)
#
#   View covers all rows and <tt>len</tt> columns starting at column <tt>col</tt>.
# ---
# * GSL::Matrix#submatrix(rows, col, len)
#
#   View covers <tt>rows</tt> rows and <tt>len</tt> columns starting at column <tt>col</tt>.
# ---
# * GSL::Matrix#submatrix(row, len, nil)
#
#   View covers <tt>len</tt> rows starting at row <tt>row</tt> and all columns.
# ---
# * GSL::Matrix#submatrix(row, len, cols)
#
#   View covers <tt>len</tt> rows starting at row <tt>row</tt> and <tt>cols</tt> columns.
# ---
# * GSL::Matrix#submatrix(row, col, len1, len2)
#
#   View covers <tt>len1</tt> rows starting at row <tt>row</tt> and <tt>len2</tt>
#   columns starting at column <tt>col</tt>.
#
# ---
# * GSL::Vector#matrix_view(n1, n2)
#
#   This creates a <tt>Matrix::View</tt> object from the vector <tt>self</tt>.
#
#   Ex:
#      >> v = Vector[1..9]
#      => GSL::Vector
#      [ 1.000e+00 2.000e+00 3.000e+00 4.000e+00 5.000e+00 6.000e+00 7.000e+00 8.000e+00 9.000e+00 ]
#      >> m = v.matrix_view(3, 3)
#      => GSL::Matrix::View
#      [ 1.000e+00 2.000e+00 3.000e+00
#        4.000e+00 5.000e+00 6.000e+00
#        7.000e+00 8.000e+00 9.000e+00 ]
#      >> m[1][1] = 99.99
#      => 99.99
#      >> v
#      => GSL::Vector
#      [ 1.000e+00 2.000e+00 3.000e+00 4.000e+00 9.999e+01 6.000e+00 7.000e+00 8.000e+00 9.000e+00 ]
#      >>
#
#
# === Creating row and column views
#
# ---
# * GSL::Matrix#row(i)
#
#   These methods return <tt>i</tt>-th row of the matrix as a <tt>Vector::View</tt>
#   object. Any modifications to the <tt>Vectror::View</tt> object returned by this method
#   propagate to the original matrix.
#
# ---
# * GSL::Matrix#column(i)
# * GSL::Matrix#col(i)
#
#   These methods return a vector view of the <tt>j</tt>-th column of the matrix.
#
# ---
# * GSL::Matrix#subrow(i, offset, n)
#
#   Returns a vector view of the <tt>i</tt>-th row of the matrix <tt>self</tt>
#   beginning at <tt>offset</tt> elements past the first column
#   and containing <tt>n</tt> elements. (>= GSL-1.10)
#
# ---
# * GSL::Matrix#subcolumn(j, offset, n)
#
#   Returns a vector view of the <tt>j</tt>-th column of the matrix <tt>self</tt>
#   beginning at <tt>offset</tt> elements past the first row
#   and containing <tt>n</tt> elements. (>= GSL-1.10)
#
# ---
# * GSL::Matrix#diag
# * GSL::Matrix#diagonal
#
#   This method returns a <tt>Vector::View</tt> of the diagonal of the matrix.
#   The matrix is not required to be square. For a rectangular matrix the
#   length of the diagonal is the same as the smaller dimension of the matrix.
#
#
#   Ex:
#     >> m = GSL::Matrix[1..9, 3, 3]
#     => GSL::Matrix
#     [ 1.000e+00 2.000e+00 3.000e+00
#       4.000e+00 5.000e+00 6.000e+00
#       7.000e+00 8.000e+00 9.000e+00 ]
#     >> m.row(1)
#     => GSL::Vector::View
#     [ 4.000e+00 5.000e+00 6.000e+00 ]
#     >> m.col(2)
#     => GSL::Vector::Col::View
#     [ 3.000e+00
#       6.000e+00
#       9.000e+00 ]
#     >> m.col(2)[2] = 123
#     => 123
#     >> m
#     => GSL::Matrix
#     [ 1.000e+00 2.000e+00 3.000e+00
#       4.000e+00 5.000e+00 6.000e+00
#       7.000e+00 8.000e+00 1.230e+02 ]
#     >> m.diagonal
#     => GSL::Vector::View:
#     [ 1.000e+00 5.000e+00 1.230e+02 ]
#
# ---
# * GSL::Matrix#subdiagonal(k)
#
#   Returns a vector view view of the <tt>k</tt>-th subdiagonal
#   of the matrix <tt>self</tt>.
#   The matrix is not required to be square. The diagonal of the matrix
#   corresponds to k = 0.
#
# ---
# * GSL::Matrix#superdiagonal(k)
#
#   Returns a vector view of the <tt>k</tt>-th superdiagonal of the matrix <tt>self</tt>.
#   The matrix is not required to be square. The diagonal of the matrix
#   corresponds to k = 0.
#
# ---
# * GSL::Matrix#to_v
#
#   Creates a <tt>GSL::Vector</tt> object "flattening" the rows of the matrix <tt>self</tt>.
#
#       >> m = GSL::Matrix[1..6, 2, 3]
#       => GSL::Matrix
#       [ 1.000e+00 2.000e+00 3.000e+00
#         4.000e+00 5.000e+00 6.000e+00 ]
#       >> m.to_v
#       => GSL::Vector
#       [ 1.000e+00 2.000e+00 3.000e+00 4.000e+00 5.000e+00 6.000e+00 ]
#
# === Iterators
# ---
# * GSL::Matrix#each_row
#
#   Iterator for each of rows in the matrix <tt>self</tt>.
# ---
# * GSL::Matrix#each_col
#
#   Iterator for each of columns in the matrix <tt>self</tt>.
#
# ---
# * GSL::Matrix#collect { |item| .. }
# * GSL::Matrix#map { |item| .. }
# * GSL::Matrix#collect! { |item| .. }
# * GSL::Matrix#map! { |item| .. }
#
#
# === Copying matrices
# ---
# * GSL::Matrix#clone
# * GSL::Matrix#duplicate
#
#   Create a new matrix of the same elements.
#
# ---
# * GSL::Matrix.memcpy(dest, src)
# * GSL::Matrix.swap(dest, src)
#
#
# === Copying rows and columns
#
# ---
# * GSL::Matrix#get_row(i)
#
#   This method returns a new vector (not a view) which contains the elements
#   of the <tt>i</tt>-th row of the matrix <tt>self</tt>.
#
# ---
# * GSL::Matrix#get_col(j)
#
#   This method returns a new vector (not a view) which contains the elements of the <tt>j</tt>-th
#   column of the matrix <tt>self</tt>.
#
# ---
# * GSL::Matrix#set_row(i, v)
#
#   This method copies the elements of the vector <tt>v</tt> into the <tt>i</tt>-th
#   row of the matrix.
#   The length of the vector must be the same as the length of the row.
#
# ---
# * GSL::Matrix#set_col(j, v)
#
#   This method copies the elements of the vector <tt>v</tt> into the <tt>j</tt>-th
#   column of the matrix. The length of the vector must be the same as the length
#   of the column.
#
# === Exchanging rows and columns
# ---
# * GSL::Matrix#swap_rows!(i, j)
#
#   This method exchanges the <tt>i</tt>-th and <tt>j</tt>-th rows of the matrix <tt>in-place</tt>.
# ---
# * GSL::Matrix#swap_rows(i, j)
#
#   This method creates a new matrix exchanging the <tt>i</tt>-th and <tt>j</tt>-th rows of the matrix <tt>self</tt>.
#
# ---
# * GSL::Matrix#swap_columns!(i, j)
#
#   This method exchanges the <tt>i</tt>-th and <tt>j</tt>-th columns of the matrix <tt>in-place</tt>.
# ---
# * GSL::Matrix#swap_columns(i, j)
#
#   This method creates a new matrix exchanging the <tt>i</tt>-th and <tt>j</tt>-th columns of the matrix <tt>self</tt>.
#
# ---
# * GSL::Matrix#swap_rowcol(i, j)
#
#   This method exchanges the <tt>i</tt>-th row and <tt>j</tt>-th column of the matrix.
#   The matrix must be square for this operation to be possible.
#
# ---
# * GSL::Matrix#transpose_memcpy
# * GSL::Matrix#transpose
#
#   This method returns a matrix of a transpose of the matrix. The matrix
#   <tt>self</tt> is not modified.
#
# ---
# * GSL::Matrix#transpose!
#
#   This method replaces the matrix by its transpose by copying the
#   elements of the matrix <tt>in-place</tt>. The matrix must be square for this
#   operation to be possible.
#
# ---
# * GSL::Matrix#reverse_rows
# * GSL::Matrix#flipud
#
#   Example:
#       >> m = GSL::Matrix::Int[1..9, 3, 3]
#       => GSL::Matrix::Int
#       [ 1 2 3
#         4 5 6
#         7 8 9 ]
#       >> m.reverse_rows
#       => GSL::Matrix::Int
#       [ 7 8 9
#         4 5 6
#         1 2 3 ]
#
# ---
# * GSL::Matrix#reverse_columns
# * GSL::Matrix#fliplr
#
#   Example:
#       >> m = GSL::Matrix::Int[1..9, 3, 3]
#       => GSL::Matrix::Int
#       [ 1 2 3
#         4 5 6
#         7 8 9 ]
#       >> m.reverse_rows.reverse_columns
#       => GSL::Matrix::Int
#       [ 9 8 7
#         6 5 4
#         3 2 1 ]
#
# ---
# * GSL::Matrix#rot90(n = 1)
#
#   Return a copy of <tt>self</tt> with the elements rotated
#   counterclockwise in 90-degree increments. The argument <tt>n</tt> is
#   optional, and specifies how many 90-degree rotations are to be applied
#   (the default value is 1).
#   Negative values of <tt>n</tt> rotate the matrix in a clockwise direction.
#
#   Examples:
#     >> m = GSL::Matrix::Int[1..6, 2, 3]
#     => GSL::Matrix::Int
#     [ 1 2 3
#       4 5 6 ]
#     >> m.rot90
#     => GSL::Matrix::Int
#     [ 3 6
#       2 5
#       1 4 ]
#     >> m.rot90(2)
#     => GSL::Matrix::Int
#     [ 6 5 4
#       3 2 1 ]
#     >> m.rot90(3)
#     => GSL::Matrix::Int
#     [ 4 1
#       5 2
#       6 3 ]
#     >> m.rot90(-1)
#     => GSL::Matrix::Int
#     [ 4 1
#       5 2
#       6 3 ]
#
# ---
# * GSL::Matrix#upper
#
#   This creates a matrix copying the upper half part of the matrix
#   <tt>self</tt>, including the diagonal elements.
# ---
# * GSL::Matrix#lower
#
#   This creates a matrix copying the lower half part of the matrix
#   <tt>self</tt>, including the diagonal elements.
#
#        >> m = GSL::Matrix[1..9, 3, 3]
#        => GSL::Matrix
#        [ 1.000e+00 2.000e+00 3.000e+00
#          4.000e+00 5.000e+00 6.000e+00
#          7.000e+00 8.000e+00 9.000e+00 ]
#        >> m.upper
#        => GSL::Matrix
#        [ 1.000e+00 2.000e+00 3.000e+00
#          0.000e+00 5.000e+00 6.000e+00
#          0.000e+00 0.000e+00 9.000e+00 ]
#        >> m.lower
#        => GSL::Matrix
#        [ 1.000e+00 0.000e+00 0.000e+00
#          4.000e+00 5.000e+00 0.000e+00
#          7.000e+00 8.000e+00 9.000e+00 ]
#
# ---
# * GSL::Matrix#horzcat(other)
#
#   Returns the horizontal concatenation of <tt>self</tt> and <tt>other</tt>.
#
#   Ex:
#     >> require("gsl")
#     => true
#     >> a = GSL::Matrix::Int[1..4, 2, 2]
#     => GSL::Matrix::Int
#     [ 1 2
#       3 4 ]
#     >> b = GSL::Matrix::Int[5..10, 2, 3]
#     => GSL::Matrix::Int
#     [  5  6  7
#        8  9 10 ]
#     >> a.horzcat(b)
#     => GSL::Matrix::Int
#     [  1  2  5  6  7
#        3  4  8  9 10 ]
#
# ---
# * GSL::Matrix#vertcat(other)
#
#   Returns the vertical concatenation of <tt>self</tt> and <tt>other</tt>.
#
#   Ex:
#     >> a = GSL::Matrix::Int[1..4, 2, 2]
#     => GSL::Matrix::Int
#     [ 1 2
#       3 4 ]
#     >> b = GSL::Matrix::Int[5..10, 3, 2]
#     => GSL::Matrix::Int
#     [  5  6
#        7  8
#        9 10 ]
#     >> a.vertcat(b)
#     => GSL::Matrix::Int
#     [  1  2
#        3  4
#        5  6
#        7  8
#        9 10 ]
#
# === Matrix operations
#
# ---
# * GSL::Matrix#add(b)
# * GSL::Matrix#+(b)
#
#   This method adds the elements of matrix <tt>b</tt>
#   to the elements of the  matrix.
#   The two matrices must have the same dimensions.
#
#   If <tt>b</tt> is a scalar, these methods add it to all the elements
#   of the matrix <tt>self</tt> (equivalent to the method <tt>add_constant</tt>).
#
# ---
# * GSL::Matrix#sub(b)
# * GSL::Matrix#-(b)
#
#   This method subtracts the elements of matrix <tt>b</tt>
#   from the elements of the
#   matrix. The two matrices must have the same dimensions.
#
# ---
# * GSL::Matrix#mul_elements(b)
#
#   This method multiplies the elements of the matrix by the elements of
#   matrix <tt>b</tt>. The two matrices must have the same dimensions.
#   If <tt>b</tt> is a scalar, the method <tt>scale</tt> (see below)
#   is called.
#
# ---
# * GSL::Matrix#div_elements(b)
#
#
#   This method divides the elements of the  matrix by the elements of
#   matrix <tt>b</tt>. The two matrices must have the same dimensions.
#
# ---
# * GSL::Matrix#scale(x)
#
#   This method multiplies the elements of the  matrix by the constant
#   factor <tt>x</tt>.
#
# ---
# * GSL::Matrix#add_constant(x)
#
#   This method adds the constant value <tt>x</tt> to the elements of the matrix.
#
# ---
# * GSL::Matrix#*(b)
#
#   Matrix multiplication.
#
#   Ex:
#
#      >> a = GSL::Matrix[1..4, 2, 2]
#      => GSL::Matrix
#      [ 1.000e+00 2.000e+00
#        3.000e+00 4.000e+00 ]
#      >> b = GSL::Matrix[5..8, 2, 2]
#      => GSL::Matrix
#      [ 5.000e+00 6.000e+00
#        7.000e+00 8.000e+00 ]
#      >> a*b
#      => GSL::Matrix
#      [ 1.900e+01 2.200e+01
#        4.300e+01 5.000e+01 ]
#      >> a*2
#      => GSL::Matrix
#      [ 2.000e+00 4.000e+00
#        6.000e+00 8.000e+00 ]
#      >> c = Vector[1, 2]
#      => GSL::Vector
#      [ 1.000e+00 2.000e+00 ]
#      >> a*c.col
#      => GSL::Vector::Col
#      [ 5.000e+00
#        1.100e+01 ]
#
# ---
# * GSL::Matrix#/(b)
#
#   If <tt>b</tt> is a scalar or a <tt>Matrix</tt>, this method calculates the
#   element-by-element divisions.
#   If a <tt>Vector::Col</tt> is given, this method solves the linear system
#   by using LU decomposition.
#
#   Ex:
#       >> m = GSL::Matrix[1..4, 2, 2]
#       => GSL::Matrix
#       [ 1.000e+00 2.000e+00
#         3.000e+00 4.000e+00 ]
#       >> m/3
#       => GSL::Matrix
#       [ 3.333e-01 6.667e-01         <--- 1/3, 2/3
#         1.000e+00 1.333e+00 ]       <--- 3/3, 4/3
#       >> b = Vector[5, 6].col
#       => GSL::Vector::Col
#       [ 5.000e+00
#         6.000e+00 ]
#       >> x = m/b          <--- Solve m (x,y) = b
#       => GSL::Vector::Col
#       [ -4.000e+00                  <--- x = -4
#         4.500e+00 ]                 <--- y = 4.5
#       >> m*x
#       => GSL::Vector::Col
#       [  5.000e+00
#          6.000e+00 ]
#
# ---
# * GSL::Matrix#^(b)
#
#   Computes matrix power of <tt>b</tt>.
#
# === Finding maximum and minimum elements of matrices
#
# ---
# * GSL::Matrix#max
# * GSL::Matrix#min
#
#   These methods return the max/min value in the  matrix.
#
# ---
# * GSL::Matrix#minmax
#
#   This method returns a two elements array [min, max],
#   which contains the minimum
#   and the maximum values in the  matrix.
#
# ---
# * GSL::Matrix#max_index
# * GSL::Matrix#min_index
#
#   These methods return the index of the max/min value in the matrix.
#
# ---
# * GSL::Matrix#minmax_index
#
#   This method returns a two elements array [imin, imax],
#   which contains the indices
#   of the minimum and the maximum value in the matrix.
#
# === Matrix properties
# ---
# * GSL::Matrix#isnull
#
#   This returns 1 if all the elements of the matrix <tt>self</tt> are zero,
#   and 0 otherwise.
#
# ---
# * GSL::Matrix#isnull?
#
#   This returns <tt>true</tt> if all the elements of the matrix <tt>self</tt>
#   are zero, and <tt>false</tt> otherwise.
#
# ---
# * GSL::Matrix#ispos
# * GSL::Matrix#ispos?
#
#   (GSL-1.9 or later) Return 1 (true) if all the elements of the matrix <tt>self</tt> are strictly positive, and 0 (false) otherwise.
#
# ---
# * GSL::Matrix#isneg
# * GSL::Matrix#isneg?
#
#   (GSL-1.9 or later) Return 1 (true) if all the elements of the matrix <tt>self</tt> are strictly negative, and 0 (false) otherwise.
#
# ---
# * GSL::Matrix#isnonneg
# * GSL::Matrix#isnonneg?
#
#   (GSL-1.10 or later) Return 1 (true) if all the elements of the matrix <tt>self</tt> are non-negative , and 0 (false) otherwise.
#
# ---
# * GSL::Matrix#any
#
#   Returns a Vector of ones and zeros with each element indicating
#   whether any of the elements of the corresponding column of the
#   matrix are nonzero.
#
# ---
# * GSL::Matrix#all
#
#   Behaves like the method <tt>any</tt>, except that it returns 1 only if
#   all the elements of the matrix.
#
# ---
# * GSL:Matrix#trace
#
#   This returns trace of the matrix <tt>self</tt>, the sum of the diagonal
#   elements.
#
# ---
# * GSL:Matrix#norm
#
#   Returns matrix norm, sqrt(sum_{ij} m_{ij}^2).
#
# ---
# * GSL::Matrix#sgn
# * GSL::Matrix#signum
#
#   Creates a new matrix, with elements +1 if <tt>x_i,j</tt> > 0, -1 if
#   <tt>x_i,j</tt> < 0, otherwise 0.  Note that this definition gives the signum
#   of NaN as 0 rather than NaN.
#
# ---
# * GSL:Matrix#abs
# * GSL:Matrix#fabs
#
#   Example:
#     >> m = GSL::Matrix::Int[-5..4, 3, 3]
#     => GSL::Matrix::Int
#     [ -5 -4 -3
#       -2 -1  0
#        1  2  3 ]
#     >> m.abs
#     => GSL::Matrix::Int
#     [ 5 4 3
#       2 1 0
#       1 2 3 ]
#
# ---
# * GSL::Matrix#equal?(other, eps = 1e-10)
# * GSL::Matrix#==(other, eps = 1e-10)
#
#   Returns <tt>true</tt> if the matrices have same size and elements
#   equal to absolute accurary <tt>eps</tt> for all the indices,
#   and <tt>false</tt> otherwise.
#
# == NArray
#
# ---
# * GSL::Matrix#to_na
#
#   The Matrix object <tt>self</tt> is converted into an <tt>NMatrix</tt> object.
#   The matrix data are copied to newly allocated memory.
#
# ---
# * NArray#to_gm
# * NArray#to_gslm
#
#   Convert <tt>NArray</tt> object into <tt>GSL::Matrix</tt>.
#
# ---
# * NArray#to_gm_view
# * NArray#to_gslm_view
#
#   A <tt>GSL::Matrix::View</tt> object is created from the NArray object <tt>na</tt>.
#   The data of <tt>na</tt> are
#   not copied, thus any modifications to the View object affect on the original
#   NArray object <tt>na</tt>.
#   The View object can be used as a reference to the NMatrix object.
#
# == Special matrices
# ---
# * GSL::Matrix.hirbert(n)
#
#   Returns the Hilbert matrix of order <tt>n</tt>. The <tt>ij</tt> element is
#   defined as 1/(i+j+1).
#
# ---
# * GSL::Matrix.invhirbert(n)
#
#   Returns the inverse of a Hilbert matrix of order <tt>n</tt>.
#
#   Ex:
#     >> m = GSL::Matrix.hilbert(4)
#     => GSL::Matrix
#     [ 1.000e+00 5.000e-01 3.333e-01 2.500e-01
#       5.000e-01 3.333e-01 2.500e-01 2.000e-01
#       3.333e-01 2.500e-01 2.000e-01 1.667e-01
#       2.500e-01 2.000e-01 1.667e-01 1.429e-01 ]
#     >> invm = GSL::Matrix.invhilbert(4)
#     => GSL::Matrix
#     [ 1.600e+01 -1.200e+02 2.400e+02 -1.400e+02
#       -1.200e+02 1.200e+03 -2.700e+03 1.680e+03
#       2.400e+02 -2.700e+03 6.480e+03 -4.200e+03
#       -1.400e+02 1.680e+03 -4.200e+03 2.800e+03 ]
#     >> invm2 = m.inv
#     => GSL::Matrix
#     [ 1.600e+01 -1.200e+02 2.400e+02 -1.400e+02
#       -1.200e+02 1.200e+03 -2.700e+03 1.680e+03
#       2.400e+02 -2.700e+03 6.480e+03 -4.200e+03
#       -1.400e+02 1.680e+03 -4.200e+03 2.800e+03 ]
#     >> m*invm
#     => GSL::Matrix
#     [ 1.000e+00 5.684e-14 -2.274e-13 1.137e-13
#       1.998e-15 1.000e+00 -4.663e-14 3.109e-14
#       3.664e-15 -7.239e-14 1.000e+00 -1.017e-13
#       -2.442e-15 1.510e-14 -8.038e-14 1.000e+00 ]
#     >> m*invm2
#     => GSL::Matrix
#     [ 1.000e+00 0.000e+00 0.000e+00 0.000e+00
#       -1.554e-15 1.000e+00 -2.389e-14 8.349e-15
#       1.295e-15 3.405e-15 1.000e+00 -6.957e-15
#       1.110e-15 1.916e-14 1.707e-14 1.000e+00 ]
#
# ---
# * GSL::Matrix.pascal(n)
#
#   Returns the Pascal matrix of order <tt>n</tt>, created from Pascal's triangle.
#
#     >> GSL::Matrix::Int.pascal(10)
#     => GSL::Matrix::Int
#     [     1     1     1     1     1     1     1     1     1     1
#           1     2     3     4     5     6     7     8     9    10
#           1     3     6    10    15    21    28    36    45    55
#           1     4    10    20    35    56    84   120   165   220
#           1     5    15    35    70   126   210   330   495   715
#           1     6    21    56   126   252   462   792  1287  2002
#           1     7    28    84   210   462   924  1716  3003  5005
#           1     8    36   120   330   792  1716  3432  6435 11440
#           1     9    45   165   495  1287  3003  6435 12870 24310
#           1    10    55   220   715  2002  5005 11440 24310 48620 ]
#
# ---
# * GSL::Matrix.vandermonde(v)
#
#   Creates a Vendermonde matrix from a vector or an array <tt>v</tt>.
#
#      >> GSL::Matrix.vander([1, 2, 3, 4])
#      => GSL::Matrix
#      [ 1.000e+00 1.000e+00 1.000e+00 1.000e+00
#        8.000e+00 4.000e+00 2.000e+00 1.000e+00
#        2.700e+01 9.000e+00 3.000e+00 1.000e+00
#        6.400e+01 1.600e+01 4.000e+00 1.000e+00 ]
#
# ---
# * GSL::Matrix.toeplitz(v)
#
#   Creates a Toeplitz matrix from a vector or an array <tt>v</tt>.
#
#       >> GSL::Matrix::Int.toeplitz([1, 2, 3, 4, 5])
#       => GSL::Matrix::Int
#       [ 1 2 3 4 5
#         2 1 2 3 4
#         3 2 1 2 3
#         4 3 2 1 2
#         5 4 3 2 1 ]
#
# ---
# * GSL::Matrix.circulant(v)
#
#   Creates a circulant matrix from a vector or an array <tt>v</tt>.
#
#       >> GSL::Matrix::Int.circulant([1, 2, 3, 4])
#       => GSL::Matrix::Int
#       [ 4 1 2 3
#         3 4 1 2
#         2 3 4 1
#         1 2 3 4 ]
#
# {prev}[link:vector_rdoc.html]
# {next}[link:perm_rdoc.html]
#
# {Reference index}[link:ref_rdoc.html]
# {top}[link:index.html]
#
#
