/**
 *
 * @file core_clrnrm.c
 *
 * PaStiX low-rank kernel to compute the norms of a low-rank block.
 *
 * @copyright 2016-2024 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
 *                      Univ. Bordeaux. All rights reserved.
 *
 * @version 6.4.0
 * @author Mathieu Faverge
 * @date 2024-07-05
 * @generated from /build/pastix/src/pastix-6.4.0/kernels/core_zlrnrm.c, normal z -> c, Sun Feb 15 18:01:31 2026
 *
 **/
#include "common.h"
#include <lapacke.h>
#include "pastix_clrcores.h"

/**
 *******************************************************************************
 *
 * @brief Compute the norm of a low-rank matrix.
 *
 *******************************************************************************
 *
 * @param[in] ntype
 *          The matrix norm to compute.
 *
 * @param[in] transV
 *          TODO
 *
 * @param[in] M
 *          TODO
 *
 * @param[in] N
 *          TODO
 *
 * @param[in] A
 *          The low-rank matrix
 *
 *******************************************************************************
 *
 * @return The norm of the matrix A
 *
 *******************************************************************************/
float
core_clrnrm( pastix_normtype_t       ntype,
             int                     transV,
             pastix_int_t            M,
             pastix_int_t            N,
             const pastix_lrblock_t *A )
{
    if ( ntype != PastixFrobeniusNorm ) {
        fprintf( stderr, "core_clrnrm: Only the Frobenius norm is available for now\n");
        ntype = PastixFrobeniusNorm;
    }

    if ( A->rk == -1 ) {
        assert( transV == PastixNoTrans );
        return LAPACKE_clange_work( LAPACK_COL_MAJOR, 'f',
                                    M, N, A->u, M, NULL );
    }
    else if ( A->rk == 0 ) {
        return 0.;
    }
    else {
        float normU, normV;

        normU = LAPACKE_clange_work( LAPACK_COL_MAJOR, 'f',
                                     M, A->rk, A->u, M, NULL );
        if ( transV == PastixNoTrans ) {
            normV = LAPACKE_clange_work( LAPACK_COL_MAJOR, 'f',
                                         A->rk, N, A->v, A->rkmax, NULL );
        }
        else {
            normV = LAPACKE_clange_work( LAPACK_COL_MAJOR, 'f',
                                         N, A->rk, A->v, N, NULL );
        }
        /* This is an over-estimation of the norm as with frobenius ||UV|| <= ||U|| * ||V|| */
        return normU * normV;
    }
}
