Esempio n. 1
0
int harp_import_netcdf(const char *filename, harp_product **product)
{
    harp_product *new_product;
    netcdf_dimensions dimensions;
    int ncid;
    int result;

    if (filename == NULL)
    {
        harp_set_error(HARP_ERROR_INVALID_ARGUMENT, "filename is NULL (%s:%u)", __FILE__, __LINE__);
        return -1;
    }

    result = nc_open(filename, 0, &ncid);
    if (result != NC_NOERR)
    {
        harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
        return -1;
    }

    if (verify_product(ncid) != 0)
    {
        nc_close(ncid);
        return -1;
    }

    if (harp_product_new(&new_product) != 0)
    {
        nc_close(ncid);
        return -1;
    }

    dimensions_init(&dimensions);

    if (read_product(ncid, new_product, &dimensions) != 0)
    {
        dimensions_done(&dimensions);
        harp_product_delete(new_product);
        nc_close(ncid);
        return -1;
    }

    dimensions_done(&dimensions);

    result = nc_close(ncid);
    if (result != NC_NOERR)
    {
        harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
        harp_product_delete(new_product);
        return -1;
    }

    *product = new_product;
    return 0;
}
Esempio n. 2
0
int harp_import_global_attributes_netcdf(const char *filename, double *datetime_start, double *datetime_stop,
                                         long dimension[], char **source_product)
{
    char *attr_source_product = NULL;
    harp_scalar attr_datetime_start;
    harp_scalar attr_datetime_stop;
    harp_data_type attr_data_type;
    long attr_dimension[HARP_NUM_DIM_TYPES];
    int result;
    int ncid;
    int i;

    if (datetime_start == NULL && datetime_stop == NULL)
    {
        return 0;
    }

    if (filename == NULL)
    {
        harp_set_error(HARP_ERROR_INVALID_ARGUMENT, "filename is NULL (%s:%u)", __FILE__, __LINE__);
        return -1;
    }

    result = nc_open(filename, 0, &ncid);
    if (result != NC_NOERR)
    {
        harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
        return -1;
    }

    if (verify_product(ncid) != 0)
    {
        nc_close(ncid);
        return -1;
    }

    if (datetime_start != NULL)
    {
        if (nc_inq_att(ncid, NC_GLOBAL, "datetime_start", NULL, NULL) == NC_NOERR)
        {
            if (read_numeric_attribute(ncid, NC_GLOBAL, "datetime_start", &attr_data_type, &attr_datetime_start) != 0)
            {
                nc_close(ncid);
                return -1;
            }

            if (attr_data_type != harp_type_double)
            {
                harp_set_error(HARP_ERROR_IMPORT, "attribute 'datetime_start' has invalid type");
                nc_close(ncid);
                return -1;
            }
        }
        else
        {
            attr_datetime_start.double_data = harp_mininf();
        }
    }

    if (datetime_stop != NULL)
    {
        if (nc_inq_att(ncid, NC_GLOBAL, "datetime_stop", NULL, NULL) == NC_NOERR)
        {
            if (read_numeric_attribute(ncid, NC_GLOBAL, "datetime_stop", &attr_data_type, &attr_datetime_stop) != 0)
            {
                nc_close(ncid);
                return -1;
            }

            if (attr_data_type != harp_type_double)
            {
                harp_set_error(HARP_ERROR_IMPORT, "attribute 'datetime_stop' has invalid type");
                nc_close(ncid);
                return -1;
            }
        }
        else
        {
            attr_datetime_stop.double_data = harp_plusinf();
        }
    }

    if (source_product != NULL)
    {
        if (read_string_attribute(ncid, NC_GLOBAL, "source_product", &attr_source_product) != 0)
        {
            nc_close(ncid);
            return -1;
        }
    }

    if (dimension != NULL)
    {
        int num_dimensions;
        int num_variables;
        int num_attributes;
        int unlim_dim;
        int result;

        for (i = 0; i < HARP_NUM_DIM_TYPES; i++)
        {
            attr_dimension[i] = -1;
        }

        result = nc_inq(ncid, &num_dimensions, &num_variables, &num_attributes, &unlim_dim);
        if (result != NC_NOERR)
        {
            harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
            return -1;
        }

        for (i = 0; i < num_dimensions; i++)
        {
            netcdf_dimension_type netcdf_dim_type;
            harp_dimension_type harp_dim_type;
            char name[NC_MAX_NAME + 1];
            size_t length;

            result = nc_inq_dim(ncid, i, name, &length);
            if (result != NC_NOERR)
            {
                harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
                return -1;
            }

            if (parse_dimension_type(name, &netcdf_dim_type) != 0)
            {
                return -1;
            }
            if (netcdf_dim_type != netcdf_dimension_independent && netcdf_dim_type != netcdf_dimension_string)
            {
                if (get_harp_dimension_type(netcdf_dim_type, &harp_dim_type) != 0)
                {
                    return -1;
                }
                attr_dimension[harp_dim_type] = length;
            }
        }
    }

    result = nc_close(ncid);
    if (result != NC_NOERR)
    {
        harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
        free(attr_source_product);
        return -1;
    }

    if (datetime_start != NULL)
    {
        *datetime_start = attr_datetime_start.double_data;
    }

    if (datetime_stop != NULL)
    {
        *datetime_stop = attr_datetime_stop.double_data;
    }

    if (source_product != NULL)
    {
        *source_product = attr_source_product;
    }

    if (dimension != NULL)
    {
        for (i = 0; i < HARP_NUM_DIM_TYPES; i++)
        {
            dimension[i] = attr_dimension[i];
        }
    }

    return 0;
}
Esempio n. 3
0
/*-------------------------------------------------------------------*/
void alg_square_root(msieve_obj *obj, mp_poly_t *mp_alg_poly, 
			mp_t *n, mp_t *c, signed_mp_t *m1, 
			signed_mp_t *m0, abpair_t *rlist, 
			uint32 num_relations, uint32 check_q,
			mp_t *sqrt_a) {
	
	/* external interface for computing the algebraic
	   square root */

	uint32 i;
	gmp_poly_t alg_poly;
	gmp_poly_t d_alg_poly;
	gmp_poly_t prod;
	gmp_poly_t alg_sqrt;
	relation_prod_t prodinfo;
	double log2_prodsize;
	mpz_t q;

	/* initialize */

	mpz_init(q);
	gmp_poly_init(&alg_poly);
	gmp_poly_init(&d_alg_poly);
	gmp_poly_init(&prod);
	gmp_poly_init(&alg_sqrt);

	/* convert the algebraic poly to arbitrary precision */

	for (i = 0; i < mp_alg_poly->degree; i++) {
		signed_mp_t *coeff = mp_alg_poly->coeff + i;
		mp2gmp(&coeff->num, alg_poly.coeff[i]);
		if (coeff->sign == NEGATIVE)
			mpz_neg(alg_poly.coeff[i], alg_poly.coeff[i]);
	}
	alg_poly.degree = mp_alg_poly->degree - 1;

	/* multiply all the relations together */

	prodinfo.monic_poly = &alg_poly;
	prodinfo.rlist = rlist;
	prodinfo.c = c;

	logprintf(obj, "multiplying %u relations\n", num_relations);
	multiply_relations(&prodinfo, 0, num_relations - 1, &prod);
	logprintf(obj, "multiply complete, coefficients have about "
			"%3.2lf million bits\n",
			(double)mpz_sizeinbase(prod.coeff[0], 2) / 1e6);

	/* perform a sanity check on the result */

	i = verify_product(&prod, rlist, num_relations, 
				check_q, c, mp_alg_poly);
	free(rlist);
	if (i == 0) {
		logprintf(obj, "error: relation product is incorrect\n");
		goto finished;
	}

	/* multiply by the square of the derivative of alg_poly;
	   this will guarantee that the square root of prod actually 
	   is an element of the number field defined by alg_poly.
	   If we didn't do this, we run the risk of the main Newton
	   iteration not converging */

	gmp_poly_monic_derivative(&alg_poly, &d_alg_poly);
	gmp_poly_mul(&d_alg_poly, &d_alg_poly, &alg_poly, 0);
	gmp_poly_mul(&prod, &d_alg_poly, &alg_poly, 1);

	/* pick the initial small prime to start the Newton iteration.
	   To save both time and memory, choose an initial prime 
	   such that squaring it a large number of times will produce
	   a value just a little larger than we need to calculate
	   the square root.
	
	   Note that contrary to what some authors write, pretty much
	   any starting prime is okay. The Newton iteration has a division
	   by 2, so that 2 must be invertible mod the prime (this is
	   guaranteed for odd primes). Also, the Newton iteration will
	   fail if both square roots have the same value mod the prime;
	   however, even a 16-bit prime makes this very unlikely */

	i = mpz_size(prod.coeff[0]);
	log2_prodsize = (double)GMP_LIMB_BITS * (i - 2) +
			log(mpz_getlimbn(prod.coeff[0], (mp_size_t)(i-1)) *
				pow(2.0, (double)GMP_LIMB_BITS) +
			    mpz_getlimbn(prod.coeff[0], (mp_size_t)(i-2))) / 
			M_LN2 + 10000;

	while (log2_prodsize > 31.5)
		log2_prodsize *= 0.5;

	mpz_set_d(q, (uint32)pow(2.0, log2_prodsize) + 1);

	/* get the initial inverse square root */

	if (!get_initial_inv_sqrt(obj, mp_alg_poly, 
				&prod, &alg_sqrt, q)) {
		goto finished;
	}

	/* compute the actual square root */

	if (get_final_sqrt(obj, &alg_poly, &prod, &alg_sqrt, q))
		convert_to_integer(&alg_sqrt, n, c, m1, m0, sqrt_a);

finished:
	gmp_poly_clear(&prod);
	gmp_poly_clear(&alg_sqrt);
	gmp_poly_clear(&alg_poly);
	gmp_poly_clear(&d_alg_poly);
	mpz_clear(q);
}