Skip to content

Commit 90429f5

Browse files
Implement support for complex number datatypes (#4630)
* Implement support for complex number datatypes Adds the new datatype class H5T_COMPLEX Adds the new API function H5Tcomplex_create which creates a complex number datatype from an ID of a base floating-point datatype Adds the new feature check macros H5_HAVE_COMPLEX_NUMBERS and H5_HAVE_C99_COMPLEX_NUMBERS Adds the new datatype size macros H5_SIZEOF_FLOAT_COMPLEX, H5_SIZEOF_DOUBLE_COMPLEX and H5_SIZEOF_LONG_DOUBLE_COMPLEX Adds the new datatype ID macros H5T_NATIVE_FLOAT_COMPLEX, H5T_NATIVE_DOUBLE_COMPLEX, H5T_NATIVE_LDOUBLE_COMPLEX, H5T_CPLX_IEEE_F16LE, H5T_CPLX_IEEE_F16BE, H5T_CPLX_IEEE_F32LE, H5T_CPLX_IEEE_F32BE, H5T_CPLX_IEEE_F64LE and H5T_CPLX_IEEE_F64BE Adds hard and soft datatype conversion paths between complex number datatypes and all the integer and floating-point datatypes, as well as between other complex number datatypes Adds a special conversion path between complex number datatypes and array or compound datatypes where the in-memory layout of data is the same between the datatypes and data can be converted directly Adds support for complex number datatypes to the h5dump, h5ls and h5diff/ph5diff tools. Allows h5dump '-m' option to change floating-point printing format for float complex and double complex datatypes, as well as long double complex if it has the same size as double complex Adds minimal support to the h5watch and h5import tools Adds support for the predefined complex number datatypes and H5Tcomplex_create function to the Java wrappers. Also adds initial, untested support to the JNI for future use with HDFView Adds support for just the H5T_COMPLEX datatype class to the Fortran wrappers Adds support for the predefined complex number datatypes and H5Tcomplex_create function to the high level library H5LT interface for use with the H5LTtext_to_dtype and H5LTdtype_to_text functions Changes some usages of "complex" in the library since it conflicts with the "complex" keyword from the complex.h header. Also changes various usages of the word "complex" throughout the library to distinguish compound datatypes from complex datatypes.
1 parent e8257bd commit 90429f5

File tree

141 files changed

+24772
-4934
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

141 files changed

+24772
-4934
lines changed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/************************************************************
2+
3+
This example shows how to read and write complex number
4+
datatypes to a dataset. The program first writes float
5+
complex values to a dataset with a dataspace of DIM0xDIM1,
6+
then closes the file. Next, it reopens the file, reads
7+
back the data, and outputs it to the screen. This example
8+
assumes the C99 complex number types are supported. For an
9+
example that uses MSVC's complex number types, see the
10+
h5ex_t_complex_msvc.c example file.
11+
12+
************************************************************/
13+
14+
#include "hdf5.h"
15+
#include <stdio.h>
16+
#include <stdlib.h>
17+
#include <complex.h>
18+
19+
#define FILE "h5ex_t_complex.h5"
20+
#define DATASET "DS1"
21+
#define DIM0 4
22+
#define DIM1 7
23+
24+
int
25+
main(void)
26+
{
27+
float _Complex wdata[DIM0][DIM1]; /* Write buffer */
28+
float _Complex **rdata; /* Read buffer */
29+
hid_t file, space, dset; /* Handles */
30+
herr_t status;
31+
hsize_t dims[2] = {DIM0, DIM1};
32+
int ndims;
33+
hsize_t i, j;
34+
35+
/*
36+
* Initialize data.
37+
*/
38+
for (i = 0; i < DIM0; i++)
39+
for (j = 0; j < DIM1; j++) {
40+
float real = (float)i / (j + 0.5) + j;
41+
float imaginary = (float)i / (j + 0.5) + j + 1;
42+
wdata[i][j] = real + imaginary * I;
43+
}
44+
45+
/*
46+
* Create a new file using the default properties.
47+
*/
48+
file = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
49+
50+
/*
51+
* Create dataspace. Setting maximum size to NULL sets the maximum
52+
* size to be the current size.
53+
*/
54+
space = H5Screate_simple(2, dims, NULL);
55+
56+
/*
57+
* Create the dataset and write the complex number data to it. In
58+
* this example we will save the data as complex numbers of 2 64-bit
59+
* little endian IEEE floating point numbers, regardless of the native
60+
* type. The HDF5 library automatically converts between different
61+
* complex number types.
62+
*/
63+
dset = H5Dcreate(file, DATASET, H5T_COMPLEX_IEEE_F64LE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
64+
status = H5Dwrite(dset, H5T_NATIVE_FLOAT_COMPLEX, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata[0]);
65+
66+
/*
67+
* Close and release resources.
68+
*/
69+
status = H5Dclose(dset);
70+
status = H5Sclose(space);
71+
status = H5Fclose(file);
72+
73+
/*
74+
* Now we begin the read section of this example. Here we assume
75+
* the dataset has the same name and rank, but can have any size.
76+
* Therefore we must allocate a new array to read in data using
77+
* malloc().
78+
*/
79+
80+
/*
81+
* Open file and dataset.
82+
*/
83+
file = H5Fopen(FILE, H5F_ACC_RDONLY, H5P_DEFAULT);
84+
dset = H5Dopen(file, DATASET, H5P_DEFAULT);
85+
86+
/*
87+
* Get dataspace and allocate memory for read buffer. This is a
88+
* two dimensional dataset so the dynamic allocation must be done
89+
* in steps.
90+
*/
91+
space = H5Dget_space(dset);
92+
ndims = H5Sget_simple_extent_dims(space, dims, NULL);
93+
94+
/*
95+
* Allocate array of pointers to rows.
96+
*/
97+
rdata = malloc(dims[0] * sizeof(float _Complex *));
98+
99+
/*
100+
* Allocate space for complex number data.
101+
*/
102+
rdata[0] = malloc(dims[0] * dims[1] * sizeof(float _Complex));
103+
104+
/*
105+
* Set the rest of the pointers to rows to the correct addresses.
106+
*/
107+
for (i = 1; i < dims[0]; i++)
108+
rdata[i] = rdata[0] + i * dims[1];
109+
110+
/*
111+
* Read the data.
112+
*/
113+
status = H5Dread(dset, H5T_NATIVE_FLOAT_COMPLEX, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata[0]);
114+
115+
/*
116+
* Output the data to the screen.
117+
*/
118+
printf("%s:\n", DATASET);
119+
for (i = 0; i < dims[0]; i++) {
120+
printf(" [");
121+
for (j = 0; j < dims[1]; j++) {
122+
printf(" %6.4f%+6.4fi", crealf(rdata[i][j]), cimagf(rdata[i][j]));
123+
}
124+
printf("]\n");
125+
}
126+
127+
/*
128+
* Close and release resources.
129+
*/
130+
free(rdata[0]);
131+
free(rdata);
132+
status = H5Dclose(dset);
133+
status = H5Sclose(space);
134+
status = H5Fclose(file);
135+
136+
return 0;
137+
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/************************************************************
2+
3+
This example shows how to read and write complex number
4+
datatypes to a dataset. The program first writes float
5+
complex values to a dataset with a dataspace of DIM0xDIM1,
6+
then closes the file. Next, it reopens the file, reads
7+
back the data, and outputs it to the screen. This example
8+
assumes the C99 complex number types are supported. For an
9+
example that uses MSVC's complex number types, see the
10+
h5ex_t_complex_msvc.c example file.
11+
12+
************************************************************/
13+
14+
#include "hdf5.h"
15+
#include <stdio.h>
16+
#include <stdlib.h>
17+
#include <complex.h>
18+
19+
#define FILE "h5ex_t_complex_custom.h5"
20+
#define DATASET "DS1"
21+
#define DIM0 4
22+
#define DIM1 7
23+
24+
int
25+
main(void)
26+
{
27+
float _Complex wdata[DIM0][DIM1]; /* Write buffer */
28+
float _Complex **rdata; /* Read buffer */
29+
hid_t file, space, dset, dtype; /* Handles */
30+
herr_t status;
31+
hsize_t dims[2] = {DIM0, DIM1};
32+
int ndims;
33+
hsize_t i, j;
34+
35+
/*
36+
* Initialize data.
37+
*/
38+
for (i = 0; i < DIM0; i++)
39+
for (j = 0; j < DIM1; j++) {
40+
float real = (float)i / (j + 0.5) + j;
41+
float imaginary = (float)i / (j + 0.5) + j + 1;
42+
wdata[i][j] = real + imaginary * I;
43+
}
44+
45+
/*
46+
* Create a new file using the default properties.
47+
*/
48+
file = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
49+
50+
/*
51+
* Create dataspace. Setting maximum size to NULL sets the maximum
52+
* size to be the current size.
53+
*/
54+
space = H5Screate_simple(2, dims, NULL);
55+
56+
/*
57+
* Create the dataset and write the complex number data to it. In
58+
* this example we will save the data as complex numbers of 2 64-bit
59+
* little endian IEEE floating point numbers, regardless of the native
60+
* type. The HDF5 library automatically converts between different
61+
* complex number types.
62+
*/
63+
dset = H5Dcreate(file, DATASET, H5T_COMPLEX_IEEE_F64LE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
64+
65+
/*
66+
* Create a datatype for writing to the dataset. This datatype is a
67+
* complex number equivalent to the H5T_NATIVE_FLOAT_COMPLEX type.
68+
*/
69+
dtype = H5Tcomplex_create(H5T_NATIVE_FLOAT);
70+
71+
status = H5Dwrite(dset, dtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata[0]);
72+
73+
/*
74+
* Close and release resources.
75+
*/
76+
status = H5Dclose(dset);
77+
status = H5Sclose(space);
78+
status = H5Fclose(file);
79+
80+
/*
81+
* Now we begin the read section of this example. Here we assume
82+
* the dataset has the same name and rank, but can have any size.
83+
* Therefore we must allocate a new array to read in data using
84+
* malloc().
85+
*/
86+
87+
/*
88+
* Open file and dataset.
89+
*/
90+
file = H5Fopen(FILE, H5F_ACC_RDONLY, H5P_DEFAULT);
91+
dset = H5Dopen(file, DATASET, H5P_DEFAULT);
92+
93+
/*
94+
* Get dataspace and allocate memory for read buffer. This is a
95+
* two dimensional dataset so the dynamic allocation must be done
96+
* in steps.
97+
*/
98+
space = H5Dget_space(dset);
99+
ndims = H5Sget_simple_extent_dims(space, dims, NULL);
100+
101+
/*
102+
* Allocate array of pointers to rows.
103+
*/
104+
rdata = malloc(dims[0] * sizeof(float _Complex *));
105+
106+
/*
107+
* Allocate space for complex number data.
108+
*/
109+
rdata[0] = malloc(dims[0] * dims[1] * sizeof(float _Complex));
110+
111+
/*
112+
* Set the rest of the pointers to rows to the correct addresses.
113+
*/
114+
for (i = 1; i < dims[0]; i++)
115+
rdata[i] = rdata[0] + i * dims[1];
116+
117+
/*
118+
* Read the data.
119+
*/
120+
status = H5Dread(dset, dtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata[0]);
121+
122+
/*
123+
* Output the data to the screen.
124+
*/
125+
printf("%s:\n", DATASET);
126+
for (i = 0; i < dims[0]; i++) {
127+
printf(" [");
128+
for (j = 0; j < dims[1]; j++) {
129+
printf(" %6.4f%+6.4fi", crealf(rdata[i][j]), cimagf(rdata[i][j]));
130+
}
131+
printf("]\n");
132+
}
133+
134+
/*
135+
* Close and release resources.
136+
*/
137+
free(rdata[0]);
138+
free(rdata);
139+
status = H5Dclose(dset);
140+
status = H5Sclose(space);
141+
status = H5Tclose(dtype);
142+
status = H5Fclose(file);
143+
144+
return 0;
145+
}

0 commit comments

Comments
 (0)