aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJ08nY2020-07-05 23:42:30 +0200
committerJ08nY2020-07-05 23:42:30 +0200
commitfe1b7145e0ce0c5a647216ccf5b749da1de27877 (patch)
treeb661077ec106206e90dc6ae50c8491926f7e312d
parent0e65cac7129365128ea3444bb08390edcce13d9e (diff)
downloadpyecsca-fe1b7145e0ce0c5a647216ccf5b749da1de27877.tar.gz
pyecsca-fe1b7145e0ce0c5a647216ccf5b749da1de27877.tar.zst
pyecsca-fe1b7145e0ce0c5a647216ccf5b749da1de27877.zip
Fix trace combination functions.
-rw-r--r--pyecsca/sca/scope/picoscope_sdk.py2
-rw-r--r--pyecsca/sca/trace/combine.py61
2 files changed, 53 insertions, 10 deletions
diff --git a/pyecsca/sca/scope/picoscope_sdk.py b/pyecsca/sca/scope/picoscope_sdk.py
index 46c1da2..f747388 100644
--- a/pyecsca/sca/scope/picoscope_sdk.py
+++ b/pyecsca/sca/scope/picoscope_sdk.py
@@ -204,7 +204,7 @@ class PicoScopeSdk(Scope): # pragma: no cover
if type == SampleType.Raw:
data = arr
else:
- data = adc2volt(arr, self.ranges[channel], self.MAX_ADC_VALUE)
+ data = adc2volt(arr, self.ranges[channel], self.MAX_ADC_VALUE, dtype=dtype)
return Trace(data, {"sampling_frequency": self.frequency, "channel": channel, "sample_type": type})
def stop(self):
diff --git a/pyecsca/sca/trace/combine.py b/pyecsca/sca/trace/combine.py
index 04b1a70..496cfcc 100644
--- a/pyecsca/sca/trace/combine.py
+++ b/pyecsca/sca/trace/combine.py
@@ -18,9 +18,13 @@ def average(*traces: Trace) -> Optional[CombinedTrace]:
return None
if len(traces) == 1:
return CombinedTrace(traces[0].samples.copy())
- dtype = traces[0].samples.dtype
- result_samples = np.mean(np.stack([trace.samples for trace in traces]), axis=0).astype(dtype, copy=False)
- return CombinedTrace(result_samples)
+ min_samples = min(map(len, traces))
+ s = np.zeros(min_samples, dtype=np.float64)
+ for t in traces:
+ s = np.add(s, t.samples[:min_samples])
+ avg = ((1/len(traces)) * s)
+ del s
+ return CombinedTrace(avg)
@public
@@ -45,9 +49,46 @@ def standard_deviation(*traces: Trace) -> Optional[CombinedTrace]:
"""
if not traces:
return None
- dtype = traces[0].samples.dtype
- result_samples = np.std(np.stack([trace.samples for trace in traces]), axis=0).astype(dtype, copy=False)
- return CombinedTrace(result_samples)
+ if len(traces) == 0:
+ return CombinedTrace(np.zeros(len(traces[0]), dtype=np.float64))
+ min_samples = min(map(len, traces))
+ s = np.zeros(min_samples, dtype=np.float64)
+ for t in traces:
+ s = np.add(s, t.samples[:min_samples])
+ ts = np.zeros(min_samples, dtype=np.float64)
+ for t in traces:
+ d = np.subtract(t.samples[:min_samples], s)
+ ts = np.add(ts, np.multiply(d, d, dtype=np.float64))
+ std = np.sqrt((1/len(traces)-1) * ts)
+ del s
+ del ts
+ return CombinedTrace(std)
+
+
+@public
+def variance(*traces: Trace) -> Optional[CombinedTrace]:
+ """
+ Compute the variance of the `traces`, sample-wise.
+
+ :param traces:
+ :return:
+ """
+ if not traces:
+ return None
+ if len(traces) == 0:
+ return CombinedTrace(np.zeros(len(traces[0]), dtype=np.float64))
+ min_samples = min(map(len, traces))
+ s = np.zeros(min_samples, dtype=np.float64)
+ for t in traces:
+ s = np.add(s, t.samples[:min_samples])
+ ts = np.zeros(min_samples, dtype=np.float64)
+ for t in traces:
+ d = np.subtract(t.samples[:min_samples], s)
+ ts = np.add(ts, np.multiply(d, d, dtype=np.float64))
+ var = (1/len(traces)-1) * ts
+ del s
+ del ts
+ return CombinedTrace(var)
@public
@@ -62,9 +103,11 @@ def add(*traces: Trace) -> Optional[CombinedTrace]:
return None
if len(traces) == 1:
return CombinedTrace(traces[0].samples.copy())
- dtype = traces[0].samples.dtype
- result_samples = np.sum(np.stack([trace.samples for trace in traces]), axis=0).astype(dtype, copy=False)
- return CombinedTrace(result_samples)
+ min_samples = min(map(len, traces))
+ s = np.zeros(min_samples, dtype=np.float64)
+ for t in traces:
+ s = np.add(s, t.samples[:min_samples])
+ return CombinedTrace(s)
@public