The MDDatasets.jl module provides tools to simplify manipulation of multi-dimensional datasets.

–> https://github.com/ma-laforge/MDDatasets.jl

Insallation:

```
] add MDDatasets
```

### Grouping (x,y) vectors

MDDatasets also provides a means to group `(x,y)`

data in a single data structure to simplify calculations (`DataF1`

structure). For example, we can take the derivative of a dataset (wrt `x`

) very simply using:

**(Using MDDatasets.jl:)**

```
#Assuming f1 has time-domain data y=f(x=t):
slope = deriv(f1)
```

Note that internally, `f1`

contains **both**`y`

values, and `x`

values (which represent time, `t`

). This is much more straightforward than the typical way to do differentiation:

**(WITHOUT the help of MDDatasets.jl:)**

```
#Assuming we have f1_x & f1_y data:
deltax = f1_x[2:end] .- f1_x[1:end-1]
deltay = f1_y[2:end] .- f1_y[1:end-1]
slope = deltay ./ deltax
```

### AUTOMATIC INTERPOLATION

Note that operations on `DataF1`

objects will * automatically interpolate* intermediate values if the

`x`

sample points don’t match. This is particularly useful if you wish to perform operations on results collected from multiple simulations that have different/non-uniform time steps (or whatever the x-values might represent).### Multi-Dimensional Data & “Parametric Analysis”

`MDDatasets.jl`

is designed to store values from a “Parametric Analysis”. Basically, you re-run the same experiments with different conditions by “sweeping” the values of different control variables in order to see how they affect results.

For example, you might want to simulate circuit behaviour by “sweeping” the following parameters:

```
for vSupply in [0.9V, 1V, 1.1V]
for temp in [-40, 0, 100, 125]
for trise in 10e-12:10e-12:100e-12
#Read in data & compute characteristics that might be insighful
end
end
end
```

With MDDatasets.jl, the procedure is a bit more straightforward…

### Step 1: Collect Data in Multi-Dimensional Dataset using `DataRS`

To build a multi-dimensional dataset, you would “fill” a `DataRS`

structure:

```
signal1 = fill(DataRS, PSweep("tbit", [1, 3, 9] * 1e-9)) do tbit
fill(DataRS, PSweep("VDD", 0.9 * [0.9, 1, 1.1])) do vdd
#Inner-most sweep: need to specify element type (DataF1):
fill(DataRS{DataF1}, PSweep("trise", [0.1, 0.15, 0.2] * tbit)) do trise
y = get_ydata(tbit, vdd, trise) #Read in y values
x = get_xdata(tbit, vdd, trise) #Read in x values
return DataF1(x, y) #"Leaf" elements of DataRS structure are DataF1 containers.
end
end
end
```

This assumes `get_xdata()`

& `get_ydata()`

functions retrieve simulation data at certain values of `tbit`

, `vdd`

, & `trise`

.

**Indeed, this DOES seem like alot, but you only have to read in data once. Once data is read in, performing the actual calculations becomes much more straightforward and easy to read/write (see below).**

### Step 2: Run Calculations

Assuming `vin`

& `vout`

are `DataRS`

structures storing the input & output voltages of a closed-loop op-amp time-domain simulation, one could easily compute the gain error over all of the simulated time:

```
gainideal = 6 #Desired gain of op-amp
#Compute error in gain value, over time:
error = 100 * ((vout/vin) - gainideal) / gainideal
```

**NOTE:**

- There is no need for explicit
`for`

loops. MDDatasets.jl automatically broadcasts operations over all “swept” parameters. - There is no need for the “dot” notation (
`.+`

,`.*`

, …). Unlike with`Array`

objects,`DataRS`

structures are not meant to natively support matrix operations (matrix multiplication, etc). Consequently, there is no confusion between element-by-element & matrix operations.

### Sample Usage

More advanced uses of the `MDDatasets.jl`

module can be found in the (not-yet-registered) `SignalProcessing.jl`

module: