UNPKG

differential-privacy

Version:

Implements Global Differential Privacy for almost any numeric function

114 lines 5.29 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.calculateSensitivity = void 0; var tslib_1 = require("tslib"); var decimal_js_1 = tslib_1.__importDefault(require("decimal.js")); function calculateSensitivity(func, newSubsetIter, dataset, maxConcurrencyCount) { return tslib_1.__awaiter(this, void 0, void 0, function () { var concurrency, pendingDatasetIter, datasetIter, _a, minOutput, maxOutput, pendingCalculations, _loop_1, curIter, state_1; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: concurrency = Math.max(1, Math.min(maxConcurrencyCount, 9999)); pendingDatasetIter = newSubsetIter(dataset); if (!(pendingDatasetIter instanceof Promise)) return [3, 2]; return [4, pendingDatasetIter]; case 1: _a = (_b.sent()); return [3, 3]; case 2: _a = pendingDatasetIter; _b.label = 3; case 3: datasetIter = _a; minOutput = new decimal_js_1.default(Number.POSITIVE_INFINITY); maxOutput = new decimal_js_1.default(Number.NEGATIVE_INFINITY); pendingCalculations = []; _loop_1 = function (curIter) { var curValue, minMaxCalculation; return tslib_1.__generator(this, function (_c) { switch (_c.label) { case 0: curValue = curIter.value; minMaxCalculation = runOnModifiedDataset(func, curValue) .then(function (modResult) { var removeIndex = pendingCalculations .findIndex(function (pc) { return pc === minMaxCalculation; }); pendingCalculations.splice(removeIndex, 1); if (modResult !== undefined) { minOutput = decimal_js_1.default.min(minOutput, modResult); maxOutput = decimal_js_1.default.max(maxOutput, modResult); } }); pendingCalculations.push(minMaxCalculation); if (!(pendingCalculations.length >= concurrency)) return [3, 2]; return [4, pendingCalculations[0]]; case 1: _c.sent(); _c.label = 2; case 2: if (curIter.done) { return [2, "break"]; } return [2]; } }); }; curIter = datasetIter.next(); _b.label = 4; case 4: if (!true) return [3, 7]; return [5, _loop_1(curIter)]; case 5: state_1 = _b.sent(); if (state_1 === "break") return [3, 7]; _b.label = 6; case 6: curIter = datasetIter.next(); return [3, 4]; case 7: return [4, Promise.all(pendingCalculations)]; case 8: _b.sent(); return [2, maxOutput.minus(minOutput)]; } }); }); } exports.calculateSensitivity = calculateSensitivity; function runOnModifiedDataset(func, next) { return tslib_1.__awaiter(this, void 0, void 0, function () { var innerResult, _a, funcRun, funcVal, _b; return tslib_1.__generator(this, function (_c) { switch (_c.label) { case 0: if (!(next instanceof Promise)) return [3, 2]; return [4, next]; case 1: _a = (_c.sent()); return [3, 3]; case 2: _a = next; _c.label = 3; case 3: innerResult = _a; if (next === undefined || innerResult === undefined) { return [2, undefined]; } funcRun = func(innerResult); if (!(funcRun instanceof Promise)) return [3, 5]; return [4, funcRun]; case 4: _b = (_c.sent()); return [3, 6]; case 5: _b = funcRun; _c.label = 6; case 6: funcVal = _b; return [2, new decimal_js_1.default(funcVal)]; } }); }); } //# sourceMappingURL=sensitivity.js.map