Ejemplo n.º 1
0
/* inplace transpose of 3x3 matrix */
double* transposem_inplace_3d( double *M )
{
    swap_double( M[1], M[3] );
    swap_double( M[2], M[6] );
    swap_double( M[5], M[7] );

    return M;
}
Ejemplo n.º 2
0
/** Switch the delimiting points of the ring and set the switch flag. 
 */
void swap_ring( Ring *r )
{
  /* check parameters */
  if( r == NULL ) error("swap_ring: invalid ring.");

  swap_double( &(r->x1), &(r->x2) );
  swap_double( &(r->y1), &(r->y2) );
  swap_double( &(r->ang_start), &(r->ang_end) );
  r->full = 1;
}
Ejemplo n.º 3
0
 CRIOGPSPacket CrioReceiver::swapGPSPacket(CRIOGPSPacket& packet) {
   CRIOGPSPacket swapped_packet = packet;
   swapped_packet.latitude = swap_double(packet.latitude);
   swapped_packet.longitude = swap_double(packet.longitude);
   swapped_packet.lat_std_dev = swap_float(packet.lat_std_dev);
   swapped_packet.long_std_dev = swap_float(packet.long_std_dev);
   swapped_packet.solution_status = be32toh(packet.solution_status);
   swapped_packet.position_type = be32toh(packet.position_type);
   swapped_packet.differential_age = swap_float(packet.differential_age);
   swapped_packet.solution_age = swap_float(packet.solution_age);
   return swapped_packet;
 }
Ejemplo n.º 4
0
void send_double (char *name, double double_precision) /* includefile */
{
  send_string(name);
  if (swapout) swap_double(&double_precision);
  fwrite(&double_precision,sizeof(double),1,output);
  /*fprintf(stderr,"%f\n",double_precision);*/
}
Ejemplo n.º 5
0
void	solve_second(double *coef, double *sol)
{
  double	det;
  double	opti;

  sol[0] = -MAX_ROOT;
  opti = -2.0 * coef[0];
  det = coef[1] * coef[1] + 2.0 * opti * coef[2];
  if (det == 0.0)
    {
      sol[1] = coef[1] / opti;
      sol[2] = MAX_ROOT;
    }
  else if (det >= 0.0)
    {
      det = sqrt(det);
      sol[1] = (coef[1] - det) / opti;
      sol[2] = (coef[1] + det) / opti;
      if (sol[1] > sol[2])
	swap_double(sol + 1, sol + 2);
      sol[3] = MAX_ROOT;
    }
  else
    sol[1] = MAX_ROOT;
}
Ejemplo n.º 6
0
/*!
  \brief Perform the "sift" operation for the heap-sort algorithm.

  A heap is a collection of items arranged in a binary tree.  Each
  child node is greater than or equal to its parent.  If x[k] is the
  parent, than its children are x[2k+1] and x[2k+2].

  This routine promotes ("sifts up") children that are smaller than
  their parents.  Thus, this is a "inverse" heap, where the smallest
  element of the heap is the root node.

  Elements in y are associated with those in x and are reordered accordingly.

  \param[in]     root       The root index from which to start sifting.
  \param[in]     lastChild  The last child (largest node index) in the sift operation.
  \param[in,out] x          The array to be sifted.
  \param[in,out] y          The array to be sifted accordingly.
*/
static void heap_sift_2( int root, int lastChild, double x[], double y[] )
{
    int child;

    for (; (child = (root * 2) + 1) <= lastChild; root = child) {

	if (child < lastChild)
	    if ( fabs(x[child]) < fabs(x[child+1]) )
		child++;
	
	if ( fabs(x[child]) <= fabs(x[root]) )
	    break;

	swap_double( x[root], x[child] );
        swap_double( y[root], y[child] );
    }
}
Ejemplo n.º 7
0
/*!
  \brief Discard the smallest element of x and contract the heaps.

  On entry, the numElems of the heap are stored in x[0],...,x[numElems-1],
  and the smallest element is x[0].  The following operations are performed:
    -# Swap the first and last elements of both heaps
    -# Shorten the length of the heaps by one.
    -# Restore the heap property to the contracted heap x.
       This effectively makes x[0] the next smallest element
       in the list.  

  \param[in]     numElems   The number of elements in the current heap.
  \param[in,out] x          The array to be modified.
  \param[in,out] y          The array to be modified accordingly

  \return  The number of elements in each heap after they have been contracted.
*/
static int heap_del_min_2( int numElems, double x[], double y[] )
{
    int lastChild = numElems - 1;

    assert(numElems > 0);

    /* Swap the smallest element with the lastChild. */
    swap_double( x[0], x[lastChild] );
    swap_double( y[0], y[lastChild] ); 

    /* Contract the heap size, thereby discarding the smallest element. */
    lastChild--;
    
    /* Restore the heap property of the contracted heap. */
    heap_sift_2( 0, lastChild, x, y );

    return numElems - 1;
}
Ejemplo n.º 8
0
/** Code taken from Wikipedia */
void quicksort(double *array, int begin, int end) {
	if (end > begin) {
		double pivot = array[begin];
		int l = begin + 1;
		int r = end+1;
		while(l < r) {
			if (array[l] < pivot) {
				l++;
			} else {
				r--;
				swap_double(array+l, array+r); 
			}
		}
		l--;
		swap_double(array+begin, array+l);
		if(l>begin)
		quicksort(array, begin, l);
		if(end>r)
		quicksort(array, r, end);
	}
}
Ejemplo n.º 9
0
int main() {
   int a = 10;
   int b = 20;
   double c = 10.0;
   double d = 20.0;

   printf("Before swap: %d %d\n", a, b);
   swap(&a, &b);
   printf("After swap: %d %d\n", a, b);

   printf("Before swap: %lf %lf\n", c, d);
   swap_double(&c, &d);
   printf("After swap: %lf %lf\n", c, d);

   return 0;
}
Ejemplo n.º 10
0
/*************************************************************************
 mcell_sort_numeric_list:
    Sort a num_expr_list in ascending numeric order.  N.B. This uses bubble
    sort, which is O(n^2).  Don't use it if you expect your list to be very
    long.  The list is sorted in-place.

 In:  head:  the list to sort
 Out: list is sorted
*************************************************************************/
void mcell_sort_numeric_list(struct num_expr_list *head) {
  struct num_expr_list *curr, *next;
  int done = 0;
  while (!done) {
    done = 1;
    curr = head;
    while (curr != NULL) {
      next = curr->next;
      if (next != NULL) {
        if (curr->value > next->value) {
          done = 0;
          swap_double(&curr->value, &next->value);
        }
      }
      curr = next;
    }
  }
}
Ejemplo n.º 11
0
/** Check if ellipse is valid: axes must be positive; ensure big axis is first 
    and orientation in [-pi/2, pi/2].
 */
int check_ell( double *eparam )
{
  /* check parameters */
  if( eparam == NULL ) error("check_ell: invalid ellipse.");

  /* reject if degenerate ellipse (negative axes) */
  if( (eparam[2] <= 1) || (eparam[3] <= 1) ) return FALSE;
  /* make sure 'ax' is the greater axis */
  if( eparam[2] < eparam[3] )
    {
      swap_double( &(eparam[2]), &(eparam[3]) );
      eparam[4] += M_1_2_PI;
    }
  /* reject directly if very thin ellipse, to win time */
  if( eparam[2] / eparam[3] > 100 ) return FALSE;

  /* make sure orientation belongs to [-pi/2, pi/2] */
  if( eparam[4] > M_1_2_PI ) eparam[4] -= M_PI;
  if( eparam[4] > M_PI ) eparam[4] -= M_PI;
  if( eparam[4] < -M_1_2_PI ) eparam[4] += M_PI;

  return TRUE;
}
Ejemplo n.º 12
0
// adaptiveMeshConstructor()
// Inputs: n (width/height of the square mesh), l (maximum level of refinement),
//         pointers for the level, x, and y arrays (should be NULL for all three)
// Output: number of cells in the adaptive mesh
//
int adaptiveMeshConstructorWij(const int n, const int l, 
         int** level_ptr, double** x_ptr, double** y_ptr, int **i_ptr, int **j_ptr) {
   int ncells = SQR(n);

   // ints used for for() loops later
   int ic, xc, yc, xlc, ylc, nlc;

   //printf("\nBuilding the mesh...\n");

   // Initialize Coarse Mesh
   int*  level = (int*)  malloc(sizeof(int)*ncells);
   double* x   = (double*) malloc(sizeof(double)*ncells);
   double* y   = (double*) malloc(sizeof(double)*ncells);
   int*  i     = (int*)  malloc(sizeof(int)*ncells);
   int*  j     = (int*)  malloc(sizeof(int)*ncells);
   for(yc = 0; yc < n; yc++) {
      for(xc = 0; xc < n; xc++) {
         level[n*yc+xc] = 0;
         x[n*yc+xc]     = (real)(TWO*xc+ONE) / (real)(TWO*n);
         y[n*yc+xc]     = (real)(TWO*yc+ONE) / (real)(TWO*n);
         i[n*yc+xc]     = xc;
         j[n*yc+xc]     = yc;
      }
   }
   //printf("Coarse mesh initialized.\n");

   // Randomly Set Level of Refinement
   //unsigned int iseed = (unsigned int)time(NULL);
   //srand (iseed);
   srand (0);
   for(int ii = l; ii > 0; ii--) {
      for(ic = 0; ic < ncells; ic++) {
         int jj = 1 + (int)(10.0*rand() / (RAND_MAX+1.0));
         // XXX Consider distribution across levels: Clustered at 1 level XXX
         if(jj>5) {level[ic] = ii;}
      }
   }

   //printf("Levels of refinement randomly set.\n");

   // Smooth the Refinement
   int newcount = -1;
   while(newcount != 0) {
      newcount = 0;
      int lev = 0;
      for(ic = 0; ic < ncells; ic++) {
         lev = level[ic];
         lev++;
         // Check bottom neighbor
         if(ic - n >= 0) {
            if(level[ic-n] > lev) {
               level[ic] = lev;
               newcount++;
               continue;
            }
         }
         // Check top neighbor
         if(ic + n < ncells) {
            if(level[ic+n] > lev) {
               level[ic] = lev;
               newcount++;
               continue;
            }
         }
         // Check left neighbor
         if((ic%n)-1 >= 0) {
            if(level[ic-1] > lev) {
               level[ic] = lev;
               newcount++;
               continue;
            }
         }
         // Check right neighbor
         if((ic%n)+1 < n) {
            if(level[ic+1] > lev) {
               level[ic] = lev;
               newcount++;
               continue;
            }
         }
      }
   }
   //printf("Refinement smoothed.\n");

   // Allocate Space for the Adaptive Mesh
   newcount = 0;
   for(ic = 0; ic < ncells; ic++) {newcount += (powerOfFour(level[ic]) - 1);}
   int*  level_temp = (int*)  malloc(sizeof(int)*(ncells+newcount));
   double* x_temp   = (double*) malloc(sizeof(double)*(ncells+newcount));
   double* y_temp   = (double*) malloc(sizeof(double)*(ncells+newcount));
   int*  i_temp     = (int*)  malloc(sizeof(int)*(ncells+newcount));
   int*  j_temp     = (int*)  malloc(sizeof(int)*(ncells+newcount));

   // Set the Adaptive Mesh
   int offset = 0;
   for(yc = 0; yc < n; yc++) {
      for(xc = 0; xc < n; xc++) {
         ic = n*yc + xc;
         nlc = (int) SQRT( (real) powerOfFour(level[ic]) );
         for(ylc = 0; ylc < nlc; ylc++) {
            for(xlc = 0; xlc < nlc; xlc++) {
               level_temp[ic + offset + (nlc*ylc + xlc)] = level[ic];
               x_temp[ic + offset + (nlc*ylc + xlc)] = x[ic]-(ONE / (real)(TWO*n))
                                    + ((real)(TWO*xlc+ONE) / (real)(n*nlc*TWO));
               y_temp[ic + offset + (nlc*ylc + xlc)] = y[ic]-(ONE / (real)(TWO*n))
                                    + ((real)(TWO*ylc+ONE) / (real)(n*nlc*TWO));
               i_temp[ic + offset + (nlc*ylc + xlc)] = i[ic]*pow(2,level[ic]) + xlc;
               j_temp[ic + offset + (nlc*ylc + xlc)] = j[ic]*pow(2,level[ic]) + ylc;
            }         
         }
         offset += powerOfFour(level[ic])-1;
      }
   }
   //printf("Adaptive mesh built.\n");

   // Swap pointers and free memory used by Coarse Mesh
   swap_int(&level, &level_temp);
   swap_double(&x, &x_temp);
   swap_double(&y, &y_temp);
   swap_int(&i, &i_temp);
   swap_int(&j, &j_temp);
   free(level_temp);
   free(x_temp);
   free(y_temp);
   free(i_temp);
   free(j_temp);


   //printf("Old ncells: %d", ncells);
   // Update ncells
   ncells += newcount;
   //printf("\tNew ncells: %d\n", ncells);

   // Randomize the order of the arrays
   int* random = (int*) malloc(sizeof(int)*ncells);
   int* temp1 = (int*) malloc(sizeof(int)*ncells);
   real* temp2 = (real*) malloc(sizeof(real)*ncells*2);
   int* temp3 = (int*) malloc(sizeof(int)*ncells*2);
   // XXX Want better randomization? XXX
   // XXX Why is the time between printf() statements the longest part? XXX
   //printf("Shuffling");
   //fflush(stdout);
   for(ic = 0; ic < ncells; ic++) {random[ic] = ic;}
   //iseed = (unsigned int)time(NULL);
   //srand (iseed);
   srand(0);
   nlc = 0;
   for(int ii = 0; ii < 7; ii++) {
      for(ic = 0; ic < ncells; ic++) {
         int jj = (int)( ((real)ncells*rand()) / (RAND_MAX+ONE) );
         nlc = random[jj];
         random[jj] = random[ic];
         random[ic] = nlc;
      }
      //printf(".");
      //fflush(stdout);
   }
   //printf("\n");

   for(ic = 0; ic < ncells; ic++) {
      temp1[ic] = level[random[ic]];
      temp2[2*ic] = x[random[ic]];
      temp2[2*ic+1] = y[random[ic]];
      temp3[2*ic] = i[random[ic]];
      temp3[2*ic+1] = j[random[ic]];
   }
   for(ic = 0; ic < ncells; ic++) {
      level[ic] = temp1[ic];
      x[ic]     = temp2[2*ic];
      y[ic]     = temp2[2*ic+1];
      i[ic]     = temp3[2*ic];
      j[ic]     = temp3[2*ic+1];
   }

   free(temp1);
   free(temp2);
   free(temp3);
   free(random);
   //printf("Adaptive mesh randomized.\n");

   *level_ptr = level;
   *x_ptr = x;
   *y_ptr = y;
   *i_ptr = i;
   *j_ptr = j;

   //printf("Adaptive mesh construction complete.\n");
   return ncells;

}
Ejemplo n.º 13
0
static void swapendian_BPP_header(BPP_SEARCH_HEADER * hdr)
/* This is required since it is a binary header */
{
    int ii;

    hdr->header_version = swap_int(hdr->header_version);
    hdr->bit_mode = swap_int(hdr->bit_mode);
    hdr->num_chans = swap_int(hdr->num_chans);
    hdr->lmst = swap_int(hdr->lmst);
    hdr->scan_file_number = swap_int(hdr->scan_file_number);
    hdr->file_size = swap_int(hdr->file_size);
    hdr->tape_num = swap_int(hdr->tape_num);
    hdr->tape_file_number = swap_int(hdr->tape_file_number);
    hdr->enabled_CBs = swap_int(hdr->enabled_CBs);
    hdr->mb_start_address = swap_int(hdr->mb_start_address);
    hdr->mb_end_address = swap_int(hdr->mb_end_address);
    hdr->mb_start_board = swap_int(hdr->mb_start_board);
    hdr->mb_end_board = swap_int(hdr->mb_end_board);
    hdr->mb_vme_mid_address = swap_int(hdr->mb_vme_mid_address);
    hdr->mb_ack_enabled = swap_int(hdr->mb_ack_enabled);
    hdr->start_from_ste = swap_int(hdr->start_from_ste);
    hdr->cb_sum_polarizations = swap_int(hdr->cb_sum_polarizations);
    hdr->cb_direct_mode = swap_int(hdr->cb_direct_mode);
    hdr->cb_accum_length = swap_int(hdr->cb_accum_length);
    hdr->tb_outs_reg = swap_int(hdr->tb_outs_reg);
    hdr->tb_ste = swap_int(hdr->tb_ste);
    hdr->tb_stc = swap_int(hdr->tb_stc);
    hdr->H_deci_factor = swap_int(hdr->H_deci_factor);
    hdr->GenStat0 = swap_int(hdr->GenStat0);
    hdr->GenStat1 = swap_int(hdr->GenStat1);
    hdr->Ack_Reg = swap_int(hdr->Ack_Reg);
    hdr->dfb_sram_length = swap_int(hdr->dfb_sram_length);
    hdr->ASYMMETRIC = swap_int(hdr->ASYMMETRIC);
    hdr->mb_long_ds0 = swap_int(hdr->mb_long_ds0);
    hdr->aib_serial = swap_int(hdr->aib_serial);
    hdr->aib_rev = swap_int(hdr->aib_rev);
    hdr->BACKEND_TYPE = swap_int(hdr->BACKEND_TYPE);
    hdr->UPDATE_DONE = swap_int(hdr->UPDATE_DONE);
    hdr->HEADER_TYPE = swap_int(hdr->HEADER_TYPE);
    hdr->tb_id = swap_int(hdr->tb_id);
    hdr->aib_if_switch = swap_int(hdr->aib_if_switch);
    hdr->mb_rev = swap_int(hdr->mb_rev);
    hdr->mb_serial = swap_int(hdr->mb_serial);
    hdr->tb_rev = swap_int(hdr->tb_rev);
    hdr->tb_serial = swap_int(hdr->tb_serial);
    hdr->mb_xtal_freq = swap_int(hdr->mb_xtal_freq);
    hdr->scan_num = swap_uint(hdr->scan_num);
    hdr->ll_file_offset = swap_longlong(hdr->ll_file_offset);
    hdr->ll_file_size = swap_longlong(hdr->ll_file_size);
    hdr->length_of_integration = swap_double(hdr->length_of_integration);
    hdr->samp_rate = swap_double(hdr->samp_rate);
    hdr->ra_2000 = swap_double(hdr->ra_2000);
    hdr->dec_2000 = swap_double(hdr->dec_2000);
    hdr->tele_x = swap_double(hdr->tele_x);
    hdr->tele_y = swap_double(hdr->tele_y);
    hdr->tele_z = swap_double(hdr->tele_z);
    hdr->tele_inc = swap_double(hdr->tele_inc);
    hdr->Fclk = swap_double(hdr->Fclk);
    hdr->Har_Clk = swap_double(hdr->Har_Clk);
    hdr->bandwidth = swap_double(hdr->bandwidth);
    hdr->rf_lo = swap_double(hdr->rf_lo);
    hdr->max_dfb_freq = swap_double(hdr->max_dfb_freq);
    hdr->mjd_start = swap_longdouble(hdr->mjd_start);
    for (ii = 0; ii < FB_CHAN_PER_BRD; ii++) {
        hdr->dfb_sram_freqs[ii] = swap_float(hdr->dfb_sram_freqs[ii]);
    }
    for (ii = 0; ii < MAX_HARRIS_TAPS; ii++) {
        hdr->i_hcoef[ii] = swap_int(hdr->i_hcoef[ii]);
        hdr->q_hcoef[ii] = swap_int(hdr->q_hcoef[ii]);
    }
    for (ii = 0; ii < MAXNUMCB; ii++) {
        hdr->cb_id[ii] = swap_int(hdr->cb_id[ii]);
        hdr->cb_rev[ii] = swap_int(hdr->cb_rev[ii]);
        hdr->cb_serial[ii] = swap_int(hdr->cb_serial[ii]);
        hdr->cb_eprom_mode[ii] = swap_int(hdr->cb_eprom_mode[ii]);
    }
    for (ii = 0; ii < MAX_NUM_MF_BOARDS; ii++) {
        hdr->mf_rev[ii] = swap_int(hdr->mf_rev[ii]);
        hdr->mf_serial[ii] = swap_int(hdr->mf_serial[ii]);
        hdr->mf_filt_width[ii] = swap_double(hdr->mf_filt_width[ii]);
        hdr->mf_atten[ii] = swap_double(hdr->mf_atten[ii]);
    }
    for (ii = 0; ii < MAX_NUM_LO_BOARDS; ii++) {
        hdr->lo_rev[ii] = swap_int(hdr->lo_rev[ii]);
        hdr->lo_serial[ii] = swap_int(hdr->lo_serial[ii]);
        hdr->aib_los[ii] = swap_double(hdr->aib_los[ii]);
    }
    for (ii = 0; ii < MAXNUMDFB; ii++) {
        hdr->dfb_mixer_reg[ii] = swap_int(hdr->dfb_mixer_reg[ii]);
        hdr->dfb_conf_reg[ii] = swap_int(hdr->dfb_conf_reg[ii]);
        hdr->dfb_sram_addr_msb[ii] = swap_int(hdr->dfb_sram_addr_msb[ii]);
        hdr->dfb_id[ii] = swap_int(hdr->dfb_id[ii]);
        hdr->dfb_rev[ii] = swap_int(hdr->dfb_rev[ii]);
        hdr->dfb_serial[ii] = swap_int(hdr->dfb_serial[ii]);
        hdr->dfb_sun_program[ii] = swap_int(hdr->dfb_sun_program[ii]);
        hdr->dfb_eprom[ii] = swap_int(hdr->dfb_eprom[ii]);
        hdr->dfb_sram_addr[ii] = swap_int(hdr->dfb_sram_addr[ii]);
        hdr->dfb_har_addr[ii] = swap_int(hdr->dfb_har_addr[ii]);
        hdr->dfb_clip_adc_neg8[ii] = swap_int(hdr->dfb_clip_adc_neg8[ii]);
        hdr->dfb_shften_[ii] = swap_int(hdr->dfb_shften_[ii]);
        hdr->dfb_fwd_[ii] = swap_int(hdr->dfb_fwd_[ii]);
        hdr->dfb_rvrs_[ii] = swap_int(hdr->dfb_rvrs_[ii]);
        hdr->dfb_asymmetric[ii] = swap_int(hdr->dfb_asymmetric[ii]);
        hdr->dfb_i_dc[ii] = swap_double(hdr->dfb_i_dc[ii]);
        hdr->dfb_q_dc[ii] = swap_double(hdr->dfb_q_dc[ii]);
        hdr->dfb_gain[ii] = swap_double(hdr->dfb_gain[ii]);
    }
}
Ejemplo n.º 14
0
void G_xdr_put_double(void *dst, const double *src)
{
    swap_double(dst, src);
}
Ejemplo n.º 15
0
void read_prepfoldinfo(prepfoldinfo * in, char *filename)
/* Read a prepfoldinfo data structure from a binary file */
{
   FILE *infile;
   int itmp, byteswap = 0;
   char temp[16];

   infile = chkfopen(filename, "rb");
   in->numdms = read_int(infile, byteswap);
   in->numperiods = read_int(infile, byteswap);
   in->numpdots = read_int(infile, byteswap);
   in->nsub = read_int(infile, byteswap);
   in->npart = read_int(infile, byteswap);
   /* The following is not exactly the most robust, but it should work... */
   if (in->npart < 1 || in->npart > 10000) {
      byteswap = 1;
      in->numdms = swap_int(in->numdms);
      in->numperiods = swap_int(in->numperiods);
      in->numpdots = swap_int(in->numpdots);
      in->nsub = swap_int(in->nsub);
      in->npart = swap_int(in->npart);
   }
   in->proflen = read_int(infile, byteswap);
   in->numchan = read_int(infile, byteswap);
   in->pstep = read_int(infile, byteswap);
   in->pdstep = read_int(infile, byteswap);
   in->dmstep = read_int(infile, byteswap);
   in->ndmfact = read_int(infile, byteswap);
   in->npfact = read_int(infile, byteswap);
   itmp = read_int(infile, byteswap);
   in->filenm = calloc(itmp + 1, sizeof(char));
   chkfread(in->filenm, sizeof(char), itmp, infile);
   itmp = read_int(infile, byteswap);
   in->candnm = calloc(itmp + 1, sizeof(char));
   chkfread(in->candnm, sizeof(char), itmp, infile);
   itmp = read_int(infile, byteswap);
   in->telescope = calloc(itmp + 1, sizeof(char));
   chkfread(in->telescope, sizeof(char), itmp, infile);
   itmp = read_int(infile, byteswap);
   in->pgdev = calloc(itmp + 1, sizeof(char));
   chkfread(in->pgdev, sizeof(char), itmp, infile);
   //chkfread(in->rastr, sizeof(char), 16, infile);
   {
       int has_posn = 1, ii;
       chkfread(temp, sizeof(char), 16, infile);
       /* Check to see if a position string was written */
       for (ii = 0; ii < 16; ii++){
           if (!isdigit(temp[ii]) &&
               temp[ii] != ':' &&
               temp[ii] != '.' &&
               temp[ii] != '-' &&
               temp[ii] != '\0'){
               has_posn = 0;
               break;
           }
       }
       if (has_posn){
           strcpy(in->rastr, temp);
           chkfread(in->decstr, sizeof(char), 16, infile);
           in->dt = read_double(infile, byteswap);
           in->startT = read_double(infile, byteswap);
       } else {
           strcpy(in->rastr, "Unknown");
           strcpy(in->decstr, "Unknown");
           in->dt = *(double *)(temp + 0);
           if (byteswap) in->dt = swap_double(in->dt);
           in->startT = *(double *)(temp + sizeof(double));
           if (byteswap) in->startT = swap_double(in->startT);
       }
   }
   in->endT = read_double(infile, byteswap);
   in->tepoch = read_double(infile, byteswap);
   in->bepoch = read_double(infile, byteswap);
   in->avgvoverc = read_double(infile, byteswap);
   in->lofreq = read_double(infile, byteswap);
   in->chan_wid = read_double(infile, byteswap);
   in->bestdm = read_double(infile, byteswap);
   /* The .pow elements were written as doubles (Why??) */
   in->topo.pow = read_float(infile, byteswap);
   read_float(infile, byteswap);
   in->topo.p1 = read_double(infile, byteswap);
   in->topo.p2 = read_double(infile, byteswap);
   in->topo.p3 = read_double(infile, byteswap);
   /* The .pow elements were written as doubles (Why??) */
   in->bary.pow = read_float(infile, byteswap);
   read_float(infile, byteswap);
   in->bary.p1 = read_double(infile, byteswap);
   in->bary.p2 = read_double(infile, byteswap);
   in->bary.p3 = read_double(infile, byteswap);
   /* The .pow elements were written as doubles (Why??) */
   in->fold.pow = read_float(infile, byteswap);
   read_float(infile, byteswap);
   in->fold.p1 = read_double(infile, byteswap);
   in->fold.p2 = read_double(infile, byteswap);
   in->fold.p3 = read_double(infile, byteswap);
   in->orb.p = read_double(infile, byteswap);
   in->orb.e = read_double(infile, byteswap);
   in->orb.x = read_double(infile, byteswap);
   in->orb.w = read_double(infile, byteswap);
   in->orb.t = read_double(infile, byteswap);
   in->orb.pd = read_double(infile, byteswap);
   in->orb.wd = read_double(infile, byteswap);
   in->dms = gen_dvect(in->numdms);
   chkfread(in->dms, sizeof(double), in->numdms, infile);
   in->periods = gen_dvect(in->numperiods);
   chkfread(in->periods, sizeof(double), in->numperiods, infile);
   in->pdots = gen_dvect(in->numpdots);
   chkfread(in->pdots, sizeof(double), in->numpdots, infile);
   in->rawfolds = gen_dvect(in->nsub * in->npart * in->proflen);
   chkfread(in->rawfolds, sizeof(double), in->nsub *
            in->npart * in->proflen, infile);
   in->stats = (foldstats *) malloc(sizeof(foldstats) * in->nsub * in->npart);
   chkfread(in->stats, sizeof(foldstats), in->nsub * in->npart, infile);
   fclose(infile);
   if (byteswap) {
      int ii;
      for (ii = 0; ii < in->numdms; ii++)
         in->dms[ii] = swap_double(in->dms[ii]);
      for (ii = 0; ii < in->numperiods; ii++)
         in->periods[ii] = swap_double(in->periods[ii]);
      for (ii = 0; ii < in->numpdots; ii++)
         in->pdots[ii] = swap_double(in->pdots[ii]);
      for (ii = 0; ii < in->nsub * in->npart * in->proflen; ii++)
         in->rawfolds[ii] = swap_double(in->rawfolds[ii]);
      for (ii = 0; ii < in->nsub * in->npart; ii++) {
         in->stats[ii].numdata = swap_double(in->stats[ii].numdata);
         in->stats[ii].data_avg = swap_double(in->stats[ii].data_avg);
         in->stats[ii].data_var = swap_double(in->stats[ii].data_var);
         in->stats[ii].numprof = swap_double(in->stats[ii].numprof);
         in->stats[ii].prof_avg = swap_double(in->stats[ii].prof_avg);
         in->stats[ii].prof_var = swap_double(in->stats[ii].prof_var);
         in->stats[ii].redchi = swap_double(in->stats[ii].redchi);
      }
   }
}
Ejemplo n.º 16
0
void G_xdr_get_double(double *dst, const void *src)
{
    swap_double(dst, src);
}
Ejemplo n.º 17
0
/** Given conic parameters and extreme points, fill in all the ring parameters.
    If conic is 1, get circle ring, if 0 get ellipse ring.
 */
int get_ring( Point *reg, int reg_size, double ang, double *param, 
              double *pext1, double *pext2, int conic, double spir, Ring *r, 
              int *grad_dir, double *foci, int msize )
{
  double tang;
  /* check parameters */
  if( reg == NULL ) error("get_ring: invalid region."); 
  if( param == NULL ) error("get_ring: invalid conic parameters."); 
  if( r == NULL ) error("get_ring: ring must be non null.");
  if( foci == NULL ) error("get_ring: foci must be non null."); 
  
  /* fill in centre */
  r->cx = param[0]; r->cy = param[1];

  /* Init 'full' flag; by default, set to 0. */
  r->full = 0;

  if( conic == CIRCLE ) 
    {
      if( !check_circ(param) ) return FALSE;
      *grad_dir = dir_gradient_circ( reg[0].x, reg[0].y, ang, param );   
    }
  else
    {
      if( !check_ell(param) ) return FALSE;
      ellipse_foci( param, foci );
      *grad_dir = dir_gradient_ell( reg[0].x, reg[0].y, ang, foci );
    }
  /* fill in axes and orientation: this must be done after check, as for the 
     ellipse the axes might have been swapped, and orientation normalized */
  r->ax = param[2]; r->bx = param[3];
  r->theta = param[4];

  /* fill in extremal points */
  r->x1 = pext1[0]; r->y1 = pext1[1];
  r->x2 = pext2[0]; r->y2 = pext2[1]; 
  
  /* if gradient converges, interchange the extremal points to keep 
     trigonometric sense */    
  if( *grad_dir == 0 )
    {
      swap_double( &(r->x1), &(r->x2) );
      swap_double( &(r->y1), &(r->y2) );
    } 
  
  /* set delimiting angles */
  r->ang_start = atan2( r->y1 - r->cy, r->x1 - r->cx );
  if( r->ang_start < 0 ) r->ang_start += M_2__PI; 
  r->ang_end = atan2( r->y2 - r->cy, r->x2 - r->cx );
  if( r->ang_end < 0 ) r->ang_end += M_2__PI;

  /* if the ends of the last rectangles got interwined, swap the ends 
     of the ring  */
  if( r->ang_start > r->ang_end ) tang = r->ang_end + M_2__PI;
  else tang = r->ang_end;      
  if( (spir > M_PI) && (tang - r->ang_start < M_1_2_PI/2.0) ) 
    swap_ring( r );
  
  /* set ring widths */
  if( conic == CIRCLE ) 
    circ_ring_width( reg, reg_size, r );
  else
    ell_ring_width( reg, reg_size, r );

  /* abnormal case: width of the ring is bigger than little axis -> 
     discard ring */  
  if( r->wmax - r->wmin > r->bx ) return FALSE;
  if( r->ax > msize ) return FALSE;
  
  return TRUE;
}
Ejemplo n.º 18
0
/****************************************************************************
**    jpl_init_ephemeris( ephemeris_filename, nam, val, n_constants)       **
*****************************************************************************
**                                                                         **
**    this function does the initial prep work for use of binary JPL       **
**    ephemerides.                                                         **
**      const char *ephemeris_filename = full path/filename of the binary  **
**          ephemeris (on the Willmann-Bell CDs,  this is UNIX.200, 405,   **
**          or 406)
**      char nam[][6] = array of constant names (max 6 characters each)    **
**          You can pass nam=NULL if you don't care about the names        **
**      double *val = array of values of constants                         **
**          You can pass val=NULL if you don't care about the constants    **
**      Return value is a pointer to the jpl_eph_data structure            **
**      NULL is returned if the file isn't opened or memory isn't alloced  **
****************************************************************************/
void * DLL_FUNC jpl_init_ephemeris( const char *ephemeris_filename,
                                    char nam[][6], double *val)
{
    int i, j;
    JPLlong de_version;
    char title[84];
    FILE *ifile;
    struct jpl_eph_data *rval;
    struct interpolation_info *iinfo;
    ifile = fopen( ephemeris_filename, "rb");
    if( !ifile)
        return( NULL);
    /* Rather than do three separate allocations,  everything   */
    /* we need is allocated in _one_ chunk,  then parceled out. */
    /* This looks a little weird,  but it does simplify error   */
    /* handling and cleanup.                                    */
    rval = (struct jpl_eph_data *)calloc( sizeof( struct jpl_eph_data)
                                          + sizeof( struct interpolation_info)
                                          + MAX_KERNEL_SIZE * 4, 1);
    if( !rval)
    {
        fclose( ifile);
        return( NULL);
    }
    rval->ifile = ifile;
    fread( title, 84, 1, ifile);
    fseek( ifile, 2652L, SEEK_SET);      /* skip title & constant name data */
    fread( rval, JPL_HEADER_SIZE, 1, ifile);
    de_version = atoi( title + 26);
    /* Once upon a time,  the kernel size was determined from the */
    /* DE version.  This was not a terrible idea,  except that it */
    /* meant that when the code faced a new version,  it broke.   */
    /* Thus,  the 'OLD_CODE' section was replaced with some logic */
    /* that figures out the kernel size.  The 'OLD_CODE' section  */
    /* should therefore be of only historical interest.           */
#ifdef OLD_CODE
    switch( de_version)
    {
    case 200:
    case 202:
        rval->kernel_size = 1652;
        break;
    case 403:
    case 405:
        rval->kernel_size = 2036;
        break;
    case 404:
    case 406:
        rval->kernel_size = 1456;
        break;
    }
#endif
    /* The 'iinfo' struct is right after the 'jpl_eph_data' struct: */
    iinfo = (struct interpolation_info *)(rval + 1);
    rval->iinfo = (void *)iinfo;
    iinfo->np = 2;
    iinfo->nv = 3;
    iinfo->pc[0] = 1.0;
    iinfo->pc[1] = 0.0;
    iinfo->vc[1] = 1.0;
    rval->curr_cache_loc = -1L;
    /* The 'cache' data is right after the 'iinfo' struct: */
    rval->cache = (double *)( iinfo + 1);
    /* A small piece of trickery:  in the binary file,  data is stored */
    /* for ipt[0...11],  then the ephemeris version,  then the         */
    /* remaining ipt[12] data.  A little switching is required to get  */
    /* the correct order. */

    /* 2010-02-05 M.Keith Modified this so that it doesn't use array
    * incicies that are out of bounds, avoiding segfaults when
    * compiled with gcc -O2 */
    rval->ipt[12][0] = rval->ipt[12][1];
    rval->ipt[12][1] = rval->ipt[12][2];
    rval->ipt[12][2] = rval->ephemeris_version;

    rval->ephemeris_version = de_version;
    rval->swap_bytes = ( rval->ncon < 0 || rval->ncon > 65536L);
    if( rval->swap_bytes)     /* byte order is wrong for current platform */
    {
        swap_double( &rval->ephem_start, 1);
        swap_double( &rval->ephem_end, 1);
        swap_double( &rval->ephem_step, 1);
        swap_long_integer( &rval->ncon);
        swap_double( &rval->au, 1);
        swap_double( &rval->emrat, 1);
        for( j = 0; j < 3; j++)
            for( i = 0; i < 13; i++)
                swap_long_integer( &rval->ipt[i][j]);
    }
    rval->kernel_size = 4;
    for( i = 0; i < 13; i++)
        rval->kernel_size +=
            rval->ipt[i][1] * rval->ipt[i][2] * ((i == 11) ? 4 : 6);
    /* printf( "Kernel size = %d\n", rval->kernel_size); */
    rval->recsize = rval->kernel_size * 4L;
    rval->ncoeff = rval->kernel_size / 2L;
    if( val)
    {
        fseek( ifile, rval->recsize, SEEK_SET);
        fread( val, (size_t)rval->ncon, sizeof( double), ifile);
        if( rval->swap_bytes)     /* gotta swap the constants,  too */
        {
            swap_double( val, rval->ncon);
        }
    }
    if( nam)
    {
        fseek( ifile, 84L * 3L, SEEK_SET);   /* just after the 3 'title' lines */
        for( i = 0; i < (int)rval->ncon; i++)
            fread( nam[i], 6, 1, ifile);
    }
    /* the file gets closed in jpl_close_ephemeris */
    return( rval);
}
Ejemplo n.º 19
0
/*****************************************************************************
**                        jpl_state(ephem,et2,list,pv,nut,bary)             **
******************************************************************************
** This subroutine reads and interpolates the jpl planetary ephemeris file  **
**                                                                          **
**    Calling sequence parameters:                                          **
**                                                                          **
**    Input:                                                                **
**                                                                          **
**        et2[] double, 2-element JED epoch at which interpolation          **
**              is wanted.  Any combination of et2[0]+et2[1] which falls    **
**              within the time span on the file is a permissible epoch.    **
**                                                                          **
**               a. for ease in programming, the user may put the           **
**                  entire epoch in et2[0] and set et2[1]=0.0               **
**                                                                          **
**               b. for maximum interpolation accuracy, set et2[0] =        **
**                  the most recent midnight at or before interpolation     **
**                  epoch and set et2[1] = fractional part of a day         **
**                  elapsed between et2[0] and epoch.                       **
**                                                                          **
**               c. as an alternative, it may prove convenient to set       **
**                  et2[0] = some fixed epoch, such as start of integration,**
**                  and et2[1] = elapsed interval between then and epoch.   **
**                                                                          **
**       list   12-element integer array specifying what interpolation      **
**              is wanted for each of the "bodies" on the file.             **
**                                                                          **
**                        list[i]=0, no interpolation for body i            **
**                               =1, position only                          **
**                               =2, position and velocity                  **
**                                                                          **
**              the designation of the astronomical bodies by i is:         **
**                                                                          **
**                        i = 0: mercury                                    **
**                          = 1: venus                                      **
**                          = 2: earth-moon barycenter                      **
**                          = 3: mars                                       **
**                          = 4: jupiter                                    **
**                          = 5: saturn                                     **
**                          = 6: uranus                                     **
**                          = 7: neptune                                    **
**                          = 8: pluto                                      **
**                          = 9: geocentric moon                            **
**                          =10: nutations in longitude and obliquity       **
**                          =11: lunar librations (if on file)              **
**                                                                          **
**    output:                                                               **
**                                                                          **
**    pv[][6]   double array that will contain requested interpolated       **
**              quantities.  The body specified by list[i] will have its    **
**              state in the array starting at pv[i][0]  (on any given      **
**              call, only those words in 'pv' which are affected by the    **
**              first 10 'list' entries (and by list(11) if librations are  **
**              on the file) are set.  The rest of the 'pv' array           **
**              is untouched.)  The order of components in pv[][] is:       **
**              pv[][0]=x,....pv[][5]=dz.                                   **
**                                                                          **
**              All output vectors are referenced to the earth mean         **
**              equator and equinox of epoch. The moon state is always      **
**              geocentric; the other nine states are either heliocentric   **
**              or solar-system barycentric, depending on the setting of    **
**              global variables (see below).                               **
**                                                                          **
**              Lunar librations, if on file, are put into pv[10][k] if     **
**              list[11] is 1 or 2.                                         **
**                                                                          **
**        nut   dp 4-word array that will contain nutations and rates,      **
**              depending on the setting of list[10].  the order of         **
**              quantities in nut is:                                       **
**                                                                          **
**                       d psi  (nutation in longitude)                     **
**                       d epsilon (nutation in obliquity)                  **
**                       d psi dot                                          **
**                       d epsilon dot                                      **
**                                                                          **
*****************************************************************************/
int DLL_FUNC jpl_state( void *ephem, const double et[2], const int list[12],
                        double pv[][6], double nut[4], const int bary)
{
    struct jpl_eph_data *eph = (struct jpl_eph_data *)ephem;
    int i,j, n_intervals;
    JPLlong nr;
    double prev_midnight, time_of_day;
    double *buf = eph->cache;
    double t[2],aufac;
    struct interpolation_info *iinfo = (struct interpolation_info *)eph->iinfo;


    /*  ********** main entry point **********  */
    if (et[1] >= 0.5)
    {
        prev_midnight = et[0] + 0.5;
        time_of_day   = et[1] - 0.5;
    }
    else
    {
        prev_midnight = et[0] - 0.5;
        time_of_day   = et[1] + 0.5;
    }
    /*  s=et[0] - 0.5;
        prev_midnight = floor( s); */
    /*  time_of_day = s - prev_midnight; */
    /*   prev_midnight += 0.5; */


    /* here prev_midnight contains last midnight before epoch desired (in JED: *.5)
       and time_of_day contains the remaining, fractional part of the epoch    */

    /*   error return for epoch out of range  */

    if( et[0] < eph->ephem_start || et[0] > eph->ephem_end)
        return( -1);

    /*   calculate record # and relative time in interval   */

    nr = (JPLlong)((prev_midnight-eph->ephem_start)/eph->ephem_step)+2;
    /* add 2 to adjus for the first two records containing header data */
    if( prev_midnight == eph->ephem_end)
        nr--;
    t[0]=( prev_midnight-( (1.0*nr-2.0)*eph->ephem_step+eph->ephem_start) +
           time_of_day )/eph->ephem_step;

    /*   read correct record if not in core (static vector buf[])   */

    if( nr != eph->curr_cache_loc)
    {
        eph->curr_cache_loc = nr;
        fseek( eph->ifile, nr * eph->recsize, SEEK_SET);
        fread( buf, (size_t)eph->ncoeff, sizeof( double), eph->ifile);
        if( eph->swap_bytes)
            swap_double( buf, eph->ncoeff);
    }
    t[1] = eph->ephem_step;
    aufac = 1.0 / eph->au;

    for( n_intervals = 1; n_intervals <= 8; n_intervals *= 2)
        for( i = 0; i < 11; i++)
            if( n_intervals == eph->ipt[i][2] && (list[i] || i == 10))
            {
                int flag = ((i == 10) ? 2 : list[i]);
                double *dest = ((i == 10) ? eph->pvsun : pv[i]);

                interp( iinfo, &buf[eph->ipt[i][0]-1], t, (int)eph->ipt[i][1], 3,
                        n_intervals, flag, dest);
                /* gotta convert units */
                for( j = 0; j < flag * 3; j++)
                    dest[j] *= aufac;
            }

    if( !bary)                             /* gotta correct everybody for */
        for( i = 0; i < 9; i++)            /* the solar system barycenter */
            for( j = 0; j < list[i] * 3; j++)
                pv[i][j] -= eph->pvsun[j];

    /*  do nutations if requested (and if on file)    */

    if(list[10] > 0 && eph->ipt[11][1] > 0)
        interp( iinfo, &buf[eph->ipt[11][0]-1], t, (int)eph->ipt[11][1], 2,
                (int)eph->ipt[11][2], list[10], nut);

    /*  get librations if requested (and if on file)    */

    if(list[11] > 0 && eph->ipt[12][1] > 0)
    {
        double pefau[6];

        interp( iinfo, &buf[eph->ipt[12][0]-1], t, (int)eph->ipt[12][1], 3,
                (int)eph->ipt[12][2], list[11], pefau);
        for( j = 0; j < 6; ++j) pv[10][j]=pefau[j];
    }
    return( 0);
}
Ejemplo n.º 20
0
void control_output(void)
{
	Str_out_point *outs;
	U8_T point = 0;
	U32_T val;
//	U8_T loop;
	U32_T value;
	point = 0;
	outs = outputs;

	
	
	while( point < MAX_OUTS )
	{	

		if(point < get_max_output())
		{
			
#ifdef ASIX_CON
			if(point < get_max_internal_output())
			{		
				outs->sub_id = 0;
				outs->sub_product = 0;
				outs->sub_number = 0;
				outs->decom = 0;
			}
			else
			{
				outs->switch_status = 2/*SW_AUTO*/;
			}
#endif	

#ifdef ARM_CON
			outs->decom = 0;
#endif			
			if( outs->range == not_used_output )
			{
				outs->value = 0L;
				val = 0;
			}
			else
			{	
				if(outs->switch_status == 0/*SW_OFF*/)
				{
					outs->value = 0L;
					outs->control = 0;
					//output_raw[point] = 0;
					set_output_raw(point,0);
				}
				else if(outs->switch_status == 2/*SW_HAND*/)
				{
					set_output_raw(point,1000);//output_raw[point] = 1000;
					outs->control = 1;
					switch( outs->range )
					{
						case V0_10:	
							outs->value = swap_double(10000);		
							break;
						case P0_100_Open:
						case P0_100_Close:
						case P0_100:
						case P0_100_PWM:	
							outs->value = swap_double(100000);
							break;
						case P0_20psi:
						case I_0_20ma:
							outs->value = swap_double(20000);
							break;
						default:
							val = 0;
							break; 
					 }
				}
				else
				{
					if( outs->digital_analog == 0 ) // digital_analog 0=digital 1=analog
					{ // digtal input range 
						 if( outs->range >= OFF_ON && outs->range <= LOW_HIGH )
							if( outs->control ) val = 1000;
							else 
								val = 0;
						if( outs->range >= ON_OFF && outs->range <= HIGH_LOW )
							if( outs->control ) val = 0;
							else 
								val = 1000;
						if( outs->range >= custom_digital1 && outs->range <= custom_digital8 ) 
							if( outs->control ) val = 1000;
							else 
								val = 0;
						
					  set_output_raw(point,val);//output_raw[point] = val;					

						outs->value = swap_double(val);	
						
					}
					else if( outs->digital_analog == 1 ) //  analog
					{	
#ifdef ASIX_CON						
						if(point < get_max_internal_output())  // internal output
#endif
						{
							value = swap_double(outs->value);
							val = value;
							switch( outs->range )
							{
								case V0_10:	
									//outs->count = 10;												
									set_output_raw(point, value * 100 / 1000);//output_raw[point] = value * 100 / 1000;
									break;
								case P0_100_Open:
								case P0_100_Close:
								case P0_100:
								case P0_100_PWM:
									//outs->count = 100;
									set_output_raw(point, value * 10 / 1000);//output_raw[point] = value * 10 / 1000;
								/*	if( outs->m_del_low < outs->s_del_high )
									{
										delta = outs->s_del_high - outs->m_del_low;
										value *= delta;
										value += (long)( outs->m_del_low * 100000L );
									}
									else
									{
										delta =  outs->m_del_low - outs->s_del_high;
										value *= delta;
										value += (long)( outs->s_del_high * 100000L );
									}
									val = (Byte)( value * 213 / 10000000L );*/
									break;
								case P0_20psi:
								case I_0_20ma:
									//outs->count = 20;
									set_output_raw(point, value * 50 / 1000);//output_raw[point] = value * 50 / 1000;
									break;
								
								default:
									val = 0;
									break; 
							 }

//#if MINI						
//						 if(flag_output == ADJUST_AUTO)
//						 {
//							  if(output_raw_back[point] != output_raw[point])
//								{
//									output_raw_back[point] = output_raw[point];
//									AO_auto[point] = output_raw[point];
//								}
//						}
//#endif

							 outs->value = swap_double(val);	
						}
#ifdef ASIX_CON
						else// external ouput 
						{  // range is 0-10v
							if(outs->read_remote == 1)
							{
								val = 10000000 / 4095;
								val = val * get_output_raw(point) / 1000;
								outs->read_remote = 0;
							}
							else
							{		
								val = swap_double(outs->value);	
								val = val * 4095 / 10000;
								// ?????????
								if(val < get_output_raw(point))
								{
									if(get_output_raw(point) - val == 1)
										set_output_raw(point,val + 1);//output_raw[point] = val + 1;
									if(get_output_raw(point) - val == 2)
										set_output_raw(point,val + 2);//output_raw[point] = val + 2;
								}
								else
									set_output_raw(point,val);//output_raw[point] = val;
							}
						}
#endif
					}
				}
			}
#ifdef ASIX_CON
			map_extern_output(point);
#endif

		}
		else
		{
			outs->sub_id = 0;
			outs->sub_product = 0;
			outs->sub_number = 0;
			
			outs->decom = 1;  // no used
		}
		point++;
		outs++;
				
	}	

}
/**
 * Compute transient reachability probabilities in nonuniform CTMDPs.
 *
 * @param ctmdp CTMDP to compute probabilities for
 * @param rates vector of different rates occuring in CTMDP
 * @param num_rates size of rates vector
 * @param choices_to_rates maps choice numbers to corresponding rate index
 * @param k_bound maximal cardinality to consider
 * @
 */
static double *ctmdpi_iterate
(const NDSparseMatrix *ctmdp, const double *rates, const unsigned num_rates,
 const unsigned *choices_to_rates, const unsigned k_bound, const bitset *B,
 const double time_bound, const BOOL min)
{
	double *probs_k;
	double *probs_km1;
	unsigned state_nr;
	double li;
	unsigned prob_nr;
	unsigned vec_nr;
	unsigned num_k_vecs;
	unsigned num_km1_vecs;
	unsigned *rates_quant;
	unsigned *all_k_rates_quant;
	unsigned *all_km1_rates_quant;
	unsigned k;
	const unsigned num_states = (unsigned) ctmdp->n;
	const unsigned max_entries = multiset_coeff(num_rates, k_bound);
	unsigned succ_nr;
	unsigned choice_nr;
	double choice_prob;
	double succ_prob;
	unsigned succ_vec_nr;
	const unsigned *row_starts = (unsigned *) ctmdp->row_counts;
	const unsigned *choice_starts = (unsigned *) ctmdp->choice_counts;
	unsigned rate_nr;
	double *non_zeros = ctmdp->non_zeros;
	hypoexp_t *hypoexp;
	unsigned *rate_to_succ_vec_nr;

	probs_k = malloc(max_entries * num_states * sizeof(double));
	probs_km1 = malloc(max_entries * num_states * sizeof(double));
	all_k_rates_quant = malloc(max_entries * num_rates * sizeof(unsigned));
	all_km1_rates_quant = malloc(max_entries * num_rates * sizeof(unsigned));
	enumerate_k_vectors(num_rates, k_bound, all_k_rates_quant, &num_k_vecs);
	hypoexp = init_hypoexp(k_bound, rates, num_rates, time_bound);
	rate_to_succ_vec_nr = malloc(num_rates * sizeof(unsigned));

	compute_k_bound_probs(all_k_rates_quant, num_k_vecs, num_rates,
			      hypoexp, k_bound, num_states, B, probs_k);

	for (k = k_bound; k > 0; k--) {
		enumerate_k_vectors(num_rates, k - 1, all_km1_rates_quant, &num_km1_vecs);
		prob_nr = 0;
		for (vec_nr = 0; vec_nr < num_km1_vecs; vec_nr++) {
			rates_quant = get_ith_vec(all_km1_rates_quant, vec_nr, num_rates);
			li = hypoexp_cumulate(rates_quant, k - 1, hypoexp);
			for (rate_nr = 0; rate_nr < num_rates; rate_nr++) {
				rates_quant[rate_nr] += 1;
				succ_vec_nr = vector_to_number
						(rates_quant, all_k_rates_quant, num_rates, 0, num_k_vecs-1);
				rates_quant[rate_nr] -= 1;
				rate_to_succ_vec_nr[rate_nr] = succ_vec_nr;
			}

			for (state_nr = 0; state_nr < num_states; state_nr++) {
				if (get_bit_val(B, state_nr)) {
					probs_km1[prob_nr] = li;
				} else {
					unsigned state_start = row_starts[state_nr];
					unsigned state_end = row_starts[state_nr + 1];
					double opt_choice_prob = min ? 2.0 : -1.0;
					for (choice_nr = state_start; choice_nr < state_end; choice_nr++) {
						unsigned choice_start = choice_starts[choice_nr];
						unsigned choice_end = choice_starts[choice_nr + 1];
						choice_prob = 0.0;
						rate_nr = choices_to_rates[choice_nr];
						succ_vec_nr = rate_to_succ_vec_nr[rate_nr];
						for (succ_nr = choice_start; succ_nr < choice_end; succ_nr++) {
							succ_prob = probs_k[succ_vec_nr * num_states + (ctmdp->cols)[succ_nr]];
							choice_prob += non_zeros[succ_nr] * succ_prob;
						}
						opt_choice_prob = optimum(min, choice_prob, opt_choice_prob);
					}
					if (state_start == state_end) {
						opt_choice_prob = 0.0;
					}
					probs_km1[prob_nr] = opt_choice_prob;
				}
				prob_nr++;
			}
		}
		swap_double(&probs_k, &probs_km1);
		swap_unsigned(&all_k_rates_quant, &all_km1_rates_quant);
		num_k_vecs = num_km1_vecs;
	}

	free_hypoexp(hypoexp);
	free(probs_km1);
	free(all_k_rates_quant);
	free(all_km1_rates_quant);
	free(rate_to_succ_vec_nr);

	return probs_k;
}