commit 6614ac837e077911b7c3c2616e2e293c14d190e3 Author: Ján Malinovský Date: Wed Oct 21 14:14:51 2026 +0200 Prvy diff --git a/README.md b/README.md new file mode 100644 index 0000000..e50490a --- /dev/null +++ b/README.md @@ -0,0 +1,28 @@ +# MDS-MAP localization simulation + +This project simulates localization in an ad-hoc/sensor network using MDS-MAP +and two anchor-only baselines: circular lateration (nonlinear least squares) +and square lateration (min-max bounds). + +## Install and run + +Use Python 3.10 or newer: + +```powershell +python -m pip install -r requirements.txt +python scripts/run_single.py +python scripts/run_remote_carlo.py +pytest +``` + +The default experiment places 4 anchors and 16 unknown nodes in a 100 m +square, uses a 55 m radio range, Gaussian ranging noise, and 30 repetitions. +Outputs are written to `results/figures` and `results/tables`. Edit +`config/default.yaml` to change the experiment. A connected graph is required +for shortest-path completion; increase `radio_range` if a random run is +disconnected. + +The position figure compares actual unknown positions with all estimates and +anchors. The error-distribution figure is a histogram over all unknown nodes +and repetitions. The metrics CSV contains RMSE, MAE, mean, standard deviation, +median, maximum, and 95th percentile errors for every repetition and method. \ No newline at end of file diff --git a/config/default.yaml b/config/default.yaml new file mode 100644 index 0000000..9345e9b --- /dev/null +++ b/config/default.yaml @@ -0,0 +1,10 @@ +area_size: [100.0, 100.0] +anchor_count: 4 +unknown_count: 16 +radio_range: 55.0 +noise_model: gaussian +noise_sigma: 1.0 +multiplicative_sigma: 0.02 +repetitions: 30 +seed: 2026 +output_dir: results \ No newline at end of file diff --git a/docs/report.md b/docs/report.md new file mode 100644 index 0000000..c97ae00 --- /dev/null +++ b/docs/report.md @@ -0,0 +1,14 @@ +# First-version report + +The pipeline generates random node positions, measures only radio-connected +links, completes the distance matrix using all-pairs shortest paths, and +applies classical two-dimensional MDS. An SVD-based Procrustes similarity +transform maps the relative MDS coordinates to the known anchor coordinates. + +Circular lateration estimates each unknown by minimizing range residuals. +Square lateration intersects axis-aligned square bounds around the anchors and +uses the center of the intersection. Both baselines use only direct +anchor-to-unknown measurements. + +The Monte Carlo script records per-node errors and the metrics table, allowing +methods to be compared under the same generated networks and noise settings. \ No newline at end of file diff --git a/notebooks/analysis.ipynb b/notebooks/analysis.ipynb new file mode 100644 index 0000000..e69de29 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..f0a55a3 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,7 @@ +numpy>=1.24 +scipy>=1.10 +matplotlib>=3.7 +pandas>=2.0 +networkx>=3.0 +PyYAML>=6.0 +pytest>=7.0 \ No newline at end of file diff --git a/results/figures/error_distribution.png b/results/figures/error_distribution.png new file mode 100644 index 0000000..545af90 Binary files /dev/null and b/results/figures/error_distribution.png differ diff --git a/results/figures/single_positions.png b/results/figures/single_positions.png new file mode 100644 index 0000000..134621c Binary files /dev/null and b/results/figures/single_positions.png differ diff --git a/results/tables/monte_carlo_errors.csv b/results/tables/monte_carlo_errors.csv new file mode 100644 index 0000000..37330c1 --- /dev/null +++ b/results/tables/monte_carlo_errors.csv @@ -0,0 +1,1441 @@ +repetition,method,error +0,MDS-MAP,1.8096425019264493 +0,MDS-MAP,3.361252643359399 +0,MDS-MAP,1.1827705234761403 +0,MDS-MAP,0.4288318423413857 +0,MDS-MAP,3.0055677264833345 +0,MDS-MAP,2.293319946919274 +0,MDS-MAP,1.5152592540856946 +0,MDS-MAP,1.9215616050147621 +0,MDS-MAP,3.499173190314767 +0,MDS-MAP,0.955203166961077 +0,MDS-MAP,3.9786433573742683 +0,MDS-MAP,0.46135450637631126 +0,MDS-MAP,3.0108812602656734 +0,MDS-MAP,1.0653952746719206 +0,MDS-MAP,0.4219347489504768 +0,MDS-MAP,0.6232689663899446 +0,Circular lateration,20.758475463238277 +0,Circular lateration,52.1329531491847 +0,Circular lateration,34.59046753517319 +0,Circular lateration,60.39303493086488 +0,Circular lateration,4.402844137632711 +0,Circular lateration,37.73289795096564 +0,Circular lateration,13.778634845094956 +0,Circular lateration,96.88504803126659 +0,Circular lateration,43.141969902354454 +0,Circular lateration,38.31555181141581 +0,Circular lateration,17.87494648634003 +0,Circular lateration,89.49105753148085 +0,Circular lateration,2.2522969682493965 +0,Circular lateration,2.082827254184974 +0,Circular lateration,0.6275591455762581 +0,Circular lateration,0.8431505332481255 +0,Square lateration,19.90699669820593 +0,Square lateration,74.6598885796099 +0,Square lateration,35.80418388655937 +0,Square lateration,65.30917398105493 +0,Square lateration,3.6890176407479194 +0,Square lateration,42.41742903949016 +0,Square lateration,8.128972386611114 +0,Square lateration,82.22363715665422 +0,Square lateration,22.596618845924425 +0,Square lateration,25.244087913520477 +0,Square lateration,16.208957052938743 +0,Square lateration,92.82196959355585 +0,Square lateration,20.5207973670589 +0,Square lateration,15.66095198263396 +0,Square lateration,3.4056890459748512 +0,Square lateration,15.706251579536975 +1,MDS-MAP,132.10038459753554 +1,MDS-MAP,1.7074847744006385 +1,MDS-MAP,154.42495044494277 +1,MDS-MAP,21.884829993120533 +1,MDS-MAP,119.10333780771364 +1,MDS-MAP,7.915783343694788 +1,MDS-MAP,152.86096461963848 +1,MDS-MAP,66.26907826191153 +1,MDS-MAP,85.50358431476509 +1,MDS-MAP,13.01524666482672 +1,MDS-MAP,119.61862223594748 +1,MDS-MAP,119.22035110933433 +1,MDS-MAP,127.70496897237668 +1,MDS-MAP,154.50445738294167 +1,MDS-MAP,9.45234566212284 +1,MDS-MAP,115.76034396470213 +1,Circular lateration,58.98004785001234 +1,Circular lateration,63.738100152107236 +1,Circular lateration,63.18781377146729 +1,Circular lateration,61.26528877087669 +1,Circular lateration,44.556634015378904 +1,Circular lateration,42.61942235235798 +1,Circular lateration,58.77522073886943 +1,Circular lateration,105.70269235241321 +1,Circular lateration,23.18498984994899 +1,Circular lateration,113.07254488237886 +1,Circular lateration,71.91890409773157 +1,Circular lateration,24.67476615237944 +1,Circular lateration,38.39120027132589 +1,Circular lateration,62.25808132686654 +1,Circular lateration,1.2392377171293019 +1,Circular lateration,34.019087253905084 +1,Square lateration,61.399731999816574 +1,Square lateration,54.477318764587146 +1,Square lateration,83.03762636505944 +1,Square lateration,69.75356638874216 +1,Square lateration,60.284040957715625 +1,Square lateration,44.3277395689281 +1,Square lateration,82.39759709596703 +1,Square lateration,40.87132416788545 +1,Square lateration,52.233204905958154 +1,Square lateration,29.243908934296016 +1,Square lateration,79.13180895838039 +1,Square lateration,59.15571722496001 +1,Square lateration,62.86266683942511 +1,Square lateration,86.93801531391847 +1,Square lateration,17.269572256975234 +1,Square lateration,54.237510854802494 +2,MDS-MAP,7.829825196837947 +2,MDS-MAP,6.866196764095104 +2,MDS-MAP,4.2706787314804435 +2,MDS-MAP,13.558096423887427 +2,MDS-MAP,11.98917950334393 +2,MDS-MAP,6.222798552655802 +2,MDS-MAP,10.31011136305071 +2,MDS-MAP,10.705872558048224 +2,MDS-MAP,8.528985313979986 +2,MDS-MAP,1.1155820791413054 +2,MDS-MAP,5.6894959258693 +2,MDS-MAP,0.6216641750146675 +2,MDS-MAP,6.762333104465965 +2,MDS-MAP,7.039053558968506 +2,MDS-MAP,13.65028634375217 +2,MDS-MAP,1.5633326496860807 +2,Circular lateration,37.88560735033533 +2,Circular lateration,72.31097936692525 +2,Circular lateration,88.26532416876486 +2,Circular lateration,66.28609551922167 +2,Circular lateration,15.695554256057997 +2,Circular lateration,87.7284072636327 +2,Circular lateration,44.61065767253721 +2,Circular lateration,36.11236507918839 +2,Circular lateration,92.35989879083971 +2,Circular lateration,94.71083181490397 +2,Circular lateration,79.17903686077149 +2,Circular lateration,19.05429293633071 +2,Circular lateration,2.4397731834647924 +2,Circular lateration,19.928611628992307 +2,Circular lateration,27.35242981264306 +2,Circular lateration,12.145438579253478 +2,Square lateration,52.36039008166723 +2,Square lateration,66.99794719836423 +2,Square lateration,49.12439628608602 +2,Square lateration,58.06951369032889 +2,Square lateration,46.764121599357246 +2,Square lateration,82.0436751907646 +2,Square lateration,45.127701253846965 +2,Square lateration,42.269072491580246 +2,Square lateration,74.37929074697249 +2,Square lateration,52.45126767568141 +2,Square lateration,40.74355393247123 +2,Square lateration,28.789240903606732 +2,Square lateration,32.79673423420238 +2,Square lateration,48.36099249832547 +2,Square lateration,40.408946054242705 +2,Square lateration,27.242789177213073 +3,MDS-MAP,2.7623259553190764 +3,MDS-MAP,7.7470435979913725 +3,MDS-MAP,0.4646437159602584 +3,MDS-MAP,10.496007008331187 +3,MDS-MAP,1.5455652779651414 +3,MDS-MAP,2.4130156263240807 +3,MDS-MAP,4.734136106176655 +3,MDS-MAP,1.9834256899595046 +3,MDS-MAP,8.256503061421554 +3,MDS-MAP,3.119590597497269 +3,MDS-MAP,2.2372572811807863 +3,MDS-MAP,1.220213215883376 +3,MDS-MAP,3.085556709658804 +3,MDS-MAP,3.3962330007578543 +3,MDS-MAP,1.604006433835543 +3,MDS-MAP,3.5332682089191425 +3,Circular lateration,45.769598750385825 +3,Circular lateration,74.70901861348932 +3,Circular lateration,62.114207059816614 +3,Circular lateration,53.829314051399194 +3,Circular lateration,14.342486955253113 +3,Circular lateration,21.054413874870328 +3,Circular lateration,55.545380810385645 +3,Circular lateration,58.54698554994547 +3,Circular lateration,34.41577316444151 +3,Circular lateration,49.58249870790591 +3,Circular lateration,21.479113018188542 +3,Circular lateration,18.43381484349875 +3,Circular lateration,2.0662150909893326 +3,Circular lateration,77.21968011045794 +3,Circular lateration,2.098826887948533 +3,Circular lateration,2.0799197787777026 +3,Square lateration,26.40695768368223 +3,Square lateration,67.26928046498466 +3,Square lateration,18.92181174589812 +3,Square lateration,58.676540645368995 +3,Square lateration,37.19188717780813 +3,Square lateration,23.69163645748182 +3,Square lateration,47.64478126857779 +3,Square lateration,58.287284131048516 +3,Square lateration,56.49627509104648 +3,Square lateration,52.346984313501956 +3,Square lateration,26.49561255170193 +3,Square lateration,17.388551856668684 +3,Square lateration,27.010240465011172 +3,Square lateration,38.163925372035436 +3,Square lateration,12.148194949909042 +3,Square lateration,13.368590003484467 +4,MDS-MAP,57.19032812340169 +4,MDS-MAP,25.068756746814756 +4,MDS-MAP,9.990889918414283 +4,MDS-MAP,20.504789173844436 +4,MDS-MAP,3.0607287142615895 +4,MDS-MAP,88.2057668995198 +4,MDS-MAP,48.99241634717416 +4,MDS-MAP,63.592673407163375 +4,MDS-MAP,9.960206214542811 +4,MDS-MAP,29.027122648578935 +4,MDS-MAP,0.9083598509093511 +4,MDS-MAP,2.0458645673332465 +4,MDS-MAP,26.845940735844774 +4,MDS-MAP,40.76220993148557 +4,MDS-MAP,9.138937284603387 +4,MDS-MAP,26.697784437548457 +4,Circular lateration,43.0341788567584 +4,Circular lateration,63.88951680632521 +4,Circular lateration,46.494998201114484 +4,Circular lateration,47.419609666424705 +4,Circular lateration,19.759949223127684 +4,Circular lateration,35.372251805258365 +4,Circular lateration,38.21912116432985 +4,Circular lateration,59.845113537227206 +4,Circular lateration,18.739642763650707 +4,Circular lateration,60.819152144119364 +4,Circular lateration,29.3090528302453 +4,Circular lateration,14.27824490545149 +4,Circular lateration,4.303088300150597 +4,Circular lateration,1.690910677539593 +4,Circular lateration,2.6942966476158046 +4,Circular lateration,3.1631822248535055 +4,Square lateration,30.766237438892578 +4,Square lateration,46.40982732464278 +4,Square lateration,45.254712569936444 +4,Square lateration,41.583150914807895 +4,Square lateration,7.559790694441616 +4,Square lateration,25.26140633935527 +4,Square lateration,39.09104641675703 +4,Square lateration,38.53933564011563 +4,Square lateration,43.88616110034728 +4,Square lateration,55.700989968264395 +4,Square lateration,1.1841973899478846 +4,Square lateration,30.31493251247525 +4,Square lateration,32.032162334008355 +4,Square lateration,6.768111404826375 +4,Square lateration,29.852699425879344 +4,Square lateration,27.849912422979035 +5,MDS-MAP,1.4437532876216972 +5,MDS-MAP,1.900906472742613 +5,MDS-MAP,2.3875295752802486 +5,MDS-MAP,5.413479298540223 +5,MDS-MAP,3.3419026659774462 +5,MDS-MAP,4.3109015977572644 +5,MDS-MAP,4.084519461814833 +5,MDS-MAP,3.174506569153364 +5,MDS-MAP,2.030420942851835 +5,MDS-MAP,3.886113575400758 +5,MDS-MAP,1.0862241702316766 +5,MDS-MAP,1.9917997106323118 +5,MDS-MAP,2.8995216902524583 +5,MDS-MAP,4.37794132975626 +5,MDS-MAP,32.773206869979084 +5,MDS-MAP,0.6944435367701574 +5,Circular lateration,78.19831453470195 +5,Circular lateration,59.31389672300617 +5,Circular lateration,88.93101709649824 +5,Circular lateration,98.6286881422611 +5,Circular lateration,72.28450640655156 +5,Circular lateration,24.16626479009583 +5,Circular lateration,35.90143099000641 +5,Circular lateration,71.91760358263454 +5,Circular lateration,54.66156043587596 +5,Circular lateration,91.8186765882566 +5,Circular lateration,86.44748850944421 +5,Circular lateration,72.74711146495815 +5,Circular lateration,0.8816342843370123 +5,Circular lateration,4.462124634712609 +5,Circular lateration,3.2313575031796957 +5,Circular lateration,2.569209649594056 +5,Square lateration,69.78715953054835 +5,Square lateration,29.58815434022797 +5,Square lateration,54.978439439270836 +5,Square lateration,84.61054214239813 +5,Square lateration,49.33522197905439 +5,Square lateration,36.194878059611014 +5,Square lateration,41.26936045295859 +5,Square lateration,62.26365687765068 +5,Square lateration,43.72204995961108 +5,Square lateration,58.387674010806585 +5,Square lateration,57.93462940911668 +5,Square lateration,52.060238683902504 +5,Square lateration,15.659037851381587 +5,Square lateration,55.693192897519864 +5,Square lateration,57.1497139104787 +5,Square lateration,23.69903820096558 +6,MDS-MAP,1.5855296523448221 +6,MDS-MAP,2.6715225085002907 +6,MDS-MAP,2.0523766099035434 +6,MDS-MAP,2.850739169910647 +6,MDS-MAP,2.9054190099254087 +6,MDS-MAP,1.6455699483630721 +6,MDS-MAP,2.6264716674621775 +6,MDS-MAP,0.6376198446994558 +6,MDS-MAP,0.9036431569287987 +6,MDS-MAP,0.8221205698059109 +6,MDS-MAP,1.166590441723271 +6,MDS-MAP,2.838889862882747 +6,MDS-MAP,3.86694194821288 +6,MDS-MAP,0.5791512351965046 +6,MDS-MAP,0.3305327751889383 +6,MDS-MAP,1.1522320833008155 +6,Circular lateration,21.686168758458425 +6,Circular lateration,55.75158034269187 +6,Circular lateration,60.877592489466714 +6,Circular lateration,24.083169601350317 +6,Circular lateration,80.80282359292899 +6,Circular lateration,24.09060438363944 +6,Circular lateration,48.95305446505832 +6,Circular lateration,52.99927979336321 +6,Circular lateration,77.87860930767216 +6,Circular lateration,46.40618197914462 +6,Circular lateration,21.0778480037609 +6,Circular lateration,36.473388410182515 +6,Circular lateration,1.3800450257815564 +6,Circular lateration,0.7054472030863675 +6,Circular lateration,1.251038191863526 +6,Circular lateration,1.3733282859698113 +6,Square lateration,20.690156959675218 +6,Square lateration,59.828020786034415 +6,Square lateration,46.949306864590035 +6,Square lateration,28.114877153271017 +6,Square lateration,74.69818358853158 +6,Square lateration,31.009255926189294 +6,Square lateration,43.31249573911364 +6,Square lateration,10.23589428439797 +6,Square lateration,60.316994448812885 +6,Square lateration,46.0254122472428 +6,Square lateration,34.84779323216061 +6,Square lateration,54.77103332195379 +6,Square lateration,28.061089690685996 +6,Square lateration,5.283279718203744 +6,Square lateration,29.314774700595525 +6,Square lateration,20.893514149254866 +7,MDS-MAP,14.663935653020317 +7,MDS-MAP,7.949156209107183 +7,MDS-MAP,16.554267620021584 +7,MDS-MAP,4.725000035952799 +7,MDS-MAP,4.073435123822658 +7,MDS-MAP,3.0516631719994427 +7,MDS-MAP,0.7507748786015223 +7,MDS-MAP,6.261968031191885 +7,MDS-MAP,9.85705753341575 +7,MDS-MAP,2.0982339392812723 +7,MDS-MAP,1.4229735823289709 +7,MDS-MAP,2.2708605180572734 +7,MDS-MAP,4.585697053191991 +7,MDS-MAP,3.9773433708568104 +7,MDS-MAP,8.237349527366533 +7,MDS-MAP,2.430922487810637 +7,Circular lateration,6.087532548251693 +7,Circular lateration,42.689339074117825 +7,Circular lateration,91.15678801909966 +7,Circular lateration,40.032591373082916 +7,Circular lateration,96.17515806770614 +7,Circular lateration,46.52073925389471 +7,Circular lateration,54.3490382237322 +7,Circular lateration,50.95963388463303 +7,Circular lateration,81.45326146322353 +7,Circular lateration,40.62896731010867 +7,Circular lateration,39.43994740013365 +7,Circular lateration,13.528020306911145 +7,Circular lateration,1.474880076867908 +7,Circular lateration,0.546456620050474 +7,Circular lateration,3.350602983608745 +7,Circular lateration,0.34691923661795654 +7,Square lateration,51.57964366203661 +7,Square lateration,44.607802467238145 +7,Square lateration,68.35651600837703 +7,Square lateration,17.219631501913312 +7,Square lateration,90.19680481386244 +7,Square lateration,43.58841075978496 +7,Square lateration,57.68738636533378 +7,Square lateration,50.94853487924663 +7,Square lateration,68.45551472474094 +7,Square lateration,38.955701651605494 +7,Square lateration,35.07895814118272 +7,Square lateration,14.79797272040091 +7,Square lateration,18.303085225128413 +7,Square lateration,21.21312132868551 +7,Square lateration,12.2568160837197 +7,Square lateration,6.574579847626256 +8,MDS-MAP,3.0952060144925855 +8,MDS-MAP,1.0795331733760243 +8,MDS-MAP,1.5072279756202698 +8,MDS-MAP,1.2233717051985553 +8,MDS-MAP,1.400428386284577 +8,MDS-MAP,5.277335426175595 +8,MDS-MAP,1.5796272478211404 +8,MDS-MAP,2.355066684936711 +8,MDS-MAP,1.975606010474347 +8,MDS-MAP,1.8064009380788337 +8,MDS-MAP,1.723864634201643 +8,MDS-MAP,2.032068445427485 +8,MDS-MAP,1.9243728621128133 +8,MDS-MAP,1.9834790026348066 +8,MDS-MAP,2.25772760787079 +8,MDS-MAP,3.1322236708700646 +8,Circular lateration,51.38920541396284 +8,Circular lateration,47.121534761262005 +8,Circular lateration,51.46258114160135 +8,Circular lateration,18.08713092017517 +8,Circular lateration,77.2192568520714 +8,Circular lateration,57.73543006271733 +8,Circular lateration,65.84272873574695 +8,Circular lateration,63.56597172310178 +8,Circular lateration,26.10586266414753 +8,Circular lateration,63.02074715842679 +8,Circular lateration,63.689897276093106 +8,Circular lateration,43.884641164419754 +8,Circular lateration,1.6866491615734005 +8,Circular lateration,3.059743138579226 +8,Circular lateration,1.5673706001427898 +8,Circular lateration,4.6926472871947675 +8,Square lateration,53.324908030918664 +8,Square lateration,43.302585877844 +8,Square lateration,23.33483364565785 +8,Square lateration,29.39119502415623 +8,Square lateration,79.44514858379279 +8,Square lateration,27.83332935171038 +8,Square lateration,73.44858460570282 +8,Square lateration,28.385876271532876 +8,Square lateration,33.82288144606667 +8,Square lateration,70.12444997255425 +8,Square lateration,19.891388945160728 +8,Square lateration,61.929215630758684 +8,Square lateration,32.18271731906434 +8,Square lateration,11.96128330065889 +8,Square lateration,51.33458334769087 +8,Square lateration,29.25380043141019 +9,MDS-MAP,7.983742820083919 +9,MDS-MAP,34.39874449949074 +9,MDS-MAP,80.11262037098052 +9,MDS-MAP,66.3548743704071 +9,MDS-MAP,50.925626160752046 +9,MDS-MAP,7.550891413575943 +9,MDS-MAP,58.95324208124569 +9,MDS-MAP,123.03355597499362 +9,MDS-MAP,3.760726454659019 +9,MDS-MAP,54.0799915408295 +9,MDS-MAP,11.558849154599825 +9,MDS-MAP,80.75910161149602 +9,MDS-MAP,72.96270286352754 +9,MDS-MAP,17.42246526320295 +9,MDS-MAP,56.7698767237573 +9,MDS-MAP,34.31831801709722 +9,Circular lateration,31.622115148135066 +9,Circular lateration,20.850992101469863 +9,Circular lateration,59.01057931454149 +9,Circular lateration,103.85513225229437 +9,Circular lateration,31.507460946012703 +9,Circular lateration,37.992891986456826 +9,Circular lateration,58.154755683488794 +9,Circular lateration,23.766364799556477 +9,Circular lateration,34.48307626266331 +9,Circular lateration,47.188627841848565 +9,Circular lateration,65.08063755678214 +9,Circular lateration,43.59976780170616 +9,Circular lateration,0.7712032343141402 +9,Circular lateration,3.5308767175178244 +9,Circular lateration,0.5840035998921177 +9,Circular lateration,44.890338736492915 +9,Square lateration,20.321149718114214 +9,Square lateration,25.365644881107745 +9,Square lateration,36.123500669698466 +9,Square lateration,51.92775175745584 +9,Square lateration,32.02094880740199 +9,Square lateration,28.613343048281866 +9,Square lateration,49.86270570155219 +9,Square lateration,51.09445692925334 +9,Square lateration,9.652849437775242 +9,Square lateration,45.53278750133929 +9,Square lateration,63.88645630943104 +9,Square lateration,54.954884253618275 +9,Square lateration,26.86614894478585 +9,Square lateration,3.016350179293921 +9,Square lateration,19.44416376288595 +9,Square lateration,22.081227210773157 +10,MDS-MAP,1.2721292770460417 +10,MDS-MAP,1.383709681771458 +10,MDS-MAP,1.3213038084129944 +10,MDS-MAP,1.2340795301453522 +10,MDS-MAP,2.4998667422435097 +10,MDS-MAP,1.6363810774349408 +10,MDS-MAP,1.1417828103504428 +10,MDS-MAP,3.2477428625751004 +10,MDS-MAP,0.7379467930771975 +10,MDS-MAP,1.4142124578247797 +10,MDS-MAP,0.8217612860164205 +10,MDS-MAP,1.180378926006657 +10,MDS-MAP,1.0203432032836641 +10,MDS-MAP,2.372516570957 +10,MDS-MAP,2.8783893218434593 +10,MDS-MAP,2.810904058221609 +10,Circular lateration,63.941646296831074 +10,Circular lateration,44.95144090358834 +10,Circular lateration,41.989620357350844 +10,Circular lateration,41.484767025649 +10,Circular lateration,114.8385863544283 +10,Circular lateration,87.21606644078808 +10,Circular lateration,53.88581292886004 +10,Circular lateration,49.19346204822347 +10,Circular lateration,69.84749832028486 +10,Circular lateration,69.74884035932648 +10,Circular lateration,45.67363238063904 +10,Circular lateration,80.79866946643023 +10,Circular lateration,1.1784157500880366 +10,Circular lateration,2.1919978671309006 +10,Circular lateration,1.7482926519102338 +10,Circular lateration,2.523099345733022 +10,Square lateration,40.73169411992031 +10,Square lateration,33.86676189143993 +10,Square lateration,40.75702775112633 +10,Square lateration,22.647388235478374 +10,Square lateration,89.45446667558086 +10,Square lateration,60.40275865268304 +10,Square lateration,51.49081155761267 +10,Square lateration,42.57208273237824 +10,Square lateration,62.25810657235215 +10,Square lateration,39.888001870253355 +10,Square lateration,46.36191960774366 +10,Square lateration,48.186639394178776 +10,Square lateration,13.36327218021413 +10,Square lateration,36.818612836610725 +10,Square lateration,5.4445319988465615 +10,Square lateration,35.14001540558485 +11,MDS-MAP,3.141286739110067 +11,MDS-MAP,0.7616697346637401 +11,MDS-MAP,3.463238376924719 +11,MDS-MAP,2.672920018252081 +11,MDS-MAP,5.355327598862131 +11,MDS-MAP,4.172213712309137 +11,MDS-MAP,2.0945319359037704 +11,MDS-MAP,11.475930347382185 +11,MDS-MAP,4.373220835386713 +11,MDS-MAP,4.035007903329198 +11,MDS-MAP,2.0916752568315817 +11,MDS-MAP,4.719174476761389 +11,MDS-MAP,1.673144295289258 +11,MDS-MAP,1.1677418010787775 +11,MDS-MAP,2.2761244881149287 +11,MDS-MAP,4.801414599883582 +11,Circular lateration,39.448691141038445 +11,Circular lateration,34.83818633655431 +11,Circular lateration,10.506243530068273 +11,Circular lateration,63.547411123946105 +11,Circular lateration,19.57655510342637 +11,Circular lateration,63.10389993040152 +11,Circular lateration,55.88090730875343 +11,Circular lateration,59.753178932455214 +11,Circular lateration,29.47486893740696 +11,Circular lateration,59.56957434041198 +11,Circular lateration,79.62054347862745 +11,Circular lateration,8.273568517418411 +11,Circular lateration,1.3508644847308553 +11,Circular lateration,74.37087061289031 +11,Circular lateration,0.7836865900332055 +11,Circular lateration,0.46735291222530695 +11,Square lateration,33.45694738337565 +11,Square lateration,4.3518491016797185 +11,Square lateration,11.265580314180264 +11,Square lateration,14.65480479142615 +11,Square lateration,17.896642365118606 +11,Square lateration,67.94645160288945 +11,Square lateration,40.681355427629974 +11,Square lateration,74.25605309539402 +11,Square lateration,29.25385437728017 +11,Square lateration,23.996219589471288 +11,Square lateration,80.93635896211804 +11,Square lateration,37.22183210165265 +11,Square lateration,8.591003619769111 +11,Square lateration,40.30992580314805 +11,Square lateration,4.1544414865661325 +11,Square lateration,38.81718193755445 +12,MDS-MAP,30.45062835292178 +12,MDS-MAP,69.74931407993141 +12,MDS-MAP,62.23926759225582 +12,MDS-MAP,49.44651551886821 +12,MDS-MAP,84.3422848043104 +12,MDS-MAP,31.568245524171076 +12,MDS-MAP,65.56625957973635 +12,MDS-MAP,72.6219085092033 +12,MDS-MAP,53.05818813262967 +12,MDS-MAP,95.0659939561794 +12,MDS-MAP,9.233838967914892 +12,MDS-MAP,3.492045765570928 +12,MDS-MAP,9.42907481494203 +12,MDS-MAP,22.93018168801703 +12,MDS-MAP,63.78425680970562 +12,MDS-MAP,4.193088141325295 +12,Circular lateration,75.6029268872449 +12,Circular lateration,40.34858657864962 +12,Circular lateration,61.89563065502907 +12,Circular lateration,60.328859352382416 +12,Circular lateration,90.70643165184782 +12,Circular lateration,55.17886711544589 +12,Circular lateration,66.86170376560396 +12,Circular lateration,35.824076433210045 +12,Circular lateration,79.32221873638835 +12,Circular lateration,79.338220464669 +12,Circular lateration,30.232523661787344 +12,Circular lateration,14.356228683122248 +12,Circular lateration,6.183846673619549 +12,Circular lateration,1.5445865704670791 +12,Circular lateration,1.198560992679868 +12,Circular lateration,6.293793058569835 +12,Square lateration,71.49018544207341 +12,Square lateration,44.697781464304924 +12,Square lateration,44.69112156026866 +12,Square lateration,44.61007713278827 +12,Square lateration,84.1085157934101 +12,Square lateration,52.580290145880596 +12,Square lateration,60.32753788427287 +12,Square lateration,36.52581724053823 +12,Square lateration,73.37700357454791 +12,Square lateration,64.4292753529277 +12,Square lateration,7.989046271499952 +12,Square lateration,12.331262812502086 +12,Square lateration,4.055718956914249 +12,Square lateration,15.20839741215472 +12,Square lateration,24.82904494340541 +12,Square lateration,2.182831754201394 +13,MDS-MAP,1.5814416170597438 +13,MDS-MAP,0.9180798313425734 +13,MDS-MAP,2.4209600524292507 +13,MDS-MAP,1.7567859801659185 +13,MDS-MAP,0.33549048148724053 +13,MDS-MAP,1.7088766740756194 +13,MDS-MAP,1.3848697873672449 +13,MDS-MAP,1.651195990981782 +13,MDS-MAP,3.2219358867319587 +13,MDS-MAP,0.7379089329112927 +13,MDS-MAP,2.047507333510048 +13,MDS-MAP,0.5290950887677678 +13,MDS-MAP,4.730287165926998 +13,MDS-MAP,9.572599566724628 +13,MDS-MAP,1.3701174644650604 +13,MDS-MAP,0.9515309787293078 +13,Circular lateration,34.587238531077965 +13,Circular lateration,64.55003348759055 +13,Circular lateration,60.387018334225864 +13,Circular lateration,61.72538481850007 +13,Circular lateration,67.50563711226016 +13,Circular lateration,34.21664868459413 +13,Circular lateration,30.581230523967527 +13,Circular lateration,43.54026465984893 +13,Circular lateration,50.3478783022907 +13,Circular lateration,52.59431492033957 +13,Circular lateration,76.71289949529327 +13,Circular lateration,60.48116221106656 +13,Circular lateration,1.4196330770815988 +13,Circular lateration,2.436902554599474 +13,Circular lateration,0.9083292656917942 +13,Circular lateration,1.6580270660702563 +13,Square lateration,42.25738379667419 +13,Square lateration,61.25343235507883 +13,Square lateration,59.752093196714654 +13,Square lateration,41.55078303541329 +13,Square lateration,61.20236652758884 +13,Square lateration,36.073018333370946 +13,Square lateration,28.55441927618469 +13,Square lateration,44.288816441544384 +13,Square lateration,34.60825917129634 +13,Square lateration,48.63094470633982 +13,Square lateration,63.09338958846434 +13,Square lateration,53.9187311103894 +13,Square lateration,65.84431477484452 +13,Square lateration,18.046922222125843 +13,Square lateration,17.96051965640158 +13,Square lateration,16.5981196992404 +14,MDS-MAP,3.0092330414308774 +14,MDS-MAP,2.283693391830993 +14,MDS-MAP,1.6620001751301339 +14,MDS-MAP,2.639384466605923 +14,MDS-MAP,1.877096010991359 +14,MDS-MAP,2.3360001768618384 +14,MDS-MAP,1.729127892165237 +14,MDS-MAP,5.572865068980912 +14,MDS-MAP,3.3926601531090435 +14,MDS-MAP,9.001952922608695 +14,MDS-MAP,15.192536389037334 +14,MDS-MAP,3.5116823771862005 +14,MDS-MAP,3.5542950237629616 +14,MDS-MAP,1.1089582505968292 +14,MDS-MAP,2.2910353823656147 +14,MDS-MAP,3.2735833772266623 +14,Circular lateration,79.63666556574412 +14,Circular lateration,6.872630128810055 +14,Circular lateration,29.97334009610381 +14,Circular lateration,41.508787585992124 +14,Circular lateration,36.05499127168008 +14,Circular lateration,41.31557674191374 +14,Circular lateration,63.86074904221249 +14,Circular lateration,12.119604298109447 +14,Circular lateration,63.082874667073916 +14,Circular lateration,34.69341300681079 +14,Circular lateration,76.29822697075733 +14,Circular lateration,14.98235378693217 +14,Circular lateration,1.400127256558628 +14,Circular lateration,1.706179749247172 +14,Circular lateration,1.6392957927936 +14,Circular lateration,5.569678698810957 +14,Square lateration,84.57357738605965 +14,Square lateration,10.41486532104026 +14,Square lateration,37.989652387131166 +14,Square lateration,45.62265457886259 +14,Square lateration,40.14772362801795 +14,Square lateration,16.08347376181171 +14,Square lateration,60.81374894132389 +14,Square lateration,6.74411069429528 +14,Square lateration,63.01338958278507 +14,Square lateration,32.51185441963381 +14,Square lateration,81.1032566560281 +14,Square lateration,15.27217048023191 +14,Square lateration,7.9759232824637945 +14,Square lateration,3.0781319399799956 +14,Square lateration,4.5663340628504585 +14,Square lateration,4.331136705547868 +15,MDS-MAP,0.6050955761281581 +15,MDS-MAP,1.6652078461386268 +15,MDS-MAP,0.7282144156885123 +15,MDS-MAP,1.447001073098149 +15,MDS-MAP,1.9872661653019128 +15,MDS-MAP,1.040355880571539 +15,MDS-MAP,0.9144477624704205 +15,MDS-MAP,1.6212552529932966 +15,MDS-MAP,1.4292171473190833 +15,MDS-MAP,0.8109909519761752 +15,MDS-MAP,0.9200867397816094 +15,MDS-MAP,0.7386040155561924 +15,MDS-MAP,1.253433463765034 +15,MDS-MAP,0.7123812352726058 +15,MDS-MAP,2.447716323126961 +15,MDS-MAP,1.2013551170204673 +15,Circular lateration,81.71574767085636 +15,Circular lateration,64.34716562423742 +15,Circular lateration,85.63387597380695 +15,Circular lateration,60.01070454122429 +15,Circular lateration,49.557928378026865 +15,Circular lateration,28.564610054572057 +15,Circular lateration,58.19379123769278 +15,Circular lateration,69.30072929929273 +15,Circular lateration,46.772868439145924 +15,Circular lateration,53.61912523577675 +15,Circular lateration,49.68467150358579 +15,Circular lateration,69.57356558334693 +15,Circular lateration,23.448254724815627 +15,Circular lateration,1.6884799230796133 +15,Circular lateration,56.08270517476422 +15,Circular lateration,92.56010223504823 +15,Square lateration,63.931401275998496 +15,Square lateration,51.551229843270285 +15,Square lateration,33.71833935631521 +15,Square lateration,33.27920242405495 +15,Square lateration,39.51830992234479 +15,Square lateration,28.148511660798466 +15,Square lateration,53.281999175062076 +15,Square lateration,48.40753763821248 +15,Square lateration,31.041862465281614 +15,Square lateration,40.88217072408648 +15,Square lateration,13.25027661624868 +15,Square lateration,23.92173179443448 +15,Square lateration,17.211678025618582 +15,Square lateration,32.970470399471445 +15,Square lateration,39.25961089217 +15,Square lateration,47.64179255335014 +16,MDS-MAP,28.743719124538348 +16,MDS-MAP,40.47839007757884 +16,MDS-MAP,71.44220878591807 +16,MDS-MAP,17.71944103410247 +16,MDS-MAP,55.83328332780149 +16,MDS-MAP,4.89117033019484 +16,MDS-MAP,31.726988961469022 +16,MDS-MAP,14.957762539163923 +16,MDS-MAP,101.33507969494782 +16,MDS-MAP,44.86378027770342 +16,MDS-MAP,108.21902501556505 +16,MDS-MAP,131.29314676931065 +16,MDS-MAP,74.68525084010209 +16,MDS-MAP,85.41302629596969 +16,MDS-MAP,64.58963949391887 +16,MDS-MAP,0.6695351432114817 +16,Circular lateration,41.80411567632386 +16,Circular lateration,64.3366678305219 +16,Circular lateration,65.64263660644352 +16,Circular lateration,53.238126824218206 +16,Circular lateration,24.68572320950283 +16,Circular lateration,18.38981858566279 +16,Circular lateration,69.11883605120283 +16,Circular lateration,77.90649951769777 +16,Circular lateration,99.15759476797687 +16,Circular lateration,64.24534309217597 +16,Circular lateration,22.517119083064095 +16,Circular lateration,74.96625532770148 +16,Circular lateration,0.6920889798874553 +16,Circular lateration,1.4087185481265159 +16,Circular lateration,0.4991385956614281 +16,Circular lateration,0.9582622755300052 +16,Square lateration,24.292827349306958 +16,Square lateration,63.10781599155121 +16,Square lateration,43.48063687802796 +16,Square lateration,54.32454811847847 +16,Square lateration,27.207403818852924 +16,Square lateration,10.175092973534959 +16,Square lateration,31.13322349371747 +16,Square lateration,48.83714730823657 +16,Square lateration,64.18244781009933 +16,Square lateration,35.583511255324396 +16,Square lateration,44.45548586674477 +16,Square lateration,74.32996795543133 +16,Square lateration,40.92950051874058 +16,Square lateration,29.89373121573352 +16,Square lateration,22.30774248285812 +16,Square lateration,1.8598373462400815 +17,MDS-MAP,1.514672992497411 +17,MDS-MAP,1.7098555122972223 +17,MDS-MAP,0.49182061073665473 +17,MDS-MAP,2.6240475510222425 +17,MDS-MAP,3.043659419755073 +17,MDS-MAP,1.9862728073695466 +17,MDS-MAP,2.223447426334696 +17,MDS-MAP,6.341403276845636 +17,MDS-MAP,4.875756235965961 +17,MDS-MAP,1.716885652016475 +17,MDS-MAP,3.3887505649202954 +17,MDS-MAP,1.7459744357963747 +17,MDS-MAP,3.0095095464338053 +17,MDS-MAP,4.532419547502806 +17,MDS-MAP,2.4400495897876033 +17,MDS-MAP,1.459174758674573 +17,Circular lateration,57.70465190123326 +17,Circular lateration,80.28978675266092 +17,Circular lateration,35.88585692901826 +17,Circular lateration,70.22844266859067 +17,Circular lateration,98.33996430050375 +17,Circular lateration,39.740569801502055 +17,Circular lateration,31.986038213786433 +17,Circular lateration,56.064381224018035 +17,Circular lateration,95.10188308945837 +17,Circular lateration,45.426122981118546 +17,Circular lateration,30.30843274208632 +17,Circular lateration,38.98253067254318 +17,Circular lateration,1.698652394027199 +17,Circular lateration,4.30283370066899 +17,Circular lateration,5.023212150874325 +17,Circular lateration,2.1376545437161045 +17,Square lateration,65.15703084017771 +17,Square lateration,56.50954100715878 +17,Square lateration,37.92112799687124 +17,Square lateration,40.05102637585243 +17,Square lateration,63.97199176245357 +17,Square lateration,30.519415141468887 +17,Square lateration,54.83827473642154 +17,Square lateration,59.833315480261525 +17,Square lateration,76.66926777515424 +17,Square lateration,48.302991214261446 +17,Square lateration,26.44416770362301 +17,Square lateration,12.225133978954611 +17,Square lateration,32.98127696253789 +17,Square lateration,22.625324149340447 +17,Square lateration,53.58096981760492 +17,Square lateration,43.00158016881512 +18,MDS-MAP,53.11103415593215 +18,MDS-MAP,37.9608102036034 +18,MDS-MAP,21.251865349187028 +18,MDS-MAP,87.38504909112143 +18,MDS-MAP,47.72272219153767 +18,MDS-MAP,55.939115862402076 +18,MDS-MAP,14.03711506192164 +18,MDS-MAP,41.16191658147403 +18,MDS-MAP,59.147618483920574 +18,MDS-MAP,39.843383853896974 +18,MDS-MAP,0.7798119418255631 +18,MDS-MAP,15.483447204568524 +18,MDS-MAP,38.334579065423355 +18,MDS-MAP,73.88838392499672 +18,MDS-MAP,94.0302941222651 +18,MDS-MAP,23.925891313380472 +18,Circular lateration,65.86259877624741 +18,Circular lateration,29.05688892309742 +18,Circular lateration,9.335202608240687 +18,Circular lateration,68.14795669855297 +18,Circular lateration,70.24345430809842 +18,Circular lateration,20.944138941380906 +18,Circular lateration,6.27048831217129 +18,Circular lateration,35.83565475894172 +18,Circular lateration,103.98084517106099 +18,Circular lateration,64.64739550578054 +18,Circular lateration,87.7610988570487 +18,Circular lateration,35.756725106227876 +18,Circular lateration,5.833950587197409 +18,Circular lateration,1.4203797417941944 +18,Circular lateration,2.8280841950876714 +18,Circular lateration,0.48802086904114167 +18,Square lateration,54.1885162849634 +18,Square lateration,16.58946454842943 +18,Square lateration,15.642152600345872 +18,Square lateration,57.77683348785427 +18,Square lateration,54.309929307313936 +18,Square lateration,26.92174847102946 +18,Square lateration,9.849127844688317 +18,Square lateration,38.15168295996093 +18,Square lateration,88.58172204599529 +18,Square lateration,65.04043086848701 +18,Square lateration,67.02150613104143 +18,Square lateration,36.98360536018487 +18,Square lateration,19.422443111282476 +18,Square lateration,0.6764895558148041 +18,Square lateration,25.07292504962557 +18,Square lateration,7.240974273238235 +19,MDS-MAP,0.4673303469152433 +19,MDS-MAP,0.7408258700991665 +19,MDS-MAP,1.5644413207541485 +19,MDS-MAP,2.098417950599192 +19,MDS-MAP,1.6340748309293727 +19,MDS-MAP,1.4780535613897001 +19,MDS-MAP,3.5978247075835905 +19,MDS-MAP,1.032455161119772 +19,MDS-MAP,1.6339288574558457 +19,MDS-MAP,2.3639162587710314 +19,MDS-MAP,0.9803829410402427 +19,MDS-MAP,2.6485059418588155 +19,MDS-MAP,3.2440858313393695 +19,MDS-MAP,2.344205899701721 +19,MDS-MAP,1.1126652341328638 +19,MDS-MAP,1.6852885384516367 +19,Circular lateration,25.605243050000787 +19,Circular lateration,27.69708282997426 +19,Circular lateration,32.527244836408386 +19,Circular lateration,56.5876157915094 +19,Circular lateration,24.667321557525646 +19,Circular lateration,43.199792513426544 +19,Circular lateration,52.70949187041597 +19,Circular lateration,54.267051322733735 +19,Circular lateration,36.20888102444059 +19,Circular lateration,49.71051543490964 +19,Circular lateration,22.047472910878692 +19,Circular lateration,20.48918194004584 +19,Circular lateration,1.3084236927886288 +19,Circular lateration,1.780430319866706 +19,Circular lateration,1.7917232672433678 +19,Circular lateration,76.09233791394873 +19,Square lateration,14.171460429792392 +19,Square lateration,12.297999034603059 +19,Square lateration,20.25730934210159 +19,Square lateration,69.09042188907085 +19,Square lateration,28.795372912603323 +19,Square lateration,37.2536216683044 +19,Square lateration,53.434145705133034 +19,Square lateration,47.74051005900028 +19,Square lateration,37.357759073197464 +19,Square lateration,57.61990533416098 +19,Square lateration,1.9610784328450475 +19,Square lateration,57.93887081805741 +19,Square lateration,16.59292754980268 +19,Square lateration,8.56073923985013 +19,Square lateration,22.315755803751188 +19,Square lateration,35.87694393593071 +20,MDS-MAP,9.117857526928214 +20,MDS-MAP,42.22669017721573 +20,MDS-MAP,57.25748727695468 +20,MDS-MAP,73.22968280145018 +20,MDS-MAP,71.80973670029086 +20,MDS-MAP,102.08110726231311 +20,MDS-MAP,113.509781745756 +20,MDS-MAP,45.754682388953746 +20,MDS-MAP,15.841472632962564 +20,MDS-MAP,97.28503697614332 +20,MDS-MAP,65.57827732048806 +20,MDS-MAP,15.665161997113923 +20,MDS-MAP,28.892769620001687 +20,MDS-MAP,22.290592893664016 +20,MDS-MAP,39.01637631588058 +20,MDS-MAP,50.980054225051106 +20,Circular lateration,40.14854224224834 +20,Circular lateration,38.61027844507328 +20,Circular lateration,24.238963685973783 +20,Circular lateration,84.95198958516787 +20,Circular lateration,36.073942168480784 +20,Circular lateration,1.1155858150225741 +20,Circular lateration,92.71719695510292 +20,Circular lateration,60.54784311437401 +20,Circular lateration,24.778818016447673 +20,Circular lateration,62.922089043643275 +20,Circular lateration,53.42044540284632 +20,Circular lateration,57.406797818237976 +20,Circular lateration,2.399361171981224 +20,Circular lateration,2.2549098020946325 +20,Circular lateration,0.3856480650784374 +20,Circular lateration,0.4929122057857174 +20,Square lateration,26.75825968020585 +20,Square lateration,19.413090691067904 +20,Square lateration,12.096375002049077 +20,Square lateration,47.134643542092334 +20,Square lateration,35.03386153519866 +20,Square lateration,25.9899549953368 +20,Square lateration,57.6455479427844 +20,Square lateration,40.38583963223083 +20,Square lateration,24.306589717334006 +20,Square lateration,49.176996849476915 +20,Square lateration,57.199722471941236 +20,Square lateration,21.966247506775385 +20,Square lateration,3.1492696569822387 +20,Square lateration,18.637116102149175 +20,Square lateration,4.878507853232023 +20,Square lateration,36.56701405802016 +21,MDS-MAP,41.135932187723675 +21,MDS-MAP,25.50438441095066 +21,MDS-MAP,122.69000685998019 +21,MDS-MAP,31.64429994379402 +21,MDS-MAP,120.95497370764222 +21,MDS-MAP,64.3526436081159 +21,MDS-MAP,29.839056360356672 +21,MDS-MAP,54.27785577237416 +21,MDS-MAP,59.484172814160836 +21,MDS-MAP,19.314573152199905 +21,MDS-MAP,56.69968802445737 +21,MDS-MAP,72.67499884577218 +21,MDS-MAP,46.69703994394017 +21,MDS-MAP,29.72011136794991 +21,MDS-MAP,47.45008123752416 +21,MDS-MAP,0.4468478612244815 +21,Circular lateration,49.068127842178754 +21,Circular lateration,19.604109622671373 +21,Circular lateration,52.538552094315314 +21,Circular lateration,21.88118236422285 +21,Circular lateration,83.71874032272832 +21,Circular lateration,28.971177682191655 +21,Circular lateration,34.718748774993 +21,Circular lateration,68.123018799166 +21,Circular lateration,11.37327194128522 +21,Circular lateration,21.251903637496 +21,Circular lateration,24.437296805958553 +21,Circular lateration,35.542502764595945 +21,Circular lateration,0.8132851928227479 +21,Circular lateration,1.3300037401077716 +21,Circular lateration,1.1676739591112169 +21,Circular lateration,1.2745309146676143 +21,Square lateration,16.50917613122958 +21,Square lateration,18.76444860273923 +21,Square lateration,61.208627072246784 +21,Square lateration,19.04676480036681 +21,Square lateration,78.46165875539442 +21,Square lateration,32.11399530132271 +21,Square lateration,36.11523456160722 +21,Square lateration,39.88121459532336 +21,Square lateration,24.279479680179314 +21,Square lateration,7.709090213068808 +21,Square lateration,32.74581372587489 +21,Square lateration,38.47115994721153 +21,Square lateration,12.893940522869885 +21,Square lateration,23.98895952410933 +21,Square lateration,19.655010334786972 +21,Square lateration,12.662822101958975 +22,MDS-MAP,1.1314334351583022 +22,MDS-MAP,3.290513602643628 +22,MDS-MAP,0.7646035320090528 +22,MDS-MAP,4.204940503082699 +22,MDS-MAP,2.402050709495825 +22,MDS-MAP,0.4492167968978389 +22,MDS-MAP,0.7086558270321177 +22,MDS-MAP,1.8330794533660328 +22,MDS-MAP,1.9030750964733032 +22,MDS-MAP,1.0176304315238514 +22,MDS-MAP,1.1660538312036353 +22,MDS-MAP,1.6840267142739858 +22,MDS-MAP,2.578995453257712 +22,MDS-MAP,1.9296704228736115 +22,MDS-MAP,1.8652093742007128 +22,MDS-MAP,3.8199699502199085 +22,Circular lateration,27.786475413744885 +22,Circular lateration,54.29212869969182 +22,Circular lateration,51.328861371945464 +22,Circular lateration,52.6953073838022 +22,Circular lateration,32.36737760405231 +22,Circular lateration,55.68016808292707 +22,Circular lateration,21.6492434251116 +22,Circular lateration,66.20315741928451 +22,Circular lateration,31.886578079775212 +22,Circular lateration,13.308606416310013 +22,Circular lateration,4.512191096358083 +22,Circular lateration,84.9502592125001 +22,Circular lateration,1.2394538697795994 +22,Circular lateration,3.296010437088151 +22,Circular lateration,3.4104477098087433 +22,Circular lateration,1.5345022319205415 +22,Square lateration,49.57188480028902 +22,Square lateration,56.980081994450906 +22,Square lateration,39.72822879889151 +22,Square lateration,42.45175017273396 +22,Square lateration,31.69963476829511 +22,Square lateration,63.7693353671699 +22,Square lateration,29.673554250149245 +22,Square lateration,57.93698469650087 +22,Square lateration,40.88360871603828 +22,Square lateration,13.329802192154181 +22,Square lateration,6.2603358667323175 +22,Square lateration,76.8495999708694 +22,Square lateration,12.008414320489498 +22,Square lateration,13.833427336191827 +22,Square lateration,7.036986634983064 +22,Square lateration,47.08282292442138 +23,MDS-MAP,2.946230730460074 +23,MDS-MAP,4.339670262505556 +23,MDS-MAP,2.265784352296047 +23,MDS-MAP,3.7057631288632087 +23,MDS-MAP,2.5070233306281535 +23,MDS-MAP,4.849031517294981 +23,MDS-MAP,2.2469177659462716 +23,MDS-MAP,2.719722271010889 +23,MDS-MAP,2.119784505761398 +23,MDS-MAP,2.785725687426313 +23,MDS-MAP,4.135514071255931 +23,MDS-MAP,2.0717999717546953 +23,MDS-MAP,3.2576630973783427 +23,MDS-MAP,4.5431475810843045 +23,MDS-MAP,2.756222239921567 +23,MDS-MAP,1.9641221749212714 +23,Circular lateration,67.13422125364228 +23,Circular lateration,97.64322600984542 +23,Circular lateration,28.140342154250096 +23,Circular lateration,43.854805240361515 +23,Circular lateration,67.88517556962218 +23,Circular lateration,44.07300757165231 +23,Circular lateration,55.97818035460755 +23,Circular lateration,51.06911971134757 +23,Circular lateration,56.32756153369408 +23,Circular lateration,19.35833726901824 +23,Circular lateration,64.17374115228657 +23,Circular lateration,70.59875440337206 +23,Circular lateration,1.819684337568812 +23,Circular lateration,41.86399605247777 +23,Circular lateration,49.859315387894355 +23,Circular lateration,13.663952576577543 +23,Square lateration,68.95591495229476 +23,Square lateration,90.60077168231615 +23,Square lateration,23.147567470908278 +23,Square lateration,24.18980847316066 +23,Square lateration,42.95012623948193 +23,Square lateration,49.53097903957901 +23,Square lateration,21.94362783943184 +23,Square lateration,51.644129837475305 +23,Square lateration,59.47651532175785 +23,Square lateration,37.76398169244784 +23,Square lateration,45.17357334234201 +23,Square lateration,68.71153863520559 +23,Square lateration,42.08721307366177 +23,Square lateration,22.0368640823992 +23,Square lateration,24.30512729007005 +23,Square lateration,7.9472482184262825 +24,MDS-MAP,4.374575748025075 +24,MDS-MAP,2.8652641655371953 +24,MDS-MAP,4.507446770168268 +24,MDS-MAP,3.1883058751723916 +24,MDS-MAP,1.1306269052347275 +24,MDS-MAP,1.7252124430754079 +24,MDS-MAP,2.7832300950695665 +24,MDS-MAP,2.293167215223234 +24,MDS-MAP,1.1850921832978738 +24,MDS-MAP,5.426110622622798 +24,MDS-MAP,3.6804699229034226 +24,MDS-MAP,2.3418933281772962 +24,MDS-MAP,1.146434938204854 +24,MDS-MAP,1.4108568539690587 +24,MDS-MAP,1.2034779051800744 +24,MDS-MAP,7.254101956700976 +24,Circular lateration,96.62673680815409 +24,Circular lateration,69.0378520677268 +24,Circular lateration,26.633690067582002 +24,Circular lateration,65.52538934762981 +24,Circular lateration,34.35771777475692 +24,Circular lateration,65.28595752161173 +24,Circular lateration,52.851910242495826 +24,Circular lateration,59.667771551182106 +24,Circular lateration,44.5603519075226 +24,Circular lateration,69.22127172316036 +24,Circular lateration,13.336441797844314 +24,Circular lateration,45.794390272287366 +24,Circular lateration,0.7059179926296151 +24,Circular lateration,1.138449597496588 +24,Circular lateration,0.6226127638133266 +24,Circular lateration,8.185608531011333 +24,Square lateration,69.99097068057958 +24,Square lateration,63.94834443473513 +24,Square lateration,21.503236618281452 +24,Square lateration,63.8407531888733 +24,Square lateration,35.40343204748949 +24,Square lateration,59.47590766303715 +24,Square lateration,28.313661482344152 +24,Square lateration,60.80749952671574 +24,Square lateration,38.43807277165695 +24,Square lateration,65.48647919899193 +24,Square lateration,54.913215402769666 +24,Square lateration,21.228289592620627 +24,Square lateration,13.241203050189558 +24,Square lateration,9.120552284231382 +24,Square lateration,42.16394076666998 +24,Square lateration,57.949480653936845 +25,MDS-MAP,1.9818472253431767 +25,MDS-MAP,2.455645041139276 +25,MDS-MAP,1.191918597375824 +25,MDS-MAP,3.2053757394060503 +25,MDS-MAP,2.2215532694811664 +25,MDS-MAP,0.5892651958340627 +25,MDS-MAP,1.283696199831959 +25,MDS-MAP,1.2678388062833732 +25,MDS-MAP,0.9899597234529104 +25,MDS-MAP,1.4360359658626807 +25,MDS-MAP,0.15335390921487368 +25,MDS-MAP,1.698685412073158 +25,MDS-MAP,1.1686823662001027 +25,MDS-MAP,1.142474843113804 +25,MDS-MAP,1.932283757110502 +25,MDS-MAP,1.7473378478867516 +25,Circular lateration,58.193223105655235 +25,Circular lateration,49.19428304755718 +25,Circular lateration,71.91993969813228 +25,Circular lateration,100.64479219243462 +25,Circular lateration,41.76787607338637 +25,Circular lateration,14.885557713691828 +25,Circular lateration,66.48344327905635 +25,Circular lateration,26.50421845708952 +25,Circular lateration,35.1517199650461 +25,Circular lateration,14.603470998836055 +25,Circular lateration,80.94309720231453 +25,Circular lateration,39.12463184383552 +25,Circular lateration,1.0102357274325606 +25,Circular lateration,1.0978989756289343 +25,Circular lateration,1.9701005188750624 +25,Circular lateration,4.841102820505347 +25,Square lateration,54.528547390313676 +25,Square lateration,80.1747882643584 +25,Square lateration,72.37860489304602 +25,Square lateration,86.53432907821617 +25,Square lateration,66.9146155882158 +25,Square lateration,31.422449840071216 +25,Square lateration,48.563389105665934 +25,Square lateration,40.33239274042587 +25,Square lateration,40.885933303964606 +25,Square lateration,35.73082022519667 +25,Square lateration,34.13770557297621 +25,Square lateration,32.67422047578089 +25,Square lateration,13.48940304223426 +25,Square lateration,22.338252675496733 +25,Square lateration,69.88245158506247 +25,Square lateration,23.890329212249316 +26,MDS-MAP,11.63293837464996 +26,MDS-MAP,40.193074180115424 +26,MDS-MAP,52.73827099768758 +26,MDS-MAP,160.35701624075972 +26,MDS-MAP,52.99576846752935 +26,MDS-MAP,15.139457247366462 +26,MDS-MAP,66.67577163260371 +26,MDS-MAP,70.29591626828888 +26,MDS-MAP,65.71701818567425 +26,MDS-MAP,0.6808515939304786 +26,MDS-MAP,56.868708260497776 +26,MDS-MAP,13.495207975457584 +26,MDS-MAP,133.83379057954843 +26,MDS-MAP,23.25290611124651 +26,MDS-MAP,13.602447144839045 +26,MDS-MAP,6.500238230306064 +26,Circular lateration,24.358584586282742 +26,Circular lateration,13.287779497655839 +26,Circular lateration,58.82188038930167 +26,Circular lateration,112.57535412463584 +26,Circular lateration,55.90852573006228 +26,Circular lateration,40.9987941098011 +26,Circular lateration,37.15975960181108 +26,Circular lateration,69.3085272913823 +26,Circular lateration,103.96609069217446 +26,Circular lateration,16.887236320253088 +26,Circular lateration,32.758492189437135 +26,Circular lateration,36.88671711938151 +26,Circular lateration,8.583063356562155 +26,Circular lateration,1.7981810445490451 +26,Circular lateration,1.3896507881841451 +26,Circular lateration,1.3075207766939076 +26,Square lateration,16.311379468545347 +26,Square lateration,35.76671873235115 +26,Square lateration,42.712497087301145 +26,Square lateration,104.69810184851322 +26,Square lateration,25.487307030738272 +26,Square lateration,43.09142443312215 +26,Square lateration,49.04172760167667 +26,Square lateration,49.64988823383055 +26,Square lateration,50.75132042932953 +26,Square lateration,11.846649758411898 +26,Square lateration,28.95901498799316 +26,Square lateration,71.29369311436 +26,Square lateration,52.18181641213668 +26,Square lateration,6.412557359468619 +26,Square lateration,27.714713021623414 +26,Square lateration,36.44942190588798 +27,MDS-MAP,42.68079462983385 +27,MDS-MAP,99.86052295368206 +27,MDS-MAP,3.545251662182522 +27,MDS-MAP,82.69183469751236 +27,MDS-MAP,7.934389515160054 +27,MDS-MAP,54.71596109554526 +27,MDS-MAP,99.49127099926878 +27,MDS-MAP,113.88425855038005 +27,MDS-MAP,38.511923003386 +27,MDS-MAP,20.477030537866934 +27,MDS-MAP,16.505616324329118 +27,MDS-MAP,101.39269709282358 +27,MDS-MAP,22.65907491834107 +27,MDS-MAP,52.95335356350707 +27,MDS-MAP,14.735543961480511 +27,MDS-MAP,68.80659969857739 +27,Circular lateration,75.3333097924693 +27,Circular lateration,43.520806046509485 +27,Circular lateration,53.637244590803974 +27,Circular lateration,38.288722997747065 +27,Circular lateration,57.6108532032378 +27,Circular lateration,57.76715851496237 +27,Circular lateration,78.66703287525907 +27,Circular lateration,85.82836079828114 +27,Circular lateration,37.91680449328673 +27,Circular lateration,34.58127700124481 +27,Circular lateration,67.76359896249048 +27,Circular lateration,86.27533864289673 +27,Circular lateration,17.630108022065123 +27,Circular lateration,0.4880156502566974 +27,Circular lateration,0.5233155584928728 +27,Circular lateration,2.8346114660048736 +27,Square lateration,53.8319003732019 +27,Square lateration,64.79479511033875 +27,Square lateration,15.281870571593192 +27,Square lateration,33.88869072146075 +27,Square lateration,56.50842554815788 +27,Square lateration,52.54094245670175 +27,Square lateration,62.43300284438112 +27,Square lateration,74.46262949393181 +27,Square lateration,31.225839720349644 +27,Square lateration,21.476809097463956 +27,Square lateration,66.05724702214226 +27,Square lateration,85.34970490364616 +27,Square lateration,11.335232238392269 +27,Square lateration,15.818882328663422 +27,Square lateration,2.7474438797065748 +27,Square lateration,23.73251350805657 +28,MDS-MAP,30.500128813021202 +28,MDS-MAP,102.43708339974626 +28,MDS-MAP,89.66569265207025 +28,MDS-MAP,43.652393626759746 +28,MDS-MAP,9.70264368763485 +28,MDS-MAP,51.23464001972041 +28,MDS-MAP,45.97895699252704 +28,MDS-MAP,116.92626058392128 +28,MDS-MAP,81.1536279870134 +28,MDS-MAP,100.55119105625111 +28,MDS-MAP,93.54662145828814 +28,MDS-MAP,111.65621083779494 +28,MDS-MAP,43.014250401231756 +28,MDS-MAP,51.42542068618485 +28,MDS-MAP,3.4730596931521864 +28,MDS-MAP,1.8879590892769398 +28,Circular lateration,40.52344887006936 +28,Circular lateration,29.484251408563637 +28,Circular lateration,29.759331100590817 +28,Circular lateration,82.9816460488956 +28,Circular lateration,37.59803699600615 +28,Circular lateration,76.60131878478882 +28,Circular lateration,70.33211834540052 +28,Circular lateration,114.69136410055505 +28,Circular lateration,59.17469401923126 +28,Circular lateration,41.805659160473624 +28,Circular lateration,48.367682460351176 +28,Circular lateration,61.34284697831364 +28,Circular lateration,1.9072095561914577 +28,Circular lateration,2.131761256227453 +28,Circular lateration,0.4264876771382929 +28,Circular lateration,1.4645842750376394 +28,Square lateration,38.760328173063115 +28,Square lateration,50.19858645390992 +28,Square lateration,45.985831180291434 +28,Square lateration,15.538206842525446 +28,Square lateration,12.446418852616908 +28,Square lateration,21.880330095356726 +28,Square lateration,26.68753908025812 +28,Square lateration,64.81990641003765 +28,Square lateration,68.27469321910384 +28,Square lateration,52.794993360845126 +28,Square lateration,46.75860383915221 +28,Square lateration,56.834053371212775 +28,Square lateration,24.720836617059007 +28,Square lateration,17.639405212189413 +28,Square lateration,10.37770484016742 +28,Square lateration,17.536247642231544 +29,MDS-MAP,68.9363186050703 +29,MDS-MAP,78.54905729672839 +29,MDS-MAP,95.30407809279569 +29,MDS-MAP,47.812976571002864 +29,MDS-MAP,81.61752373549706 +29,MDS-MAP,28.91973389829186 +29,MDS-MAP,93.89215840349235 +29,MDS-MAP,67.6659883445706 +29,MDS-MAP,5.794889844664516 +29,MDS-MAP,48.30913767023259 +29,MDS-MAP,95.08459858634909 +29,MDS-MAP,30.47461579568944 +29,MDS-MAP,59.5121225789394 +29,MDS-MAP,43.27215982414858 +29,MDS-MAP,15.284900467613198 +29,MDS-MAP,14.647578100567465 +29,Circular lateration,97.48409624108919 +29,Circular lateration,35.25232304656789 +29,Circular lateration,28.04238763255003 +29,Circular lateration,57.6018549595341 +29,Circular lateration,47.40663179920113 +29,Circular lateration,101.6580199083523 +29,Circular lateration,99.74281824298546 +29,Circular lateration,25.916652376130088 +29,Circular lateration,48.11018487802395 +29,Circular lateration,9.543046153094837 +29,Circular lateration,70.45446566240952 +29,Circular lateration,76.37258270035672 +29,Circular lateration,2.4994837689084313 +29,Circular lateration,12.04016209997336 +29,Circular lateration,2.2499410825352406 +29,Circular lateration,1.0430406465255266 +29,Square lateration,59.95906924064238 +29,Square lateration,36.71791616927682 +29,Square lateration,39.0707207054637 +29,Square lateration,31.081992244121942 +29,Square lateration,41.603553565142334 +29,Square lateration,85.22654740570816 +29,Square lateration,85.11668475121868 +29,Square lateration,32.599713321163726 +29,Square lateration,49.90777939080009 +29,Square lateration,7.0093020607128 +29,Square lateration,72.06293279866672 +29,Square lateration,70.28881322155365 +29,Square lateration,20.205905307357348 +29,Square lateration,4.3792947522206065 +29,Square lateration,7.33192611049785 +29,Square lateration,9.417298779036654 diff --git a/results/tables/monte_carlo_metrics.csv b/results/tables/monte_carlo_metrics.csv new file mode 100644 index 0000000..6433cef --- /dev/null +++ b/results/tables/monte_carlo_metrics.csv @@ -0,0 +1,91 @@ +repetition,method,rmse,mae,mean,std,median,max,p95 +0,MDS-MAP,2.185218449708254,1.8458787821819298,1.8458787821819298,1.1695773571833123,1.662450878006072,3.9786433573742683,3.6190407320796423 +0,Circular lateration,43.78947366843516,32.206482229766934,32.206482229766934,29.669184460350156,27.674471499205733,96.88504803126659,91.33955515642728 +0,Square lateration,44.0939637244304,34.019038921879854,34.019038921879854,28.05321064981703,21.558708106491665,92.82196959355585,84.87322026587962 +1,MDS-MAP,104.12076076763218,87.56542088437342,87.56542088437342,56.33320413550988,117.43184088620788,154.50445738294167,154.44482717944248 +1,Circular lateration,60.89413219933657,54.2240019721968,54.2240019721968,27.71015962475634,58.87763429444088,113.07254488237886,107.54515548490463 +1,Square lateration,61.569113134199235,58.60133441233858,58.60133441233858,18.884896007791138,59.719879091337816,86.93801531391847,84.01272360227419 +2,MDS-MAP,8.309204011897831,7.295218265267347,7.295218265267347,3.9777709553779834,6.952625161531805,13.65028634375217,13.581143903853613 +2,Circular lateration,58.90527147459289,49.75408151774144,49.75408151774144,31.533512012166153,41.24813251143627,94.71083181490397,92.94763204685577 +2,Square lateration,51.428699145885744,49.24560206341943,49.24560206341943,14.825038726740953,47.562557048841356,82.0436751907646,76.29538685792052 +3,MDS-MAP,4.562718714542838,3.6624244679488505,3.6624244679488505,2.7212219837067737,2.9239413324889405,10.496007008331187,8.816379048148963 +3,Circular lateration,44.731144318040506,37.08045295423461,37.08045295423461,25.01829891719581,40.092685957413664,77.21968011045794,75.33668398773148 +3,Square lateration,40.37648518063248,36.344284636138084,36.344284636138084,17.58844876130954,32.10106382140965,67.26928046498466,60.82472560027291 +4,MDS-MAP,37.731531242875896,28.874548437590043,28.874548437590043,24.288452039135517,25.883270592181606,88.2057668995198,69.74594678025248 +4,Circular lateration,37.232108800794904,30.564519359637014,30.564519359637014,21.261234255531907,32.34065231775183,63.88951680632521,61.58674330967082 +4,Square lateration,34.70763712101917,31.378417118604823,31.378417118604823,14.832903075770295,31.399199886450468,55.700989968264395,48.73261798554818 +5,MDS-MAP,8.745454088470565,4.7373231721726405,4.7373231721726405,7.351240465114897,3.037014129702911,32.773206869979084,12.253411191399938 +5,Circular lateration,63.12743447788416,52.88505533350713,52.88505533350713,34.470913914943516,65.61575015282035,98.6286881422611,93.52117947675772 +5,Square lateration,52.329087777359454,49.52081173409391,49.52081173409391,16.91220366501711,53.51933906158667,84.61054214239813,73.4930051835108 +6,MDS-MAP,2.062801521780494,1.7897094052718303,1.7897094052718303,1.0257145621182693,1.6155498003539472,3.86694194821288,3.1457997444972765 +6,Circular lateration,43.42985452935746,34.73688498965117,34.73688498965117,26.067241619643962,30.281996396910976,80.80282359292899,78.60966287898637 +6,Square lateration,41.53781614889254,37.147005175669584,37.147005175669584,18.58736605595249,32.928524579174955,74.69818358853158,63.912291733742556 +7,MDS-MAP,7.329853096812777,5.806914921001663,5.806914921001663,4.472860999528612,4.329566088507324,16.554267620021584,15.136518644770634 +7,Circular lateration,49.22768079299547,38.04624224012751,38.04624224012751,31.238566030831056,40.33077934159579,96.17515806770614,92.41138053125128 +7,Square lateration,46.23994292584898,39.98878001130518,39.98878001130518,23.217015204224907,41.27205620569523,90.19680481386244,73.89083724702131 +8,MDS-MAP,2.360876038225514,2.1470962365985153,2.1470962365985153,0.9816890641399094,1.9499894362935801,5.277335426175595,3.668501609696447 +8,Circular lateration,47.55326094328507,40.008212378826016,40.008212378826016,25.703220976969288,49.25537008761242,77.2192568520714,68.68686076482805 +8,Square lateration,46.351806700557724,41.81042386154252,41.81042386154252,20.00945878638461,33.0027993825655,79.44514858379279,74.94772560022531 +9,MDS-MAP,57.52895101157319,47.55908308254369,47.55908308254369,32.36840775879616,52.50280885079077,123.03355597499362,91.32771520237043 +9,Circular lateration,45.87120443806874,37.9305514989483,37.9305514989483,25.796136524385343,36.23798412456007,103.85513225229437,74.77426123066019 +9,Square lateration,37.80148521481428,33.79777306954802,33.79777306954802,16.931119868016896,30.317145927841928,63.88645630943104,57.18777726757146 +10,MDS-MAP,1.85488763269496,1.685840525450664,1.685840525450664,0.7736600368850265,1.3525067450922261,3.2477428625751004,2.9707277070263696 +10,Circular lateration,58.140560551166196,48.20074053107887,48.20074053107887,32.5117423934712,47.43354721443126,114.8385863544283,94.12169641919814 +10,Square lateration,45.98335566739533,41.83650571762525,41.83650571762525,19.083390363698168,40.74436093552332,89.45446667558086,69.05719659815932 +11,MDS-MAP,4.374690752867252,3.642163882505203,3.642163882505203,2.4233368391944325,3.302262558017393,11.475930347382185,6.885478285992145 +11,Circular lateration,46.32486086309956,37.53540020502426,37.53540020502426,27.1493363718931,37.14343873879638,79.62054347862745,75.6832888293246 +11,Square lateration,40.447821876509984,32.986906372453355,32.986906372453355,23.40705668231006,31.35540088032791,80.93635896211804,75.92612956207503 +12,MDS-MAP,53.8776564431605,45.4481932648552,45.4481932648552,28.935507473821914,51.25235182574894,95.0659939561794,87.02321209227765 +12,Circular lateration,53.40237345336564,44.07606633004481,44.07606633004481,30.15151517456828,47.76372684704776,90.70643165184782,82.18027326146371 +12,Square lateration,47.78124737925289,40.21461923385566,40.21461923385566,25.803720681199604,44.650599346528466,84.1085157934101,76.05988162926346 +13,MDS-MAP,3.0838168228627265,2.1824176770422774,2.1824176770422774,2.1787563608408704,1.616318804020763,9.572599566724628,5.940865266126406 +13,Circular lateration,47.58794103662907,40.22828769028115,40.22828769028115,25.42237206898008,46.94407148106981,76.71289949529327,69.80745270801845 +13,Square lateration,46.34668603920483,43.3520946182295,43.3520946182295,16.389362374073634,43.27310011910929,65.84431477484452,63.78112088505939 +14,MDS-MAP,5.199427827353785,3.9022565062431633,3.9022565062431633,3.4360506240950226,2.8243087540184,15.192536389037334,10.549598789215855 +14,Circular lateration,41.46548551790006,31.919655916221906,31.919655916221906,26.467377192029808,32.333376551457306,79.63666556574412,77.13283661950402 +14,Square lateration,42.09475799999618,32.14012523925396,32.14012523925396,27.184204985309258,24.297664090722762,84.57357738605965,81.97083683853599 +15,MDS-MAP,1.3196834826611386,1.2201643103880464,1.2201643103880464,0.5027559547771608,1.120855498796003,2.447716323126961,2.102378704758175 +15,Circular lateration,60.13036542114176,55.67214534995453,55.67214534995453,22.72164337836453,57.138248206228496,92.56010223504823,87.36543253911728 +15,Square lateration,39.60950104561243,37.37600779791989,37.37600779791989,13.112841575044081,36.48897512424261,63.931401275998496,55.94434970029618 +16,MDS-MAP,66.39400918244505,54.80384048196851,54.80384048196851,37.47937464453679,50.348531802752454,131.29314676931065,113.98755545400145 +16,Circular lateration,52.98274188678472,42.47293406073109,42.47293406073109,31.673661141624283,47.52112125027104,99.15759476797687,83.21927333026754 +16,Square lateration,42.989345265532585,38.50630752392992,38.50630752392992,19.114080862853633,38.25650588703249,74.32996795543133,66.71932784643234 +17,MDS-MAP,3.0582610407542914,2.693981245497273,2.693981245497273,1.4475585108397115,2.3317485080611497,6.341403276845636,5.24216799618588 +17,Circular lateration,53.038800761023275,43.326313379112904,43.326313379112904,30.593217469603054,39.36155023702261,98.33996430050375,95.91140339221971 +17,Square lateration,48.394089022730206,45.28952719443483,45.28952719443483,17.0542246626601,45.65228569153828,76.66926777515424,68.03509007392185 +18,MDS-MAP,50.81648323314002,44.00018990046605,44.00018990046605,25.422396757719888,40.5026502176855,94.0302941222651,89.04636034890734 +18,Circular lateration,50.38968903699181,38.02580520999808,38.02580520999808,33.062953579134685,32.40680701466265,103.98084517106099,91.81603543555177 +18,Square lateration,44.02894711317046,36.466846993765955,36.466846993765955,24.67219597497605,31.952676915607164,88.58172204599529,72.4115601097799 +19,MDS-MAP,1.9813880538858075,1.789150203258857,1.789150203258857,0.8513754578681362,1.6340018441926092,3.5978247075835905,3.3325205504004245 +19,Circular lateration,39.02490480403007,32.918113142257305,32.918113142257305,20.96046330874287,30.112163833191325,76.09233791394873,61.46379632211923 +19,Square lateration,37.99462125118168,32.57905132676278,32.57905132676278,19.54985060477196,32.33615842426702,69.09042188907085,60.72675858581077 +20,MDS-MAP,61.63224191111844,53.15854799132299,53.15854799132299,31.18817113017105,48.36736830700242,113.509781745756,104.93827588317383 +20,Circular lateration,46.90803333848101,36.404082721097424,36.404082721097424,29.5821965533248,37.34211030677703,92.71719695510292,86.89329142765163 +20,Square lateration,34.27778241046017,30.02118982730481,30.02118982730481,16.543715674895484,26.374107337771324,57.6455479427844,57.31117883965203 +21,MDS-MAP,60.5847543897754,51.43041663113541,51.43041663113541,32.022253350088285,47.073560590732164,122.69000685998019,121.38873199572672 +21,Circular lateration,37.225869399929884,28.48838290365702,28.48838290365702,23.961998917353664,23.159239585090702,83.71874032272832,72.02194918005658 +21,Square lateration,34.736442305808644,29.656712241893114,29.656712241893114,18.08590177642022,24.13421960214432,78.46165875539442,65.5218849930337 +22,MDS-MAP,2.200947200025575,1.9218203208570137,1.9218203208570137,1.0727419221981882,1.8491444137833728,4.204940503082699,3.916212588435606 +22,Circular lateration,40.7644238161979,31.63379802838127,31.63379802838127,25.71071899745676,29.83652674676005,84.9502592125001,70.88993286758841 +22,Square lateration,42.41850774493398,36.81852830064753,36.81852830064753,21.064799383840366,40.305918757464894,76.8495999708694,67.03940151809478 +23,MDS-MAP,3.211103347989262,3.075882668031813,3.075882668031813,0.9220252295731095,2.77097396367394,4.849031517294981,4.619618565136974 +23,Circular lateration,53.693177933212304,48.34021378613865,48.34021378613865,23.370517488451295,50.46421754962096,97.64322600984542,77.3598723049904 +23,Square lateration,47.54432223995426,42.529061699434905,42.529061699434905,21.254211070333046,42.51866965657185,90.60077168231615,74.36712913480011 +24,MDS-MAP,3.3758453649322036,2.9072666830351386,2.9072666830351386,1.71584741793905,2.5625617116234314,7.254101956700976,5.883108456142343 +24,Circular lateration,50.01471051173797,40.84700437293155,40.84700437293155,28.8616267963305,45.17737108990498,96.62673680815409,76.0726379944088 +24,Square lateration,48.37527761305981,44.11406496019518,44.11406496019518,19.8523740854409,48.53857808471982,69.99097068057958,66.61260206938884 +25,MDS-MAP,1.688195866735363,1.5291221187256046,1.5291221187256046,0.7153955762279225,1.35986608284732,3.2053757394060503,2.6430777157059695 +25,Circular lateration,48.57854970451968,38.02097447621735,38.02097447621735,30.23707974116083,37.138175904440814,100.64479219243462,85.86852094984455 +25,Square lateration,51.77768437386115,47.11738956207964,47.11738956207964,21.46812055058415,40.60916302219523,86.53432907821617,81.76467346782285 +26,MDS-MAP,65.7106616279215,48.99871134315633,48.99871134315633,43.78375655753212,46.4656725889015,160.35701624075972,140.46459699485126 +26,Circular lateration,50.930548543361965,38.49975985113552,38.49975985113552,33.342004533810545,34.82260465440932,112.57535412463584,106.1184065502898 +26,Square lateration,46.90830731876349,40.77301446408061,40.77301446408061,23.19376181268218,39.58095949659456,104.69810184851322,79.6447952978983 +27,MDS-MAP,63.881520230218655,52.55288270024229,52.55288270024229,36.31863360340543,47.81707409667046,113.88425855038005,104.5155874572127 +27,Circular lateration,54.26294140659503,46.16665991350053,46.16665991350053,28.51501924471994,48.57902531865673,86.27533864289673,85.94010525943503 +27,Square lateration,48.67524865466301,41.96787061363675,41.96787061363675,24.657203161557426,43.21481658908125,85.34970490364616,77.1843983463604 +28,MDS-MAP,71.71949947564966,61.05038381153715,61.05038381153715,37.63691328339394,51.33003035295263,116.92626058392128,112.97372327432653 +28,Circular lateration,54.21449099352405,43.66202756486465,43.66202756486465,32.13780301470372,41.16455401527149,114.69136410055505,90.90907556181045 +28,Square lateration,40.410864637426094,35.70335532437629,35.70335532437629,18.929035879455295,32.72393362666062,68.27469321910384,65.6836031123042 +29,MDS-MAP,61.93888214183786,54.69236486347834,54.69236486347834,29.071813610792166,53.91063012458599,95.30407809279569,95.13946846296074 +29,Circular lateration,56.68547804599702,44.71360569988986,44.71360569988986,34.84159707329714,41.32947742288451,101.6580199083523,100.22161865932718 +29,Square lateration,48.7219906646825,40.74871561397397,40.74871561397397,26.709072431308492,37.89431843737026,85.22654740570816,85.14415041484105 diff --git a/results/tables/single_node_positions.csv b/results/tables/single_node_positions.csv new file mode 100644 index 0000000..46a4008 --- /dev/null +++ b/results/tables/single_node_positions.csv @@ -0,0 +1,17 @@ +node,actual_x,actual_y,mdsmap_x,mdsmap_y,mdsmap_error,circular_lateration_x,circular_lateration_y,circular_lateration_error,square_lateration_x,square_lateration_y,square_lateration_error +4,65.27848026851319,29.830276735556925,65.65635742866027,31.60002667173938,1.8096425019264493,45.22271872981485,35.18571627500968,20.758475463238277,46.72684011434851,37.050052710804806,19.90699669820593 +5,96.69622001623905,91.98501605372782,94.65231618317293,94.6534381443402,3.361252643359399,61.65627696232398,53.38388660349702,52.1329531491847,42.1214436463396,41.03707451635823,74.6598885796099 +6,63.587080414465134,75.27320970790866,63.89069512631613,76.41634759020968,1.1827705234761403,52.415884672274515,42.53630652523831,34.59046753517319,49.948882459523645,42.16823817304116,35.80418388655937 +7,51.51536963223518,82.589525837557,51.43669862062896,83.01107965492646,0.4288318423413857,93.40686018098665,39.08755245973734,60.39303493086488,74.53976989458292,21.47352794300486,65.30917398105493 +8,44.83805454001032,33.881245331376185,47.32380386998021,35.57076823060911,3.0055677264833345,46.80673119048737,37.819436381357534,4.402844137632711,46.72684011434851,37.050052710804806,3.6890176407479194 +9,27.789921550015904,22.633305684340343,29.543834536888305,24.11083930947994,2.293319946919274,22.262720946818927,59.959190017735665,37.73289795096564,18.36902871671778,63.991316571515455,42.41742903949016 +10,52.58168433452484,43.09120606844314,53.08388149707605,44.520824415072006,1.5152592540856946,44.47226904506267,31.951719461893354,13.778634845094956,47.142506255827556,37.050052710804806,8.128972386611114 +11,66.31806204725955,1.2840482366806572,66.40619703129819,3.203587563304474,1.9215616050147621,22.05073587047681,87.46476745611605,96.88504803126659,30.436372117522012,75.26533529668862,82.22363715665422 +12,44.77019015387208,36.51808011323914,48.06032430961217,37.70939461959338,3.499173190314767,81.46146959597802,59.21124163729637,43.141969902354454,65.17929821604753,46.217332217109416,22.596618845924425 +13,19.539759987155403,59.486587100605284,19.165142406868064,58.607909253660154,0.955203166961077,32.59813654362682,95.50825158633785,38.31555181141581,35.49173343096512,79.0518245853265,25.244087913520477 +14,43.531315595064456,29.999150374514983,46.533994145758776,32.60942325036123,3.9786433573742683,55.75639682122007,43.039898087104824,17.87494648634003,52.93283670992049,43.20300168657272,16.208957052938743 +15,20.941612123621955,87.46240571921795,21.10127395440427,87.89525220510524,0.46135450637631126,90.72908375752743,31.441354488009765,89.49105753148085,82.61843345326878,18.094634024447277,92.82196959355585 +16,79.74623155214327,60.6709676684979,82.57515955749263,61.70177914688235,3.0108812602656734,81.46146959597802,59.21124163729637,2.2522969682493965,65.17929821604753,46.217332217109416,20.5207973670589 +17,34.51005786672921,94.68197909796484,34.000057208416735,95.61737549512173,1.0653952746719206,32.59813654362682,95.50825158633785,2.082827254184974,35.49173343096512,79.0518245853265,15.66095198263396 +18,56.33773745025456,43.2762739619952,56.342564645803634,43.69818109698468,0.4219347489504768,55.75639682122007,43.039898087104824,0.6275591455762581,52.93283670992049,43.20300168657272,3.4056890459748512 +19,90.0449599004222,31.93418039018624,90.19968543561002,31.330421983846723,0.6232689663899446,90.72908375752743,31.441354488009765,0.8431505332481255,82.61843345326878,18.094634024447277,15.706251579536975 diff --git a/scripts/run_monte_carlo.py b/scripts/run_monte_carlo.py new file mode 100644 index 0000000..52a40cc --- /dev/null +++ b/scripts/run_monte_carlo.py @@ -0,0 +1,20 @@ +"""Run repeated experiments and save error distributions and metrics.""" + +from pathlib import Path +import sys + +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) + +from mdsmap_sim.experiment import run_monte_carlo +from mdsmap_sim.plots import plot_error_distribution +from mdsmap_sim.utils import ensure_output_dirs, load_config + + +root = Path(__file__).resolve().parents[1] +config = load_config(root / "config" / "default.yaml") +figures, tables = ensure_output_dirs(root / config["output_dir"]) +metrics, errors = run_monte_carlo(config) +metrics.to_csv(tables / "monte_carlo_metrics.csv", index=False) +errors.to_csv(tables / "monte_carlo_errors.csv", index=False) +plot_error_distribution(errors, figures / "error_distribution.png") +print(metrics.groupby("method").mean(numeric_only=True).to_string()) diff --git a/scripts/run_remote_carlo.py b/scripts/run_remote_carlo.py new file mode 100644 index 0000000..9d5c999 --- /dev/null +++ b/scripts/run_remote_carlo.py @@ -0,0 +1,18 @@ +from pathlib import Path +import sys + +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) + +from mdsmap_sim.experiment import run_monte_carlo +from mdsmap_sim.plots import plot_error_distribution +from mdsmap_sim.utils import ensure_output_dirs, load_config + + +root = Path(__file__).resolve().parents[1] +config = load_config(root / "config" / "default.yaml") +figures, tables = ensure_output_dirs(root / config["output_dir"]) +metrics, errors = run_monte_carlo(config) +metrics.to_csv(tables / "monte_carlo_metrics.csv", index=False) +errors.to_csv(tables / "monte_carlo_errors.csv", index=False) +plot_error_distribution(errors, figures / "error_distribution.png") +print(metrics.groupby("method").mean(numeric_only=True).to_string()) \ No newline at end of file diff --git a/scripts/run_single.py b/scripts/run_single.py new file mode 100644 index 0000000..32aaa25 --- /dev/null +++ b/scripts/run_single.py @@ -0,0 +1,20 @@ +from pathlib import Path +import sys + +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) + +from mdsmap_sim.experiment import run_single_experiment +from mdsmap_sim.plots import plot_positions +from mdsmap_sim.utils import ensure_output_dirs, load_config + + +root = Path(__file__).resolve().parents[1] +config = load_config(root / "config" / "default.yaml") +figures, tables = ensure_output_dirs(root / config["output_dir"]) +result = run_single_experiment(config) +result["node_table"].to_csv(tables / "single_node_positions.csv", index=False) +plot_positions(result, figures / "single_positions.png") +print(result["node_table"].to_string(index=False)) +print("\nMetrics:") +for method, metrics in result["metrics"].items(): + print(method, metrics) \ No newline at end of file diff --git a/scripts/run_sweep.py b/scripts/run_sweep.py new file mode 100644 index 0000000..f3f3218 --- /dev/null +++ b/scripts/run_sweep.py @@ -0,0 +1,16 @@ +"""Small noise sweep built on the main Monte Carlo pipeline.""" +from pathlib import Path +import sys + +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) + +from mdsmap_sim.experiment import run_monte_carlo +from mdsmap_sim.utils import load_config + +root = Path(__file__).resolve().parents[1] +config = load_config(root / "config" / "default.yaml") +for sigma in (0.0, 0.5, 1.0, 2.0, 5.0): + config["noise_sigma"] = sigma + metrics, _ = run_monte_carlo(config) + summary = metrics.groupby("method")["rmse"].mean() + print(f"sigma={sigma:.1f}\n{summary.to_string()}\n") \ No newline at end of file diff --git a/src/mdsmap_sim/__init__.py b/src/mdsmap_sim/__init__.py new file mode 100644 index 0000000..9904d20 --- /dev/null +++ b/src/mdsmap_sim/__init__.py @@ -0,0 +1,5 @@ +"""MDS-MAP localization simulation.""" + +from .experiment import run_monte_carlo, run_single_experiment + +__all__ = ["run_monte_carlo", "run_single_experiment"] \ No newline at end of file diff --git a/src/mdsmap_sim/experiment.py b/src/mdsmap_sim/experiment.py new file mode 100644 index 0000000..3b397cf --- /dev/null +++ b/src/mdsmap_sim/experiment.py @@ -0,0 +1,55 @@ +from typing import Any + +import numpy as np +import pandas as pd + +from .lateration import estimate_all +from .mds_map import classical_mds, procrustes_align +from .metrics import error_metrics, localization_errors +from .network import generate_network +from .ranging import measure_distances +from .shortest_path import complete_distances + + +def run_single_experiment(config: dict[str, Any], seed: int | None = None) -> dict[str, Any]: + rng = np.random.default_rng(config["seed"] if seed is None else seed) + area = tuple(config["area_size"]) + network = generate_network( + area, config["anchor_count"], config["unknown_count"], config["radio_range"], rng + ) + measured = measure_distances( + network.distances, network.adjacency, rng, config["noise_model"], + config["noise_sigma"], config["multiplicative_sigma"], + ) + completed = complete_distances(measured) + mds = procrustes_align(classical_mds(completed), network.positions, network.anchors) + # The completed anchor ranges keep the baselines defined when an + # unknown is not directly connected to every anchor. + baseline_ranges = completed[np.ix_(network.unknowns, network.anchors)] + circular, square = estimate_all( + network.positions, network.anchors, network.unknowns, baseline_ranges + ) + actual = network.positions[network.unknowns] + estimates = {"MDS-MAP": mds[network.unknowns], "Circular lateration": circular, "Square lateration": square} + errors = {name: localization_errors(actual, estimate) for name, estimate in estimates.items()} + rows = [] + for node_offset, node in enumerate(network.unknowns): + row = {"node": int(node), "actual_x": actual[node_offset, 0], "actual_y": actual[node_offset, 1]} + for name, estimate in estimates.items(): + key = name.lower().replace(" ", "_").replace("-", "") + row.update({f"{key}_x": estimate[node_offset, 0], f"{key}_y": estimate[node_offset, 1], + f"{key}_error": errors[name][node_offset]}) + rows.append(row) + return {"network": network, "estimates": estimates, "errors": errors, "node_table": pd.DataFrame(rows), + "metrics": {name: error_metrics(values) for name, values in errors.items()}} + + +def run_monte_carlo(config: dict[str, Any]) -> tuple[pd.DataFrame, pd.DataFrame]: + metric_rows, error_rows = [], [] + for repetition in range(int(config["repetitions"])): + result = run_single_experiment(config, int(config["seed"]) + repetition) + for method, metrics in result["metrics"].items(): + metric_rows.append({"repetition": repetition, "method": method, **metrics}) + error_rows.extend({"repetition": repetition, "method": method, "error": error} + for error in result["errors"][method]) + return pd.DataFrame(metric_rows), pd.DataFrame(error_rows) \ No newline at end of file diff --git a/src/mdsmap_sim/lateration.py b/src/mdsmap_sim/lateration.py new file mode 100644 index 0000000..a011034 --- /dev/null +++ b/src/mdsmap_sim/lateration.py @@ -0,0 +1,47 @@ +import numpy as np +from scipy.optimize import least_squares + + +def circular_lateration( + anchors: np.ndarray, anchor_indices: np.ndarray, distances: np.ndarray +) -> np.ndarray: + """Estimate a point from anchor ranges by nonlinear least squares.""" + if len(anchor_indices) < 3: + raise ValueError("Circular lateration requires at least 3 anchors.") + anchor_points = anchors[anchor_indices] + initial = anchor_points.mean(axis=0) + + def residual(point: np.ndarray) -> np.ndarray: + return np.linalg.norm(point - anchor_points, axis=1) - distances + + return least_squares(residual, initial).x + + +def square_lateration( + anchors: np.ndarray, anchor_indices: np.ndarray, distances: np.ndarray +) -> np.ndarray: + """Min-max (square intersection) lateration using anchor distance bounds.""" + if len(anchor_indices) < 3: + raise ValueError("Square lateration requires at least 3 anchors.") + anchor_points = anchors[anchor_indices] + lower = np.max(anchor_points - distances[:, None], axis=0) + upper = np.min(anchor_points + distances[:, None], axis=0) + if np.any(lower > upper): + return np.mean(anchor_points, axis=0) + return (lower + upper) / 2.0 + + +def estimate_all( + positions: np.ndarray, + anchor_indices: np.ndarray, + unknown_indices: np.ndarray, + measured_distances: np.ndarray, +) -> tuple[np.ndarray, np.ndarray]: + anchor_points = positions[anchor_indices] + circular, square = [], [] + for offset, node in enumerate(unknown_indices): + row = node if measured_distances.shape[0] > node else offset + ranges = measured_distances[row, anchor_indices] + circular.append(circular_lateration(anchor_points, np.arange(len(anchor_points)), ranges)) + square.append(square_lateration(anchor_points, np.arange(len(anchor_points)), ranges)) + return np.asarray(circular), np.asarray(square) \ No newline at end of file diff --git a/src/mdsmap_sim/mds_map.py b/src/mdsmap_sim/mds_map.py new file mode 100644 index 0000000..9cf884d --- /dev/null +++ b/src/mdsmap_sim/mds_map.py @@ -0,0 +1,28 @@ +import numpy as np + + +def classical_mds(distances: np.ndarray, dimensions: int = 2) -> np.ndarray: + n = distances.shape[0] + centering = np.eye(n) - np.ones((n, n)) / n + gram = -0.5 * centering @ (distances**2) @ centering + eigenvalues, eigenvectors = np.linalg.eigh((gram + gram.T) / 2) + order = np.argsort(eigenvalues)[::-1] + eigenvalues = np.maximum(eigenvalues[order[:dimensions]], 0.0) + return eigenvectors[:, order[:dimensions]] * np.sqrt(eigenvalues) + + +def procrustes_align( + estimated: np.ndarray, reference: np.ndarray, indices: np.ndarray +) -> np.ndarray: + """Align an MDS map to known anchors using a similarity transform.""" + x = estimated[indices] + y = reference[indices] + x_mean, y_mean = x.mean(axis=0), y.mean(axis=0) + xc, yc = x - x_mean, y - y_mean + u, singular_values, vt = np.linalg.svd(xc.T @ yc) + rotation = u @ vt + if np.linalg.det(rotation) < 0: + vt[-1, :] *= -1 + rotation = u @ vt + scale = singular_values.sum() / max(np.sum(xc**2), 1e-12) + return (estimated - x_mean) @ rotation * scale + y_mean \ No newline at end of file diff --git a/src/mdsmap_sim/metrics.py b/src/mdsmap_sim/metrics.py new file mode 100644 index 0000000..b87311c --- /dev/null +++ b/src/mdsmap_sim/metrics.py @@ -0,0 +1,18 @@ +import numpy as np + + +def localization_errors(actual: np.ndarray, estimated: np.ndarray) -> np.ndarray: + return np.linalg.norm(actual - estimated, axis=1) + + +def error_metrics(errors: np.ndarray) -> dict[str, float]: + errors = np.asarray(errors, dtype=float) + return { + "rmse": float(np.sqrt(np.mean(errors**2))), + "mae": float(np.mean(np.abs(errors))), + "mean": float(np.mean(errors)), + "std": float(np.std(errors)), + "median": float(np.median(errors)), + "max": float(np.max(errors)), + "p95": float(np.percentile(errors, 95)), + } \ No newline at end of file diff --git a/src/mdsmap_sim/network.py b/src/mdsmap_sim/network.py new file mode 100644 index 0000000..d3f1a0b --- /dev/null +++ b/src/mdsmap_sim/network.py @@ -0,0 +1,33 @@ +from dataclasses import dataclass + +import numpy as np + + +@dataclass(frozen=True) +class Network: + positions: np.ndarray + anchors: np.ndarray + unknowns: np.ndarray + adjacency: np.ndarray + distances: np.ndarray + + +def generate_network( + area_size: tuple[float, float], + anchor_count: int, + unknown_count: int, + radio_range: float, + rng: np.random.Generator, +) -> Network: + if anchor_count < 3 or unknown_count < 5: + raise ValueError("At least 3 anchors and 5 unknown nodes are required.") + positions = rng.uniform([0.0, 0.0], area_size, size=(anchor_count + unknown_count, 2)) + distances = np.linalg.norm(positions[:, None, :] - positions[None, :, :], axis=2) + adjacency = (distances <= radio_range) & ~np.eye(len(positions), dtype=bool) + return Network( + positions=positions, + anchors=np.arange(anchor_count), + unknowns=np.arange(anchor_count, anchor_count + unknown_count), + adjacency=adjacency, + distances=distances, + ) \ No newline at end of file diff --git a/src/mdsmap_sim/plots.py b/src/mdsmap_sim/plots.py new file mode 100644 index 0000000..7c64315 --- /dev/null +++ b/src/mdsmap_sim/plots.py @@ -0,0 +1,36 @@ +from pathlib import Path + +import matplotlib.pyplot as plt +import pandas as pd + + +def plot_positions(result: dict, path: str | Path) -> None: + network, estimates = result["network"], result["estimates"] + fig, ax = plt.subplots(figsize=(8, 7)) + ax.scatter(network.positions[network.unknowns, 0], network.positions[network.unknowns, 1], + marker="o", label="Actual unknowns", color="black") + ax.scatter(network.positions[network.anchors, 0], network.positions[network.anchors, 1], + marker="^", s=90, label="Anchors", color="tab:green") + styles = {"MDS-MAP": ("tab:blue", "x"), "Circular lateration": ("tab:orange", "+"), + "Square lateration": ("tab:red", "s")} + for method, estimate in estimates.items(): + color, marker = styles[method] + ax.scatter(estimate[:, 0], estimate[:, 1], marker=marker, color=color, label=method) + ax.set(xlabel="x (m)", ylabel="y (m)", title="Actual and estimated node positions") + ax.legend() + ax.grid(alpha=0.25) + fig.tight_layout() + fig.savefig(path, dpi=160) + plt.close(fig) + + +def plot_error_distribution(errors: pd.DataFrame, path: str | Path) -> None: + fig, ax = plt.subplots(figsize=(8, 5)) + for method, group in errors.groupby("method"): + ax.hist(group["error"], bins=20, alpha=0.55, label=method) + ax.set(xlabel="Localization error (m)", ylabel="Node count", title="Localization error distribution") + ax.legend() + ax.grid(alpha=0.25) + fig.tight_layout() + fig.savefig(path, dpi=160) + plt.close(fig) \ No newline at end of file diff --git a/src/mdsmap_sim/ranging.py b/src/mdsmap_sim/ranging.py new file mode 100644 index 0000000..f6a0d6c --- /dev/null +++ b/src/mdsmap_sim/ranging.py @@ -0,0 +1,27 @@ +import numpy as np + + +def measure_distances( + distances: np.ndarray, + adjacency: np.ndarray, + rng: np.random.Generator, + model: str = "gaussian", + sigma: float = 1.0, + multiplicative_sigma: float = 0.02, +) -> np.ndarray: + """Measure connected links and represent unavailable links by infinity.""" + measured = np.full_like(distances, np.inf, dtype=float) + np.fill_diagonal(measured, 0.0) + links = adjacency.astype(bool) + if model == "gaussian": + noise = rng.normal(0.0, sigma, size=distances.shape) + values = distances + noise + elif model == "multiplicative": + values = distances * (1.0 + rng.normal(0.0, multiplicative_sigma, size=distances.shape)) + elif model == "none": + values = distances.copy() + else: + raise ValueError(f"Unknown noise model: {model}") + measured[links] = np.maximum(values[links], 1e-9) + measured[links] = measured[links.T] + return measured \ No newline at end of file diff --git a/src/mdsmap_sim/shortest_path.py b/src/mdsmap_sim/shortest_path.py new file mode 100644 index 0000000..39bf744 --- /dev/null +++ b/src/mdsmap_sim/shortest_path.py @@ -0,0 +1,9 @@ +import numpy as np +from scipy.sparse.csgraph import shortest_path + + +def complete_distances(measured_distances: np.ndarray) -> np.ndarray: + completed = shortest_path(measured_distances, directed=False, unweighted=False) + if not np.isfinite(completed).all(): + raise ValueError("Network is disconnected; increase radio_range or retry.") + return completed \ No newline at end of file diff --git a/src/mdsmap_sim/utils.py b/src/mdsmap_sim/utils.py new file mode 100644 index 0000000..31990a1 --- /dev/null +++ b/src/mdsmap_sim/utils.py @@ -0,0 +1,22 @@ +from pathlib import Path +from typing import Any + +import yaml + + +def load_config(path: str | Path) -> dict[str, Any]: + """Load a YAML configuration and fail clearly for malformed files.""" + with Path(path).open(encoding="utf-8") as handle: + config = yaml.safe_load(handle) + if not isinstance(config, dict): + raise ValueError(f"Configuration must be a mapping: {path}") + return config + + +def ensure_output_dirs(root: str | Path) -> tuple[Path, Path]: + root_path = Path(root) + figures = root_path / "figures" + tables = root_path / "tables" + figures.mkdir(parents=True, exist_ok=True) + tables.mkdir(parents=True, exist_ok=True) + return figures, tables \ No newline at end of file diff --git a/tests/test_lateration.py b/tests/test_lateration.py new file mode 100644 index 0000000..c32f7b3 --- /dev/null +++ b/tests/test_lateration.py @@ -0,0 +1,13 @@ +import numpy as np + +from mdsmap_sim.lateration import circular_lateration, square_lateration + + +def test_lateration_noise_free(): + anchors = np.array([[0, 0], [10, 0], [0, 10], [10, 10]], dtype=float) + target = np.array([4.0, 6.0]) + distances = np.linalg.norm(anchors - target, axis=1) + assert np.linalg.norm(circular_lateration(anchors, np.arange(4), distances) - target) < 1e-7 + estimate = square_lateration(anchors, np.arange(4), distances) + assert np.all(np.isfinite(estimate)) + assert np.linalg.norm(estimate - target) < 1.0 \ No newline at end of file diff --git a/tests/test_mds_map.py b/tests/test_mds_map.py new file mode 100644 index 0000000..9f30620 --- /dev/null +++ b/tests/test_mds_map.py @@ -0,0 +1,10 @@ +import numpy as np + +from mdsmap_sim.mds_map import classical_mds, procrustes_align + + +def test_noise_free_mds_alignment_is_exact(): + points = np.array([[0, 0], [10, 0], [0, 10], [7, 4], [3, 8]], dtype=float) + distances = np.linalg.norm(points[:, None] - points[None, :], axis=2) + aligned = procrustes_align(classical_mds(distances), points, np.array([0, 1, 2])) + assert np.max(np.linalg.norm(aligned - points, axis=1)) < 1e-8 \ No newline at end of file diff --git a/tests/ttest_metrics.py b/tests/ttest_metrics.py new file mode 100644 index 0000000..c3597b6 --- /dev/null +++ b/tests/ttest_metrics.py @@ -0,0 +1,10 @@ +import numpy as np + +from mdsmap_sim.metrics import error_metrics + + +def test_error_metrics(): + metrics = error_metrics(np.array([1.0, 2.0, 3.0])) + assert metrics["mae"] == 2.0 + assert metrics["median"] == 2.0 + assert metrics["max"] == 3.0 \ No newline at end of file