initial
This commit is contained in:
commit
fb20596fba
36 changed files with 8679 additions and 0 deletions
50
www/tests/demo.mjs
Normal file
50
www/tests/demo.mjs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import assert from 'assert';
|
||||
import { Objective } from '../src/Objective.js';
|
||||
import { PSO } from '../src/PSO.js';
|
||||
import { monod, pirt } from '../src/conhecidos.js';
|
||||
|
||||
function monodPirt(_, y, params) {
|
||||
const K_S = params[0];
|
||||
const mu_max = params[1];
|
||||
const m_S = params[2];
|
||||
const Y_XS = params[3];
|
||||
const X = y[0];
|
||||
const S = y[1];
|
||||
const dmu = monod(S, mu_max, K_S);
|
||||
const dX = X * dmu;
|
||||
const qS = pirt(dmu, Y_XS, m_S);
|
||||
const dS = -qS * X;
|
||||
return [dX, dS];
|
||||
}
|
||||
|
||||
const demoData = [
|
||||
['tempo', 'substrato', 'celulas'],
|
||||
[0, 3.0, 0.05],
|
||||
[1, 2.9835, 0.0595],
|
||||
[2, 2.964, 0.0708],
|
||||
[3, 2.9406, 0.0843],
|
||||
[4, 2.9129, 0.1003],
|
||||
[5, 2.8799, 0.1194],
|
||||
[6, 2.8407, 0.1421],
|
||||
[7, 2.794, 0.1691],
|
||||
[8, 2.7385, 0.2011],
|
||||
[9, 2.6725, 0.2393],
|
||||
[10, 2.5942, 0.2846],
|
||||
[11, 2.501, 0.3384],
|
||||
[12, 2.3905, 0.4023],
|
||||
[13, 2.2594, 0.478],
|
||||
[14, 2.104, 0.5678],
|
||||
[15, 1.9202, 0.674],
|
||||
];
|
||||
|
||||
const obj = new Objective(demoData, monodPirt, 100, 2);
|
||||
const optim = new PSO(obj, 30, [
|
||||
[0.005, 2],
|
||||
[0.05, 0.9],
|
||||
[0.0015, 0.05],
|
||||
[0.3, 0.7],
|
||||
]);
|
||||
optim.run(1.49618, 1.49618, 0.7298, 30);
|
||||
|
||||
assert(Number.isFinite(optim.err_best_g));
|
||||
console.log('Final error', optim.err_best_g);
|
||||
107
www/tests/synthetic-search.mjs
Normal file
107
www/tests/synthetic-search.mjs
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
import assert from 'assert';
|
||||
import { Objective } from '../src/Objective.js';
|
||||
import { PSO } from '../src/PSO.js';
|
||||
import { monod, pirt } from '../src/conhecidos.js';
|
||||
import { RK4, RK4getvalue } from '../src/runge-kutta.js';
|
||||
|
||||
function monodPirt(_, y, params) {
|
||||
const K_S = params[0];
|
||||
const mu_max = params[1];
|
||||
const m_S = params[2];
|
||||
const Y_XS = params[3];
|
||||
const X = y[0];
|
||||
const S = y[1];
|
||||
const dmu = monod(S, mu_max, K_S);
|
||||
const dX = X * dmu;
|
||||
const qS = pirt(dmu, Y_XS, m_S);
|
||||
const dS = -qS * X;
|
||||
return [dX, dS];
|
||||
}
|
||||
|
||||
function generateDataset(params, options) {
|
||||
const {
|
||||
initialCells,
|
||||
initialSubstrate,
|
||||
timeFinal,
|
||||
sampleCount,
|
||||
resolution,
|
||||
} = options;
|
||||
|
||||
const y0 = [initialCells, initialSubstrate];
|
||||
const timeArray = Array.from({ length: resolution + 1 }, (_, i) => (i * timeFinal) / resolution);
|
||||
const solution = RK4(monodPirt, timeArray, y0, params);
|
||||
|
||||
const rows = [['tempo', 'substrato', 'celulas']];
|
||||
for (let i = 0; i <= sampleCount; i++) {
|
||||
const timePoint = (i * timeFinal) / sampleCount;
|
||||
const [cells, substrate] = RK4getvalue(solution, timeArray, timePoint, monodPirt, params);
|
||||
rows.push([timePoint, substrate, cells]);
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
function createDeterministicRandom(seed) {
|
||||
let state = seed >>> 0;
|
||||
return function random() {
|
||||
state = (state * 1664525 + 1013904223) >>> 0;
|
||||
return state / 0x100000000;
|
||||
};
|
||||
}
|
||||
|
||||
const trueParams = [160, 0.45, 1.5, 0.5];
|
||||
const dataset = generateDataset(trueParams, {
|
||||
initialCells: 1.2,
|
||||
initialSubstrate: 120,
|
||||
timeFinal: 12,
|
||||
sampleCount: 12,
|
||||
resolution: 240,
|
||||
});
|
||||
|
||||
const bounds = [
|
||||
[140, 200],
|
||||
[0.3, 0.6],
|
||||
[1.0, 2.5],
|
||||
[0.3, 0.7],
|
||||
];
|
||||
|
||||
const objective = new Objective(dataset, monodPirt, 240, 2);
|
||||
const originalRandom = Math.random;
|
||||
Math.random = createDeterministicRandom(12345);
|
||||
|
||||
let optim;
|
||||
try {
|
||||
optim = new PSO(objective, 50, bounds);
|
||||
optim.run(1.49618, 1.49618, 0.7298, 150);
|
||||
} finally {
|
||||
Math.random = originalRandom;
|
||||
}
|
||||
|
||||
const defaultGuess = bounds.map(([min, max]) => (min + max) / 2);
|
||||
const defaultError = objective.objective(defaultGuess);
|
||||
|
||||
assert(
|
||||
optim.err_best_g < defaultError,
|
||||
'Swarm should reduce the error compared to the midpoint default parameters',
|
||||
);
|
||||
|
||||
const bestError = optim.err_best_g;
|
||||
assert(
|
||||
bestError < 1e-3,
|
||||
`Best error ${bestError} should approach the synthetic optimum with the default hyperparameters`,
|
||||
);
|
||||
|
||||
const boundaryMargin = optim.pos_best_g.map((value, index) => {
|
||||
const [min, max] = bounds[index];
|
||||
const distanceToEdge = Math.min(value - min, max - value);
|
||||
return distanceToEdge;
|
||||
});
|
||||
|
||||
boundaryMargin.forEach((margin, index) => {
|
||||
assert(
|
||||
margin > 1e-3,
|
||||
`Parameter ${index} is clamped to the boundary, default configuration should explore the interior`,
|
||||
);
|
||||
});
|
||||
|
||||
console.log('Synthetic dataset best parameters', optim.pos_best_g);
|
||||
Loading…
Add table
Add a link
Reference in a new issue