101 lines
3.2 KiB
Python
101 lines
3.2 KiB
Python
#!/usr/bin/python
|
|
|
|
|
|
import numpy as np
|
|
from scipy.optimize import curve_fit
|
|
from libs.models import log_gamma_loc
|
|
|
|
|
|
def modelfit_log_gamma_func(input_data, *target_data):
|
|
# unpack input_data
|
|
rx_locs = input_data
|
|
|
|
# unpack target_data
|
|
if len(target_data) < 4:
|
|
print("missing arguments, should have loc_x, loc_y, pwr, gamma at least")
|
|
return
|
|
tx_loc_x = target_data[0]
|
|
tx_loc_y = target_data[1]
|
|
tx_power = target_data[2]
|
|
env_gamma = target_data[3]
|
|
tx_loc_z = None if len(target_data) == 4 else target_data[4]
|
|
tx_loc = np.array([tx_loc_x, tx_loc_y])
|
|
if tx_loc_z is not None:
|
|
tx_loc = np.array([tx_loc_x, tx_loc_y, tx_loc_z])
|
|
return log_gamma_loc(rx_locs, tx_loc, tx_power, env_gamma)
|
|
|
|
|
|
def modelfit_log_gamma(
|
|
rx_locs,
|
|
rx_rsses,
|
|
bounds_pwr=(-60, 0),
|
|
bounds_gamma=(2, 6),
|
|
bounds_loc_x=(0, 6.2),
|
|
bounds_loc_y=(0, 6.2),
|
|
bounds_loc_z=None,
|
|
monte_carlo_sampling=False,
|
|
monte_carlo_sampling_rate=0.8
|
|
):
|
|
# initial seeds
|
|
seed_pwr = np.random.uniform(bounds_pwr[0], bounds_pwr[1])
|
|
seed_gamma = np.random.uniform(bounds_gamma[0], bounds_gamma[1])
|
|
seed_loc_x = np.random.uniform(bounds_loc_x[0], bounds_loc_x[1])
|
|
seed_loc_y = np.random.uniform(bounds_loc_y[0], bounds_loc_y[1])
|
|
if bounds_loc_z is not None:
|
|
seed_loc_z = np.random.uniform(bounds_loc_z[0], bounds_loc_z[1])
|
|
seeds = [
|
|
seed_loc_x, seed_loc_y,
|
|
seed_pwr, seed_gamma,
|
|
seed_loc_z
|
|
]
|
|
bounds = list(zip(*[
|
|
bounds_loc_x, bounds_loc_y,
|
|
bounds_pwr, bounds_gamma,
|
|
bounds_loc_z
|
|
]))
|
|
else:
|
|
seeds = [
|
|
seed_loc_x, seed_loc_y,
|
|
seed_pwr, seed_gamma
|
|
]
|
|
bounds = list(zip(*[
|
|
bounds_loc_x, bounds_loc_y,
|
|
bounds_pwr, bounds_gamma
|
|
]))
|
|
sampled_rx_locs = rx_locs
|
|
sampled_rx_rsses = rx_rsses
|
|
if monte_carlo_sampling and rx_rsses.shape[0] > 10:
|
|
logistics = np.random.choice(
|
|
np.arange(rx_rsses.shape[0]),
|
|
size=int(monte_carlo_sampling_rate * rx_rsses.shape[0]),
|
|
replace=False
|
|
)
|
|
sampled_rx_locs = rx_locs[logistics, :]
|
|
sampled_rx_rsses = rx_rsses[logistics]
|
|
|
|
# fit
|
|
popt, pcov = curve_fit(
|
|
modelfit_log_gamma_func, sampled_rx_locs, sampled_rx_rsses,
|
|
p0=seeds, bounds=bounds
|
|
)
|
|
|
|
# unpack popt
|
|
if bounds_loc_z is None:
|
|
est_loc_x, est_loc_y, est_tx_pwr, est_env_gamma = popt
|
|
est_tx_loc = np.array([est_loc_x, est_loc_y])
|
|
else:
|
|
est_loc_x, est_loc_y, est_tx_pwr, est_env_gamma, est_loc_z = popt
|
|
est_tx_loc = np.array([est_loc_x, est_loc_y, est_loc_z])
|
|
|
|
# compute fit mse
|
|
est_sampled_rsses = log_gamma_loc(sampled_rx_locs, est_tx_loc, est_tx_pwr, est_env_gamma)
|
|
est_errors = est_sampled_rsses - sampled_rx_rsses
|
|
fit_mse = 1.0 * np.nansum(est_errors * est_errors) / est_errors.shape[0]
|
|
|
|
# compute the full original map if monte_carlo_sampling enabled
|
|
est_rsses = est_sampled_rsses
|
|
if monte_carlo_sampling and rx_rsses.shape[0] > 10:
|
|
est_rsses = log_gamma_loc(rx_locs, est_tx_loc, est_tx_pwr, est_env_gamma)
|
|
|
|
return fit_mse, est_tx_loc, est_tx_pwr, est_env_gamma, est_rsses
|