Skip to content

File comp_rational_data.c

File List > comp-rational_data > src > comp_rational_data.c

Go to the documentation of this file

/******************************************************************************/
/************************** Includes ******************************************/
/******************************************************************************/

#include "comp_rational_data.h"
#include "stdbool.h"
#include "stdint.h"
#include "stdio.h"
#include "stdlib.h"

/******************************************************************************/
/************************** Defines *******************************************/
/******************************************************************************/

/******************************************************************************/
/************************** Typedefs ******************************************/
/******************************************************************************/

/******************************************************************************/
/************************** Private Function Declarations *********************/
/******************************************************************************/

STATIC_INLINE_UINT8 comp_rational_data_alg_eq(uint16_t p, uint16_t q);

STATIC_INLINE_UINT8 comp_rational_data_write_alg_eq(uint16_t num_eq,
                                                    uint16_t den_eq);

STATIC_INLINE_UINT8 comp_rational_data_parity(uint16_t p, uint16_t q);

STATIC_INLINE_UINT8 comp_rational_data_write_parity(char *parity);

STATIC_INLINE_UINT8 comp_rational_data_rat_num(uint16_t *p, uint16_t *q);

STATIC_INLINE_UINT8 comp_rational_data_write_rat_num(uint16_t p, uint16_t q);

/******************************************************************************/
/************************** Local Variables ***********************************/
/******************************************************************************/

static comp_rational_data_config_t *comp_rational_data_localcfg = NULL;

static comp_rational_data_result_t comp_rational_data_localrestult = { 0,
                                                                       0,
                                                                       NULL,
                                                                       0,
                                                                       0 };

static bool comp_rational_data_executed = false;

/******************************************************************************/
/************************** Public Function Definitions ***********************/
/******************************************************************************/

/*
 *  Documentation in header
 */
uint8_t comp_rational_data_config(comp_rational_data_config_t *config_arg)
{
    uint8_t ret_val = COMP_DEFS_CONFIG_FAIL;

    /*Ensure the cfg is not empty.*/
    if (config_arg == NULL)
    {
        ret_val |= COMP_RATIONAL_DAT_CONFIG_IS_NULL;
    } /*Ensure the tv is not empty.*/
    else if (config_arg->tv_n == NULL)
    {
        ret_val |= COMP_RATIONAL_DAT_CONFIG_BUFFER;
    } /* Ensure the string buffer exists and has a length. */
    else if (config_arg->tv_str_buff == NULL)
    {
        ret_val |= COMP_RATIONAL_DAT_CONFIG_STR_BUFFER;
    }
    else
    {
        /* Set the config. */
        comp_rational_data_localcfg = config_arg;

        /* Clear the return value*/
        comp_rational_data_localrestult.den_algebraic_equ = 0;
        comp_rational_data_localrestult.denominator       = 0;
        comp_rational_data_localrestult.num_algebraic_equ = 0;
        comp_rational_data_localrestult.numerator         = 0;
        comp_rational_data_localrestult.parity            = NULL;

        /*clear the executed status*/
        comp_rational_data_executed = false;

        ret_val = COMP_DEFS_CONFIG_SUCCESS;
    }
    return ret_val;
}

/*
 *  Documentation in header
 */
uint8_t comp_rational_data_compute()
{
    uint8_t  ret_val = COMP_DEFS_COMPUTE_SUCCESS;
    uint16_t p;
    uint16_t q;

    /*Ensure the cfg is not empty.*/
    if (comp_rational_data_localcfg == NULL)
    {
        ret_val |= COMP_DEFS_COMPUTE_FAIL;
    } /*Ensure not executed.*/
    else if (comp_rational_data_executed != false)
    {
        ret_val |= COMP_DEFS_COMPUTE_FAIL;
    }
    else
    {
        comp_rational_data_executed = true;

        /*All code paths need the stringified twist vector as a key. We encode here.*/
        note_tv_encode(*(comp_rational_data_localcfg->tv_n),
                       comp_rational_data_localcfg->tv_str_buff,
                       comp_rational_data_localcfg->tv_str_buff_len);

        /*@@@TODO: Add error handling.*/
        /*Execute local functions.*/
        ret_val |= comp_rational_data_rat_num(&p, &q);
        ret_val |= comp_rational_data_write_rat_num(p, q);
        ret_val |= comp_rational_data_alg_eq(p, q);
        ret_val |= comp_rational_data_parity(p, q);
    }
    return ret_val;
}

/*
 *  Documentation in header
 */
const comp_rational_data_result_t *comp_rational_data_result()
{
    const comp_rational_data_result_t *ret_val = NULL;

    ;
    if (comp_rational_data_localcfg == NULL)
    {
        ret_val = NULL;
    } /*Ensure not executed.*/
    else if (comp_rational_data_executed == false)
    {
        ret_val = NULL;
    }
    else
    {
        ret_val =
            (const comp_rational_data_result_t *)&comp_rational_data_localrestult;
    }
    return ret_val;
}

/******************************************************************************/
/************************** Private Function Declarations *********************/
/******************************************************************************/

/*
 *  Documentation at declaration
 */
STATIC_INLINE_UINT8 comp_rational_data_alg_eq(uint16_t p, uint16_t q)
{
    /*EQ class computation is described in docs.*/
    return comp_rational_data_write_alg_eq(p % q, q % p);
}

/*
 *  Documentation at declaration
 */
STATIC_INLINE_UINT8 comp_rational_data_write_alg_eq(uint16_t num_eq,
                                                    uint16_t den_eq)
{
    uint8_t ret_val = COMP_DEFS_COMPUTE_SUCCESS;
    char *  value   = COMP_RATIONAL_DAT_STORAGE_UKEY;
    char    local_str[UTIL_TANG_DEFS_MAX_CROSSINGNUM];

    value = "numerator_eq";

    /* Decode to get the string representation for the numerator equivalence class and store.*/
    sprintf(local_str, "%u", num_eq);
    comp_rational_data_localcfg->storage_write(
        comp_rational_data_localcfg->tv_str_buff, value, local_str);
    comp_rational_data_localrestult.num_algebraic_equ = num_eq;

    value = "denominator_eq";

    /* Decode to get the string representation for the denominator equivalence class and store.*/
    sprintf(local_str, "%u", den_eq);
    comp_rational_data_localcfg->storage_write(
        comp_rational_data_localcfg->tv_str_buff, value, local_str);
    comp_rational_data_localrestult.den_algebraic_equ = den_eq;
    return ret_val;
}

/*
 *  Documentation at declaration
 */
STATIC_INLINE_UINT8 comp_rational_data_parity(uint16_t p, uint16_t q)
{
    uint8_t ret_val = COMP_DEFS_COMPUTE_FAIL;

    /*Parity computation is described in docs.*/
    /*Check if p,q are even*/
    if (!((p % 2 == 0) && (q % 2 == 0)))
    {
        char *parity = "";
        ret_val = COMP_DEFS_COMPUTE_SUCCESS;
        if (p % 2 == 1)
        {
            if (q % 2 == 1)
            {
                /*p odd q odd*/
                parity = UTIL_TANG_DEFS_ONE_TANG_STR;
            }
            else
            {
                /*p odd q even*/
                parity = UTIL_TANG_DEFS_INF_TANG_STR;
            }
        }
        else
        {
            /*p even q odd*/
            parity = UTIL_TANG_DEFS_ZERO_TANG_STR;
        }
        /*Write data*/
        (void)comp_rational_data_write_parity(parity);
        comp_rational_data_localrestult.parity = parity;
    }
    return ret_val;
}

/*
 *  Documentation at declaration
 */
STATIC_INLINE_UINT8 comp_rational_data_write_parity(char *parity)
{
    uint8_t ret_val = COMP_DEFS_COMPUTE_SUCCESS;
    char *  value   = COMP_RATIONAL_DAT_STORAGE_UKEY;

    value = "parity";
    /* Store parity.*/
    comp_rational_data_localcfg->storage_write(
        comp_rational_data_localcfg->tv_str_buff, value, parity);
    return ret_val;
}

/*
 *  Documentation at declaration
 */
STATIC_INLINE_UINT8 comp_rational_data_rat_num(uint16_t *p, uint16_t *q)
{
    uint8_t ret_val = COMP_DEFS_COMPUTE_SUCCESS;
    /*p_{i-1}*/
    uint16_t pimo = 0;
    /*p_{i}*/
    uint16_t pi = 1;
    /*q_{i-1}*/
    uint16_t qimo = 1;
    /*q_{i}*/
    uint16_t qi = 0;
    size_t   i  = 0;

    /*Rational number computation is described in docs.*/

    /*For each entry in twist vector.*/
    for (i = 0; i < comp_rational_data_localcfg->tv_n->tv_length; i++)
    {
        uint16_t tmp_p = pi;
        uint16_t tmp_q = qi;
        /*Compute p_i and q_i*/
        pi = comp_rational_data_localcfg->tv_n->twist_vector[i] * pi + pimo;
        qi = comp_rational_data_localcfg->tv_n->twist_vector[i] * qi + qimo;

        pimo = tmp_p;
        qimo = tmp_q;
    }

    /*Pass p_i and q_i to calling function as num and den respectively*/
    *p = pi;
    *q = qi;

    return ret_val;
}

/*
 *  Documentation at declaration
 */
STATIC_INLINE_UINT8 comp_rational_data_write_rat_num(uint16_t p, uint16_t q)
{
    uint8_t ret_val = COMP_DEFS_COMPUTE_SUCCESS;
    char    local_str[UTIL_TANG_DEFS_MAX_CROSSINGNUM];
    char *  value = COMP_RATIONAL_DAT_STORAGE_UKEY;

    value = "numerator";
    /* Decode to get the string representation for the numerator and store.*/
    sprintf(local_str, "%u", p);
    comp_rational_data_localcfg->storage_write(
        comp_rational_data_localcfg->tv_str_buff, value, local_str);
    comp_rational_data_localrestult.numerator = p;

    value = "denominator";
    /* Decode to get the string representation for the denominator and store.*/
    sprintf(local_str, "%u", q);
    comp_rational_data_localcfg->storage_write(
        comp_rational_data_localcfg->tv_str_buff, value, local_str);
    comp_rational_data_localrestult.denominator = q;

    return ret_val;
}