def get_matrix_dimensions(name, matrix):
    """
    Return the number of rows and number of columns in a matrix.

    Args:
        name:      string to print as the vector's name if an error occurs
        vector:    numpy 2D ndarray or matrix representing the matrix

    Returns:
        A tuple of two elements where each element is described in order below:

        - number of rows in matrix
        - number of columns in matrix

    Raises:
        TypeError: if matrix is not a 2D NumPy ndarray or matrix
    """

    try:
        rows, cols = matrix.shape

        return rows, cols

    except (AttributeError, TypeError):
        raise_not_2d_numpy(name) def get_square_matrix_dimension(name, matrix):
    """
    Return the dimension of a square matrix.

    Args:
        name:      string to print as the matrix's name if an error occurs
        vector:    numpy 2D ndarray or matrix representing a square matrix

    Returns:
        An int representing both the number of rows and number of columns in matrix.

    Raises:
        TypeError:  if matrix is not a 2D NumPy ndarray or matrix
        ValueError: if matrix is not square
    """

    try:
        rows, cols = matrix.shape

        if rows != cols:
            raise_not_square(name, rows, cols)

        return rows

    except (AttributeError, TypeError):
        raise_not_2d_numpy(name) def check_equal_sizes(name_1, size_1, name_2, size_2):
    """
    Check that size_1 and size_2 are equal.

    Args:
        name_1:    string to print as the name of the first element
        size_1:    size of the first element
        name_2:    string to print as the name of the second element
        size_2:    size of the second element

    Raises:
        ValueError: if size_1 != size_2
    """

    if size_1 != size_2:
        raise_size_mismatch(name_1, size_1, name_2, size_2) def convert_uplo(uplo):
    if uplo == 'u' or uplo == 'U':
        return UPPER
    elif uplo == 'l' or uplo == 'L':
        return LOWER
    else:
        raise_invalid_parameter('uplo', ('u', 'U', 'l', 'L'), uplo) def convert_side(side):
    if side == 'l' or side == 'L':
        return LEFT
    elif side == 'r' or side == 'R':
        return RIGHT
    else:
        raise_invalid_parameter('side', ('l', 'L', 'r', 'R'), side) def convert_trans(trans):
    if trans == 'n' or trans == 'N':
        return NO_TRANS
    elif trans == 't' or trans == 'T':
        return TRANS
    else:
        raise_invalid_parameter('trans', ('n', 'N', 't', 'T'), trans) def convert_diag(diag):
    if diag == 'n' or diag == 'N':
        return NON_UNIT
    elif diag == 'u' or diag == 'U':
        return UNIT
    else:
        raise_invalid_parameter('diag', ('n', 'N', 'u', 'U'), diag) def get_cblas_info(calling_func, dtypes):
    """
    Return the appropriate CBLAS subroutine and ctype data type based on the calling function and
    dtypes of args.

    Args:
        calling_func:    a string representation of the calling function
        dtypes:          a tuple of the dtypes of all of the matrices or vectors passed into the
                         calling function

    Returns:
        A tuple of two elements where each element is described in order below:

        - appropriate CBLAS function
        - appropriate ctypes data type

    Raises:
        ValueError: if all matrices and/or vectors do not have the same dtype
    """

    if all(dtype == 'float64' for dtype in dtypes):
        return FUNC_DICT[calling_func][0], c_double

    elif all(dtype == 'float32' for dtype in dtypes):
        return FUNC_DICT[calling_func][1], c_float

    else:
        raise_invalid_dtypes(('float64', 'float32')) ROW_MAJOR = 101 LEFT = 141
from ..helpers import (get_matrix_dimensions, get_square_matrix_dimension, check_equal_sizes,
                       convert_uplo, convert_side, convert_trans, convert_diag, get_cblas_info,
                       ROW_MAJOR, LEFT)
from ctypes import c_int, POINTER
"""

    Copyright (c) 2014-2015-2015, The University of Texas at Austin.
    All rights reserved.

    This file is part of BLASpy and is available under the 3-Clause
    BSD License, which can be found in the LICENSE file at the top-level
    directory or at http://opensource.org/licenses/BSD-3-Clause

"""



def trmm(A, B, side='l', uplo='u', trans_a='n', diag='n', alpha=1.0, lda=None, ldb=None):
    """
    Perform a triangular matrix-matrix multiplication operation.

    B := alpha * A * B
    or
    B :=  alpha * B * A

    where alpha is a scalar, A is a triangular matrix, and B is a general matrix.

    The 'side' argument indicates whether the symmetric matrix A is multiplied on the left or the
    right side of B. The 'uplo' argument indicates whether the lower or upper triangle of A is to be
    referenced by the operation. The 'trans_a' argument allows the computation to proceed as if A is
    transposed.

    Args:
        A:          2D NumPy matrix or ndarray representing matrix A
        B:          2D NumPy matrix or ndarray representing matrix A

        --optional arguments--

        side:       'l'  if the operation is to proceed as if A is to the left of B
                    'r'  if the operation is to proceed as if A is to the right of B
                        < default is 'l' >
        uplo:       'u'  if the upper triangular part of A is to be used
                    'l'  if the lower triangular part of A is to be used
                        < default is 'u' >
        trans_a:    'n'  if the operation is to proceed as if A is not transposed
                    't'  if the operation is to proceed as if A is transposed
                        < default is 'n' >
        diag:       'n'  if the diagonal of A is non-unit
                    'u'  if the diagonal of A is unit
                        < default is 'n' >
        alpha:      scalar alpha
                        < default is 1.0 >
        lda:        leading dimension of A (must be >= # of cols in A)
                        < default is the number of columns in A >
        ldb:        leading dimension of B (must be >= # of cols in B)
                        < default is the number of columns in B >

    Raises:
        ValueError: if any of the following conditions occur:
                    - A or B is not a 2D NumPy ndarray or NumPy matrix
                    - A and B do not have the same dtype or that dtype is not supported
                    - A is not a square matrix
                    - the dimensions of A and B do not conform
                    - 'uplo' is not equal to one of the following: 'u', 'U', 'l', 'L'
                    - 'side' is not equal to one of the following: 'l', 'L', 'r', 'R'
                    - 'trans_a' is not equal to one of the following: 'n', 'N', 't', 'T'
                    - 'diag' is not equal to one of the following: 'n', 'N', 'u', 'U'
    """

    # convert to appropriate CBLAS value

    cblas_uplo = convert_uplo(uplo)