siafun
Version:
A collection of structure induction algorithms
136 lines (135 loc) • 6.54 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const _ = require("lodash");
const fs = require("fs");
const child_process_1 = require("child_process");
const util_1 = require("./util");
const siatec_1 = require("./siatec");
const cosiatec_1 = require("./cosiatec");
const heuristics_1 = require("./heuristics");
const optimizer_1 = require("./optimizer");
function opsiatec(points, options) {
const result = getCosiatec(points, options);
if (options.minHeuristicValue != null) { //could be 0 if heuristics go negative
result.patterns = result.patterns.filter((_, i) => result.scores[i] >= options.minHeuristicValue);
result.scores = result.scores.filter(s => s >= options.minHeuristicValue);
}
return result;
}
exports.opsiatec = opsiatec;
function getCosiatec(points, options) {
const file = 'cosiatec_' + getCosiatecOptionsString(options) + '.json';
return util_1.loadOrPerformAndCache(file, () => {
const optimized = getOptimized(points, options);
const cresult = cosiatec_1.cosiatec(points, options, optimized);
return Object.assign({}, cresult, {
numSiatecPatterns: optimized.numSiatecPatterns,
numOptimizedPatterns: optimized.numOptimizedPatterns
});
}, options, " COSIATEC");
}
function getOptimized(points, options) {
if (needToOptimize(options)) {
const file = 'optimized_' + getOptimOptionsString(options) + '.json';
let result = util_1.loadCached(file, options.cacheDir);
if (!result) {
const input = getSiatec(points, options);
//result = performAndCache<SiatecResult>(" OPTIMIZING",
//() => getOptimizedPatterns(input, options), file, options);
const optimized = getOptimizedPatterns(input, options);
result = Object.assign({}, optimized, {
numSiatecPatterns: input.patterns.length,
numOptimizedPatterns: optimized.patterns.length
});
}
return result;
}
const siatec = getSiatec(points, options);
return Object.assign({}, siatec, { numSiatecPatterns: siatec.patterns.length });
}
function getSiatec(points, options) {
let result = loadCachedSiatec(options.cacheDir);
if (!result) {
result = performAndCacheSiatec(points, options, options.cacheDir); //pySiatec(points, file);
}
//filter for patterns with min length
result = optimizer_1.minLength(result, options.minPatternLength);
return result;
}
exports.getSiatec = getSiatec;
function pySiatec(points, file) {
console.log("starting pysiatec", JSON.stringify(points), file);
console.log(execute("python src/siatec.py '" + JSON.stringify(points) + "' '" + file + "'"));
return util_1.loadJson(file);
}
function getCosiatecOptionsString(options) {
return getOptimOptionsString(options)
+ '_' + (options.overlapping ? 't' : '')
+ '_' + (options.ignoreNovelty ? 't' : '')
+ '_' + heuristicToSymbol(options.selectionHeuristic)
+ '_' + (options.minPatternLength != null ? options.minPatternLength : '')
+ '_' + (options.numPatterns ? options.numPatterns : ''); //0 == null (unlimited)
}
exports.getCosiatecOptionsString = getCosiatecOptionsString;
function getOptimOptionsString(options) {
return _.sortBy(options.optimizationMethods).map(m => m.toString()).join('')
+ '_' + heuristicToSymbol(options.optimizationHeuristic)
+ '_' + (options.optimizationDimension != null ? options.optimizationDimension : '')
+ '_' + (options.minHeuristicValue != null ? options.minHeuristicValue : '');
}
function heuristicToSymbol(heuristic) {
const str = heuristic.toString();
const name = str === heuristics_1.HEURISTICS.SIZE_AND_1D_COMPACTNESS(0).toString() ? "s0"
: str === heuristics_1.HEURISTICS.SIZE_AND_1D_COMPACTNESS_AXIS(0).toString() ? "a0"
: str === heuristics_1.HEURISTICS.SIZE_AND_1D_COMPACTNESS_AXIS2(0).toString() ? "at0"
: str === heuristics_1.HEURISTICS.SIZE_AND_1D_COMPACTNESS_NOAXIS(0).toString() ? "n0"
: str === heuristics_1.HEURISTICS.SIZE_AND_COMPACTNESS.toString() ? "sm"
: str === heuristics_1.HEURISTICS.COMPACTNESS.toString() ? "m"
: str === heuristics_1.HEURISTICS.COVERAGE.toString() ? "v" : null;
if (name != null) {
return name;
}
else
throw new Error("heuristic unknown to options string generator");
}
function needToOptimize(options) {
return (options.optimizationMethods && options.optimizationMethods.length > 0)
|| options.minPatternLength > 1;
}
function getOptimizedPatterns(input, options) {
//always filter for patterns of min length to optimize runtime
let result = optimizer_1.minLength(input, options.minPatternLength);
if (options.optimizationMethods && options.optimizationMethods.indexOf(optimizer_1.OPTIMIZATION.PARTITION) >= 0) {
if (options.loggingLevel > 0)
console.log(" PARTITIONING");
result = optimizer_1.partition(result, options.optimizationHeuristic, options.optimizationDimension, options.minPatternLength);
}
if (options.optimizationMethods && options.optimizationMethods.indexOf(optimizer_1.OPTIMIZATION.DIVIDE) >= 0) {
if (options.loggingLevel > 0)
console.log(" DIVIDING");
result = optimizer_1.divide(result, options.optimizationHeuristic, options.optimizationDimension, options.minPatternLength);
}
if (options.optimizationMethods && options.optimizationMethods.indexOf(optimizer_1.OPTIMIZATION.MINIMIZE) >= 0) {
if (options.loggingLevel > 0)
console.log(" MINIMIZING");
result = optimizer_1.minimize(result, options.optimizationHeuristic, options.optimizationDimension, options.minPatternLength);
}
return result;
}
function loadCachedSiatec(cacheDir) {
//single file
if (fs.existsSync(cacheDir + 'siatec.json')) {
return util_1.loadJson(cacheDir + 'siatec.json');
}
}
function performAndCacheSiatec(points, options, cacheDir) {
if (options.loggingLevel > 0)
console.log(' SIATEC');
const result = siatec_1.siatec(points, options.minPatternLength);
util_1.saveCached('siatec.json', result, cacheDir);
return result;
}
function execute(command) {
let options = { shell: '/bin/bash' }; //{stdio: ['pipe', 'pipe', 'ignore']};
return child_process_1.execSync(command, options);
}