diff --git a/Pipfile b/Pipfile index ba475f75..548d00a7 100644 --- a/Pipfile +++ b/Pipfile @@ -19,6 +19,7 @@ esridump = "*" sqlalchemy = "*" psycopg2-binary = "*" geoalchemy2 = "*" +mapbox = "*" [dev-packages] diff --git a/Pipfile.lock b/Pipfile.lock index a25c38c4..bf79935c 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "304d3732a0e4467e0533740d3ca4dcd9be9a293b58ad52e9f48d6559f0013bfe" + "sha256": "36c824d5284bbf554ee303d347700694bdb6f31786581709bcdc7e340ce013af" }, "pipfile-spec": 6, "requires": { @@ -166,6 +166,30 @@ "markers": "python_version >= '3.7'", "version": "==6.0.0" }, + "boto3": { + "hashes": [ + "sha256:4aec1b54ba6cd352abba2cdd7cdc76e631a4d3ce79c55c0719f85f9c9842e4a2", + "sha256:709cf438ad3ea48d426e4659538fe1148fc2719469b52179d07a11c5d26abac6" + ], + "markers": "python_version >= '3.7'", + "version": "==1.28.37" + }, + "botocore": { + "hashes": [ + "sha256:5c92c8bc3c6b49950c95501b30f0ac551fd4952359b53a6fba243094028157de", + "sha256:72e10759be3dff39c5eeb29f85c11a227c369c946d044f2caf62c352d6a6fc06" + ], + "markers": "python_version >= '3.7'", + "version": "==1.31.37" + }, + "cachecontrol": { + "hashes": [ + "sha256:95dedbec849f46dda3137866dc28b9d133fc9af55f5b805ab1291833e4457aa4", + "sha256:f012366b79d2243a6118309ce73151bf52a38d4a5dac8ea57f09bd29087e506b" + ], + "markers": "python_version >= '3.7'", + "version": "==0.13.1" + }, "certifi": { "hashes": [ "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082", @@ -598,6 +622,14 @@ "markers": "python_version >= '3.7'", "version": "==8.1.0" }, + "iso3166": { + "hashes": [ + "sha256:263660b36f8471c42acd1ff673d28a3715edbce7d24b1550d0cf010f6816c47f", + "sha256:fcd551b8dda66b44e9f9e6d6bbbee3a1145a22447c0a556e5d0fb1ad1e491719" + ], + "markers": "python_version >= '3.6'", + "version": "==2.1.1" + }, "isoduration": { "hashes": [ "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9", @@ -621,6 +653,14 @@ "markers": "python_version >= '3.7'", "version": "==3.1.2" }, + "jmespath": { + "hashes": [ + "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", + "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe" + ], + "markers": "python_version >= '3.7'", + "version": "==1.0.1" + }, "joblib": { "hashes": [ "sha256:92f865e621e17784e7955080b6d042489e3b8e294949cc44c6eac304f59772b1", @@ -670,11 +710,11 @@ }, "jupyter-client": { "hashes": [ - "sha256:3af69921fe99617be1670399a0b857ad67275eefcfa291e2c81a160b7b650f5f", - "sha256:7441af0c0672edc5d28035e92ba5e32fadcfa8a4e608a434c228836a89df6158" + "sha256:5eb9f55eb0650e81de6b7e34308d8b92d04fe4ec41cd8193a913979e33d8e1a5", + "sha256:60294b2d5b869356c893f57b1a877ea6510d60d45cf4b38057f1672d85699ac9" ], "markers": "python_version >= '3.8'", - "version": "==8.3.0" + "version": "==8.3.1" }, "jupyter-console": { "hashes": [ @@ -866,6 +906,14 @@ "markers": "python_version >= '3.7'", "version": "==1.4.5" }, + "mapbox": { + "hashes": [ + "sha256:13c0774d8e4a4de07c224db00f04f6da21a40c1df7febda1791444d95c3d3c2b", + "sha256:e61be76f1594c0851ec2b7c1d713d4ae8a9c07bada5fa3648ffd718b908b470b" + ], + "index": "pypi", + "version": "==0.18.1" + }, "mapclassify": { "hashes": [ "sha256:3368ecd3ee197f1673979a2e19071a7dd7d88675cfa339c4fbb2432c118d9d47", @@ -993,6 +1041,74 @@ "markers": "python_version >= '3.7'", "version": "==3.0.1" }, + "msgpack": { + "hashes": [ + "sha256:06f5174b5f8ed0ed919da0e62cbd4ffde676a374aba4020034da05fab67b9164", + "sha256:0c05a4a96585525916b109bb85f8cb6511db1c6f5b9d9cbcbc940dc6b4be944b", + "sha256:137850656634abddfb88236008339fdaba3178f4751b28f270d2ebe77a563b6c", + "sha256:17358523b85973e5f242ad74aa4712b7ee560715562554aa2134d96e7aa4cbbf", + "sha256:18334484eafc2b1aa47a6d42427da7fa8f2ab3d60b674120bce7a895a0a85bdd", + "sha256:1835c84d65f46900920b3708f5ba829fb19b1096c1800ad60bae8418652a951d", + "sha256:1967f6129fc50a43bfe0951c35acbb729be89a55d849fab7686004da85103f1c", + "sha256:1ab2f3331cb1b54165976a9d976cb251a83183631c88076613c6c780f0d6e45a", + "sha256:1c0f7c47f0087ffda62961d425e4407961a7ffd2aa004c81b9c07d9269512f6e", + "sha256:20a97bf595a232c3ee6d57ddaadd5453d174a52594bf9c21d10407e2a2d9b3bd", + "sha256:20c784e66b613c7f16f632e7b5e8a1651aa5702463d61394671ba07b2fc9e025", + "sha256:266fa4202c0eb94d26822d9bfd7af25d1e2c088927fe8de9033d929dd5ba24c5", + "sha256:28592e20bbb1620848256ebc105fc420436af59515793ed27d5c77a217477705", + "sha256:288e32b47e67f7b171f86b030e527e302c91bd3f40fd9033483f2cacc37f327a", + "sha256:3055b0455e45810820db1f29d900bf39466df96ddca11dfa6d074fa47054376d", + "sha256:332360ff25469c346a1c5e47cbe2a725517919892eda5cfaffe6046656f0b7bb", + "sha256:362d9655cd369b08fda06b6657a303eb7172d5279997abe094512e919cf74b11", + "sha256:366c9a7b9057e1547f4ad51d8facad8b406bab69c7d72c0eb6f529cf76d4b85f", + "sha256:36961b0568c36027c76e2ae3ca1132e35123dcec0706c4b7992683cc26c1320c", + "sha256:379026812e49258016dd84ad79ac8446922234d498058ae1d415f04b522d5b2d", + "sha256:382b2c77589331f2cb80b67cc058c00f225e19827dbc818d700f61513ab47bea", + "sha256:476a8fe8fae289fdf273d6d2a6cb6e35b5a58541693e8f9f019bfe990a51e4ba", + "sha256:48296af57cdb1d885843afd73c4656be5c76c0c6328db3440c9601a98f303d87", + "sha256:4867aa2df9e2a5fa5f76d7d5565d25ec76e84c106b55509e78c1ede0f152659a", + "sha256:4c075728a1095efd0634a7dccb06204919a2f67d1893b6aa8e00497258bf926c", + "sha256:4f837b93669ce4336e24d08286c38761132bc7ab29782727f8557e1eb21b2080", + "sha256:4f8d8b3bf1ff2672567d6b5c725a1b347fe838b912772aa8ae2bf70338d5a198", + "sha256:525228efd79bb831cf6830a732e2e80bc1b05436b086d4264814b4b2955b2fa9", + "sha256:5494ea30d517a3576749cad32fa27f7585c65f5f38309c88c6d137877fa28a5a", + "sha256:55b56a24893105dc52c1253649b60f475f36b3aa0fc66115bffafb624d7cb30b", + "sha256:56a62ec00b636583e5cb6ad313bbed36bb7ead5fa3a3e38938503142c72cba4f", + "sha256:57e1f3528bd95cc44684beda696f74d3aaa8a5e58c816214b9046512240ef437", + "sha256:586d0d636f9a628ddc6a17bfd45aa5b5efaf1606d2b60fa5d87b8986326e933f", + "sha256:5cb47c21a8a65b165ce29f2bec852790cbc04936f502966768e4aae9fa763cb7", + "sha256:6c4c68d87497f66f96d50142a2b73b97972130d93677ce930718f68828b382e2", + "sha256:821c7e677cc6acf0fd3f7ac664c98803827ae6de594a9f99563e48c5a2f27eb0", + "sha256:916723458c25dfb77ff07f4c66aed34e47503b2eb3188b3adbec8d8aa6e00f48", + "sha256:9e6ca5d5699bcd89ae605c150aee83b5321f2115695e741b99618f4856c50898", + "sha256:9f5ae84c5c8a857ec44dc180a8b0cc08238e021f57abdf51a8182e915e6299f0", + "sha256:a2b031c2e9b9af485d5e3c4520f4220d74f4d222a5b8dc8c1a3ab9448ca79c57", + "sha256:a61215eac016f391129a013c9e46f3ab308db5f5ec9f25811e811f96962599a8", + "sha256:a740fa0e4087a734455f0fc3abf5e746004c9da72fbd541e9b113013c8dc3282", + "sha256:a9985b214f33311df47e274eb788a5893a761d025e2b92c723ba4c63936b69b1", + "sha256:ab31e908d8424d55601ad7075e471b7d0140d4d3dd3272daf39c5c19d936bd82", + "sha256:ac9dd47af78cae935901a9a500104e2dea2e253207c924cc95de149606dc43cc", + "sha256:addab7e2e1fcc04bd08e4eb631c2a90960c340e40dfc4a5e24d2ff0d5a3b3edb", + "sha256:b1d46dfe3832660f53b13b925d4e0fa1432b00f5f7210eb3ad3bb9a13c6204a6", + "sha256:b2de4c1c0538dcb7010902a2b97f4e00fc4ddf2c8cda9749af0e594d3b7fa3d7", + "sha256:b5ef2f015b95f912c2fcab19c36814963b5463f1fb9049846994b007962743e9", + "sha256:b72d0698f86e8d9ddf9442bdedec15b71df3598199ba33322d9711a19f08145c", + "sha256:bae7de2026cbfe3782c8b78b0db9cbfc5455e079f1937cb0ab8d133496ac55e1", + "sha256:bf22a83f973b50f9d38e55c6aade04c41ddda19b00c4ebc558930d78eecc64ed", + "sha256:c075544284eadc5cddc70f4757331d99dcbc16b2bbd4849d15f8aae4cf36d31c", + "sha256:c396e2cc213d12ce017b686e0f53497f94f8ba2b24799c25d913d46c08ec422c", + "sha256:cb5aaa8c17760909ec6cb15e744c3ebc2ca8918e727216e79607b7bbce9c8f77", + "sha256:cdc793c50be3f01106245a61b739328f7dccc2c648b501e237f0699fe1395b81", + "sha256:d25dd59bbbbb996eacf7be6b4ad082ed7eacc4e8f3d2df1ba43822da9bfa122a", + "sha256:e42b9594cc3bf4d838d67d6ed62b9e59e201862a25e9a157019e171fbe672dd3", + "sha256:e57916ef1bd0fee4f21c4600e9d1da352d8816b52a599c46460e93a6e9f17086", + "sha256:ed40e926fa2f297e8a653c954b732f125ef97bdd4c889f243182299de27e2aa9", + "sha256:ef8108f8dedf204bb7b42994abf93882da1159728a2d4c5e82012edd92c9da9f", + "sha256:f933bbda5a3ee63b8834179096923b094b76f0c7a73c1cfe8f07ad608c58844b", + "sha256:fe5c63197c55bce6385d9aee16c4d0641684628f63ace85f73571e65ad1c1e8d" + ], + "version": "==1.0.5" + }, "mypy-extensions": { "hashes": [ "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", @@ -1011,11 +1127,11 @@ }, "nbconvert": { "hashes": [ - "sha256:1113d039fa3fc3a846ffa5a3b0a019e85aaa94c566a09fa0c400fb7638e46087", - "sha256:ace26f4386d08eb5c55833596a942048c5502a95e05590cb523826a749a40a37" + "sha256:aec605e051fa682ccc7934ccc338ba1e8b626cfadbab0db592106b630f63f0f2", + "sha256:f5bc15a1247e14dd41ceef0c0a3bc70020e016576eb0578da62f1c5b4f950479" ], "markers": "python_version >= '3.8'", - "version": "==7.7.4" + "version": "==7.8.0" }, "nbformat": { "hashes": [ @@ -1244,6 +1360,14 @@ "markers": "python_version >= '3.7'", "version": "==3.10.0" }, + "polyline": { + "hashes": [ + "sha256:1492b8fcadc2143f8aedc673d3c6d95df45131f1c62eb8d51c8183b24e771486", + "sha256:45c9c0e8c0814a17df78390e3196cd47f6bc69697cd8a83f00d527c72f4d2a88" + ], + "markers": "python_version >= '3.7'", + "version": "==2.0.0" + }, "prometheus-client": { "hashes": [ "sha256:21e674f39831ae3f8acde238afd9a27a37d0d2fb5a28ea094f0ce25d2cbf2091", @@ -1439,7 +1563,9 @@ }, "pyyaml": { "hashes": [ + "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5", "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc", + "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df", "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741", "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206", "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27", @@ -1447,7 +1573,10 @@ "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62", "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98", "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696", + "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290", + "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9", "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d", + "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6", "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867", "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47", "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486", @@ -1455,9 +1584,12 @@ "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3", "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007", "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938", + "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0", "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c", "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735", "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d", + "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28", + "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", @@ -1472,7 +1604,9 @@ "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43", "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859", "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673", + "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54", "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a", + "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b", "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab", "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa", "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c", @@ -1592,11 +1726,11 @@ }, "qtpy": { "hashes": [ - "sha256:5193d20e0b16e4d9d3bc2c642d04d9f4e2c892590bd1b9c92bfe38a95d5a2e12", - "sha256:a8c74982d6d172ce124d80cafd39653df78989683f760f2281ba91a6e7b9de8b" + "sha256:4d4f045a41e09ac9fa57fcb47ef05781aa5af294a0a646acc1b729d14225e741", + "sha256:db2d508167aa6106781565c8da5c6f1487debacba33519cedc35fa8997d424d4" ], "markers": "python_version >= '3.7'", - "version": "==2.3.1" + "version": "==2.4.0" }, "rasterio": { "hashes": [ @@ -1655,106 +1789,114 @@ }, "rpds-py": { "hashes": [ - "sha256:0173c0444bec0a3d7d848eaeca2d8bd32a1b43f3d3fde6617aac3731fa4be05f", - "sha256:01899794b654e616c8625b194ddd1e5b51ef5b60ed61baa7a2d9c2ad7b2a4238", - "sha256:02938432352359805b6da099c9c95c8a0547fe4b274ce8f1a91677401bb9a45f", - "sha256:03421628f0dc10a4119d714a17f646e2837126a25ac7a256bdf7c3943400f67f", - "sha256:03975db5f103997904c37e804e5f340c8fdabbb5883f26ee50a255d664eed58c", - "sha256:0766babfcf941db8607bdaf82569ec38107dbb03c7f0b72604a0b346b6eb3298", - "sha256:07e2c54bef6838fa44c48dfbc8234e8e2466d851124b551fc4e07a1cfeb37260", - "sha256:0836d71ca19071090d524739420a61580f3f894618d10b666cf3d9a1688355b1", - "sha256:095b460e117685867d45548fbd8598a8d9999227e9061ee7f012d9d264e6048d", - "sha256:0e7521f5af0233e89939ad626b15278c71b69dc1dfccaa7b97bd4cdf96536bb7", - "sha256:0f2996fbac8e0b77fd67102becb9229986396e051f33dbceada3debaacc7033f", - "sha256:1054a08e818f8e18910f1bee731583fe8f899b0a0a5044c6e680ceea34f93876", - "sha256:13b602dc3e8dff3063734f02dcf05111e887f301fdda74151a93dbbc249930fe", - "sha256:141acb9d4ccc04e704e5992d35472f78c35af047fa0cfae2923835d153f091be", - "sha256:14c408e9d1a80dcb45c05a5149e5961aadb912fff42ca1dd9b68c0044904eb32", - "sha256:159fba751a1e6b1c69244e23ba6c28f879a8758a3e992ed056d86d74a194a0f3", - "sha256:190ca6f55042ea4649ed19c9093a9be9d63cd8a97880106747d7147f88a49d18", - "sha256:196cb208825a8b9c8fc360dc0f87993b8b260038615230242bf18ec84447c08d", - "sha256:1fcdee18fea97238ed17ab6478c66b2095e4ae7177e35fb71fbe561a27adf620", - "sha256:207f57c402d1f8712618f737356e4b6f35253b6d20a324d9a47cb9f38ee43a6b", - "sha256:24a81c177379300220e907e9b864107614b144f6c2a15ed5c3450e19cf536fae", - "sha256:29cd8bfb2d716366a035913ced99188a79b623a3512292963d84d3e06e63b496", - "sha256:2d8b3b3a2ce0eaa00c5bbbb60b6713e94e7e0becab7b3db6c5c77f979e8ed1f1", - "sha256:35da5cc5cb37c04c4ee03128ad59b8c3941a1e5cd398d78c37f716f32a9b7f67", - "sha256:44659b1f326214950a8204a248ca6199535e73a694be8d3e0e869f820767f12f", - "sha256:47c5f58a8e0c2c920cc7783113df2fc4ff12bf3a411d985012f145e9242a2764", - "sha256:4bd4dc3602370679c2dfb818d9c97b1137d4dd412230cfecd3c66a1bf388a196", - "sha256:4ea6b73c22d8182dff91155af018b11aac9ff7eca085750455c5990cb1cfae6e", - "sha256:50025635ba8b629a86d9d5474e650da304cb46bbb4d18690532dd79341467846", - "sha256:517cbf6e67ae3623c5127206489d69eb2bdb27239a3c3cc559350ef52a3bbf0b", - "sha256:5855c85eb8b8a968a74dc7fb014c9166a05e7e7a8377fb91d78512900aadd13d", - "sha256:5a46859d7f947061b4010e554ccd1791467d1b1759f2dc2ec9055fa239f1bc26", - "sha256:65a0583c43d9f22cb2130c7b110e695fff834fd5e832a776a107197e59a1898e", - "sha256:674c704605092e3ebbbd13687b09c9f78c362a4bc710343efe37a91457123044", - "sha256:682726178138ea45a0766907957b60f3a1bf3acdf212436be9733f28b6c5af3c", - "sha256:686ba516e02db6d6f8c279d1641f7067ebb5dc58b1d0536c4aaebb7bf01cdc5d", - "sha256:6a5d3fbd02efd9cf6a8ffc2f17b53a33542f6b154e88dd7b42ef4a4c0700fdad", - "sha256:6aa8326a4a608e1c28da191edd7c924dff445251b94653988efb059b16577a4d", - "sha256:700375326ed641f3d9d32060a91513ad668bcb7e2cffb18415c399acb25de2ab", - "sha256:71f2f7715935a61fa3e4ae91d91b67e571aeb5cb5d10331ab681256bda2ad920", - "sha256:745f5a43fdd7d6d25a53ab1a99979e7f8ea419dfefebcab0a5a1e9095490ee5e", - "sha256:79f594919d2c1a0cc17d1988a6adaf9a2f000d2e1048f71f298b056b1018e872", - "sha256:7d68dc8acded354c972116f59b5eb2e5864432948e098c19fe6994926d8e15c3", - "sha256:7f67da97f5b9eac838b6980fc6da268622e91f8960e083a34533ca710bec8611", - "sha256:83b32f0940adec65099f3b1c215ef7f1d025d13ff947975a055989cb7fd019a4", - "sha256:876bf9ed62323bc7dcfc261dbc5572c996ef26fe6406b0ff985cbcf460fc8a4c", - "sha256:890ba852c16ace6ed9f90e8670f2c1c178d96510a21b06d2fa12d8783a905193", - "sha256:8b08605d248b974eb02f40bdcd1a35d3924c83a2a5e8f5d0fa5af852c4d960af", - "sha256:8b2eb034c94b0b96d5eddb290b7b5198460e2d5d0c421751713953a9c4e47d10", - "sha256:8b9ec12ad5f0a4625db34db7e0005be2632c1013b253a4a60e8302ad4d462afd", - "sha256:8c8d7594e38cf98d8a7df25b440f684b510cf4627fe038c297a87496d10a174f", - "sha256:8d3335c03100a073883857e91db9f2e0ef8a1cf42dc0369cbb9151c149dbbc1b", - "sha256:8d70e8f14900f2657c249ea4def963bed86a29b81f81f5b76b5a9215680de945", - "sha256:9039a11bca3c41be5a58282ed81ae422fa680409022b996032a43badef2a3752", - "sha256:91378d9f4151adc223d584489591dbb79f78814c0734a7c3bfa9c9e09978121c", - "sha256:9251eb8aa82e6cf88510530b29eef4fac825a2b709baf5b94a6094894f252387", - "sha256:933a7d5cd4b84f959aedeb84f2030f0a01d63ae6cf256629af3081cf3e3426e8", - "sha256:978fa96dbb005d599ec4fd9ed301b1cc45f1a8f7982d4793faf20b404b56677d", - "sha256:987b06d1cdb28f88a42e4fb8a87f094e43f3c435ed8e486533aea0bf2e53d931", - "sha256:99b1c16f732b3a9971406fbfe18468592c5a3529585a45a35adbc1389a529a03", - "sha256:99e7c4bb27ff1aab90dcc3e9d37ee5af0231ed98d99cb6f5250de28889a3d502", - "sha256:9c439fd54b2b9053717cca3de9583be6584b384d88d045f97d409f0ca867d80f", - "sha256:9ea4d00850ef1e917815e59b078ecb338f6a8efda23369677c54a5825dbebb55", - "sha256:9f30d205755566a25f2ae0382944fcae2f350500ae4df4e795efa9e850821d82", - "sha256:a06418fe1155e72e16dddc68bb3780ae44cebb2912fbd8bb6ff9161de56e1798", - "sha256:a0805911caedfe2736935250be5008b261f10a729a303f676d3d5fea6900c96a", - "sha256:a1f044792e1adcea82468a72310c66a7f08728d72a244730d14880cd1dabe36b", - "sha256:a216b26e5af0a8e265d4efd65d3bcec5fba6b26909014effe20cd302fd1138fa", - "sha256:a987578ac5214f18b99d1f2a3851cba5b09f4a689818a106c23dbad0dfeb760f", - "sha256:aad51239bee6bff6823bbbdc8ad85136c6125542bbc609e035ab98ca1e32a192", - "sha256:ab2299e3f92aa5417d5e16bb45bb4586171c1327568f638e8453c9f8d9e0f020", - "sha256:ab6919a09c055c9b092798ce18c6c4adf49d24d4d9e43a92b257e3f2548231e7", - "sha256:b0c43f8ae8f6be1d605b0465671124aa8d6a0e40f1fb81dcea28b7e3d87ca1e1", - "sha256:b1440c291db3f98a914e1afd9d6541e8fc60b4c3aab1a9008d03da4651e67386", - "sha256:b52e7c5ae35b00566d244ffefba0f46bb6bec749a50412acf42b1c3f402e2c90", - "sha256:bf4151acb541b6e895354f6ff9ac06995ad9e4175cbc6d30aaed08856558201f", - "sha256:c27ee01a6c3223025f4badd533bea5e87c988cb0ba2811b690395dfe16088cfe", - "sha256:c545d9d14d47be716495076b659db179206e3fd997769bc01e2d550eeb685596", - "sha256:c5934e2833afeaf36bd1eadb57256239785f5af0220ed8d21c2896ec4d3a765f", - "sha256:c7671d45530fcb6d5e22fd40c97e1e1e01965fc298cbda523bb640f3d923b387", - "sha256:c861a7e4aef15ff91233751619ce3a3d2b9e5877e0fcd76f9ea4f6847183aa16", - "sha256:d25b1c1096ef0447355f7293fbe9ad740f7c47ae032c2884113f8e87660d8f6e", - "sha256:d55777a80f78dd09410bd84ff8c95ee05519f41113b2df90a69622f5540c4f8b", - "sha256:d576c3ef8c7b2d560e301eb33891d1944d965a4d7a2eacb6332eee8a71827db6", - "sha256:dd9da77c6ec1f258387957b754f0df60766ac23ed698b61941ba9acccd3284d1", - "sha256:de0b6eceb46141984671802d412568d22c6bacc9b230174f9e55fc72ef4f57de", - "sha256:e07e5dbf8a83c66783a9fe2d4566968ea8c161199680e8ad38d53e075df5f0d0", - "sha256:e564d2238512c5ef5e9d79338ab77f1cbbda6c2d541ad41b2af445fb200385e3", - "sha256:ed89861ee8c8c47d6beb742a602f912b1bb64f598b1e2f3d758948721d44d468", - "sha256:ef1f08f2a924837e112cba2953e15aacfccbbfcd773b4b9b4723f8f2ddded08e", - "sha256:f411330a6376fb50e5b7a3e66894e4a39e60ca2e17dce258d53768fea06a37bd", - "sha256:f68996a3b3dc9335037f82754f9cdbe3a95db42bde571d8c3be26cc6245f2324", - "sha256:f7fdf55283ad38c33e35e2855565361f4bf0abd02470b8ab28d499c663bc5d7c", - "sha256:f963c6b1218b96db85fc37a9f0851eaf8b9040aa46dec112611697a7023da535", - "sha256:fa2818759aba55df50592ecbc95ebcdc99917fa7b55cc6796235b04193eb3c55", - "sha256:fae5cb554b604b3f9e2c608241b5d8d303e410d7dfb6d397c335f983495ce7f6", - "sha256:fb39aca7a64ad0c9490adfa719dbeeb87d13be137ca189d2564e596f8ba32c07" + "sha256:00215f6a9058fbf84f9d47536902558eb61f180a6b2a0fa35338d06ceb9a2e5a", + "sha256:0028eb0967942d0d2891eae700ae1a27b7fd18604cfcb16a1ef486a790fee99e", + "sha256:0155c33af0676fc38e1107679be882077680ad1abb6303956b97259c3177e85e", + "sha256:063411228b852fb2ed7485cf91f8e7d30893e69b0acb207ec349db04cccc8225", + "sha256:0700c2133ba203c4068aaecd6a59bda22e06a5e46255c9da23cbf68c6942215d", + "sha256:08e08ccf5b10badb7d0a5c84829b914c6e1e1f3a716fdb2bf294e2bd01562775", + "sha256:0d292cabd7c8335bdd3237ded442480a249dbcdb4ddfac5218799364a01a0f5c", + "sha256:15932ec5f224b0e35764dc156514533a4fca52dcfda0dfbe462a1a22b37efd59", + "sha256:18f87baa20e02e9277ad8960cd89b63c79c05caf106f4c959a9595c43f2a34a5", + "sha256:1a6420a36975e0073acaeee44ead260c1f6ea56812cfc6c31ec00c1c48197173", + "sha256:1b401e8b9aece651512e62c431181e6e83048a651698a727ea0eb0699e9f9b74", + "sha256:1d7b7b71bcb82d8713c7c2e9c5f061415598af5938666beded20d81fa23e7640", + "sha256:23750a9b8a329844ba1fe267ca456bb3184984da2880ed17ae641c5af8de3fef", + "sha256:23a059143c1393015c68936370cce11690f7294731904bdae47cc3e16d0b2474", + "sha256:26d9fd624649a10e4610fab2bc820e215a184d193e47d0be7fe53c1c8f67f370", + "sha256:291c9ce3929a75b45ce8ddde2aa7694fc8449f2bc8f5bd93adf021efaae2d10b", + "sha256:298e8b5d8087e0330aac211c85428c8761230ef46a1f2c516d6a2f67fb8803c5", + "sha256:2c7c4266c1b61eb429e8aeb7d8ed6a3bfe6c890a1788b18dbec090c35c6b93fa", + "sha256:2d68a8e8a3a816629283faf82358d8c93fe5bd974dd2704152394a3de4cec22a", + "sha256:344b89384c250ba6a4ce1786e04d01500e4dac0f4137ceebcaad12973c0ac0b3", + "sha256:3455ecc46ea443b5f7d9c2f946ce4017745e017b0d0f8b99c92564eff97e97f5", + "sha256:3d544a614055b131111bed6edfa1cb0fb082a7265761bcb03321f2dd7b5c6c48", + "sha256:3e5c26905aa651cc8c0ddc45e0e5dea2a1296f70bdc96af17aee9d0493280a17", + "sha256:3f5cc8c7bc99d2bbcd704cef165ca7d155cd6464c86cbda8339026a42d219397", + "sha256:4992266817169997854f81df7f6db7bdcda1609972d8ffd6919252f09ec3c0f6", + "sha256:4d55528ef13af4b4e074d067977b1f61408602f53ae4537dccf42ba665c2c7bd", + "sha256:576da63eae7809f375932bfcbca2cf20620a1915bf2fedce4b9cc8491eceefe3", + "sha256:58fc4d66ee349a23dbf08c7e964120dc9027059566e29cf0ce6205d590ed7eca", + "sha256:5b9bf77008f2c55dabbd099fd3ac87009471d223a1c7ebea36873d39511b780a", + "sha256:5e7996aed3f65667c6dcc8302a69368435a87c2364079a066750a2eac75ea01e", + "sha256:5f7487be65b9c2c510819e744e375bd41b929a97e5915c4852a82fbb085df62c", + "sha256:6388e4e95a26717b94a05ced084e19da4d92aca883f392dffcf8e48c8e221a24", + "sha256:65af12f70355de29e1092f319f85a3467f4005e959ab65129cb697169ce94b86", + "sha256:668d2b45d62c68c7a370ac3dce108ffda482b0a0f50abd8b4c604a813a59e08f", + "sha256:71333c22f7cf5f0480b59a0aef21f652cf9bbaa9679ad261b405b65a57511d1e", + "sha256:7150b83b3e3ddaac81a8bb6a9b5f93117674a0e7a2b5a5b32ab31fdfea6df27f", + "sha256:748e472345c3a82cfb462d0dff998a7bf43e621eed73374cb19f307e97e08a83", + "sha256:75dbfd41a61bc1fb0536bf7b1abf272dc115c53d4d77db770cd65d46d4520882", + "sha256:7618a082c55cf038eede4a918c1001cc8a4411dfe508dc762659bcd48d8f4c6e", + "sha256:780fcb855be29153901c67fc9c5633d48aebef21b90aa72812fa181d731c6b00", + "sha256:78d10c431073dc6ebceed35ab22948a016cc2b5120963c13a41e38bdde4a7212", + "sha256:7a3a3d3e4f1e3cd2a67b93a0b6ed0f2499e33f47cc568e3a0023e405abdc0ff1", + "sha256:7b6975d3763d0952c111700c0634968419268e6bbc0b55fe71138987fa66f309", + "sha256:80772e3bda6787510d9620bc0c7572be404a922f8ccdfd436bf6c3778119464c", + "sha256:80992eb20755701753e30a6952a96aa58f353d12a65ad3c9d48a8da5ec4690cf", + "sha256:841128a22e6ac04070a0f84776d07e9c38c4dcce8e28792a95e45fc621605517", + "sha256:861d25ae0985a1dd5297fee35f476b60c6029e2e6e19847d5b4d0a43a390b696", + "sha256:872f3dcaa8bf2245944861d7311179d2c0c9b2aaa7d3b464d99a7c2e401f01fa", + "sha256:87c93b25d538c433fb053da6228c6290117ba53ff6a537c133b0f2087948a582", + "sha256:8856aa76839dc234d3469f1e270918ce6bec1d6a601eba928f45d68a15f04fc3", + "sha256:885e023e73ce09b11b89ab91fc60f35d80878d2c19d6213a32b42ff36543c291", + "sha256:899b5e7e2d5a8bc92aa533c2d4e55e5ebba095c485568a5e4bedbc163421259a", + "sha256:8ce8caa29ebbdcde67e5fd652c811d34bc01f249dbc0d61e5cc4db05ae79a83b", + "sha256:8e1c68303ccf7fceb50fbab79064a2636119fd9aca121f28453709283dbca727", + "sha256:8e7e2b3577e97fa43c2c2b12a16139b2cedbd0770235d5179c0412b4794efd9b", + "sha256:92f05fc7d832e970047662b3440b190d24ea04f8d3c760e33e7163b67308c878", + "sha256:97f5811df21703446b42303475b8b855ee07d6ab6cdf8565eff115540624f25d", + "sha256:9affee8cb1ec453382c27eb9043378ab32f49cd4bc24a24275f5c39bf186c279", + "sha256:a2da4a8c6d465fde36cea7d54bf47b5cf089073452f0e47c8632ecb9dec23c07", + "sha256:a6903cdca64f1e301af9be424798328c1fe3b4b14aede35f04510989fc72f012", + "sha256:a8ab1adf04ae2d6d65835995218fd3f3eb644fe20655ca8ee233e2c7270ff53b", + "sha256:a8edd467551c1102dc0f5754ab55cd0703431cd3044edf8c8e7d9208d63fa453", + "sha256:ac00c41dd315d147b129976204839ca9de699d83519ff1272afbe4fb9d362d12", + "sha256:ad277f74b1c164f7248afa968700e410651eb858d7c160d109fb451dc45a2f09", + "sha256:ae46a50d235f1631d9ec4670503f7b30405103034830bc13df29fd947207f795", + "sha256:afe6b5a04b2ab1aa89bad32ca47bf71358e7302a06fdfdad857389dca8fb5f04", + "sha256:b1cb078f54af0abd835ca76f93a3152565b73be0f056264da45117d0adf5e99c", + "sha256:b25136212a3d064a8f0b9ebbb6c57094c5229e0de76d15c79b76feff26aeb7b8", + "sha256:b3226b246facae14909b465061ddcfa2dfeadb6a64f407f24300d42d69bcb1a1", + "sha256:b98e75b21fc2ba5285aef8efaf34131d16af1c38df36bdca2f50634bea2d3060", + "sha256:bbd7b24d108509a1b9b6679fcc1166a7dd031dbef1f3c2c73788f42e3ebb3beb", + "sha256:bed57543c99249ab3a4586ddc8786529fbc33309e5e8a1351802a06ca2baf4c2", + "sha256:c0583f69522732bdd79dca4cd3873e63a29acf4a299769c7541f2ca1e4dd4bc6", + "sha256:c1e0e9916301e3b3d970814b1439ca59487f0616d30f36a44cead66ee1748c31", + "sha256:c651847545422c8131660704c58606d841e228ed576c8f1666d98b3d318f89da", + "sha256:c7853f27195598e550fe089f78f0732c66ee1d1f0eaae8ad081589a5a2f5d4af", + "sha256:cbae50d352e4717ffc22c566afc2d0da744380e87ed44a144508e3fb9114a3f4", + "sha256:cdbed8f21204398f47de39b0a9b180d7e571f02dfb18bf5f1b618e238454b685", + "sha256:d08395595c42bcd82c3608762ce734504c6d025eef1c06f42326a6023a584186", + "sha256:d4639111e73997567343df6551da9dd90d66aece1b9fc26c786d328439488103", + "sha256:d63787f289944cc4bde518ad2b5e70a4f0d6e2ce76324635359c74c113fd188f", + "sha256:d6d5f061f6a2aa55790b9e64a23dfd87b6664ab56e24cd06c78eb43986cb260b", + "sha256:d7865df1fb564092bcf46dac61b5def25342faf6352e4bc0e61a286e3fa26a3d", + "sha256:db6585b600b2e76e98131e0ac0e5195759082b51687ad0c94505970c90718f4a", + "sha256:e36d7369363d2707d5f68950a64c4e025991eb0177db01ccb6aa6facae48b69f", + "sha256:e7947d9a6264c727a556541b1630296bbd5d0a05068d21c38dde8e7a1c703ef0", + "sha256:eb2d59bc196e6d3b1827c7db06c1a898bfa0787c0574af398e65ccf2e97c0fbe", + "sha256:ee9c2f6ca9774c2c24bbf7b23086264e6b5fa178201450535ec0859739e6f78d", + "sha256:f4760e1b02173f4155203054f77a5dc0b4078de7645c922b208d28e7eb99f3e2", + "sha256:f70bec8a14a692be6dbe7ce8aab303e88df891cbd4a39af091f90b6702e28055", + "sha256:f869e34d2326e417baee430ae998e91412cc8e7fdd83d979277a90a0e79a5b47", + "sha256:f8b9a7cd381970e64849070aca7c32d53ab7d96c66db6c2ef7aa23c6e803f514", + "sha256:f99d74ddf9d3b6126b509e81865f89bd1283e3fc1b568b68cd7bd9dfa15583d7", + "sha256:f9e7e493ded7042712a374471203dd43ae3fff5b81e3de1a0513fa241af9fd41", + "sha256:fc72ae476732cdb7b2c1acb5af23b478b8a0d4b6fcf19b90dd150291e0d5b26b", + "sha256:fccbf0cd3411719e4c9426755df90bf3449d9fc5a89f077f4a7f1abd4f70c910", + "sha256:ffcf18ad3edf1c170e27e88b10282a2c449aa0358659592462448d71b2000cfc" ], "markers": "python_version >= '3.8'", - "version": "==0.9.2" + "version": "==0.10.0" + }, + "s3transfer": { + "hashes": [ + "sha256:b014be3a8a2aab98cfe1abc7229cc5a9a0cf05eb9c1f2b86b230fd8df3f78084", + "sha256:cab66d3380cca3e70939ef2255d01cd8aece6a4907a9528740f668c4b0611861" + ], + "markers": "python_version >= '3.7'", + "version": "==0.6.2" }, "scikit-learn": { "hashes": [ @@ -2031,13 +2173,21 @@ ], "version": "==1.3.0" }, + "uritemplate": { + "hashes": [ + "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0", + "sha256:830c08b8d99bdd312ea4ead05994a38e8936266f84b9a7878232db50b044e02e" + ], + "markers": "python_version >= '3.6'", + "version": "==4.1.1" + }, "urllib3": { "hashes": [ - "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11", - "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4" + "sha256:8d36afa7616d8ab714608411b4a3b13e58f463aee519024578e062e141dce20f", + "sha256:8f135f6502756bde6b2a9b28989df5fbe87c9970cecaa69041edcce7f0589b14" ], - "markers": "python_version >= '3.7'", - "version": "==2.0.4" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==1.26.16" }, "wcwidth": { "hashes": [ diff --git a/README.md b/README.md index 09b5ca66..c041bb33 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ # Clean & Green Philly + Philadelphia has a gun violence problem. This dashboard aims to help solve it by empowering community groups to carry out cleaning and greening interventions in the vacant properties where they can have the biggest impact. # Motivation + Philadelphia has a gun violence problem. Homicides have been on the rise since 2013. The past three years—2020, 2021, and 2022—have been the deadliest on record, with a high of 562 homicides in 2021. Community members need solutions, but many city-run initiatives are frustratingly slow or inadequate. Nearly 80% of the city’s anti-violence spending focuses on long-term violence reduction without any clear, immediate impact. Research shows that greening and cleaning vacant and abandoned parcels is one of the most impactful, cost-effective interventions available to reduce gun violence in a neighborhood. Drs. Eugenia South and Charles Branas have led several studies that [demonstrate that greening vacant lots in Philadelphia reduced gun violence by as much as 29% in the surrounding area](https://www.pnas.org/doi/10.1073/pnas.1718503115). Similarly, cleaning and lightly repairing vacant houses led a 13% drop in gun assaults compared to nearby blocks. These “greening and cleaning” interventions not only reduce gun violence but also provide other benefits, such as reducing the urban heat island effect, lowering residents’ stress levels, and contributing to lower levels of depression among residents. @@ -9,6 +11,7 @@ Research shows that greening and cleaning vacant and abandoned parcels is one of There are roughly 40,000 vaccant properties in Philadelphia. Identifying the highest-priority vacant properties will allow community groups to invest their limited resources where they will have the biggest impact. Combining various public data, this dashboard helps users identify the properties that are ideal for them to intervene in. It also offers additional information about each property to facilitate interventions and indicates the best possible route to cleaning up the property. # Current Draft + You can view the [most recent prototype of the website and dashboard](https://nlebovits.github.io/dashboard_demo_website/more_info.html), which was created in Quarto. Currently we are in the process of user testing a newer prototype, which looks like this: @@ -18,7 +21,9 @@ Currently we are in the process of user testing a newer prototype, which looks l ![User prototype map](https://github.com/CodeForPhilly/vacant-lots-proj/assets/111617674/8cbf0b06-b299-49cd-8f9f-bbb714e55b44) # Current Tasks + At the moment, we are working on: + - User testing with the prototype - Finishing the Python script that creates the underlying dataset @@ -27,16 +32,17 @@ Current tasks for the Python script are visible under the Issues section. In September, we hope to begin turning our attention to building the dashboard and website, which will be built in React JS. # Looking For + - Front end engineer w/mapping experience - Python data engineer # Languages/Frameworks + - React - Nextjs - Tailwind - Python (data engineering) - # Setup Instructions 1. Install [pyenv](https://github.com/pyenv/pyenv) (or [pyenv-win](https://github.com/pyenv-win/pyenv-win) for Windows) for Python version management @@ -56,9 +62,15 @@ In September, we hope to begin turning our attention to building the dashboard a `CREATE EXTENSION postgis;` 5. Set your database connection string to an environment variable `VACANT_LOTS_DB` +In `/config/config`, set `FORCE_RELOAD` = `False` to read "cached" data in postgres instead of downloading new data. + # awkde -We are using the [awkde package](https://github.com/mennthor/awkde) to create the Adaptive Width KDE. It is not available through pip. Install directly in the `src` folder using their instructions. +We are using the [awkde package](https://github.com/mennthor/awkde) to create the Adaptive Width KDE. It is not available through pip. To install, navigate to `src/awkde` and run + +``` +pip install -e ./awkde +``` # Usage Instructions @@ -66,14 +78,19 @@ We are using the [awkde package](https://github.com/mennthor/awkde) to create th 2. Move the to src folder `cd src` 3. Run the main script `python script.py` +# Mapbox + +To upload to Mapbox through the API you'll need a key with `upload` write access, saved to the environment variable `CFP_MAPBOX_TOKEN_UPLOADER` + # Contribution Instructions 1. Create a fork of this repository and work from branches within your fork. When those changes are ready for review, create a pull request from fork:branch to upstream:main -2. Before committing changes, format your code to maintain a consistent codebase: - ``` - pipenv shell - black . - ``` +2. Before committing changes, format your code to maintain a consistent codebase: + ``` + pipenv shell + black . + ``` # License + MIT © Code for Philly diff --git a/src/awkde/LICENSE b/src/awkde/LICENSE new file mode 100644 index 00000000..cedffc1a --- /dev/null +++ b/src/awkde/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Thorben Menne + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/awkde/README.md b/src/awkde/README.md new file mode 100644 index 00000000..1f517a03 --- /dev/null +++ b/src/awkde/README.md @@ -0,0 +1,65 @@ +# Adaptive Width KDE with Gaussian Kernels + +## Installation + +This uses the awesome [pybind11](https://github.com/pybind/pybind11) package which makes creating C++ bindings super convenient. +Only the evaluation is written in a small C++ snippet to speed it up, the rest is a pure python implementation. + +The setup is taken from the example at https://github.com/pybind/python_example +Just clone the repository and invoke `pip`: + +```bash +git clone https://github.com/mennthor/awkde +pip install [--user] [-e] ./awkde +``` +Note: `--user` and `-e` are optional. Use `--user` to install in your user site-package directory (recommended) and `-e` if you want to only link the files to the site-package directories, so that when you make any changes in your local copy, you don't have to reinstall all the time. + +Try to run the `example/examply.py`: + +``` +cd awkde/example +python example.py +``` + +You should get this plot in the examples folder (you need matplotlib for the plot): + +![example plot](example/example.png) + + +## Algorithm + +The unweighted kernel density estimator is defined as + +![kernel density formula](tex/kernel_dens.png) + +where the product `h * lambda` takes the role of a local `sigma`. + +The kernel bandwith is choosen locally to account for variations in the +density of the data. +Areas with large density gets smaller kernels and vice versa. +This smoothes the tails and gets high resolution in high statistics regions. +The local bandwidth paramter is defined as + +![kernel density formula](tex/lambda.png) + +where + +![kernel density formula](tex/log_g.png) + +is some normalization and `^f(X_i)` the KDE estimate at the data point `X_i`. +The local bandwidth is multiplied to the global bandwidth for each kernel. + +Furthermore different scales in data is accounted for by scaling it via its +covariance matrix to an equal spread. +First a global kernel bandwidth is applied to the transformed data and then +based on that density a local bandwidth parameter is applied. + +All credit for the method goes to [1] and to S. Schoenen and L. Raedel for +huge parts of the implementation. +For information on Silverman or Scott rule, see [2] or [3]. + + +## References +- [1] B. Wang and X. Wang, "Bandwidth Selection for Weighted Kernel Density Estimation", Sep. 2007, DOI: 10.1214/154957804100000000. +- [2] D.W. Scott, "Multivariate Density Estimation: Theory, Practice, and Visualization", John Wiley & Sons, New York, Chicester, 1992. +- [3] B.W. Silverman, "Density Estimation for Statistics and Data Analysis", Vol. 26, Monographs on Statistics and Applied Probability, Chapman and Hall, London, 1986. diff --git a/src/awkde/awkde.egg-info/PKG-INFO b/src/awkde/awkde.egg-info/PKG-INFO new file mode 100644 index 00000000..f037dfad --- /dev/null +++ b/src/awkde/awkde.egg-info/PKG-INFO @@ -0,0 +1,8 @@ +Metadata-Version: 2.1 +Name: awkde +Version: 0.1 +Summary: Adaptive width gaussian KDE +Home-page: https://github.com/mennthor/awkde +Author: Thorben Menne +Author-email: thorben.menne@tu-dortmund.de +License-File: LICENSE diff --git a/src/awkde/awkde.egg-info/SOURCES.txt b/src/awkde/awkde.egg-info/SOURCES.txt new file mode 100644 index 00000000..e3893b75 --- /dev/null +++ b/src/awkde/awkde.egg-info/SOURCES.txt @@ -0,0 +1,13 @@ +LICENSE +README.md +pyproject.toml +setup.py +awkde/__init__.py +awkde/awkde.py +awkde/tools.py +awkde.egg-info/PKG-INFO +awkde.egg-info/SOURCES.txt +awkde.egg-info/dependency_links.txt +awkde.egg-info/requires.txt +awkde.egg-info/top_level.txt +cpp/backend.cpp \ No newline at end of file diff --git a/src/awkde/awkde.egg-info/dependency_links.txt b/src/awkde/awkde.egg-info/dependency_links.txt new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/src/awkde/awkde.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/src/awkde/awkde.egg-info/requires.txt b/src/awkde/awkde.egg-info/requires.txt new file mode 100644 index 00000000..3ac2e261 --- /dev/null +++ b/src/awkde/awkde.egg-info/requires.txt @@ -0,0 +1,5 @@ +numpy +scipy +scikit-learn +pybind11 +future diff --git a/src/awkde/awkde.egg-info/top_level.txt b/src/awkde/awkde.egg-info/top_level.txt new file mode 100644 index 00000000..436fa0a6 --- /dev/null +++ b/src/awkde/awkde.egg-info/top_level.txt @@ -0,0 +1 @@ +awkde diff --git a/src/awkde/awkde/__init__.py b/src/awkde/awkde/__init__.py new file mode 100644 index 00000000..dca7c77c --- /dev/null +++ b/src/awkde/awkde/__init__.py @@ -0,0 +1,10 @@ +# coding: utf-8 + +from __future__ import print_function +from __future__ import division +from __future__ import absolute_import +from future import standard_library + +standard_library.install_aliases() + +from .awkde import GaussianKDE diff --git a/src/awkde/awkde/awkde.py b/src/awkde/awkde/awkde.py new file mode 100644 index 00000000..e979acf0 --- /dev/null +++ b/src/awkde/awkde/awkde.py @@ -0,0 +1,461 @@ +# coding: utf-8 + +from __future__ import division, print_function, absolute_import, unicode_literals +from builtins import int, open +from future import standard_library + +standard_library.install_aliases() + +import os +import sys +import json +import numpy as np +from sklearn.base import BaseEstimator +from sklearn.utils import check_random_state + +from awkde.tools import standardize_nd_sample, shift_and_scale_nd_sample +import awkde.backend as backend + + +class GaussianKDE(BaseEstimator): + """ + GaussianKDE + + Kernel denstiy estimate using gaussian kernels and a local kernel bandwidth. + Implements the ``sklearn.BaseEstimator`` class and can be used in a cross- + validation gridsearch (``sklearn.model_selection``). + + Parameters + ---------- + glob_bw : float or str, optional + The global bandwidth of the kernel, must be a float ``> 0`` or one of + ``['silverman'|'scott']``. If ``alpha`` is not ``None``, this is the + bandwidth used for the first estimate KDE from which the local bandwidth + is calculated. ``If ['silverman'|'scott']`` a rule of thumb is used to + estimate the global bandwidth. (default: 'silverman') + alpha : float or None, optional + If ``None``, only the global bandwidth ``glob_bw`` is used. If + ``0 <= alpha <= 1``, an adaptive local kernel bandwith is used as + described in [1]_. (default: 0.5) + diag_cov : bool, optional + If ``True``, scale fit sample by variance only, which means using a + diagonal covariance matrix. (default: False) + + Notes + ----- + The unweighted kernel density estimator is defined as + + .. math: + + \hat{f}(x) = \sum_i \frac{1}{h\lambda_i}\cdot + K\left(\frac{x - X_i}{h\lambda_i}\right) + + + where the product :math:`h\lambda_i` takes the role of a local + variance :math`\sigma_i^2`. + + The kernel bandwith is choosen locally to account for variations in the + density of the data. + Areas with large density gets smaller kernels and vice versa. + This smoothes the tails and gets high resolution in high statistics regions. + The local bandwidth parameter is defined as + + .. math: \lambda_i = (\hat{f}(X_i) / g)^{-\alpha} + + where :math:`\log g = n^{-1}\sum_i \log\hat{f}(X_i)` is some normalization + and :math:`\hat{f}(X_i)` the KDE estimate at the data point :math:`X_i`. + The local bandwidth is multiplied to the global bandwidth for each kernel. + + Furthermore different scales in data is accounted for by scaling it via its + covariance matrix to an equal spread. + First a global kernel bandwidth is applied to the transformed data and then + based on that density a local bandwidth parameter is applied. + + All credit for the method goes to [1]_ and to S. Schoenen and L. Raedel for + huge parts of the implementation :+1:. + For information on Silverman or Scott rule, see [2]_ or [3]_. + + References + ---------- + .. [1] B. Wang and X. Wang, "Bandwidth Selection for Weighted Kernel Density + Estimation", Sep. 2007, DOI: 10.1214/154957804100000000. + .. [2] D.W. Scott, "Multivariate Density Estimation: Theory, Practice, and + Visualization", John Wiley & Sons, New York, Chicester, 1992. + .. [3] B.W. Silverman, "Density Estimation for Statistics and Data + Analysis", Vol. 26, Monographs on Statistics and Applied Probability, + Chapman and Hall, London, 1986. + """ + + def __init__(self, glob_bw="silverman", alpha=0.5, diag_cov=False): + if type(glob_bw) is str: + if glob_bw not in ["silverman", "scott"]: + raise ValueError("glob_bw can be one of ['silverman'|'scott'].") + pass + elif glob_bw <= 0: + raise ValueError("Global bandwidth must be > 0.") + + # List class attributes. Setup indicating that no fit was done yet + self._n_kernels = None + self._n_features = None + self._std_X = None + self._mean = None + self._cov = None + self._kde_values = None + self._inv_loc_bw = None + self._adaptive = None + + self.alpha = alpha + self._glob_bw = glob_bw + self._diag_cov = diag_cov + + return + + # Properties + @property + def alpha(self): + return self._alpha + + @alpha.setter + def alpha(self, alpha): + """ + The adaptive width can easily be changed after the model has been fit, + because the computation only needs the cached ``_kde_values``. + """ + if alpha is None: + self._adaptive = False + else: + if alpha < 0 or alpha > 1: + raise ValueError("alpha must be in [0, 1]") + self._adaptive = True + + self._alpha = alpha + + if self._std_X is not None and self._adaptive: + # Recalculate local bandwidth if we already have a fitted model + self._calc_local_bandwidth() + + @property + def glob_bw(self): + return self._glob_bw + + @property + def diag_cov(self): + return self._diag_cov + + # Public Methods + def __call__(self, X): + # Does the same as `predict`, only copy docstring here + self.__call__.__func__.__doc__ = self.predict.__doc__ + return self.predict(X) + + def fit(self, X, bounds=None, weights=None): + """ + Prepare KDE to describe the data. + + Data is transformed via global covariance matrix to equalize scales in + different features. + Then a symmetric kernel with cov = diag(1) is used to describe the pdf + at each point. + + Parameters + ----------- + X : array-like, shape (n_samples, n_features) + Data points defining each kernel position. Each row is a point, each + column is a feature. + bounds : array-like, shape (n_features, 2) + Boundary condition for each dimension. The method of mirrored points + is used to improve prediction close to bounds. If no bound shall be + given in a specific direction use ``None``, eg. + ``[[0, None], ...]``. If ``bounds`` is ``None`` no bounds are used + in any direction. (default: ``None``) + weights : array-like, shape (n_samples), optional + Per event weights to consider for ``X``. If ``None`` all weights are + set to one. (default: ``None``) + + Returns + ------- + mean : array-like, shape (n_features) + The (weighted) mean of the given data. + cov : array-like, shape (n_features, n_features) + The (weighted) covariance matrix of the given data. + + Raises + ------ + ``NotImplementedError`` if ``bounds`` or ``weights`` are not ``None``. + """ + if bounds is not None: + # TODO: Use mirroring of points near boundary regions and then + # constrain KDE to values inside Region but taking all kernels + # into account. (only neccessary on hard cuts) + raise NotImplementedError("TODO: Boundary conditions.") + if weights is not None: + # TODO: Implement weighted statitistics + raise NotImplementedError("TODO: Implement weighted statistics.") + + if len(X.shape) != 2: + raise ValueError("`X` must have shape (n_samples, n_features).") + + # Transform sample to zero mean and unity covariance matrix + self._n_kernels, self._n_features = X.shape + self._std_X, self._mean, self._cov = standardize_nd_sample( + X, cholesky=True, ret_stats=True, diag=self._diag_cov + ) + + # Get global bandwidth number + self._glob_bw = self._get_glob_bw(self._glob_bw) + + # Build local bandwidth parameter if alpha is set + if self._adaptive: + self._kde_values = self._evaluate(self._std_X, adaptive=False) + self._calc_local_bandwidth() + + return self._mean, self._cov + + def predict(self, X): + """ + Evaluate KDE at given points X. + + Parameters + ----------- + X : array-like, shape (n_samples, n_features) + Data points we want to evaluate the KDE at. Each row is a point, + each column is a feature. + + Returns + ------- + prob : array-like, shape (len(X)) + The probability from the KDE pdf for each point in X. + """ + if self._std_X is None: + raise ValueError("KDE has not been fitted to data yet.") + + X = np.atleast_2d(X) + _, n_feat = X.shape + if n_feat != self._n_features: + raise ValueError("Dimensions of given points and KDE don't match.") + + # Standardize given points to be in the same space as the KDE + X = standardize_nd_sample( + X, + mean=self._mean, + cov=self._cov, + cholesky=True, + ret_stats=False, + diag=self._diag_cov, + ) + + # No need to backtransform, because we only return y-values + return self._evaluate(X, adaptive=self._adaptive) + + def sample(self, n_samples, random_state=None): + """ + Get random samples from the KDE model. + + Parameters + ---------- + n_samples : int, optional + Number of samples to generate. (default: 1) + random_state : RandomState, optional + Turn seed into a `np.random.RandomState` instance. Method from + `sklearn.utils`. Can be None, int or RndState. (default: None) + + Returns + ------- + X : array_like, shape (n_samples, n_features) + Generated samples from the fitted model. + """ + if self._std_X is None: + raise ValueError("KDE has not been fitted to data yet.") + + rndgen = check_random_state(random_state) + + # Select randomly all kernels to sample from + idx = rndgen.randint(0, self._n_kernels, size=n_samples) + + # Because we scaled to standard normal dist, we can draw uncorrelated + # and the cov is only the inverse bandwidth of each kernel. + means = self._std_X[idx] + invbw = np.ones(n_samples) / self._glob_bw + if self._adaptive: + invbw *= self._inv_loc_bw[idx] + invbw = invbw.reshape(n_samples, 1) + + # Retransform to original space + sample = np.atleast_2d(rndgen.normal(means, 1.0 / invbw)) + return shift_and_scale_nd_sample(sample, self._mean, self._cov) + + def score(self, X): + """ + Compute the total ln-probability of points X under the KDE model. + + Parameters + ---------- + X : array-like, shape (n_samples, n_features) + Data points included in the score calculation. Each row is a point, + each column is a feature. + + Returns + ------- + lnprob : float + Total ln-likelihood of the data ``X`` given the KDE model. + """ + if self._std_X is None: + raise ValueError("KDE has not been fitted to data yet.") + + X = np.atleast_2d(X) + _, n_feat = X.shape + if n_feat != self._n_features: + raise ValueError("Dimensions of given points and KDE don't match.") + + probs = self.predict(np.atleast_2d(X)) + if np.any(probs <= 0): + return -np.inf + else: + return np.sum(np.log(probs)) + + def to_json(self, fpath): + """ + Write out the relevant parameters for the KDE model as a JSON file, + which can be used to reconstruct the whole model with ``from_json``. + + Parameters + ---------- + fpath : string + File path where to save the JSON dump. + """ + if self._std_X is None: + raise ValueError("KDE has not been fitted to data yet.") + + out = self.get_params() # From implementing sklearnBaseEstimator + out["kde_X_std"] = [list(Xi) for Xi in self._std_X] + out["kde_X_mean"] = list(self._mean) + out["kde_X_cov"] = [list(Xi) for Xi in self._cov] + + if self._kde_values is not None: + out["kde_Y"] = list(self._kde_values) + else: + out["kde_Y"] = None + + # json seems to behave differently in py2 vs py3 ... + if sys.version_info[0] < 3: + mode = "wb" + else: + mode = "w" + with open(os.path.abspath(fpath), mode) as f: + json.dump(obj=out, fp=f, indent=2) + + return + + @classmethod + def from_json(cls, fpath, verb=False): + """ + Build a awKDE object from a JSON dict with the needed parts. + + Parameters + ---------- + fpath : string + Path to the JSON file. Must have keys: + + - 'alpha', 'diag_cov', 'glob_bw': See GaussianKDE docstring. + - 'kde_Y': KDE function values at points 'kde_X_std' used for the + adaptive kernel computation. + - 'kde_X_std': Standardized sample in shape + ``(nsamples, nfeatures)``. + - 'kde_X_mean': Mean vector of the standardized sample. + - 'kde_X_cov': Covariance matrix of the stadardized sample. + verb : bool, optional + If ``True`` print model summary. (default: ``False``) + + Returns + ------- + kde : KDE.GaussianKDE + KDE object in fitted state, ready to evaluate or sample from. + """ + with open(os.path.abspath(fpath), "rb") as f: + d = json.load(f) + + kde = cls(glob_bw=d["glob_bw"], alpha=d["alpha"], diag_cov=d["diag_cov"]) + + # Reconstruct all internals without using fit again + kde._std_X = np.atleast_2d(d["kde_X_std"]) + kde._n_kernels, kde._n_features = kde._std_X.shape + kde._mean = np.atleast_1d(d["kde_X_mean"]) + kde._cov = np.atleast_2d(d["kde_X_cov"]) + + if len(kde._mean) != kde._n_features: + raise ValueError( + "'kde_X_mean' has not the same dimension " + "as the X values." + ) + if kde._cov.shape != (kde._n_features, kde._n_features): + raise ValueError("'kde_X_cov' has not shape " + "(n_features, n_features).") + + if d["kde_Y"] is not None: + if d["alpha"] is None: + raise ValueError("Saved 'alpha' is None, but 'kde_Y' is not.") + # Set kde values and alpha to restore inverse bandwidth internally + kde._kde_values = np.atleast_1d(d["kde_Y"]) + kde.alpha = d["alpha"] + + if len(kde._kde_values) != kde._n_kernels: + raise ValueError("'kde_Y' has not the same length as 'kde_X_std'.") + + if verb: + print("Loaded KDE model from {}".format(fpath)) + print("- glob_bw : {:.3f}".format(kde._glob_bw)) + print("- alpha : {:.3f}".format(kde._alpha)) + print("- adaptive : {}".format(kde._adaptive)) + print("- Nr. of kernels : {:d}".format(kde._n_kernels)) + print("- Nr. of data dim : {:d}".format(kde._n_features)) + + return kde + + # Private Methods + def _evaluate(self, X, adaptive): + """ + Evaluate KDE at given points, returning the log-probability. + + Parameters + ----------- + X : array-like, shape (n_samples, n_features) + Data points we want to evaluate the KDE at. Each row is a point, + each column is a feature. + adaptive : bool, optional + Wether to evaluate with fixed or with adaptive kernel. + (default: True) + + Returns + ------- + prob : array-like, shape (len(X)) + The probability from the KDE PDF for each point in X. + """ + n = self._n_kernels + d = self._n_features + + # Get fixed or adaptive bandwidth + invbw = np.ones(n) / self._glob_bw + if adaptive: + invbw *= self._inv_loc_bw + + # Total norm, including gaussian kernel norm with data covariance + norm = invbw**d / np.sqrt(np.linalg.det(2 * np.pi * self._cov)) / n + + return backend.kernel_sum(self._std_X, X, invbw, norm) + + def _get_glob_bw(self, glob_bw): + """Simple wrapper to handle string args given for global bw.""" + dim = self._n_features + nsam = self._n_kernels + if glob_bw == "silverman": + return np.power(nsam * (dim + 2.0) / 4.0, -1.0 / (dim + 4)) + elif glob_bw == "scott": + return np.power(nsam, -1.0 / (dim + 4)) + else: + return self._glob_bw + + def _calc_local_bandwidth(self): + """Build the local bandwidth from cached ``_kde_values``.""" + # Get local bandwidth from local "density" g + g = np.exp(np.sum(np.log(self._kde_values)) / self._n_kernels) + # Needed inverted so use power of (+alpha), shape (n_samples) + self._inv_loc_bw = (self._kde_values / g) ** (self._alpha) + return diff --git a/src/awkde/awkde/backend.cpython-311-darwin.so b/src/awkde/awkde/backend.cpython-311-darwin.so new file mode 100755 index 00000000..0e8079aa Binary files /dev/null and b/src/awkde/awkde/backend.cpython-311-darwin.so differ diff --git a/src/awkde/awkde/tools.py b/src/awkde/awkde/tools.py new file mode 100644 index 00000000..153adf3e --- /dev/null +++ b/src/awkde/awkde/tools.py @@ -0,0 +1,147 @@ +# coding: utf8 + +""" +Part of awkde package +--------------------- + +Helper tools for standardizing a data sample. +""" + +from __future__ import print_function, division, absolute_import +from future import standard_library + +standard_library.install_aliases() + +import numpy as _np + + +def standardize_nd_sample( + sam, mean=None, cov=None, cholesky=True, ret_stats=False, diag=False +): + """ + Standardizes a n-dimensional sample using the Mahalanobis distance. + + .. math:: x' = \Sigma^{-1/2} (x - y) + + The resulting sample :math:`x'` has a zero mean vector and an identity + covariance. + + Parameters + ---------- + sam : array-like, shape (n_samples, n_features) + Data points in the sample, each column is a feature, each row a point. + mean : array-like, shape (n_features), optional + If explicitely given, use this mean vector for the transformation. If + None, the estimated mean from data is used. (default: None) + cov : array-like, shape (n_features, n_features), optional + If explicitely given, use this covariance matrix for the transformation. + If None, the estimated cov from data is used. (default: None) + cholesky : bool, optional + If true, use fast Cholesky decomposition to calculate the sqrt of the + inverse covariance matrix. Else use eigenvalue decomposition (Can be + numerically unstable, not recommended). (default: True) + ret_stats : bool, optional + If True, the mean vector and covariance matrix of the input sample are + returned, too. (default: False) + diag : bool + If True, only scale by variance, diagonal cov matrix. (default: False) + + Returns + ------- + stand_sam : array-like, shape (n_samples, n_features) + Standardized sample, with mean = [0., ..., 0.] and cov = identity. + + Optional Returns + ---------------- + mean : array-like, shape(n_features) + Mean vector of the input data, only if ret_stats is True. + cov : array-like, shape(n_features, n_features) + Covariance matrix of the input data, only if ret_stats is True. + + Example + ------- + >>> mean = [10, -0.01, 1] + >>> cov = [[14, -.2, 0], [-.2, .1, -0.1], [0, -0.1, 1]] + >>> sam = np.random.multivariate_normal(mean, cov, size=1000) + >>> std_sam = standardize_nd_sample(sam) + >>> print(np.mean(std_sam, axis=0)) + >>> print(np.cov(std_sam, rowvar=False)) + """ + if len(sam.shape) != 2: + raise ValueError("Shape of `sam` must be (n_samples, n_features).") + if mean is None and cov is None: + # Mean and cov over the first axis + mean = _np.mean(sam, axis=0) + cov = _np.atleast_2d(_np.cov(sam, rowvar=False)) + elif mean is not None and cov is not None: + mean = _np.atleast_1d(mean) + cov = _np.atleast_2d(cov) + if len(mean) != sam.shape[1]: + raise ValueError("Dimensions of mean and sample don't match.") + if cov.shape[0] != sam.shape[1]: + raise ValueError("Dimensions of cov and sample don't match.") + + if diag: + cov = _np.diag(cov) * _np.eye(cov.shape[0]) + + if cholesky: + # Cholesky produces a tridiagonal matrix from A with: L L^T = A + # To get the correct trafo, we need to transpose the returned L: + # L.L^t + sqrtinvcov = _np.linalg.cholesky(_np.linalg.inv(cov)).T + else: + # The naive sqrt of eigenvalues. Is (at least) instable for > 3d + # A = Q lam Q^-1. If A is symmetric: A = Q lam Q^T + lam, Q = _np.linalg.eig(_np.linalg.inv(cov)) + sqrtlam = _np.sqrt(lam) + sqrtinvcov = _np.dot(sqrtlam * Q, Q.T) + + # Transform each sample point and reshape result (n_samples, n_features) + stand_sam = _np.dot(sqrtinvcov, (sam - mean).T).T + + if ret_stats: + return stand_sam, mean, cov + else: + return stand_sam + + +def shift_and_scale_nd_sample(sam, mean, cov, cholesky=True): + """ + Shift and scale a nD sample by given mean and covariance matrix. + + This is the inverse operation of `standardize_nd_sample`. If a + standardized sample :math:`x'` with zero mean vector and identity covariance + matrix is given, it is rescaled and shifted using + + .. math:: x = (\Sigma^{1/2} x) + y + + then having a mean vector `mean` and a covariance matrix `cov`. + + Parameters + ---------- + sam : array-like, shape (n_samples, n_features) + Data points in the sample, each column is a feature, each row a point. + mean : array-like, shape (n_features) + Mean vector used for the transformation. + cov : array-like, shape (n_features, n_features) + Covariance matrix used for the transformation. + + Returns + ------- + scaled_sam : array-like, shape (n_samples, n_features) + Scaled sample using the transformation with the given mean and cov. + """ + if len(sam.shape) != 2: + raise ValueError("Shape of `sam` must be (n_samples, n_features).") + mean = _np.atleast_1d(mean) + cov = _np.atleast_2d(cov) + if len(mean) != sam.shape[1]: + raise ValueError("Dimensions of mean and sample don't match.") + if cov.shape[0] != sam.shape[1]: + raise ValueError("Dimensions of cov and sample don't match.") + + # Transformation matrix: inverse of original trafo + sqrtinvcov = _np.linalg.cholesky(_np.linalg.inv(cov)).T + sqrtcov = _np.linalg.inv(sqrtinvcov) + + return _np.dot(sqrtcov, sam.T).T + mean diff --git a/src/awkde/cpp/backend.cpp b/src/awkde/cpp/backend.cpp new file mode 100644 index 00000000..e88b2ec3 --- /dev/null +++ b/src/awkde/cpp/backend.cpp @@ -0,0 +1,115 @@ +#include +#include +#include + + +namespace py = pybind11; + +// Actual C++ snippet. See `docstr` below for argument info. +template +py::array_t kernel_sum (const py::array_t& X, + const py::array_t& Y, + const py::array_t& invbw, + const py::array_t& norm) { + // Gather input shape info + auto bX = X.template unchecked<2>(); + auto bY = Y.template unchecked<2>(); + auto lenX = bX.shape(0); + auto ndim = bX.shape(1); + auto lenY = bY.shape(0); + auto ndimY = bY.shape(1); + auto binvbw = invbw.template unchecked<1>(); + auto bnorm = norm.template unchecked<1>(); + + // Check data integrity + if (ndim != ndimY) { + throw std::runtime_error( + "Points in X and Y must have the same number of dimensions."); + } + if (lenX != binvbw.shape(0) || lenX != bnorm.shape(0)) { + throw std::runtime_error( + "X, invbw and norm must have the same lengths."); + } + + // Set up output: shape (lenY) + py::array_t eval(lenY); + auto beval = eval.template mutable_unchecked<1>(); + + // Get squared distances for all in Y to all in X and sum up the PDF value + // from the gaussian kernel PDF for each Y. + T diff_ij; + T dist2_ij; + for (unsigned int i = 0; i < lenY; ++i) { // Loop over Y elements + beval(i) = 0.; + for (unsigned int j = 0; j < lenX; ++j) { // Loop over X elements + dist2_ij = 0.; + for (unsigned int k = 0; k < ndim; ++k) { // Loop over features + diff_ij = bY(i, k) - bX(j, k); + dist2_ij += diff_ij * diff_ij; + } + // PDF_i = sum_{j in X} (norm_j * exp(-0.5 * dist2_ij * invbw_j^2) + beval(i) += bnorm(j) * std::exp(-0.5 * dist2_ij * + binvbw(j) * binvbw(j)); + } + } + + return eval; +} + + +// //////////////////////////////////////////////////////////////////////////// +// pybind11 binding stuff +PYBIND11_MODULE(backend, m) { + // Module docstring + m.doc() = R"pbdoc( + Pybind11 C++ backend for awkde + ------------------------------ + + .. currentmodule:: awkde_backend + + .. autosummary:: + :toctree: _generate + + kernel_sum + )pbdoc"; + + // Method docstrings (easier to read when separated) + // Note: using C++ multi-line literals (pbdoc delimiter) + auto docstr = R"pbdoc( + kernel_sum + + Takes an array of kernel points `X` and points `Y` to + evaluate the KDE at and returns the KDE PDF values for + each point in `Y`. + + Parameters + ---------- + X : double array, shape (len(X), ndim) + Data points defining each kernel position. Each row is + a point, each column is a feature. + Y : double array, shape (len(Y), ndim) + Data points we want to evaluate the KDE at. Each row is + a point, each column is a feature. + invbw : double array, shape (len(X)) + Inverse kernel bandwidth, acting as :math:`1 / sigma^2`. + norm : double array, shape (len(X)) + Kernel gaussian norm for `ndim` dimensions. + + Returns + ------- + eval : float array, shape (len(Y)) + The probability from the KDE PDF for each point in `Y`. + )pbdoc"; + + // Define the actual template typess + m.def("kernel_sum", &kernel_sum, docstr, + py::arg("X"), py::arg("Y"), py::arg("invbw"), py::arg("norm")); + m.def("kernel_sum", &kernel_sum, "", + py::arg("X"), py::arg("Y"), py::arg("invbw"), py::arg("norm")); + +#ifdef VERSION_INFO + m.attr("__version__") = py::str(VERSION_INFO); +#else + m.attr("__version__") = py::str("dev"); +#endif +} \ No newline at end of file diff --git a/src/awkde/example/example.png b/src/awkde/example/example.png new file mode 100644 index 00000000..4a3562a3 Binary files /dev/null and b/src/awkde/example/example.png differ diff --git a/src/awkde/example/example.py b/src/awkde/example/example.py new file mode 100644 index 00000000..15f8c513 --- /dev/null +++ b/src/awkde/example/example.py @@ -0,0 +1,127 @@ +# coding: utf-8 + +""" +A 2D example for the adaptive width KDE. + +Sample x1 from a gaussian and x2 from x*exp(-x). +Make a plot with the prediction and save the model to a JSON dump. +""" + +import numpy as np +import scipy.stats as scs +import matplotlib.pyplot as plt +import matplotlib.gridspec as gridspec +from matplotlib.colors import LogNorm + +from awkde import GaussianKDE + + +rndgen = np.random.RandomState(seed=3575) # ESEL +# Gaussian +mean = 3.0 +sigma = 0.25 +# a^2 * x * exp(-a * x) +a = 100.0 + +n_samples = 1000 +logE_sam = rndgen.normal(mean, sigma, size=n_samples) + +# From pythia8: home.thep.lu.se/~torbjorn/doxygen/Basics_8h_source.html +u1, u2 = rndgen.uniform(size=(2, n_samples)) +sigma_sam = -np.log(u1 * u2) / a + +# Shape must be (n_points, n_features) +sample = np.vstack((logE_sam, sigma_sam)).T + +# Create KDE and fit it. Save model in JSON format +print("Fitting model to {} sample points.".format(n_samples)) +kde = GaussianKDE(glob_bw="silverman", alpha=0.5, diag_cov=True) +kde.fit(sample) + +# Save and load the model +outf = "./example_KDE.json" +print("Saving model to {}".format(outf)) +kde.to_json(outf) +print("Loading same model from {}".format(outf)) +kde = GaussianKDE.from_json(outf) + +# Evaluate at dense grid +minx, maxx = np.amin(sample[:, 0]), np.amax(sample[:, 0]) +miny, maxy = np.amin(sample[:, 1]), np.amax(sample[:, 1]) + +x = np.linspace(minx, maxx, 100) +y = np.linspace(miny, maxy, 100) + +XX, YY = np.meshgrid(x, y) +grid_pts = np.array(list(map(np.ravel, [XX, YY]))).T + +zz = kde.predict(grid_pts) +ZZ = zz.reshape(XX.shape) + +# These are bin edges for pcolormesh, len = len(x) + 1 +dx2, dy2 = (x[1] - x[0]) / 2.0, (y[1] - y[0]) / 2.0 +bx = np.concatenate((x - dx2, [x[-1] + dx2])) +by = np.concatenate((y - dy2, [y[-1] + dy2])) + + +# Evaluate true PDFs at same grid +def fx(x): + return scs.norm.pdf(x, mean, sigma) + + +def fy(y): + return a**2 * y * np.exp(-a * y) + + +fZ = (fx(grid_pts[:, 0]) * fy(grid_pts[:, 1])).reshape(XX.shape) + +# Sample new points from KDE model +kde_sam = kde.sample(n_samples=100000, random_state=rndgen) + +print("Making example plot.") +# Big plot on the left (2D KDE + points ) and three right (1D margins + hist) +fig = plt.figure(figsize=(10, 6)) +gs = gridspec.GridSpec(3, 3) +axl = fig.add_subplot(gs[:, :2]) +axrt = fig.add_subplot(gs[0, 2]) +axrc = fig.add_subplot(gs[1, 2]) +axrb = fig.add_subplot(gs[2, 2]) + +color_of_points = "#351322" +color_of_dist = "#1e90ff" + +# Main plot +axl.pcolormesh(bx, by, ZZ, cmap="Blues", norm=LogNorm(), shading="flat") +axl.scatter( + logE_sam, sigma_sam, marker=".", color=color_of_points, edgecolor="none", s=30 +) +axl.set_title("KDE log PDF + original sample") + +# Top right: truth with scatter +axrt.pcolormesh(bx, by, fZ, cmap="Blues", norm=LogNorm(), shading="flat") +axrt.scatter(logE_sam, sigma_sam, marker=".", color=color_of_points, s=1) +axrt.set_title("True log PDF + KDE sample") + +# 1D x1, x2 hists. Hist very fine, so we get the shape of the PDF and don't +# have to integrate the KDE PDF numerically. +axrc.hist(kde_sam[:, 0], bins=250, density=True, color=color_of_points) +axrc.plot(x, fx(x), color=color_of_dist) +axrb.hist(kde_sam[:, 1], bins=250, density=True, color=color_of_points) +axrb.plot(y, fy(y), color=color_of_dist) +axrc.set_title("True 1D PDF + KDE sample") +axrb.set_title("True 1D PDF + KDE sample") + +for axi in (axl, axrt): + axi.set_xlim(minx, maxx) + axi.set_ylim(0, maxy) + axi.set_xlabel("x1") + axi.set_ylabel("x2") + +axrc.set_xlim(minx, maxx) +axrb.set_xlim(miny, maxy) +axrc.set_xlabel("x1") +axrb.set_xlabel("x2") + +fig.tight_layout() +fig.savefig("example.png", dpi=50) +# plt.show() diff --git a/src/awkde/example/example_KDE.json b/src/awkde/example/example_KDE.json new file mode 100644 index 00000000..b12fc55c --- /dev/null +++ b/src/awkde/example/example_KDE.json @@ -0,0 +1,5023 @@ +{ + "kde_X_cov": [ + [ + 0.055394409593707866, + 0.0 + ], + [ + 0.0, + 0.000189259752803009 + ] + ], + "glob_bw": 0.31622776601683794, + "kde_X_std": [ + [ + -0.038772367739634397, + -1.1254927149286837 + ], + [ + 0.91283236066410689, + -1.0203477536431722 + ], + [ + -0.053052130849891473, + 0.043403576093835834 + ], + [ + -1.0756456141606578, + 0.42504425101493282 + ], + [ + 0.12079924319366782, + 0.84469339896658147 + ], + [ + -1.0539632687647917, + -0.5483372178811039 + ], + [ + 1.5767696954279486, + -0.78224177248956683 + ], + [ + -1.2190236670242769, + -0.99111259730203682 + ], + [ + 1.4931503939595865, + -1.300980586705534 + ], + [ + 0.1220377935327538, + 0.061519148878938459 + ], + [ + 2.2069432312913313, + -0.7143264313133022 + ], + [ + 1.9341883310230343, + 0.99504117628753064 + ], + [ + 0.72551610777568942, + 0.28456885096661361 + ], + [ + 1.5285619237773624, + -0.55287318744585356 + ], + [ + 0.16333960386251034, + -0.53061949111115592 + ], + [ + -0.5050524027018567, + 1.2524600532486772 + ], + [ + 0.23234176914316912, + -0.18131358604187067 + ], + [ + -0.90780269926272628, + 0.036142650371662817 + ], + [ + 0.36800071918168614, + -0.0070031795904719179 + ], + [ + -0.10064751715853765, + 1.5304585212365116 + ], + [ + -0.35122794397872431, + 0.27943077479246325 + ], + [ + -0.80382666045113094, + -0.12898312177038987 + ], + [ + 0.41224958215799318, + 0.64365480467782732 + ], + [ + 2.7129398019058595, + -0.32810905962283138 + ], + [ + -2.2361614923831334, + 0.16002049630640255 + ], + [ + -1.3206348042010336, + 0.98041885279393159 + ], + [ + -0.34139280736010874, + -1.2286699964943877 + ], + [ + 1.7729512081167225, + 0.91163034764109918 + ], + [ + 0.57505284564283687, + -1.0972390183490282 + ], + [ + 0.19825977243802756, + -1.0873055838346457 + ], + [ + -0.654932972471994, + -1.3078385530466843 + ], + [ + -0.58475208340517848, + -1.0580303697727917 + ], + [ + 0.42983230302562808, + 2.0044995350940944 + ], + [ + -0.27815222403779749, + -0.43678173076992693 + ], + [ + -0.60728286225878769, + -1.1700500534079419 + ], + [ + -0.78891057551636723, + 0.59585812659142612 + ], + [ + -0.016170617822073137, + -0.95961686832095305 + ], + [ + -2.1426063401230699, + -1.3315591188358176 + ], + [ + -0.30090661571572924, + 2.6456443611317471 + ], + [ + -0.15802001927584688, + 0.45495088779220688 + ], + [ + -0.83488247617177946, + -0.44589633575639986 + ], + [ + 0.2479730662335021, + -0.084092313195468629 + ], + [ + 1.5254718117934776, + -1.1404409003946978 + ], + [ + 1.2238974647235652, + 0.34090541177725814 + ], + [ + 0.91465263273951047, + 0.44160441828566543 + ], + [ + -0.066259199584315018, + 0.56380852126987846 + ], + [ + -0.39542212734122262, + 0.17718601155493119 + ], + [ + 0.17652094257423095, + -0.39508111489101982 + ], + [ + 0.068107825083629031, + 0.69008735825929512 + ], + [ + -0.56695604118475917, + 0.3275177676362917 + ], + [ + -0.22399671484983688, + -0.001379326037921005 + ], + [ + -0.15367203570186891, + 1.3294631530719758 + ], + [ + -0.23324842028993184, + -0.93250741110297264 + ], + [ + 0.98047025711942104, + 1.8479876249111546 + ], + [ + 1.0238816220332314, + -0.62935347216543913 + ], + [ + -0.41792921871027139, + 1.7055333860412465 + ], + [ + 1.6228851342570911, + 1.7892960657909092 + ], + [ + -0.028484886684660357, + 0.86975888426881254 + ], + [ + 0.33489307530858553, + -0.46931069767422345 + ], + [ + -0.081242722847126303, + 0.18488730963420796 + ], + [ + -0.5007790087922257, + -0.79155910992885026 + ], + [ + -0.72034839456750921, + -0.6650074954682067 + ], + [ + -0.41252933420480936, + -0.48949394331785628 + ], + [ + 0.38996746421843415, + -0.64509175234983829 + ], + [ + -0.85012548480957884, + -0.034286906329572403 + ], + [ + 1.9687233064963148, + 2.3046159837380054 + ], + [ + 0.72823689131001434, + -0.19626461186956734 + ], + [ + -1.2118822992970855, + -0.76934394415088303 + ], + [ + -0.19297178364046058, + -0.41834660295120024 + ], + [ + 0.61563343534856618, + -0.11845238952535454 + ], + [ + 0.70167061759060212, + -0.74833812899924113 + ], + [ + -0.070465004791077632, + 1.8055424732738568 + ], + [ + -1.3638929226972762, + -0.89510132739248938 + ], + [ + -1.4529943556801053, + -1.1818187779871725 + ], + [ + -1.2606917362347754, + -0.4301030229653996 + ], + [ + -1.2273726958298214, + 0.36584025502615763 + ], + [ + 1.0863784937705043, + -0.20155908611548315 + ], + [ + 0.24309476807382935, + 0.4109723885746695 + ], + [ + 1.1036479238383679, + -1.0412773345339248 + ], + [ + -0.99185219253367318, + -0.86210030402568805 + ], + [ + 0.94724982938884028, + -0.97758633409625328 + ], + [ + -0.12875083391666997, + -1.0597380645788717 + ], + [ + 1.2944206187944147, + 0.53650163036127041 + ], + [ + -1.293252604981163, + -0.85211866718453977 + ], + [ + -0.18609554341345411, + -1.0489853388664461 + ], + [ + -2.5534850985478732, + -0.27068344556963386 + ], + [ + -0.091969682364326386, + -0.23420189267828612 + ], + [ + 0.17298936823033406, + -0.19084454636041906 + ], + [ + 0.79166305555512406, + 0.12303226027725996 + ], + [ + 0.83417560704215055, + 0.42771761436946582 + ], + [ + -0.72406631107421193, + 1.6492482353640665 + ], + [ + 2.5296769249474353, + -1.1944429926515672 + ], + [ + -1.3351024481102842, + 2.2501007625819249 + ], + [ + -1.7266120099747977, + -1.2066642818074598 + ], + [ + -0.65803886018625757, + -0.42458375854079838 + ], + [ + -1.4751932272875081, + 0.03627627608030197 + ], + [ + 0.50870519076321097, + -1.1041803060942859 + ], + [ + 2.3876324293900817, + -0.065491912365537905 + ], + [ + 0.46050388632359573, + -0.90306586825358603 + ], + [ + -1.3157209197658335, + -0.048096838642655057 + ], + [ + -0.47008421513190757, + 0.26771642480144492 + ], + [ + 0.58373521102510872, + -0.65413820068944328 + ], + [ + -0.89548301995423063, + -1.2534087588670748 + ], + [ + -1.8304030833253615, + -0.85349112885425837 + ], + [ + 0.40778211224941996, + -1.1891623150576829 + ], + [ + -1.5063201088328682, + -0.034693614602703704 + ], + [ + 0.077394827047095063, + -0.48079377456933525 + ], + [ + 1.8872348565628514, + -0.99100401556364426 + ], + [ + -0.57983754184705638, + -0.069222549088807261 + ], + [ + 0.63205639406195957, + 0.040974523293963346 + ], + [ + 0.69070940799810543, + -0.52952487183260122 + ], + [ + -2.0183416947523241, + -1.1738751914291645 + ], + [ + -0.23232863884416557, + 1.1253437050027864 + ], + [ + -0.33270088596271385, + 0.17169354028770778 + ], + [ + -1.7776536530548805, + -0.67581426204984585 + ], + [ + -0.18813186215523445, + -0.055577446545041619 + ], + [ + 0.80496678542421618, + 0.34579195436671761 + ], + [ + -0.31887618979112076, + -1.3471343588011564 + ], + [ + 0.46671827236945357, + 1.120698581857722 + ], + [ + -1.080246617945092, + -0.8367469372976718 + ], + [ + 1.8684702823371175, + -0.24514232476644246 + ], + [ + 0.63284900258848775, + -0.065054649027471823 + ], + [ + -0.0506976364495378, + -0.20743569170279827 + ], + [ + -2.1322566738075071, + 0.23179887530253848 + ], + [ + 1.1446042978333772, + 3.07776901701085 + ], + [ + 0.66843336391437047, + -1.0031320601347922 + ], + [ + 0.016509218339861579, + 4.0513080405612758 + ], + [ + 2.1004373648957362, + -0.44531771019951666 + ], + [ + 0.78075616290166516, + -0.32842613834560586 + ], + [ + 0.13016871926236007, + -0.048037283489279596 + ], + [ + 0.48696002404338373, + 0.11079036304780647 + ], + [ + -0.35852091006074049, + -0.62481725704504065 + ], + [ + -0.84856541980158517, + -0.18807486230713741 + ], + [ + -0.73713678884965439, + 0.20361340058431293 + ], + [ + -0.55901765955143923, + 1.3966559490697048 + ], + [ + 1.0245902185486961, + 0.57016475567687619 + ], + [ + 0.12439137474745653, + 0.57804562782782098 + ], + [ + 0.9227204032733437, + 1.7272179211285759 + ], + [ + 1.1129534258487503, + -0.62880004779541732 + ], + [ + -0.56260201865246617, + -0.77449635413316964 + ], + [ + 1.0695428278985164, + 0.24135785164700549 + ], + [ + 0.10511656252554125, + 0.22227012884682679 + ], + [ + 0.66899149347343356, + -0.74326663440881935 + ], + [ + 0.57594460914975154, + -1.0352070625914438 + ], + [ + 0.63140022559718145, + -0.47914365212599352 + ], + [ + -0.36175692574754931, + -1.1111035181890572 + ], + [ + 0.45918854118962094, + 0.90291757666583505 + ], + [ + 0.62797180607299585, + -1.0022068876321306 + ], + [ + -0.80998512772424813, + -1.0099204639373431 + ], + [ + -1.1525043094121921, + -1.2384537226113088 + ], + [ + 1.2171438489881916, + 0.11207717513910258 + ], + [ + 1.3166105228343228, + 1.7449027854895383 + ], + [ + 0.061434181754760481, + 0.68786128655135514 + ], + [ + -0.76594256403931316, + -0.49398561381701117 + ], + [ + 1.7362652563759693, + -0.17398681290053361 + ], + [ + -0.85423174450574246, + 0.27616823819484776 + ], + [ + -0.69683213650374265, + 2.3795666222152803 + ], + [ + 1.0615877681027768, + 0.18585301362333759 + ], + [ + 1.3241362247841066, + 0.40681190078073048 + ], + [ + -0.23617873940978798, + -0.9250586245365261 + ], + [ + 0.30614001089815185, + 1.8155252075806645 + ], + [ + 1.1447902753480921, + -0.35350137720339486 + ], + [ + 2.2193115033287838, + -0.12501181744103168 + ], + [ + -0.36161163527524959, + -0.83512028922215076 + ], + [ + 0.85769413844023845, + -0.5964211893654342 + ], + [ + 1.3263983911040482, + 1.4300922383927743 + ], + [ + -0.14044019719883249, + 4.0847224381413456 + ], + [ + -1.9164805785535866, + 0.26176065966185952 + ], + [ + -1.2205965197881774, + -0.448947175875897 + ], + [ + -0.95929931312859262, + -0.17727592645617476 + ], + [ + -1.8260296395509554, + 0.92890503993689955 + ], + [ + 0.31033945951677444, + 0.18070744806028158 + ], + [ + -0.46473371296099525, + 1.1221774850395263 + ], + [ + -0.43048835312942246, + -0.81807681983944036 + ], + [ + -0.084383655173623381, + -0.48378913724778372 + ], + [ + 0.32579630937407844, + 0.041551188262265462 + ], + [ + -1.2982712510279686, + -0.66307225202100273 + ], + [ + 0.4317412641500768, + 0.81972401222948443 + ], + [ + -0.37127360085483413, + 0.12639698660058676 + ], + [ + 0.69692819441339326, + -0.23773434981674194 + ], + [ + -0.0074801683471671983, + -0.20104741922358621 + ], + [ + -0.055147440662418543, + -0.43452629558626565 + ], + [ + 0.50478587778940565, + -0.84443531229231206 + ], + [ + 1.1307622274138558, + 1.5853231181599845 + ], + [ + 1.1959743113386254, + -1.0787095913829654 + ], + [ + 1.5696343300299844, + -1.1747629367630215 + ], + [ + 0.2816675394476203, + -0.40299502508143409 + ], + [ + 0.23151506141696973, + 1.8706673665136597 + ], + [ + 1.3883010472771509, + 0.32315693057847727 + ], + [ + -0.54460716881955906, + 1.5688309903376627 + ], + [ + -0.5317213266115034, + -1.0166494084974111 + ], + [ + -2.0984918740299756, + -1.26639178175762 + ], + [ + -0.18360212569648834, + 0.64294180715265281 + ], + [ + 0.10365598178725659, + -1.0318580774405659 + ], + [ + -1.1398433327839337, + 0.18709003014587619 + ], + [ + -1.1322231761991095, + 1.67457090495573 + ], + [ + -1.7083367159353426, + 0.5069947817121021 + ], + [ + 1.0463254795378605, + -1.0178800522694997 + ], + [ + 0.30177844720871189, + -0.82392407631122222 + ], + [ + 0.078450619741106495, + 0.12711093961029016 + ], + [ + -0.55829413029875252, + -0.62384473059007384 + ], + [ + 0.59651665633358031, + 1.8770321860630763 + ], + [ + -0.26008743438510146, + -0.2153572802037064 + ], + [ + -1.1571302038178415, + -0.85140591889631878 + ], + [ + 0.41586464912586862, + 0.74729441986402323 + ], + [ + 0.3216650292147652, + -0.37517562881151606 + ], + [ + -0.77576829238067124, + 0.71082302414057108 + ], + [ + 0.058716208065102686, + 2.4264876555529509 + ], + [ + -0.84656310622970665, + -1.2251104183368262 + ], + [ + -0.16957889600888504, + 0.96681336485228975 + ], + [ + 0.050541605216527223, + -0.35577652634348655 + ], + [ + -1.009633012791783, + 0.72972084650696534 + ], + [ + 1.200054936246054, + -0.027295846102759116 + ], + [ + -0.72131061371335781, + 0.70802097763500749 + ], + [ + 1.4073082403256783, + -1.25434998978715 + ], + [ + -0.11501738116978749, + 0.2196298777965433 + ], + [ + 0.3595481269433865, + 0.27339310794141219 + ], + [ + 0.22181458596256512, + -0.37092426441722048 + ], + [ + 1.2760796847578442, + -0.66892965265429238 + ], + [ + 1.0386951705787386, + -0.87921787432277365 + ], + [ + 0.083344673016501003, + -0.65103857425159406 + ], + [ + -0.77056961898768894, + -0.25119061428510997 + ], + [ + 0.89172439215447818, + 0.17177598214858897 + ], + [ + 0.32786004032878474, + 0.59506986307945897 + ], + [ + -0.99458966089482292, + -0.60404146551631377 + ], + [ + 1.0461491482098195, + 0.72839284850390229 + ], + [ + 0.77211642362359068, + -1.1358760767547065 + ], + [ + 0.081326524674480927, + -1.2828246803900651 + ], + [ + -1.4141726917342572, + -0.69867427938741933 + ], + [ + -0.77440081976785913, + 0.06239382341632374 + ], + [ + -1.0410523724932224, + 0.67458830133685688 + ], + [ + 0.24394134356542713, + 0.092916826582491299 + ], + [ + 2.3634735236775639, + -0.76932513088265531 + ], + [ + 1.3148937143981232, + 2.0174121198730335 + ], + [ + 0.86737832418597116, + -1.3603777328869375 + ], + [ + 1.0840866533936795, + 2.7711026162264334 + ], + [ + 0.06373545090123546, + -0.0064245026989267926 + ], + [ + -0.10431039177819733, + -0.96115766850677509 + ], + [ + -0.075881020247073355, + 0.88721386023077464 + ], + [ + -0.22821886483635412, + -0.38710836517487501 + ], + [ + 1.8841888052477882, + -0.59467269668651668 + ], + [ + 0.29220168615373221, + -0.76987412993647286 + ], + [ + 0.64610690923558822, + -0.64955376155301092 + ], + [ + -1.0682233585017915, + 0.80166151733259261 + ], + [ + -1.2612078796538013, + -0.75270538581342383 + ], + [ + 0.7095214533715094, + 2.3105040813806843 + ], + [ + 1.5039504086331914, + 0.14007868633098647 + ], + [ + 1.3380543118563046, + -0.25640617920655334 + ], + [ + 1.2226498482995041, + -0.00089506022554323343 + ], + [ + -0.019661793258092527, + 0.40803889265168197 + ], + [ + 1.2775920040208901, + -1.2684459286823662 + ], + [ + -1.2778071657107795, + -1.0910451912242203 + ], + [ + 0.34965871177150609, + -1.0474561550775634 + ], + [ + 1.1486569046524178, + -0.42994811484625634 + ], + [ + -0.21630698013390459, + -0.44211907762238783 + ], + [ + -0.00054254421756896507, + -1.0562998085229567 + ], + [ + -1.4188769921773732, + -0.47822218704892583 + ], + [ + 0.36247378978261835, + -0.23348653935813538 + ], + [ + -0.093595988606501104, + -0.4674922746157647 + ], + [ + -1.2656609064589821, + 1.0710325755653278 + ], + [ + -1.096220508616192, + 1.7252725039180747 + ], + [ + -0.19951263494514818, + -0.32560511284556964 + ], + [ + -0.069865506857691231, + 3.3161992083517862 + ], + [ + 1.036672989723346, + 1.2633752037288446 + ], + [ + 0.57974183950416758, + -0.81058177940404685 + ], + [ + -0.20550602420698749, + -0.27769559682023948 + ], + [ + -0.46830590405679301, + -1.0608242236545382 + ], + [ + -1.0762261852300323, + 0.81986017379618048 + ], + [ + 1.9930414263229996, + -0.39275358704938135 + ], + [ + -0.94519134206770239, + -0.49717907065587114 + ], + [ + 1.0906462992263881, + 0.0027652534656527313 + ], + [ + -0.89732334321138552, + -0.029523365664926301 + ], + [ + -1.7595987971855063, + 1.1660091550327485 + ], + [ + 1.8599759429718832, + -1.2467098752507697 + ], + [ + 0.38627242430293346, + -0.83747870753241516 + ], + [ + -0.34607289334662922, + 0.66524124525691342 + ], + [ + 0.45893279021302841, + 2.9886044421613684 + ], + [ + -1.6394844540621569, + 0.062834283414431494 + ], + [ + -2.2905629318242244, + -0.26131590863109183 + ], + [ + -0.15409076534397678, + 3.016934913739441 + ], + [ + -0.89856952257515821, + -0.66929507366412522 + ], + [ + 0.53674950878614414, + 0.45022328723557359 + ], + [ + 0.15118098017793752, + 0.93095453632969627 + ], + [ + 0.23378769094664395, + -0.042035731699233213 + ], + [ + 1.4674417789334102, + 4.7920913309784332 + ], + [ + -1.7825917409912677, + -0.85247406041774643 + ], + [ + -0.80722822241566372, + 2.25424255274091 + ], + [ + 1.3443094164774547, + 0.47684181963771854 + ], + [ + 0.04940316072602844, + -1.1013571616803501 + ], + [ + -2.0348243714058953, + 0.17559625427594222 + ], + [ + 0.88052985123750027, + -0.22012597378284263 + ], + [ + -1.3008893255035219, + -1.1355787104007635 + ], + [ + -0.02040288320632944, + 0.21177891591912584 + ], + [ + 1.2827834030433407, + -0.049807641636370734 + ], + [ + -0.89810292118688995, + -0.66900271872748496 + ], + [ + 1.7325879493282812, + 1.0308464004837354 + ], + [ + 1.0067103331422083, + 0.31910135122814298 + ], + [ + -0.44392001514028584, + -0.78190006108094479 + ], + [ + 0.22587195510668104, + -0.72953114730101143 + ], + [ + 0.74206087734895743, + 1.0912328226346859 + ], + [ + 0.097145008343504174, + 0.17543784754044761 + ], + [ + -0.18329917693049047, + -0.66370207312170615 + ], + [ + -1.0367329523445921, + 0.15718729907400572 + ], + [ + -0.75982010745273121, + 0.90027471200362641 + ], + [ + 0.74439980334784384, + -0.45490082139974258 + ], + [ + -0.29787008377543867, + -0.58428349891216835 + ], + [ + 0.43329429098381461, + -0.92500562378642448 + ], + [ + -1.4136935216029332, + -0.6051483145419323 + ], + [ + -0.062392624319586275, + -0.72888292718735304 + ], + [ + -0.7284226073267529, + -1.4090611416125385 + ], + [ + -0.38148482457464095, + -0.87818785432045721 + ], + [ + 0.5544247250305514, + -0.42170318155706582 + ], + [ + -0.4699083803584202, + -0.64791137955879086 + ], + [ + -1.1085309215766259, + 0.57018147921229867 + ], + [ + -1.4940346557637216, + -0.20027517085768176 + ], + [ + -0.030812521177231756, + 0.32410496747570144 + ], + [ + -0.82856950520380779, + 0.61932671793036964 + ], + [ + 2.0794758226811285, + -0.91223144753231289 + ], + [ + 0.58769733087590903, + 0.76768366455908299 + ], + [ + -0.085259128106072085, + -0.50065190675183102 + ], + [ + 0.3676126261279562, + -1.1399376911189127 + ], + [ + -0.46390793423409821, + -1.0327151617022614 + ], + [ + -0.53892159942564744, + -0.87126869290383413 + ], + [ + 0.91318971643561664, + 0.46923374564339271 + ], + [ + -1.259060502860178, + -0.71233592639689747 + ], + [ + 0.25535666869549545, + -0.17130602786113208 + ], + [ + -1.7182048579765581, + -0.4861211262382632 + ], + [ + 1.148696259249856, + -0.061672198789416169 + ], + [ + 0.46919210494501473, + 1.4717653497109209 + ], + [ + -0.11947921387279919, + 2.1702093129614832 + ], + [ + 1.269835281241769, + 0.04536870654057229 + ], + [ + 0.24526552002884472, + -0.26385028861922227 + ], + [ + -0.43964413776480354, + 0.21562246474285321 + ], + [ + -0.52785080228036119, + -1.2637280721668753 + ], + [ + -1.5420525983395876, + -0.35012342931878127 + ], + [ + 1.653279192170418, + -0.63465087131149278 + ], + [ + -0.42062684537668843, + -0.068081690792821753 + ], + [ + -0.83184620159220046, + 0.86143159737118802 + ], + [ + -1.7020690159867411, + 3.1194186765196639 + ], + [ + -1.106879180714013, + -1.2304074119069459 + ], + [ + -0.29489926007964634, + 1.0718234265019582 + ], + [ + 0.39280793617139204, + -1.0023891709216715 + ], + [ + 0.26451526784563567, + 1.048540002866303 + ], + [ + -1.6522504055194287, + 0.2950149551907737 + ], + [ + -1.2387236438636988, + -0.7929346478870406 + ], + [ + 0.55066217685413543, + -0.20317647284134285 + ], + [ + 2.6740559260418082, + 1.7347625255172812 + ], + [ + 1.4160450037908057, + -0.36694221900205815 + ], + [ + 0.83052792119356356, + -0.1673232160557562 + ], + [ + -0.27023299143369245, + 0.062958840172052374 + ], + [ + -1.7417166110181892, + -1.1320939435595274 + ], + [ + 1.1442951880720658, + -1.0398573884126241 + ], + [ + -0.22463424366598642, + 0.70312868578524479 + ], + [ + 1.3450007232012335, + 0.16750227047793401 + ], + [ + 0.24078620013191107, + -0.47070799902892879 + ], + [ + -2.3664436483846769, + -0.39540330921270317 + ], + [ + 0.77235177321267912, + 1.693275523084059 + ], + [ + 1.6496490948634868, + 0.89634275890721227 + ], + [ + -1.8994487253664945, + -1.2288824133662326 + ], + [ + -0.24560605830569862, + 3.2743797152863117 + ], + [ + -1.2599205198505798, + 0.89143679809129872 + ], + [ + -0.15612778603254088, + 0.10401744461807529 + ], + [ + 0.59442624332418603, + 1.3891710708076974 + ], + [ + 0.40841416640963429, + -0.80808870987488868 + ], + [ + -0.65992023098670083, + -0.069518262047872453 + ], + [ + 0.13618945021488899, + -0.68712626886700301 + ], + [ + -0.95140752991998789, + 0.16339088575613187 + ], + [ + -0.96073969777784773, + -1.1262363370236042 + ], + [ + 0.29470868105739795, + 1.9152879866969408 + ], + [ + 0.62083937704722714, + 0.63585980200661252 + ], + [ + 0.36683291040766353, + -0.03469039768447383 + ], + [ + -1.349464664534628, + -0.94702658578263466 + ], + [ + -0.25679884730621289, + 1.2254657698059013 + ], + [ + -0.18003360913046398, + -0.45868362965832615 + ], + [ + -1.7351253395854325, + -0.43779615941407313 + ], + [ + -0.35706001537260618, + -1.2371884418096708 + ], + [ + 1.1199504313233037, + -0.45844399118471812 + ], + [ + -0.60635508813620975, + 2.1155620377282363 + ], + [ + -1.531351146992882, + -0.6370202185222541 + ], + [ + -1.1730683580361221, + -0.56933803746889389 + ], + [ + 0.87282813056700514, + 0.66051601828226036 + ], + [ + 0.63427541304832358, + -0.29840789589526534 + ], + [ + 0.41921213408448832, + -0.64064590438346625 + ], + [ + -0.55152371664973909, + 0.59531335560615706 + ], + [ + 0.40587513739332126, + 0.5251911697063737 + ], + [ + 0.27342225316800395, + -0.70194674286044823 + ], + [ + 0.44571139722156911, + 0.034439406957182263 + ], + [ + -1.0584077971392292, + 1.6173172291684141 + ], + [ + -0.652685443749627, + -0.9651623447399601 + ], + [ + -2.0306867493968777, + 0.32984619145604022 + ], + [ + -1.5575857018971058, + 1.3410793174275275 + ], + [ + 0.41847193743296374, + 1.9562859611789249 + ], + [ + 0.02799674758998226, + 0.43777611357044477 + ], + [ + -1.4007213418350453, + -0.77040995977134552 + ], + [ + 0.46608038439296007, + -0.79489825138451742 + ], + [ + 0.18622769520271207, + 0.082029552696723324 + ], + [ + 0.20561471046884777, + -0.52594286334315954 + ], + [ + 0.28354076706057418, + 0.60903805604741834 + ], + [ + 0.34031968648652694, + 0.51684052251500123 + ], + [ + 0.79723432417027673, + 0.65255145459067321 + ], + [ + -0.32807577186950271, + 0.58493767041583355 + ], + [ + -1.3494872861816536, + -1.1733874079592674 + ], + [ + -0.61952990931183693, + 0.4737208039314299 + ], + [ + -0.38427429113315603, + -0.60776861847695429 + ], + [ + -0.75462049958834543, + -0.19264075451232762 + ], + [ + -0.85326764518070963, + -0.97876039091088207 + ], + [ + 0.66911275074137844, + -0.6199656271307652 + ], + [ + -0.015604410980802454, + -0.88599186597239921 + ], + [ + 0.39553952513365331, + 0.20832923129660177 + ], + [ + -1.5287075713183713, + 1.2066634030934982 + ], + [ + 0.27517842324312253, + 0.02725865892610646 + ], + [ + 0.46270733961663657, + -0.90072028555045003 + ], + [ + -1.726005346418569, + -0.95555176330199509 + ], + [ + -1.5458390942286737, + -0.27537853242350641 + ], + [ + 0.18509197783479991, + -0.12306335963542384 + ], + [ + -0.032075769686101326, + -0.032126769435998348 + ], + [ + 1.16460965855905, + -0.71891786802006719 + ], + [ + -0.73633625933156521, + 0.34696049389242883 + ], + [ + 0.85066518577317318, + -0.7009027705190749 + ], + [ + 0.41042088606399463, + -0.96693029540255904 + ], + [ + 0.29624392272240158, + 0.14339724465325043 + ], + [ + 0.69186415774720622, + 1.9639597199176677 + ], + [ + 0.21411099824136356, + 0.53487432108907329 + ], + [ + -0.74953226714111221, + -0.62801052268158952 + ], + [ + 0.12183895289908145, + -1.1436483076905128 + ], + [ + 0.38965211308850173, + -0.66570941522884342 + ], + [ + 0.079487471487274794, + -1.0379010130716657 + ], + [ + 1.7274002792905663, + 0.92482159614853987 + ], + [ + -0.31662903285267152, + -0.68054430314990932 + ], + [ + 1.5609748542203803, + -0.81633076572424534 + ], + [ + 0.54545298375430407, + -1.2270792724307749 + ], + [ + 1.4587899217164493, + -1.1727095877961453 + ], + [ + -0.42300707104670537, + -0.86380502683328775 + ], + [ + 1.0971522642048472, + 0.50152846593946587 + ], + [ + 1.1352721348899601, + -0.40392951682898776 + ], + [ + 0.56737877129407122, + 0.47235379506935998 + ], + [ + 0.74922822615053508, + -0.4824069093053247 + ], + [ + 1.7918142140843081, + 0.070172397555055555 + ], + [ + -0.75762853804939212, + -1.1328532830669313 + ], + [ + -0.42304339441158395, + -0.46008195146630343 + ], + [ + -1.341201412662226, + -0.24979894876135578 + ], + [ + 0.54395278221441357, + 0.82369301792408267 + ], + [ + -1.4392952255672031, + -0.029086134551374317 + ], + [ + -0.0085933388170272903, + -0.92969254382684019 + ], + [ + -0.25070191774215328, + -0.1857877906151362 + ], + [ + -0.12451801311022484, + 1.9151591741476923 + ], + [ + -0.51572237686215694, + -0.42993558459150322 + ], + [ + -0.074692260643293276, + -0.27874860649762578 + ], + [ + 1.1673482454716386, + -0.68465941425614818 + ], + [ + -0.048746758052004312, + -0.80264234873090934 + ], + [ + -0.10766013162620562, + -1.2507886571224582 + ], + [ + -1.3624148671079765, + -0.82452015069772122 + ], + [ + 1.4738360532854535, + -0.36397217114893543 + ], + [ + -1.8028738101377959, + 0.54243132357497981 + ], + [ + -0.78381224036880504, + -0.74887855338110187 + ], + [ + -1.2176441005354581, + 1.6771386140428375 + ], + [ + 0.6506109977469301, + 0.41833590708362844 + ], + [ + 0.17475206016906358, + 0.017363105379250007 + ], + [ + 0.51982753596126774, + -0.19798956433791148 + ], + [ + -0.12232958664217702, + 0.045182736636573059 + ], + [ + -0.83489081328543557, + -0.75218916188954676 + ], + [ + -0.18125780910074607, + 0.54121802910019712 + ], + [ + -1.8594144213748516, + -0.4495708687690298 + ], + [ + 0.40959628285355376, + 4.1456707132810928 + ], + [ + 1.9621575184866216, + -0.52403581776960373 + ], + [ + 1.2021682219360754, + -0.788722959367956 + ], + [ + -0.48072327933240816, + -0.54036933556712641 + ], + [ + 0.68719767358707917, + -1.1162574593847145 + ], + [ + 0.011389857062708302, + -0.51484595162882218 + ], + [ + -0.11501274776326752, + -0.84392062425267178 + ], + [ + 1.7275566226455863, + -1.0147637845280002 + ], + [ + 0.54826118472461072, + -1.0704029838446221 + ], + [ + -0.11550868973492655, + 0.58752568327945864 + ], + [ + 0.21852595981093942, + -0.49393607974925952 + ], + [ + -0.57929661052350923, + 0.066773443167881974 + ], + [ + -0.90028869183995475, + 0.28764731977488822 + ], + [ + 0.47927410861717595, + 0.56838728600388699 + ], + [ + -0.82294813674700629, + 4.6466063441023353 + ], + [ + -1.2780121876531243, + -0.22471318131939297 + ], + [ + 0.54628127848944508, + -0.83909839132931074 + ], + [ + -0.0510633719910547, + 0.38838776536813469 + ], + [ + -0.22704067371550618, + -0.34975846878104477 + ], + [ + 1.7632088390120277, + -0.9404994954230409 + ], + [ + 1.3797657810704411, + 1.0245191873750374 + ], + [ + 0.28626696463026502, + -0.12828060800589741 + ], + [ + -1.6657921823477875, + 0.88088849458582796 + ], + [ + 0.84032960550909452, + 0.12093766108149392 + ], + [ + -1.3057899369654606, + 0.47902269005622511 + ], + [ + -2.4328490217302732, + -0.036277429764608751 + ], + [ + -0.87196582882682572, + 1.0090558296192642 + ], + [ + -1.1761334494997122, + -0.61601977218276005 + ], + [ + -1.358613540648512, + -0.94793374369000261 + ], + [ + 0.045373829071832232, + 0.56640136925671558 + ], + [ + -0.42459517712832884, + -1.2190447445159518 + ], + [ + -0.50032211586188824, + -0.75518245639041048 + ], + [ + -1.4380576058005687, + 0.32336710128982038 + ], + [ + 0.019201698308925787, + -0.46510748744097208 + ], + [ + 0.52375465899271045, + 0.53199294398310726 + ], + [ + -0.10585351689837114, + 1.1360857165080338 + ], + [ + 0.20769312136434381, + -1.2631490960567631 + ], + [ + 0.33024109192373124, + -0.96770527482189517 + ], + [ + 1.2879830145819355, + 0.01188577066183695 + ], + [ + 0.40660876720700628, + 1.1626303036858234 + ], + [ + 1.0069891932531609, + -0.5963466662921062 + ], + [ + -0.58254235421261291, + -0.95069153975843068 + ], + [ + -1.1245968351435438, + 4.3538894592881956 + ], + [ + -0.98328965864717599, + -1.1194180737253812 + ], + [ + 2.5382357183001063, + -1.0326306155893687 + ], + [ + 0.89783454156886211, + -0.60779235467941239 + ], + [ + 1.5925657628516241, + 0.085009208669705391 + ], + [ + 0.20024668177255719, + 0.011712822835025016 + ], + [ + 0.75146729862466544, + -0.45870818100448102 + ], + [ + -1.0500141999557266, + 2.4728390505874827 + ], + [ + -1.8717659027054936, + -0.39880888585104957 + ], + [ + 1.2376418785315864, + -0.47739366232602076 + ], + [ + 1.4942631026508342, + -0.75481123524698912 + ], + [ + 2.5102280957182783, + 0.72793991787782786 + ], + [ + 0.53288293072720083, + 0.20623214193948269 + ], + [ + -0.79816913350711716, + -0.73900914919297922 + ], + [ + -2.0633810050985404, + -0.94545314767168642 + ], + [ + 0.57919986938124213, + -0.92589241249779275 + ], + [ + -0.38192737016004136, + 3.7891140209449223 + ], + [ + 0.21130950316818473, + 0.16579263570172084 + ], + [ + 0.28266686310556949, + -0.59018341030184629 + ], + [ + -0.13942126205280719, + -0.98796519444759601 + ], + [ + 1.636145353314252, + 1.8545033419780752 + ], + [ + -0.12522341090194475, + -0.82812532599695032 + ], + [ + -0.59599893612523658, + -0.77903138160648555 + ], + [ + 0.50272236526258751, + -0.30134619696588133 + ], + [ + 1.4199734531250037, + -0.70618421105847451 + ], + [ + -0.73504063134721376, + 1.4124192967373226 + ], + [ + -0.8119478858550162, + 0.74759609496403756 + ], + [ + -0.3473364110100215, + -0.95306155291366257 + ], + [ + -0.88910690842249596, + -0.70499869514138525 + ], + [ + 0.80964251598120973, + 1.5463286400315523 + ], + [ + -0.1211433108823691, + -0.36563019271101216 + ], + [ + 1.1554528543662683, + -1.0820594437219524 + ], + [ + -1.8713750030423453, + 0.79898701073748957 + ], + [ + -1.5296515565485764, + -0.88462133233614837 + ], + [ + 0.38277639649608219, + -1.1824547411518469 + ], + [ + 0.5361019008125939, + -0.34378500246050003 + ], + [ + 0.9517023407702293, + 1.8796807669032525 + ], + [ + 0.47302939537601069, + 2.3425442506906946 + ], + [ + 1.6298990041572958, + -0.45129070296195717 + ], + [ + 2.0925367846229994, + 0.097634338946067462 + ], + [ + -1.394493186164445, + -0.30132678468006596 + ], + [ + 0.94419939947001974, + -0.20268034555279746 + ], + [ + 0.75237526324177129, + 0.1778709913540793 + ], + [ + -0.25569422891502258, + 0.88925480388259381 + ], + [ + 0.15386534907970928, + -1.1866915737743247 + ], + [ + 0.20961068690539456, + -0.95841980028906659 + ], + [ + 0.54576996065133787, + 2.8801671050878843 + ], + [ + 0.43779294917430794, + -1.0900305552815579 + ], + [ + -0.32761632897744636, + -0.17000792756682262 + ], + [ + -0.22734302280355356, + -0.055476587751778994 + ], + [ + 0.10760164169310379, + -0.58748077261779452 + ], + [ + 0.96583728328833063, + -1.3094992371810341 + ], + [ + 0.11954098633552884, + 0.083367147974049885 + ], + [ + 1.4757692546733225, + -1.0870906477352322 + ], + [ + -0.34541790870196204, + 2.0913918799016975 + ], + [ + -0.1260239230425598, + 1.4016232858653983 + ], + [ + 1.7904950058643005, + -0.53031182912575558 + ], + [ + 1.660285443836562, + 0.2833543708378074 + ], + [ + 1.9017469895337311, + 0.80892814658533974 + ], + [ + 1.124579632287692, + -0.56663096957413961 + ], + [ + 1.7212486956635624, + -1.2381004979014529 + ], + [ + 0.62478491579924778, + 0.23783318352958024 + ], + [ + 0.49189298828058076, + -1.2330370707888052 + ], + [ + 1.9931287992340192, + -0.059979595583994259 + ], + [ + 0.36664679801616601, + -0.30771617680569069 + ], + [ + 1.1083772541412531, + 0.647529078300634 + ], + [ + -0.17691935957471988, + -0.4706379665715078 + ], + [ + -0.71267149462758372, + 1.2438341715907075 + ], + [ + 1.3389082614383827, + -0.94915376741204183 + ], + [ + 0.29225141418512479, + -0.52338626570308244 + ], + [ + -0.53815426035102931, + -0.15269427788279644 + ], + [ + 0.28854856657024269, + -1.3503957024281525 + ], + [ + -0.73060434596328483, + -1.359946477552604 + ], + [ + -1.2727760861674593, + -0.49443687084427146 + ], + [ + -1.2384458790452693, + 1.3902779053717105 + ], + [ + -1.7564962105191564, + 1.3025181280068165 + ], + [ + 0.22232248014063899, + -0.70665073096594799 + ], + [ + -0.25684907557010789, + 0.28947727192854761 + ], + [ + 0.043617308126989975, + -1.2860290810753976 + ], + [ + -0.42557672511354017, + -0.48372930975825923 + ], + [ + -0.72080097088613215, + -1.1698178562908885 + ], + [ + 0.097126424664030861, + -0.68623841632929716 + ], + [ + 0.23225539403210607, + 1.0140301861987588 + ], + [ + 1.0152111317360764, + -0.62016126087918744 + ], + [ + 2.2167300898119469, + -1.0740235033879098 + ], + [ + -1.1348562725076465, + -0.0069826846631364592 + ], + [ + -0.33924641415238033, + -0.45958009061818333 + ], + [ + -1.0386540111874181, + -0.69229111812892896 + ], + [ + 1.1756705657876212, + 1.4949805878225575 + ], + [ + 0.83063535302500424, + -0.37773338179620275 + ], + [ + -1.2448058032510216, + -0.80877711956450871 + ], + [ + -0.61590466933836119, + -0.26193910801104481 + ], + [ + -0.94488156665926815, + -1.0537196332522067 + ], + [ + -0.034467871362708159, + 0.68376052557549172 + ], + [ + -1.5127760557399601, + 0.43957282065309777 + ], + [ + 1.1691522613172272, + 0.50861477507093911 + ], + [ + 0.60938391086495125, + -0.93783287247472069 + ], + [ + -0.40813651330022882, + 0.39468916819133826 + ], + [ + -0.84227786158550411, + 0.77221336875655211 + ], + [ + 0.41786082652127216, + 0.57578434788309096 + ], + [ + -1.9914819206780536, + 0.32145154398358616 + ], + [ + 0.14193034961544485, + 0.75674419421318273 + ], + [ + 0.36055227546109297, + -0.071390379829925132 + ], + [ + -0.7486821772000436, + 0.26076827498704536 + ], + [ + 0.36571449413285434, + 0.17504191755399423 + ], + [ + 2.3753737049877106, + -0.7825380019361563 + ], + [ + -0.20745047304345732, + -0.13160253269707417 + ], + [ + -0.54265382067515477, + 0.49748233411890153 + ], + [ + -0.89393672300573401, + 0.90236526460043354 + ], + [ + -0.36211088839710115, + -0.93824957616873039 + ], + [ + 0.22210686009206693, + -0.96129111264611866 + ], + [ + 0.58579519784270839, + 0.012843456355346021 + ], + [ + -2.1176662495736061, + 1.7976600124872024 + ], + [ + -0.67547569598293533, + 0.1690373674303918 + ], + [ + -0.096371081452420168, + 2.4494056887504749 + ], + [ + 0.069523894856745372, + 0.0048751427693802989 + ], + [ + 1.8571108549481392, + 0.55258518107743027 + ], + [ + -0.73617334154081371, + 1.6932388395480167 + ], + [ + 2.2437022294470532, + -0.02429134849515744 + ], + [ + -0.34508763659263647, + 0.45805308990323573 + ], + [ + -0.21053979409550394, + 0.077017483150054925 + ], + [ + 0.35553625439878067, + 0.32240430586329161 + ], + [ + -1.0100972582895185, + 1.5761029959993684 + ], + [ + 0.32482232737837385, + -0.54719101530289838 + ], + [ + 0.93168797216438703, + 0.5367040575788059 + ], + [ + 2.0443649368490071, + -0.5704790743313547 + ], + [ + 0.34096756622234475, + -1.2311450138468414 + ], + [ + 0.72502121566972044, + -0.85933928851056485 + ], + [ + -0.86523734468134961, + 0.99311604704004774 + ], + [ + 0.027404874066695985, + -0.33679071004271804 + ], + [ + 0.34142831684047442, + -0.10462391360456712 + ], + [ + -1.6323894609044642, + -1.126519534747745 + ], + [ + -1.4166970150102369, + 1.5608591320178149 + ], + [ + -0.40292802701007346, + 1.6025598103584273 + ], + [ + -0.064235998514311429, + 1.2899025502190546 + ], + [ + 0.26980893500490571, + -0.59411837978649029 + ], + [ + -0.5714575789324523, + 0.45104108058990461 + ], + [ + -1.072796028944871, + 0.49031873666064468 + ], + [ + 0.44047812236340272, + -0.88075222583011614 + ], + [ + 0.41084573880331809, + 0.37589408451227485 + ], + [ + 0.02899537567105712, + 0.29896270603125324 + ], + [ + 2.4381879725243132, + 1.7023322560462719 + ], + [ + -0.27125101758973508, + -0.46977034332266238 + ], + [ + -1.5056319976340771, + 0.50119444333541074 + ], + [ + 0.85422399680930994, + 0.27015774983778235 + ], + [ + 0.040075672643251813, + -0.92170722847878828 + ], + [ + 0.1198867291146198, + 2.4995869502757477 + ], + [ + -0.060843581762378508, + -0.96580589049308119 + ], + [ + 1.5358063196438907, + 0.5288598992907384 + ], + [ + 1.1784331299918469, + -0.63346184506085634 + ], + [ + 0.76824849736613987, + -0.0053144629474307032 + ], + [ + -0.11895631513444653, + 3.1884126764722773 + ], + [ + -0.52292595218697979, + -0.43524690616268935 + ], + [ + 0.12560013382204827, + 0.095316465906865669 + ], + [ + -0.076722846112039736, + 1.7109752143923243 + ], + [ + -1.3334385135296953, + 1.8660662388089109 + ], + [ + -0.21038865799719841, + -0.6468267728799727 + ], + [ + 0.41240575883415659, + -0.9915615701390833 + ], + [ + -0.67825456864330891, + 0.19441339016097092 + ], + [ + -0.056315406877964061, + -0.87536196758787232 + ], + [ + -0.8474948260714309, + -0.95549644270944356 + ], + [ + -0.94922495517050731, + 0.51412367393698433 + ], + [ + -0.24746936952909221, + 0.49766964699672561 + ], + [ + 0.97176325964357335, + 0.82651937664031683 + ], + [ + -0.99662467300273272, + -0.5474319846077973 + ], + [ + -0.20219609934375582, + -0.82796484579756546 + ], + [ + -1.0616268687530708, + -0.64016341131933951 + ], + [ + -0.24519690628273447, + 0.082838309699840712 + ], + [ + 0.78799794019478442, + 0.34019358152402951 + ], + [ + -1.400273862117341, + -0.57824520484389574 + ], + [ + -0.35008206760806126, + 0.40733168840864331 + ], + [ + -0.75138966559921294, + 1.4984658339154302 + ], + [ + 0.31624660159923484, + 0.85729913020520554 + ], + [ + -0.16901854230557731, + 1.4208622572687577 + ], + [ + -0.54866990336051846, + 0.60294565184496318 + ], + [ + 1.0295030783080428, + -0.35565790120229374 + ], + [ + -0.92545040275499812, + 0.79646786148460602 + ], + [ + 0.71578759714167273, + 0.34100064000512015 + ], + [ + 0.79417504154819207, + -0.13549382942264418 + ], + [ + -0.83285015419595942, + -1.1754681966204763 + ], + [ + 0.1277484744374752, + 0.70661991624300602 + ], + [ + -0.76210942950431559, + -1.0348976894493329 + ], + [ + 0.36985945845849405, + 0.45832415120606229 + ], + [ + 0.23037730199281453, + 1.5238655434236037 + ], + [ + -0.68873681967107558, + 0.23814309296902078 + ], + [ + 0.37895817722752401, + 0.86652545420350391 + ], + [ + -0.61452623121665328, + -0.83037697317432824 + ], + [ + -0.46759728485064272, + 3.0779222875125645 + ], + [ + 0.64297139999814568, + 0.32201013655908711 + ], + [ + 1.0499981428972764, + -0.4118948694303316 + ], + [ + 0.37991663175634144, + -0.38958009759662471 + ], + [ + -0.19051001427641906, + -0.32826026839237787 + ], + [ + -0.31957046500313896, + 1.9209574779212009 + ], + [ + -0.30278778776381277, + -0.42585929911560072 + ], + [ + -0.45862726512799457, + 1.4327051725463991 + ], + [ + -0.32123823837179416, + -0.7419694173105339 + ], + [ + -1.7314550767820003, + -0.43533629426662862 + ], + [ + 0.056283975698490071, + -0.80229526379454941 + ], + [ + -1.5488596476896033, + -0.20125070946410911 + ], + [ + -0.82676619717450306, + 0.86545714563440779 + ], + [ + -0.12990042764278903, + 0.74997607615010575 + ], + [ + 1.1544347030155846, + -0.80884470255449403 + ], + [ + 1.3897230514084447, + -0.05278022368339888 + ], + [ + 1.8101676732330501, + 1.2183786621122199 + ], + [ + -0.5293056693862318, + -0.58492421036694753 + ], + [ + 1.6260810309559155, + 3.3839331002649078 + ], + [ + -0.37035580433641124, + -0.88712847888409208 + ], + [ + 0.78685862487249358, + -0.85407236980951606 + ], + [ + -0.11235748644835822, + -0.43112880723590274 + ], + [ + 1.429094304511533, + -1.0805303046113981 + ], + [ + -1.7198178874445791, + -1.0515469229380745 + ], + [ + -0.76624214733263951, + -0.94055896405732242 + ], + [ + 1.4090479042505855, + -0.91689414157344595 + ], + [ + -0.91028803829609306, + 1.2612860663067751 + ], + [ + -1.0713796339794823, + -0.77529384562251946 + ], + [ + -1.1387924505618983, + 0.32661090706962498 + ], + [ + -0.6152830101846094, + -0.50972086664259841 + ], + [ + 1.0475953587461406, + -0.44925336066120702 + ], + [ + 0.43402925099450851, + 0.38522891519471469 + ], + [ + 2.2470752558728995, + -0.62609459047164917 + ], + [ + -0.60003097998206101, + -0.92645100806009617 + ], + [ + 0.35687256611987583, + 0.58996758239104496 + ], + [ + 0.41432556235482465, + -0.4292673967979872 + ], + [ + -1.5976920319636894, + 1.2320921580136515 + ], + [ + -1.381832418435387, + -0.38892505732745003 + ], + [ + -1.3850374970241497, + 0.51862834951326775 + ], + [ + -0.40923845361663136, + -0.73201421580043269 + ], + [ + -0.21895674129703099, + 1.1985162340415438 + ], + [ + -0.90918161003378428, + -0.2939347321358366 + ], + [ + -0.11062737843749168, + -0.77597234402056081 + ], + [ + 1.8092017231896984, + -0.41882426700232056 + ], + [ + -1.0220492345870229, + 0.74518306933503653 + ], + [ + -0.051658857921433682, + -1.0134056521077515 + ], + [ + -1.0990361036858254, + -0.96446624581242957 + ], + [ + -1.0137399509944411, + 2.5793782725031162 + ], + [ + -1.2230593390166693, + -0.3916488667974925 + ], + [ + -1.1412329150073897, + 0.87394813238953439 + ], + [ + -0.29899524236977426, + -1.1459972601245485 + ], + [ + -0.53602371178692387, + -0.58077343385764224 + ], + [ + -0.30302194525961973, + -0.73516913571807763 + ], + [ + 0.37947536491117068, + -0.45721238036532774 + ], + [ + -0.41525569328088741, + -0.58695734222633 + ], + [ + 0.17901638602669953, + 0.27645840648384762 + ], + [ + -0.45433552771271279, + 1.3821245813627188 + ], + [ + -0.78352015989380508, + -0.57911006437652457 + ], + [ + -1.1685097535494646, + -0.48976060131476051 + ], + [ + -0.23219271396864891, + 0.66714978236381406 + ], + [ + -0.34606951337702724, + -0.28593700727711252 + ], + [ + 1.7856086258179171, + -0.0089694636979336991 + ], + [ + 0.68455371873593496, + -0.46693997631585843 + ], + [ + 0.49438092426553903, + -0.45216111819910049 + ], + [ + -0.80637273715923641, + -1.4007336951201212 + ], + [ + -1.1661731478932367, + -1.2233150115157199 + ], + [ + -0.93500127247118203, + 1.0409690949494512 + ], + [ + -0.30512241824863906, + 0.73532122916177067 + ], + [ + -0.59839576795447702, + -0.19112523803812698 + ], + [ + 1.3020017240136244, + -0.51278957542459624 + ], + [ + 0.17591170485113131, + 0.45338320577774116 + ], + [ + 0.20973442788065649, + -0.81371994942729542 + ], + [ + 0.43379913382290991, + -0.30231742959720276 + ], + [ + -0.93970980990469166, + -0.025987209112253568 + ], + [ + -1.1875665815956753, + -0.38066421888239582 + ], + [ + 0.43403995933553041, + -0.51248565562300419 + ], + [ + 0.25996537419014454, + -0.49599530457327512 + ], + [ + -0.00081995101648347102, + -0.64029131265401096 + ], + [ + -1.2073456605651858, + -0.18498452423770223 + ], + [ + 0.65138475950055297, + -0.9270612184712651 + ], + [ + -2.469590206466366, + -1.2188027838992124 + ], + [ + 0.49645525921707501, + 0.28135873077246054 + ], + [ + 0.22310932460834471, + -0.64348478972473944 + ], + [ + 0.51604303414572983, + -1.2221615215556112 + ], + [ + 0.23772043353427724, + 1.3287552752618657 + ], + [ + 2.7152528174695734, + -0.15100212800471838 + ], + [ + 0.15178158009275267, + -0.24537494323872699 + ], + [ + 0.097685183714898108, + -0.055752432912720661 + ], + [ + 0.45740441095843426, + 0.62665547317068293 + ], + [ + -0.61638162286099285, + 1.0455925649519933 + ], + [ + 0.56580382906466498, + 1.9277618048040581 + ], + [ + 0.39616136787117634, + -1.2978397931467791 + ], + [ + -0.27828968610826205, + 0.051521126931848141 + ], + [ + -0.37206461213409253, + -0.10700939840845389 + ], + [ + -0.47717689854213896, + -0.48175377050797863 + ], + [ + 0.086916845444621554, + -0.76314838319567579 + ], + [ + 0.63304929218941786, + -0.65397754023077215 + ], + [ + -0.42024847941317484, + -0.4846434253922729 + ], + [ + 0.69217759667108292, + 0.56326035189570156 + ], + [ + -0.80431044620547343, + -0.7443293506898655 + ], + [ + -0.7307150380719073, + -0.70127964851282865 + ], + [ + -1.4769163586315339, + -0.34070108366356211 + ], + [ + 2.5608129024825779, + -0.69687102019295488 + ], + [ + 2.6066317092745503, + 1.1755956622843371 + ], + [ + -0.72527060672351373, + -0.73679493294022691 + ], + [ + -0.32661408007727744, + -1.2223708241625497 + ], + [ + -0.48055445412039888, + 0.21946462052807153 + ], + [ + -0.57470643044992231, + 0.72271425239237408 + ], + [ + -1.7419972533490153, + 0.0201359289185193 + ], + [ + 0.32022324201780772, + -0.64187952277812754 + ], + [ + -1.0608263737074271, + 0.70579408401938704 + ], + [ + -0.25936228872365658, + -1.0981310136991134 + ], + [ + 1.4852368239336982, + -1.0256228695579712 + ], + [ + -1.1445370194442355, + -0.017858521651390433 + ], + [ + 1.2588973316983996, + -0.90716142388893717 + ], + [ + -0.57812505431399919, + -1.1587819180742105 + ], + [ + 0.94919138297041528, + -0.39561413936620432 + ], + [ + 0.68879177485099508, + -0.9796118758675163 + ], + [ + -1.1215305942888565, + 1.2407480306766532 + ], + [ + -0.11414266067329142, + -0.1838334202778617 + ], + [ + 1.3305159004159859, + -0.70905242193912832 + ], + [ + 0.25479943289360568, + -0.16812772935319192 + ], + [ + -0.62385523336936788, + -0.76684440092925066 + ], + [ + -0.39415553351032995, + -0.92884974890744432 + ], + [ + -1.7270053259709028, + 0.060222182250420177 + ], + [ + 0.15598888873213934, + 0.84223257730056711 + ], + [ + 0.50545901504650892, + -0.81519232381659956 + ], + [ + -0.34125024189926206, + -0.70467513091452028 + ], + [ + 1.9843728888124075, + 0.52968110592402351 + ], + [ + -0.080643101689739496, + 2.2168396795209611 + ], + [ + -0.95739330917728305, + -0.9703890321870392 + ], + [ + 0.50832529424896156, + -0.24355797628438755 + ], + [ + 1.1932815357952666, + -0.27833129056538691 + ], + [ + 0.78552416660124491, + -0.54724040130057949 + ], + [ + 1.3744535990903839, + -0.44738456564148077 + ], + [ + -0.31221492024917996, + 0.61442675801638569 + ], + [ + -1.227995405821138, + 0.086405967764408884 + ], + [ + 0.4572897192776082, + -1.020754747001404 + ], + [ + 1.0865279526442122, + 0.36697892718447234 + ], + [ + -0.3574708614182075, + -0.92940006304693823 + ], + [ + -0.53701845451920094, + 0.49415276859287988 + ], + [ + -0.072738925343856356, + -0.63496797359015655 + ], + [ + 0.70158307105352158, + -0.79258839526711145 + ], + [ + -0.43187664450344715, + 1.0416250134304654 + ], + [ + -0.91158916566312131, + 0.27014241164222269 + ], + [ + 1.9035810583850181, + -1.0757251717567651 + ], + [ + 1.6568495254864082, + 3.4003730331927549 + ], + [ + -0.33475306638736591, + -0.63782126414193796 + ], + [ + 0.70166090637479928, + 2.1508391416191679 + ], + [ + 0.75947690907833276, + 1.7410542902049924 + ], + [ + -1.3713212363943286, + 1.1839584299253301 + ], + [ + -0.18267161442293209, + 1.560613791288449 + ], + [ + 0.72894340755077935, + -0.78823319563095762 + ], + [ + 0.39861705393701607, + 1.6761946087646589 + ], + [ + -1.0447890476824329, + -0.94984483654838869 + ], + [ + -0.92516509280340131, + 0.5751488557790756 + ], + [ + -0.77536882903877247, + 0.70699343900209355 + ], + [ + -0.29534372393334407, + -0.018146183414483003 + ], + [ + -1.3294394769029612, + -0.81995323789358976 + ], + [ + -0.42511256794529595, + -0.47433156351473171 + ], + [ + -0.45569146372950686, + 1.2192100168809292 + ], + [ + -0.1658737941930748, + 0.37814973666150298 + ], + [ + 1.0774403319510983, + -0.29298616457832438 + ], + [ + 0.32335459001658295, + 0.27597020499898556 + ], + [ + -0.7380306705450066, + 0.63553483345944406 + ], + [ + -0.13417764779342811, + 0.14409994558849756 + ], + [ + 0.97530095917266968, + -0.74012476843708352 + ], + [ + -1.7490213228935065, + 1.0841141846076847 + ], + [ + 1.7430247722768664, + -0.84871510532589645 + ], + [ + -0.17649711268543405, + -0.83085857447928968 + ], + [ + -0.73371351106393778, + -1.1471309547736939 + ], + [ + 0.61949512085543523, + -1.0710560560171998 + ], + [ + -1.0216998404311013, + -0.6655290437341761 + ], + [ + -0.87063590749529562, + 0.99672256367844103 + ], + [ + 1.8593419885099842, + -0.3670718513634264 + ], + [ + -1.6911944474763698, + -0.06020089218561353 + ], + [ + 1.2590429980897362, + -0.17414907160975573 + ], + [ + 1.1895994320515475, + 0.073273945205572039 + ], + [ + -0.66148883065972486, + 0.46996699316976137 + ], + [ + 1.3950470194435363, + -0.98464496768394494 + ], + [ + -0.74312762982041214, + 1.33197065209145 + ], + [ + 0.75342417050233801, + -1.099276110530828 + ], + [ + -1.137066594754087, + 1.9835584912553574 + ], + [ + -0.9127200493960016, + -1.0200454781323858 + ], + [ + -0.75134507187536492, + 0.033227469574114168 + ], + [ + 0.021653180561481675, + -0.84794279564935882 + ], + [ + -0.4023633745065856, + -0.59058280918097916 + ], + [ + 0.23959709252433919, + 0.64230207126039252 + ], + [ + 0.57504161541406762, + -1.0624203760691524 + ], + [ + 1.1716450875421218, + -0.38324806424996788 + ], + [ + -0.091377218241175243, + 0.86390312353203458 + ], + [ + -0.55832882139697682, + -0.95333634135293666 + ], + [ + 0.44842577537256462, + -0.82899963373758379 + ], + [ + -0.55723398791081957, + -0.7166549786370694 + ], + [ + 1.8751981114640184, + -0.60377026438693371 + ], + [ + -0.39612416336761125, + 1.7969394636020231 + ], + [ + 0.61010917696934841, + -0.77826655244239262 + ], + [ + 2.014247524438233, + 0.83624747729413473 + ], + [ + -0.086294531582960396, + -1.3841504405304073 + ], + [ + -0.18614210089546629, + -0.99540562150519085 + ], + [ + 0.26033342865643572, + -0.40727409202444903 + ], + [ + 0.93683859812215731, + 0.19900764663603784 + ], + [ + 0.53635674422729596, + 0.078221744366387722 + ], + [ + 0.7285287055815034, + -0.67739849579317379 + ], + [ + -1.4651167337267308, + -0.11148680446540411 + ], + [ + -0.68812317611456753, + 0.43964130486540071 + ], + [ + 0.48070083750058712, + 0.048700805644858208 + ], + [ + 0.94706833172484173, + -0.046480070727231558 + ], + [ + 0.55281648141689022, + 1.0370303322820973 + ], + [ + 1.3338176248801223, + 0.77191447357626142 + ], + [ + -0.15728990969292053, + 0.51657290774209808 + ], + [ + 1.1813339218102028, + 1.6737533769658159 + ], + [ + 1.6959978916096572, + -1.147893995709742 + ], + [ + 0.48114095983581218, + -0.72438726693117028 + ], + [ + -3.1098943690266934, + -0.90331012874292815 + ], + [ + 1.6213434124867383, + 0.73527072846995334 + ], + [ + 0.90029227387115041, + -0.64660222303079862 + ], + [ + -1.4908716920370286, + 0.070677661470540512 + ], + [ + -0.46630588223069031, + -0.35878892897671855 + ], + [ + 0.66607829001505903, + 2.4616979115067332 + ], + [ + -0.9277689144319331, + 0.69101189872559665 + ], + [ + -0.13937963191623176, + -0.61259855181129186 + ], + [ + -1.6344491299933943, + 0.10235682610233486 + ], + [ + 1.8196902967530668, + -0.577273653087512 + ], + [ + -1.9791421767803392, + -0.96108550607150323 + ], + [ + -1.5678353237302709, + -0.0062857254093395395 + ], + [ + 0.093399061648542031, + -0.76028212749222324 + ], + [ + -0.21027954009066835, + 0.38908868283951875 + ], + [ + -1.3566773553024079, + 0.96288613225318864 + ], + [ + -0.02671394923972745, + -1.046715692530058 + ], + [ + -0.14154560788559292, + 0.8098878484035944 + ], + [ + 2.4705661916282859, + 0.041660644863640288 + ], + [ + 0.93702118640954701, + 0.42335336159135828 + ], + [ + 0.051137778754577499, + 0.13436980965718021 + ], + [ + 1.4046464588479264, + -0.52054365987973394 + ], + [ + -1.1622117541285157, + -1.208671978003458 + ], + [ + -1.8138244125806526, + 1.1003252933691874 + ], + [ + -1.2265874618321888, + 1.775558808341867 + ], + [ + -0.73130786163005979, + 2.6607538714051944 + ], + [ + -1.389551833549894, + -0.27657184219998721 + ], + [ + -0.68037431724136566, + -0.073178405903521551 + ], + [ + 1.1478586868877843, + -0.61730075204123214 + ], + [ + -1.5823301281551125, + 0.87762620955523296 + ], + [ + 1.1267555104550091, + -0.43883307912922981 + ], + [ + -0.25560250925081746, + -1.0087955847865093 + ], + [ + -1.452930504970505, + -0.79403218585055813 + ], + [ + 1.0233438317016526, + 0.50088077539263653 + ], + [ + -0.20362814776019092, + -0.50648492102808773 + ], + [ + 1.6005968759460532, + 2.074324210806008 + ], + [ + -0.10498972787240267, + -1.2239076975943382 + ], + [ + -1.8687767760537586, + 0.33453990602779926 + ], + [ + 0.8683733920298089, + -0.50871540654546521 + ], + [ + 0.85794764497907328, + -0.7588109837532836 + ], + [ + -0.22028593158861151, + -0.86352513986292367 + ], + [ + 1.2279992189970097, + 0.24793744745506513 + ], + [ + 0.50377685464604771, + 0.27534467858084111 + ], + [ + 0.40979547921555132, + -0.87354103885453904 + ], + [ + -0.99235011788124194, + -0.8486239151255669 + ], + [ + -1.4311908773560886, + -0.11504762446315678 + ], + [ + 1.4785946267553578, + -0.65066022257784251 + ], + [ + -0.47480157720656735, + 0.09644531237731381 + ], + [ + -2.1794375743328542, + -0.84233746268252108 + ], + [ + 1.1101782208257609, + 1.0017617896845226 + ], + [ + 0.11419896582735879, + -0.2639149081336839 + ], + [ + 0.80432516515295871, + 1.2707905282780276 + ], + [ + 0.19902248103833883, + -0.59936584736639786 + ], + [ + 0.92597828524005954, + -0.22489320188794387 + ], + [ + -0.088727333990267651, + -0.67998892115370646 + ], + [ + 1.8520033385470844, + -0.22206836353309395 + ], + [ + -0.4828279072122445, + 0.067483912228601867 + ], + [ + -0.40816071089190326, + -0.81103914655746046 + ], + [ + -0.86401178129977596, + -0.76472826459382337 + ], + [ + -0.61302428779116813, + 1.1310824222520093 + ], + [ + -0.65991154639283667, + 0.21485087910052386 + ], + [ + -0.49791715552480392, + 0.44408443655113822 + ], + [ + -1.0492267346154001, + 0.50987611934150656 + ], + [ + -1.1562149108302007, + -0.50527730714086172 + ], + [ + 1.6940147339355371, + -0.60153875736691598 + ], + [ + -0.14012919277893718, + 0.14149123618650314 + ], + [ + 0.78745067934201285, + -1.0634598844052747 + ], + [ + -0.1998015474720331, + -0.81319634765656279 + ], + [ + 2.1428992452830786, + -0.62101854828573921 + ], + [ + 0.1267235727073461, + -0.040093384099933752 + ], + [ + 0.47775011857078031, + -0.71087817191621194 + ], + [ + 0.80438009742914285, + -0.74602546309607376 + ], + [ + -0.68070875667918207, + -0.89049991487907365 + ], + [ + 1.1113846017085027, + -1.3858166624886763 + ], + [ + 0.89372830255954416, + 0.17933403131655243 + ], + [ + -0.42615648456386629, + -0.38818370234181748 + ], + [ + -0.39302361226174787, + 0.10760031020823717 + ], + [ + -0.019854830480376041, + -0.7482579631181635 + ], + [ + 0.85283826130183538, + 1.8469428948997217 + ], + [ + -1.6414969720484809, + -0.5220809912665455 + ], + [ + 1.2794873049557611, + 0.56866326077848972 + ], + [ + 0.89304974398458514, + -0.83682069316650154 + ], + [ + 0.36894644108728508, + 2.7122618249565908 + ], + [ + -0.43386961706205135, + -0.21865003017375065 + ], + [ + -1.6885191310987748, + 1.797976857648826 + ], + [ + 0.08394375900139571, + -0.17878689217042129 + ], + [ + 0.31763523089072587, + 0.19666923738566897 + ], + [ + -0.52025063880369793, + 0.88015466944995036 + ], + [ + 0.26728720113124599, + -0.21922270979900474 + ], + [ + -0.44510128852844111, + -0.92139374907316141 + ], + [ + -0.16939981681572505, + -0.63915149367459856 + ], + [ + -0.94926523889940295, + -1.3123733609666077 + ], + [ + -1.4051014141151579, + 0.40607208688640134 + ], + [ + 0.046569046258715059, + -1.4049934406408175 + ], + [ + -1.0260618526705936, + 0.10936729210002812 + ] + ], + "diag_cov": true, + "kde_X_mean": [ + 2.9957584207719301, + 0.019682788619989001 + ], + "alpha": 0.5, + "kde_Y": [ + 36.318970486538532, + 27.156436109632285, + 44.104300127601832, + 20.906374218285425, + 22.630343438003468, + 31.436499618143849, + 18.327554665953208, + 24.882629805269445, + 10.005867304821107, + 44.612869506431871, + 8.2369520422874807, + 4.4258411409684415, + 29.817225179724069, + 19.808113508887143, + 53.405110448687509, + 14.787696033739161, + 48.110427760591946, + 25.347712878632457, + 42.850792751415376, + 10.277472920174112, + 34.942635588910235, + 28.777794596305082, + 26.735040880792411, + 2.5750920037104912, + 4.6252101350748758, + 11.970092721832399, + 28.844627460969019, + 5.7511352170743733, + 32.864318512398434, + 37.94930061055593, + 21.554230075429334, + 36.763318185972906, + 6.9888466541161263, + 51.075892975615439, + 30.156409927055517, + 25.098703864676665, + 46.163229132560076, + 3.7675019150115778, + 2.9817199994007968, + 33.530881436376937, + 34.056584450981234, + 46.329451189232586, + 13.601862347009982, + 18.404815232397624, + 23.154578887516351, + 31.209109656220932, + 35.712248883387439, + 51.952025929803007, + 27.702313291776335, + 30.815362103319487, + 42.276207617838878, + 12.901676060641908, + 47.659220353357448, + 6.5311852262994128, + 32.85646663506143, + 9.1377844621646958, + 2.9547885458147536, + 22.237700028345127, + 50.255558669184566, + 40.71006572976917, + 48.156075924185053, + 41.647740152114984, + 48.91547449236019, + 50.117926333323012, + 26.905207762568235, + 0.96014163572736, + 35.694384019624756, + 29.128444197896084, + 52.118601150653383, + 37.659086624866447, + 41.550537667738105, + 7.8743129306837449, + 23.226671189246812, + 13.640847308138333, + 26.163567656664892, + 18.010487446671885, + 27.56593806453014, + 35.51615815157637, + 21.87804068646189, + 33.519622478502683, + 27.81570830257531, + 40.732377140629957, + 14.055526826187277, + 25.977744220776081, + 41.388686765371254, + 2.1730641279468497, + 49.402769318945573, + 48.952562525729284, + 30.256190518857835, + 24.995925655838047, + 8.9286999792299877, + 2.4043964266893525, + 2.4061994874607362, + 8.8278348667784705, + 38.975464190971159, + 17.32191108530823, + 33.798474215344612, + 4.4746965487379429, + 44.293525328394118, + 20.332902656568287, + 33.125892038035033, + 45.55211791926223, + 21.395780940117294, + 11.048831967409411, + 30.006162363903865, + 17.603897285547035, + 53.802308782991901, + 10.669158851107733, + 34.138927923687525, + 35.178572022409064, + 41.858189930003064, + 6.0731632672868763, + 16.451301652182977, + 37.021115148382293, + 12.966786451342342, + 44.075372118213124, + 27.134826560911304, + 21.044854821193248, + 11.880698564104401, + 31.716982218316879, + 11.312885563038707, + 36.448921954121722, + 49.256578307416312, + 5.7186470370939357, + 1.1391502084171377, + 35.218142234230889, + 1.3651832022734713, + 9.7010608704578853, + 36.54045731554924, + 46.749956126358157, + 38.1511267207119, + 52.336408576445805, + 28.498518359344395, + 28.427185671981178, + 12.761072504244732, + 18.237057336187117, + 31.094984921991877, + 7.1403198776093539, + 30.449357048658342, + 46.663690304087616, + 23.062826727264085, + 40.953091491447381, + 42.610388997529753, + 36.136608325063733, + 42.916317068562179, + 36.604652738889357, + 17.629539639971775, + 36.393507752663218, + 34.096976796664187, + 17.505589494839374, + 20.937853649352487, + 4.801589087181358, + 27.776928459401464, + 37.158763959415104, + 12.333565863896998, + 25.831112800958056, + 3.3790007051316882, + 23.810819552767096, + 15.282875075720888, + 47.991201586853173, + 7.567359721507037, + 28.246425623625875, + 6.3250049785111626, + 50.122639738885745, + 37.546489837366487, + 4.6743659565154481, + 1.334811642185872, + 8.5822281243088412, + 27.080652616617392, + 26.205029357791613, + 6.1513623878398995, + 40.501966455492223, + 16.754849681184854, + 49.302131831619917, + 54.136073082975443, + 42.911536956317768, + 27.253993435857982, + 20.65272144681316, + 36.934670341483454, + 37.193970330584911, + 49.437541289784171, + 53.515432295954355, + 45.180965129437752, + 5.9934365367055058, + 19.119796764569958, + 12.311138069967445, + 50.497537844717677, + 7.3056063278438446, + 14.735622238442716, + 10.594010122769339, + 39.842235981384356, + 4.6057798497744109, + 28.406610107727087, + 41.692513885045699, + 20.535383730205719, + 7.1662491096656842, + 9.4787908910198837, + 23.874052737391036, + 49.096452798618287, + 43.167666736914356, + 46.636057452177738, + 7.6732097197512825, + 46.074077163914552, + 29.598315307380624, + 23.270131628764695, + 49.367168670506857, + 23.715149384449326, + 4.1916314225920717, + 23.576349579681434, + 19.70280880005631, + 52.2945186743001, + 20.405768336934262, + 22.720254954393329, + 24.145802413329864, + 11.84964537765825, + 39.539484885859636, + 37.733599205085341, + 51.053997612175877, + 25.931263716242245, + 28.425778128402811, + 54.17945326472514, + 31.455009939801428, + 27.554907433602942, + 29.325030195682345, + 33.458982936701126, + 13.941603707914556, + 25.818240243331292, + 25.400151954115472, + 23.96002858719147, + 28.09955615621557, + 20.34750454015823, + 43.177616280628698, + 6.0562815557575096, + 3.6424578178348872, + 13.048000875305942, + 1.3958633882817615, + 45.968840729564462, + 46.364603808713653, + 21.765726680883006, + 50.88966909711165, + 13.304780879188751, + 50.444765892945306, + 43.79716043372499, + 18.468446428343967, + 27.966315810131771, + 4.4041241319840614, + 13.611164117546664, + 21.960000694107702, + 21.893116842913731, + 35.708045029475286, + 12.311966287973945, + 20.311579292079678, + 39.224411810937319, + 28.972407670069799, + 52.270306120077713, + 40.659274526591226, + 23.426206565518353, + 46.409704080175089, + 53.875058899597271, + 11.786060345246657, + 6.8974528413201632, + 49.949102904440558, + 2.2049936543287072, + 6.1218798302751809, + 44.121101908321592, + 48.706992704816628, + 38.507369883912382, + 18.08802211311848, + 10.941345863599086, + 32.610047492688757, + 24.932505479161115, + 25.902716990349596, + 6.1519098738647946, + 7.2681955045018727, + 47.585076760329088, + 26.870630451540165, + 2.0187259819950505, + 14.409695086391228, + 3.8744839185939854, + 2.6733748799062345, + 36.483288912504925, + 30.402406466574252, + 19.747744909926094, + 45.810590164258251, + 0.4918131894553216, + 12.160438304835512, + 3.6855464274131333, + 13.947158360199692, + 37.658494523339492, + 7.1779887457608753, + 32.391483145757647, + 18.279580011454645, + 40.667208298297638, + 20.908180979923728, + 36.492655811303898, + 5.2108697266666377, + 23.433699037595087, + 49.714674937382213, + 51.926000869007183, + 9.5854401203683075, + 42.078704440240656, + 54.728899251409935, + 22.473538919249766, + 20.412077619987738, + 39.469240638845193, + 53.192387958519554, + 43.959606344234608, + 24.100694568585663, + 54.156010671020915, + 15.539692595380675, + 48.451154327842787, + 44.222463455358039, + 49.639143302426668, + 19.605903271753071, + 19.445619128101288, + 37.826871835312303, + 24.366281070413624, + 8.6820569640871277, + 19.901064419465005, + 54.344367574076408, + 33.540944063937673, + 40.138964768418546, + 45.426756447211957, + 22.591608917318336, + 28.205483725616276, + 47.60977731256957, + 14.858554090618405, + 24.321504052180057, + 8.0465022315402237, + 5.3910220846802019, + 20.264168924855099, + 49.178812116239222, + 34.337542777576672, + 25.305401880630072, + 19.52193976388514, + 17.333974381115247, + 38.695328201349781, + 20.723975513523481, + 0.51790893797721504, + 18.706032533850113, + 17.551372346853096, + 41.113762516379516, + 15.472876360693943, + 12.106791940310767, + 28.229871403909133, + 40.808954105418572, + 0.98581562201568285, + 21.193120258219082, + 32.72371437590418, + 40.114660215132858, + 9.894703927509255, + 21.186249879261322, + 26.550621232917731, + 17.249223087794302, + 51.931243477699105, + 3.1012528691074759, + 7.6565541953280913, + 6.3882413252737145, + 6.6841605299672429, + 2.3458891399033979, + 13.803932643561019, + 41.427414098762412, + 7.9289610363318195, + 47.942931482844642, + 31.880329145645604, + 53.406744622166457, + 24.080770514075237, + 26.08189868995288, + 7.2022533504867656, + 23.507975686568624, + 43.31066729720478, + 22.546334050275355, + 14.886956367995539, + 53.059365636019017, + 14.319739244332137, + 28.18855216191653, + 29.957873596755501, + 4.6893446999374575, + 20.568078873843689, + 29.505714400293606, + 18.331164407445002, + 39.944599090698823, + 49.534682202534512, + 27.139354081427271, + 30.503022840245738, + 51.685115674464363, + 40.343495090881838, + 7.9462389900928239, + 39.512336056484216, + 6.6479280586512184, + 6.8516222995283265, + 7.2244788461990135, + 35.100555489578923, + 23.883930340643943, + 47.126543954748037, + 43.920443319265502, + 52.864715544942548, + 29.309630207066867, + 31.585272902226436, + 19.824951061056488, + 28.951492081905062, + 15.960314724315921, + 28.417258597703491, + 51.611290406701102, + 30.877859753934626, + 34.154898938299603, + 43.086823898197991, + 49.515941894649927, + 38.49421596198242, + 8.0499374478947949, + 44.01632232432933, + 44.334475969320863, + 12.600114966165179, + 18.945317839357994, + 47.723104017194608, + 45.887103274052556, + 28.304859111653606, + 27.827527799906544, + 37.389405328917348, + 42.555858026597122, + 41.480434348353455, + 7.1475205146957199, + 32.093218120553651, + 40.279805008772826, + 34.666593541644097, + 50.069309426833158, + 41.450166915156927, + 5.8946481742637085, + 53.226465007624711, + 18.35635697042261, + 25.726539113550064, + 13.557948654420791, + 48.211056079146985, + 18.460514889565207, + 29.063286972621093, + 29.244042000507871, + 39.699730417236175, + 8.9925691662168674, + 29.753720882275417, + 47.922753477630245, + 22.536049965301647, + 18.843080689849778, + 18.557929836984989, + 47.584220212449438, + 45.59111571214796, + 7.1160446078449651, + 44.121003298579446, + 50.507389446016923, + 28.60321542949541, + 52.500286170273895, + 27.781838785522023, + 24.409007355395232, + 19.69678036516677, + 8.0622899032925535, + 40.032858770319756, + 6.7413031824492746, + 28.904598694887415, + 45.288748406785054, + 41.630748064963136, + 43.154188518346018, + 38.553782662529905, + 31.14454708688594, + 10.858084187496427, + 0.83525399858056149, + 11.995951336812285, + 26.355374998374362, + 47.874106987240438, + 29.092435490797275, + 54.439390771903867, + 51.419296955020698, + 12.971612180798248, + 34.918772522966236, + 30.304892756252062, + 52.461986134252584, + 32.756523932633336, + 24.87260103445481, + 28.085002704027723, + 0.71186213372331975, + 23.009384136567572, + 44.341788350103784, + 36.039580902547769, + 50.036742807998657, + 13.349795323688566, + 6.178356091658924, + 46.416830292535124, + 8.1065018623664624, + 29.171849064979327, + 15.829899003162184, + 2.9809134940834583, + 17.560477889703883, + 29.885175281442688, + 22.273107031154506, + 31.462782966292966, + 28.99492827934974, + 48.631378424321241, + 14.802538895222032, + 53.91370509811, + 28.40397492835525, + 15.763743077642754, + 26.407761744951291, + 43.507505733175165, + 20.134582810535282, + 11.584956103249869, + 33.41218691886062, + 41.715929719771594, + 0.70433048845115243, + 25.898479775404699, + 3.2254175689536089, + 36.417225827529307, + 12.165237542613809, + 45.19988129808538, + 39.331353771104695, + 2.5651199506199802, + 10.524033781175424, + 26.961468881952602, + 20.221448742854335, + 1.3525495124539006, + 35.53545043448208, + 39.614364443420143, + 6.5471898096765475, + 40.83852147947114, + 1.2429476090065579, + 41.932400240615443, + 51.995791309036328, + 44.979782293205794, + 2.8170111365178179, + 51.94612485916231, + 45.624188814993552, + 43.750987496496272, + 22.192523730935342, + 11.80792760475709, + 22.843178331351371, + 45.793692650595439, + 36.98140503277876, + 7.3119525891138055, + 51.869802620761781, + 19.61129384563678, + 5.9388898085491979, + 18.59813611638571, + 30.68932371883071, + 43.494633968476052, + 6.5378842946993849, + 4.6766598290442385, + 17.051372427736837, + 5.7150817396366298, + 22.31014956055197, + 30.716572551477846, + 30.591162526919753, + 21.549494920047024, + 31.70300128250436, + 44.956920984345203, + 2.254521828724164, + 35.751812940105765, + 43.327354987485492, + 43.281169018999826, + 54.143157868668212, + 13.782174372220251, + 44.154149545806675, + 15.41141491611647, + 5.524357952411898, + 11.816952102971555, + 14.667364354364452, + 9.3689027163595942, + 5.26473566772599, + 30.285267439026935, + 9.1474128634016516, + 32.842737779336716, + 26.173909905314726, + 8.0152064520270798, + 47.418743924113066, + 15.024682204338431, + 53.302421369937008, + 14.284718785302672, + 20.425272007043549, + 51.533579737753087, + 36.688272766519802, + 20.455766436624526, + 18.022133216129589, + 26.753188199109072, + 8.7516488087862196, + 5.4169648205461929, + 52.272828637859945, + 36.176670796491479, + 25.244594097404295, + 48.399345920959163, + 28.467787436462274, + 53.768549978621735, + 16.694722360432436, + 33.130789317828125, + 5.4991626777315021, + 21.959601260434304, + 50.220679851590532, + 33.312545294414861, + 5.5839547046289741, + 36.103240046435126, + 27.897649178242418, + 36.387346807282462, + 29.368943019396358, + 27.827671031426593, + 12.642062936813161, + 16.944270892290159, + 39.592960370982119, + 32.160579935067339, + 22.176525277698527, + 28.803387162119595, + 7.2153130240714525, + 25.39216033377485, + 44.018203151610422, + 27.985770094686007, + 39.707796480511753, + 5.8739178448004408, + 45.300201716707861, + 28.902869296601086, + 19.417118961211937, + 46.307896460139688, + 44.732853958246785, + 36.805143863194608, + 1.0403842268640591, + 29.880827918718367, + 3.9719542885717591, + 45.756034179211483, + 5.8318364619855618, + 8.3566351785194843, + 5.4204294314143313, + 31.666763266695806, + 41.027344674499545, + 36.64708467544181, + 8.5215988549035142, + 51.108665698028162, + 20.672472669506146, + 10.836509324668253, + 27.862490274279523, + 38.644107756259416, + 17.926873109491879, + 52.018178509635661, + 44.951959383379538, + 11.745308858925672, + 6.2753090554992035, + 10.402506666865762, + 12.85133627230554, + 52.200763230012633, + 29.277191657061977, + 20.748529946403281, + 45.409872870918299, + 34.498237160844901, + 38.811971945081709, + 1.0931221372973035, + 51.906552236311519, + 12.229311467810859, + 27.236337618558412, + 47.700895972576312, + 3.8792306110059283, + 46.012614525712294, + 9.8831595977644042, + 28.682090490778233, + 32.134629495505415, + 2.5091010910557654, + 44.008906725986357, + 43.888437976138427, + 8.6045394949823422, + 4.7367241805222937, + 54.589163976622295, + 41.379693382240241, + 29.699170081577005, + 50.114080482877533, + 35.019915932983508, + 23.214425302032065, + 31.712285813756985, + 12.422440989715579, + 32.526164468844911, + 51.848004613083575, + 32.458185143702664, + 40.258470287616305, + 27.582427939166038, + 24.409363859697496, + 32.640324830264412, + 10.640377804582986, + 20.806849107747183, + 11.860451219614809, + 27.016824132769475, + 31.082540304669205, + 20.852782654506381, + 29.099760975527136, + 33.125368921692484, + 26.282644448186829, + 27.06221231986023, + 34.200436325223407, + 32.913971233886578, + 8.5192972226808319, + 29.272174885994175, + 19.808120598057677, + 44.343097815181579, + 2.0686236754932161, + 31.031553067262308, + 31.283328018566962, + 48.289441645540457, + 50.159213666930768, + 6.9730002409391387, + 50.302964916197034, + 12.489518481327167, + 52.659867221402649, + 14.424768526076889, + 51.914845647183462, + 18.328440502701472, + 20.687721172687219, + 25.629438542278439, + 27.13783278567599, + 18.202979131485026, + 3.6245489273321585, + 47.06467986911661, + 1.0956640995328628, + 48.297724135862872, + 36.773822999433499, + 53.187017437395276, + 16.142969263985609, + 11.491116897431926, + 37.512082220523176, + 19.863975325619986, + 12.763600276582078, + 32.508842822816185, + 19.920404282668631, + 42.585193698095537, + 31.721204945799006, + 33.886220846571455, + 7.8621221015947356, + 42.186900473770685, + 29.1601992528417, + 48.013825541909661, + 7.3028846229521704, + 23.485913855780161, + 14.078026166392331, + 51.124299425207901, + 15.16114254724916, + 29.004797372725921, + 53.345202454194983, + 13.73489901709752, + 20.004714047539789, + 43.377446455439369, + 28.636981481605119, + 2.2962966249677401, + 26.180540624569243, + 16.181115761950863, + 34.694448691650074, + 46.773139689665527, + 53.006252954912021, + 49.175667584925655, + 50.582505810199223, + 39.456538457202726, + 13.131150815978327, + 38.428578539927933, + 28.532739729358497, + 27.480150231499032, + 45.658945067916797, + 9.8414778159534269, + 41.271097365154837, + 46.294024133656599, + 15.29981634560643, + 17.849744799794554, + 16.375945277520032, + 25.310891158156448, + 35.496702512632346, + 25.398163997851572, + 34.660244734153494, + 50.347114614737031, + 45.657629175232074, + 25.073916217891757, + 26.494155729887442, + 48.530635667399416, + 51.858880755762101, + 54.794098185085062, + 23.222271114501645, + 38.800355742946799, + 1.9789483863123571, + 35.010457211409538, + 52.773667038920891, + 26.502182568789642, + 10.122087898783139, + 2.3788103572937294, + 50.01342748433774, + 46.962323629006924, + 26.617425520714605, + 17.934737438945206, + 7.4812993026954997, + 23.104076456096635, + 40.149509050567559, + 40.771098461802332, + 46.723374899845972, + 52.635796956964541, + 44.172083659817019, + 48.579634680209686, + 24.347856994604054, + 39.434790898720955, + 41.573765938902454, + 21.026605024597043, + 3.9932827960797801, + 1.0533036636859447, + 41.82355614963339, + 29.343807949363171, + 33.506796570301731, + 24.536990689735092, + 12.759997635851883, + 51.372484494965725, + 19.66663385046856, + 38.060730249818164, + 16.592055826276749, + 21.938103060854161, + 22.780193705418771, + 31.219259930307274, + 33.511318723075853, + 35.636576316642845, + 11.235021378830382, + 48.047326057557967, + 24.284577297183393, + 47.569184979666282, + 44.884342057252411, + 46.283035604278183, + 12.824645414853348, + 22.541498469913247, + 45.861486835024714, + 52.694507448857586, + 4.6666355359449723, + 5.1611445243559118, + 31.900858964772265, + 42.67103286493542, + 26.047842958596643, + 39.351979877286261, + 23.044032671963386, + 28.343824330733181, + 19.946938676047807, + 39.247586667905445, + 21.073333877699426, + 46.760851341167395, + 29.013052631886257, + 55.042580872304796, + 40.885541602667914, + 18.145896800828897, + 24.675137405278139, + 9.3017621695631423, + 1.0733077242944951, + 52.887550316723278, + 5.7224566808089392, + 7.6960529523554788, + 9.5552186193791595, + 10.40559670302105, + 40.097720313781188, + 7.8563901317277347, + 30.35600628746154, + 23.299021977679555, + 23.776742908537543, + 41.031206447278578, + 25.42163817618184, + 48.19729227049028, + 15.290708710424536, + 35.333112182256265, + 29.084465651484177, + 38.198137681078045, + 25.124006920866719, + 40.927737008843806, + 33.170123192486578, + 6.6040121942653878, + 14.661859731972147, + 51.832485970238423, + 29.449770882028407, + 33.233422823071976, + 33.530017994606389, + 17.812913250567938, + 12.594319259034958, + 14.253989744087066, + 22.990516673628314, + 21.963071429637179, + 27.96050061636506, + 18.770001818209437, + 12.839330375167572, + 28.17229893397765, + 4.6667985098828693, + 31.342865368255325, + 28.766494302243771, + 50.734140498280354, + 50.970862539716585, + 28.587909248576455, + 34.755641269292028, + 27.903732791373844, + 22.427836463823169, + 42.157679244272472, + 46.731760693912491, + 47.176026657907826, + 13.450548450738633, + 8.1128913279853929, + 43.866693792689333, + 4.3394433300189323, + 18.983180617701212, + 44.547540210971071, + 50.919662642673735, + 26.324359939212492, + 37.327227097263304, + 41.294350655098846, + 19.072134306540487, + 27.918123581256179, + 39.225876918122701, + 28.551495618149172, + 12.769161714227161, + 9.6653161392732105, + 31.958550403262258, + 5.7404511944700154, + 11.222923666045629, + 47.804356789001716, + 0.57027547357606601, + 7.5153789194363965, + 36.260376481446194, + 16.720736992997807, + 43.908791998194147, + 3.5710106546605873, + 22.211432491073893, + 54.985592889771382, + 14.158579507562456, + 14.319189369670475, + 7.7996374807844049, + 16.284212380756816, + 52.644725301314423, + 34.620930269307401, + 11.603027699150203, + 41.329513686656405, + 23.893220540608787, + 3.35726337055902, + 23.092115453703997, + 42.91675627478088, + 22.703510332271698, + 18.512582138539187, + 5.8355763839843506, + 5.9658312232276325, + 2.42518569344475, + 22.117049709080668, + 31.359257689932228, + 29.568199358633507, + 9.094466539299555, + 29.619216870382324, + 43.578324363505843, + 22.066960771913884, + 19.852750460183696, + 53.579607372711664, + 2.3783433659767281, + 29.644875520377518, + 8.8027546924996685, + 36.791790214451979, + 36.454094739492099, + 50.588704800035238, + 19.370408581706556, + 34.971383532994309, + 46.158730733043924, + 33.709989490058035, + 19.638448901732374, + 21.052762214824543, + 34.997025092242289, + 4.9270640856981833, + 7.7683317737252393, + 50.566424908782459, + 7.3568951718136599, + 53.174811893116093, + 31.456130949649658, + 54.813499718710439, + 11.280591146127239, + 35.133817673925449, + 49.916080966325332, + 37.722830835505079, + 16.436101327031679, + 29.974271949367534, + 30.240331735694799, + 21.183672230077256, + 28.970994890540663, + 16.535206396309981, + 40.897340746796466, + 28.928573088106919, + 52.289039045227284, + 9.3571900179660084, + 46.612744837571363, + 47.995318271519757, + 38.336506498140558, + 41.166985213366388, + 9.6802631889116704, + 27.436112839496531, + 45.993712380390342, + 36.730619567706249, + 53.638757822070176, + 7.1762278004760258, + 17.209221569866042, + 13.799859459842168, + 33.779727721046328, + 2.996432239544859, + 41.371424000539982, + 2.8477112501289699, + 49.219046990937962, + 40.056090946982764, + 21.311370819047767, + 48.147130011209825, + 45.74857187216324, + 54.866374157734441, + 17.764577485033492, + 14.577875212950264, + 17.676516435232401, + 22.851717190124688 + ] +} \ No newline at end of file diff --git a/src/awkde/pyproject.toml b/src/awkde/pyproject.toml new file mode 100644 index 00000000..38a53fd1 --- /dev/null +++ b/src/awkde/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools>=42", "wheel", "pybind11"] +build-backend = "setuptools.build_meta" diff --git a/src/awkde/setup.py b/src/awkde/setup.py new file mode 100644 index 00000000..d77c9bfd --- /dev/null +++ b/src/awkde/setup.py @@ -0,0 +1,36 @@ +""" +Note: `pip install --user pybind11` mandatory. Did not really test if the +instal_requires and import workaround below works. If not, just install it +manually first. + +Credits: +- https://pybind11.readthedocs.io/en/latest/compiling.html +- https://github.com/pybind/python_example +""" + +from setuptools import setup, find_packages + +from pybind11.setup_helpers import Pybind11Extension, build_ext + + +ext_modules = [ + Pybind11Extension( + # Module name (toplevel same as python, then same as in C++ file) + name="awkde.backend", + sources=["cpp/backend.cpp"], + extra_compile_args=["-O3"], # "-ggdb" for debugging stuff + ), +] + +setup( + name="awkde", + version="0.1", + author="Thorben Menne", + author_email="thorben.menne@tu-dortmund.de", + url="https://github.com/mennthor/awkde", + description="Adaptive width gaussian KDE", + packages=find_packages(), + install_requires=["numpy", "scipy", "scikit-learn", "pybind11", "future"], + ext_modules=ext_modules, # Compiled external modules + cmdclass={"build_ext": build_ext}, # Finds highest supported C++ version +) diff --git a/src/awkde/tex/kernel_dens.png b/src/awkde/tex/kernel_dens.png new file mode 100644 index 00000000..6affc9b7 Binary files /dev/null and b/src/awkde/tex/kernel_dens.png differ diff --git a/src/awkde/tex/lambda.png b/src/awkde/tex/lambda.png new file mode 100644 index 00000000..7e062ea8 Binary files /dev/null and b/src/awkde/tex/lambda.png differ diff --git a/src/awkde/tex/log_g.png b/src/awkde/tex/log_g.png new file mode 100644 index 00000000..b6f01fd1 Binary files /dev/null and b/src/awkde/tex/log_g.png differ diff --git a/src/classes/featurelayer.py b/src/classes/featurelayer.py index 7a2dbbf2..2e42ad22 100644 --- a/src/classes/featurelayer.py +++ b/src/classes/featurelayer.py @@ -1,10 +1,12 @@ import requests +import json import geopandas as gpd import pandas as pd from esridump.dumper import EsriDumper import traceback -from config.config import USE_CRS, FORCE_RELOAD +from config.config import USE_CRS, FORCE_RELOAD, MAPBOX_TOKEN from config.psql import conn +from mapbox import Uploader class FeatureLayer: @@ -157,3 +159,47 @@ def spatial_join(self, other_layer, how="left", predicate="intersects"): def rebuild_gdf(self): self.gdf = gpd.GeoDataFrame(self.gdf, geometry="geometry") + + def upload_to_mapbox(self, tileset_id): + """Upload GeoDataFrame to Mapbox as Tileset.""" + + # Initialize Mapbox Uploader + uploader = Uploader() + uploader.session.params.update(access_token=MAPBOX_TOKEN) + + # Reproject + self.gdf_wm = self.gdf.to_crs(epsg=4326) + + # Convert to GeoJSON + geojson_data = json.loads(self.gdf_wm.to_json()) + + # Save to a temporary file + with open("tmp/temp.geojson", "w") as f: + json.dump(geojson_data, f) + + # Stage the data on S3 + print("Beginning Mapbox upload.") + s3_url = uploader.stage(open("tmp/temp.geojson", "rb")) + + # Create Tileset + response = uploader.create(s3_url, tileset_id) + print("Uploaded gdf tileset to Mapbox.") + + return response + + def drop_columns(self): + """ + Method to clean up the database by dropping columns that are not needed. + Ideally we'll do this in each data_utils file, but for now we'll do it here. + """ + columns = [ + "OBJECTID_left", + "Shape__Area_left", + "Shape__Length_left", + "OBJECTID_right", + "Shape__Area_right", + "Shape__Length_right", + "MAPREG_1", + ] + + self.gdf.drop(columns=columns, inplace=True) diff --git a/src/config/config.py b/src/config/config.py index 5ee847d2..0a027bd0 100644 --- a/src/config/config.py +++ b/src/config/config.py @@ -1,2 +1,5 @@ +import os + FORCE_RELOAD = True USE_CRS = "EPSG:2272" +MAPBOX_TOKEN = os.environ.get("CFP_MAPBOX_TOKEN_UPLOADER") diff --git a/src/data_utils/gun_crimes.py b/src/data_utils/gun_crimes.py index 62e816ab..47115196 100644 --- a/src/data_utils/gun_crimes.py +++ b/src/data_utils/gun_crimes.py @@ -33,6 +33,7 @@ def gun_crimes(primary_featurelayer): grid_points = np.array([xx.ravel(), yy.ravel()]).T # Compute adaptive KDE values + print("fitting KDE for gun crime data") kde = GaussianKDE(glob_bw="silverman", alpha=0.999, diag_cov=True) kde.fit(X) diff --git a/src/data_utils/rco_geoms.py b/src/data_utils/rco_geoms.py index a508358e..c81c48f3 100644 --- a/src/data_utils/rco_geoms.py +++ b/src/data_utils/rco_geoms.py @@ -12,13 +12,10 @@ def rco_geoms(primary_featurelayer): "PRIMARY_PHONE", ] - rco_geoms.gdf["rco_info"] = ( - rco_geoms.gdf[rco_aggregate_cols].apply( - lambda x: "; ".join(map(str, x)), axis=1 - ) - + "; " - + rco_geoms.gdf["geometry"].apply(str) + rco_geoms.gdf["rco_info"] = rco_geoms.gdf[rco_aggregate_cols].apply( + lambda x: "; ".join(map(str, x)), axis=1 ) + rco_geoms.gdf = rco_geoms.gdf[["rco_info", "geometry"]] rco_geoms.rebuild_gdf() diff --git a/src/script.py b/src/script.py index e1608111..35b657db 100644 --- a/src/script.py +++ b/src/script.py @@ -54,6 +54,12 @@ vacant_properties = gun_crimes(vacant_properties) +""" +Post to Mapbox +""" +vacant_properties.drop_columns() +vacant_properties.upload_to_mapbox("vacant_properties") + # Clean up vacant_properties.gdf.to_postgis( "vacant_properties_end", conn, if_exists="replace", index=False