Skip to main content

Uncertainty Hexadecimal (“Ux”) Data Format

Introduction

Terminology

The Signaloid Uncertainty Hexadecimal data format is a digital representation for complete probability distributions. You can think of each Signaloid Ux number as representing a complete histogram of values.

Traditional computing platforms take integer and floating-point values as inputs and perform operations (such as ADD, SUBTRACT, MULTIPLY, XOR, etc.) on these inputs. The results of these operations are other integers or floating-point values.

The Signaloid Cloud Compute Engine can perform the same operations as a traditional computing platform on standard inputs, however it can also handle unique uncertainty tracking values. Instead of using integer or floating-point inputs, you may assign additional information to the input about its probability distribution. Then, when performing operations on these inputs, the Signaloid uncertainty tracking processor performs arithmetic simultaneously on the inputs and the inputs' probability distributions. The result is an output value and its associated probability distribution.

Ux Data is the way these values and their uncertainty information are defined in Signaloid’s Ux Hardware. It exploits the mathematics of probability distributions to make efficient computations on distributions. With Ux Data representations, computing systems no longer need to make the false choice between speed (time to reach an answer) and accuracy (how many standard deviations out from the expected value the uncertainty quantification has sampled, e.g., 3-sigma or 6-sigma). The Signaloid Cloud Compute Engine also provides several valuable operations that act on distribution information, such as performing Bayesian inference or creating empirical probability distributions from data, e.g., using UxHwDoubleDistFromSamples.

The format of Ux Data

Ux Data refers to the general form of the information about an input's value and its probability distribution. The more specific term Ux Binary refers to the binary representation of the information, and Ux String is the ASCII-formatted version of the information.

Single-precision and double-precision representations

The underlying data type of a distribution is either single-precision or double-precision floating-point. The core you build for decides which. The types you declare in your source code do not, so a distribution held in a float variable and one held in a double variable share the same underlying data type on the same core.

The precision changes the size of the Ux data that carries a distribution. In both Ux Binary and Ux String, the support position of each Dirac delta is the only field whose width changes. Every other field keeps its width.

Cores in the C0 and C0Pro classes use a double-precision underlying data type. Cores targeting the C0-microSD and C0-microSD+ compute modules use a single-precision underlying data type.

Ux Binary

Ux Binary data is little-endian. The layout is the following.

FieldSizeType
Particle value8 bytesdouble
Format marker3 bytesThe literal bytes 0xF0 0x00 0x00
Representation type1 byteuint8
Number of samples8 bytesuint64
Mean value of the distribution8 bytesdouble
Number of non-zero mass Dirac deltas4 bytesuint32
Support position and probability mass, one pair per Dirac delta4 or 8 bytes, then 8 bytesfloat or double, then uint64

The support position is the only field whose width depends on the underlying data type. It is 4 bytes when the data type is single-precision and 8 bytes when it is double-precision. Every other field keeps the width above in both cases.

The probability mass is a fixed-point value rather than a floating-point one. The value 0x8000000000000000 represents a probability of 1.0, so you recover the probability by dividing the stored value by 0x8000000000000000.

Ux String

The format of a Ux String is:

  1. Particle value (printed floating-point value)
  2. "Ux" (2 ASCII characters)
  3. Representation type (hexadecimal value as 2 ASCII characters)
  4. Number of samples (hexadecimal value as 16 ASCII characters)
  5. Mean value of distribution (hexadecimal value as 16 ASCII characters)
  6. Number of non-zero mass Dirac deltas (hexadecimal value as 8 ASCII characters)
  7. A sequence of n pairs of (a) support position (hexadecimal value as 8 ASCII characters for single-precision representation or 16 ASCII characters for double-precision one); (b) probability mass (hexadecimal value as 16 ASCII characters)

Unlike Ux Binary, the hexadecimal fields of a Ux String are big-endian. The probability mass uses the same fixed-point encoding as Ux Binary, with 8000000000000000 representing a probability of 1.0.

You can see the Ux String value in the Signaloid Cloud Developer Platform when using fprintf() on a floating-point value:

0.785398Ux0400000000000000003FE921FB54442D18000000013FE921FB54442D188000000000000000

By comparing this with the format defined above, the first part of the string (0.785398) is the particle value, followed by the separator characters "Ux", and finally the hexadecimal string at the end (0400…0000) is the uncertainty distribution information associated with the particle value.

✏️   Example of storing a Ux String

The following simple code example shows a distribution representing the uncertainty of a variable value whose samples are stored in the samples array. The simple example runs on the Signaloid C0 processor and uses the capabilities exposed above the ISA to inject distribution information into the processor, i.e., using UxHwDoubleDistFromSamples. The example assumes that you have mounted your Signaloid Cloud Storage at sd0. You can read the reference of the Code Editor for detailed steps on how to mount your Signaloid Cloud Storage. The example opens the uxString.txt file and stores the distributional information of value encoded as a Ux String. Figure 1 shows the visualization of the distribution of the variable value. The Ux String and binary digits that follow below show the representation of that distribution as hexadecimal and binary formatted uncertainty information in Signaloid’s uncertainty data format. Figure 2 shows the contents of the uxString.txt file as they appear in the Signaloid Cloud Data Storage in the Data and Sensors page.

#include <stdio.h>
#include <uxhw.h>

int
main(void)
{
FILE * fp;
double value, samples[] = {90, 120, 96, 20, 99, 102, 112, 68, 90, 109};

value = UxHwDoubleDistFromSamples(samples, sizeof(samples)/sizeof(double));

fp = fopen("sd0/uxString.txt", "w+");
fprintf(fp, "value = %lf\n", value);
printf("value = %lf\n", value);

return 0;
}
Figure 1. The distribution representing the uncertainty of the variable value whose samples are stored in the samples array. The simple code example runs on the Signaloid C0 processor and uses the UxHwDoubleDistFromSamples to initialize the uncertainty of the variable value.

Ux String representing the distribution of the variable value (including particle value prefix):

90.600000Ux04000000000000000A4056A666666666670000000A40568000000000000CCCCCCCCCCCCCCD405E0000000000000CCCCCCCCCCCCCCD40580000000000000CCCCCCCCCCCCCCD40340000000000000CCCCCCCCCCCCCCD4058C000000000000CCCCCCCCCCCCCCD40598000000000000CCCCCCCCCCCCCCD405C0000000000000CCCCCCCCCCCCCCD40510000000000000CCCCCCCCCCCCCCD40568000000000000CCCCCCCCCCCCCCC405B4000000000000CCCCCCCCCCCCCCC
Ux Binary representing the distribution of the variable "value" (excluding particle value prefix and "Ux"):
00000100000000000000000000000000000000000000000000000000000000000000101001000000010101101010011001100110011001100110011001100110011001110000000000000000000000000000101001000000010101101000000000000000000000000000000000000000000000000000110011001100110011001100110011001100110011001100110011001101010000000101111000000000000000000000000000000000000000000000000000001100110011001100110011001100110011001100110011001100110011010100000001011000000000000000000000000000000000000000000000000000000011001100110011001100110011001100110011001100110011001100110101000000001101000000000000000000000000000000000000000000000000000000110011001100110011001100110011001100110011001100110011001101010000000101100011000000000000000000000000000000000000000000000000001100110011001100110011001100110011001100110011001100110011010100000001011001100000000000000000000000000000000000000000000000000011001100110011001100110011001100110011001100110011001100110101000000010111000000000000000000000000000000000000000000000000000000110011001100110011001100110011001100110011001100110011001101010000000101000100000000000000000000000000000000000000000000000000001100110011001100110011001100110011001100110011001100110011010100000001010110100000000000000000000000000000000000000000000000000011001100110011001100110011001100110011001100110011001100110001000000010110110100000000000000000000000000000000000000000000000000110011001100110011001100110011001100110011001100110011001100
Figure 2. The code example stored the distributional information of variable value encoded as a Ux String in the file uxString.txt in the Signaloid Cloud Data Storage. You can see the contents of the uxString.txt file as they appear in the Signaloid Cloud Data Storage in the Data and Sensors page.

✏️   Example of ingesting a Ux String

The simple program shown below reads in the Ux String using the standard C library call sscanf, and by doing so, injects distribution information encoded as a Ux String into the variable value when executed on the Signaloid C0 processor.

#include <stdio.h>

int
main(void)
{
double value;

sscanf("90.600000Ux04000000000000000A4056A666666666670000000A40568000000000000CCCCCCCCCCCCCCD405E0000000000000CCCCCCCCCCCCCCD40580000000000000CCCCCCCCCCCCCCD40340000000000000CCCCCCCCCCCCCCD4058C000000000000CCCCCCCCCCCCCCD40598000000000000CCCCCCCCCCCCCCD405C0000000000000CCCCCCCCCCCCCCD40510000000000000CCCCCCCCCCCCCCD40568000000000000CCCCCCCCCCCCCCC405B4000000000000CCCCCCCCCCCCCCC", "%lf", &value);

printf("value = %lf\n", value);

return 0;
}