https://gitlab.inria.fr/cado-nfs/cado-nfs
Raw File
Tip revision: b0795d85dd65d5365c3308ae1a2966403bb7878a authored by Pierrick Gaudry on 14 February 2013, 14:48:36 UTC
at work here
Tip revision: b0795d8
sparse.c
/* 
 * Program: history
 * Author : F. Morain
 * Purpose: managing history of merges
 * 
 * Algorithm:
 *
 */


#include "cado.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "macros.h"
#include "sparse.h"

#define DEBUG 0

void
fprintRow(FILE *file, typerow_t *row)
{
    int i;
#ifdef FOR_FFS
    fprintf(file, "[%d]", row[0].id);
    for(i = 1; i <= row[0].id; i++)
        fprintf(file, " %d(%d)", row[i].id, row[i].e);
#else
    fprintf(file, "[%d]", row[0]);
    for(i = 1; i <= row[0]; i++)
        fprintf(file, " %d", row[i]);
#endif
}

// row[0..row[0]] is of lenfth row[0]+1.
int32_t*
copyRow(int32_t *row)
{
    int32_t *tmp = (int32_t *)malloc((1+row[0]) * sizeof(int32_t));
    
    memcpy(tmp, row, (1+row[0]) * sizeof(int32_t));
    return tmp;
}

// i1 += i2
// A row is row[0..max] where row[0] = max and the real components are
// row[1..max].
// If len != -1, then it is the real length of row[i1]+row[i2].
void
addRows(typerow_t **rows, int i1, int i2, MAYBE_UNUSED int32_t j)
{
    int32_t k1, k2, k, len;
    typerow_t *tmp;

    ASSERT(rows[i1] != NULL);
    ASSERT(rows[i2] != NULL);
#if DEBUG >= 1
    fprintf(stderr, "R[%d] =", i1); fprintRow(stderr, rows[i1]); 
    fprintf(stderr, "\n");
    fprintf(stderr, "R[%d] =", i2); fprintRow(stderr, rows[i2]);
    fprintf(stderr, "\n");
#endif
    len = 1 + rowLength(rows, i1) + rowLength(rows, i2);
    tmp = (typerow_t *)malloc(len * sizeof(typerow_t));
    k = k1 = k2 = 1;

#ifdef FOR_FFS /* look for the exponents of j in i1 i2*/
    int e1 = 0, e2 = 0;
    int d;
    int l;
    for (l = 1 ; l <= rowLength(rows, i1) ; l++)
        if (rowCell(rows, i1, l) == j)
            e1 = rows[i1][l].e;
    for (l = 1 ; l <= rowLength(rows, i2) ; l++)
        if (rowCell(rows, i2, l) == j)
            e2 = rows[i2][l].e;

    ASSERT (e1 != 0 && e2 != 0);

    d  = (int) gcd_int64 ((int64_t) e1, (int64_t) e2);
    e1 /= -d;
    e2 /= d;

    for (l = 1 ; l <= rowLength(rows, i2) ; l++)
        rows[i2][l].e *= e1;
    for (l = 1 ; l <= rowLength(rows, i1) ; l++)
        rows[i1][l].e *= e2;

#if DEBUG >= 1
    fprintf (stdout, "Computing %d*rows[%d] + %d*rows[%d] for j=%d\n", 
                      e2, i1, e1, i2, j);
#endif

#endif


    // loop while everybody is here
    while((k1 <= rowLength(rows, i1)) && (k2 <= rowLength(rows, i2))){
        if(rowCell(rows, i1, k1) < rowCell(rows, i2, k2))
            tmp[k++] = rows[i1][k1++];
        else if(rowCell(rows, i1, k1) > rowCell(rows, i2, k2))
            tmp[k++] = rows[i2][k2++];
        else{
#ifdef FOR_FFS
            if (rows[i1][k1].e + rows[i2][k2].e != 0)
            {
                tmp[k].id = rows[i1][k1].id;
                tmp[k++].e = rows[i1][k1].e + rows[i2][k2].e;
            }
#else
#if DEBUG >= 1
            fprintf(stderr, "WARNING: j1=j2=%d in addRows\n", k1);
#endif
#endif
            k1++;
            k2++;
        }
    }
    // finish with k1
    for( ; k1 <= rowLength(rows, i1); k1++)
	tmp[k++] = rows[i1][k1];
    // finish with k2
    for( ; k2 <= rowLength(rows, i2); k2++)
	tmp[k++] = rows[i2][k2];
    ASSERT(k <= len);
    // copy back
    free(rows[i1]);
        /* FIXME: why not use realloc here instead? Since k <= len,
           it suffices to shrink the tmp[] array to k entries.
           Also, we might detect the special case k = len. */
#if 0
	int *tmp2 = (int32_t *)malloc(k * sizeof(int32_t));
	memcpy(tmp2, tmp, k * sizeof(int32_t));
	tmp2[0] = k-1;
	rows[i1] = tmp2;
	free(tmp);
#else
#ifdef FOR_FFS
        tmp[0].id = k-1;
#else
        tmp[0] = k-1;
#endif
	if(k == len)
	    rows[i1] = tmp;
	else
	    rows[i1] = realloc(tmp, k * sizeof(typerow_t));
#ifdef FOR_FFS
    /* restore old coeff for row i2 */
    for (l = 1 ; l <= rowLength(rows, i2) ; l++)
        rows[i2][l].e /= e1;
#endif
#endif
#if DEBUG >= 1
    fprintf(stderr, "row[%d]+row[%d] =", i1, i2);
    fprintRow(stderr, rows[i1]); fprintf(stderr, "\n");
#endif
}

void
removeWeight(int32_t **rows, int *wt, int i)
{
    int32_t k;

    for(k = 1; k <= rows[i][0]; k++)
	wt[rows[i][k]]--;
}

int
hasCol(int32_t **rows, int i, int32_t j)
{
    int32_t k;

    for(k = 1; k <= rows[i][0]; k++)
	if(rows[i][k] == j)
	    return 1;
    return 0;
}

int 
cmp (const void *p, const void *q)
{
  int x = *((int *)p);
  int y = *((int *)q);
  return (x <= y ? -1 : 1);
}

// A line is "[-]i i1 ... ik [#j]"
int parse_hisfile_line (int32_t *ind, char *t, int32_t *j)
{
  int ni = 0, sg = 1;

  if(*t == '-')
    {
      sg = -1;
	    t++;
    }

  ind[0] = 0;
  while(1)
    {
      if((*t == '\n') || (*t == '#'))
          break;
      else if (*t == ' ')
        {
          ni++;
          ind[ni] = 0;
        }
	    else
          ind[ni] = 10 * ind[ni] + (*t - '0');

	    t++;
    }

  ind[0] = sg * ind[0];
  *j=0;

  if (*t == '#')
      for (t++ ; (*t != '\n') ; t++)
          *j = 10 * (*j) + (*t - '0');
  else
    {
      ni++;
      *j = -1;
    }

  return ni;
}
back to top