From bb0108fb60d9670a5f5aec296a261076173fa0b3 Mon Sep 17 00:00:00 2001 From: NunoSempere Date: Wed, 15 Jun 2022 23:00:54 -0400 Subject: [PATCH] feat: Add utility tools I'm hoping to have these be a separate package that are also used in the website. --- .gitignore | 3 + .vscode/settings.json | 3 - packages/utility-tools/README.md | 9 + packages/utility-tools/input/input-links.json | 241 +++++++++ packages/utility-tools/input/input-list.json | 47 ++ packages/utility-tools/output/output.txt | 95 ++++ packages/utility-tools/package.json | 15 + packages/utility-tools/src/aggregatePaths.js | 54 ++ packages/utility-tools/src/findPaths.js | 314 +++++++++++ packages/utility-tools/src/index.js | 60 +++ packages/utility-tools/src/mergeSort.js | 115 ++++ packages/utility-tools/yarn.lock | 498 ++++++++++++++++++ 12 files changed, 1451 insertions(+), 3 deletions(-) delete mode 100644 .vscode/settings.json create mode 100644 packages/utility-tools/README.md create mode 100644 packages/utility-tools/input/input-links.json create mode 100644 packages/utility-tools/input/input-list.json create mode 100644 packages/utility-tools/output/output.txt create mode 100644 packages/utility-tools/package.json create mode 100644 packages/utility-tools/src/aggregatePaths.js create mode 100644 packages/utility-tools/src/findPaths.js create mode 100644 packages/utility-tools/src/index.js create mode 100644 packages/utility-tools/src/mergeSort.js create mode 100644 packages/utility-tools/yarn.lock diff --git a/.gitignore b/.gitignore index 0d80623..e9ec88d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,9 @@ # personal notes Notes.md +# personal outputs +packages/utility-tools/input/input-links-* + # vim files .swp diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index a4df25f..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "cSpell.words": ["Stdev"] -} diff --git a/packages/utility-tools/README.md b/packages/utility-tools/README.md new file mode 100644 index 0000000..0ee865f --- /dev/null +++ b/packages/utility-tools/README.md @@ -0,0 +1,9 @@ +## Utility function processor + +This package contains a series of utilities to work with the utility functions produced by [this utility function extractor](https://utility-function-extractor.quantifieduncertainty.org/openphil-2018-ai-risk) + +### Merge sort + +Given a list of elements and a list of utilitity comparisons, sort the list. + +Gotcha: The list of elements has to be the same list, and in the same order, as that produced when initially doing the comparisons. This is because the merge-sort algorithm depends on the initial order of the list. diff --git a/packages/utility-tools/input/input-links.json b/packages/utility-tools/input/input-links.json new file mode 100644 index 0000000..dfd7b73 --- /dev/null +++ b/packages/utility-tools/input/input-links.json @@ -0,0 +1,241 @@ +[ + { + "source": "Stanford University — Machine Learning Security Research Led by Dan Boneh and Florian Tramer", + + "target": "Wilson Center — AI Policy Seminar Series", + + "distance": 4.039836724233664, + + "reasoning": "Jaime's estimates.\nThe Wilson Center seems to not be running the AI Policy Seminar Series anymore, so I am led to believe it was not a great success (?). There could be someone key influenced that will facilitate things later but seems unlikely\nThe ML Security program does not seem to have resulted on anything substantial", + + "squiggleString": "1 to 10" + }, + + { + "source": "Stanford University — Machine Learning Security Research Led by Dan Boneh and Florian Tramer", + + "target": "Open Phil AI Fellowship — 2018 Class", + + "distance": 657.4661082204123, + + "reasoning": "The AI fellows have produced work on interpretability and out of distribution learning.\nSeems to have been better for purchasing influence too, though that's a secondary consideration IMO", + + "squiggleString": "400 to 1000" + }, + + { + "source": "Wilson Center — AI Policy Seminar Series", + + "target": "Open Phil AI Fellowship — 2018 Class", + + "distance": 403.9836724233662, + + "reasoning": "The research seems more directly relevant from the AI fellows, the policy seminar has no legible output", + + "squiggleString": "100 to 1000" + }, + + { + "source": "UC Berkeley — AI Safety Research (2018)", + + "target": "Machine Intelligence Research Institute — AI Safety Retraining Program", + + "distance": 40.39836724233665, + + "reasoning": "Seems to support directly people working on the topic, and more counterfactual", + + "squiggleString": "10 to 100" + }, + + { + "source": "Stanford University — Machine Learning Security Research Led by Dan Boneh and Florian Tramer", + + "target": "UC Berkeley — AI Safety Research (2018)", + + "distance": 7.229755173700019, + + "reasoning": "AI Safety Research Affects more people, someone might end up doing something cool", + + "squiggleString": "5 to 10" + }, + + { + "source": "Wilson Center — AI Policy Seminar Series", + + "target": "UC Berkeley — AI Safety Research (2018)", + + "distance": 2.663515640351876, + + "reasoning": "Similar value from the outside", + + "squiggleString": "0.1 to 10" + }, + + { + "source": "UC Berkeley — AI Safety Research (2018)", + + "target": "Open Phil AI Fellowship — 2018 Class", + + "distance": 247.53475654135346, + + "reasoning": "AI fellows produced directly relevant research, are more successful", + + "squiggleString": "(1/(0.001 to 0.01))" + }, + + { + "source": "Machine Intelligence Research Institute — AI Safety Retraining Program", + + "target": "Open Phil AI Fellowship — 2018 Class", + + "distance": 49.50695130827075, + + "reasoning": "aI fellows seem to have produced more relevant research, though grant is less counterfactual", + + "squiggleString": "(1/(0.005 to 0.05))" + }, + + { + "source": "Ought — General Support (2018)", + + "target": "Oxford University — Research on the Global Politics of AI", + + "distance": 403.9836724233662, + + "reasoning": "GovAI is doing cool stuff, Ought not so much", + + "squiggleString": "100 to 1000" + }, + + { + "source": "AI Impacts — General Support (2018)", + + "target": "Michael Cohen and Dmitrii Krasheninnikov — Scholarship Support (2018)", + + "distance": 2.5202870466776885, + + "reasoning": "Direct work seems more important, but Ai impacts work is pretty cool", + + "squiggleString": "1 to 5" + }, + + { + "source": "Ought — General Support (2018)", + + "target": "AI Impacts — General Support (2018)", + + "distance": 109.28343925564944, + + "reasoning": "AI impacts work has been more successful \\ useful for my research", + + "squiggleString": "50 to 200" + }, + + { + "source": "AI Impacts — General Support (2018)", + + "target": "Oxford University — Research on the Global Politics of AI", + + "distance": 39.678020061969825, + + "reasoning": "GovAI is doing more work and on a more neglected topic. Both are doing good work, but GOvAI output is bigger", + + "squiggleString": "(1/(0.01 to 0.05))" + }, + + { + "source": "Oxford University — Research on the Global Politics of AI", + + "target": "Michael Cohen and Dmitrii Krasheninnikov — Scholarship Support (2018)", + + "distance": 2.865987655844147, + + "reasoning": "Cohens work seems harder to replace.\nGovAI is doing more work though", + + "squiggleString": "0.01 to 10" + }, + + { + "source": "Stanford University — Machine Learning Security Research Led by Dan Boneh and Florian Tramer", + + "target": "Ought — General Support (2018)", + + "distance": 14.338510859889407, + + "reasoning": "At least Ought is trying ", + + "squiggleString": "1 to 50" + }, + + { + "source": "Wilson Center — AI Policy Seminar Series", + + "target": "Ought — General Support (2018)", + + "distance": 2.663515640351876, + + "reasoning": "Unclear", + + "squiggleString": "0.1 to 10" + }, + + { + "source": "UC Berkeley — AI Safety Research (2018)", + + "target": "Ought — General Support (2018)", + + "distance": 4.039836724233664, + + "reasoning": "At least ought is trying", + + "squiggleString": "1 to 10" + }, + + { + "source": "Machine Intelligence Research Institute — AI Safety Retraining Program", + + "target": "Ought — General Support (2018)", + + "distance": 1.4338510859889406, + + "reasoning": "Value more the potential new hire than oughts research", + + "squiggleString": "0.1 to 5" + }, + + { + "source": "Ought — General Support (2018)", + + "target": "Open Phil AI Fellowship — 2018 Class", + + "distance": 247.53475654135346, + + "reasoning": "Fellows seem to have produced more relevant research", + + "squiggleString": "(1/(0.001 to 0.01))" + }, + + { + "source": "AI Impacts — General Support (2018)", + + "target": "Open Phil AI Fellowship — 2018 Class", + + "distance": 13.831727022205978, + + "reasoning": "Fellows produced more relevant research, AI impacts work is cool though", + + "squiggleString": "(1/(0.05 to 0.1))" + }, + + { + "source": "Open Phil AI Fellowship — 2018 Class", + + "target": "Oxford University — Research on the Global Politics of AI", + + "distance": 32.87330541102063, + + "reasoning": "GovAI's grant seems moe counterfactual, their work more directly relevant\n", + + "squiggleString": "20 to 50" + } +] diff --git a/packages/utility-tools/input/input-list.json b/packages/utility-tools/input/input-list.json new file mode 100644 index 0000000..fc1913d --- /dev/null +++ b/packages/utility-tools/input/input-list.json @@ -0,0 +1,47 @@ +[ + { + "name": "Michael Cohen and Dmitrii Krasheninnikov — Scholarship Support (2018)", + "url": "https://docs.google.com/document/d/1VlN6I4Jauarx-0Fp7AC1ggeQ02AITsN7S56ffAO9NTU/edit#heading=h.jnlrsr63yliq", + "amount": "$159k" + }, + { + "name": "AI Impacts — General Support (2018)", + "url": "https://docs.google.com/document/d/1VlN6I4Jauarx-0Fp7AC1ggeQ02AITsN7S56ffAO9NTU/edit#heading=h.6m6tebpouzt1", + "amount": "$100k" + }, + { + "name": "Oxford University — Research on the Global Politics of AI", + "url": "https://docs.google.com/document/d/1VlN6I4Jauarx-0Fp7AC1ggeQ02AITsN7S56ffAO9NTU/edit#heading=h.c6r2m7i749ay", + "amount": "$429k" + }, + { + "name": "Ought — General Support (2018)", + "url": "https://docs.google.com/document/d/1VlN6I4Jauarx-0Fp7AC1ggeQ02AITsN7S56ffAO9NTU/edit#heading=h.xnzaj48k3fdb", + "amount": "$525k" + }, + { + "name": "Machine Intelligence Research Institute — AI Safety Retraining Program", + "url": "https://docs.google.com/document/d/1VlN6I4Jauarx-0Fp7AC1ggeQ02AITsN7S56ffAO9NTU/edit#heading=h.h922w7eh5rq6", + "amount": "$150k" + }, + { + "name": "UC Berkeley — AI Safety Research (2018)", + "url": "https://docs.google.com/document/d/1VlN6I4Jauarx-0Fp7AC1ggeQ02AITsN7S56ffAO9NTU/edit#heading=h.rrsbecbboed8", + "amount": "$1.145M" + }, + { + "name": "Open Phil AI Fellowship — 2018 Class", + "url": "https://docs.google.com/document/d/1VlN6I4Jauarx-0Fp7AC1ggeQ02AITsN7S56ffAO9NTU/edit#heading=h.p8xd58asz6a2", + "amount": "$1.135M" + }, + { + "name": "Wilson Center — AI Policy Seminar Series", + "url": "https://docs.google.com/document/d/1VlN6I4Jauarx-0Fp7AC1ggeQ02AITsN7S56ffAO9NTU/edit#heading=h.qiurhycylgi3", + "amount": "$400k" + }, + { + "name": "Stanford University — Machine Learning Security Research Led by Dan Boneh and Florian Tramer", + "url": "https://docs.google.com/document/d/1VlN6I4Jauarx-0Fp7AC1ggeQ02AITsN7S56ffAO9NTU/edit#heading=h.ox8adhpgba86", + "amount": "$100k" + } +] diff --git a/packages/utility-tools/output/output.txt b/packages/utility-tools/output/output.txt new file mode 100644 index 0000000..3560337 --- /dev/null +++ b/packages/utility-tools/output/output.txt @@ -0,0 +1,95 @@ +Sorted output: + [ + 'Stanford University — Machine Learning Security Research Led by Dan Boneh and Florian Tramer', + 'Wilson Center — AI Policy Seminar Series', + 'UC Berkeley — AI Safety Research (2018)', + 'Machine Intelligence Research Institute — AI Safety Retraining Program', + 'Ought — General Support (2018)', + 'AI Impacts — General Support (2018)', + 'Open Phil AI Fellowship — 2018 Class', + 'Oxford University — Research on the Global Politics of AI', + 'Michael Cohen and Dmitrii Krasheninnikov — Scholarship Support (2018)' + ] + +Stanford University — Machine Learning Security Research Led by Dan Boneh and Florian Tramer + Number of paths: 102 + Mean: 0.04340463625937361 + 90% confidence interval: [ + 3.102187977841675e-7, + 0.10636313508232977 + ] + 3.902 seconds needed for processing + +Wilson Center — AI Policy Seminar Series + Number of paths: 52 + Mean: 0.23923636834715892 + 90% confidence interval: [ + 0.0000012797707857581555, + 0.7647175734237982 + ] + 0.855 seconds needed for processing + +UC Berkeley — AI Safety Research (2018) + Number of paths: 37 + Mean: 0.6148765126821536 + 90% confidence interval: [ + 0.0000012857319777641759, + 2.4285898907477064 + ] + 0.484 seconds needed for processing + +Machine Intelligence Research Institute — AI Safety Retraining Program + Number of paths: 21 + Mean: 46.33576477417035 + 90% confidence interval: [ + 0.000022241280559831212, + 201.37264605399085 + ] + 0.173 seconds needed for processing + +Ought — General Support (2018) + Number of paths: 36 + Mean: 63.37826067838051 + 90% confidence interval: [ + 0.00004411196776834627, + 145.5050535108514 + ] + 0.412 seconds needed for processing + +AI Impacts — General Support (2018) + Number of paths: 47 + Mean: 9862.157135402398 + 90% confidence interval: [ + 0.018650934888088284, + 22307.090052203544 + ] + 0.635 seconds needed for processing + +Open Phil AI Fellowship — 2018 Class + Number of paths: 372 + Mean: 86301.01328794319 + 90% confidence interval: [ + 26.02179139839112, + 115734.18190287006 + ] + 35.203 seconds needed for processing + +Oxford University — Research on the Global Politics of AI + Number of paths: 2261 + Mean: 785779.6653748289 + 90% confidence interval: [ + 114.32195138741375, + 960250.7929788446 + ] + 1048.955 seconds needed for processing + +Michael Cohen and Dmitrii Krasheninnikov — Scholarship Support (2018) + Number of paths: 5243 + Mean: 1482642.2273006735 + 90% confidence interval: [ + 8.379381400123396, + 330071.1150485886 + ] + 5550.563 seconds needed for processing + + diff --git a/packages/utility-tools/package.json b/packages/utility-tools/package.json new file mode 100644 index 0000000..d4d12fe --- /dev/null +++ b/packages/utility-tools/package.json @@ -0,0 +1,15 @@ +{ + "name": "utility-tools", + "version": "0.0.1", + "description": "Process the json produced by utility-function-extractor.quantifieduncertainty.org", + "scripts": { + "start": "node --max-old-space-size=8192 src/index.js" + }, + "type": "module", + "main": "src/index.js", + "author": "Nuño Sempere", + "license": "MIT", + "dependencies": { + "@quri/squiggle-lang": "^0.2.11" + } +} diff --git a/packages/utility-tools/src/aggregatePaths.js b/packages/utility-tools/src/aggregatePaths.js new file mode 100644 index 0000000..0a61e7f --- /dev/null +++ b/packages/utility-tools/src/aggregatePaths.js @@ -0,0 +1,54 @@ +// EXPORTS +import { run } from "@quri/squiggle-lang"; + +export function aggregatePaths(pathsArray, nodes) { + pathsArray.map((paths, i) => { + console.log(nodes[i].name); + let multipliedDistributions = paths.map( + (path) => path.multipliedDistributionsInPath + ); + console.group(); + console.log("Number of paths: ", multipliedDistributions.length); + // console.log(multipliedDistributions.slice(0, 10)); + let squiggleCode = `aggregatePath = mx(${multipliedDistributions + .filter((distributions) => distributions != undefined) + // .slice(0, 600) + .join(", ")})`; + + // Start measuring time + let start = Date.now(); + + // Get the mean + let squiggleCodeForMean = squiggleCode + "\n" + "mean(aggregatePath)"; + let meanAnswer = run(squiggleCodeForMean); + let mean = meanAnswer.value.value; + console.log(`Mean: ${mean}`); + + // Get the 90% CI + let squiggleCodeFor90CI = + squiggleCode + + "\n" + + "[inv(aggregatePath, 0.05), inv(aggregatePath, 0.95)]"; + let ci90percentAnswer = run(squiggleCodeFor90CI); + + // Display output + let processCI90 = (answer) => { + let value = answer.value.value; + let lower = value[0].value; + let upper = value[1].value; + return [lower, upper]; + }; + console.log( + `90% confidence interval: ${JSON.stringify( + processCI90(ci90percentAnswer), + null, + 4 + )}` + ); + // Stop measuring time + let end = Date.now(); + console.log(`${(end - start) / 1000} seconds needed for processing`); + console.groupEnd(); + console.log(""); + }); +} diff --git a/packages/utility-tools/src/findPaths.js b/packages/utility-tools/src/findPaths.js new file mode 100644 index 0000000..5e957ba --- /dev/null +++ b/packages/utility-tools/src/findPaths.js @@ -0,0 +1,314 @@ +/* Functions */ + +const pathPlusLink = (pathSoFar, link) => { + return [...pathSoFar, link]; + // previously: pathSoFar.concat(link).flat() + // Note that concat is not destructive + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat +}; + +const findElementPosition = (name, nodes) => { + let node = nodes.find((node) => node.name == name); + return node.position; +}; + +async function findPathsWithoutPrunning({ + sourceElementName, + targetElementName, + maxLengthOfPath, + pathSoFar, + links, + nodes, +}) { + // This is an un-used function which might make findPaths more understandable + // It uses the same recursive functionality + // but has no path prunning + let paths = []; + + /* Path traversing */ + if (maxLengthOfPath > 0) { + for (let link of links) { + // vs let link of linksNow in findPaths + if ( + (link.source == sourceElementName && + link.target == targetElementName) || + (link.source == targetElementName && link.target == sourceElementName) + ) { + // direct Path + let newPath = pathPlusLink(pathSoFar, link); + paths.push(newPath); + } else if (link.source == sourceElementName) { + let newPaths = await findPaths({ + pathSoFar: pathPlusLink(pathSoFar, link), + maxLengthOfPath: maxLengthOfPath - 1, + sourceElementName: link.target, + targetElementName, + links: links, // vs let link of linksInner in findPaths + nodes, + }); + if (newPaths.length != 0) { + paths.push(...newPaths); + } + } else if (link.target == sourceElementName) { + let newPaths = await findPaths({ + pathSoFar: pathPlusLink(pathSoFar, link), + maxLengthOfPath: maxLengthOfPath - 1, + sourceElementName: link.source, + targetElementName, + links: links, // vs let link of linksInner in findPaths + nodes, + }); + if (newPaths.length != 0) { + paths.push(...newPaths); + } + } + } + } + + return paths; +} + +async function findPaths({ + sourceElementName, + sourceElementPosition, + targetElementName, + targetElementPosition, + maxLengthOfPath, + pathSoFar, + links, + nodes, +}) { + // This is the key path finding function + // It finds the path from one element to another, recursively + // It used to be very computationally expensive until I added + // the path prunning step: Instead of traversing all links, + // traverse only those which are between the origin and target links + // this requires us to have a notion of "between" + + let paths = []; + + /* Path prunning*/ + let minPos = Math.min(sourceElementPosition, targetElementPosition); + let maxPos = Math.max(sourceElementPosition, targetElementPosition); + let linksInner = links.filter( + (link) => + minPos <= link.sourceElementPosition && + link.sourceElementPosition <= maxPos && + minPos <= link.targetElementPosition && + link.targetElementPosition <= maxPos + ); + let linksNow = linksInner.filter( + (link) => + link.source == sourceElementName || link.target == sourceElementName + ); + + /* Path traversing */ + if (maxLengthOfPath > 0) { + for (let link of linksNow) { + if ( + (link.source == sourceElementName && + link.target == targetElementName) || + (link.source == targetElementName && link.target == sourceElementName) + ) { + // direct Path + let newPath = pathPlusLink(pathSoFar, link); + paths.push(newPath); + } else if (link.source == sourceElementName) { + let newPaths = await findPaths({ + pathSoFar: pathPlusLink(pathSoFar, link), + maxLengthOfPath: maxLengthOfPath - 1, + sourceElementPosition: link.sourceElementPosition, + sourceElementName: link.target, + targetElementName, + targetElementPosition, + links: linksInner, + nodes, + }); + if (newPaths.length != 0) { + paths.push(...newPaths); + } + } else if (link.target == sourceElementName) { + let newPaths = await findPaths({ + pathSoFar: pathPlusLink(pathSoFar, link), + maxLengthOfPath: maxLengthOfPath - 1, + sourceElementPosition: link.sourceElementPosition, + sourceElementName: link.source, + targetElementPosition, + targetElementName, + links: linksInner, + nodes, + }); + if (newPaths.length != 0) { + paths.push(...newPaths); + } + } + } + } + + return paths; +} + +async function findExpectedValuesAndDistributionsForElement({ + sourceElementName, + sourceElementPosition, + targetElementName, + targetElementPosition, + nodes, + links, +}) { + // This function gets all possible paths using findPaths + // then orders them correctly in the for loop + // (by flipping the distance to 1/distance when necessary) + // and then gets the array of weights for the different paths. + /* + console.log( + `findDistance@findPaths.js from ${sourceElementPosition} to ${targetElementPosition}` + ); + */ + let maxLengthOfPath = Math.abs(sourceElementPosition - targetElementPosition); + let paths = await findPaths({ + sourceElementName, + sourceElementPosition, + targetElementName, + targetElementPosition, + links, + nodes, + maxLengthOfPath, + pathSoFar: [], + }); + + let processedPaths = []; + for (let path of paths) { + let currentSource = sourceElementName; + let expectedRelativeValue = 1; + let multipliedDistributionsInPath = 1; + let distances = []; + for (let element of path) { + let distance = 0; + let anotherDistributionInPath = 1; + if (element.source == currentSource) { + distance = element.distance; + anotherDistributionInPath = element.squiggleString; + currentSource = element.target; + } else if (element.target == currentSource) { + distance = 1 / Number(element.distance); + anotherDistributionInPath = `1 / (${element.squiggleString})`; + currentSource = element.source; + } + expectedRelativeValue = expectedRelativeValue * distance; + distances.push(distance); + multipliedDistributionsInPath = `${multipliedDistributionsInPath} * (${anotherDistributionInPath})`; + } + processedPaths.push({ + distances, + expectedRelativeValue, + multipliedDistributionsInPath, + // path, + }); + } + return processedPaths; + + /* + let expectedValues = []; + for (let path of paths) { + let currentSource = sourceElementName; + let weight = 1; + for (let element of path) { + let distance = 0; + if (element.source == currentSource) { + distance = element.distance; + currentSource = element.target; + } else if (element.target == currentSource) { + distance = 1 / Number(element.distance); + currentSource = element.source; + } + weight = weight * distance; + } + expectedValues.push(weight); + } + + let distributionalForm = []; + for (let path of paths) { + let currentSource = sourceElementName; + let multipliedDistributionsInPath = 1; + for (let element of path) { + let anotherDistributionInPath; + if (element.source == currentSource) { + distributionInPath = element.squiggleString; + currentSource = element.target; + } else if (element.target == currentSource) { + distance = `1 / (${element.squiggleString})`; + currentSource = element.source; + } + multipliedDistributionsInPath = `${multipliedDistributionsInPath} * (${anotherDistributionInPath})`; + } + distributionalForm.push(multipliedDistributionsInPath); + } + return { + expectedValues, + distributionalForm, + // paths, + }; + */ +} + +async function findDistancesFromAllElementsToReferencePoint({ + nodes, + links, + referenceElement, +}) { + // Simple wrapper function around findDistance + // Needs to find the reference point first + // console.log("findDistancesForAllElements@findPaths.js"); + /* Get or build reference element */ + let midpoint = Math.round(nodes.length / 2); + referenceElement = referenceElement || nodes[midpoint]; + // console.log(`referenceElement.position: ${referenceElement.position}`); + + /* Get distances. */ + let distancesArray = nodes.map((node) => { + if (node.name == referenceElement.name) { + return [1]; + } else { + // console.log("node"); + // console.log(node); + let expectedValuesAndDistributionsForElement = + findExpectedValuesAndDistributionsForElement({ + sourceElementName: referenceElement.name, + sourceElementPosition: referenceElement.position, + targetElementName: node.name, + targetElementPosition: node.position, + nodes: nodes, + links: links, + }); + return expectedValuesAndDistributionsForElement; + } + }); + distancesArray = await Promise.all(distancesArray); + return distancesArray; +} + +export async function findDistancesFromAllElementsToAllReferencePoints({ + nodes, + links, +}) { + let nodes2 = nodes.map((node) => ({ ...node, isReferenceValue: false })); + let distancesForAllElements = Array(nodes.length); + for (let i = 0; i < nodes.length; i++) { + distancesForAllElements[i] = []; + } + for (let node of nodes2) { + let distancesFromNode = await findDistancesFromAllElementsToReferencePoint({ + nodes: nodes2, + links, + referenceElement: node, + }); + // alert(`distancesFromNode.length: ${distancesFromNode.length}`); + distancesForAllElements = distancesForAllElements.map((arr, i) => { + return !!arr && arr.length > 0 + ? [...arr, ...distancesFromNode[i]] + : distancesFromNode[i]; + }); + } + return distancesForAllElements; +} diff --git a/packages/utility-tools/src/index.js b/packages/utility-tools/src/index.js new file mode 100644 index 0000000..4c1094c --- /dev/null +++ b/packages/utility-tools/src/index.js @@ -0,0 +1,60 @@ +// IMPORTS +import * as fs from "fs"; +import { mergeSort } from "./mergeSort.js"; +import { findDistancesFromAllElementsToAllReferencePoints } from "./findPaths.js"; +import { aggregatePaths } from "./aggregatePaths.js"; + +// DEFS +const inputLinksFilePath = "./input/input-links.json"; +const inputListFilePath = "./input/input-list.json"; +const outputFilePath = "./output/output.json"; + +// HELPERS + +const findElementPosition = (name, orderedList) => { + let node = orderedList.find((node) => node.name == name); + return node.position; +}; + +// MAIN +async function main() { + // read file + const inputLinksAsString = fs.readFileSync(inputLinksFilePath); + const inputListAsString = fs.readFileSync(inputListFilePath); + const links = JSON.parse(inputLinksAsString); + const list = JSON.parse(inputListAsString); + + // process file + // const sources = links.map((link) => link.source); + // const targets = links.map((link) => link.target); + // const list = [...new Set([...sources, ...targets])]; + + // Merge sort + let mergeSortOutput = mergeSort({ list, links }); + // console.log("Output: "); + console.log("Sorted output: "); + console.group(); + console.log(mergeSortOutput.map((x) => x.name)); + console.groupEnd(); + console.log(""); + + // find Paths + let nodes = mergeSortOutput.map((element, i) => ({ + ...element, + position: i, + })); + const linksWithPosition = links.map((link) => ({ + ...link, + sourceElementPosition: findElementPosition(link.source, nodes), + targetElementPosition: findElementPosition(link.target, nodes), + })); + let paths = await findDistancesFromAllElementsToAllReferencePoints({ + nodes, + links: linksWithPosition, + }); + // console.log(JSON.stringify(paths, null, 4)); + + // Aggregate paths. + let aggregatedPaths = aggregatePaths(paths, nodes); +} +main(); diff --git a/packages/utility-tools/src/mergeSort.js b/packages/utility-tools/src/mergeSort.js new file mode 100644 index 0000000..68812a7 --- /dev/null +++ b/packages/utility-tools/src/mergeSort.js @@ -0,0 +1,115 @@ +const errorMsg = "No link found; unable to proceed"; + +function isFirstElementGreater(links, element1, element2) { + const relevantComparisons = links.filter( + (link) => + (link.source == element1.name && link.target == element2.name) || + (link.source == element2.name && link.target == element1.name) + ); + if (relevantComparisons.length == 0) { + // console.log(element1, "vs", element2); + return errorMsg; + } else { + const firstLink = relevantComparisons[0]; + // console.log(firstLink); + const firstElementFirst = + firstLink.source == element1.name && firstLink.target == element2.name + ? true + : false; + const distanceIsGreaterThanOne = Number(firstLink.distance) > 1; + const answer = + (firstElementFirst && !distanceIsGreaterThanOne) || + (!firstElementFirst && distanceIsGreaterThanOne); + return !answer; + } +} + +function merge(links, left, right) { + let sortedArr = []; // the sorted elements will go here + + while (left.length && right.length) { + // insert the biggest element to the sortedArr + let link = isFirstElementGreater(links, left[0], right[0]); + if (link == errorMsg) { + // console.log("Error@:"); + // console.group(); + // console.log({ left, right }); + // console.groupEnd(); + return errorMsg; + } else if (link) { + // left[0] > right[0] + sortedArr.push(left.shift()); + } else { + sortedArr.push(right.shift()); + } + } + + // use spread operator and create a new array, combining the three arrays + return [...sortedArr, ...left, ...right]; // if they don't have the same size, the remaining ones will be greater than the ones before +} + +export function mergeSortInner({ list, links }) { + // console.log({ l: list.length }); + if (list == errorMsg) { + return errorMsg; + } + const half = list.length / 2; + + // the base case is list length <=1 + if (list.length <= 1) { + return list; + } + + const left = list.slice(0, half); // the first half of the list + const right = list.slice(half, list.length); // Note that splice is destructive. + let orderedFirstHalf = mergeSortInner({ list: left, links }); + let orderedSecondHalf = mergeSortInner({ list: right, links }); + if (orderedFirstHalf != errorMsg && orderedSecondHalf != errorMsg) { + let result = merge(links, orderedFirstHalf, orderedSecondHalf); + return result; + } else { + return errorMsg; + } +} + +export function mergeSort({ list, links }) { + // Try normally + let answer = mergeSortInner({ list, links }); + if (answer != errorMsg) return answer; + + // otherwise + let permutation = list.slice(); + var length = list.length; + // let result = [list.slice()]; + let c = new Array(length).fill(0); + let i = 1; + let k; + let p; + let counter = 0; + + while (i < length) { + counter++; + if (counter > 10) console.log(counter); + if (c[i] < i) { + k = i % 2 && c[i]; + p = permutation[i]; + permutation[i] = permutation[k]; + permutation[k] = p; + // ++c[i]; + c[i] = c[i] + 1; + i = 1; + let answer = mergeSortInner({ list: permutation, links }); + if (answer != errorMsg) { + console.log(answer); + return answer; + } + // result.push(permutation.slice()); + } else { + c[i] = 0; + i = i + 1; + // ++i; + } + } + console.log("Error"); + return "Error: The original list was wrongly ordered, and trying permutations didn't work"; +} diff --git a/packages/utility-tools/yarn.lock b/packages/utility-tools/yarn.lock new file mode 100644 index 0000000..027a1de --- /dev/null +++ b/packages/utility-tools/yarn.lock @@ -0,0 +1,498 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/runtime@^7.18.3": + version "7.18.3" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.3.tgz#c7b654b57f6f63cf7f8b418ac9ca04408c4579f4" + integrity sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug== + dependencies: + regenerator-runtime "^0.13.4" + +"@quri/squiggle-lang@^0.2.11": + version "0.2.11" + resolved "https://registry.yarnpkg.com/@quri/squiggle-lang/-/squiggle-lang-0.2.11.tgz#fc9df37c1c5537b4da099c71c8249373210cfadf" + integrity sha512-n879EbSS0eWWEl+s38XmB4xDy18wOJSk3t7moCxIGDhUc70aH1kgNhg56M+M57a8f55MbIhhr7kAVb9RbqqhuA== + dependencies: + "@stdlib/stats" "^0.0.13" + jstat "^1.9.5" + lodash "^4.17.21" + mathjs "^10.6.0" + pdfast "^0.2.0" + rescript "^9.1.4" + +"@stdlib/array@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/array/-/array-0.0.12.tgz#12f40ab95bb36d424cdad991f29fc3cb491ee29e" + integrity sha512-nDksiuvRC1dSTHrf5yOGQmlRwAzSKV8MdFQwFSvLbZGGhi5Y4hExqea5HloLgNVouVs8lnAFi2oubSM4Mc7YAg== + dependencies: + "@stdlib/assert" "^0.0.x" + "@stdlib/blas" "^0.0.x" + "@stdlib/complex" "^0.0.x" + "@stdlib/constants" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/symbol" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/assert@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/assert/-/assert-0.0.12.tgz#1648c9016e5041291f55a6464abcc4069c5103ce" + integrity sha512-38FxFf+ZoQZbdc+m09UsWtaCmzd/2e7im0JOaaFYE7icmRfm+4KiE9BRvBT4tIn7ioLB2f9PsBicKjIsf+tY1w== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/cli" "^0.0.x" + "@stdlib/complex" "^0.0.x" + "@stdlib/constants" "^0.0.x" + "@stdlib/fs" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/ndarray" "^0.0.x" + "@stdlib/number" "^0.0.x" + "@stdlib/os" "^0.0.x" + "@stdlib/process" "^0.0.x" + "@stdlib/regexp" "^0.0.x" + "@stdlib/streams" "^0.0.x" + "@stdlib/string" "^0.0.x" + "@stdlib/symbol" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/bigint@^0.0.x": + version "0.0.11" + resolved "https://registry.yarnpkg.com/@stdlib/bigint/-/bigint-0.0.11.tgz#c416a1d727001c55f4897e6424124199d638f2fd" + integrity sha512-uz0aYDLABAYyqxaCSHYbUt0yPkXYUCR7TrVvHN+UUD3i8FZ02ZKcLO+faKisDyxKEoSFTNtn3Ro8Ir5ebOlVXQ== + dependencies: + "@stdlib/utils" "^0.0.x" + +"@stdlib/blas@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/blas/-/blas-0.0.12.tgz#7e93e42b4621fc6903bf63264f045047333536c2" + integrity sha512-nWY749bWceuoWQ7gz977blCwR7lyQ/rsIXVO4b600h+NFpeA2i/ea7MYC680utIbeu2cnDWHdglBPoK535VAzA== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/assert" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/number" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/buffer@^0.0.x": + version "0.0.11" + resolved "https://registry.yarnpkg.com/@stdlib/buffer/-/buffer-0.0.11.tgz#6137b00845e6c905181cc7ebfae9f7e47c01b0ce" + integrity sha512-Jeie5eDDa1tVuRcuU+cBXI/oOXSmMxUUccZpqXzgYe0IO8QSNtNxv9mUTzJk/m5wH+lmLoDvNxzPpOH9TODjJg== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/assert" "^0.0.x" + "@stdlib/process" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/cli@^0.0.x": + version "0.0.10" + resolved "https://registry.yarnpkg.com/@stdlib/cli/-/cli-0.0.10.tgz#28e2fbe6865d7f5cd15b7dc5846c99bd3b91674f" + integrity sha512-OITGaxG46kwK799+NuOd/+ccosJ9koVuQBC610DDJv0ZJf8mD7sbjGXrmue9C4EOh8MP7Vm/6HN14BojX8oTCg== + dependencies: + "@stdlib/utils" "^0.0.x" + minimist "^1.2.0" + +"@stdlib/complex@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/complex/-/complex-0.0.12.tgz#3afbc190cd0a9b37fc7c6e508c3aa9fda9106944" + integrity sha512-UbZBdaUxT2G+lsTIrVlRZwx2IRY6GXnVILggeejsIVxHSuK+oTyapfetcAv0FJFLP+Rrr+ZzrN4b9G3hBw6NHA== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/assert" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/constants@^0.0.x": + version "0.0.11" + resolved "https://registry.yarnpkg.com/@stdlib/constants/-/constants-0.0.11.tgz#78cd56d6c2982b30264843c3d75bde7125e90cd2" + integrity sha512-cWKy0L9hXHUQTvFzdPkTvZnn/5Pjv7H4UwY0WC1rLt+A5CxFDJKjvnIi9ypSzJS3CAiGl1ZaHCdadoqXhNdkUg== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/assert" "^0.0.x" + "@stdlib/number" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/fs@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/fs/-/fs-0.0.12.tgz#662365fd5846a51f075724b4f2888ae88441b70d" + integrity sha512-zcDLbt39EEM3M3wJW6luChS53B8T+TMJkjs2526UpKJ71O0/0adR57cI7PfCpkMd33d05uM7GM+leEj4eks4Cw== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/assert" "^0.0.x" + "@stdlib/cli" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/process" "^0.0.x" + "@stdlib/string" "^0.0.x" + "@stdlib/utils" "^0.0.x" + debug "^2.6.9" + +"@stdlib/math@^0.0.x": + version "0.0.11" + resolved "https://registry.yarnpkg.com/@stdlib/math/-/math-0.0.11.tgz#eb6638bc03a20fbd6727dd5b977ee0170bda4649" + integrity sha512-qI78sR1QqGjHj8k/aAqkZ51Su2fyBvaR/jMKQqcB/ML8bpYpf+QGlGvTty5Qdru/wpqds4kVFOVbWGcNFIV2+Q== + dependencies: + "@stdlib/assert" "^0.0.x" + "@stdlib/constants" "^0.0.x" + "@stdlib/ndarray" "^0.0.x" + "@stdlib/number" "^0.0.x" + "@stdlib/strided" "^0.0.x" + "@stdlib/symbol" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + debug "^2.6.9" + +"@stdlib/ndarray@^0.0.x": + version "0.0.13" + resolved "https://registry.yarnpkg.com/@stdlib/ndarray/-/ndarray-0.0.13.tgz#2e8fc645e10f56a645a0ab81598808c0e8f43b82" + integrity sha512-Z+U9KJP4U2HWrLtuAXSPvhNetAdqaNLMcliR6S/fz+VPlFDeymRK7omRFMgVQ+1zcAvIgKZGJxpLC3vjiPUYEw== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/assert" "^0.0.x" + "@stdlib/bigint" "^0.0.x" + "@stdlib/buffer" "^0.0.x" + "@stdlib/complex" "^0.0.x" + "@stdlib/constants" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/number" "^0.0.x" + "@stdlib/string" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/nlp@^0.0.x": + version "0.0.11" + resolved "https://registry.yarnpkg.com/@stdlib/nlp/-/nlp-0.0.11.tgz#532ec0f7267b8d639e4c20c6de864e8de8a09054" + integrity sha512-D9avYWANm0Db2W7RpzdSdi5GxRYALGAqUrNnRnnKIO6sMEfr/DvONoAbWruda4QyvSC+0MJNwcEn7+PHhRwYhw== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/assert" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/random" "^0.0.x" + "@stdlib/string" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/number@^0.0.x": + version "0.0.10" + resolved "https://registry.yarnpkg.com/@stdlib/number/-/number-0.0.10.tgz#4030ad8fc3fac19a9afb415c443cee6deea0e65c" + integrity sha512-RyfoP9MlnX4kccvg8qv7vYQPbLdzfS1Mnp/prGOoWhvMG3pyBwFAan34kwFb5IS/zHC3W5EmrgXCV2QWyLg/Kg== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/assert" "^0.0.x" + "@stdlib/constants" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/os" "^0.0.x" + "@stdlib/string" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/os@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/os/-/os-0.0.12.tgz#08bbf013c62a7153099fa9cbac086ca1349a4677" + integrity sha512-O7lklZ/9XEzoCmYvzjPh7jrFWkbpOSHGI71ve3dkSvBy5tyiSL3TtivfKsIC+9ZxuEJZ3d3lIjc9e+yz4HVbqQ== + dependencies: + "@stdlib/assert" "^0.0.x" + "@stdlib/cli" "^0.0.x" + "@stdlib/fs" "^0.0.x" + "@stdlib/process" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/process@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/process/-/process-0.0.12.tgz#123325079d89a32f4212f72fb694f8fe3614cf18" + integrity sha512-P0X0TMvkissBE1Wr877Avi2/AxmP7X5Toa6GatHbpJdDg6jQmN4SgPd+NZNp98YtZUyk478c8XSIzMr1krQ20g== + dependencies: + "@stdlib/assert" "^0.0.x" + "@stdlib/buffer" "^0.0.x" + "@stdlib/cli" "^0.0.x" + "@stdlib/fs" "^0.0.x" + "@stdlib/streams" "^0.0.x" + "@stdlib/string" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/random@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/random/-/random-0.0.12.tgz#e819c3abd602ed5559ba800dba751e49c633ff85" + integrity sha512-c5yND4Ahnm9Jx0I+jsKhn4Yrz10D53ALSrIe3PG1qIz3kNFcIPnmvCuNGd+3V4ch4Mbrez55Y8z/ZC5RJh4vJQ== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/assert" "^0.0.x" + "@stdlib/blas" "^0.0.x" + "@stdlib/buffer" "^0.0.x" + "@stdlib/cli" "^0.0.x" + "@stdlib/constants" "^0.0.x" + "@stdlib/fs" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/process" "^0.0.x" + "@stdlib/stats" "^0.0.x" + "@stdlib/streams" "^0.0.x" + "@stdlib/symbol" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + debug "^2.6.9" + readable-stream "^2.1.4" + +"@stdlib/regexp@^0.0.x": + version "0.0.13" + resolved "https://registry.yarnpkg.com/@stdlib/regexp/-/regexp-0.0.13.tgz#80b98361dc7a441b47bc3fa964bb0c826759e971" + integrity sha512-3JT5ZIoq/1nXY+dY+QtkU8/m7oWDeekyItEEXMx9c/AOf0ph8fmvTUGMDNfUq0RetcznFe3b66kFz6Zt4XHviA== + dependencies: + "@stdlib/assert" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/stats@^0.0.13", "@stdlib/stats@^0.0.x": + version "0.0.13" + resolved "https://registry.yarnpkg.com/@stdlib/stats/-/stats-0.0.13.tgz#87c973f385379d794707c7b5196a173dba8b07e1" + integrity sha512-hm+t32dKbx/L7+7WlQ1o4NDEzV0J4QSnwFBCsIMIAO8+VPxTZ4FxyNERl4oKlS3hZZe4AVKjoOVhBDtgEWrS4g== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/assert" "^0.0.x" + "@stdlib/blas" "^0.0.x" + "@stdlib/constants" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/ndarray" "^0.0.x" + "@stdlib/random" "^0.0.x" + "@stdlib/string" "^0.0.x" + "@stdlib/symbol" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/streams@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/streams/-/streams-0.0.12.tgz#07f5ceae5852590afad8e1cb7ce94174becc8739" + integrity sha512-YLUlXwjJNknHp92IkJUdvn5jEQjDckpawKhDLLCoxyh3h5V+w/8+61SH7TMTfKx5lBxKJ8vvtchZh90mIJOAjQ== + dependencies: + "@stdlib/assert" "^0.0.x" + "@stdlib/buffer" "^0.0.x" + "@stdlib/cli" "^0.0.x" + "@stdlib/fs" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + debug "^2.6.9" + readable-stream "^2.1.4" + +"@stdlib/strided@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/strided/-/strided-0.0.12.tgz#86ac48e660cb7f64a45cf07e80cbbfe58be21ae1" + integrity sha512-1NINP+Y7IJht34iri/bYLY7TVxrip51f6Z3qWxGHUCH33kvk5H5QqV+RsmFEGbbyoGtdeHrT2O+xA+7R2e3SNg== + dependencies: + "@stdlib/assert" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/ndarray" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/string@^0.0.x": + version "0.0.13" + resolved "https://registry.yarnpkg.com/@stdlib/string/-/string-0.0.13.tgz#37457ca49e8d1dff0e523c68f5673c655c79eb2d" + integrity sha512-nGMHi7Qk9LBW0+Y+e3pSePQEBqyWH7+7DjFR1APcbsYccJE0p4aCaQdhPhx9Tp7j3uRGBmqPFek8wpcvIuC+CQ== + dependencies: + "@stdlib/assert" "^0.0.x" + "@stdlib/cli" "^0.0.x" + "@stdlib/constants" "^0.0.x" + "@stdlib/fs" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/nlp" "^0.0.x" + "@stdlib/process" "^0.0.x" + "@stdlib/regexp" "^0.0.x" + "@stdlib/streams" "^0.0.x" + "@stdlib/types" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/symbol@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/symbol/-/symbol-0.0.12.tgz#b9f396b0bf269c2985bb7fe99810a8e26d7288c3" + integrity sha512-2IDhpzWVGeLHgsvIsX12RXvf78r7xBkc4QLoRUv3k7Cp61BisR1Ym1p0Tq9PbxT8fknlvLToh9n5RpmESi2d4w== + dependencies: + "@stdlib/assert" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/time@^0.0.x": + version "0.0.14" + resolved "https://registry.yarnpkg.com/@stdlib/time/-/time-0.0.14.tgz#ea6daa438b1d3b019b99f5091117ee4bcef55d60" + integrity sha512-1gMFCQTabMVIgww+k4g8HHHIhyy1tIlvwT8mC0BHW7Q7TzDAgobwL0bvor+lwvCb5LlDAvNQEpaRgVT99QWGeQ== + dependencies: + "@stdlib/assert" "^0.0.x" + "@stdlib/cli" "^0.0.x" + "@stdlib/constants" "^0.0.x" + "@stdlib/fs" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/string" "^0.0.x" + "@stdlib/utils" "^0.0.x" + +"@stdlib/types@^0.0.x": + version "0.0.14" + resolved "https://registry.yarnpkg.com/@stdlib/types/-/types-0.0.14.tgz#02d3aab7a9bfaeb86e34ab749772ea22f7b2f7e0" + integrity sha512-AP3EI9/il/xkwUazcoY+SbjtxHRrheXgSbWZdEGD+rWpEgj6n2i63hp6hTOpAB5NipE0tJwinQlDGOuQ1lCaCw== + +"@stdlib/utils@^0.0.x": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@stdlib/utils/-/utils-0.0.12.tgz#670de5a7b253f04f11a4cba38f790e82393bcb46" + integrity sha512-+JhFpl6l7RSq/xGnbWRQ5dAL90h9ONj8MViqlb7teBZFtePZLMwoRA1wssypFcJ8SFMRWQn7lPmpYVUkGwRSOg== + dependencies: + "@stdlib/array" "^0.0.x" + "@stdlib/assert" "^0.0.x" + "@stdlib/blas" "^0.0.x" + "@stdlib/buffer" "^0.0.x" + "@stdlib/cli" "^0.0.x" + "@stdlib/constants" "^0.0.x" + "@stdlib/fs" "^0.0.x" + "@stdlib/math" "^0.0.x" + "@stdlib/os" "^0.0.x" + "@stdlib/process" "^0.0.x" + "@stdlib/random" "^0.0.x" + "@stdlib/regexp" "^0.0.x" + "@stdlib/streams" "^0.0.x" + "@stdlib/string" "^0.0.x" + "@stdlib/symbol" "^0.0.x" + "@stdlib/time" "^0.0.x" + "@stdlib/types" "^0.0.x" + debug "^2.6.9" + +complex.js@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/complex.js/-/complex.js-2.1.1.tgz#0675dac8e464ec431fb2ab7d30f41d889fb25c31" + integrity sha512-8njCHOTtFFLtegk6zQo0kkVX1rngygb/KQI6z1qZxlFI3scluC+LVTCFbrkWjBv4vvLlbQ9t88IPMC6k95VTTg== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +decimal.js@^10.3.1: + version "10.3.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" + integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== + +escape-latex@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/escape-latex/-/escape-latex-1.2.0.tgz#07c03818cf7dac250cce517f4fda1b001ef2bca1" + integrity sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw== + +fraction.js@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" + integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== + +inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +javascript-natural-sort@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz#f9e2303d4507f6d74355a73664d1440fb5a0ef59" + integrity sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw== + +jstat@^1.9.5: + version "1.9.5" + resolved "https://registry.yarnpkg.com/jstat/-/jstat-1.9.5.tgz#9941741566f683624ddeb56f5ba60ed8c29b374e" + integrity sha512-cWnp4vObF5GmB2XsIEzxI/1ZTcYlcfNqxQ/9Fp5KFUa0Jf/4tO0ZkGVnqoEHDisJvYgvn5n3eWZbd2xTVJJPUQ== + +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +mathjs@^10.6.0: + version "10.6.1" + resolved "https://registry.yarnpkg.com/mathjs/-/mathjs-10.6.1.tgz#95b34178eed65cbf7a63d35c468ad3ac912f7ddf" + integrity sha512-8iZp6uUKKBoCFoUHze9ydsrSji9/IOEzMhwURyoQXaLL1+ILEZnraw4KzZnUBt/XN6lPJPV+7JO94oil3AmosQ== + dependencies: + "@babel/runtime" "^7.18.3" + complex.js "^2.1.1" + decimal.js "^10.3.1" + escape-latex "^1.2.0" + fraction.js "^4.2.0" + javascript-natural-sort "^0.7.1" + seedrandom "^3.0.5" + tiny-emitter "^2.1.0" + typed-function "^2.1.0" + +minimist@^1.2.0: + version "1.2.6" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" + integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +pdfast@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/pdfast/-/pdfast-0.2.0.tgz#8cbc556e1bf2522177787c0de2e0d4373ba885c9" + integrity sha512-cq6TTu6qKSFUHwEahi68k/kqN2mfepjkGrG9Un70cgdRRKLKY6Rf8P8uvP2NvZktaQZNF3YE7agEkLj0vGK9bA== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +readable-stream@^2.1.4: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +regenerator-runtime@^0.13.4: + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== + +rescript@^9.1.4: + version "9.1.4" + resolved "https://registry.yarnpkg.com/rescript/-/rescript-9.1.4.tgz#1eb126f98d6c16942c0bf0df67c050198e580515" + integrity sha512-aXANK4IqecJzdnDpJUsU6pxMViCR5ogAxzuqS0mOr8TloMnzAjJFu63fjD6LCkWrKAhlMkFFzQvVQYaAaVkFXw== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +seedrandom@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7" + integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg== + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +tiny-emitter@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" + integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== + +typed-function@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/typed-function/-/typed-function-2.1.0.tgz#ded6f8a442ba8749ff3fe75bc41419c8d46ccc3f" + integrity sha512-bctQIOqx2iVbWGDGPWwIm18QScpu2XRmkC19D8rQGFsjKSgteq/o1hTZvIG/wuDq8fanpBDrLkLq+aEN/6y5XQ== + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==