add code snippets to release notes
* Scalar networks
* If all sampled vertices are scalar then you are returned a dictionary keyed on vertex ID with the values containing a list of primitive values.
* An example of a network of size 2 with three samples: `{"gaussian": [0., 1., 2.], "exponential": [0.5, 1.5, 3.5]}`
+ * `samples["gaussian"] = [0., 1., 2.]`
* Tensor networks
* If any of the sampled vertices are tensors then you are returned a dictionary keyed on a tuple of vertex ID and tensor index.
* This makes it much easier to extract all the samples for a given index and for creating a multi-index dataframe
1 4.231334 5.017627 5.734130 3.904472 9.909033
2 4.676046 4.308018 5.035550 6.240894 10.112683
```
+ * `samples["(gaussian, (0, 1))"] = [5.734130, 5.734130, 5.035550] `
* As a result, whenever keying into a sample dictionary, you are guaranteed to receive a list of primitives.
* This greatly reduces the complexity of the `autocorrelation` and `traceplot` API's as they now simply expect a list of values.
* Reorganised the factory methods for building `PosteriorSamplingAlgorithm` objects. The following are available and give you access to either a default implementation or, when you need more control over the configuration, a Builder object:
