differential-privacy
Version:
Implements Global Differential Privacy for almost any numeric function
114 lines • 5.29 kB
JavaScript
;
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