Finishing up freq meas

This commit is contained in:
jaseg 2020-03-02 19:42:36 +01:00
parent 5effadcbaf
commit ca01d52a86
14 changed files with 296 additions and 47 deletions

3
.gitmodules vendored
View file

@ -16,3 +16,6 @@
[submodule "controller/fw/musl"] [submodule "controller/fw/musl"]
path = controller/fw/musl path = controller/fw/musl
url = git://git.musl-libc.org/musl url = git://git.musl-libc.org/musl
[submodule "controller/fw/levmarq"]
path = controller/fw/levmarq
url = https://gist.github.com/3539146.git

View file

@ -6,13 +6,17 @@ LIBSODIUM_DIR ?= libsodium
TINYAES_DIR ?= tinyaes TINYAES_DIR ?= tinyaes
MUSL_DIR ?= musl MUSL_DIR ?= musl
C_SOURCES := src/main.c src/mspdebug_wrapper.c src/spi_flash.c C_SOURCES := src/main.c src/mspdebug_wrapper.c src/spi_flash.c src/freq_meas.c
C_SOURCES += $(MSPDEBUG_DIR)/drivers/jtaglib.c C_SOURCES += $(MSPDEBUG_DIR)/drivers/jtaglib.c
C_SOURCES += $(CMSIS_DIR)/CMSIS/DSP/Source/TransformFunctions/arm_rfft_f32.c C_SOURCES += $(CMSIS_DIR)/CMSIS/DSP/Source/TransformFunctions/arm_rfft_f32.c
C_SOURCES += $(CMSIS_DIR)/CMSIS/DSP/Source/TransformFunctions/arm_bitreversal.c C_SOURCES += $(CMSIS_DIR)/CMSIS/DSP/Source/TransformFunctions/arm_bitreversal.c
C_SOURCES += $(CMSIS_DIR)/CMSIS/DSP/Source/TransformFunctions/arm_cfft_radix4_f32.c C_SOURCES += $(CMSIS_DIR)/CMSIS/DSP/Source/TransformFunctions/arm_cfft_radix4_f32.c
C_SOURCES += $(MUSL_DIR)/src/math/tanhf.c $(MUSL_DIR)/src/math/atanhf.c C_SOURCES += $(MUSL_DIR)/src/math/tanhf.c $(MUSL_DIR)/src/math/atanhf.c
C_SOURCES += $(MUSL_DIR)/src/math/expm1f.c $(MUSL_DIR)/src/math/log1pf.c C_SOURCES += $(MUSL_DIR)/src/math/expm1f.c $(MUSL_DIR)/src/math/log1pf.c
C_SOURCES += $(MUSL_DIR)/src/math/expf.c $(MUSL_DIR)/src/math/exp2f_data.c
C_SOURCES += $(MUSL_DIR)/src/math/__math_oflowf.c
C_SOURCES += $(MUSL_DIR)/src/math/__math_uflowf.c
C_SOURCES += $(MUSL_DIR)/src/math/__math_xflowf.c
CXX_SOURCES += src/ldpc_wrapper.cpp CXX_SOURCES += src/ldpc_wrapper.cpp
@ -24,6 +28,14 @@ OPENCM3_LIB := opencm3_stm32f4
PREFIX ?= arm-none-eabi- PREFIX ?= arm-none-eabi-
GOLD_CODE_NBITS ?= 5
FMEAS_ADC_SAMPLING_RATE ?= 1000
FMEAS_ADC_MAX ?= 4096
FMEAS_FFT_LEN ?= 256
FMEAS_FFT_WINDOW ?= gaussian
FMEAS_FFT_WINDOW_SIGMA ?= 8.0
CC := $(PREFIX)gcc CC := $(PREFIX)gcc
CXX := $(PREFIX)g++ CXX := $(PREFIX)g++
LD := $(PREFIX)gcc LD := $(PREFIX)gcc
@ -32,6 +44,7 @@ AS := $(PREFIX)as
OBJCOPY := $(PREFIX)objcopy OBJCOPY := $(PREFIX)objcopy
OBJDUMP := $(PREFIX)objdump OBJDUMP := $(PREFIX)objdump
GDB := $(PREFIX)gdb GDB := $(PREFIX)gdb
PYTHON3 ?= python3
OPENCM3_DIR_ABS := $(abspath $(OPENCM3_DIR)) OPENCM3_DIR_ABS := $(abspath $(OPENCM3_DIR))
CMSIS_DIR_ABS := $(abspath $(CMSIS_DIR)) CMSIS_DIR_ABS := $(abspath $(CMSIS_DIR))
@ -41,14 +54,17 @@ TINYAES_DIR_ABS := $(abspath $(TINYAES_DIR))
MUSL_DIR_ABS := $(abspath $(MUSL_DIR)) MUSL_DIR_ABS := $(abspath $(MUSL_DIR))
CFLAGS += -I$(OPENCM3_DIR_ABS)/include -Imspdebug/util -Imspdebug/drivers CFLAGS += -I$(OPENCM3_DIR_ABS)/include -Imspdebug/util -Imspdebug/drivers
CFLAGS += -I$(CMSIS_DIR_ABS)/CMSIS/DSP/Include -I$(CMSIS_DIR_ABS)/CMSIS/Core/Include CFLAGS += -I$(CMSIS_DIR_ABS)/CMSIS/DSP/Include -I$(CMSIS_DIR_ABS)/CMSIS/Core/Include -Dhidden=
CFLAGS += -I$(abspath musl_include_shims) CFLAGS += -I$(abspath musl_include_shims) -Ilevmarq -D
CFLAGS += -Os -std=gnu11 -g -DSTM32F4 CFLAGS += -Os -std=gnu11 -g -DSTM32F4
# Note: libopencm3 requires some standard libc definitions from stdint.h and stdbool.h, so we don't pass -nostdinc here. # Note: libopencm3 requires some standard libc definitions from stdint.h and stdbool.h, so we don't pass -nostdinc here.
CFLAGS += -nostdlib -ffreestanding CFLAGS += -nostdlib -ffreestanding
CFLAGS += -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 CFLAGS += -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16
CFLAGS += -fno-common -ffunction-sections -fdata-sections CFLAGS += -fno-common -ffunction-sections -fdata-sections
CFLAGS += -DGOLD_CODE_NBITS=$(GOLD_CODE_NBITS) -DFMEAS_FFT_LEN=$(FMEAS_FFT_LEN) -DFMEAS_ADC_MAX=$(FMEAS_ADC_MAX)
CFLAGS += -DFMEAS_ADC_SAMPLING_RATE=$(FMEAS_ADC_SAMPLING_RATE) -DFMEAS_FFT_WINDOW=$(FMEAS_FFT_WINDOW)
CFLAGS += -DFMEAS_FFT_WINDOW_SIGMA=$(FMEAS_FFT_WINDOW_SIGMA)
INT_CFLAGS += -Wall -Wextra -Wpedantic -Wshadow -Wimplicit-function-declaration -Wundef INT_CFLAGS += -Wall -Wextra -Wpedantic -Wshadow -Wimplicit-function-declaration -Wundef
INT_CFLAGS += -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes INT_CFLAGS += -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes
@ -71,7 +87,13 @@ all: $(BUILDDIR)/$(BINARY)
OBJS := $(addprefix $(BUILDDIR)/,$(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o)) OBJS := $(addprefix $(BUILDDIR)/,$(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o))
$(BUILDDIR)/$(BINARY): $(OBJS) $(OPENCM3_DIR)/lib/lib$(OPENCM3_LIB).a $(BUILDDIR)/libsodium/src/libsodium/.libs/libsodium.a $(BUILDDIR)/tinyaes/aes.o $(BUILDDIR)/$(BINARY): $(OBJS) \
$(OPENCM3_DIR)/lib/lib$(OPENCM3_LIB).a \
$(BUILDDIR)/libsodium/src/libsodium/.libs/libsodium.a \
$(BUILDDIR)/tinyaes/aes.o \
$(BUILDDIR)/levmarq/levmarq.o \
$(BUILDDIR)/generated/gold_code_$(GOLD_CODE_NBITS).o \
$(BUILDDIR)/generated/fmeas_fft_window.o
$(LD) -T$(LDSCRIPT) $(LDFLAGS) -o $@ -Wl,-Map=$(BUILDDIR)/src/$*.map $^ $(LD) -T$(LDSCRIPT) $(LDFLAGS) -o $@ -Wl,-Map=$(BUILDDIR)/src/$*.map $^
$(BUILDDIR)/src/%.o: src/%.c $(BUILDDIR)/src/%.o: src/%.c
@ -82,6 +104,10 @@ $(BUILDDIR)/src/%.o: src/%.cpp
mkdir -p $(@D) mkdir -p $(@D)
$(CXX) $(CXXFLAGS) -o $@ -c $< $(CXX) $(CXXFLAGS) -o $@ -c $<
$(BUILDDIR)/generated/%.o: $(BUILDDIR)/generated/%.c
mkdir -p $(@D)
$(CC) $(CFLAGS) $(INT_CFLAGS) -o $@ -c $<
$(BUILDDIR)/%.o: %.c $(BUILDDIR)/%.o: %.c
mkdir -p $(@D) mkdir -p $(@D)
$(CC) $(CFLAGS) $(EXT_CFLAGS) -o $@ -c $< $(CC) $(CFLAGS) $(EXT_CFLAGS) -o $@ -c $<
@ -97,11 +123,21 @@ $(BUILDDIR)/tinyaes/aes.o:
mkdir -p $(@D) mkdir -p $(@D)
make -C $(@D) -f $(TINYAES_DIR_ABS)/Makefile VPATH=$(TINYAES_DIR_ABS) CFLAGS="$(CFLAGS) -c" CC=$(CC) LD=$(LD) AR=$(AR) aes.o make -C $(@D) -f $(TINYAES_DIR_ABS)/Makefile VPATH=$(TINYAES_DIR_ABS) CFLAGS="$(CFLAGS) -c" CC=$(CC) LD=$(LD) AR=$(AR) aes.o
ldpc_decoder_test.so: ldpc_decoder.c $(BUILDDIR)/generated/gold_code_%.c:
mkdir -p $(@D)
$(PYTHON3) tools/gold_code_header_gen.py $* > $@
$(BUILDDIR)/generated/fmeas_fft_window.c:
mkdir -p $(@D)
$(PYTHON3) tools/fft_window_header_gen.py -v fmeas_fft_window_table $(FMEAS_FFT_WINDOW) $(FMEAS_FFT_LEN) $(FMEAS_FFT_WINDOW_SIGMA) > $@
build/ldpc_decoder_test.so: src/ldpc_decoder.c
gcc -fPIC -shared -Wall -Wextra -Wpedantic -std=gnu11 -O0 -g -o $@ $^ gcc -fPIC -shared -Wall -Wextra -Wpedantic -std=gnu11 -O0 -g -o $@ $^
clean: clean:
-rm -r $(BUILDDIR)/src -rm -r $(BUILDDIR)/src
-rm -r $(BUILDDIR)/generated
-rm $(BUILDDIR)/$(BINARY) -rm $(BUILDDIR)/$(BINARY)
mrproper: clean mrproper: clean

1
controller/fw/levmarq Submodule

@ -0,0 +1 @@
Subproject commit d7734ce5a436b891d00dd3445dd0b57b1dfbe778

View file

@ -0,0 +1,94 @@
#include <unistd.h>
#include <math.h>
#include <arm_math.h>
#include <levmarq.h>
#include "freq_meas.h"
#include "sr_global.h"
/* FTT window lookup table defined in generated/fmeas_fft_window.c */
extern const float * const fmeas_fft_window_table;
/* jury-rig some definitions for these functions since the ARM headers only export an over-generalized variable bin size
* variant. */
extern arm_status arm_rfft_32_fast_init_f32(arm_rfft_fast_instance_f32 * S);
extern arm_status arm_rfft_64_fast_init_f32(arm_rfft_fast_instance_f32 * S);
extern arm_status arm_rfft_128_fast_init_f32(arm_rfft_fast_instance_f32 * S);
extern arm_status arm_rfft_256_fast_init_f32(arm_rfft_fast_instance_f32 * S);
extern arm_status arm_rfft_512_fast_init_f32(arm_rfft_fast_instance_f32 * S);
extern arm_status arm_rfft_1024_fast_init_f32(arm_rfft_fast_instance_f32 * S);
extern arm_status arm_rfft_2048_fast_init_f32(arm_rfft_fast_instance_f32 * S);
extern arm_status arm_rfft_4096_fast_init_f32(arm_rfft_fast_instance_f32 * S);
#define CONCAT(A, B, C) A ## B ## C
#define arm_rfft_init_name(nbits) CONCAT(arm_rfft_, nbits, _fast_init_f32)
float func_gauss_grad(float *out, float *params, int x, void *userdata);
float func_gauss(float *params, int x, void *userdata);
int adc_buf_measure_freq(uint16_t adc_buf[FMEAS_FFT_LEN], float *out) {
int rc;
float in_buf[FMEAS_FFT_LEN];
float out_buf[FMEAS_FFT_LEN];
for (size_t i=0; i<FMEAS_FFT_LEN; i++)
in_buf[i] = (float)adc_buf[i] / (float)FMEAS_ADC_MAX * fmeas_fft_window_table[i];
arm_rfft_fast_instance_f32 fft_inst;
if ((rc = arm_rfft_init_name(FMEAS_FFT_LEN)(&fft_inst)) != ARM_MATH_SUCCESS)
return rc;
arm_rfft_fast_f32(&fft_inst, in_buf, out_buf, 0);
#define FMEAS_FFT_WINDOW_MIN_F 30.0f
#define FMEAS_FFT_WINDOW_MAX_F 70.0f
const float binsize = (float)FMEAS_ADC_SAMPLING_RATE / FMEAS_FFT_LEN;
const int first_bin = (int)(FMEAS_FFT_WINDOW_MIN_F / binsize);
const int last_bin = (int)(FMEAS_FFT_WINDOW_MAX_F / binsize + 0.5f);
const int nbins = last_bin - first_bin + 1;
/* Copy real values of target data to front of output buffer */
for (size_t i=0; i<nbins; i++)
out_buf[i] = out_buf[2 * (first_bin + i)];
LMstat lmstat;
levmarq_init(&lmstat);
float a_max = 0.0f;
int i_max = 0;
for (size_t i=0; i<nbins; i++) {
if (out_buf[i] > a_max) {
a_max = out_buf[i];
i_max = i;
}
}
float par[3] = {
a_max, i_max, 1.0f
};
if (levmarq(3, &params, nbins, out_buf, NULL, func_gauss, func_gauss_grad, NULL, &lmstat))
return -1;
*out = (params[1] + first_bin) * binsize;
return 0;
}
float func_gauss(float *params, int x, void *userdata) {
UNUSED(userdata);
float a = params[0];
float mu = params[1];
float sigma = params[2];
return a*expf(-arm_power_f32((x-mu), 2.0f/(2.0f*(sigma*sigma))));
}
float func_gauss_grad(float *out, float *params, int x, void *userdata) {
UNUSED(userdata);
float a = params[0];
float mu = params[1];
float sigma = params[2];
return -(x-mu) / ( sigma*sigma*sigma * 2.5066282746310002f) * a*expf(-arm_power_f32((x-mu), 2.0f/(2.0f*(sigma*sigma))));
}

View file

@ -0,0 +1,7 @@
#ifndef __FREQ_MEAS_H__
#define __FREQ_MEAS_H__
int adc_buf_measure_freq(uint16_t adc_buf[FMEAS_FFT_LEN], float *out);
#endif /* __FREQ_MEAS_H__ */

View file

@ -0,0 +1,4 @@
/* header file for generated gold code tables */
extern const uint8_t * const gold_code_table;

View file

@ -0,0 +1,59 @@
#!/usr/bin/env python3
import textwrap
import scipy.signal as sig
import numpy as np
WINDOW_TYPES = [
'boxcar',
'triang',
'blackman',
'hamming',
'hann',
'bartlett',
'flattop',
'parzen',
'bohman',
'blackmanharris',
'nuttall',
'barthann',
'kaiser',
'gaussian',
'general_gaussian',
'slepian',
'dpss',
'chebwin',
'exponential',
'tukey',
]
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('window', choices=WINDOW_TYPES, help='Type of window function to use')
parser.add_argument('n', type=int, help='Width of window in samples')
parser.add_argument('window_args', nargs='*', type=float,
help='''Window argument(s) if required. See https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.get_window.html#scipy.signal.get_window for details.''')
parser.add_argument('-v', '--variable', default='fft_window_table', help='Name for alias variable pointing to generated window')
args = parser.parse_args()
print(f'/* FTT window table for {args.n} sample {args.window} window.')
if args.window_args:
print(f' * Window arguments were: ({" ,".join(str(arg) for arg in args.window_args)})')
print(f' */')
winargs = ''.join(f'_{arg:.4g}'.replace('.', 'F') for arg in args.window_args)
varname = f'fft_{args.n}_window_{args.window}{winargs}'
print(f'const float {varname}[{args.n}] = {{')
win = sig.get_window(args.window if not args.window_args else (args.window, *args.window_args),
Nx=args.n, fftbins=True)
par = ' '.join(f'{f:>013.8g},' for f in win)
print(textwrap.fill(par,
initial_indent=' '*4, subsequent_indent=' '*4,
width=120,
replace_whitespace=False, drop_whitespace=False))
print('};')
print()
print(f'const float * const {args.variable} __attribute__((weak)) = {varname};')

View file

@ -0,0 +1,45 @@
#!/usr/bin/env python3
import textwrap
import numpy as np
import scipy.signal as sig
# From https://github.com/mubeta06/python/blob/master/signal_processing/sp/gold.py
preferred_pairs = {5:[[2],[1,2,3]], 6:[[5],[1,4,5]], 7:[[4],[4,5,6]],
8:[[1,2,3,6,7],[1,2,7]], 9:[[5],[3,5,6]],
10:[[2,5,9],[3,4,6,8,9]], 11:[[9],[3,6,9]]}
def gen_gold(seq1, seq2):
gold = [seq1, seq2]
for shift in range(len(seq1)):
gold.append(seq1 ^ np.roll(seq2, -shift))
return gold
def gold(n):
n = int(n)
if not n in preferred_pairs:
raise KeyError('preferred pairs for %s bits unknown' % str(n))
t0, t1 = preferred_pairs[n]
(seq0, _st0), (seq1, _st1) = sig.max_len_seq(n, taps=t0), sig.max_len_seq(n, taps=t1)
return gen_gold(seq0, seq1)
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('n', type=int, choices=preferred_pairs, help='bit width of shift register. Generate 2**n + 1 sequences of length 2**n - 1.')
args = parser.parse_args()
print('#include <unistd.h>')
print()
print(f'/* {args.n} bit gold sequences: {2**args.n+1} sequences of length {2**args.n-1} bit.')
print(f' *')
print(f' * Each code is packed left-aligned into {2**args.n // 8} bytes in big-endian byte order.')
print(f' */')
print(f'const uint8_t gold_code_{args.n}bit[] = {{')
for i, code in enumerate(gold(args.n)):
par = ' '.join(f'0x{d:02x},' for d in np.packbits(code)) + f' /* {i: 3d} "{"".join(str(x) for x in code)}" */'
print(textwrap.fill(par, initial_indent=' '*4, subsequent_indent=' '*4, width=120))
print('};')
print()
print(f'const uint8_t * const gold_code_table __attribute__((weak)) = gold_code_{args.n}bit;')

View file

@ -33,13 +33,13 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 12, "execution_count": 4,
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"data": { "data": {
"application/vnd.jupyter.widget-view+json": { "application/vnd.jupyter.widget-view+json": {
"model_id": "45cbf0c7c4314a3386adf52c261b1505", "model_id": "171a6975a39e48bcac5e1247903b70f4",
"version_major": 2, "version_major": 2,
"version_minor": 0 "version_minor": 0
}, },
@ -53,10 +53,10 @@
{ {
"data": { "data": {
"text/plain": [ "text/plain": [
"[<matplotlib.lines.Line2D at 0x7f8371954d00>]" "[<matplotlib.lines.Line2D at 0x7f0144563d30>]"
] ]
}, },
"execution_count": 12, "execution_count": 4,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
@ -88,13 +88,13 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 10, "execution_count": 6,
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"data": { "data": {
"application/vnd.jupyter.widget-view+json": { "application/vnd.jupyter.widget-view+json": {
"model_id": "125cd5cc3ac44df5885f2c82cfa80c11", "model_id": "2b835c8fb082428cabc1ad9112286728",
"version_major": 2, "version_major": 2,
"version_minor": 0 "version_minor": 0
}, },
@ -111,7 +111,7 @@
"(1e-06, 0.5)" "(1e-06, 0.5)"
] ]
}, },
"execution_count": 10, "execution_count": 6,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
@ -141,13 +141,13 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 11, "execution_count": 7,
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"data": { "data": {
"application/vnd.jupyter.widget-view+json": { "application/vnd.jupyter.widget-view+json": {
"model_id": "65216e331e154ee980d16ae5de7fbfcd", "model_id": "94ca3cb49e7d452dab8f7e2e8d632b84",
"version_major": 2, "version_major": 2,
"version_minor": 0 "version_minor": 0
}, },
@ -164,7 +164,7 @@
"(5e-07, 0.02)" "(5e-07, 0.02)"
] ]
}, },
"execution_count": 11, "execution_count": 7,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
@ -206,13 +206,13 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 9, "execution_count": 8,
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"data": { "data": {
"application/vnd.jupyter.widget-view+json": { "application/vnd.jupyter.widget-view+json": {
"model_id": "d5721ab27d01416fb7fce8449b5d2289", "model_id": "91a04300b9164bd7a9915d0028f3e563",
"version_major": 2, "version_major": 2,
"version_minor": 0 "version_minor": 0
}, },
@ -242,13 +242,13 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 15, "execution_count": 9,
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"data": { "data": {
"application/vnd.jupyter.widget-view+json": { "application/vnd.jupyter.widget-view+json": {
"model_id": "c419327f1f4f43c1903d3817d4651241", "model_id": "2811a79d4ad8487f822750e4419ccfdb",
"version_major": 2, "version_major": 2,
"version_minor": 0 "version_minor": 0
}, },
@ -278,13 +278,13 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 16, "execution_count": 10,
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"data": { "data": {
"application/vnd.jupyter.widget-view+json": { "application/vnd.jupyter.widget-view+json": {
"model_id": "7c1941babb2e4d0c951d060fa9a4ba78", "model_id": "c678197e011e4ab4982d3e1d2a2cee9a",
"version_major": 2, "version_major": 2,
"version_minor": 0 "version_minor": 0
}, },
@ -316,13 +316,13 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 17, "execution_count": 11,
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"data": { "data": {
"application/vnd.jupyter.widget-view+json": { "application/vnd.jupyter.widget-view+json": {
"model_id": "6034b96d5f08488a84d94b82cf319047", "model_id": "52bcd29a41a54ed1bf9dc63e0c9e83d8",
"version_major": 2, "version_major": 2,
"version_minor": 0 "version_minor": 0
}, },
@ -356,7 +356,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 18, "execution_count": 12,
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
@ -365,7 +365,7 @@
"15.923566878980893" "15.923566878980893"
] ]
}, },
"execution_count": 18, "execution_count": 12,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }

View file

@ -100,7 +100,7 @@
{ {
"data": { "data": {
"application/vnd.jupyter.widget-view+json": { "application/vnd.jupyter.widget-view+json": {
"model_id": "e612fe37a7c34ceaa77e8bc587b8e065", "model_id": "0b088957d9a24a74ab1b81d68099aa99",
"version_major": 2, "version_major": 2,
"version_minor": 0 "version_minor": 0
}, },
@ -177,7 +177,7 @@
{ {
"data": { "data": {
"application/vnd.jupyter.widget-view+json": { "application/vnd.jupyter.widget-view+json": {
"model_id": "f8fa09f5053c4c52866ef240c789e741", "model_id": "8a6f7e9ac8f04d1b84035c29623cfa99",
"version_major": 2, "version_major": 2,
"version_minor": 0 "version_minor": 0
}, },
@ -240,7 +240,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 13, "execution_count": 10,
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
@ -249,7 +249,7 @@
"(200.0, 800.0)" "(200.0, 800.0)"
] ]
}, },
"execution_count": 13, "execution_count": 10,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
@ -260,13 +260,13 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 10, "execution_count": 11,
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"data": { "data": {
"application/vnd.jupyter.widget-view+json": { "application/vnd.jupyter.widget-view+json": {
"model_id": "e8e8458ea5914a939c7188785efd286c", "model_id": "a3824e732a0647d4a12e8c5a567f5dc0",
"version_major": 2, "version_major": 2,
"version_minor": 0 "version_minor": 0
}, },
@ -293,13 +293,13 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 11, "execution_count": 12,
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"data": { "data": {
"application/vnd.jupyter.widget-view+json": { "application/vnd.jupyter.widget-view+json": {
"model_id": "875deca2c3d84e069dd0a5eaef4ea0aa", "model_id": "342f89b5d55f435ab132deb5d051c926",
"version_major": 2, "version_major": 2,
"version_minor": 0 "version_minor": 0
}, },
@ -370,13 +370,13 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 12, "execution_count": 13,
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"data": { "data": {
"application/vnd.jupyter.widget-view+json": { "application/vnd.jupyter.widget-view+json": {
"model_id": "a36a994f6f484a6cba81b6e680c9eee1", "model_id": "33431729d479469cb89bcf86e22508ad",
"version_major": 2, "version_major": 2,
"version_minor": 0 "version_minor": 0
}, },
@ -426,13 +426,13 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 13, "execution_count": 14,
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"data": { "data": {
"application/vnd.jupyter.widget-view+json": { "application/vnd.jupyter.widget-view+json": {
"model_id": "e4116959544f44f6a4b898419a5d51db", "model_id": "e8a4ecab028f4fcf8d9821dd66a42027",
"version_major": 2, "version_major": 2,
"version_minor": 0 "version_minor": 0
}, },
@ -510,7 +510,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 14, "execution_count": 15,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
@ -529,13 +529,13 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 15, "execution_count": 16,
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"data": { "data": {
"application/vnd.jupyter.widget-view+json": { "application/vnd.jupyter.widget-view+json": {
"model_id": "09069e2c9cb740d5b58846371aeea0f2", "model_id": "bcf4b384d95949c38a4754cdb47ae512",
"version_major": 2, "version_major": 2,
"version_minor": 0 "version_minor": 0
}, },
@ -560,7 +560,7 @@
"5.0" "5.0"
] ]
}, },
"execution_count": 15, "execution_count": 16,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
@ -597,13 +597,13 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 16, "execution_count": 17,
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"data": { "data": {
"application/vnd.jupyter.widget-view+json": { "application/vnd.jupyter.widget-view+json": {
"model_id": "b812e4b240a642398f09bb3cff8f5cee", "model_id": "cbc03380a4234b4d8160d25e867ff5a9",
"version_major": 2, "version_major": 2,
"version_minor": 0 "version_minor": 0
}, },
@ -620,7 +620,7 @@
"(1.6666666666666667e-05, 0.5)" "(1.6666666666666667e-05, 0.5)"
] ]
}, },
"execution_count": 16, "execution_count": 17,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
@ -656,13 +656,13 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 27, "execution_count": 18,
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"data": { "data": {
"application/vnd.jupyter.widget-view+json": { "application/vnd.jupyter.widget-view+json": {
"model_id": "c835382368b6423ab5446835c5785afd", "model_id": "8eb3621b74c04c4fb7dd3e919f0d1fed",
"version_major": 2, "version_major": 2,
"version_minor": 0 "version_minor": 0
}, },
@ -679,7 +679,7 @@
"(5e-07, 0.02)" "(5e-07, 0.02)"
] ]
}, },
"execution_count": 27, "execution_count": 18,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }