Speed comparison with dimensionality reduction and fluid.kdtree~

Based on the discussions in this thread about applying dimensionality reduction to real-time input I’ve built a patch that compares the speed.

This patch creates fake corpus data with 500 entries, each with 200 dimensions. And then also makes some similarly sized fake “input” data to use to query it.

What I was wondering (out loud) in the other thread was whether it was faster to immediately query a large dimensional space or to apply dimensionality reduction to real-time input with a pre-computed fit.

All signs point to dimensionality reduction still being faster!

With this dummy data, on my desktop computer I’m getting an average speed of 0.56ms for the version that applies a fairly aggressive dimensionality reduction (200 -> 20) to the incoming data, and an average speed of 0.96ms for the queries which happen directly on the larger dimensional space.

I only did this with 500 entries for the sake of testing, but I do wonder how fluid.kdtree~ scales up. (is it linear, logarithmic, or exponential? (logarithmic is the “good” one yes?))

Also, for the sake of realistic data processing, I followed @jamesbradbury suggestion of:
[data] -> [standardize] -> [normalize] -> [pca]

So a double-whammy of pre-processing before getting to the fluid.pca~ part of the process. For the version with no dimensionality reduction, I still compare with standardize/normalize in the mix.


----------begin_max5_patcher----------
17689.3oc68k1iaakrne14WgfvE3B7t1sO6KuOMYabFL1IFwNHHXxCMXKwtM
SqlTfhxKyfq+s+NKTTbmGJtH0Noaj1Jhhh0oN0dcpp9Oe0SVdSzG82sbw+2E
+qEO4I+mu5IOw7V523Io++OY4Cdeb0FuclO1xUQO7feXxxmZuVh+GSLuO6pE
23Ed2hjnEqdm+p6Wraqu+5CerMAg9qh1GZ9rnz2bar+N0WkWRPT3009ItMJL
Iz6AeyS3G727d+jfUdG9R25kr5cAg2ccr+pD6Z.B4fq.OcgPbkDj6WL8oKfX
r9RD1UfE++R+JB2+Pz9jM9IlEGH2i8VuUlGKL88BVa.hna9imAgKy8A2E7uM
ePj9Am8sFDd3KEpeu+2u5qz+4oCDISuZwlHu0O+1fjE9u2O9SI50+rijQRnF
ShPzoDKCNWXYxEAoLGflbJY44BEiuHHjEP4zSGKNW3XzUKdv6d+E2p+yuuLH
b69jee4h0dIdyuXYlFYRwJ4FlePb8uXLQgnIjwAQSmZD8M6SRhBaUvHyn8Ag
YUInPlko9uMrLOrjruUxm15a+VWpEFsL6lxsh4GgkX01Qhe709gd2rwOOVa5
W1b4rtpYyxp9A+c67tyuBW0GhCR7W77eYme7tm+yQqiCtK54em+t6Sh197vn
3G71nI8ZgHQZPIXD+JJI2uLnVRjESh5O5pVTEYYcnCzHhNTBvSh8B2cqZkuH
IPIHR8AuZWhW3Zu30JLw5iuaF1YcaxjMRJPB3UPg9WKxghTXGLfNpXG7ngcB
8+f5KrBxIVAGJ4u4PQctvwbb5B+vubkHR.uiENpwE9SaXwCm5E+sa1Gr93d9
m6doWGGgD2wJG2zJeSvtD8p+VkgFIMhFPKOqBLxwnzB9AALHHMY.Cq9kXUhB
fZAr3wUjATL4rEIKtYwMsZs.1XWFjhqwtrNEBfZUixSaQyhx4wQibng09Vs3
vbl5V2xGXsHByj0nOEHOUFhLFgRundLQ8xGv4Aa+3z0eJBPY4UvFs076TVNl
ix6IK81tM2a+jb2hFq8GQluHwSydqfP6aAydqX+2Gb39oYuqWrB4knvb6isF
i9Q1AUd5uln09wg6Cx1BM6eofjYmRaD6tsolTZ1POb4iaGTKsHvrmnX8LFqJ
.Gw+JJg61Ds5d+04L.Qg+25Gpr4NmwzEt7Z+a81uI457FqBQWU60OXzasWLy
P7uNNvaS1B3t3f0QgZfnvNg9sO73TjZTKeV9Ei4SD5sslaVQYnPKMbQknrj8
6twKVuQkZMF5vEShh1T7RY22F+aSRu71fvvRXQkPxlunRT56Z4duIRcwGZ66
1bkcWuOzd0qUzDIWuy68Ew1Ida1jxNW7q+idgAO3k3qsvw5rQ1EsVj9tcqhi
1rov50dk2WyUVqnwW4+gf0Iuy7fxSLn93AaOPDsLaWdcvc96RJ9dId2sq36r
K4SVjdt2Z+Mo7vWm3+v1MpUQwOfh6Po.c26h9vtzO3ABs7HfiwNLOOcdYiEd
+17rnYwgPKCH3fmDE8mnYMdN3WQE4dTdQvoQOLZPKwSNnoHUZyThYn.KhgNK
HF5EAhonUVE0stZiuWbG3LDwJxiY9GbEaI5KRqQDFu.9ppoTiD9nfYFEQGO3
60EEDhlFHWiU1XoCXCTaXiLKKBBSZFyfWdtoTdlTJ6Rri.ck1bSKSFFOYDJL
wrPnzF5vArgkPABEF7fTiZlFrA6by1jn7Z+t2oz91AJgQxw5PYNPefcl0oCN
HJ4bij156ce2nHHUXITrgRWLq3H7YGGsX018ZSCKnSpYS1akNCZ+G1fUXUzm
uJALjWFVqw2jpHzxqfidFVD20nGhM4kXoauNuEaviwl8ZraOGax6wBdP5fWj
k8jDYs8PXRrGTZCpGlWbyrd2IcvkxlcqDdEURgBl7vOMcGkczzQmMawgS2b5
rCGO6z4yNc.sCmP61QzNcF0AGRcwoz93XZKNm1oCps6jZ6Np1typs5vZSNsV
uiqM37pSNv5nSr06HaYwNk0FT45kzJXk5VPdR8B2wVg6bq4kzC+s.iQiIDsV
+zVV8NyYecoKdH0w56VoL0O98daVDDt3gcKB1sH1eaTbh+5EJ7le4u2fv09e
rjrwbZTKpUcn3yJZYKpo8lEUV1sKrpwPMXDIysFpXEOC5b2nLRsaGqaJID0q
3sMo2M6A04a2PY0yJsBrwbKIM7qolYOB6IUMCporC9kwlxyJZs9ougjJwhXi
XfwG44Y+fLd6GnubDYYcpZ1kXQ+KIVMtivMwMZ9EXwdbsmXdZtqAfv6kIRCm
Dm2pkTfVrjxb3Q2obVXWZxdW3EtN0ZJkgUo1Y0nAUnKHjuU7xri6ECE26owz
oH+NQ3sQsWzEU8ogrCGELHQ8mq8cicQ6iWc.ejtjWTEwp7iJIHLyU++UlzW8
m8jnSNU3i2C3CcFfOVOfOkoDKfyL7Q6A7wNC3OROfO3Y.9v8b+ctgOTOfObm
vWtKlOfiK0g.Z801PgcsWRRbvM6SrhjpKZqmTXXbOzg2sI5FuMkhrRSwz4qp
tTGg3uWVQVy4I2dxcvY+cZRSNC0XZGxG977prxeCU0IMS3nzSYwXgjZAAgGG
DDZtQPT3LREQFGjDdDQRUhoYyIqJ8fZ6DVBzDJn4yOA7bwH4DJHMomiBNfMN
3.zbiCROWIiBNfON3f5XENdnGqXX+QzRcFDjC4T0P4JV50fU.7RlAz5lSugB
riPgAAOYfAS3JxnJVKJdsMOxfyKnoOIAZ2EpCzfSCnwbDzpYML0XMWAMJYtw
ZThyj7zIjjm5NmGaBACBumhglOZHmAsZ1Qy.MzYFzZAqMMj2FiBcSpvTRWYL
f2M5aJeRgCjyvwTxtmsJ6DNLzVvICLn8ALpGaj9lGh3PWQa3+bJUmP6wLnb7
Br.2XU5UgQ+r+58qz.5WGt9UZXvgxPCoKOQI.QPGpCKjNAnibY2wquRDQ+4q
fqPjzJtxdL4v1ydMiQ9qRt5uJ4p+pjqFVIWUrYgTT.4u9C+1hu9m+9E+1O8K
Kd4O8S+y+wO9hE+iebwO78+72ek5meO72C+te5G+ueq4hGtR9uoBMKDRSG54
xMLjFaqDlDnC00.Kmx3DNjJA.gh4AwsoDVvbNjB0z6PxV7qh1Xk98uTD.T.T
pdZLfPnj7.UpJuRG1aFRhnRHPR0uC.CAXIjhPRBVpqP+R.R9C2kr4iTM3pYo
nodDsoajGuffm4cc.URUOPlDHP.l7ooDBHoDK3RLTfrDB51QAmHoBBTJZeaW
7Wa6tusa66IJ6srIYhQYJq.jFNqobaWJTOGFfHI.BjPLr1.tZChKDJxArcaG
f3DLAJDBNhxYsusy+qs8dvsyRqBSgB6R35sc53tkmeqAc12ZZqH7FTmzoIDr
DhsUOj7JJgoVmXAVo0hSD01NcFuz7wO6E0Xru25E+9xzFuRbZiW4MeJb0yec
bjwp5m+22r+aidk2yeswbqcO+sZySi93BzyeqBUu3swJ6R2brqN86KajU.2w
9.MsEYQtBh4.jZeAvzs2G8Yn0lXQ4jjs0y91PFM81nfvjEO6YOSIaJ9SEIry
dWmIrE7zdFDpJBE.mN55YpxK2+vM9wcmxdlkxgcEyfCTllPT1p.wOM8LOLjZ
4tRmxoBt.c42Q.h1rqKIjoDRT9UJq7HBhxrOgPgOIGRb4jPHIN2Umps2jUh6
zE7U5oogxthPoBN+.iGVGTL3PKwWSi55os0WEZDwgmGDWC80rNDTQTN1TgIU
hGJ5p4lbVamX+KICbzsiz5M2oqiZhUuYsl1f3SGmKBd4nBfaY3HnyjF.7EuF
fFL+nd6P55bDJsUyAiVwlCDYBI3drppfIrd0KPk7uaFTSf.WF5IxQd8Y2Huv
XTUKQffYTUATt7QfgabZZunALqFtAmGw+tbjTEBShxnjhrWS8gS8x6761FkD
B.5.MRn1V3i0PM5zQ5b9cF2A1JJkZK4Kxwit4jfMHmcrwuuDiYEioScE7LCq
OOuTNuHa1DRn.ofKCc92G56E6uyIs8XA0fmf0k6FHXx03CIhYQkeaTTY3qZB
nUgB9tVDnhYiVm4RLwDFOK9ki2LosZOkoN8mQanNxbYz1O6jg7N+Di42clWE
qegXQQTosySMTTYKnQ5YWn9ALzh+KXFWnazcjRB3cSn0Ix2gO6svOq+I5vur
yO4yKRThstJ2rgoCjk1zS.fwXJrDWZmOCP7fkxenEs6fSJX3kPDsNgbxgsAm
hfHWoGANRrEERj5LKimvbW.AWFzb2uNI1uS2gSUGR3zpnINYF8FFvmEBM2qj
05NlDC2ou1ZllJ63t7JqUmpDMBBTq06Cqlz.SWsINI0jlyk5zTVQZtdb8I7I
FJft.EnorDgTe2HWJMmor9fbc6.LkPAB5JXHmRn.3Ls4TCENQaNkENJ5RXCw
7k6BGxgctoAJ3W.hMgrKAffJckr.OoE8kNFONwivlxZshHbtDOAycwU1CfiB
l6RzE5b8UNspcfjKAlJryHCLYRgCWKcPzjBENaQBFNovAzQcOY3soANffKCV
kKBKzrqQm1UNH+aZfCW4Tfyd4g651De10H4JjAA8qb+O5proZ6ZvW4iEq490
AQuwTxjW+J+v8GcI+PwcV+B5l6tMXylr5F4IU9DOY4gvnrz9oJLgHxWuIHIA
BE5ZJAqj9iXlWodAkVRQb58AObiDJQBLEiBgg3DSQnQDHLEaJPkZtUzwmI.J
sOIfT.H1WodKXkBY4IK8BuKsLR4k5n+aiiz8uzC0T6U3BcBNu8IQ2E6sNHMd
GfZ61aOMGMTr5SVWq8e4CpMhf7eG0QClso9x84Kxj12HyWhJJZteZqe3h23E
tawa7eH3lnMqKF+KuUqTvXg8OLRsOXPfDJPZ2H412qbMAcycEqzH.AxM2pPR
Ibt4UDjja1JorB2q+F+GJ+n4BFy9gE.nPXekBJPnpO6B2HgSgXyGGIwBa8Kh
nPSUtU9F2odxlxiu3iVWRblEKjwQVJNA..IU+BxpvpqCB0EfteFUHVhfL6y9
.oLhKHXXcnN2Y3xH5ZgmqGz+E45DY7ZBNfJD1WUKPWlqicf9fo+gaek8a6wO
S2q7RR5CS2gBy5eUxai70fktdFtpfZ6I.ve8Wmbs4qAbhxLrE7eWhIbeyupX
BKgYcupUtbIUqawJKgvAF5cM4NV1ClTvSy8mx2UoMqx4dwL7EyARP6WjTIqi
ZwEJdHN9KSt8dcqO5X2+0292OQ1ke3SqiityO7slMvN3Zn.NyVBtLJFZ3ZfP
DD0sxUndlnauANgIkouBTycVmpUhNI1VSpjHFwP8PkP0FXGLcPsQbVE3ZNMi
RM9Ay4Zm8QT5xYFUWjZValnQgqBQPs0kNVSfYKG8KS9H2MR5OWlpZxbYvpSj
U5E9g9u2qSlHRpL+5dUGbQBrjakbgko5RzuEE2kAl83QNFpdjNw5z5W3H3RG
r+nsAQtWdqJ0Z5puZPLJyLuv2TZLW2NGQUqKDYXPP5qfStMjof92UXZv7HBv
egWP3mOAHWQdjojq5qlOve2GBN1215bATQDILUdvw+LqvM5QGf+O2sIXc9yt
aWQKycwv0ZLVOzlzA1oy.az4yZNvuuL+AFrcbac3KVaH3pBdJ7Imik2q7RhC
93pj3AHsb9AZ8g+9ymHIemhIGJGvbfA9wn096FBc4IxG2KaapyvvYA4zOQhc
HPbVf3R0eQ6.bcRKqZ3xLB9uNXUR+v4WrLVuV2cRSdTZ43aVEs0+TkJdxxCN
lvKIV+ybS68VuaFBQWeDmc4Qs9Vk+52zKmzpIlDf9XhxYvB22Fcm1C4ArIi4
LBGZUzSvPim7jJYl8Bzape4gdjH7Kfspe06895dPwD4.6f7X.bEchQBq8hu+
Yg5Nv7y15MDmfOw7EcBo6ngnyQxjExyxFbVdgEF3XBBtMrC90IKdcSVfsmq3
08GoMjZ.HWU2MEe8nSMwr2rwWokxddN9lnn6W1piBzVycYq4v.3DA9wT.W4E
SWnncGp+KR6bzdAg2O.IoL0ZEHxLwAy.JIgcmrkdHBs1v931S8TtmJh6c79p
Wioq.ZEVviIW0bK37uB5HO3SK72IHKP8aUdFTC8nKKo2a8y+W0iYjGCFltQa
NV+bQpb7BARR5wxyzt4SeEW33wWfkY3DMSX+AJqoe8+f2GY4liKmf.TQQmi4
oD0sJ.sz1LnjB8djl4IG4Tptt6g6JDDlhjE0hq0ZLa6qU58AsC7mVx8GYS6E
YG4tpupCAqbg9DU+zZe0YxHnwTjbUN09SQTtl66afuycN1msPYY6GEeyl894
6cc8VLEFxSOjYGE3JmMwroKh3nODNnUw4UYgcU7sexaXKB.RRsGSONGiQVdb
DDBwy2h3Ew99CbUX1ExhoMjo8IX9V.uRIYOLwaPKAAAvX1Hxy.pEfYKgIgR5
7sN9Y+0CZMvyL8Fl40LHUy6bsF9M+Mah9vv1JPT6Ylka6Hw1YZDg5xA41zk9
lyEJ5K4EpIUquHZy.IKyBKKUYYL0d5lyaRwjtH1tOdq6oDohCMDf0tUDEvjF
dKjfxPhdbfP4Y0+.ARUhFMx30RHmEQKw9q7Cdu6m.h5nSyhqywE.HeUfLsK.
qazZxvSbWrSBvFCyDQoSPlpSlmVpaJFT4rncdme35cOF0JebCaZkazXEDA3P
.2lmcBCHSqPQNbVnWS71dhQ9+kdIQKdoNJLKmbXbWh+s62rIoWILtbwpHnTn
MiWLLGaqIRlRxPWGH.csCyMebVl6l5vNlUlJyxhePqcjfKr1Khy3vvHIttYo
3IEpqKTbmdfw9XrdI+fNJre5DYL+tf3jOs36uKZoCoI.n2eLQbAmtsnDkkli
ZmsYnG0cYQTIl4TBEfRIv5jCP23ESUoC.oiI1wXy3KjQvdg.hW+bdEaav7H5
UoiU8zgqNUOMULs2SR+ms5E5xyEGHg3iPSic24Z5tm8bgWb3adrymp1FiOFJ
05G27RtogmZG9sEwHTaiaFzHFAT2RlrbpWVpOTqKIaKTt1kTZmtsmKI5zujB
ZktUo8nwcIj3TVRrQaIULd8GWRJYSJoTDYqaUb6be.Rptt3UZ.8txO1.uHu1
kLZDWxJhKJmfYstUZaiv0tjEjQdIKl7kro0h.acWVJlwMY4nshKzQoOtf+ex
FoB0SQik1YtJqFNUCS7orXy2ljKrdEfQa81s1yz0lTNOJOEvYQ4YC6ywdgqi
dXAMaR9zFJAJwWgYG+0bhZ33Sk1t4sazTSdmr3lE2zxJlYGXQPZMZhfUmsy0
OkGZtE72L0.Stbh2w2paq9AZ3nwUOUXre.ypiE.H6X0iaZ0m0O3K8h5QD0KT
GmGp8iKaq9sAa70tsjZq9gNF9Rusay81EbtRgz9CqaHhml8VAg12JqkiuL1+
8AGteZ165EuR6F2pj8wVK8+H63vmX4CQqUNArOHWmoKy6E6otV6gvtsotjtL
WFjWle10YHEAFYOL6vPjHxenCWdixsiU26uNeiUeYzV+vfvs5ZhILIqgvkc4
T2Mut3vZ+pZu9Amlq8hGaBbw4pa6k2EGrNJTCDE1IzucN+roV1r7KFymHzaa
M2r0WsFt3NS6m6FuX8FUp3STliW5oOdgKkcea7uMI8xaCBCKgESh117Ei0gF
q4KeSj5hOz12s4J6tden8pWqnIRtV6WZwOm2lMobyE+5+nWXvCdI95AkgY4B
xtnUEx6TttFsYSg0q8JuulqrVQiux+CAqSdm8PRja+tG9.ezI2B8PvRu09aR
4guNw+gsaTqhhe.cMIrKY26h9vtRtSmGAzTmIzswbP4yVVStkXY.AGT9WzDf
lU44fo.Uj6QuLlVRNgYriLiC5CmZDC8xejnqOnscfyPDqHOF0NZzmrQRCmdt
mHMO360EEDhlNSdvoCekANBsxrrnsItBGe1mtQOSJkcI1Qfz9QASmKM3oazY
JN6CVLGvFVBEHLcvzV1EywCavN2rMIwQ6u6cJsucMBnI4XcnrgN0lJv5zAGD
8rOg0156ce2nHHUXITvVilmUbD9riiVrZ6dsogEzI0rI6sRmAs+CavJrJ5yW
YrVwYlYC9lTEgVdE3234ctAODaxKwR2dcdK1fGiM60X2dN1j2ikx+UmdQV1S
Rj01C6npTmSDSL73kOE004NoCtT1rakvqnRJTvjG9oo6nrilN5rYKNb5lSmc
33YmNe1oCnc3DZ2Nh1oynN3PpKNk1GGSaw4zNcPscmTa2Q01cVsUGVaxo05c
bsAmWcxAVGchsdGYKK1or1fJWuq42WSB2sYJFlFDW5g+Vfw3IsM79p3m1xp2
YsivuzCRxww3mRYpe7681rHHbwC6VDraQrutjM7WuPg27K+8VcR+UrbMJnUc
n3yJZYKpo8lEUV1sKrp4zlo2ARSWDubFO6VcqiNVWdSCUGz6jz6l8f57sanr
5YkVA1XtkjF90TyrGg8jplAUdSA+E0lxyJZs9ougjJwhXiXfwG44Y+fLd6Gn
ubDYYcpZ1kXQ+KIVMtiXNpSmAAVrGW6IkGJzcnAfv6kIRCmDm2pkTfVrjR+U
uXmxYgco45cgW35TqoTFVkZmUiFTgtfP9VwKyNtWLTbumFSmh76Dg2F0dQWT
qL2pqtOT2HDqlcitmi0G7ip6Q2XunSNU3i2C3CcFfOVOfORwIn5r.ezd.ery
.9izC3CdFfObO2ema3C0C3C2I7k6h4C3XWmY9xQa8jBCi6gNr8Saecm39xsz
gAG+8xJxZNO41StCN6uSSZxYnFS6.nPE7bTkU9anpNoYBGkdJKFKjTKHH73f
fPyMBhBmQpHx3fjviHRpRLMaNYUX6QRwIrDnITPymeB34hQxITPZROGEb.ab
vAn4FGjdtRFEb.ebvA3VmxtULr+zmIvbWG43b7DNMm4XWGMwrobDayDthLny
8ra1YPSeRBJUspS7.ulwbDzpYML0XMWAMJYtwZThyj7S4zsm5NmGaBACBumh
glOZHmAsZ1QacpoOmfVKXsog71XTnaRElR5JiA7tQeS4SJbfbFNlR18rUYmv
gg1BNYfAsOfQ8XiuPpP+Fq7p0AO7y9q2ux+qCW+pbSYfVJAMjfomFMHB5PQX
oGnBX73VPoLX8Ub2e9p1Jj8PnKrEcElXNpbLI5uJ2p+pbq9qxsZXkaUw1BQQ
gi+5O7aK95e96W7a+zur3k+zO8O+G+3KV7O9wE+v2+ye+Upe98veO769oe7+
9slKd3J4+lrcTl8VWvI4COPNVxqa7SUf05G727d0t7JuNByfIsjTntJY4TFm
vgltfnhECwsIMVvbNnC447gsMy.n.nT8zX.g.iS6ONpeXHIhJg.a+NGfg.rD
RQHIAKq1flKb7ujMenqAWMKkU0WbjFFY6KrcxjYj1P2uNUOPlDHP.6PsWStX
698RLLc51KEDJgSjTAAVWCBKOwg3uHNFahCDHsb2rozhQ0s7JogKcJINjB0y
gAHRBf.I1gnFfq1F4BghnAaIN.HNASfBgfinbV6DG7+jRbbZxDXo07oPgcIb
81Ncb2xyu0fN6aMNkVqC40xVMJSchsDWdI+qsBi71.kSudg6zykO8wIxOT8g
uR4tzCdaT6lqO9dwF+JW2YtgL4GSJpJ4AI.SWIlBO6kXZ8XRkSLgq8hWWDWd
D+1A5TxsUkZMcAILX5JsaH+riNi88Vu32W97eYmxQ+mGGsV4aVzyeymBW87W
GGYba74+8M6+1nW487Wa7mX2yeq1+qnOt.872pvzKdarxwqMOOCY+6KaTxKt
qyN.vbLAEvqHkIqwnTwKSxYI3ruOjQSuMJHLYwyd1yTxsh+TQB6r20cB6zSY
OSVCFE.mNJ6YpvhKMxtasG1gI1SRMXnMmfJc9oJqdzkeKtHZytNwaVhGDfbE
kj6WcaxFOcJYDm65sNVAq9KJwQ5DByJ9BCvkrLj.GZEqqo4L+WiMCiFwZ34A
qc6l8AqOJY5ytIYBwLDRR7PQPaB1Urmj0bA8e16ZH0aCyZuDu5snoqyJEW1j
0K1wm0zvmhfmaF0a1e6s9wetN8hK9a67dX6Ncnc6.6Irki.QJx0FNFkdWSq5
HlmdWSePdEL0n2nuzF.DdlPevyNSLpKtRaeclZamrzIzorytwqNnajcr0ICl
TqGlGCOcqgyk16jErYoupcQXyoSVjyk1FDFe1LHGewaP934HdN43mtq3L3gx
NspeiooDYR7DG7ETDQTl4c5a.Hq.y5xs.hwmrM.4kZjPp2Nktz5XCSJTQwVg
LFQlPSier5BKGasBFqmAS4+kOOdwh.WFtwliF6yNRiobBqRTRffYzuVn7raS
7uuDiXEk4UaYzQ0E1BkCKFljIzFYHEbYvRdenuWr+NmXFoHSGffB30b3CffI
mYDRDyB2XaTTY3qLw+oIHqPaOo91mgomxf4rRAiKcNAMMg8le4D26zFNa4fQ
NKlaeYz7q6ja7N+DipwNy2uM2SJkiEPkBzXfJaAMRO6Vic.Cs3+BlwB5FcGg
WhuCNgh2wm8FYq0tAcLb24m74E5wYn4+yMjk9XJC.LFSgk3RJEoMd.OXQ7Gl
SINX7.FdIDV79dNHno9hBEWg3XrDawel4NHDxlNBNH3xff690Iw9cZiZptPB
SVEMwIynIp.9xGAY9Dyv19qqdLIQv.DB.4fIOwmP.6xI3kD6jVDi.EEiO0gw
DPd7DGSLylu2x3n4vDK.7wgIVZ1sRAhnKrZpYUrRFPf.yfKO.vY2kmNC.lap
Fw1v0nrEuZbIPvo6PsIkWFZF2tx6yK9apm+ZsIE5hPSmNS2PZHDqF6I3r4SS
ojs7R4j8Ra7PtO7C4aaCdAHUd40BjbpqkbHvMxRRvFV+KAb40GaFncVBqE50
JhZJsypeGbkIo4tnkR5TUVKmxZv27kiboz205EmNv3R.W3bWbYJa1NthHjSL
P.cgl.Mk86G3k.MA0Q1ior+T3bynALkPAx08C3TRZh.tBEjoFJbhCYJaLWnK
gMDyWtKbHnoT+AzUY20HUIqY6fOufFBN68AHWAMHetarStCZPvb2Ymf7K.CE
frKAff5pgalDBNcvgNO0NIPlMkMNIhyDsLvryq6NvQAM2u8lHtcmaVZSqMNP
xk.SE1YjAlLovgq8ALzrqcvYPCRmcFMry1qigS51GzUW6wSJ4LDbYvaeQ3+h
cM5ztxAA1SDbvtDbu1FUIm7jhvmcNY2AN.Y1EABbmsZREy.FNa0w3qZ52YMD
f0isKu8qChdioo0c8q7C2eLVtGZud0C62b2sAa1j0GcdRkOwSVdH3wKsepBy
m278eGjj.gBcO1AqTWiXlWodAkVhfI89fGtQBkHAllyCgg3DSC9hHPXJ1zvd
p4VQGel.nz9j.RAfXek5sfUZrOOYoW3coMxOdo4o513H8zi5PWM7Jbg4vg29
jn6h8VGjlAAPsyZimlibIV8Iqavpt7A0FQP9ui5H2x1Te497Mcm12Hy2xdTT
W+zV+vEuwKb2h23+PvMQaVWLv+dqVofwB6eXjZevf.ITfztQxsuW4djzM2Ur
yKAHPt4VERJgyMuhfjbyVIkU3d823+P4GMWvX1Or..EB6qTPABU8YW3FIbJD
a93HIVX6MbHJzzavJei6TO4U583hOZciDyrXgLNxRwI..Ho5WPVGm55fPcG.
0OiJDKQPl8YefTFwEDLrNTm6LbYDcsvy0C5+hbchLdMAGPEB6qpEnKy0wNPe
vz+vsux9s83mo6UdII8go6Pip5eURqX9dRktKHbUA47S.f+5uN4ZyWC3DkYX
a4pcIlv8M+phIrDl08pV4xkTstEqrDBGXn20j6XYOXRAOM2eJeWk1rJme0Ua
78hyARP6WjTIqiZwEJdHN9KSt8dcqO5X2+0292OQ1ke3SqiityO7slMvN3Zn
.Ny1RBYTLzv0.gHHpakqPFVQzatANgIkouBTycVmpUh9vSaMoRhXDC0CUBUa
fcvzA0FwYUfq4zLJ03GLmqc1GQoKmY+bQpYsYhFEtJDA01MOwZBLaS77xjOx
cij9ykoplS+RvpSjU5E9g9u2qSlHRpL+5dUGbQBrjakbgko5RzuEE2kAl83Q
NFpdjNw5z5W3H3RGr+nsAQtWdqJ0Z5puZPLJyLuv2T5.k2NGQUqKDYXPP5qf
StMjof92UXVb+HBvegWP3mOAHWQdjojq5qlOve2GBNN2L5bATQDILUdvw+Lq
vM5QGf+O2sIXc9JZnqnk4tX3ZMFqGZS5.6zYfM57YMG32Wl+.42NtsN7EqMD
bUAOE9jywx6UdIwAebUR7.jVN+.sthX97IRx2oXxgxALGXfeLZs+tgPWdh7w
8x1l5LLbVPN8SjXGBDmEHtTUo0N.WmzxpFtLif+qCVkzOb9EKi0q0CUhjGkV
N9lUQa8OUohmr7fiI7Rh0+L2zdu06lgPz0GwYWdTquU4u9M8xIsZhIAnOlnb
Frv8sQ2o8Pd.axXNivgVE8DLz3IOoRlYu.8l5WdnGIB+BXq5W8duutBWmHGX
GjGCfqnSLRXsW78OKTOC7d1Vug3D7IlunSHcGMDcNRlrPdV1fyxKrv.GSPvs
gcvuNYwqaxBr8bEut+Hcj.Bx28.lhudzolX1a13qzRYOOGeSTz8Ka0QAZq4t
r0bX.bh.+XJfq7hoKTztC0+EocNZufv6GfjTlZsBDYl3fY.kjvtS1RODgVaX
eb6odJ2SEw8Nde0qwzU.sBK3wjqZtEb9WAcjG7oE96DjEn9sJOCpgdzkkz6s
94+q5477iACS2nMGqetHUNdg.II8X4YFRmouhKb73KvxLbhlIr+.k0zu9ev6
irbCR6SP.pnnyw7Th5VEfVZaFTRgdORy7jibJ0oT5g6JDDlhjE0hq0ZLa6qU
5RGsC7mVx8GYS6EYG4tpupCAqbg9DU+zZe0YxHnwTjbUN09SQTtK1z2.em6b
rOagxx1vm9lM68yO7W5sXJLjmdHyNJvUNahYSWDwQeHbPqhyqxB6p3a+j2vV
D.jjZOldbNFir73Hnxhw4aQ7hXe+AtJL6BYwzFxz9DLeKfWojrGl3Mnkff.X
LaD4Y.0BvrkvjPIc9VG+r+5AsF3YldCy7ZFjp4ctVC+l+lMQeXXaEHp8Lyx0
icgmlNI3ITWNH2lVC+btPQeIuPMoZ8EQaFHYYVXYoJKio1S2bdSJlzEw18wa
cOkHUbng.r1shn.lzvagDTFRziCDJOq9GHPpRznQFuVB4rHZI1ekev6c+DPT
GcZVbcNt..4qBjocAXciVSFdh6hcR.1XXlHJcBxTcx7zRcSwfJmEsy67CWu6
wnV4iaXSqbiFqfH.GB317rSX.YZEJxgyB8Zh21SLx+uzKIZwK0QgY4jCi6R7
uc+lMI8JgwkKVEAkBsY7hg4XaMQxTRF55.AnqcXt4iyxb2TG1wrxTYVV7CZs
iDbg0dQbFGFFIwRwHEpqKTbm+tGm0K4GzQg8SmHi42EDm7oEe+cQKcHMA.89
iIhK3zsEknrzbT6rMC8ntKKhJwLmRn.TJAVmb.5VYbpJc..CSKGqguYj9cb3
KX4Nu26u9ZkkyJb10dIIwA2rOw1pCxg808NgUwAaOD5nrGxx0A2oI9J7d2sI
5FuMoobMauN6xId2YaRuK+piAWx7WKsh4YlqO+ZggVlT.0Nu33PaGvmVyrmt
xjBn9t2aGSHfhsDZ7QfowNdeMsK6dttOzDkS+9x5owpcw3iQRs9AnGwLoMH3
pHjzAOEnQDBn5JVbnOfOcKJ0GpkEjRprYBqT2BBCOgEDc5WPAsQxRorF2gPh
SXAQFsETw.0ebAozSprBjRZit6vfvgTcUwEkak1txHVKSn.V6BFMtKXITJvs
QWBgMtfEjQcAS4ywBlfXHXazsnYaGlxFsEbgwzvw06+yh1VprzIsfRedUVTo
l68TVp4m0.EGZejQa41oByzklTNO5KIyi9xF1ki8BWG8vBZ1PUoELBTpG1RG
+0bDZ33Sktt4Ma3TSaucwCd26+sQwa2u66NNA3pc.HXW5.9U10Lv9iwWcHZT
4ogXP85oxCc9wksH81fM9ZiySsH8v.WXo21s4d6BtPnPR+g0XawSydqfP6ak
MwFVF6+9fC2OM6c8hWocVYUx9Xq8rejcbfPs7gn0JSc2GjqqukYit8rEqsCd
21TGuVlKOoKyMjW31LXSLSgdHBavzFSYO1KxtQYd8p68WmejbrLZqeXP3Vcs
eDlj0hyxtbpaUWm2qDy1XMW+fyg0dwiM6r3b0m7x6hCVGEpAhB6E52Nm+jlQ
6i9uGWLlOQn21ZtYqOIMbwcl1r1Mdw5spTgFnLGLzC87BWJ6913eaR5k2FDF
VBKlDss4KFqCATyW9lH0EensuayU1c89P6UuVQUjbs1+qheNuMaR4eK90+Qu
vfG7R70ChPyxEjcQqfy2obQKZylBqW6UdeMWYshJek+GBVm7N6gAH29cO706
nybE5Udkdq82jxEech+Ca2nVEE+.5yd+tjcuK5C6J41XdDPScfuAOWltY+s2
5G+49NHqDLrcZ5XGJeXxPGtZYSeo1mvZD5xy7DTqLByQDE0XYrPLW3IvYelN
tMt6wJmDBL98gj1HVLgiwwy9T60nMvIhkCniKloszjNvFg.jYPnRUK97CbJS
P.mio1H5RenM5BmDDH.MhEchwpoYbFd4EwLqTy9rvMLQJ8jd8l2gN8gHGhoS
+7pjLKiqxdL2q627a9fTHNuJkDjKlw4eM8QgRLEtwhSPSrRL7iAcXDoHO1X5
zgQtbTgwnl3wioryhFL1WBJv3VejqEGND8W7GYpuNPKoQGmCsWhKUkWgQwO3
sQgFW6nDHNnF8WRx7o+R93P8kcv3RPfIV8kf+nP+k.jGcLc5uDhKHEXXoMJE
jyhBLg7KAMXLIuQj3PzfIAO1TgkRMAwmGUXR3kpNrcIdgq8hW6hVrT4PLQUp
IDXN0hgdTnFCCM3DLGqmu649EOoJ0nyjaHCSzDlZhSOEHJjOWLmLLQSTz4Vz
jMwt+rIo1uNpaLARJsGgwC+XpEIkG74QK1CLLBNcTMMKgBVF98ar1caHOvMk
K3R2dc4Dtg7B2btg6N+vMki3RmkyNyUbo7EaONQPajx4LiE+LjnbAAWWFicH
qwtj43NydriYPtkrH6Vlj6HaxclQ4NypbGYVt6rK2YFlcHKytjo49js4Vx3b
mYct8LO2d1maOCzslE5lxDc8YitgLR6TVocLyz0mc5xxYJKkux06RZeQI96+
2A4N8Rs5YqwyEo477XOwrkEl2tUSsa4zg+M+oZp1nXur5yqFiDJ1rAJntbhQ
n+eznSvUNiPQ1yWtyXTXWXTqMnsgCIhKcj3+dyh6TtIs0Arn8.zggVSxfNhE
QcgEqXDeEjH9RGI97EPyYsqGzhVC.nxYjVDcoiFSOhmVboynRn8fOJwiEprK
AiX9kNhTqpA0GTn0WpymtF74WYSodxTGXLRtnrhACmlqRXFqv8JaECAJcwCk
yRYiiLeqgq8+XIOZlLzZ4tCTWZWX3dgXAMiwnfVwXvwFiUzuFcgB1g0k0Mej
qAcVYNISjkmSxGr9ttYkbwQkbu1oOY.TzC.Tqce9gPbOfPJ3b.gn9fCEmAHD
y6CDhNGPHr7PW+RiNDC6AN7.BeVgvdAfcKrI2EyGDstpo4xQP7jhzP603bc0
4bwEvDmrf06eXaWAAlYJH35yUfb5h564NUAIKzHmE2nHtLME3tPS3zRgx5pE
zkDASZCyX2ZJZN6SWXaPwMep2Xm87O4DxBQaN+Szo6LAReLbnJfBwU7F43lt
yXA9B5PBd.GPU7QbzweYR3rbHKvW7my8bGy.ibJmNs2oXUBqz4kS2wSP.9Ux
7+nav4CQ.V1QOnsDlia97ZPlojh5c+Bu0q2pyG5hfriePWGDLPiBvfSnDLj7
beZMVEsOLwg5TQXOfbhqJfdzcUbaNFFBkUppvC+W4.8T.g07AGiNOHrMA6Rt
ceXn+lNUJZ6L.BzU4OCKTcGSixFJIkFLZFKwN6GMAe+6+rqLeoXp5otvCESU
Mp1EPUzyMGXhxlzMtw+UaCn.R.k6.E8U+4AaRaFKQtTJ8zCjTK9a67dX6tRg
nt1CSFhaqt95NmKbz7TTpm8yJTSmJu0GaHDcDsZnr3gwyzk0oyYIQMK3vxwv
uEmC0Av27yARplB5beDW0Q8Z1r9OPglTXsAhtlfPOBXrJgmuVTFEX8.PhLd.
HvoHMcur0IrVS0nYK1PAGJJ4XGqnRr3+OeUagEK+TusR3v.kiGVSwcmVLVXs
tW0an.dQ.EDWgBzTCEPWfB7TBEZDMxEnfLgPg9HO6DTHgSIT.cbGQBlZnvEp
SgbJgBG2PDSHLHDNhIjSIepfeQ.ENRZxmXXvEDAaBgApyxtmRfvUVTzTJzjd
AfIbc2XJEUoyWgS7FT3TCEtHwTaMs9CNcPA1EnnxFWT7ZakO.lNH6bSt5L5A
1L5ANMP1k.2L9RP3pNZ9NwHQQSMT3Bp.O4PgS9HflTIrW.R4QxK.ZSjql.Yf
V3TAEtJJEMkdQibUXARL0PgKbHnozpTnyDF3IELbTxItY+WOF7ISkL0PzmNV
Xc6WGD8FSorc8q7C269rTYzFW054pAzNe30SYa6jKUOjYokOCckltp4lemYC
vbhdBohG2QL+itwV8K2ux6DmSJ+zV+vEuwKb2h23+PvM5I1UA5w5lEoYC+lr
QV3gQDbGycdIf.41Y6jjRRGNWDjja1JorNGAObAiY+vB.THruRAEHTGifGBm
Bwoi4ZrHcfWSg.lz0QIOGo9vB6T4hirTbB..R5wHhAkMmoQYjxHyHfbplLwm
D8e4YZ7AdsiCUNQ8.cYtN2GINOBY5dkWxiy4pzq+5jqMeMfSTlgs3r6RLQOl
GRUDSbX5KV8UsOnsRmYSZYIGFDcf7i54SaJs25T8rHznOFjkmT75A.FmSs3B
EODG+kI2dut0Gcr6+5a+6mH6xO7o0wQ24G9VyFXGbMT.mQri1KJ1NpYgPDD0
sxUndTLXuANgIkouBHca51QXPHvZRkDwHoCwQnfK5foCpMhyp.WyoYTpwOXN
W6rOBmF7YHsYh14gIBRYVSOzDXnzAe1kHej6FI8mKSUMGHffUmHqzK7C8euW
mLQjTY908pN3hDXoc9+odQptD8aQwcYfYOdjigpGoSrNs9ENBtzA6OZaPj6k
2pRslt5qFDixLyK7M4m9RcxQT05BQFFDj9poenhlB5eWgtzyiH.+EdAge9Df
bE4QlRtpuZ9.+ceHPwuexSpYXp7fi+YVgaziN.+eZGP1m3jGtUwv0ZLVOzlz
A1oy.az4yZNvuuz24IEesil41PvUE7T3SNGKuW4kDG7wUIwCPZ47Cz5he5ym
HIemhIGJGvbfA9wn096FBc4IxG2KaapyvvYA4zOQhcHPbVf3REgX6.bcRKqZ
3xLB9uNXUR+v4WrLVuV2UISdTZ43aVEs0+TkJdxxCNlvKIV+ybS68VuaFBQW
eDmc4Qs9Vk+52zKmzpIlDf9XhxYvB22Fcm1C4ArIi4LBGZUzSvPim7jJYl8B
zape4gdjH7Kfspe06892FE+vD4.6f7X.bEchQBq8hu+Yg5Ng6yLA8Z.7jmT9
hNgzczPz4HYxB4YYCNKuvBCbLAA2F1A+5jEutIKv1yU759izN5C.jqHCmhud
zolX1a13qzRYOOGeSTz8Ka0QAZq4tr0bX.bh.+XJfq7hoKTztC0+EocNZufv
6GfjTlZsBDYl3fY.kjvtS1RODgVaXeb6odJ2SEw8Nde0qwzU.sBK3wjqZtEb
9WAcjG7oE96DjEn9sJOCpgdzkkz6s94+q5gFwiACS2nMGqetHUNdg.II8X4I
kXAO8UbgiGeAVlgSzLg8Gnrl90+CdejUXRbzaAnhhNGySIpaU.ZosYPIE58H
MySNxoT+RnGtqPPXJRVTKtVqwrsuVowt0NveZI2ejMsWjcj6p9pNDrxE5ST8
Sq8UmIifFSQxU4T6OEQ4VYQeC7ctyw9rEJKaSe4a1r2OeGRo2hovPd5gL6n.
W4rIlMcQDG8gvAsJNuJKrqhu8SdCaQ.PRp8X5w4XLxxiifPHd9VDuH12efqB
ytPVLsgLsOAy2B3UJI6gIdCZIHH.FyFQdFPs.LaILITRmu0wO6udPqAdlo2v
LulAoZdmq0vu4uYSzGF1VAhZOyrbcmgyrHnJtDpKGjapd7aNmKTzWxKTSpVe
QzlARVlEVVpxxXp8zMm2jhIcQrce7V2SIREGZH.qcqHJfIM7VHAkgD83.gxy
p+ABjpDMZjwqkPNKhVh8W4G7d2OAD0QmlEWmiK.P9p.YZW.V2n0jgm3tXmDf
MFlIhRmfLUmLOsT2TLnxYQ67N+v06dLpU93F1zJ2nwJHBvg.tMO6DFPlVghb
3rPul3s8Di7+K8RhV7RcTXVN4v3tD+a2uYSRuRXb4hUQPoPaFuXXN1VSjLfs
ca15FDApbAw3.Rl6l5vNlUlJyxhePqcjfKr1Khy3vvHIVJFoPccgh6ziJiGi
0K4GzQg8SmHi42EDm7oEe+cQKcHMA.89iIhK3zsEc6vzliZmsYnG0cYQTotc
k5PBEfRIv5jihckjdJrX..FlVNVCeyH863vWPWyrkTreiypk5lSKcLiVJOeV
rAWx7WKsh4Ylq0mZgg1FID0OOxqsONiMsyZFAmNFDR6M+Zrd0YQd8sM1VZu7
E5KpvCiXvZl8CizxM2zuntUqcnJV+hELxKVwnsXKLPKpcSTxsCdaVZ6JOsgH
qqtSZWqKTiqqxsP5hqO4Q.pwgWQMME49t1y2.ocmrFQoMhQ5jrFTyxEAVNwK
obyaiNYZS2uQD6vg.Y585Bo1z+ZFND027qaYdZT6FNBVKF.OhapKdv6d+2pD
e9cG6A3MyFqaby1N1bJartr2kzSXyExpeyMOD3GWVEvsAa70ZCSUAbn0Nuza
61bucAc1JzveX0tIdZ1aEDZeqrdCsxYX8fc2d+zr20Kdk15fUI6isJP9H6XS
ve4CQJmYB2GjqKzkoTzdX9zJd1sM0Rmk4RLwxbcVcocFSQz+ifa9+Xh70Nsx
ByMQqtu3ndeodJ1GDtUeTqCSx5nPYWN0JlqyaDfN7P0c8C1hU6EO1aghyUNf
KuKNXcTnFHJrSne6bluYHMz+83hw7IB81VyMaMAngKtyzUitwKVuQkJyCkoO
2Ny6ycor6ai+sIoWdaPXXIrXRz1luXr1iqlu7MQpK9Pae2lqr658g1qdshlH
4Zs4NE+bda1jxeV7q+idgAO3k3qaT+lkKH6hV49uSYQTzlMEVu1q79ZtxZEM
9J+ODrN4c1buka+tGlVcz1oBslpRu09aR4guNw+gsaTqhhe.8QccWxt2E8gc
krRKOBnoFd0XNVpXP6bHGTyHZY5mJUP3E+XoxkwPEBJaDKhcY9ZzTm8GhWd4
LUtbZfbYomHLYgAYisuv3zXjB6zD3pYBJxrLMaZah34BdBCI0Nts3NRvbZCa
Kx4dDTZs35mMSn9WG4.ikTZc0O8GpIVk0NGaPvICs4130njUakOhKMX8VSVv
U51qyRtFrlqYK551ptlrrqTHO5zBuRV4ILD6Pjz5ijYh4vPhxmal5rzyAq8b
whuNs5yQK+Zw5O2r.rCq.6zRvNsFrCKB61pvNsLzAqCcwBw9XkXKVJ1o0hsa
wX6VM1tkisZ8XSVPVuUjMXIoSVS5nEk0aUYY4LkExW45cIrun.+8+6.kcjfx
WuwYrkcTJR30IKuciEpWl9gYqU9YNbkuyFlvVsnkr3Yx6IsOzvGUD5+GM5Db
kyHTDG1KLJrKLZ0gIXEqLDW5Hw+8lE2oLrcqCXQtIb0XH1ZfuiXQTWXwJFwV
AIhuzQhOWOZv6Gsn0..pbFoEQW5nwXiwvo3RmQkPaHIqe1fdJnxtDLh4W5HR
spFTePgVGsNe5ZvmekMkG0isiwHYCovpipvSglqRngpv8JaECAJcwFFvg1u0
JC4vIDsVYdP1g1EFtWHVPyXLJnULFbrwXE8qoxHhrJhrtoHPMnypy1oJSbiC
Ve28T2nW6zmL.J5A.RvmCHD2CHjBNGPHpO3PwY.Bw79.gnyADVYtQdoQGhg8
.Gh4mAHrW.X2Baxcw7AQqqi9S4HHdRQZn8iBTcGGnx0a1jFq706eXaWw.lQz
S28ZCUtbxh4KFdtiUdxBMxYwMJhKSsy61D4V4GgAm.cI4cj1PM1slhly9zE1
53u4LLLOIrpMRJmPVHZioegNcoeYdx+RaHmbmWsFSgmPXlS40hb.SGxgd1SN
k28K7VudqNuTKBVnOSuqOdtfZ20n5PVo46XZvVhYIMmsfsVEsOLo6yW.vjrG
LRTHev553zFp2gHgJUhzg+qr+1M5IYQ7EcdvWaB1kb69vP+McJaRp02gDnZN
RFrgRQoAiFwRE7d77bZK78u+ytx5khopi3RHFJhpZrEKfovma9uDkkAabi6S
aZfDj6WS+Nf.LjYC338bvxflwRzyM8zM6u8V+3iTTK9a67dX6tRAJrNbGAYB
LX8G1.FanGMJK4UWmOJJ6bi.ucy9f0WoQc67Sr3wqbVqHAJuJuHLrtcOAcxH
BrKDdYHwlQf7YAAVNNpsXftxmEygGlmxLxPME4u9HspiSYWy7gfBETUsQCrl
HAV6L5rRz+N8YGpqiWW5TNSY0zNNMASMG5roCLntNQ4ASMT3xVBYJm6xTWGD
1T7DBEDWIOMgnbpF7xDWmxuT9ThKnWDPA4h.JvNxoJmZf3x.Uf6ATjW4V7Z6
wnDdlAMVyfFX5.MjqBYQS0d2k.AT0jDbNfBikStIpGOofgqCVdSECLwvAvI3
.0xTc+KhJftghJrCGlZoJgEhp0NJryxDtwpqrYmjJ5a.bzJzzlJR5ODGj3u3
4+xN+3cO+miVGGbWzy+N+c2mDs842FzZc0x31CoCpfijlRyGx4iZITKoSd4h
qVrIwdg6zS3fE5iprxiocWEp9+71D7u8We78h8WueU1fCqYpFhMSFHw3VN4L
33UM4swmrck2mW72TOi05EtthEzwlo6Uc8zCrSkWwDUzN4UXiWMYWneB2RIG
STKFyOl1G.GiUxDPlpoP+29tU2X00mcLIm1hquerEl30k8+sKwKbsW7ZMaRm
3MHEWMhm1tw53wiflbdDaw2kG6z4JGQnECFtIST.9PZJC0u5AyiDhb66et68
corZRSf.7zJW3XqoXvbHGBAWYbA7JSkys3V8eVEEuc+tE4spv1Ia1aCd2gMy
BkwzO3u489IAqZyPDnohoVPw1yGqzVJmc1ZCxWOUv55jCKy8AOTcTnr5nY1j
lxxDbNxhOwhAI9z7UVL7o1UcY6ySW6UCWZAuTZvjbVtvCVA+55Sh6vCBxKDB
hR9yOwOZTdGkJ4u9I+nYv4B+xbYQxfSxhzkGMcR1ZKdtOazkR1HffIN7jPiv
yAKbYIgGCZF7LsjPtvE.kiwSB3vSBOFOn7waq6CS9I+bfRGdPnwfX.Jvy0tD
T3DaqXbVVNQ7wGmmEvYUMC9YwcZ6hCOFu2A7rPN+rfC9Y419kbzdVvNeVhQ6
Y0oHCNeTdVNQGJFG5PfS3vQQXHS5xyhIFsmUm3Px3rtDNPaHFE1KlvATHkOZ
OptvflbkM7GkSBMXiBiLE67yZvBdIDmMqevDgD2VWihA.Dm1uHjw3YgcQXHZ
TPgHmzmLNlq4lQ0ii8ZPm7IANJ3PHeFeVNoSdbnMbIP.UeP1H7TpMOoeFkZq
SkZmSUaiSM29lJ21lLoW01RYJEUoic1n8qChdioWBc8qxFS3kZA3oXhZFhaG
RLa8iPyxyOMhh7yz8u0S8S6jTSOz6n4yqcoI8VtYIV1vTknmVa3hi61Sb7YV
+bZq4YzVCymsCIO9ooDR00LvK1HvyS3ksY7x8GBMa8a.k585+zV+zYg7a7eH
3F8T.IirrtYaVyCN3bnjxcyeIfnLQ2NwtojzA8AAI4T6bEO69pqU9yELl8CJ
.Pgv9J0SGUbVrWZhHxoPb5nxDKRGZlTHfUBPquGyyQpOnvNUO3HKUh..fEG1
jM2d4QYynxiypbT0Y1qSLCkmjgm17DrxrOzsgJbINBGaa9WVLDuxKIoKFhZl
iBMNCEFL.85uN4ZysA5Aeps6w0FqoaaNUYMOL8jp9pF4tjoyaAMu6ggHCH+X
ZrKFjllym0LItNBAkF7yoyyUoRdB0ttUzxb7iaNLmusKJVre8s+8dPJ+CeZc
bzc9gu0rAzBEMEvYD6nyfhsixMnx7KT6JafLb532DxILoL8UfR2UcpZHLHDX
MOPhXjzgiDTvEsvLbb7iS0b.Fg87CljzLocttVYCCQDj1DG6rkBAoLqZWMQA
JcHhbtowcyXfuLLqxjj3fU8fL+E9g9u2qUB7Ci115dUKT3BrjeXVXmJGV+VT
baFD43iZnhrkcRV23WzI5Z.renkSlbr7VPpEdUe0IQDOAzpeStSyP8TrU0lJ
xvFfzWAGM6dRAquKqM3dAATuvKH7yNBUpsqLA8Ue03CZ69PfhOpMfqhnkRS8
9oBlPWT.0+zNXDaO5CtIJpViCbTBZGq3Vc7rymwXhud4gC.Y83pZGqdMgvpx
zV3SMlfsxet3fOtJItmRQlN.ReNs9bOH65T7wPnBGyU1OFs9vjs0cZjSfOwY
8o0Yrwntf6VDRGBPFUnI2jWodfoNoHUUZNAf1qCVkzMt5rS.+Zcq9O4hyZi2
rJZqeejXbR7TGC1sLaFpNEzBu06l9RD3J694ix4sJ+ftoSCnaZrP6hJxIzRn
2laz659lxg4iqVYDACMdBQJjgjynUv+xCcjXoYD89qdu2WWDEinCCmrUgfqn
izhasW78OKTONNdlww8dR226XB2yPd1PzDHYxO3YYZIKmKByyeDBTFrCdjQO
9BidPxFy3K7Go0CK.jV4RiwWEpOIC4lM9JIy17V9MQQ2urQCDoMl+fVieInS
BuioaoxKFuPZ4FD9mBRtfv66oDIldtsKxTGi0SKbR6AV0QQQ05Zb2Os994qH
pzg6odMHt.bUXONlXCyGGm+UPG3OdZg+NBQ508UyLJ19hJKE2a8I6W0Gsmys
wRazlRzsIzkiMBPRROtFRIVvSeEW3P56XYJ9oYBIOryOdqqG79HKaD04rvHQ
Qmc3oDUMJLpz1BHmhrdjhlQaAmqwz4f4tDDlhjE0VokrN56CEJD75Ar9mPqQ
vLQQ1Qvn5qZQnCWnOUZOs1WMiJtGhnphbGtsKleLm3ZP2xcl9F8P.Xqi7uYy
d+CywMmYywPd5gO3nvH4nKBJE.ii9PXugv4QHoEB+1O40e.DfjT6QufywXjk
2AAgP73CfuH12+DfPC1KKlZPl1twwG3dkRxVXhWuAOAAvX1n8w.JfyfJYRnj
N9v3O6ut2vGOyDLXlWMfTMFiM78a9a1D8g9iBQT64Mhqa8EF.jpnJoccX0nR
.PLEK.ziwEfI8EuHZyIPhjEBIpxhIp8zbkWk1n.fa2Gus8vjVw3TBvZWChBX
RCMLRPYHgiGhFd1Yrj.oJwFFYaZoGiJqYr+J+f22dl6pilIym2i.GH+IHcb.
NqKJZxhdf46jfnVWrIJ4fxT8G7zicthIPNpZR14Gtd2klFjiH4wm2q1SDLfC
AbatlHLfL8D9ygiJsSh21dDkvW5kDs3kZuPWNZO+cI92teyljNSvR4CkpfRg
1nSyvbrs1.X.aWfuQjJApLmzXLYlI95PejcbTG0EUuWSHAWXsy.mQIiQRrTL
BtpeFwG5l.4kT8B7Aczb9TOH7+tf3jOs36uKZYGgEDnwmFuLwonQE6eZdbbR
eli0bPQTCl0YvCgRIvZ3phEgjlMdF.fgoG849iXskNmICdZT0tsoaglVB0W8
+9U++AWAS+YA
-----------end_max5_patcher-----------

What about reduction to 2 dims? I would try this myself, but your patch makes it very clear that I shouldn’t do that.

I’ll try some more aggressive reduction. I was just going with a roughly 25% (well, 10% here) suggestion that @jamesbradbury made. It’s kind of shooting in the dark though.

I do remember you getting kind of funky results where the first few dimensions kind of did the heavy lifting and the petered out from there. Some way to validate the compression (or however that would work) to see how many (few) dimensions is “good enough”.

For my purposes a 2d plane isn’t necessary at all, so as long as it’s less than “all”, it will all be gaining speed back in querying.

Hehe, I couldn’t be bothered to tidy up the guts of those subpatches since most of that is workarounds for a current bug.

My understanding of that thread was that 2 dims is all you need. Maybe 1 dim is all you need, but we humans like to see 2. Reminds me of that Star Trek TNG episode with the 2 dimensional lifeforms.

1 Like

Ran a quick test and running it with 2d (vs 20) is a tiiny amount faster. On my (faster) laptop, I get 0.37ms for the real-time transform on 20d space and 0.35ms for the same but going down to a 2d space.

I’m curious to see how far down I can push it. I’m aiming for keeping as much accuracy as possible since it will make a bit part of how I actually query the corpus space (pseudo-predictive matching). If that can be 2d, even better!

I may very well do something where I make a whole bunch of 2d reductions (e.g. 2d “loudness” space, 2d "spectral space, etc…), and then concatenate them into a manually curated dimensionality reduced space, for the final matching step. But mucho experiments to try before I get it there.

OK. Thinking through again, I guess a point could be closer to one object in a 3D space and a different object in a 2D space. But I can’t imagine this will be the deciding factor of how convincing something is in a real-time context.

Yeah. It’s weird to think about.

Now that I have this bit of patch working, my next step is to wrap it around the actual querying and iteration and tally up the numbers. Having a 96d space (12 MFCCs + a few stats) gave me around 70% accuracy, so I’ll try varying amounts of reduction to see where the diminishing returns are.

I also need to experiment with the front end of that, where i can use more MFCCs/stats, but working with a baseline of 70% matching, I can see the impact the reduction has on its own, and (hopefully/presumably) extrapolate that out to try to get better matching in the descriptor-space part of the equation.

Early morning tests not promising.

I decided to go balls out and smash everything down to 2d (via fluid.pca~) and try matching based on that.

I also used your pipeline of [data] -> fluid.standardize~ -> fluid.pca~ -> fluid.normalize~.

Pre PCA I was getting around 67% accuracy. With a 2d version of the same data I get around 25% accuracy… (plus some new error messages to boot)

I’ll try some milder reduction to see how that fares, but in this context, that much smashing is definitely “lossy”.

Bringing that up to 6d pulls the accuracy up to 44%.

I initially tried 20d, since that’s more in line with the 25%, but after some terrible matching I noticed that most of my dimensions were filled with nans. Don’t know if it’s the standardize/normalize-part of the process, but after around 7d (down from 96) I started getting numbers with e13 on the end of them, and the next dimension started nan-ing.

So presumably efficacy has dropped off by that point, but it’s crazy that it got so nan-ny so quickly.

So short of trying some other data sanitization routine, or if there’s something weird going on with the nan stuff, the dimensionality reduction in this context comes at too big an accuracy loss.

Aaand tested everything again with 20 MFCCs as per @groma’s suggestion on Slack. (well, 19 since I’m omitting the 0th coefficient).

The overall matching accuracy went up to 75% for the large dimensional space (152d), but bringing those 152 dimensions down to 6d made things worse. My accuracy dropped to 40%.

I tried upping the amount of dimensions, but if I go above 8d (with fluid.pca~ on a 152d space) I start getting crazy values (scientific notation entries).

So testing 152d -> 8d with the original 20MFCCs + stats approach gives me an accuracy of 46%, which is an improvement, but still a far cry from 75%.

This all sounds super interesting. Can we have a session on this topic over the weekend?

1 Like

I’m totally down for that.

Sadly we didn’t end up doing a break out session, but I wanted transfer a bit of the discussion over from Slack where @a.harker was getting some slow querying out of fluid.mlpregressor~ when being used as an auto-encoder.

I did some testing myself and found that:

I get around 28ms per predictpoint query. This is using the same settings that are in 8c, trained on a 19d -> 2d space with just 10 entries. I got the error rate down to 0.02 before testing this.

So this is a bit of a broader question in terms of where an auto-encoder falls in the overall scheme of things with regards to speed.

Based on some of the discussions in the thread about transformpoint and fluid.mds~, where it became clear that that’s not possible given the algorithm, with @weefuzzy then mentioning that:

https://discourse.flucoma.org/t/transformpoint-for-fluid-mds/575/11

I’m wondering about doing something like PCA->NN to get something from a ~200d space down to 2d, by taking a huge chunk down with PCA and then getting the last bits with fluid.mlpregressor~.

At the moment even going from 19d -> 2d with fluid.mlpregressor~ is “really slow” (~28ms per predictpoint as mentioned above, with a tiny data set).

When @tremblap first presented fluid.mlpregressor~ a few weeks ago during the Friday geek out sessions, he said that mlp stuff takes a long to compute, but once it’s computed, running data through it is really fast since it’s just simple multiplications.

I don’t know if that holds true for predictpoint as well, and there’s either a bug and/or it’s not optimized at all (particularly since it’s fairly fresh research-ish code) or if predictpoint is an altogether more complex operation that will never be as fast as simply running values through the NN once computed.