Computational routine
eng


genmllsrs

File content


/* Modnumlib Scicos interfacing function
 * Copyright (C) 2009-2011 Alan Layec
 *
 * This library 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 2 of the License, or (at your option) any later version.
 *
 * This library 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 this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
 
/* Genmllsrs Scicos Maximal Length Linear feddback Shift Regiter Sequences Generator block
 * Type 4 simulation function ver 1.1 - scilab-3.0
 * 15 décembre 2004 - IRCOM GROUP - Author : A.Layec
 */

/* REVISION HISTORY :
 * $Log$
 */

#include "modnum_lib.h"
#include "scicos_block.h"

/* Cette fonction de simulation est un générateur de sequences pseudoaléatoires
 * à longueur maximale.
 * Les valeurs de sortie sont soit -1 soit 1 et dependent d'une combinaison linéaire
 * des valeurs des registres internes Z. Les opérations sont réalisées grâce à des
 * opérateurs de manipulations de bit, et les mots binaires sont stockés par leurs valeurs entières.
 * La fonction est capable de délivrer des vecteurs de nb_gen générateurs.
 *
 * Entrée régulière : néant
 * Sorties régulières : y[0..ny[0]-1]                              : sortie du générateur 1
 *                      y[ny[0]..ny[0]+ny[1]-1]                    : sortie du générateur 2
 *                      ...
 *                      y[ny[nb_gen-2]..ny[nb_gen-2]+ny[nb_gen-1]] : sortie du générateur nb_gen
 *
 * Entrée évenementielle : période de déclenchement
 * Sortie évènementielle : néant.
 *
 * Etats discrets : z[0..nb_gen-1]        : valeur des registres à décalage 
 *
 * paramètres entiers : ipar[0]                    : nb_gen nombre de générateurs
 *                      ipar[1..nb_gen]            : ny[0..nb_gen-1] longeur des vecteurs de sortie des géné
 *                      ipar[nb_gen+1..2*nb_gen]   : longueur des registres (nbre de bascules)
 *                     ipar[2*nb_gen+1..3*nb_gen] : valeurs des coefficients des registres
 */

/*work structure of that block*/
typedef struct work_st {
  double *y__;    /* discrete output state of generators */
} work_struct;

void genmllsrs(scicos_block *block,int flag)
{
  /*déclaration des variables*/
  int ny;
  int my=1; /* */
  int m;
  int nb_gen;
  int coef;
  int reg,N;
  int k;
  int y_ptr;
  double *y;

  /*ptr of the struct of that block*/
  work_struct *work;

  /*get the struct of that block*/
  work = (work_struct*) *block->work;

  /*Récupération des adresses des ports réguliers*/
  y=(double *)block->outptr[0];

  /*Récupération du nombre de générateurs*/
  nb_gen=block->ipar[0];

  /*initialisation*/
  if(flag==4) {
    /*Récuperation de la 1ere dimension du port de sortie*/
    ny = block->outsz[0];

    /*allocation*/
    if ((work=(work_struct*) scicos_malloc(sizeof(work_struct))) == NULL) {
      set_block_error(-16);
      return;
    }

    /*etats cachés pour le calcul des états discrets*/
    if ((work->y__=(double*) scicos_malloc(my*ny*sizeof(double))) == NULL) {
      set_block_error(-16);
      return;
    }

    /*store my_st in block->work*/
    *block->work=(void *)work; /*store my_st in *block->work*/

    for(k=0;k<nb_gen;k++) {
      /*Définition de l'adresse de départ de la sortie du géné k*/
      if(k!=0) y_ptr=y_ptr+block->ipar[k];
      else y_ptr=0;

      /*Récupération de la longueur du vecteur de sortie*/
      ny=block->ipar[1+k];

      /*Récupération de la longueur du registre*/
      N=block->ipar[nb_gen+1+k];

      /*Récupération de la valeur du registre*/
      reg=(int) block->z[k];

      /*Récupération de la valeur des coef*/
      coef=block->ipar[2*nb_gen+1+k];

      /*Appel routine mllsrs_c*/
      mllsrs_c(&N,&ny,&work->y__[y_ptr],&reg,&coef);

      /*Sauvegarde la valeur du registre dans z[0]*/
      block->z[k] = reg;
    }
  }
  /*Calcul des sorties */
  else if((flag==1)||(flag==6)) {
    /*Récuperation de la 1ere dimension du port de sortie*/
    ny = block->outsz[0];

    /*appel copyd_c*/
    copyd_c((m=ny*my,&m),work->y__,y);
  }
  /*Calcul des états*/
  else if(flag==2) {
    for(k=0;k<nb_gen;k++) {
      /*Définition de l'adresse de départ de la sortie du géné k*/
      if(k!=0) y_ptr=y_ptr+block->ipar[k];
      else y_ptr=0;

      /*Récupération de la longueur du vecteur de sortie*/
      ny=block->ipar[1+k];

      /*Récupération de la longueur du registre*/
      N=block->ipar[nb_gen+1+k];

      /*Récupération de la valeur du registre*/
      reg=(int) block->z[k];

      /*Récupération de la valeur des coef*/
      coef=block->ipar[2*nb_gen+1+k];

      /*Appel routine mllsrs_c*/
      mllsrs_c(&N,&ny,&work->y__[y_ptr],&reg,&coef);

      /*Sauvegarde la valeur du registre dans z[0]*/
      block->z[k] = reg;
    }
  }
  /*Terminaison*/
  else if(flag==5) {
    if (work!=NULL) {
      scicos_free(work->y__);
    }
    scicos_free(work);
  }
}