@@ -275,7 +275,7 @@ private Quantizer quantizer(@Nullable final AccessInfo accessInfo) {
275275 final EntryNodeReference entryNodeReference = accessInfo .getEntryNodeReference ();
276276
277277 final AffineOperator storageTransform = storageTransform (accessInfo );
278- final RealVector transformedQueryVector = storageTransform .invertedApply (queryVector );
278+ final RealVector transformedQueryVector = storageTransform .apply (queryVector );
279279 final Quantizer quantizer = quantizer (accessInfo );
280280 final Estimator estimator = quantizer .estimator ();
281281
@@ -356,7 +356,7 @@ private Quantizer quantizer(@Nullable final AccessInfo accessInfo) {
356356 Objects .requireNonNull (nodeReferenceAndNode ).getNodeReferenceWithDistance ();
357357 final AbstractNode <N > node = nodeReferenceAndNode .getNode ();
358358 @ Nullable final RealVector reconstructedVector =
359- includeVectors ? storageTransform .apply (node .asCompactNode ().getVector ()) : null ;
359+ includeVectors ? storageTransform .invertedApply (node .asCompactNode ().getVector ()) : null ;
360360
361361 resultBuilder .add (
362362 new ResultEntry (node .getPrimaryKey (),
@@ -789,7 +789,7 @@ public CompletableFuture<Void> insert(@Nonnull final Transaction transaction, @N
789789 .thenCompose (accessInfo -> {
790790 final AccessInfo currentAccessInfo ;
791791 final AffineOperator storageTransform = storageTransform (accessInfo );
792- final RealVector transformedNewVector = storageTransform .invertedApply (newVector );
792+ final RealVector transformedNewVector = storageTransform .apply (newVector );
793793 final Quantizer quantizer = quantizer (accessInfo );
794794 final Estimator estimator = quantizer .estimator ();
795795
@@ -826,7 +826,7 @@ public CompletableFuture<Void> insert(@Nonnull final Transaction transaction, @N
826826 currentAccessInfo = accessInfo ;
827827 }
828828 }
829-
829+
830830 final EntryNodeReference entryNodeReference = accessInfo .getEntryNodeReference ();
831831 final int lMax = entryNodeReference .getLayer ();
832832 if (logger .isTraceEnabled ()) {
@@ -849,14 +849,30 @@ public CompletableFuture<Void> insert(@Nonnull final Transaction transaction, @N
849849 insertIntoLayers (transaction , storageTransform , quantizer , newPrimaryKey ,
850850 transformedNewVector , nodeReference , lMax , insertionLayer ))
851851 .thenCompose (ignored ->
852- addToStats (transaction , currentAccessInfo , transformedNewVector ));
852+ addToStatsIfNecessary (transaction , currentAccessInfo , transformedNewVector ));
853853 }).thenCompose (ignored -> AsyncUtil .DONE );
854854 }
855855
856+ /**
857+ * Method to keep stats if necessary. Stats need to be kept and maintained when the client would like to use
858+ * e.g. RaBitQ as RaBitQ needs a stable somewhat correct centroid in order to function properly.
859+ * <p>
860+ * Specifically for RaBitQ, we add vectors to a set of sampled vectors in a designated subspace of the HNSW
861+ * structure. The parameter {@link Config#getSampleVectorStatsProbability()} governs when we do sample. Another
862+ * parameter, {@link Config#getMaintainStatsProbability()}, determines how many times we add-up/replace (consume)
863+ * vectors from this sampled-vector space and aggregate them in the typical running count/running sum scheme
864+ * in order to finally compute the centroid if {@link Config#getStatsThreshold()} number of vectors have been
865+ * sampled and aggregated. That centroid is then used to update the access info.
866+ *
867+ * @param transaction the transaction
868+ * @param currentAccessInfo this current access info that was fetched as part of an insert
869+ * @param transformedNewVector the new vector (in the transformed coordinate system) that may be added
870+ * @return a future that returns {@code null} when completed
871+ */
856872 @ Nonnull
857- private CompletableFuture <Void > addToStats (@ Nonnull final Transaction transaction ,
858- @ Nonnull final AccessInfo currentAccessInfo ,
859- @ Nonnull final RealVector transformedNewVector ) {
873+ private CompletableFuture <Void > addToStatsIfNecessary (@ Nonnull final Transaction transaction ,
874+ @ Nonnull final AccessInfo currentAccessInfo ,
875+ @ Nonnull final RealVector transformedNewVector ) {
860876 if (getConfig ().isUseRaBitQ () && !currentAccessInfo .canUseRaBitQ ()) {
861877 if (shouldSampleVector ()) {
862878 StorageAdapter .appendSampledVector (transaction , getSubspace (),
@@ -885,12 +901,12 @@ private CompletableFuture<Void> addToStats(@Nonnull final Transaction transactio
885901 new FhtKacRotator (rotatorSeed , getConfig ().getNumDimensions (), 10 );
886902
887903 final RealVector centroid =
888- partialVector .multiply (1.0d / partialCount );
889- final RealVector transformedCentroid = rotator .invertedApply (centroid );
904+ partialVector .multiply (- 1.0d / partialCount );
905+ final RealVector transformedCentroid = rotator .apply (centroid );
890906
891907 final var transformedEntryNodeVector =
892- rotator .invertedApply (currentAccessInfo .getEntryNodeReference ()
893- .getVector ()).subtract (transformedCentroid );
908+ rotator .apply (currentAccessInfo .getEntryNodeReference ()
909+ .getVector ()).add (transformedCentroid );
894910
895911 final AccessInfo newAccessInfo =
896912 new AccessInfo (currentAccessInfo .getEntryNodeReference ().withVector (transformedEntryNodeVector ),
0 commit comments