/*
* Copyright (C) 2020 Weber Yann
*
* This file is part of pyrpn.
*
* pyrpn is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* pyrpn is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with pyrpn. If not, see .
*/
#ifndef __rpn_ifs__h__
#define __rpn_ifs__h__
#include "config.h"
#include
#include
#include "rpn_jit.h"
#include "rpn_if.h"
/**@file rpn_ifs.h
* @brief IFS header
* @ingroup ifs
*/
/**@defgroup ifs Iterated function system
* @brief IFS implementation with RPN expressions
*
* IFS are basically a list of @ref ifs_if associated with a probability
* of evaluation.
*
* This implementation aims to :
* - optimize @ref ifs_if calls
* - optimize random number generation and IF random calls
*
* @note It aims to provide an API close to @ref ifs_if API, in order to
* be able to use both IFS and IF almost tansparently via Python API.
*/
/**@brief struct @ref rpn_ifs_s shortcut */
typedef struct rpn_ifs_s rpn_ifs_t;
/**@brief Stores IFS informations */
struct rpn_ifs_s
{
/**@brief Parameters shared by all IF of the system */
rpn_if_param_t params;
/**@brief Memory map shared by all iterated functions */
rpn_value_t *mem;
/**@brief If 1 the mem has to be munmap at free time */
short self_mem;
/**@brief Pointers on iterated function structures */
rpn_if_t **rpn_if;
/**@brief Number of iterated functions in the system */
size_t if_sz;
/**@brief Current position in memory map */
size_t pos;
/**@brief Stores the original chance of choosing corresponding IF */
unsigned int *weight;
/** @brief Stores an array of 256 pointers on IF allowing fast
* random choice.*/
rpn_if_t *if_proba[256];
/**@brief Stores the RPN expressions pointer of the IF contained in
* the system */
rpn_expr_t **flat_rpn;
/**Number of rpn expression in the system */
size_t flat_sz;
};
/**@brief Initialize a new IFS struct given params
* @param params Individual, but shared, parameters for iteraed functions
* in the system
* @param memmap A suitable memory map or NULL
* @return NULL if error and set errno
* @note Initialized system is empty. Use @ref rpn_ifs_add_if to add an iterated
* function to the system
*/
rpn_ifs_t* rpn_ifs_new(rpn_if_param_t *params, rpn_value_t *memmap);
/**@brief Free ressources of an iterated function system
* @param rifs The iterated function system to free
*/
void rpn_ifs_free(rpn_ifs_t *rifs);
/**@brief Set the number and weights of functions in the system
* @note Do not re-init existing function
* @param rifs The iterated function system
* @param count The number of functions in the system
* @param weights The function's weight
* @return The number of function in the system
*/
size_t rpn_ifs_set_if_count(rpn_ifs_t *rifs, size_t count, unsigned int *weights);
/**@brief Add a new iterated function to the system
* @param rifs The iterated function system
* @param weight The new expression weight
* @return 0 on error, else returns the new @ref rpn_if_s index
* @note if epxrs is NULL empty RPN expressions are used
* @todo change the exprs argument when if init will be updated
*/
size_t rpn_ifs_add_if(rpn_ifs_t *rifs, unsigned int weight);
/**@brief Delete an iterated function from the system given its index
* @param rifs The iterated function system
* @param if_idx The iterated function index in the system
* @return -1 if error else 0
* @note Update sizes but do not calls realloc
*/
int rpn_ifs_del_if(rpn_ifs_t *rifs, size_t if_idx);
/**@brief Call IFS n times
* @note Make n random choices and call corresponding IF
* @param rifs The iterated function system
* @param n consecutive IFS calls
* @param seed prepopulated array of random bytes (if NULL one is generated)
* @return -1 if error else 0
*/
int rpn_ifs_run(rpn_ifs_t *rifs, size_t n, unsigned char *rnd);
/**@brief Updates the @ref rpn_ifs_s.if_proba array using
* @ref rpn_ifs_s.if_proba values
* @param rifs The iterated function system
* @return -1 if error else 0
*/
int rpn_ifs_weight_update(rpn_ifs_t *rifs);
/**@brief Returns an array of pointer on all RPN expressions contained in the
* system, allowing to recompile/update them
* @param rifs The IF system
* @returns An array of pointer on @ref rpn_expr_s
*/
rpn_expr_t **rpn_ifs_flat_rpn(rpn_ifs_t *rifs);
/**@brief Randomly choose an IF and make a step updating ifs current posisition
* @param rifs The IF system
* @param seed A random byte
* @return -1 on error else 0
*/
int rpn_ifs_step(rpn_ifs_t *rifs, unsigned char rnd);
#endif