@nshiab/simple-data-analysis-core 2.0.9 → 2.1.1
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 +2806 -1139
- package/esm/class/SimpleTable.d.ts.map +1 -1
- package/esm/class/SimpleTable.js +2792 -1149
- 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 +2 -5
- package/esm/helpers/buildUmapGraph.d.ts.map +1 -1
- package/esm/helpers/buildUmapGraph.js +6 -100
- 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/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/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/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/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/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/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/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/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/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/trim.d.ts +1 -1
- package/esm/methods/trim.d.ts.map +1 -1
- package/esm/methods/trim.js +17 -8
- package/llm.md +2146 -173
- 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 +2806 -1139
- package/script/class/SimpleTable.d.ts.map +1 -1
- package/script/class/SimpleTable.js +2792 -1149
- 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 +2 -5
- package/script/helpers/buildUmapGraph.d.ts.map +1 -1
- package/script/helpers/buildUmapGraph.js +6 -100
- 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/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/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/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/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/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/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/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/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/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/trim.d.ts +1 -1
- package/script/methods/trim.d.ts.map +1 -1
- package/script/methods/trim.js +17 -8
|
@@ -5,14 +5,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.default = fuzzyClean;
|
|
7
7
|
const quoteIdentifier_js_1 = __importDefault(require("../helpers/quoteIdentifier.js"));
|
|
8
|
+
const node_api_1 = require("@duckdb/node-api");
|
|
8
9
|
const mergeOptions_js_1 = __importDefault(require("../helpers/mergeOptions.js"));
|
|
9
10
|
const queryDB_js_1 = __importDefault(require("../helpers/queryDB.js"));
|
|
10
11
|
const queueOp_js_1 = __importDefault(require("../helpers/queueOp.js"));
|
|
11
12
|
const buildFuzzyMatchSql_js_1 = __importDefault(require("../helpers/buildFuzzyMatchSql.js"));
|
|
13
|
+
const selectFuzzyReplacements_js_1 = __importDefault(require("../helpers/selectFuzzyReplacements.js"));
|
|
12
14
|
function fuzzyClean(table, column, newColumn, threshold, options = {}) {
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
// executes as a barrier.
|
|
15
|
+
// This implementation clusters fuzzy pairs in JS and writes the mapping
|
|
16
|
+
// back to DuckDB, so it executes as a barrier.
|
|
16
17
|
options = structuredClone(options);
|
|
17
18
|
(0, queueOp_js_1.default)(table, {
|
|
18
19
|
kind: "barrier",
|
|
@@ -63,149 +64,29 @@ async function executeFuzzyClean(table, column, newColumn, threshold, options =
|
|
|
63
64
|
}
|
|
64
65
|
return;
|
|
65
66
|
}
|
|
66
|
-
|
|
67
|
-
const countMap = new Map();
|
|
68
|
-
for (const { left_value, left_cnt, right_value, right_cnt } of pairs) {
|
|
69
|
-
countMap.set(left_value, Number(left_cnt));
|
|
70
|
-
countMap.set(right_value, Number(right_cnt));
|
|
71
|
-
}
|
|
72
|
-
// Union-Find — only over values that actually participate in a pair.
|
|
73
|
-
const parent = new Map();
|
|
74
|
-
const find = (x) => {
|
|
75
|
-
if (!parent.has(x))
|
|
76
|
-
parent.set(x, x);
|
|
77
|
-
if (parent.get(x) !== x)
|
|
78
|
-
parent.set(x, find(parent.get(x)));
|
|
79
|
-
return parent.get(x);
|
|
80
|
-
};
|
|
81
|
-
const union = (a, b) => {
|
|
82
|
-
const ra = find(a);
|
|
83
|
-
const rb = find(b);
|
|
84
|
-
if (ra !== rb)
|
|
85
|
-
parent.set(ra, rb);
|
|
86
|
-
};
|
|
87
|
-
for (const v of countMap.keys())
|
|
88
|
-
find(v);
|
|
89
|
-
for (const { left_value, right_value } of pairs) {
|
|
90
|
-
union(left_value, right_value);
|
|
91
|
-
}
|
|
92
|
-
// Group values by their cluster root.
|
|
93
|
-
const clusters = new Map();
|
|
94
|
-
for (const v of countMap.keys()) {
|
|
95
|
-
const root = find(v);
|
|
96
|
-
if (!clusters.has(root))
|
|
97
|
-
clusters.set(root, []);
|
|
98
|
-
clusters.get(root).push(v);
|
|
99
|
-
}
|
|
100
|
-
// Pick the canonical value for each cluster.
|
|
101
|
-
const replacement = new Map();
|
|
102
|
-
for (const members of clusters.values()) {
|
|
103
|
-
if (members.length === 1)
|
|
104
|
-
continue; // All pairs are already canonical — skip.
|
|
105
|
-
// Score sums and per-member max scores are computed lazily — only when
|
|
106
|
-
// actually needed as a primary criterion or tie-breaker.
|
|
107
|
-
//
|
|
108
|
-
// scoreSum: total similarity to all other cluster members (used by
|
|
109
|
-
// "mostCentral" as primary, and as tie-breaker for all strategies).
|
|
110
|
-
// scoreMax: highest single pairwise score (used by "maxScore" as primary).
|
|
111
|
-
let scoreSum = null;
|
|
112
|
-
const getScoreSum = () => {
|
|
113
|
-
if (scoreSum === null) {
|
|
114
|
-
scoreSum = new Map(members.map((m) => [m, 0]));
|
|
115
|
-
for (const { left_value, right_value, score } of pairs) {
|
|
116
|
-
if (scoreSum.has(left_value) && scoreSum.has(right_value)) {
|
|
117
|
-
scoreSum.set(left_value, (scoreSum.get(left_value) ?? 0) + score);
|
|
118
|
-
scoreSum.set(right_value, (scoreSum.get(right_value) ?? 0) + score);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return scoreSum;
|
|
123
|
-
};
|
|
124
|
-
let scoreMax = null;
|
|
125
|
-
const getScoreMax = () => {
|
|
126
|
-
if (scoreMax === null) {
|
|
127
|
-
scoreMax = new Map(members.map((m) => [m, 0]));
|
|
128
|
-
for (const { left_value, right_value, score } of pairs) {
|
|
129
|
-
if (scoreMax.has(left_value) && scoreMax.has(right_value)) {
|
|
130
|
-
scoreMax.set(left_value, Math.max(scoreMax.get(left_value) ?? 0, score));
|
|
131
|
-
scoreMax.set(right_value, Math.max(scoreMax.get(right_value) ?? 0, score));
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
return scoreMax;
|
|
136
|
-
};
|
|
137
|
-
// Sum-based comparator: highest total similarity, then alphabetical.
|
|
138
|
-
const byScore = (a, b) => {
|
|
139
|
-
const sum = getScoreSum();
|
|
140
|
-
const sa = sum.get(a) ?? 0;
|
|
141
|
-
const sb = sum.get(b) ?? 0;
|
|
142
|
-
if (sa !== sb)
|
|
143
|
-
return sa > sb ? a : b;
|
|
144
|
-
return a <= b ? a : b; // alphabetical tie-break
|
|
145
|
-
};
|
|
146
|
-
// Max-based comparator: highest single-pair score, then sum, then alphabetical.
|
|
147
|
-
const byMaxScore = (a, b) => {
|
|
148
|
-
const mx = getScoreMax();
|
|
149
|
-
const ma = mx.get(a) ?? 0;
|
|
150
|
-
const mb = mx.get(b) ?? 0;
|
|
151
|
-
if (ma !== mb)
|
|
152
|
-
return ma > mb ? a : b;
|
|
153
|
-
return byScore(a, b); // sum then alphabetical tie-break
|
|
154
|
-
};
|
|
155
|
-
let canonical;
|
|
156
|
-
if (strategy === "longestString") {
|
|
157
|
-
canonical = members.reduce((a, b) => {
|
|
158
|
-
if (a.length !== b.length)
|
|
159
|
-
return a.length > b.length ? a : b;
|
|
160
|
-
return byScore(a, b);
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
else if (strategy === "shortestString") {
|
|
164
|
-
canonical = members.reduce((a, b) => {
|
|
165
|
-
if (a.length !== b.length)
|
|
166
|
-
return a.length < b.length ? a : b;
|
|
167
|
-
return byScore(a, b);
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
else if (strategy === "mostCommon") {
|
|
171
|
-
canonical = members.reduce((a, b) => {
|
|
172
|
-
const ca = countMap.get(a) ?? 0;
|
|
173
|
-
const cb = countMap.get(b) ?? 0;
|
|
174
|
-
if (ca !== cb)
|
|
175
|
-
return ca > cb ? a : b;
|
|
176
|
-
return byScore(a, b);
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
else if (strategy === "mostCentral") {
|
|
180
|
-
// Most central string — highest total similarity to all other cluster members.
|
|
181
|
-
canonical = members.reduce((a, b) => byScore(a, b));
|
|
182
|
-
}
|
|
183
|
-
else {
|
|
184
|
-
// "maxScore": the string participating in the single highest-scoring pair.
|
|
185
|
-
canonical = members.reduce((a, b) => byMaxScore(a, b));
|
|
186
|
-
}
|
|
187
|
-
for (const m of members) {
|
|
188
|
-
if (m !== canonical)
|
|
189
|
-
replacement.set(m, canonical);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
67
|
+
const replacement = (0, selectFuzzyReplacements_js_1.default)(pairs, strategy);
|
|
192
68
|
if (replacement.size === 0)
|
|
193
69
|
return;
|
|
194
|
-
//
|
|
195
|
-
//
|
|
196
|
-
|
|
197
|
-
const
|
|
198
|
-
|
|
70
|
+
// Two bound lists keep the SQL and parameter count fixed as the mapping
|
|
71
|
+
// grows. Side-by-side UNNEST zips the equally sized lists into mapping rows,
|
|
72
|
+
// which DuckDB can hash-join to the original table.
|
|
73
|
+
const values = [
|
|
74
|
+
new node_api_1.DuckDBListValue([...replacement.keys()]),
|
|
75
|
+
new node_api_1.DuckDBListValue([...replacement.values()]),
|
|
76
|
+
];
|
|
77
|
+
const mapping = `WITH mapping(original, canonical) AS (
|
|
78
|
+
SELECT UNNEST(?::VARCHAR[]), UNNEST(?::VARCHAR[])
|
|
79
|
+
)`;
|
|
199
80
|
const query = newColumn !== column
|
|
200
81
|
? `ALTER TABLE ${(0, quoteIdentifier_js_1.default)(table.name)} ADD ${(0, quoteIdentifier_js_1.default)(newColumn)} VARCHAR;
|
|
201
82
|
UPDATE ${(0, quoteIdentifier_js_1.default)(table.name)}
|
|
202
83
|
SET ${(0, quoteIdentifier_js_1.default)(newColumn)} = ${(0, quoteIdentifier_js_1.default)(column)};
|
|
203
|
-
|
|
84
|
+
${mapping}
|
|
204
85
|
UPDATE ${(0, quoteIdentifier_js_1.default)(table.name)}
|
|
205
86
|
SET ${(0, quoteIdentifier_js_1.default)(newColumn)} = m.canonical
|
|
206
87
|
FROM mapping m
|
|
207
88
|
WHERE ${(0, quoteIdentifier_js_1.default)(table.name)}.${(0, quoteIdentifier_js_1.default)(newColumn)} = m.original`
|
|
208
|
-
:
|
|
89
|
+
: `${mapping}
|
|
209
90
|
UPDATE ${(0, quoteIdentifier_js_1.default)(table.name)}
|
|
210
91
|
SET ${(0, quoteIdentifier_js_1.default)(column)} = m.canonical
|
|
211
92
|
FROM mapping m
|
|
@@ -54,17 +54,7 @@ async function executeFuzzyJoin(leftTable, rightTable, outputTable, leftColumn,
|
|
|
54
54
|
}
|
|
55
55
|
const method = options.method ?? "ratio";
|
|
56
56
|
const similarityColumn = options.similarityColumn;
|
|
57
|
-
|
|
58
|
-
// rightColumn can be shared, checked above) is excluded from the SELECT
|
|
59
|
-
// directly, instead of dropping its _1 duplicate with a rewrite after the
|
|
60
|
-
// join.
|
|
61
|
-
const rightSelect = rightCols
|
|
62
|
-
.filter((d) => !leftCols.includes(d))
|
|
63
|
-
.map((d) => `${(0, quoteIdentifier_js_1.default)(rightTable.name)}.${(0, quoteIdentifier_js_1.default)(d)}`)
|
|
64
|
-
.join(", ");
|
|
65
|
-
const sql = `INSTALL rapidfuzz FROM community; LOAD rapidfuzz;\n` +
|
|
66
|
-
fuzzyJoinQuery(leftTable.name, leftColumn, rightTable.name, rightColumn, method, threshold, outputTable.name, similarityColumn, rightSelect, options.prefilterPrefixLength);
|
|
67
|
-
await (0, queryDB_js_1.default)(leftTable, sql, (0, mergeOptions_js_1.default)(leftTable, {
|
|
57
|
+
const queryOptions = (0, mergeOptions_js_1.default)(leftTable, {
|
|
68
58
|
table: outputTable.name,
|
|
69
59
|
method: "fuzzyJoin()",
|
|
70
60
|
parameters: {
|
|
@@ -74,26 +64,90 @@ async function executeFuzzyJoin(leftTable, rightTable, outputTable, leftColumn,
|
|
|
74
64
|
threshold,
|
|
75
65
|
options,
|
|
76
66
|
},
|
|
77
|
-
})
|
|
67
|
+
});
|
|
68
|
+
const deduplicate = await shouldDeduplicateFuzzyJoin(leftTable, rightTable, leftColumn, rightColumn, queryOptions);
|
|
69
|
+
// The right table's copy of a column shared with the left table (only
|
|
70
|
+
// rightColumn can be shared, checked above) is excluded from the SELECT
|
|
71
|
+
// directly, instead of dropping its _1 duplicate with a rewrite after the
|
|
72
|
+
// join.
|
|
73
|
+
const rightSelect = rightCols
|
|
74
|
+
.filter((d) => !leftCols.includes(d))
|
|
75
|
+
.map((d) => `${(0, quoteIdentifier_js_1.default)(rightTable.name)}.${(0, quoteIdentifier_js_1.default)(d)}`)
|
|
76
|
+
.join(", ");
|
|
77
|
+
const sql = `INSTALL rapidfuzz FROM community; LOAD rapidfuzz;\n` +
|
|
78
|
+
fuzzyJoinQuery(leftTable.name, leftColumn, rightTable.name, rightColumn, method, threshold, outputTable.name, similarityColumn, rightSelect, options.prefilterPrefixLength, deduplicate);
|
|
79
|
+
await (0, queryDB_js_1.default)(leftTable, sql, queryOptions);
|
|
78
80
|
}
|
|
79
|
-
function
|
|
81
|
+
async function shouldDeduplicateFuzzyJoin(leftTable, rightTable, leftColumn, rightColumn, queryOptions) {
|
|
82
|
+
const left = (0, quoteIdentifier_js_1.default)(leftTable.name);
|
|
83
|
+
const right = (0, quoteIdentifier_js_1.default)(rightTable.name);
|
|
84
|
+
const counts = (await (0, queryDB_js_1.default)(leftTable, `SELECT (SELECT COUNT(*) FROM ${left}) AS left_count,
|
|
85
|
+
(SELECT COUNT(*) FROM ${right}) AS right_count`, { ...queryOptions, returnData: true }))[0];
|
|
86
|
+
const leftCount = Number(counts.left_count);
|
|
87
|
+
const rightCount = Number(counts.right_count);
|
|
88
|
+
const comparisons = leftCount * rightCount;
|
|
89
|
+
// Avoid distinct scans for small joins and short lookup tables. For larger
|
|
90
|
+
// joins, require at least a twofold reduction to pay for grouping and rejoining.
|
|
91
|
+
if (comparisons < 100_000 || Math.min(leftCount, rightCount) < 32) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
const distinct = (await (0, queryDB_js_1.default)(leftTable, `SELECT
|
|
95
|
+
(SELECT COUNT(DISTINCT ENCODE(${(0, quoteIdentifier_js_1.default)(leftColumn)})) FROM ${left}) AS left_count,
|
|
96
|
+
(SELECT COUNT(DISTINCT ENCODE(${(0, quoteIdentifier_js_1.default)(rightColumn)})) FROM ${right}) AS right_count`, { ...queryOptions, returnData: true }))[0];
|
|
97
|
+
return Number(distinct.left_count) * Number(distinct.right_count) <=
|
|
98
|
+
comparisons / 2;
|
|
99
|
+
}
|
|
100
|
+
function fuzzyJoinQuery(leftTable, leftColumn, rightTable, rightColumn, method, threshold, outputTable, similarityColumn, rightSelect, prefilterPrefixLength, deduplicate = false) {
|
|
80
101
|
const leftExpression = `${(0, quoteIdentifier_js_1.default)(leftTable)}.${(0, quoteIdentifier_js_1.default)(leftColumn)}`;
|
|
81
102
|
const rightExpression = `${(0, quoteIdentifier_js_1.default)(rightTable)}.${(0, quoteIdentifier_js_1.default)(rightColumn)}`;
|
|
82
103
|
const { scoreExpression, condition } = (0, buildFuzzyMatchSql_js_1.default)(leftExpression, rightExpression, method, threshold, { decimals: 2, prefilterPrefixLength });
|
|
104
|
+
let cte = "";
|
|
105
|
+
let from = `FROM ${(0, quoteIdentifier_js_1.default)(leftTable)} LEFT JOIN ${(0, quoteIdentifier_js_1.default)(rightTable)} ON ${condition}`;
|
|
106
|
+
let score = scoreExpression;
|
|
107
|
+
if (deduplicate) {
|
|
108
|
+
const matches = (0, quoteIdentifier_js_1.default)(`__sda_fuzzy_matches_${crypto.randomUUID().replaceAll("-", "")}`);
|
|
109
|
+
const match = (0, buildFuzzyMatchSql_js_1.default)("l.value", "r.value", method, threshold, { decimals: 2, prefilterPrefixLength });
|
|
110
|
+
// Keep the original value's collation for prefix matching, but use byte
|
|
111
|
+
// keys for deduplication and expansion: fuzzy scores distinguish case even
|
|
112
|
+
// when an input column has a case-insensitive collation.
|
|
113
|
+
cte = `WITH ${matches} AS MATERIALIZED (
|
|
114
|
+
SELECT l.key AS left_key, r.key AS right_key,
|
|
115
|
+
${match.scoreExpression} AS score
|
|
116
|
+
FROM (
|
|
117
|
+
SELECT DISTINCT ${(0, quoteIdentifier_js_1.default)(leftColumn)} AS value,
|
|
118
|
+
ENCODE(${(0, quoteIdentifier_js_1.default)(leftColumn)}) AS key
|
|
119
|
+
FROM ${(0, quoteIdentifier_js_1.default)(leftTable)}
|
|
120
|
+
WHERE ${(0, quoteIdentifier_js_1.default)(leftColumn)} IS NOT NULL
|
|
121
|
+
) l
|
|
122
|
+
INNER JOIN (
|
|
123
|
+
SELECT DISTINCT ${(0, quoteIdentifier_js_1.default)(rightColumn)} AS value,
|
|
124
|
+
ENCODE(${(0, quoteIdentifier_js_1.default)(rightColumn)}) AS key
|
|
125
|
+
FROM ${(0, quoteIdentifier_js_1.default)(rightTable)}
|
|
126
|
+
WHERE ${(0, quoteIdentifier_js_1.default)(rightColumn)} IS NOT NULL
|
|
127
|
+
) r ON ${match.condition}
|
|
128
|
+
)`;
|
|
129
|
+
from = `FROM ${(0, quoteIdentifier_js_1.default)(leftTable)}
|
|
130
|
+
LEFT JOIN ${matches} ON ENCODE(${leftExpression}) = ${matches}.left_key
|
|
131
|
+
LEFT JOIN ${(0, quoteIdentifier_js_1.default)(rightTable)}
|
|
132
|
+
ON ENCODE(${rightExpression}) = ${matches}.right_key`;
|
|
133
|
+
score = `${matches}.score`;
|
|
134
|
+
}
|
|
83
135
|
if (similarityColumn) {
|
|
84
136
|
return `CREATE OR REPLACE TABLE ${(0, quoteIdentifier_js_1.default)(outputTable)} AS
|
|
137
|
+
${cte}
|
|
85
138
|
SELECT * EXCLUDE ("_sda_score"), "_sda_score" AS ${(0, quoteIdentifier_js_1.default)(similarityColumn)}
|
|
86
139
|
FROM (
|
|
87
|
-
SELECT ${(0, quoteIdentifier_js_1.default)(leftTable)}.*, ${rightSelect}, ${
|
|
88
|
-
|
|
140
|
+
SELECT ${(0, quoteIdentifier_js_1.default)(leftTable)}.*, ${rightSelect}, ${score} AS "_sda_score"
|
|
141
|
+
${from}
|
|
89
142
|
) _sda
|
|
90
143
|
ORDER BY ${(0, quoteIdentifier_js_1.default)(leftColumn)}, "_sda_score" DESC;\n`;
|
|
91
144
|
}
|
|
92
145
|
return `CREATE OR REPLACE TABLE ${(0, quoteIdentifier_js_1.default)(outputTable)} AS
|
|
146
|
+
${cte}
|
|
93
147
|
SELECT *
|
|
94
148
|
FROM (
|
|
95
149
|
SELECT ${(0, quoteIdentifier_js_1.default)(leftTable)}.*, ${rightSelect}
|
|
96
|
-
|
|
150
|
+
${from}
|
|
97
151
|
) _sda
|
|
98
152
|
ORDER BY ${(0, quoteIdentifier_js_1.default)(leftColumn)}, ${(0, quoteIdentifier_js_1.default)(rightColumn)};\n`;
|
|
99
153
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type SimpleTable from "../class/SimpleTable.js";
|
|
2
|
+
type Options = NonNullable<Parameters<SimpleTable["hdbscan"]>[2]>;
|
|
3
|
+
export default function hdbscan(table: SimpleTable, columns: string | string[], newColumn: string, options?: Options): void;
|
|
4
|
+
export {};
|
|
5
|
+
//# sourceMappingURL=hdbscan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hdbscan.d.ts","sourceRoot":"","sources":["../../src/methods/hdbscan.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAWvD,KAAK,OAAO,GAAG,WAAW,CAAC,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAElE,MAAM,CAAC,OAAO,UAAU,OAAO,CAC7B,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,EAC1B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,OAAY,GACpB,IAAI,CASN"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = hdbscan;
|
|
7
|
+
const node_api_1 = require("@duckdb/node-api");
|
|
8
|
+
const appendColumnBatches_js_1 = __importDefault(require("../helpers/appendColumnBatches.js"));
|
|
9
|
+
const buildApproximateMutualReachabilityMst_js_1 = __importDefault(require("../helpers/buildApproximateMutualReachabilityMst.js"));
|
|
10
|
+
const buildExactMutualReachabilityMst_js_1 = __importDefault(require("../helpers/buildExactMutualReachabilityMst.js"));
|
|
11
|
+
const clusterHdbscan_js_1 = __importDefault(require("../helpers/clusterHdbscan.js"));
|
|
12
|
+
const foldIdentifier_js_1 = __importDefault(require("../helpers/foldIdentifier.js"));
|
|
13
|
+
const prepareNumericFeatures_js_1 = __importDefault(require("../helpers/prepareNumericFeatures.js"));
|
|
14
|
+
const publishPreparedColumns_js_1 = __importDefault(require("../helpers/publishPreparedColumns.js"));
|
|
15
|
+
const queueOp_js_1 = __importDefault(require("../helpers/queueOp.js"));
|
|
16
|
+
const quoteIdentifier_js_1 = __importDefault(require("../helpers/quoteIdentifier.js"));
|
|
17
|
+
function hdbscan(table, columns, newColumn, options = {}) {
|
|
18
|
+
const selected = typeof columns === "string" ? columns : [...columns];
|
|
19
|
+
const settings = structuredClone(options);
|
|
20
|
+
(0, queueOp_js_1.default)(table, {
|
|
21
|
+
kind: "barrier",
|
|
22
|
+
method: "hdbscan()",
|
|
23
|
+
parameters: { columns: selected, newColumn, options: settings },
|
|
24
|
+
execute: () => execute(table, selected, newColumn, settings),
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
async function execute(table, columns, newColumn, options) {
|
|
28
|
+
const { minClusterSize = 5, metric = "euclidean", allowSingleCluster = false, approximate = false, membershipScoreColumn, outlierScoreColumn, } = options;
|
|
29
|
+
const minSamples = options.minSamples ?? minClusterSize;
|
|
30
|
+
if (typeof newColumn !== "string") {
|
|
31
|
+
throw new Error("hdbscan() newColumn must be a string.");
|
|
32
|
+
}
|
|
33
|
+
if (!Number.isSafeInteger(minClusterSize) || minClusterSize < 2) {
|
|
34
|
+
throw new Error("hdbscan() minClusterSize must be a safe integer of at least 2.");
|
|
35
|
+
}
|
|
36
|
+
if (!Number.isSafeInteger(minSamples) || minSamples < 1) {
|
|
37
|
+
throw new Error("hdbscan() minSamples must be a safe integer of at least 1.");
|
|
38
|
+
}
|
|
39
|
+
if (!["euclidean", "cosine"].includes(metric)) {
|
|
40
|
+
throw new Error('hdbscan() metric must be "euclidean" or "cosine".');
|
|
41
|
+
}
|
|
42
|
+
if (typeof allowSingleCluster !== "boolean") {
|
|
43
|
+
throw new Error("hdbscan() allowSingleCluster must be a boolean.");
|
|
44
|
+
}
|
|
45
|
+
if (typeof approximate !== "boolean") {
|
|
46
|
+
throw new Error("hdbscan() approximate must be a boolean.");
|
|
47
|
+
}
|
|
48
|
+
if (membershipScoreColumn !== undefined &&
|
|
49
|
+
typeof membershipScoreColumn !== "string") {
|
|
50
|
+
throw new Error("hdbscan() membershipScoreColumn must be a string.");
|
|
51
|
+
}
|
|
52
|
+
if (outlierScoreColumn !== undefined &&
|
|
53
|
+
typeof outlierScoreColumn !== "string") {
|
|
54
|
+
throw new Error("hdbscan() outlierScoreColumn must be a string.");
|
|
55
|
+
}
|
|
56
|
+
const sourceColumns = Object.keys(await table.getTypes());
|
|
57
|
+
const outputNames = [newColumn, membershipScoreColumn, outlierScoreColumn]
|
|
58
|
+
.filter((name) => name !== undefined);
|
|
59
|
+
validateOutputNames(sourceColumns, outputNames);
|
|
60
|
+
const prepared = await (0, prepareNumericFeatures_js_1.default)(table, typeof columns === "string"
|
|
61
|
+
? { kind: "vector", column: columns }
|
|
62
|
+
: { kind: "scalars", columns }, { method: "hdbscan()" });
|
|
63
|
+
const connection = table.connection;
|
|
64
|
+
const suffix = crypto.randomUUID().replaceAll("-", "");
|
|
65
|
+
const name = (part) => `__sda_hdbscan_${suffix}_${part}`;
|
|
66
|
+
const names = {
|
|
67
|
+
rows: name("rows"),
|
|
68
|
+
neighbors: name("neighbors"),
|
|
69
|
+
search: name("search"),
|
|
70
|
+
hnsw: name("hnsw"),
|
|
71
|
+
candidates: name("candidates"),
|
|
72
|
+
coreDistances: name("core_distances"),
|
|
73
|
+
frontier: name("frontier"),
|
|
74
|
+
edges: name("edges"),
|
|
75
|
+
components: name("components"),
|
|
76
|
+
representatives: name("representatives"),
|
|
77
|
+
componentPairs: name("component_pairs"),
|
|
78
|
+
bridgeCandidates: name("bridge_candidates"),
|
|
79
|
+
mst: name("mst"),
|
|
80
|
+
result: name("result"),
|
|
81
|
+
};
|
|
82
|
+
try {
|
|
83
|
+
if (prepared.rowCount < 2) {
|
|
84
|
+
throw new Error(`hdbscan() requires at least 2 rows, but the input has ${prepared.rowCount}.`);
|
|
85
|
+
}
|
|
86
|
+
if (prepared.rowCount > 0x40000000) {
|
|
87
|
+
throw new Error("hdbscan() supports at most 1073741824 rows because its 2*n-1 hierarchy nodes use signed INTEGER identifiers.");
|
|
88
|
+
}
|
|
89
|
+
if (minSamples >= prepared.rowCount) {
|
|
90
|
+
const defaulted = options.minSamples === undefined
|
|
91
|
+
? " (defaulted from minClusterSize)"
|
|
92
|
+
: "";
|
|
93
|
+
throw new Error(`hdbscan() minSamples is ${minSamples}${defaulted}, but ${prepared.rowCount} rows provide at most ${prepared.rowCount - 1} other point${prepared.rowCount === 2 ? "" : "s"}. Set minSamples between 1 and ${prepared.rowCount - 1}, or provide at least ${minSamples + 1} rows.`);
|
|
94
|
+
}
|
|
95
|
+
if (minClusterSize > prepared.rowCount) {
|
|
96
|
+
throw new Error(`hdbscan() minClusterSize is ${minClusterSize}, but the input has ${prepared.rowCount} rows. Set minClusterSize between 2 and ${prepared.rowCount}, or provide more rows.`);
|
|
97
|
+
}
|
|
98
|
+
const q = quoteIdentifier_js_1.default;
|
|
99
|
+
await connection.run(`CREATE TEMP TABLE ${q(names.rows)} AS
|
|
100
|
+
SELECT ${q(prepared.rowIdColumn)}::INTEGER AS vertex,
|
|
101
|
+
${q(prepared.vectorColumn)} AS vec
|
|
102
|
+
FROM ${q(prepared.relation)}
|
|
103
|
+
ORDER BY ${q(prepared.rowIdColumn)}`);
|
|
104
|
+
if (approximate) {
|
|
105
|
+
await (0, buildApproximateMutualReachabilityMst_js_1.default)(connection, {
|
|
106
|
+
count: prepared.rowCount,
|
|
107
|
+
dimensions: prepared.dimensions,
|
|
108
|
+
minSamples,
|
|
109
|
+
}, { metric }, {
|
|
110
|
+
rows: names.rows,
|
|
111
|
+
neighbors: names.neighbors,
|
|
112
|
+
search: names.search,
|
|
113
|
+
hnsw: names.hnsw,
|
|
114
|
+
candidates: names.candidates,
|
|
115
|
+
coreDistances: names.coreDistances,
|
|
116
|
+
edges: names.edges,
|
|
117
|
+
components: names.components,
|
|
118
|
+
representatives: names.representatives,
|
|
119
|
+
componentPairs: names.componentPairs,
|
|
120
|
+
bridgeCandidates: names.bridgeCandidates,
|
|
121
|
+
mst: names.mst,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
await (0, buildExactMutualReachabilityMst_js_1.default)(connection, { count: prepared.rowCount, minSamples }, { metric }, {
|
|
126
|
+
rows: q(names.rows),
|
|
127
|
+
coreDistances: q(names.coreDistances),
|
|
128
|
+
frontier: q(names.frontier),
|
|
129
|
+
mst: q(names.mst),
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
const result = await (0, clusterHdbscan_js_1.default)(connection, q(names.mst), {
|
|
133
|
+
count: prepared.rowCount,
|
|
134
|
+
minClusterSize,
|
|
135
|
+
allowSingleCluster,
|
|
136
|
+
});
|
|
137
|
+
const labelColumn = "label";
|
|
138
|
+
const membershipColumn = "membership";
|
|
139
|
+
const gloshColumn = "glosh";
|
|
140
|
+
const resultColumns = [
|
|
141
|
+
"row_id INTEGER",
|
|
142
|
+
`${labelColumn} VARCHAR`,
|
|
143
|
+
membershipScoreColumn === undefined
|
|
144
|
+
? undefined
|
|
145
|
+
: `${membershipColumn} DOUBLE`,
|
|
146
|
+
outlierScoreColumn === undefined ? undefined : `${gloshColumn} DOUBLE`,
|
|
147
|
+
].filter((definition) => definition !== undefined);
|
|
148
|
+
await connection.run(`CREATE TEMP TABLE ${q(names.result)} (${resultColumns.join(",")})`);
|
|
149
|
+
const outputTypes = [
|
|
150
|
+
node_api_1.INTEGER,
|
|
151
|
+
node_api_1.VARCHAR,
|
|
152
|
+
...(membershipScoreColumn === undefined ? [] : [node_api_1.DOUBLE]),
|
|
153
|
+
...(outlierScoreColumn === undefined ? [] : [node_api_1.DOUBLE]),
|
|
154
|
+
];
|
|
155
|
+
await (0, appendColumnBatches_js_1.default)(connection, names.result, outputTypes, prepared.rowCount, (column, start, end) => {
|
|
156
|
+
if (column === 0) {
|
|
157
|
+
return Array.from({ length: end - start }, (_, offset) => start + offset);
|
|
158
|
+
}
|
|
159
|
+
if (column === 1) {
|
|
160
|
+
return Array.from(result.labels.subarray(start, end), (label) => label < 0 ? "noise" : `cluster-${label}`);
|
|
161
|
+
}
|
|
162
|
+
const membershipIndex = membershipScoreColumn === undefined ? -1 : 2;
|
|
163
|
+
return Array.from(column === membershipIndex
|
|
164
|
+
? result.probabilities.subarray(start, end)
|
|
165
|
+
: result.outlierScores.subarray(start, end));
|
|
166
|
+
});
|
|
167
|
+
const publicationOutputs = [{
|
|
168
|
+
name: newColumn,
|
|
169
|
+
expression: `r.${q(labelColumn)}`,
|
|
170
|
+
}];
|
|
171
|
+
if (membershipScoreColumn !== undefined) {
|
|
172
|
+
publicationOutputs.push({
|
|
173
|
+
name: membershipScoreColumn,
|
|
174
|
+
expression: `r.${q(membershipColumn)}`,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
if (outlierScoreColumn !== undefined) {
|
|
178
|
+
publicationOutputs.push({
|
|
179
|
+
name: outlierScoreColumn,
|
|
180
|
+
expression: `r.${q(gloshColumn)}`,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
await (0, publishPreparedColumns_js_1.default)(table, prepared, {
|
|
184
|
+
method: "hdbscan()",
|
|
185
|
+
parameters: { columns, newColumn, options },
|
|
186
|
+
result: { relation: names.result, rowIdColumn: "row_id" },
|
|
187
|
+
outputs: publicationOutputs,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
finally {
|
|
191
|
+
for (const relation of Object.entries(names).reverse().flatMap(([key, value]) => key === "hnsw" ? [] : [value])) {
|
|
192
|
+
await connection.run(`DROP TABLE IF EXISTS ${(0, quoteIdentifier_js_1.default)(relation)}`);
|
|
193
|
+
}
|
|
194
|
+
await prepared.cleanup();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
function validateOutputNames(sourceColumns, outputNames) {
|
|
198
|
+
const seen = new Map();
|
|
199
|
+
for (const name of outputNames) {
|
|
200
|
+
if (name.length === 0 || name.includes("\0")) {
|
|
201
|
+
throw new Error("hdbscan() output column names must be non-empty strings without null characters.");
|
|
202
|
+
}
|
|
203
|
+
const folded = (0, foldIdentifier_js_1.default)(name);
|
|
204
|
+
const source = sourceColumns.find((column) => (0, foldIdentifier_js_1.default)(column) === folded);
|
|
205
|
+
if (source !== undefined) {
|
|
206
|
+
throw new Error(`hdbscan() cannot create ${(0, quoteIdentifier_js_1.default)(name)} because that source column already exists. Remove it first or choose different output names.`);
|
|
207
|
+
}
|
|
208
|
+
const duplicate = seen.get(folded);
|
|
209
|
+
if (duplicate !== undefined) {
|
|
210
|
+
throw new Error(`hdbscan() output columns ${(0, quoteIdentifier_js_1.default)(duplicate)} and ${(0, quoteIdentifier_js_1.default)(name)} refer to the same column. Choose distinct output names.`);
|
|
211
|
+
}
|
|
212
|
+
seen.set(folded, name);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type SimpleTable from "../class/SimpleTable.js";
|
|
2
|
+
type Options = NonNullable<Parameters<SimpleTable["mahalanobis"]>[3]>;
|
|
3
|
+
export default function mahalanobis(table: SimpleTable, columns: string | string[], referencePoint: number[], newColumn: string, options?: Options): void;
|
|
4
|
+
export {};
|
|
5
|
+
//# sourceMappingURL=mahalanobis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mahalanobis.d.ts","sourceRoot":"","sources":["../../src/methods/mahalanobis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AASvD,KAAK,OAAO,GAAG,WAAW,CAAC,UAAU,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEtE,MAAM,CAAC,OAAO,UAAU,WAAW,CACjC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,EAC1B,cAAc,EAAE,MAAM,EAAE,EACxB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,OAAY,GACpB,IAAI,CAyBN"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = mahalanobis;
|
|
7
|
+
const computeCovariance_js_1 = __importDefault(require("../helpers/computeCovariance.js"));
|
|
8
|
+
const computeMahalanobisDistances_js_1 = __importDefault(require("../helpers/computeMahalanobisDistances.js"));
|
|
9
|
+
const foldIdentifier_js_1 = __importDefault(require("../helpers/foldIdentifier.js"));
|
|
10
|
+
const prepareNumericFeatures_js_1 = __importDefault(require("../helpers/prepareNumericFeatures.js"));
|
|
11
|
+
const publishPreparedColumns_js_1 = __importDefault(require("../helpers/publishPreparedColumns.js"));
|
|
12
|
+
const queueOp_js_1 = __importDefault(require("../helpers/queueOp.js"));
|
|
13
|
+
const quoteIdentifier_js_1 = __importDefault(require("../helpers/quoteIdentifier.js"));
|
|
14
|
+
function mahalanobis(table, columns, referencePoint, newColumn, options = {}) {
|
|
15
|
+
if (!Array.isArray(referencePoint) || referencePoint.length === 0 ||
|
|
16
|
+
Array.from(referencePoint).some((value) => typeof value !== "number" || !Number.isFinite(value))) {
|
|
17
|
+
throw new Error("mahalanobis() referencePoint must be a nonempty array of finite numbers in feature-dimension order.");
|
|
18
|
+
}
|
|
19
|
+
const selected = typeof columns === "string" ? columns : [...columns];
|
|
20
|
+
const reference = [...referencePoint];
|
|
21
|
+
const settings = { ...options };
|
|
22
|
+
(0, queueOp_js_1.default)(table, {
|
|
23
|
+
kind: "barrier",
|
|
24
|
+
method: "mahalanobis()",
|
|
25
|
+
parameters: {
|
|
26
|
+
columns: selected,
|
|
27
|
+
referencePoint: reference,
|
|
28
|
+
newColumn,
|
|
29
|
+
options: settings,
|
|
30
|
+
},
|
|
31
|
+
execute: () => execute(table, selected, reference, newColumn, settings),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
async function execute(table, columns, referencePoint, newColumn, options) {
|
|
35
|
+
const sourceColumns = Object.keys(await table.getTypes());
|
|
36
|
+
const outputNames = options.similarityScoreColumn === undefined
|
|
37
|
+
? [newColumn]
|
|
38
|
+
: [newColumn, options.similarityScoreColumn];
|
|
39
|
+
const seen = new Set();
|
|
40
|
+
for (const name of outputNames) {
|
|
41
|
+
if (typeof name !== "string" || name.length === 0 || name.includes("\0")) {
|
|
42
|
+
throw new Error("mahalanobis() output column names must be nonempty strings without null characters.");
|
|
43
|
+
}
|
|
44
|
+
const folded = (0, foldIdentifier_js_1.default)(name);
|
|
45
|
+
if (seen.has(folded)) {
|
|
46
|
+
throw new Error("mahalanobis() distance and similarity score columns must have different names (case-insensitive).");
|
|
47
|
+
}
|
|
48
|
+
seen.add(folded);
|
|
49
|
+
if (sourceColumns.some((column) => (0, foldIdentifier_js_1.default)(column) === folded)) {
|
|
50
|
+
throw new Error(`mahalanobis() cannot create ${(0, quoteIdentifier_js_1.default)(name)} because that column already exists. Remove it first or choose a different name.`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const prepared = await (0, prepareNumericFeatures_js_1.default)(table, typeof columns === "string"
|
|
54
|
+
? { kind: "vector", column: columns }
|
|
55
|
+
: { kind: "scalars", columns }, { method: "mahalanobis()" });
|
|
56
|
+
try {
|
|
57
|
+
if (referencePoint.length !== prepared.dimensions) {
|
|
58
|
+
throw new Error(`mahalanobis() referencePoint must contain ${prepared.dimensions} values in feature-dimension order; received ${referencePoint.length}.`);
|
|
59
|
+
}
|
|
60
|
+
const model = await (0, computeCovariance_js_1.default)(table.connection, {
|
|
61
|
+
relation: prepared.relation,
|
|
62
|
+
rowIdColumn: prepared.rowIdColumn,
|
|
63
|
+
vectorColumn: prepared.vectorColumn,
|
|
64
|
+
observations: prepared.rowCount,
|
|
65
|
+
dimensions: prepared.dimensions,
|
|
66
|
+
});
|
|
67
|
+
const distances = await (0, computeMahalanobisDistances_js_1.default)(table.connection, {
|
|
68
|
+
relation: prepared.relation,
|
|
69
|
+
rowIdColumn: prepared.rowIdColumn,
|
|
70
|
+
vectorColumn: prepared.vectorColumn,
|
|
71
|
+
}, model, referencePoint);
|
|
72
|
+
try {
|
|
73
|
+
const distance = `r.${(0, quoteIdentifier_js_1.default)(distances.distanceColumn)}`;
|
|
74
|
+
const outputs = [{ name: newColumn, expression: distance }];
|
|
75
|
+
if (options.similarityScoreColumn !== undefined) {
|
|
76
|
+
outputs.push({
|
|
77
|
+
name: options.similarityScoreColumn,
|
|
78
|
+
expression: `CASE WHEN max(${distance}) OVER () = 0 THEN 1::DOUBLE ELSE 1 - ${distance} / max(${distance}) OVER () END`,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
await (0, publishPreparedColumns_js_1.default)(table, prepared, {
|
|
82
|
+
method: "mahalanobis()",
|
|
83
|
+
parameters: { columns, referencePoint, newColumn, options },
|
|
84
|
+
result: {
|
|
85
|
+
relation: distances.relation,
|
|
86
|
+
rowIdColumn: distances.rowIdColumn,
|
|
87
|
+
},
|
|
88
|
+
outputs,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
await distances.cleanup();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
await prepared.cleanup();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type GraphId } from "../helpers/prepareGraphStarts.js";
|
|
2
|
+
import type SimpleTable from "../class/SimpleTable.js";
|
|
3
|
+
type NeighborsOptions = {
|
|
4
|
+
direction?: "outgoing" | "incoming" | "both";
|
|
5
|
+
outputTable?: string | boolean;
|
|
6
|
+
};
|
|
7
|
+
export default function neighbors(simpleTable: SimpleTable, sourceColumn: string, targetColumn: string, startNodes: GraphId | GraphId[], options?: NeighborsOptions): SimpleTable;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=neighbors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"neighbors.d.ts","sourceRoot":"","sources":["../../src/methods/neighbors.ts"],"names":[],"mappings":"AAAA,OAA2B,EACzB,KAAK,OAAO,EAEb,MAAM,kCAAkC,CAAC;AAO1C,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAGvD,KAAK,gBAAgB,GAAG;IACtB,SAAS,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;IAC7C,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAChC,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,OAAO,GAAG,OAAO,EAAE,EAC/B,OAAO,GAAE,gBAAqB,GAC7B,WAAW,CAuEb"}
|