5 | | Therefore we are submitting a proposal for the addition of support for complex numbers. |
| 6 | == The nature of complex numbers == |
| 7 | |
| 8 | A complex number can be expressed in the form P = X + iY, where X and Y are real numbers, and i is the square root of -1. For the complex number P = X + iY, X is called the real part, and Y is called the imaginary part. |
| 9 | |
| 10 | Complex numbers can also be represented in a polar or exponential forms. |
| 11 | |
| 12 | The relationship between the Cartesian form and the polar form is: |
| 13 | |
| 14 | P = X + iY = R(cos(theta) + isin(theta)) |
| 15 | |
| 16 | where R is the distance from the origin to the point P, and theta is the angle between the X axis and the line OP, measured counterclockwise. |
| 17 | |
| 18 | == Representing complex numbers as 2 reals == |
| 19 | |
| 20 | The above discussion demonstrates that no matter which form you choose to use, a complex number requires the storage of two real numbers, as well as a clear description of which form you are using. |
| 21 | It seems reasonable to determine the form being used by inspecting |
| 22 | the units attribute. |
| 23 | |
| 24 | == Use of complex numbers in radar data == |
| 25 | |
| 26 | At the most raw level, radars generate time series of I (in-phase) and Q (quadrature) signals. These two signal components are considered to comprise a complex number. |
| 27 | |
| 28 | Additionally, the spectra of radar signals are stored as complex numbers. |
| 29 | |
| 30 | Because of the very large dynamic range of radar signals (up to 10 orders of magnitude), these complex numbers are often stored as power, in log units, and phase, in degrees. |
| 31 | |
| 32 | == Storing complex numbers in NetCDF == |
| 33 | |
| 34 | Because complex numbers must be represented by 2 real numbers, a complex variable will have one extra dimension, of size 2. |
| 35 | |
| 36 | We propose that this dimension should be the last of the dimensions used for a variable – i.e. the 2 parts of the number are stored immediately one after the other in the array. |
| 37 | |
| 38 | So, for example, a radar variable holding complex data for an I/Q time series could be represented as follows |
| 39 | |
| 40 | |
| 41 | {{{ |
| 42 | time = 3000 ; |
| 43 | range = 996 ; |
| 44 | complex = 2; |
| 45 | float IQ(time, range, complex) ; |
| 46 | IQ:is_complex = “true” ; |
| 47 | IQ:long_name = "time_series_inphase_and_quadrature" ; |
| 48 | IQ:standard_name = "radar_time_series_inphase_and_quadrature" ; |
| 49 | IQ:units = "volt" ; |
| 50 | IQ:_FillValue = -9999F ; |
| 51 | IQ:coordinates = "time range" ; |
| 52 | }}} |
| 53 | |
| 54 | == Attribute indicating variable is complex == |
| 55 | |
| 56 | As indicated in the example above, we propose that the string attribute: |
| 57 | |
| 58 | |
| 59 | {{{ |
| 60 | is_complex = "true"; |
| 61 | |
| 62 | }}} |
| 63 | |
| 64 | be attached to any variable that holds complex numbers. |
| 65 | |
| 66 | == Units attribute for real/imaginary form == |
| 67 | |
| 68 | If the complex number is stored using real and imaginary parts, the units of both parts will be the same. |
| 69 | |
| 70 | This is true for the example above, where we have: |
| 71 | |
| 72 | {{{ |
| 73 | IQ:units = "volts"; |
| 74 | }}} |
| 75 | |
| 76 | == Units attribute for polar form == |
| 77 | |
| 78 | If the polar or exponential form is used, the units of the two parts will not be the same. |
| 79 | |
| 80 | We could use a single units string attribute, but make it comma-delimited to separate the units for the 2 parts. |
| 81 | |
| 82 | For example: |
| 83 | |
| 84 | {{{ |
| 85 | IQ:units = "dBm,degree"; |
| 86 | }}} |
| 87 | |
| 88 | Or we could have 2 separate units attributes: |
| 89 | |
| 90 | For example: |
| 91 | |
| 92 | {{{ |
| 93 | IQ:units_first_part = "dBm"; |
| 94 | IQ:units_second_part = "degree"; |
| 95 | }}} |
| 96 | |
| 97 | |
| 98 | |