コード例 #1
0
ファイル: social_reg.c プロジェクト: GHamrouni/Recommender
/*
 * Stochastic gradient descent
 */
struct learned_factors*
learn_social (learning_algorithm_params_t* learning_param)
{
	struct training_set* tset = learning_param->tset;
	struct model_parameters params = learning_param->params;
	struct learned_factors* lfactors = init_learned_factors (&params);
	sparse_matrix_t * social_matrix = learning_param->social_matrix;

	if (!lfactors)
	{
		return NULL;
	}

	lfactors->dimensionality = params.dimensionality;
	lfactors->items_number = params.items_number;
	lfactors->users_number = params.users_number;

	if (tset->ratings_matrix)
	{
		calculate_average_ratings (tset, lfactors);

		free_sparse_matrix (tset->ratings_matrix);
		tset->ratings_matrix = NULL;
	}

	update_learned_factors_social (lfactors, tset, social_matrix, &params);

	return lfactors;
}
コード例 #2
0
ファイル: ep2.c プロジェクト: GustavoCayres/MAC300_EP2
void free_sparse_matrix(sparse_matrix sp){
	sparse_matrix down;
	if(sp != NULL){
		down = sp->down;
		free_right(sp->right);
		free(sp);
		free_sparse_matrix(down);
	}
}
コード例 #3
0
ファイル: sparse_matrix.c プロジェクト: davidjulien/ouroboros
int main()
{
    t_sm_line line = EMPTY_SM_LINE;
    t_sparse_matrix sm;


    display_line_nl(line);

    sm_line_set_value(&line, 5, 17);
    display_line_nl(line);

    sm_line_set_value(&line, 3, 27);
    display_line_nl(line);

    sm_line_set_value(&line, 7, 14);
    display_line_nl(line);

    sm_line_set_value(&line, 7, 27);
    display_line_nl(line);

    sm_line_set_value(&line, 3, 23);
    display_line_nl(line);

    sm_line_set_value(&line, 5, 25);
    display_line_nl(line);

    printf("%u\n", sm_line_get_value(line, 3));
    printf("%u\n", sm_line_get_value(line, 4));
    printf("%u\n", sm_line_get_value(line, 5));
    printf("%u\n", sm_line_get_value(line, 9));

    free_line(&line);


    printf("TEST SM\n");

    sm = new_sparse_matrix(20);

    printf("%u\n\n", sm_get_value(sm, 5, 10));

    sm_set_value(sm, 5, 10, 14);
    printf("%u\n", sm_get_value(sm, 5, 10));
    printf("%u\n\n", sm_get_value(sm, 5, 12));

    sm_set_value(sm, 5, 12, 15);
    sm_set_value(sm, 5, 8, 13);
    printf("%u\n", sm_get_value(sm, 5, 8));
    printf("%u\n", sm_get_value(sm, 5, 10));
    printf("%u\n", sm_get_value(sm, 5, 11));
    printf("%u\n", sm_get_value(sm, 5, 12));

    free_sparse_matrix(&sm);

    return 0;
}
コード例 #4
0
ファイル: ep2.c プロジェクト: GustavoCayres/MAC300_EP2
int main() {
	char file_name[100];
	FILE *file;
	sparse_matrix A;
	double *b;
	double duration, aux;
	int n, i, j, k;
	clock_t start, end;
 
	printf("Nome do Arquivo: ");
	scanf("%s", file_name);
	file = fopen(file_name, "r");

	/* Reading file */
	if (file == NULL) {
		fprintf(stderr, "Não foi possível abrir o arquivo!\n");
		return -1;
	}

	fscanf(file, "%d", &n);
	create_matrix(&A);
	b = malloc(n*sizeof(double));

	for (k = 0; k < n*n; k ++) {
		fscanf(file, "%d %d", &i, &j);
		fscanf(file, "%lf", &aux);
		if(aux != 0)
			insert(A, i, j, aux);
	}
	for (k= 0; k < n; k ++) {
		fscanf(file, "%d", &i);
		fscanf(file, "%lf", &b[i]);
	}
	printf("Matriz foi lida com sucesso.\n");
	start = clock();
	conjugate_gradient(A, b, n);
	end = clock();
	duration = (double)(end - start) / CLOCKS_PER_SEC;
	printf("Tempo de resolução por Gradientes Conjugados: %e segundos\n", duration);
        
        /* test */
	for (i = 0; i < n; i ++) {
		if (b[i] - (1 + i%(n/100)) > 1e-5 || b[i] - (1 + i%(n/100)) < -1e-5)
			printf("Erro! %e  %d %d\n", b[i], (1 + i%(n/100)), i);
	}
	fclose(file);
	printf("Fim da Análise!\n");
	free_sparse_matrix(A);
	free(b);
	return 0;
}
コード例 #5
0
int main(){
  clock_t begin, end;
  double time_spent;
  begin = clock();

  matrix* Q = create_matrix(4, 4);
  value Q_arr[16] = {1, 0, 1, 0,
		     0, 2, 0, 1,
		     1, 0, 2, 0,
		     0, 1, 0, 1};
  insert_array(Q_arr, Q);

  sparse_matrix* s_Q = create_sparse_matrix(Q, 8);

  matrix* q = create_matrix(4, 1);
  value q_arr[4] = {3,
		    20,
		    5,
		    15};
  insert_array(q_arr, q);

  matrix* expected = create_matrix(4, 1);
  value e_arr[4] = {1,
                    5,
                    2,
                    10};
  insert_array(e_arr, expected);

  matrix* x = create_zero_matrix(4, 1);


  conjugate_gradient(s_Q, x, q);

  assert(compare_matrices(x, expected));

  free_matrix(Q);
  free_matrix(q);
  free_matrix(x);
  free_matrix(expected);
  free_sparse_matrix(s_Q);


  end = clock(); 
  time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
  printf("time taken was: %f \n", time_spent);

}
コード例 #6
0
int main(int argc, char *argv[])
{
    struct sparse_matrix_t *sparseA;
    struct vector_t *d;         /* density */
    int c;
    double accu;
    struct sparse_item_t *item;

    /* cmd line arg */
    char *matrix_filename = NULL;
    char *sol_filename = NULL;

    if (argc != 3) {
        fprintf(stderr, "%s matrixfile kernel_density_file\n", argv[0]);
        exit(1);
    }
    matrix_filename = strdup(argv[1]);
    sol_filename = strdup(argv[2]);

    /* read the sparse matrix */
    sparseA = read_ijk_sparse_matrix(matrix_filename, SPARSE_COL_LINK);
    fprintf(stderr, "read*matrix: ok (size=%ldx%ld, %ld elements)\n",
            sparseA->nb_line, sparseA->nb_col,
            sparseA->nb_line * sparseA->nb_col);
    show_sparse_stats(sparseA);

    /* allocation */
    d = new_vector(sparseA->nb_col);

    fprintf(stderr, "Starting kernel density computation ...\n");
    for (c = 0; c < sparseA->nb_col; c++) {
        item = sparseA->col[c];
        accu = 0.;
        while (item) {
            accu = accu + item->val;
            item = item->next_in_col;
        }
        d->mat[c] = accu;
    }
    write_vector((struct vector_t *) d, sol_filename);
    free_sparse_matrix(sparseA);
    /* free b, rhs */
    return (1);
}
コード例 #7
0
ファイル: matrix.c プロジェクト: ederc/gb
ri_t reduce_gbla_matrix_keep_A(mat_t *mat, int verbose, int nthreads)
{
  /*  timing structs */
  struct timeval t_load_start;
  struct timeval t_complete;

  if (verbose > 2)
    gettimeofday(&t_complete, NULL);
  /* A^-1 * B */
  if (verbose > 2) {
    printf("---------------------------------------------------------------------------\n");
    printf("GBLA Matrix Reduction\n");
    printf("---------------------------------------------------------------------------\n");
    gettimeofday(&t_load_start, NULL);
    printf("%-38s","Storing A in C ...");
    fflush(stdout);
  }

  if (mat->AR->row != NULL) {
    if (elim_fl_C_sparse_dense_keep_A(mat->CR, &(mat->AR), mat->mod, nthreads)) {
      printf("Error while reducing A.\n");
      return 1;
    }
  }
  if (verbose > 2) {
    printf("%9.3f sec\n",
        walltime(t_load_start) / (1000000));
  }
  if (verbose > 3) {
    print_mem_usage();
  }
  /* reducing submatrix C to zero using methods of Faugère & Lachartre */
  if (verbose > 2) {
    gettimeofday(&t_load_start, NULL);
    printf("%-38s","Copying C to sparse block representation ...");
    fflush(stdout);
  }
  if (mat->CR->row != NULL) {
    mat->C  = copy_sparse_to_block_matrix(mat->CR, nthreads);
    free_sparse_matrix(&(mat->CR), nthreads);
  }
  if (verbose > 2) {
    printf("%9.3f sec\n",
        walltime(t_load_start) / (1000000));
  }
  if (verbose > 3) {
    print_mem_usage();
  }
  if (verbose > 2) {
    printf("%-38s","Reducing C to zero ...");
    fflush(stdout);
  }
  if (mat->C != NULL) {
    if (elim_fl_C_sparse_dense_block(mat->B, &(mat->C), mat->D, mat->mod, nthreads)) {
      printf("Error while reducing A.\n");
      return 1;
    }
  }
  if (verbose > 2) {
    printf("%9.3f sec\n",
        walltime(t_load_start) / (1000000));
  }
  if (verbose > 3) {
    print_mem_usage();
  }
  /* copy block D to dense wide (re_l_t) representation */
  mat->DR = copy_block_to_dense_matrix(&(mat->D), nthreads, 1);
  mat->DR->mod  = mat->mod;

  /* eliminate mat->DR using a structured Gaussian Elimination process on the rows */
  nelts_t rank_D = 0;
  /* echelonizing D to zero using methods of Faugère & Lachartre */
  if (verbose > 2) {
    gettimeofday(&t_load_start, NULL);
    printf("%-38s","Reducing D ...");
    fflush(stdout);
  }
  if (mat->DR->nrows > 0)
    /* rank_D = elim_fl_dense_D(mat->DR, nthreads); */
    rank_D = elim_fl_dense_D_completely(mat->DR, nthreads);
  if (verbose > 2) {
    printf("%9.3f sec %5d %5d %5d\n",
        walltime(t_load_start) / (1000000), rank_D, mat->DR->nrows - rank_D, mat->DR->nrows);
  }
  if (verbose > 3) {
    print_mem_usage();
  }
  if (verbose > 2) {
    printf("---------------------------------------------------------------------------\n");
    printf("%-38s","Reduction completed ...");
    fflush(stdout);
    printf("%9.3f sec\n",
        walltime(t_complete) / (1000000));
    if (verbose > 3)
      print_mem_usage();
  }

  return rank_D;
}
コード例 #8
0
ファイル: rse.c プロジェクト: marcopovitch/lsqrsolve
int main(int argc, char *argv[])
{
    struct matrix_t *matrixA;
    struct sparse_matrix_t *sparseA;
    struct vector_t *x, *b;

    lsqr_input *input;
    lsqr_output *output;
    lsqr_work *work;            /* zone temoraire de travail */
    lsqr_func *func;            /* func->mat_vec_prod -> APROD */

    /* cmd line arg */
    char *matrix_filename = NULL;
    char *vector_filename = NULL;
    char *sol_filename = NULL;
    int max_iter = -1;
    float damping = 0;

    if (argc != 4) {
        fprintf(stderr, "%s matrixfile vectorfile solutionfile\n",
                argv[0]);
        exit(1);
    }
    matrix_filename = strdup(argv[1]);
    vector_filename = strdup(argv[2]);
    sol_filename = strdup(argv[3]);

    /* read the  matrix */
    matrixA = read_matrix(matrix_filename);
    fprintf(stderr, "read*matrix: ok (size=%ldx%ld, %ld elements)\n",
            matrixA->nb_line, matrixA->nb_col,
            matrixA->nb_line * matrixA->nb_col);

    sparseA = sparsify(matrixA, SPARSE_COL_LINK);
    b = read_simple_vector(vector_filename);

        /*************************************************/
    /* check compatibility between matrix and vector */

        /*************************************************/
    if (sparseA->nb_line != b->length) {
        fprintf(stderr,
                "Error, check your matrix/vector sizes (%ld/%ld)\n",
                sparseA->nb_line, b->length);
        exit(1);
    }
    /* init vector solution to zero */
    x = new_vector(sparseA->nb_col);

    /* catch Ctrl-C signal */
    signal(SIGINT, emergency_halt);

        /*************************************************************/
    /* solve A.x = B                                             */

        /*************************************************************/

    /* LSQR alloc */
    alloc_lsqr_mem(&input, &output, &work, &func,
                   sparseA->nb_line, sparseA->nb_col);

    fprintf(stderr, "alloc_lsqr_mem : ok\n");

    /* defines the routine Mat.Vect to use */
    func->mat_vec_prod = sparseMATRIXxVECTOR;

    /* Set the input parameters for LSQR */
    input->num_rows = sparseA->nb_line;
    input->num_cols = sparseA->nb_col;
    input->rel_mat_err = .0;
    input->rel_rhs_err = .0;
    input->cond_lim = .0;
    input->lsqr_fp_out = stdout;
    input->rhs_vec = (dvec *) b;
    input->sol_vec = (dvec *) x;        /* initial guess */
    input->damp_val = damping;
    if (max_iter == -1) {
        input->max_iter = 4 * (sparseA->nb_col);
    } else {
        input->max_iter = max_iter;
    }

    /* resolution du systeme Ax=b */
    lsqr(input, output, work, func, sparseA);
    write_vector((struct vector_t *) output->sol_vec, sol_filename);
    free_lsqr_mem(input, output, work, func);
    free_matrix(matrixA);

    /* check A^t.A */
    /*
     * { struct sparse_matrix_t *AtA; AtA = AtransA (sparseA);
     * write_sparse_matrix(AtA, "AtA"); write_sparse_matrix(sparseA,
     * "A"); free_sparse_matrix (AtA);
     * 
     * } */

    free_sparse_matrix(sparseA);
    return (1);
}
コード例 #9
0
ファイル: tomo.c プロジェクト: marcopovitch/lsqrsolve
int main(int argc, char *argv[])
{
    struct sparse_matrix_t *sparseA = NULL;
    struct vector_t *b = NULL;
    struct vector_t *x;
    struct mesh_t *mesh;
    char *xml_output;

    long int *compress2fat = NULL;
    struct vector_t *solution;
    struct vector_t *std_error_sol;
    long int fat_sol_nb_col;

    lsqr_input *input;
    lsqr_output *output;
    lsqr_work *work;            /* zone temoraire de travail */
    lsqr_func *func;            /* func->mat_vec_prod -> APROD */

    /* cmd line arg */
    char *mesh_filename = NULL;
    char *importfilename = NULL;
    char *output_filename = NULL;
    char *sol_error_filename = NULL;
    char *log_filename = NULL;
    char *output_type = NULL;
    int max_iter;
    double damping, grad_damping;
    int use_ach = 0;            /* ACH : tele-seismic inversion tomography */
    int check_sparse = 0;       /* check sparse matrix disable by default  */

    /* velocity model */
    char *vmodel = NULL;
    struct velocity_model_t *vm = NULL;

    struct mesh_t **imported_mesh = NULL;
    char **xmlfilelist = NULL;
    int nb_xmlfile = 0;

    int i, j;

    int nb_irm = 0;
    struct irm_t **irm = NULL;
    int *nb_metacell = NULL;

    FILE *logfd;

    /*************************************************************/
    parse_command_line(argc, argv,
                       &mesh_filename,
                       &vmodel,
                       &importfilename,
                       &log_filename,
                       &output_filename, &output_type,
                       &max_iter,
                       &damping, &grad_damping, &use_ach, &check_sparse);

    if (use_ach) {
        fprintf(stderr, "Using ACH tomographic inversion\n");
    } else {
        fprintf(stderr, "Using STANDARD tomographic inversion\n");
    }

    /* load the velocity model */
    if (vmodel) {
        char *myfile;
        vm = load_velocity_model(vmodel);
        if (!vm) {
            fprintf(stderr, "Can not initialize velocity model '%s'\n",
                    vmodel);
            exit(1);
        }
        myfile = strdup(vmodel);
        fprintf(stderr, "Velocity model '%s' loaded\n", basename(myfile));
        free(myfile);
    } else {
        vm = NULL;
    }

    /* Open log file */
    if (!log_filename) {
        logfd = stdout;
    } else {
        if (!(logfd = fopen(log_filename, "w"))) {
            perror(log_filename);
            exit(1);
        }
    }

    /*check_write_access (output_filename); */

    /**************************************/
    /* test if we can open file to import */
    /**************************************/
    if (importfilename) {
        xmlfilelist = parse_separated_list(importfilename, ",");
        nb_xmlfile = 0;
        while (xmlfilelist[nb_xmlfile]) {
            if (access(xmlfilelist[nb_xmlfile], R_OK) == -1) {
                perror(xmlfilelist[nb_xmlfile]);
                exit(1);
            }
            nb_xmlfile++;
        }
    } else {
        fprintf(stderr, "No file to import ... exiting\n");
        exit(0);
    }

    /****************************/
    /* main mesh initialization */
    /****************************/
    mesh = mesh_init_from_file(mesh_filename);
    if (!mesh) {
        fprintf(stderr, "Error decoding %s.\n", mesh_filename);
        exit(1);
    }
    fprintf(stderr, "read %s ok\n", mesh_filename);

    /*****************************************/
    /* check and initialize slice xml files  */
    /*****************************************/
    if (nb_xmlfile) {
        int nb_sparse = 0;
        int nb_res = 0;
        int f;

        imported_mesh =
            (struct mesh_t **) malloc(sizeof(struct mesh_t *) *
                                      nb_xmlfile);
        assert(imported_mesh);

        for (i = 0; i < nb_xmlfile; i++) {
            imported_mesh[i] = mesh_init_from_file(xmlfilelist[i]);
            if (!imported_mesh[i]) {
                fprintf(stderr, "Error decoding %s.\n", mesh_filename);
                exit(1);
            }
            for (f = 0; f < NB_MESH_FILE_FORMAT; f++) {
                /* mandatory field : res, sparse, and irm if provided */
                if (f == RES || f == SPARSE || f == IRM) {
                    check_files_access(f, imported_mesh[i]->data[f],
                                       xmlfilelist[i]);
                }
            }
            if (imported_mesh[i]->data[SPARSE]) {
                nb_sparse += imported_mesh[i]->data[SPARSE]->ndatafile;
            }

            if (imported_mesh[i]->data[RES]) {
                nb_res += imported_mesh[i]->data[RES]->ndatafile;
            }

            if (imported_mesh[i]->data[IRM]) {
                nb_irm += imported_mesh[i]->data[IRM]->ndatafile;
            }

        }

        if (!nb_sparse || !nb_res) {
            fprintf(stderr, "Error no sparse or res file available !\n");
            exit(0);
        }
    }

    /*********************************************/
    /* read and import the sparse(s) matrix(ces) */
    /*********************************************/
    for (i = 0; i < nb_xmlfile; i++) {
        if (!imported_mesh[i]->data[SPARSE]) {
            continue;
        }

        for (j = 0; j < imported_mesh[i]->data[SPARSE]->ndatafile; j++) {
            sparseA = import_sparse_matrix(sparseA,
                                           imported_mesh[i]->data[SPARSE]->
                                           filename[j]);
        }
    }

    if (check_sparse) {
        if (check_sparse_matrix(sparseA)) {
            exit(1);
        }
    }

    /*sparse_compute_length(sparseA, "length1.txt"); */
    fat_sol_nb_col = sparseA->nb_col;
    show_sparse_stats(sparseA);

    /*********************************************/
    /* read and import the residual time vector  */
    /*********************************************/
    for (i = 0; i < nb_xmlfile; i++) {
        if (!imported_mesh[i]->data[RES]) {
            continue;
        }

        for (j = 0; j < imported_mesh[i]->data[RES]->ndatafile; j++) {
            b = import_vector(b, imported_mesh[i]->data[RES]->filename[j]);
        }
    }

    /*************************************************/
    /* check compatibility between matrix and vector */
    /*************************************************/
    if (sparseA->nb_line != b->length) {
        fprintf(stderr,
                "Error, check your matrix/vector sizes (%ld/%ld)\n",
                sparseA->nb_line, b->length);
        exit(1);
    }

    /********************/
    /* show memory used */
    /********************/
#ifdef __APPLE__
    {
        struct mstats memusage;

        memusage = mstats();
        fprintf(stderr, "Memory used: %.2f MBytes\n",
                (float) (memusage.bytes_used) / (1024. * 1024));
    }
#else
    {
        struct mallinfo m_info;

        m_info = mallinfo();
        fprintf(stderr, "Memory used: %.2f MBytes\n",
                (float) (m_info.uordblks +
                         m_info.usmblks) / (1024. * 1024.));
    }
#endif

    /**************************************/
    /* relative traveltime mode           */
    /**************************************/
    if (use_ach) {
        int nb_evt_imported = 0;

        for (i = 0; i < nb_xmlfile; i++) {
            if (!imported_mesh[i]->data[EVT]) {
                continue;
            }

            for (j = 0; j < imported_mesh[i]->data[EVT]->ndatafile; j++) {
                relative_tt(sparseA, b,
                            imported_mesh[i]->data[EVT]->filename[j]);
                nb_evt_imported++;
            }
        }

        if (!nb_evt_imported) {
            fprintf(stderr,
                    "Error in ACH mode, can not import any .evt file !\n");
            exit(1);
        }
    }

    /************************************************/
    /* read the irregular mesh definition if needed */
    /* one by layer                                 */
    /************************************************/
    if (nb_irm) {
        int cpt = 0;
        struct mesh_offset_t **offset;
        int l;

        irm = (struct irm_t **) malloc(nb_irm * sizeof(struct irm_t *));
        assert(irm);
        nb_metacell = (int *) calloc(nb_irm, sizeof(int));
        assert(nb_metacell);

        make_mesh(mesh);

        for (i = 0; i < nb_xmlfile; i++) {
            if (!imported_mesh[i]->data[IRM]) {
                continue;
            }

            /* offset between meshes */
            offset = compute_mesh_offset(mesh, imported_mesh[i]);
            for (l = 0; l < mesh->nlayers; l++) {
                if (!offset[l])
                    continue;
                fprintf(stderr,
                        "\t%s, [%s] offset[layer=%d] : lat=%d lon=%d z=%d\n",
                        xmlfilelist[i], MESH_FILE_FORMAT[IRM], l,
                        offset[l]->lat, offset[l]->lon, offset[l]->z);
            }

            for (j = 0; j < imported_mesh[i]->data[IRM]->ndatafile; j++) {
                /* FIXME: read only once the irm file */
                irm[cpt] =
                    read_irm(imported_mesh[i]->data[IRM]->filename[j],
                             &(nb_metacell[cpt]));
                import2mesh_irm_file(mesh,
                                     imported_mesh[i]->data[IRM]->
                                     filename[j], offset);
                cpt++;
            }

            for (l = 0; l < mesh->nlayers; l++) {
                if (offset[l])
                    free(offset[l]);
            }
            free(offset);
        }
        metacell_find_neighbourhood(mesh);
    }

    /*sparse_compute_length(sparseA, "length1.txt"); */
    fat_sol_nb_col = sparseA->nb_col;
    show_sparse_stats(sparseA);

    /***********************/
    /* remove empty column */
    /***********************/
    fprintf(stderr, "starting compression ...\n");
    sparse_compress_column(mesh, sparseA, &compress2fat);
    if (check_sparse) {
        if (check_sparse_matrix(sparseA)) {
            exit(1);
        }
    }
    show_sparse_stats(sparseA);

    /***************************************/
    /* add gradient damping regularisation */
    /***************************************/
    if (fabs(grad_damping) > 1.e-6) {
        int nb_faces = 6;       /* 1 cell may have 6 neighbours */
        long int nb_lines = 0;
        char *regul_name;

        fprintf(stdout, "using gradient damping : %f\n", grad_damping);

        /* tmp file name */
        regul_name = tempnam("/tmp", "regul");
        if (!regul_name) {
            perror("lsqrsolve: ");
            exit(1);
        }

        if (nb_irm) {
            create_regul_DtD_irm(sparseA, compress2fat,
                                 mesh, regul_name, nb_faces,
                                 grad_damping, &nb_lines);
        } else {
            create_regul_DtD(sparseA, compress2fat,
                             mesh, regul_name, nb_faces,
                             grad_damping, &nb_lines);
        }

        sparse_matrix_resize(sparseA,
                             sparseA->nb_line + sparseA->nb_col,
                             sparseA->nb_col);

        sparseA = import_sparse_matrix(sparseA, regul_name);
        if (check_sparse) {
            if (check_sparse_matrix(sparseA)) {
                exit(1);
            }
        }
        vector_resize(b, sparseA->nb_line);
        unlink(regul_name);

        show_sparse_stats(sparseA);
    }

    /*********************************/
    /* the real mesh is no more used */
    /* keep only the light mesh      */
    /*********************************/
    fprintf(stdout,
            "Time to free the real mesh and keep only the light structure\n");
    free_mesh(mesh);
    mesh = mesh_init_from_file(mesh_filename);
    if (!mesh) {
        fprintf(stderr, "Error decoding %s.\n", mesh_filename);
        exit(1);
    }
    fprintf(stderr, "read %s ok\n", mesh_filename);

    /********************************/
    /* init vector solution to zero */
    /********************************/
    x = new_vector(sparseA->nb_col);

    /*************************************************************/
    /* solve A.x = B                                             */
    /* A = ray length in the cells                               */
    /* B = residual travel time observed - computed              */
    /* x solution to satisfy the lsqr problem                    */
    /*************************************************************/

    /* LSQR alloc */
    alloc_lsqr_mem(&input, &output, &work, &func, sparseA->nb_line,
                   sparseA->nb_col);

    fprintf(stderr, "alloc_lsqr_mem : ok\n");

    /* defines the routine Mat.Vect to use */
    func->mat_vec_prod = sparseMATRIXxVECTOR;

    /* Set the input parameters for LSQR */
    input->num_rows = sparseA->nb_line;
    input->num_cols = sparseA->nb_col;
    input->rel_mat_err = 1.0e-3;        /* in km */
    input->rel_rhs_err = 1.0e-2;        /* in seconde */
    /*input->rel_mat_err = 0.;
       input->rel_rhs_err = 0.; */
    input->cond_lim = .0;
    input->lsqr_fp_out = logfd;
    /* input->rhs_vec = (dvec *) b; */
    dvec_copy((dvec *) b, input->rhs_vec);
    input->sol_vec = (dvec *) x;        /* initial guess */
    input->damp_val = damping;
    if (max_iter == -1) {
        input->max_iter = 4 * (sparseA->nb_col);
    } else {
        input->max_iter = max_iter;
    }

    /* catch Ctrl-C signal */
    signal(SIGINT, emergency_halt);

    /******************************/
    /* resolution du systeme Ax=b */

    /******************************/
    lsqr(input, output, work, func, sparseA);
    fprintf(stderr, "*** lsqr ended (%ld iter) : %s\n",
            output->num_iters, lsqr_msg[output->term_flag]);
    if (output->term_flag == 0) {       /* solution x=x0 */
        exit(0);
    }

    /* uncompress the solution  */
    solution = uncompress_column((struct vector_t *) output->sol_vec,
                                 compress2fat, fat_sol_nb_col);

    /* uncompress the standard error on solution  */
    std_error_sol =
        uncompress_column((struct vector_t *) output->std_err_vec,
                          compress2fat, fat_sol_nb_col);

    /* if irm file was provided, set the right value to each cell 
     * from a given metacell 
     */
    if (irm) {
        irm_update(solution, irm, nb_metacell, nb_irm, mesh);
        free_irm(irm, nb_irm);
        free(nb_metacell);
    }

    /* write solution */
    if (strchr(output_type, 'm')) {
        export2matlab(solution, output_filename, mesh, vm,
                      output->num_iters,
                      input->damp_val, grad_damping, use_ach);
    }

    if (strchr(output_type, 's')) {
        export2sco(solution, output_filename, mesh, vm,
                   output->num_iters,
                   input->damp_val, grad_damping, use_ach);
    }

    if (strchr(output_type, 'g')) {
        /* solution */
        export2gmt(solution, output_filename, mesh, vm,
                   output->num_iters,
                   input->damp_val, grad_damping, use_ach);

        /* error on solution */
        sol_error_filename = (char *)
            malloc(sizeof(char) *
                   (strlen(output_filename) + strlen(".err") + 1));
        sprintf(sol_error_filename, "%s.err", output_filename);
        export2gmt(std_error_sol, sol_error_filename, mesh, vm,
                   output->num_iters,
                   input->damp_val, grad_damping, use_ach);
        free(sol_error_filename);

    }

    /* save the xml enrichied with sections */
    xml_output = (char *)
        malloc((strlen(output_filename) + strlen(".xml") +
                1) * sizeof(char));
    assert(xml_output);
    sprintf(xml_output, "%s.xml", output_filename);
    mesh2xml(mesh, xml_output);
    free(xml_output);

    /******************************************************/
    /* variance reduction, ie how the model fits the data */
    /* X = the final solution                             */
    /*                                                    */
    /*                 ||b-AX||²                          */
    /*         VR= 1 - --------                           */
    /*                  ||b||²                            */
    /*                                                    */
    /******************************************************/
    {
        double norm_b;
        double norm_b_AX;
        double VR;              /* variance reduction */

        struct vector_t *rhs;   /* right hand side */
        rhs = new_vector(sparseA->nb_line);

        /* use copy */
        dvec_copy((dvec *) b, (dvec *) rhs);

        norm_b = dvec_norm2((dvec *) rhs);

        /* does rhs = rhs + sparseA . output->sol_vec */
        /* here  rhs is overwritten */
        dvec_scale((-1.0), (dvec *) rhs);
        sparseMATRIXxVECTOR(0, output->sol_vec, (dvec *) rhs, sparseA);
        dvec_scale((-1.0), (dvec *) rhs);

        norm_b_AX = dvec_norm2((dvec *) rhs);

        VR = 1 - (norm_b_AX * norm_b_AX) / (norm_b * norm_b);
        fprintf(stdout, "Variance reduction = %.2f%%\n", VR * 100);
        free_vector(rhs);
    }

    /********/
    /* free */
    /********/
    if (vm) {
        free_velocity_model(vm);
    }
    free_mesh(mesh);
    free_sparse_matrix(sparseA);
    free_lsqr_mem(input, output, work, func);

    free_vector(solution);
    free_vector(std_error_sol);
    free(compress2fat);

    for (i = 0; i < nb_xmlfile; i++) {
        free(xmlfilelist[i]);
        free_mesh(imported_mesh[i]);
    }
    free(xmlfilelist);
    free(imported_mesh);
    return (0);
}