@nshiab/simple-data-analysis-core 2.0.8 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/class/SDAError.d.ts +6 -6
- package/esm/class/SDAError.js +6 -6
- package/esm/class/Simple.d.ts +9 -9
- package/esm/class/Simple.js +9 -9
- package/esm/class/SimpleDB.d.ts +80 -76
- package/esm/class/SimpleDB.d.ts.map +1 -1
- package/esm/class/SimpleDB.js +80 -76
- package/esm/class/SimpleTable.d.ts +2805 -1077
- package/esm/class/SimpleTable.d.ts.map +1 -1
- package/esm/class/SimpleTable.js +2777 -1077
- package/esm/helpers/appendColumnBatches.d.ts +3 -0
- package/esm/helpers/appendColumnBatches.d.ts.map +1 -0
- package/esm/helpers/appendColumnBatches.js +21 -0
- package/esm/helpers/buildApproximateMutualReachabilityMst.d.ts +45 -0
- package/esm/helpers/buildApproximateMutualReachabilityMst.d.ts.map +1 -0
- package/esm/helpers/buildApproximateMutualReachabilityMst.js +212 -0
- package/esm/helpers/buildChronologicalGraphComponentsSql.d.ts +14 -0
- package/esm/helpers/buildChronologicalGraphComponentsSql.d.ts.map +1 -0
- package/esm/helpers/buildChronologicalGraphComponentsSql.js +167 -0
- package/esm/helpers/buildExactMutualReachabilityMst.d.ts +28 -0
- package/esm/helpers/buildExactMutualReachabilityMst.d.ts.map +1 -0
- package/esm/helpers/buildExactMutualReachabilityMst.js +97 -0
- package/esm/helpers/buildGraphTemporalCostStateSql.d.ts +12 -0
- package/esm/helpers/buildGraphTemporalCostStateSql.d.ts.map +1 -0
- package/esm/helpers/buildGraphTemporalCostStateSql.js +86 -0
- package/esm/helpers/buildGraphTemporalReachabilitySql.d.ts +13 -0
- package/esm/helpers/buildGraphTemporalReachabilitySql.d.ts.map +1 -0
- package/esm/helpers/buildGraphTemporalReachabilitySql.js +70 -0
- package/esm/helpers/buildSparseMutualReachabilityMst.d.ts +10 -0
- package/esm/helpers/buildSparseMutualReachabilityMst.d.ts.map +1 -0
- package/esm/helpers/buildSparseMutualReachabilityMst.js +47 -0
- package/esm/helpers/buildUmapGraph.d.ts +21 -0
- package/esm/helpers/buildUmapGraph.d.ts.map +1 -0
- package/esm/helpers/buildUmapGraph.js +61 -0
- package/esm/helpers/buildVectorNeighbors.d.ts +45 -0
- package/esm/helpers/buildVectorNeighbors.d.ts.map +1 -0
- package/esm/helpers/buildVectorNeighbors.js +170 -0
- package/esm/helpers/buildWeakGraphComponentsSql.d.ts +3 -0
- package/esm/helpers/buildWeakGraphComponentsSql.d.ts.map +1 -0
- package/esm/helpers/buildWeakGraphComponentsSql.js +32 -0
- package/esm/helpers/cacheDatabase.d.ts.map +1 -1
- package/esm/helpers/cacheDatabase.js +2 -1
- package/esm/helpers/camelCase.d.ts +7 -5
- package/esm/helpers/camelCase.d.ts.map +1 -1
- package/esm/helpers/camelCase.js +7 -5
- package/esm/helpers/capitalize.d.ts +6 -4
- package/esm/helpers/capitalize.d.ts.map +1 -1
- package/esm/helpers/capitalize.js +6 -4
- package/esm/helpers/clusterHdbscan.d.ts +18 -0
- package/esm/helpers/clusterHdbscan.d.ts.map +1 -0
- package/esm/helpers/clusterHdbscan.js +342 -0
- package/esm/helpers/computeCovariance.d.ts +16 -0
- package/esm/helpers/computeCovariance.d.ts.map +1 -0
- package/esm/helpers/computeCovariance.js +99 -0
- package/esm/helpers/computeMahalanobisDistances.d.ts +14 -0
- package/esm/helpers/computeMahalanobisDistances.d.ts.map +1 -0
- package/esm/helpers/computeMahalanobisDistances.js +87 -0
- package/esm/helpers/createDirectory.d.ts +4 -3
- package/esm/helpers/createDirectory.d.ts.map +1 -1
- package/esm/helpers/createDirectory.js +4 -3
- package/esm/helpers/dataToArrays.d.ts +6 -4
- package/esm/helpers/dataToArrays.d.ts.map +1 -1
- package/esm/helpers/dataToArrays.js +6 -4
- package/esm/helpers/extractTypes.d.ts +1 -1
- package/esm/helpers/extractTypes.js +4 -9
- package/esm/helpers/factorCovariance.d.ts +17 -0
- package/esm/helpers/factorCovariance.d.ts.map +1 -0
- package/esm/helpers/factorCovariance.js +189 -0
- package/esm/helpers/findGeoColumn.d.ts +6 -4
- package/esm/helpers/findGeoColumn.d.ts.map +1 -1
- package/esm/helpers/findGeoColumn.js +6 -4
- package/esm/helpers/findGeoColumnFromSchema.d.ts +8 -5
- package/esm/helpers/findGeoColumnFromSchema.d.ts.map +1 -1
- package/esm/helpers/findGeoColumnFromSchema.js +8 -5
- package/esm/helpers/fitUmapCurve.d.ts +2 -0
- package/esm/helpers/fitUmapCurve.d.ts.map +1 -0
- package/esm/helpers/fitUmapCurve.js +66 -0
- package/esm/helpers/formatDate.d.ts +12 -6
- package/esm/helpers/formatDate.d.ts.map +1 -1
- package/esm/helpers/formatDate.js +12 -6
- package/esm/helpers/formatMissingTables.d.ts +8 -5
- package/esm/helpers/formatMissingTables.d.ts.map +1 -1
- package/esm/helpers/formatMissingTables.js +8 -5
- package/esm/helpers/formatNumber.d.ts +19 -10
- package/esm/helpers/formatNumber.d.ts.map +1 -1
- package/esm/helpers/formatNumber.js +32 -17
- package/esm/helpers/getGraphEdgeIdColumn.d.ts +9 -0
- package/esm/helpers/getGraphEdgeIdColumn.d.ts.map +1 -0
- package/esm/helpers/getGraphEdgeIdColumn.js +25 -0
- package/esm/helpers/getGraphEndpointColumns.d.ts +11 -0
- package/esm/helpers/getGraphEndpointColumns.d.ts.map +1 -0
- package/esm/helpers/getGraphEndpointColumns.js +160 -0
- package/esm/helpers/getGraphWeightColumn.d.ts +10 -0
- package/esm/helpers/getGraphWeightColumn.d.ts.map +1 -0
- package/esm/helpers/getGraphWeightColumn.js +40 -0
- package/esm/helpers/graphRouteResultSchema.d.ts +4 -0
- package/esm/helpers/graphRouteResultSchema.d.ts.map +1 -0
- package/esm/helpers/graphRouteResultSchema.js +12 -0
- package/esm/helpers/graphRouteResultSelect.d.ts +4 -0
- package/esm/helpers/graphRouteResultSelect.d.ts.map +1 -0
- package/esm/helpers/graphRouteResultSelect.js +22 -0
- package/esm/helpers/hasGeometryColumn.d.ts +4 -3
- package/esm/helpers/hasGeometryColumn.d.ts.map +1 -1
- package/esm/helpers/hasGeometryColumn.js +4 -3
- package/esm/helpers/initialUmapCoordinates.d.ts +2 -0
- package/esm/helpers/initialUmapCoordinates.d.ts.map +1 -0
- package/esm/helpers/initialUmapCoordinates.js +5 -0
- package/esm/helpers/inspectGraphConnectivity.d.ts +10 -0
- package/esm/helpers/inspectGraphConnectivity.d.ts.map +1 -0
- package/esm/helpers/inspectGraphConnectivity.js +55 -0
- package/esm/helpers/mergeOptions.d.ts +24 -13
- package/esm/helpers/mergeOptions.d.ts.map +1 -1
- package/esm/helpers/mergeOptions.js +24 -13
- package/esm/helpers/optimizeUmapLayout.d.ts +7 -0
- package/esm/helpers/optimizeUmapLayout.d.ts.map +1 -0
- package/esm/helpers/optimizeUmapLayout.js +93 -0
- package/esm/helpers/parseValue.d.ts +6 -4
- package/esm/helpers/parseValue.d.ts.map +1 -1
- package/esm/helpers/parseValue.js +6 -4
- package/esm/helpers/prepareGraphRouteSql.d.ts +31 -0
- package/esm/helpers/prepareGraphRouteSql.d.ts.map +1 -0
- package/esm/helpers/prepareGraphRouteSql.js +86 -0
- package/esm/helpers/prepareGraphStarts.d.ts +9 -0
- package/esm/helpers/prepareGraphStarts.d.ts.map +1 -0
- package/esm/helpers/prepareGraphStarts.js +68 -0
- package/esm/helpers/prepareGraphTemporalSql.d.ts +28 -0
- package/esm/helpers/prepareGraphTemporalSql.d.ts.map +1 -0
- package/esm/helpers/prepareGraphTemporalSql.js +154 -0
- package/esm/helpers/prepareGraphTraversal.d.ts +19 -0
- package/esm/helpers/prepareGraphTraversal.d.ts.map +1 -0
- package/esm/helpers/prepareGraphTraversal.js +79 -0
- package/esm/helpers/prepareNumericFeatures.d.ts +41 -0
- package/esm/helpers/prepareNumericFeatures.d.ts.map +1 -0
- package/esm/helpers/prepareNumericFeatures.js +210 -0
- package/esm/helpers/prepareUmapLayoutOptions.d.ts +14 -0
- package/esm/helpers/prepareUmapLayoutOptions.d.ts.map +1 -0
- package/esm/helpers/prepareUmapLayoutOptions.js +23 -0
- package/esm/helpers/prettyDuration.d.ts +14 -8
- package/esm/helpers/prettyDuration.d.ts.map +1 -1
- package/esm/helpers/prettyDuration.js +14 -8
- package/esm/helpers/printTable.d.ts +18 -13
- package/esm/helpers/printTable.d.ts.map +1 -1
- package/esm/helpers/printTable.js +18 -13
- package/esm/helpers/publishPreparedColumns.d.ts +37 -0
- package/esm/helpers/publishPreparedColumns.d.ts.map +1 -0
- package/esm/helpers/publishPreparedColumns.js +113 -0
- package/esm/helpers/queryDB.d.ts +24 -13
- package/esm/helpers/queryDB.d.ts.map +1 -1
- package/esm/helpers/queryDB.js +24 -13
- package/esm/helpers/queueAsyncBarrier.d.ts +12 -7
- package/esm/helpers/queueAsyncBarrier.d.ts.map +1 -1
- package/esm/helpers/queueAsyncBarrier.js +12 -7
- package/esm/helpers/queueGraphResult.d.ts +18 -0
- package/esm/helpers/queueGraphResult.d.ts.map +1 -0
- package/esm/helpers/queueGraphResult.js +39 -0
- package/esm/helpers/quoteIdentifier.d.ts +4 -3
- package/esm/helpers/quoteIdentifier.d.ts.map +1 -1
- package/esm/helpers/quoteIdentifier.js +4 -3
- package/esm/helpers/quoteQualifiedIdentifier.d.ts +6 -4
- package/esm/helpers/quoteQualifiedIdentifier.d.ts.map +1 -1
- package/esm/helpers/quoteQualifiedIdentifier.js +6 -4
- package/esm/helpers/readScalarNumber.d.ts +3 -0
- package/esm/helpers/readScalarNumber.d.ts.map +1 -0
- package/esm/helpers/readScalarNumber.js +4 -0
- package/esm/helpers/runQuery.d.ts.map +1 -1
- package/esm/helpers/runQuery.js +17 -3
- package/esm/helpers/selectFuzzyReplacements.d.ts +11 -0
- package/esm/helpers/selectFuzzyReplacements.d.ts.map +1 -0
- package/esm/helpers/selectFuzzyReplacements.js +124 -0
- package/esm/helpers/stabilizeCosineVectors.d.ts +14 -0
- package/esm/helpers/stabilizeCosineVectors.d.ts.map +1 -0
- package/esm/helpers/stabilizeCosineVectors.js +34 -0
- package/esm/helpers/stringToArray.d.ts +4 -3
- package/esm/helpers/stringToArray.d.ts.map +1 -1
- package/esm/helpers/stringToArray.js +4 -3
- package/esm/helpers/umapRandom.d.ts +2 -0
- package/esm/helpers/umapRandom.d.ts.map +1 -0
- package/esm/helpers/umapRandom.js +10 -0
- package/esm/helpers/updateColumnsWithJS.d.ts +12 -6
- package/esm/helpers/updateColumnsWithJS.d.ts.map +1 -1
- package/esm/helpers/updateColumnsWithJS.js +12 -6
- package/esm/helpers/validateGraphRouteResultSchema.d.ts +4 -0
- package/esm/helpers/validateGraphRouteResultSchema.d.ts.map +1 -0
- package/esm/helpers/validateGraphRouteResultSchema.js +13 -0
- package/esm/helpers/validateGraphTemporalEvents.d.ts +7 -0
- package/esm/helpers/validateGraphTemporalEvents.d.ts.map +1 -0
- package/esm/helpers/validateGraphTemporalEvents.js +47 -0
- package/esm/helpers/validateNumericalAnalysis.d.ts +10 -6
- package/esm/helpers/validateNumericalAnalysis.d.ts.map +1 -1
- package/esm/helpers/validateNumericalAnalysis.js +10 -6
- package/esm/helpers/validateVectorRowIds.d.ts +4 -0
- package/esm/helpers/validateVectorRowIds.d.ts.map +1 -0
- package/esm/helpers/validateVectorRowIds.js +16 -0
- package/esm/helpers/vectorDistanceExpression.d.ts +6 -0
- package/esm/helpers/vectorDistanceExpression.d.ts.map +1 -0
- package/esm/helpers/vectorDistanceExpression.js +11 -0
- package/esm/helpers/wrapString.d.ts +10 -7
- package/esm/helpers/wrapString.d.ts.map +1 -1
- package/esm/helpers/wrapString.js +10 -7
- package/esm/methods/addId.d.ts +5 -0
- package/esm/methods/addId.d.ts.map +1 -0
- package/esm/methods/addId.js +38 -0
- package/esm/methods/cache.js +1 -1
- package/esm/methods/commonNeighbors.d.ts +10 -0
- package/esm/methods/commonNeighbors.d.ts.map +1 -0
- package/esm/methods/commonNeighbors.js +101 -0
- package/esm/methods/connectedComponents.d.ts +9 -0
- package/esm/methods/connectedComponents.d.ts.map +1 -0
- package/esm/methods/connectedComponents.js +147 -0
- package/esm/methods/degree.d.ts +9 -0
- package/esm/methods/degree.d.ts.map +1 -0
- package/esm/methods/degree.js +135 -0
- package/esm/methods/distances.d.ts +12 -0
- package/esm/methods/distances.d.ts.map +1 -0
- package/esm/methods/distances.js +164 -0
- package/esm/methods/findCycles.d.ts +12 -0
- package/esm/methods/findCycles.d.ts.map +1 -0
- package/esm/methods/findCycles.js +330 -0
- package/esm/methods/fuzzyClean.d.ts.map +1 -1
- package/esm/methods/fuzzyClean.js +17 -136
- package/esm/methods/fuzzyJoin.js +70 -16
- package/esm/methods/getTypes.d.ts +1 -1
- package/esm/methods/hdbscan.d.ts +5 -0
- package/esm/methods/hdbscan.d.ts.map +1 -0
- package/esm/methods/hdbscan.js +208 -0
- package/esm/methods/loadArray.d.ts.map +1 -1
- package/esm/methods/loadArray.js +3 -20
- package/esm/methods/mahalanobis.d.ts +5 -0
- package/esm/methods/mahalanobis.d.ts.map +1 -0
- package/esm/methods/mahalanobis.js +92 -0
- package/esm/methods/neighbors.d.ts +9 -0
- package/esm/methods/neighbors.d.ts.map +1 -0
- package/esm/methods/neighbors.js +81 -0
- package/esm/methods/normalizeVector.d.ts +5 -0
- package/esm/methods/normalizeVector.d.ts.map +1 -0
- package/esm/methods/normalizeVector.js +132 -0
- package/esm/methods/paths.d.ts +12 -0
- package/esm/methods/paths.d.ts.map +1 -0
- package/esm/methods/paths.js +287 -0
- package/esm/methods/reachable.d.ts +11 -0
- package/esm/methods/reachable.d.ts.map +1 -0
- package/esm/methods/reachable.js +131 -0
- package/esm/methods/rowToVector.d.ts +5 -0
- package/esm/methods/rowToVector.d.ts.map +1 -0
- package/esm/methods/rowToVector.js +77 -0
- package/esm/methods/shortestPath.d.ts +12 -0
- package/esm/methods/shortestPath.d.ts.map +1 -0
- package/esm/methods/shortestPath.js +337 -0
- package/esm/methods/topologicalSort.d.ts +7 -0
- package/esm/methods/topologicalSort.d.ts.map +1 -0
- package/esm/methods/topologicalSort.js +164 -0
- package/esm/methods/umap.d.ts +5 -0
- package/esm/methods/umap.d.ts.map +1 -0
- package/esm/methods/umap.js +156 -0
- package/esm/methods/updateWithJS.js +9 -21
- package/llm.md +2170 -128
- package/llms.txt +1 -1
- package/package.json +1 -1
- package/script/class/SDAError.d.ts +6 -6
- package/script/class/SDAError.js +6 -6
- package/script/class/Simple.d.ts +9 -9
- package/script/class/Simple.js +9 -9
- package/script/class/SimpleDB.d.ts +80 -76
- package/script/class/SimpleDB.d.ts.map +1 -1
- package/script/class/SimpleDB.js +80 -76
- package/script/class/SimpleTable.d.ts +2805 -1077
- package/script/class/SimpleTable.d.ts.map +1 -1
- package/script/class/SimpleTable.js +2777 -1077
- package/script/helpers/appendColumnBatches.d.ts +3 -0
- package/script/helpers/appendColumnBatches.d.ts.map +1 -0
- package/script/helpers/appendColumnBatches.js +24 -0
- package/script/helpers/buildApproximateMutualReachabilityMst.d.ts +45 -0
- package/script/helpers/buildApproximateMutualReachabilityMst.d.ts.map +1 -0
- package/script/helpers/buildApproximateMutualReachabilityMst.js +219 -0
- package/script/helpers/buildChronologicalGraphComponentsSql.d.ts +14 -0
- package/script/helpers/buildChronologicalGraphComponentsSql.d.ts.map +1 -0
- package/script/helpers/buildChronologicalGraphComponentsSql.js +174 -0
- package/script/helpers/buildExactMutualReachabilityMst.d.ts +28 -0
- package/script/helpers/buildExactMutualReachabilityMst.d.ts.map +1 -0
- package/script/helpers/buildExactMutualReachabilityMst.js +103 -0
- package/script/helpers/buildGraphTemporalCostStateSql.d.ts +12 -0
- package/script/helpers/buildGraphTemporalCostStateSql.d.ts.map +1 -0
- package/script/helpers/buildGraphTemporalCostStateSql.js +92 -0
- package/script/helpers/buildGraphTemporalReachabilitySql.d.ts +13 -0
- package/script/helpers/buildGraphTemporalReachabilitySql.d.ts.map +1 -0
- package/script/helpers/buildGraphTemporalReachabilitySql.js +76 -0
- package/script/helpers/buildSparseMutualReachabilityMst.d.ts +10 -0
- package/script/helpers/buildSparseMutualReachabilityMst.d.ts.map +1 -0
- package/script/helpers/buildSparseMutualReachabilityMst.js +50 -0
- package/script/helpers/buildUmapGraph.d.ts +21 -0
- package/script/helpers/buildUmapGraph.d.ts.map +1 -0
- package/script/helpers/buildUmapGraph.js +67 -0
- package/script/helpers/buildVectorNeighbors.d.ts +45 -0
- package/script/helpers/buildVectorNeighbors.d.ts.map +1 -0
- package/script/helpers/buildVectorNeighbors.js +176 -0
- package/script/helpers/buildWeakGraphComponentsSql.d.ts +3 -0
- package/script/helpers/buildWeakGraphComponentsSql.d.ts.map +1 -0
- package/script/helpers/buildWeakGraphComponentsSql.js +38 -0
- package/script/helpers/cacheDatabase.d.ts.map +1 -1
- package/script/helpers/cacheDatabase.js +2 -1
- package/script/helpers/camelCase.d.ts +7 -5
- package/script/helpers/camelCase.d.ts.map +1 -1
- package/script/helpers/camelCase.js +7 -5
- package/script/helpers/capitalize.d.ts +6 -4
- package/script/helpers/capitalize.d.ts.map +1 -1
- package/script/helpers/capitalize.js +6 -4
- package/script/helpers/clusterHdbscan.d.ts +18 -0
- package/script/helpers/clusterHdbscan.d.ts.map +1 -0
- package/script/helpers/clusterHdbscan.js +346 -0
- package/script/helpers/computeCovariance.d.ts +16 -0
- package/script/helpers/computeCovariance.d.ts.map +1 -0
- package/script/helpers/computeCovariance.js +105 -0
- package/script/helpers/computeMahalanobisDistances.d.ts +14 -0
- package/script/helpers/computeMahalanobisDistances.d.ts.map +1 -0
- package/script/helpers/computeMahalanobisDistances.js +93 -0
- package/script/helpers/createDirectory.d.ts +4 -3
- package/script/helpers/createDirectory.d.ts.map +1 -1
- package/script/helpers/createDirectory.js +4 -3
- package/script/helpers/dataToArrays.d.ts +6 -4
- package/script/helpers/dataToArrays.d.ts.map +1 -1
- package/script/helpers/dataToArrays.js +6 -4
- package/script/helpers/extractTypes.d.ts +1 -1
- package/script/helpers/extractTypes.js +4 -9
- package/script/helpers/factorCovariance.d.ts +17 -0
- package/script/helpers/factorCovariance.d.ts.map +1 -0
- package/script/helpers/factorCovariance.js +194 -0
- package/script/helpers/findGeoColumn.d.ts +6 -4
- package/script/helpers/findGeoColumn.d.ts.map +1 -1
- package/script/helpers/findGeoColumn.js +6 -4
- package/script/helpers/findGeoColumnFromSchema.d.ts +8 -5
- package/script/helpers/findGeoColumnFromSchema.d.ts.map +1 -1
- package/script/helpers/findGeoColumnFromSchema.js +8 -5
- package/script/helpers/fitUmapCurve.d.ts +2 -0
- package/script/helpers/fitUmapCurve.d.ts.map +1 -0
- package/script/helpers/fitUmapCurve.js +69 -0
- package/script/helpers/formatDate.d.ts +12 -6
- package/script/helpers/formatDate.d.ts.map +1 -1
- package/script/helpers/formatDate.js +12 -6
- package/script/helpers/formatMissingTables.d.ts +8 -5
- package/script/helpers/formatMissingTables.d.ts.map +1 -1
- package/script/helpers/formatMissingTables.js +8 -5
- package/script/helpers/formatNumber.d.ts +19 -10
- package/script/helpers/formatNumber.d.ts.map +1 -1
- package/script/helpers/formatNumber.js +32 -17
- package/script/helpers/getGraphEdgeIdColumn.d.ts +9 -0
- package/script/helpers/getGraphEdgeIdColumn.d.ts.map +1 -0
- package/script/helpers/getGraphEdgeIdColumn.js +31 -0
- package/script/helpers/getGraphEndpointColumns.d.ts +11 -0
- package/script/helpers/getGraphEndpointColumns.d.ts.map +1 -0
- package/script/helpers/getGraphEndpointColumns.js +166 -0
- package/script/helpers/getGraphWeightColumn.d.ts +10 -0
- package/script/helpers/getGraphWeightColumn.d.ts.map +1 -0
- package/script/helpers/getGraphWeightColumn.js +46 -0
- package/script/helpers/graphRouteResultSchema.d.ts +4 -0
- package/script/helpers/graphRouteResultSchema.d.ts.map +1 -0
- package/script/helpers/graphRouteResultSchema.js +18 -0
- package/script/helpers/graphRouteResultSelect.d.ts +4 -0
- package/script/helpers/graphRouteResultSelect.d.ts.map +1 -0
- package/script/helpers/graphRouteResultSelect.js +28 -0
- package/script/helpers/hasGeometryColumn.d.ts +4 -3
- package/script/helpers/hasGeometryColumn.d.ts.map +1 -1
- package/script/helpers/hasGeometryColumn.js +4 -3
- package/script/helpers/initialUmapCoordinates.d.ts +2 -0
- package/script/helpers/initialUmapCoordinates.d.ts.map +1 -0
- package/script/helpers/initialUmapCoordinates.js +11 -0
- package/script/helpers/inspectGraphConnectivity.d.ts +10 -0
- package/script/helpers/inspectGraphConnectivity.d.ts.map +1 -0
- package/script/helpers/inspectGraphConnectivity.js +58 -0
- package/script/helpers/mergeOptions.d.ts +24 -13
- package/script/helpers/mergeOptions.d.ts.map +1 -1
- package/script/helpers/mergeOptions.js +24 -13
- package/script/helpers/optimizeUmapLayout.d.ts +7 -0
- package/script/helpers/optimizeUmapLayout.d.ts.map +1 -0
- package/script/helpers/optimizeUmapLayout.js +99 -0
- package/script/helpers/parseValue.d.ts +6 -4
- package/script/helpers/parseValue.d.ts.map +1 -1
- package/script/helpers/parseValue.js +6 -4
- package/script/helpers/prepareGraphRouteSql.d.ts +31 -0
- package/script/helpers/prepareGraphRouteSql.d.ts.map +1 -0
- package/script/helpers/prepareGraphRouteSql.js +127 -0
- package/script/helpers/prepareGraphStarts.d.ts +9 -0
- package/script/helpers/prepareGraphStarts.d.ts.map +1 -0
- package/script/helpers/prepareGraphStarts.js +71 -0
- package/script/helpers/prepareGraphTemporalSql.d.ts +28 -0
- package/script/helpers/prepareGraphTemporalSql.d.ts.map +1 -0
- package/script/helpers/prepareGraphTemporalSql.js +161 -0
- package/script/helpers/prepareGraphTraversal.d.ts +19 -0
- package/script/helpers/prepareGraphTraversal.d.ts.map +1 -0
- package/script/helpers/prepareGraphTraversal.js +87 -0
- package/script/helpers/prepareNumericFeatures.d.ts +41 -0
- package/script/helpers/prepareNumericFeatures.d.ts.map +1 -0
- package/script/helpers/prepareNumericFeatures.js +217 -0
- package/script/helpers/prepareUmapLayoutOptions.d.ts +14 -0
- package/script/helpers/prepareUmapLayoutOptions.d.ts.map +1 -0
- package/script/helpers/prepareUmapLayoutOptions.js +29 -0
- package/script/helpers/prettyDuration.d.ts +14 -8
- package/script/helpers/prettyDuration.d.ts.map +1 -1
- package/script/helpers/prettyDuration.js +14 -8
- package/script/helpers/printTable.d.ts +18 -13
- package/script/helpers/printTable.d.ts.map +1 -1
- package/script/helpers/printTable.js +18 -13
- package/script/helpers/publishPreparedColumns.d.ts +37 -0
- package/script/helpers/publishPreparedColumns.d.ts.map +1 -0
- package/script/helpers/publishPreparedColumns.js +119 -0
- package/script/helpers/queryDB.d.ts +24 -13
- package/script/helpers/queryDB.d.ts.map +1 -1
- package/script/helpers/queryDB.js +24 -13
- package/script/helpers/queueAsyncBarrier.d.ts +12 -7
- package/script/helpers/queueAsyncBarrier.d.ts.map +1 -1
- package/script/helpers/queueAsyncBarrier.js +12 -7
- package/script/helpers/queueGraphResult.d.ts +18 -0
- package/script/helpers/queueGraphResult.d.ts.map +1 -0
- package/script/helpers/queueGraphResult.js +45 -0
- package/script/helpers/quoteIdentifier.d.ts +4 -3
- package/script/helpers/quoteIdentifier.d.ts.map +1 -1
- package/script/helpers/quoteIdentifier.js +4 -3
- package/script/helpers/quoteQualifiedIdentifier.d.ts +6 -4
- package/script/helpers/quoteQualifiedIdentifier.d.ts.map +1 -1
- package/script/helpers/quoteQualifiedIdentifier.js +6 -4
- package/script/helpers/readScalarNumber.d.ts +3 -0
- package/script/helpers/readScalarNumber.d.ts.map +1 -0
- package/script/helpers/readScalarNumber.js +7 -0
- package/script/helpers/runQuery.d.ts.map +1 -1
- package/script/helpers/runQuery.js +17 -3
- package/script/helpers/selectFuzzyReplacements.d.ts +11 -0
- package/script/helpers/selectFuzzyReplacements.d.ts.map +1 -0
- package/script/helpers/selectFuzzyReplacements.js +127 -0
- package/script/helpers/stabilizeCosineVectors.d.ts +14 -0
- package/script/helpers/stabilizeCosineVectors.d.ts.map +1 -0
- package/script/helpers/stabilizeCosineVectors.js +40 -0
- package/script/helpers/stringToArray.d.ts +4 -3
- package/script/helpers/stringToArray.d.ts.map +1 -1
- package/script/helpers/stringToArray.js +4 -3
- package/script/helpers/umapRandom.d.ts +2 -0
- package/script/helpers/umapRandom.d.ts.map +1 -0
- package/script/helpers/umapRandom.js +13 -0
- package/script/helpers/updateColumnsWithJS.d.ts +12 -6
- package/script/helpers/updateColumnsWithJS.d.ts.map +1 -1
- package/script/helpers/updateColumnsWithJS.js +12 -6
- package/script/helpers/validateGraphRouteResultSchema.d.ts +4 -0
- package/script/helpers/validateGraphRouteResultSchema.d.ts.map +1 -0
- package/script/helpers/validateGraphRouteResultSchema.js +19 -0
- package/script/helpers/validateGraphTemporalEvents.d.ts +7 -0
- package/script/helpers/validateGraphTemporalEvents.d.ts.map +1 -0
- package/script/helpers/validateGraphTemporalEvents.js +53 -0
- package/script/helpers/validateNumericalAnalysis.d.ts +10 -6
- package/script/helpers/validateNumericalAnalysis.d.ts.map +1 -1
- package/script/helpers/validateNumericalAnalysis.js +10 -6
- package/script/helpers/validateVectorRowIds.d.ts +4 -0
- package/script/helpers/validateVectorRowIds.d.ts.map +1 -0
- package/script/helpers/validateVectorRowIds.js +19 -0
- package/script/helpers/vectorDistanceExpression.d.ts +6 -0
- package/script/helpers/vectorDistanceExpression.d.ts.map +1 -0
- package/script/helpers/vectorDistanceExpression.js +14 -0
- package/script/helpers/wrapString.d.ts +10 -7
- package/script/helpers/wrapString.d.ts.map +1 -1
- package/script/helpers/wrapString.js +10 -7
- package/script/methods/addId.d.ts +5 -0
- package/script/methods/addId.d.ts.map +1 -0
- package/script/methods/addId.js +44 -0
- package/script/methods/cache.js +1 -1
- package/script/methods/commonNeighbors.d.ts +10 -0
- package/script/methods/commonNeighbors.d.ts.map +1 -0
- package/script/methods/commonNeighbors.js +140 -0
- package/script/methods/connectedComponents.d.ts +9 -0
- package/script/methods/connectedComponents.d.ts.map +1 -0
- package/script/methods/connectedComponents.js +186 -0
- package/script/methods/degree.d.ts +9 -0
- package/script/methods/degree.d.ts.map +1 -0
- package/script/methods/degree.js +141 -0
- package/script/methods/distances.d.ts +12 -0
- package/script/methods/distances.d.ts.map +1 -0
- package/script/methods/distances.js +203 -0
- package/script/methods/findCycles.d.ts +12 -0
- package/script/methods/findCycles.d.ts.map +1 -0
- package/script/methods/findCycles.js +369 -0
- package/script/methods/fuzzyClean.d.ts.map +1 -1
- package/script/methods/fuzzyClean.js +17 -136
- package/script/methods/fuzzyJoin.js +70 -16
- package/script/methods/getTypes.d.ts +1 -1
- package/script/methods/hdbscan.d.ts +5 -0
- package/script/methods/hdbscan.d.ts.map +1 -0
- package/script/methods/hdbscan.js +214 -0
- package/script/methods/loadArray.d.ts.map +1 -1
- package/script/methods/loadArray.js +2 -19
- package/script/methods/mahalanobis.d.ts +5 -0
- package/script/methods/mahalanobis.d.ts.map +1 -0
- package/script/methods/mahalanobis.js +98 -0
- package/script/methods/neighbors.d.ts +9 -0
- package/script/methods/neighbors.d.ts.map +1 -0
- package/script/methods/neighbors.js +120 -0
- package/script/methods/normalizeVector.d.ts +5 -0
- package/script/methods/normalizeVector.d.ts.map +1 -0
- package/script/methods/normalizeVector.js +138 -0
- package/script/methods/paths.d.ts +12 -0
- package/script/methods/paths.d.ts.map +1 -0
- package/script/methods/paths.js +326 -0
- package/script/methods/reachable.d.ts +11 -0
- package/script/methods/reachable.d.ts.map +1 -0
- package/script/methods/reachable.js +170 -0
- package/script/methods/rowToVector.d.ts +5 -0
- package/script/methods/rowToVector.d.ts.map +1 -0
- package/script/methods/rowToVector.js +83 -0
- package/script/methods/shortestPath.d.ts +12 -0
- package/script/methods/shortestPath.d.ts.map +1 -0
- package/script/methods/shortestPath.js +376 -0
- package/script/methods/topologicalSort.d.ts +7 -0
- package/script/methods/topologicalSort.d.ts.map +1 -0
- package/script/methods/topologicalSort.js +170 -0
- package/script/methods/umap.d.ts +5 -0
- package/script/methods/umap.d.ts.map +1 -0
- package/script/methods/umap.js +162 -0
- package/script/methods/updateWithJS.js +9 -21
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type DuckDBConnection, type DuckDBType, type DuckDBValue } from "@duckdb/node-api";
|
|
2
|
+
export default function appendColumnBatches(connection: DuckDBConnection, table: string, types: readonly DuckDBType[], rowCount: number, columnValues: (column: number, start: number, end: number) => readonly DuckDBValue[]): Promise<void>;
|
|
3
|
+
//# sourceMappingURL=appendColumnBatches.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appendColumnBatches.d.ts","sourceRoot":"","sources":["../../src/helpers/appendColumnBatches.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,gBAAgB,EAErB,KAAK,UAAU,EACf,KAAK,WAAW,EACjB,MAAM,kBAAkB,CAAC;AAI1B,wBAA8B,mBAAmB,CAC/C,UAAU,EAAE,gBAAgB,EAC5B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,CACZ,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,KACR,SAAS,WAAW,EAAE,iBAiB5B"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { DuckDBDataChunk, } from "@duckdb/node-api";
|
|
2
|
+
// Append to an existing table. Callers retain ownership of type conversion and
|
|
3
|
+
// publication; each column callback supplies only the requested [start, end).
|
|
4
|
+
export default async function appendColumnBatches(connection, table, types, rowCount, columnValues) {
|
|
5
|
+
const appender = await connection.createAppender(table);
|
|
6
|
+
try {
|
|
7
|
+
// Stay below DuckDB's maximum chunk capacity of 2048 rows.
|
|
8
|
+
for (let start = 0; start < rowCount; start += 2000) {
|
|
9
|
+
const end = Math.min(start + 2000, rowCount);
|
|
10
|
+
const chunk = DuckDBDataChunk.create(types, end - start);
|
|
11
|
+
for (let column = 0; column < types.length; column++) {
|
|
12
|
+
chunk.setColumnValues(column, columnValues(column, start, end));
|
|
13
|
+
}
|
|
14
|
+
appender.appendDataChunk(chunk);
|
|
15
|
+
}
|
|
16
|
+
appender.flushSync();
|
|
17
|
+
}
|
|
18
|
+
finally {
|
|
19
|
+
appender.closeSync();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type DuckDBConnection } from "@duckdb/node-api";
|
|
2
|
+
/**
|
|
3
|
+
* Build an explicitly approximate mutual-reachability MST. HNSW supplies a
|
|
4
|
+
* high-recall k-neighbor candidate graph; disconnected components are repaired
|
|
5
|
+
* with deterministic all-member projection sweeps. Neither step guarantees the
|
|
6
|
+
* complete graph's MST.
|
|
7
|
+
*/
|
|
8
|
+
export default function buildApproximateMutualReachabilityMst(connection: DuckDBConnection, input: {
|
|
9
|
+
count: number;
|
|
10
|
+
dimensions: number;
|
|
11
|
+
minSamples: number;
|
|
12
|
+
}, options: {
|
|
13
|
+
metric: "euclidean" | "cosine";
|
|
14
|
+
}, names: {
|
|
15
|
+
rows: string;
|
|
16
|
+
neighbors: string;
|
|
17
|
+
search: string;
|
|
18
|
+
hnsw: string;
|
|
19
|
+
candidates: string;
|
|
20
|
+
coreDistances: string;
|
|
21
|
+
edges: string;
|
|
22
|
+
components: string;
|
|
23
|
+
representatives: string;
|
|
24
|
+
componentPairs: string;
|
|
25
|
+
bridgeCandidates: string;
|
|
26
|
+
mst: string;
|
|
27
|
+
}): Promise<{
|
|
28
|
+
candidateComponents: number;
|
|
29
|
+
neighborCount: number;
|
|
30
|
+
}>;
|
|
31
|
+
/** Internal connectivity-repair seam used by focused approximation tests. */
|
|
32
|
+
export declare function repairApproximateConnectivity(connection: DuckDBConnection, input: {
|
|
33
|
+
count: number;
|
|
34
|
+
}, options: {
|
|
35
|
+
metric: "euclidean" | "cosine";
|
|
36
|
+
}, names: {
|
|
37
|
+
rows: string;
|
|
38
|
+
coreDistances: string;
|
|
39
|
+
edges: string;
|
|
40
|
+
components: string;
|
|
41
|
+
representatives: string;
|
|
42
|
+
componentPairs: string;
|
|
43
|
+
bridgeCandidates: string;
|
|
44
|
+
}): Promise<number>;
|
|
45
|
+
//# sourceMappingURL=buildApproximateMutualReachabilityMst.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildApproximateMutualReachabilityMst.d.ts","sourceRoot":"","sources":["../../src/helpers/buildApproximateMutualReachabilityMst.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,gBAAgB,EAAW,MAAM,kBAAkB,CAAC;AAQ1E;;;;;GAKG;AACH,wBAA8B,qCAAqC,CACjE,UAAU,EAAE,gBAAgB,EAC5B,KAAK,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,EAChE,OAAO,EAAE;IAAE,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAA;CAAE,EAC3C,KAAK,EAAE;IACL,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;CACb,GACA,OAAO,CAAC;IAAE,mBAAmB,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,CAsFjE;AAED,6EAA6E;AAC7E,wBAAsB,6BAA6B,CACjD,UAAU,EAAE,gBAAgB,EAC5B,KAAK,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,EACxB,OAAO,EAAE;IAAE,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAA;CAAE,EAC3C,KAAK,EAAE;IACL,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,GACA,OAAO,CAAC,MAAM,CAAC,CAsHjB"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { DOUBLE, INTEGER } from "@duckdb/node-api";
|
|
2
|
+
import appendColumnBatches from "./appendColumnBatches.js";
|
|
3
|
+
import buildSparseMutualReachabilityMst from "./buildSparseMutualReachabilityMst.js";
|
|
4
|
+
import buildVectorNeighbors from "./buildVectorNeighbors.js";
|
|
5
|
+
import inspectGraphConnectivity from "./inspectGraphConnectivity.js";
|
|
6
|
+
import quoteIdentifier from "./quoteIdentifier.js";
|
|
7
|
+
import vectorDistanceExpression from "./vectorDistanceExpression.js";
|
|
8
|
+
/**
|
|
9
|
+
* Build an explicitly approximate mutual-reachability MST. HNSW supplies a
|
|
10
|
+
* high-recall k-neighbor candidate graph; disconnected components are repaired
|
|
11
|
+
* with deterministic all-member projection sweeps. Neither step guarantees the
|
|
12
|
+
* complete graph's MST.
|
|
13
|
+
*/
|
|
14
|
+
export default async function buildApproximateMutualReachabilityMst(connection, input, options, names) {
|
|
15
|
+
const q = quoteIdentifier;
|
|
16
|
+
const quoted = Object.fromEntries(Object.entries(names).map(([key, value]) => [key, q(value)]));
|
|
17
|
+
const neighborCount = Math.min(input.count - 1, Math.max(input.minSamples, 64));
|
|
18
|
+
await buildVectorNeighbors(connection, {
|
|
19
|
+
count: input.count,
|
|
20
|
+
dimensions: input.dimensions,
|
|
21
|
+
neighborCount,
|
|
22
|
+
}, {
|
|
23
|
+
metric: options.metric,
|
|
24
|
+
search: "hnsw",
|
|
25
|
+
includeSelf: false,
|
|
26
|
+
hnsw: {
|
|
27
|
+
efConstruction: 256,
|
|
28
|
+
efSearch: Math.max(512, neighborCount * 2),
|
|
29
|
+
connectivity: 32,
|
|
30
|
+
candidateCount: Math.min(input.count, neighborCount * 2 + 1),
|
|
31
|
+
singleThreaded: true,
|
|
32
|
+
cosineAsL2: true,
|
|
33
|
+
},
|
|
34
|
+
}, {
|
|
35
|
+
rows: quoted.rows,
|
|
36
|
+
neighbors: quoted.neighbors,
|
|
37
|
+
search: quoted.search,
|
|
38
|
+
hnsw: quoted.hnsw,
|
|
39
|
+
candidates: quoted.candidates,
|
|
40
|
+
});
|
|
41
|
+
await connection.run(`CREATE OR REPLACE TEMP TABLE ${quoted.coreDistances} AS
|
|
42
|
+
SELECT source AS vertex,distance
|
|
43
|
+
FROM ${quoted.neighbors} WHERE rank=${input.minSamples - 1};
|
|
44
|
+
CREATE OR REPLACE TEMP TABLE ${quoted.edges} AS
|
|
45
|
+
SELECT least(n.source,n.target)::INTEGER AS source,
|
|
46
|
+
greatest(n.source,n.target)::INTEGER AS target,
|
|
47
|
+
min(greatest(cs.distance,ct.distance,n.distance))::DOUBLE AS distance
|
|
48
|
+
FROM ${quoted.neighbors} n
|
|
49
|
+
JOIN ${quoted.coreDistances} cs ON cs.vertex=n.source
|
|
50
|
+
JOIN ${quoted.coreDistances} ct ON ct.vertex=n.target
|
|
51
|
+
GROUP BY least(n.source,n.target),greatest(n.source,n.target)`);
|
|
52
|
+
await connection.run(`DROP TABLE IF EXISTS ${quoted.neighbors};
|
|
53
|
+
DROP TABLE IF EXISTS ${quoted.candidates};
|
|
54
|
+
DROP TABLE IF EXISTS ${quoted.search}`);
|
|
55
|
+
const componentCount = await repairApproximateConnectivity(connection, { count: input.count }, options, {
|
|
56
|
+
rows: names.rows,
|
|
57
|
+
coreDistances: names.coreDistances,
|
|
58
|
+
edges: names.edges,
|
|
59
|
+
components: names.components,
|
|
60
|
+
representatives: names.representatives,
|
|
61
|
+
componentPairs: names.componentPairs,
|
|
62
|
+
bridgeCandidates: names.bridgeCandidates,
|
|
63
|
+
});
|
|
64
|
+
const mst = await buildSparseMutualReachabilityMst(connection, quoted.edges, input.count);
|
|
65
|
+
await connection.run(`CREATE OR REPLACE TEMP TABLE ${quoted.mst}
|
|
66
|
+
(source INTEGER,target INTEGER,distance DOUBLE)`);
|
|
67
|
+
await appendColumnBatches(connection, names.mst, [INTEGER, INTEGER, DOUBLE], mst.length, (column, start, end) => mst.slice(start, end).map((edge) => column === 0 ? edge.source : column === 1 ? edge.target : edge.distance));
|
|
68
|
+
return { candidateComponents: componentCount, neighborCount };
|
|
69
|
+
}
|
|
70
|
+
/** Internal connectivity-repair seam used by focused approximation tests. */
|
|
71
|
+
export async function repairApproximateConnectivity(connection, input, options, names) {
|
|
72
|
+
const q = quoteIdentifier;
|
|
73
|
+
const quoted = Object.fromEntries(Object.entries(names).map(([key, value]) => [key, q(value)]));
|
|
74
|
+
const componentOf = await readComponents(connection, quoted.edges, input.count);
|
|
75
|
+
let maximumComponent = -1;
|
|
76
|
+
for (const component of componentOf) {
|
|
77
|
+
if (component > maximumComponent)
|
|
78
|
+
maximumComponent = component;
|
|
79
|
+
}
|
|
80
|
+
const componentCount = maximumComponent + 1;
|
|
81
|
+
if (componentCount > 1) {
|
|
82
|
+
await createComponentRows(connection, names.components, componentOf);
|
|
83
|
+
// Each sweep examines every point, rather than a fixed representative
|
|
84
|
+
// sample. Consecutive component runs in the projected order provide a
|
|
85
|
+
// connected backbone, while multiple directions offer alternative edges.
|
|
86
|
+
// We also connect each member of a run to the nearest projected endpoint
|
|
87
|
+
// in both adjacent runs. All weights are recomputed in the actual metric.
|
|
88
|
+
const dimensions = Number((await connection.runAndReadAll(`SELECT len(vec) FROM ${quoted.rows} LIMIT 1`)).getRowsJS()[0][0]);
|
|
89
|
+
await connection.run(`CREATE OR REPLACE TEMP TABLE ${quoted.bridgeCandidates}
|
|
90
|
+
(source INTEGER,target INTEGER,distance DOUBLE)`);
|
|
91
|
+
const rawDistance = vectorDistanceExpression("a.vec", "b.vec", options.metric);
|
|
92
|
+
const projectionCount = Math.min(dimensions, 8) + (dimensions > 1 ? 16 : 0);
|
|
93
|
+
for (let projection = 0; projection < projectionCount; projection++) {
|
|
94
|
+
// Coordinate directions handle axis-aligned and one-dimensional data;
|
|
95
|
+
// fixed pseudo-random directions cover rotated component boundaries.
|
|
96
|
+
// Coefficients do not depend on table names, execution order, or RNG state.
|
|
97
|
+
const coefficients = Array.from({ length: dimensions }, (_, dimension) => {
|
|
98
|
+
if (projection < Math.min(dimensions, 8)) {
|
|
99
|
+
return dimension === projection ? 1 : 0;
|
|
100
|
+
}
|
|
101
|
+
let hash = Math.imul(projection + 1, 0x9e3779b1) ^
|
|
102
|
+
Math.imul(dimension + 1, 0x85ebca6b);
|
|
103
|
+
hash = Math.imul(hash ^ (hash >>> 16), 0x7feb352d);
|
|
104
|
+
hash = Math.imul(hash ^ (hash >>> 15), 0x846ca68b);
|
|
105
|
+
return ((hash ^ (hash >>> 16)) >>> 0) / 0x100000000 * 2 - 1;
|
|
106
|
+
});
|
|
107
|
+
// Scaling each coordinate by the same global factor prevents overflow
|
|
108
|
+
// in the projection without changing its ordering. Unit directions are
|
|
109
|
+
// the appropriate search geometry for cosine.
|
|
110
|
+
const vector = options.metric === "cosine"
|
|
111
|
+
? `list_transform(r.vec,x -> x/sqrt(array_inner_product(r.vec,r.vec)))::DOUBLE[${dimensions}]`
|
|
112
|
+
: `list_transform(r.vec,x -> x/scale.maximum)::DOUBLE[${dimensions}]`;
|
|
113
|
+
await connection.run(`CREATE OR REPLACE TEMP TABLE ${quoted.representatives} AS
|
|
114
|
+
WITH projected AS (
|
|
115
|
+
SELECT r.vertex,c.component,
|
|
116
|
+
array_inner_product(${vector},[${coefficients.join(",")}]::DOUBLE[${dimensions}]) AS position
|
|
117
|
+
FROM ${quoted.rows} r JOIN ${quoted.components} c USING(vertex)
|
|
118
|
+
CROSS JOIN (SELECT greatest(1,max(list_max(list_transform(vec,x -> abs(x))))) AS maximum FROM ${quoted.rows}) scale
|
|
119
|
+
), ordered AS (
|
|
120
|
+
SELECT *,lag(component) OVER w AS previous_component,
|
|
121
|
+
lead(component) OVER w AS next_component,
|
|
122
|
+
lag(vertex) OVER w AS previous_vertex,
|
|
123
|
+
lead(vertex) OVER w AS next_vertex
|
|
124
|
+
FROM projected WINDOW w AS (ORDER BY position,vertex)
|
|
125
|
+
)
|
|
126
|
+
SELECT vertex,
|
|
127
|
+
last_value(CASE WHEN component != previous_component THEN previous_vertex END IGNORE NULLS)
|
|
128
|
+
OVER (ORDER BY position,vertex ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS left_vertex,
|
|
129
|
+
first_value(CASE WHEN component != next_component THEN next_vertex END IGNORE NULLS)
|
|
130
|
+
OVER (ORDER BY position,vertex ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS right_vertex
|
|
131
|
+
FROM ordered;
|
|
132
|
+
INSERT INTO ${quoted.bridgeCandidates}
|
|
133
|
+
SELECT least(a.vertex,b.vertex)::INTEGER,greatest(a.vertex,b.vertex)::INTEGER,
|
|
134
|
+
greatest(ca.distance,cb.distance,${rawDistance})::DOUBLE
|
|
135
|
+
FROM (SELECT vertex,unnest([left_vertex,right_vertex]) AS target FROM ${quoted.representatives}) p
|
|
136
|
+
JOIN ${quoted.rows} a ON a.vertex=p.vertex
|
|
137
|
+
JOIN ${quoted.rows} b ON b.vertex=p.target
|
|
138
|
+
JOIN ${quoted.coreDistances} ca ON ca.vertex=a.vertex
|
|
139
|
+
JOIN ${quoted.coreDistances} cb ON cb.vertex=b.vertex`);
|
|
140
|
+
}
|
|
141
|
+
const invalidBridgeDistances = Number((await connection.runAndReadAll(`SELECT count(*) FROM ${quoted.bridgeCandidates}
|
|
142
|
+
WHERE distance IS NULL OR NOT isfinite(distance)`)).getRowsJS()[0][0]);
|
|
143
|
+
if (invalidBridgeDistances > 0) {
|
|
144
|
+
throw new Error(`Approximate HDBSCAN connectivity repair produced ${invalidBridgeDistances} non-finite candidate distances. Rescale the input features.`);
|
|
145
|
+
}
|
|
146
|
+
await connection.run(`INSERT INTO ${quoted.edges}
|
|
147
|
+
SELECT source,target,min(distance) AS distance
|
|
148
|
+
FROM ${quoted.bridgeCandidates} GROUP BY source,target`);
|
|
149
|
+
}
|
|
150
|
+
const connectivity = await inspectGraphConnectivity(connection, quoted.edges, input.count);
|
|
151
|
+
if (connectivity.componentCount !== 1) {
|
|
152
|
+
throw new Error(`Approximate HDBSCAN connectivity repair left ${connectivity.componentCount} graph components.`);
|
|
153
|
+
}
|
|
154
|
+
return componentCount;
|
|
155
|
+
}
|
|
156
|
+
async function readComponents(connection, edges, count) {
|
|
157
|
+
const parent = new Int32Array(count);
|
|
158
|
+
const size = new Int32Array(count).fill(1);
|
|
159
|
+
for (let vertex = 0; vertex < count; vertex++)
|
|
160
|
+
parent[vertex] = vertex;
|
|
161
|
+
const find = (start) => {
|
|
162
|
+
let root = start;
|
|
163
|
+
while (parent[root] !== root)
|
|
164
|
+
root = parent[root];
|
|
165
|
+
let current = start;
|
|
166
|
+
while (parent[current] !== current) {
|
|
167
|
+
const next = parent[current];
|
|
168
|
+
parent[current] = root;
|
|
169
|
+
current = next;
|
|
170
|
+
}
|
|
171
|
+
return root;
|
|
172
|
+
};
|
|
173
|
+
const union = (left, right) => {
|
|
174
|
+
let a = find(left), b = find(right);
|
|
175
|
+
if (a === b)
|
|
176
|
+
return;
|
|
177
|
+
if (size[a] < size[b])
|
|
178
|
+
[a, b] = [b, a];
|
|
179
|
+
parent[b] = a;
|
|
180
|
+
size[a] += size[b];
|
|
181
|
+
};
|
|
182
|
+
const result = await connection.stream(`SELECT source,target FROM ${edges}`);
|
|
183
|
+
while (true) {
|
|
184
|
+
const chunk = await result.fetchChunk();
|
|
185
|
+
if (!chunk || chunk.rowCount === 0)
|
|
186
|
+
break;
|
|
187
|
+
const sources = chunk.getColumnVector(0);
|
|
188
|
+
const targets = chunk.getColumnVector(1);
|
|
189
|
+
for (let row = 0; row < chunk.rowCount; row++) {
|
|
190
|
+
union(Number(sources.getItem(row)), Number(targets.getItem(row)));
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
const minimum = new Map();
|
|
194
|
+
for (let vertex = 0; vertex < count; vertex++) {
|
|
195
|
+
const root = find(vertex);
|
|
196
|
+
minimum.set(root, Math.min(minimum.get(root) ?? vertex, vertex));
|
|
197
|
+
}
|
|
198
|
+
const ids = [...minimum]
|
|
199
|
+
.sort((a, b) => a[1] - b[1])
|
|
200
|
+
.map(([root], component) => [root, component]);
|
|
201
|
+
const componentByRoot = new Map(ids);
|
|
202
|
+
const componentOf = new Int32Array(count);
|
|
203
|
+
for (let vertex = 0; vertex < count; vertex++) {
|
|
204
|
+
componentOf[vertex] = componentByRoot.get(find(vertex));
|
|
205
|
+
}
|
|
206
|
+
return componentOf;
|
|
207
|
+
}
|
|
208
|
+
async function createComponentRows(connection, name, componentOf) {
|
|
209
|
+
await connection.run(`CREATE OR REPLACE TEMP TABLE ${quoteIdentifier(name)}
|
|
210
|
+
(vertex INTEGER,component INTEGER)`);
|
|
211
|
+
await appendColumnBatches(connection, name, [INTEGER, INTEGER], componentOf.length, (column, start, end) => Array.from({ length: end - start }, (_, offset) => column === 0 ? start + offset : componentOf[start + offset]));
|
|
212
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { PreparedGraphTemporalSql } from "./prepareGraphTemporalSql.js";
|
|
2
|
+
import type { PreparedGraphSql } from "./prepareGraphTraversal.js";
|
|
3
|
+
/** Builds all-pairs chronological reachability and maximal-clique membership SQL. */
|
|
4
|
+
export default function buildChronologicalGraphComponentsSql(prepared: PreparedGraphSql, temporal: PreparedGraphTemporalSql): string;
|
|
5
|
+
export type MaximalGraphCliqueRelations = {
|
|
6
|
+
adjacency: string;
|
|
7
|
+
initial: string;
|
|
8
|
+
maximal: string;
|
|
9
|
+
numbered: string;
|
|
10
|
+
search: string;
|
|
11
|
+
};
|
|
12
|
+
/** Builds pivoted Bron–Kerbosch CTEs over typed node and mutual-edge relations. */
|
|
13
|
+
export declare function buildMaximalGraphCliquesSql(nodes: string, mutual: string, relations: MaximalGraphCliqueRelations): string;
|
|
14
|
+
//# sourceMappingURL=buildChronologicalGraphComponentsSql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildChronologicalGraphComponentsSql.d.ts","sourceRoot":"","sources":["../../src/helpers/buildChronologicalGraphComponentsSql.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAGnE,qFAAqF;AACrF,MAAM,CAAC,OAAO,UAAU,oCAAoC,CAC1D,QAAQ,EAAE,gBAAgB,EAC1B,QAAQ,EAAE,wBAAwB,GACjC,MAAM,CA+ER;AAED,MAAM,MAAM,2BAA2B,GAAG;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,mFAAmF;AACnF,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,2BAA2B,GACrC,MAAM,CA2FR"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import buildGraphTemporalReachabilitySql from "./buildGraphTemporalReachabilitySql.js";
|
|
2
|
+
import quoteIdentifier from "./quoteIdentifier.js";
|
|
3
|
+
/** Builds all-pairs chronological reachability and maximal-clique membership SQL. */
|
|
4
|
+
export default function buildChronologicalGraphComponentsSql(prepared, temporal) {
|
|
5
|
+
const q = quoteIdentifier;
|
|
6
|
+
// Temporal mutual reachability is not transitive: groups are maximal cliques
|
|
7
|
+
// that may overlap. Returning every group has exponential worst-case output.
|
|
8
|
+
const reachability = buildGraphTemporalReachabilitySql(prepared, (edges) => `SELECT ${q("__from")} AS ${q("start")},
|
|
9
|
+
${q("__from_key")} AS ${q("__key")}
|
|
10
|
+
FROM ${edges}
|
|
11
|
+
UNION
|
|
12
|
+
SELECT ${q("__to")}, ${q("__to_key")} FROM ${edges}`, "outgoing", temporal);
|
|
13
|
+
const relations = prepared.relationNames([
|
|
14
|
+
"graph_component_nodes",
|
|
15
|
+
"graph_component_reachability",
|
|
16
|
+
"graph_mutual_neighbors",
|
|
17
|
+
"graph_mutual_adjacency",
|
|
18
|
+
"graph_clique_initial",
|
|
19
|
+
"graph_clique_search",
|
|
20
|
+
"graph_maximal_cliques",
|
|
21
|
+
"graph_numbered_cliques",
|
|
22
|
+
]);
|
|
23
|
+
const nodes = relations.graph_component_nodes;
|
|
24
|
+
const reached = relations.graph_component_reachability;
|
|
25
|
+
const mutual = relations.graph_mutual_neighbors;
|
|
26
|
+
const adjacency = relations.graph_mutual_adjacency;
|
|
27
|
+
const initial = relations.graph_clique_initial;
|
|
28
|
+
const search = relations.graph_clique_search;
|
|
29
|
+
const maximal = relations.graph_maximal_cliques;
|
|
30
|
+
const numbered = relations.graph_numbered_cliques;
|
|
31
|
+
const edges = reachability.edgesRelation;
|
|
32
|
+
const reachable = reachability.reachableRelation;
|
|
33
|
+
return `${reachability.withClause}, ${nodes} AS MATERIALIZED (
|
|
34
|
+
SELECT ${q("node")}, ${q("__key")}
|
|
35
|
+
FROM (
|
|
36
|
+
SELECT ${q("__from")} AS ${q("node")},
|
|
37
|
+
${q("__from_key")} AS ${q("__key")}
|
|
38
|
+
FROM ${edges}
|
|
39
|
+
UNION
|
|
40
|
+
SELECT ${q("__to")}, ${q("__to_key")} FROM ${edges}
|
|
41
|
+
) AS ${q("valid_nodes")}
|
|
42
|
+
), ${reached} AS MATERIALIZED (
|
|
43
|
+
SELECT ${q("__start_key")}, ${q("__node_key")}
|
|
44
|
+
FROM ${reachable}
|
|
45
|
+
UNION
|
|
46
|
+
SELECT ${q("__key")}, ${q("__key")} FROM ${nodes}
|
|
47
|
+
), ${mutual} AS MATERIALIZED (
|
|
48
|
+
SELECT ${q("forward")}.${q("__start_key")} AS ${q("__key")},
|
|
49
|
+
${q("forward")}.${q("__node_key")} AS ${q("__neighbor_key")}
|
|
50
|
+
FROM ${reached} AS ${q("forward")}
|
|
51
|
+
INNER JOIN ${reached} AS ${q("reverse")}
|
|
52
|
+
ON ${q("forward")}.${q("__start_key")} =
|
|
53
|
+
${q("reverse")}.${q("__node_key")}
|
|
54
|
+
AND ${q("forward")}.${q("__node_key")} =
|
|
55
|
+
${q("reverse")}.${q("__start_key")}
|
|
56
|
+
WHERE ${q("forward")}.${q("__start_key")} !=
|
|
57
|
+
${q("forward")}.${q("__node_key")}
|
|
58
|
+
), ${buildMaximalGraphCliquesSql(nodes, mutual, {
|
|
59
|
+
adjacency,
|
|
60
|
+
initial,
|
|
61
|
+
maximal,
|
|
62
|
+
numbered,
|
|
63
|
+
search,
|
|
64
|
+
})}
|
|
65
|
+
SELECT ${q("numbered")}.${q("componentId")},
|
|
66
|
+
${q("nodes")}.${q("node")}
|
|
67
|
+
FROM ${numbered} AS ${q("numbered")}
|
|
68
|
+
CROSS JOIN unnest(${q("numbered")}.${q("__members")}) WITH ORDINALITY
|
|
69
|
+
AS ${q("member")}(${q("__key")}, ${q("__order")})
|
|
70
|
+
INNER JOIN ${nodes} AS ${q("nodes")}
|
|
71
|
+
ON ${q("member")}.${q("__key")} = ${q("nodes")}.${q("__key")}
|
|
72
|
+
ORDER BY ${q("numbered")}.${q("componentId")},
|
|
73
|
+
${q("member")}.${q("__order")}`;
|
|
74
|
+
}
|
|
75
|
+
/** Builds pivoted Bron–Kerbosch CTEs over typed node and mutual-edge relations. */
|
|
76
|
+
export function buildMaximalGraphCliquesSql(nodes, mutual, relations) {
|
|
77
|
+
const q = quoteIdentifier;
|
|
78
|
+
const { adjacency, initial, maximal, numbered, search } = relations;
|
|
79
|
+
// Sibling candidates are P minus the pivot's neighbors. For branch v, move
|
|
80
|
+
// only earlier siblings (candidate < v and outside N(pivot)) from P to X;
|
|
81
|
+
// earlier P vertices inside N(pivot) must remain prospective.
|
|
82
|
+
return `${adjacency} AS MATERIALIZED (
|
|
83
|
+
SELECT ${q("nodes")}.${q("__key")},
|
|
84
|
+
COALESCE(
|
|
85
|
+
list(${q("mutual")}.${q("__neighbor_key")}
|
|
86
|
+
ORDER BY ${q("mutual")}.${q("__neighbor_key")})
|
|
87
|
+
FILTER (WHERE ${q("mutual")}.${q("__neighbor_key")} IS NOT NULL),
|
|
88
|
+
list_slice(list_value(${q("nodes")}.${q("__key")}), 1, 0)
|
|
89
|
+
) AS ${q("__neighbors")}
|
|
90
|
+
FROM ${nodes} AS ${q("nodes")}
|
|
91
|
+
LEFT JOIN ${mutual} AS ${q("mutual")}
|
|
92
|
+
ON ${q("nodes")}.${q("__key")} = ${q("mutual")}.${q("__key")}
|
|
93
|
+
GROUP BY ${q("nodes")}.${q("__key")}
|
|
94
|
+
), ${initial} AS MATERIALIZED (
|
|
95
|
+
SELECT list_slice(${q("__keys")}, 1, 0) AS ${q("__r")},
|
|
96
|
+
${q("__keys")} AS ${q("__p")},
|
|
97
|
+
list_slice(${q("__keys")}, 1, 0) AS ${q("__x")}
|
|
98
|
+
FROM (
|
|
99
|
+
SELECT list(${q("__key")} ORDER BY ${q("__key")}) AS ${q("__keys")}
|
|
100
|
+
FROM ${nodes}
|
|
101
|
+
) AS ${q("all_nodes")}
|
|
102
|
+
WHERE ${q("__keys")} IS NOT NULL
|
|
103
|
+
), ${search}(${q("__r")}, ${q("__p")}, ${q("__x")}) AS (
|
|
104
|
+
SELECT ${q("__r")}, ${q("__p")}, ${q("__x")} FROM ${initial}
|
|
105
|
+
UNION ALL
|
|
106
|
+
SELECT list_append(${q("state")}.${q("__r")},
|
|
107
|
+
${q("branch")}.${q("__key")}),
|
|
108
|
+
list_filter(${q("state")}.${q("__p")}, ${q("candidate")} ->
|
|
109
|
+
list_contains(${q("branch_neighbors")}.${q("__neighbors")},
|
|
110
|
+
${q("candidate")})
|
|
111
|
+
AND (
|
|
112
|
+
${q("candidate")} >= ${q("branch")}.${q("__key")}
|
|
113
|
+
OR list_contains(${q("pivot")}.${q("__neighbors")},
|
|
114
|
+
${q("candidate")})
|
|
115
|
+
)),
|
|
116
|
+
list_filter(
|
|
117
|
+
list_concat(${q("state")}.${q("__x")},
|
|
118
|
+
${q("state")}.${q("__p")}),
|
|
119
|
+
${q("candidate")} ->
|
|
120
|
+
list_contains(${q("branch_neighbors")}.${q("__neighbors")},
|
|
121
|
+
${q("candidate")})
|
|
122
|
+
AND (
|
|
123
|
+
list_contains(${q("state")}.${q("__x")}, ${q("candidate")})
|
|
124
|
+
OR (
|
|
125
|
+
${q("candidate")} < ${q("branch")}.${q("__key")}
|
|
126
|
+
AND NOT list_contains(${q("pivot")}.${q("__neighbors")},
|
|
127
|
+
${q("candidate")})
|
|
128
|
+
)
|
|
129
|
+
)
|
|
130
|
+
)
|
|
131
|
+
FROM ${search} AS ${q("state")}
|
|
132
|
+
CROSS JOIN LATERAL (
|
|
133
|
+
SELECT ${q("candidate_adjacency")}.${q("__key")},
|
|
134
|
+
${q("candidate_adjacency")}.${q("__neighbors")}
|
|
135
|
+
FROM unnest(list_concat(${q("state")}.${q("__p")},
|
|
136
|
+
${q("state")}.${q("__x")})) AS ${q("candidate_key")}(${q("__key")})
|
|
137
|
+
INNER JOIN ${adjacency} AS ${q("candidate_adjacency")}
|
|
138
|
+
ON ${q("candidate_key")}.${q("__key")} =
|
|
139
|
+
${q("candidate_adjacency")}.${q("__key")}
|
|
140
|
+
ORDER BY list_unique(list_intersect(
|
|
141
|
+
${q("state")}.${q("__p")},
|
|
142
|
+
${q("candidate_adjacency")}.${q("__neighbors")}
|
|
143
|
+
)) DESC,
|
|
144
|
+
${q("candidate_adjacency")}.${q("__key")}
|
|
145
|
+
LIMIT 1
|
|
146
|
+
) AS ${q("pivot")}
|
|
147
|
+
CROSS JOIN LATERAL (
|
|
148
|
+
SELECT ${q("candidate")}.${q("__key")}
|
|
149
|
+
FROM unnest(${q("state")}.${q("__p")})
|
|
150
|
+
AS ${q("candidate")}(${q("__key")})
|
|
151
|
+
WHERE NOT list_contains(${q("pivot")}.${q("__neighbors")},
|
|
152
|
+
${q("candidate")}.${q("__key")})
|
|
153
|
+
) AS ${q("branch")}
|
|
154
|
+
INNER JOIN ${adjacency} AS ${q("branch_neighbors")}
|
|
155
|
+
ON ${q("branch")}.${q("__key")} =
|
|
156
|
+
${q("branch_neighbors")}.${q("__key")}
|
|
157
|
+
), ${maximal} AS MATERIALIZED (
|
|
158
|
+
SELECT list_sort(${q("__r")}) AS ${q("__members")}
|
|
159
|
+
FROM ${search}
|
|
160
|
+
WHERE len(${q("__p")}) = 0 AND len(${q("__x")}) = 0
|
|
161
|
+
), ${numbered} AS MATERIALIZED (
|
|
162
|
+
SELECT ${q("__members")},
|
|
163
|
+
CAST(row_number() OVER (ORDER BY ${q("__members")}) - 1 AS BIGINT)
|
|
164
|
+
AS ${q("componentId")}
|
|
165
|
+
FROM ${maximal}
|
|
166
|
+
)`;
|
|
167
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { DuckDBConnection } from "@duckdb/node-api";
|
|
2
|
+
/** Private, already-quoted relation names owned and cleaned up by the caller. */
|
|
3
|
+
export type MutualReachabilityTables = {
|
|
4
|
+
rows: string;
|
|
5
|
+
coreDistances: string;
|
|
6
|
+
frontier: string;
|
|
7
|
+
mst: string;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Build an exact HDBSCAN mutual-reachability MST with bounded materialization.
|
|
11
|
+
*
|
|
12
|
+
* The prepared rows relation must contain contiguous INTEGER `vertex` ids and
|
|
13
|
+
* fixed-size DOUBLE `vec` values. `minSamples` excludes the point itself. Core
|
|
14
|
+
* distance calculation uses bounded top-k aggregates and retains one scalar per
|
|
15
|
+
* point. Prim's algorithm retains one frontier edge per unvisited point. This
|
|
16
|
+
* costs O(n²d) distance work, O(n) stored algorithm state, and O(n) sequential
|
|
17
|
+
* DuckDB statements; it is intended as the exact correctness baseline.
|
|
18
|
+
* Cosine preparation may rescale the private vec column, preserving direction.
|
|
19
|
+
* All supplied scratch names are already quoted, distinct, and caller-owned;
|
|
20
|
+
* the caller must drop them in finally on both success and failure.
|
|
21
|
+
*/
|
|
22
|
+
export default function buildExactMutualReachabilityMst(connection: DuckDBConnection, input: {
|
|
23
|
+
count: number;
|
|
24
|
+
minSamples: number;
|
|
25
|
+
}, options: {
|
|
26
|
+
metric: "euclidean" | "cosine";
|
|
27
|
+
}, names: MutualReachabilityTables): Promise<void>;
|
|
28
|
+
//# sourceMappingURL=buildExactMutualReachabilityMst.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildExactMutualReachabilityMst.d.ts","sourceRoot":"","sources":["../../src/helpers/buildExactMutualReachabilityMst.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAMzD,iFAAiF;AACjF,MAAM,MAAM,wBAAwB,GAAG;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,wBAA8B,+BAA+B,CAC3D,UAAU,EAAE,gBAAgB,EAC5B,KAAK,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,EAC5C,OAAO,EAAE;IAAE,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAA;CAAE,EAC3C,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC,IAAI,CAAC,CA6Gf"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import readScalarNumber from "./readScalarNumber.js";
|
|
2
|
+
import vectorDistanceExpression from "./vectorDistanceExpression.js";
|
|
3
|
+
import stabilizeCosineVectors from "./stabilizeCosineVectors.js";
|
|
4
|
+
import validateVectorRowIds from "./validateVectorRowIds.js";
|
|
5
|
+
/**
|
|
6
|
+
* Build an exact HDBSCAN mutual-reachability MST with bounded materialization.
|
|
7
|
+
*
|
|
8
|
+
* The prepared rows relation must contain contiguous INTEGER `vertex` ids and
|
|
9
|
+
* fixed-size DOUBLE `vec` values. `minSamples` excludes the point itself. Core
|
|
10
|
+
* distance calculation uses bounded top-k aggregates and retains one scalar per
|
|
11
|
+
* point. Prim's algorithm retains one frontier edge per unvisited point. This
|
|
12
|
+
* costs O(n²d) distance work, O(n) stored algorithm state, and O(n) sequential
|
|
13
|
+
* DuckDB statements; it is intended as the exact correctness baseline.
|
|
14
|
+
* Cosine preparation may rescale the private vec column, preserving direction.
|
|
15
|
+
* All supplied scratch names are already quoted, distinct, and caller-owned;
|
|
16
|
+
* the caller must drop them in finally on both success and failure.
|
|
17
|
+
*/
|
|
18
|
+
export default async function buildExactMutualReachabilityMst(connection, input, options, names) {
|
|
19
|
+
const { count, minSamples } = input;
|
|
20
|
+
if (count < 2 || !Number.isSafeInteger(count)) {
|
|
21
|
+
throw new Error("Exact mutual-reachability MST requires at least two rows.");
|
|
22
|
+
}
|
|
23
|
+
if (!Number.isSafeInteger(minSamples) || minSamples < 1 || minSamples >= count) {
|
|
24
|
+
throw new Error(`minSamples must be a safe integer between 1 and ${count - 1}.`);
|
|
25
|
+
}
|
|
26
|
+
await validateVectorRowIds(connection, names.rows, count);
|
|
27
|
+
if (options.metric === "cosine") {
|
|
28
|
+
await stabilizeCosineVectors(connection, names.rows);
|
|
29
|
+
}
|
|
30
|
+
const distance = vectorDistanceExpression("a.vec", "b.vec", options.metric);
|
|
31
|
+
await connection.run(`CREATE OR REPLACE TEMP TABLE ${names.coreDistances}
|
|
32
|
+
(vertex INTEGER PRIMARY KEY,distance DOUBLE)`);
|
|
33
|
+
for (let offset = 0; offset < count; offset += 32) {
|
|
34
|
+
await connection.run(`INSERT INTO ${names.coreDistances}
|
|
35
|
+
SELECT source,max(item.distance)::DOUBLE AS distance FROM (
|
|
36
|
+
SELECT a.vertex AS source,
|
|
37
|
+
CASE WHEN bool_and(isfinite(${distance})) THEN
|
|
38
|
+
min_by(struct_pack(target := b.vertex,distance := ${distance}),
|
|
39
|
+
struct_pack(distance := ${distance},target := b.vertex),
|
|
40
|
+
${minSamples}) ELSE error('Distance computation returned a non-finite value.') END AS closest
|
|
41
|
+
FROM ${names.rows} a CROSS JOIN ${names.rows} b
|
|
42
|
+
WHERE a.vertex >= ${offset} AND a.vertex < ${offset + 32}
|
|
43
|
+
AND a.vertex != b.vertex GROUP BY a.vertex
|
|
44
|
+
),UNNEST(closest) AS t(item) GROUP BY source`);
|
|
45
|
+
}
|
|
46
|
+
if (await readScalarNumber(connection, `SELECT count(*) FROM ${names.coreDistances}
|
|
47
|
+
WHERE NOT isfinite(distance)`) ||
|
|
48
|
+
await readScalarNumber(connection, `SELECT count(*) FROM ${names.coreDistances}`) !== count) {
|
|
49
|
+
throw new Error("Exact core-distance computation returned missing or non-finite values.");
|
|
50
|
+
}
|
|
51
|
+
const root = await readScalarNumber(connection, `SELECT min(vertex) FROM ${names.rows}`);
|
|
52
|
+
await connection.run(`CREATE OR REPLACE TEMP TABLE ${names.frontier} AS
|
|
53
|
+
SELECT b.vertex,${root}::INTEGER AS parent,
|
|
54
|
+
greatest(ca.distance,cb.distance,${distance})::DOUBLE AS distance
|
|
55
|
+
FROM ${names.rows} a CROSS JOIN ${names.rows} b
|
|
56
|
+
JOIN ${names.coreDistances} ca ON ca.vertex=a.vertex
|
|
57
|
+
JOIN ${names.coreDistances} cb ON cb.vertex=b.vertex
|
|
58
|
+
WHERE a.vertex=${root} AND b.vertex!=${root};
|
|
59
|
+
CREATE OR REPLACE TEMP TABLE ${names.mst}
|
|
60
|
+
(source INTEGER,target INTEGER,distance DOUBLE)`);
|
|
61
|
+
for (let edge = 0; edge < count - 1; edge++) {
|
|
62
|
+
const chosen = (await connection.runAndReadAll(`SELECT vertex,parent,distance FROM ${names.frontier}
|
|
63
|
+
ORDER BY distance,least(parent,vertex),greatest(parent,vertex),parent,vertex
|
|
64
|
+
LIMIT 1`)).getRowsJS()[0];
|
|
65
|
+
if (chosen === undefined) {
|
|
66
|
+
throw new Error("Exact mutual-reachability graph became disconnected.");
|
|
67
|
+
}
|
|
68
|
+
const vertex = Number(chosen[0]);
|
|
69
|
+
const parent = Number(chosen[1]);
|
|
70
|
+
const edgeDistance = Number(chosen[2]);
|
|
71
|
+
if (!Number.isFinite(edgeDistance)) {
|
|
72
|
+
throw new Error("Exact mutual-reachability MST returned a non-finite distance.");
|
|
73
|
+
}
|
|
74
|
+
await connection.run(`INSERT INTO ${names.mst} VALUES
|
|
75
|
+
(${Math.min(vertex, parent)},${Math.max(vertex, parent)},${edgeDistance})`);
|
|
76
|
+
if (edge === count - 2)
|
|
77
|
+
break;
|
|
78
|
+
const candidateDistance = vectorDistanceExpression("added.vec", "target.vec", options.metric);
|
|
79
|
+
await connection.run(`CREATE OR REPLACE TEMP TABLE ${names.frontier} AS
|
|
80
|
+
WITH candidates AS (
|
|
81
|
+
SELECT f.*,greatest(ca.distance,cb.distance,${candidateDistance})::DOUBLE
|
|
82
|
+
AS candidate_distance
|
|
83
|
+
FROM ${names.frontier} f
|
|
84
|
+
JOIN ${names.rows} target ON target.vertex=f.vertex
|
|
85
|
+
CROSS JOIN ${names.rows} added
|
|
86
|
+
JOIN ${names.coreDistances} ca ON ca.vertex=added.vertex
|
|
87
|
+
JOIN ${names.coreDistances} cb ON cb.vertex=target.vertex
|
|
88
|
+
WHERE added.vertex=${vertex} AND f.vertex!=${vertex}
|
|
89
|
+
)
|
|
90
|
+
SELECT vertex,
|
|
91
|
+
CASE WHEN candidate_distance<distance OR
|
|
92
|
+
(candidate_distance=distance AND ${vertex}<parent)
|
|
93
|
+
THEN ${vertex} ELSE parent END::INTEGER AS parent,
|
|
94
|
+
least(distance,candidate_distance)::DOUBLE AS distance
|
|
95
|
+
FROM candidates`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { PreparedGraphTemporalSql } from "./prepareGraphTemporalSql.js";
|
|
2
|
+
import type { GraphDirection, PreparedGraphSql } from "./prepareGraphTraversal.js";
|
|
3
|
+
export type GraphTemporalCostStateSql = {
|
|
4
|
+
costRelation: string;
|
|
5
|
+
edgesRelation: string;
|
|
6
|
+
settingsRelation: string;
|
|
7
|
+
startsRelation: string;
|
|
8
|
+
withClause: string;
|
|
9
|
+
};
|
|
10
|
+
/** Builds keyed best-cost chronological states from an arbitrary start relation. */
|
|
11
|
+
export default function buildGraphTemporalCostStateSql(prepared: PreparedGraphSql, startsSelect: string | ((validEdgesRelation: string) => string), direction: Exclude<GraphDirection, "both">, temporal: PreparedGraphTemporalSql, distanceType: string, edgeWeight: string, eventSelections?: string[]): GraphTemporalCostStateSql;
|
|
12
|
+
//# sourceMappingURL=buildGraphTemporalCostStateSql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildGraphTemporalCostStateSql.d.ts","sourceRoot":"","sources":["../../src/helpers/buildGraphTemporalCostStateSql.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EACjB,MAAM,4BAA4B,CAAC;AAGpC,MAAM,MAAM,yBAAyB,GAAG;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,oFAAoF;AACpF,MAAM,CAAC,OAAO,UAAU,8BAA8B,CACpD,QAAQ,EAAE,gBAAgB,EAC1B,YAAY,EAAE,MAAM,GAAG,CAAC,CAAC,kBAAkB,EAAE,MAAM,KAAK,MAAM,CAAC,EAC/D,SAAS,EAAE,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,EAC1C,QAAQ,EAAE,wBAAwB,EAClC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,eAAe,GAAE,MAAM,EAAO,GAC7B,yBAAyB,CAuF3B"}
|