Skip to content

Commit d9065c3

Browse files
committed
upgrade ppmpredictor
1 parent 2d8f259 commit d9065c3

File tree

8 files changed

+340
-23
lines changed

8 files changed

+340
-23
lines changed

browser/dasher/controlpanelspecification.js

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,25 @@ export default {
6868
'order': 1, 'control': 'select', 'label': null}},
6969
},
7070

71-
'manage': {
71+
'prediction': {
7272
'$': {'order': 5},
7373

74+
'ppmAlpha': {$: {
75+
'order': 0, 'control': 'number', 'value': '0.49', 'label': 'PPM Alpha'}},
76+
'ppmBeta': {$: {
77+
'order': 1, 'control': 'number', 'value': '0.77', 'label': 'PPM Beta'}},
78+
'ppmMaxNodes': {$: {
79+
'order': 2, 'control': 'number', 'value': '0', 'label': 'PPM Max Nodes'}},
80+
'ppmUseExclusion': {$: {
81+
'order': 3, 'control': 'checkbox', 'value': true, 'label': 'Use Exclusion'}},
82+
'ppmUpdateExclusion': {$: {
83+
'order': 4, 'control': 'checkbox', 'value': true,
84+
'label': 'Single-count Updates'}},
85+
},
86+
87+
'manage': {
88+
'$': {'order': 6},
89+
7490
'settings': {
7591
'$': {'after': 'manager'},
7692
'copy': {$: {
@@ -99,13 +115,13 @@ export default {
99115
},
100116
},
101117
'display': {
102-
'$': {'order': 6},
118+
'$': {'order': 7},
103119

104120
'popup': {$: {
105121
'order': 0, 'control': 'button'}},
106122
},
107123
'message': {
108-
'$': {'order': 7},
124+
'$': {'order': 8},
109125

110126
'add': {$: {
111127
'order': 0, 'control': 'button'}},
@@ -119,7 +135,7 @@ export default {
119135
'order': 4, 'control': 'button'}},
120136
},
121137
'developer': {
122-
'$': {'order': 8},
138+
'$': {'order': 9},
123139

124140
'pointer': {$: {
125141
'order': 0, 'control': 'button'}},

browser/dasher/predictor_ppm_new.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ const config = {
2626
lexicon: [], // No lexicon by default (can be added via updateConfig)
2727
errorTolerant: false, // Strict mode by default
2828
caseSensitive: false, // Case-insensitive matching
29+
// PPM tuning options available in @willwade/ppmpredictor >= 0.0.13.
30+
ppmAlpha: 0.49,
31+
ppmBeta: 0.77,
32+
ppmMaxNodes: 0, // 0 = unlimited
33+
ppmUseExclusion: true,
34+
ppmUpdateExclusion: true, // Single-count updates
2935
};
3036
const characterWeightRange = 90;
3137
const wordCompletionBoost = 1.8;
@@ -524,6 +530,8 @@ export async function ppmNewGetPredictorAsync() {
524530
* });
525531
*/
526532
export function ppmNewUpdateConfig(newConfig) {
533+
Object.assign(config, newConfig);
534+
527535
if (!isInitialized) {
528536
initialize();
529537
}
@@ -533,6 +541,17 @@ export function ppmNewUpdateConfig(newConfig) {
533541
}
534542
}
535543

544+
export function ppmNewUpdatePPMConfig(ppmConfig = {}) {
545+
ppmNewUpdateConfig(ppmConfig);
546+
}
547+
548+
export function ppmNewGetPPMStats() {
549+
if (!predictor || typeof predictor.getPPMStats !== 'function') {
550+
return null;
551+
}
552+
return predictor.getPPMStats();
553+
}
554+
536555
/**
537556
* Add a training corpus for domain-specific predictions.
538557
*

browser/dasher/userinterface.js

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ import predictor_ppm_new, {
2828
ppmNewAddCorpus,
2929
ppmNewSetLearningEnabled,
3030
ppmNewGetLearningEnabled,
31+
ppmNewUpdatePPMConfig,
32+
ppmNewGetPPMStats,
3133
} from './predictor_ppm_new.js';
3234

3335
import Speech from './speech.js';
@@ -111,6 +113,8 @@ export default class UserInterface {
111113
this._keyHandler = new KeyHandler();
112114

113115
this._diagnosticSpans = null;
116+
this._ppmStatsTextNode = null;
117+
this._lastPPMStatsRefresh = 0;
114118
this._controlPanel = new ControlPanel(panels);
115119
this._panels = this._controlPanel.load();
116120

@@ -616,6 +620,7 @@ export default class UserInterface {
616620
['colour', 'Colour'],
617621
['speed', 'Speed'],
618622
['speech', 'Speech'],
623+
['prediction', 'Prediction'],
619624
['display', 'Display'],
620625
['message', 'Messages'],
621626
['manage', 'Manage'],
@@ -1267,9 +1272,45 @@ export default class UserInterface {
12671272
}
12681273
this._load_display_controls();
12691274
this._load_message_controls();
1275+
this._load_prediction_controls();
12701276
this._load_developer_controls();
12711277
}
12721278

1279+
_load_prediction_controls() {
1280+
if (this._panels.prediction === undefined) {
1281+
return;
1282+
}
1283+
const panel = this._panels.prediction;
1284+
const numberOrFallback = (value, fallback) => {
1285+
const parsed = Number.parseFloat(value);
1286+
return Number.isFinite(parsed) ? parsed : fallback;
1287+
};
1288+
const intOrFallback = (value, fallback) => {
1289+
const parsed = Number.parseInt(value, 10);
1290+
return Number.isFinite(parsed) ? parsed : fallback;
1291+
};
1292+
const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
1293+
1294+
panel.ppmAlpha.listener = (value) => {
1295+
const next = clamp(numberOrFallback(value, 0.49), 0.01, 4);
1296+
ppmNewUpdatePPMConfig({'ppmAlpha': next});
1297+
};
1298+
panel.ppmBeta.listener = (value) => {
1299+
const next = clamp(numberOrFallback(value, 0.77), 0.01, 4);
1300+
ppmNewUpdatePPMConfig({'ppmBeta': next});
1301+
};
1302+
panel.ppmMaxNodes.listener = (value) => {
1303+
const next = Math.max(0, intOrFallback(value, 0));
1304+
ppmNewUpdatePPMConfig({'ppmMaxNodes': next});
1305+
};
1306+
panel.ppmUseExclusion.listener = (checked) => {
1307+
ppmNewUpdatePPMConfig({'ppmUseExclusion': !!checked});
1308+
};
1309+
panel.ppmUpdateExclusion.listener = (checked) => {
1310+
ppmNewUpdatePPMConfig({'ppmUpdateExclusion': !!checked});
1311+
};
1312+
}
1313+
12731314
_select_behaviour(index) {
12741315
this._limits.targetRight = (index === 0);
12751316
this._currentSpeed = (index === 0 ? 0.1 : 0.2);
@@ -1549,7 +1590,8 @@ export default class UserInterface {
15491590
this._diagnostic_div_display();
15501591
// Diagnostic area in which to display various numbers. This is an array
15511592
// so that the values can be updated.
1552-
const diagnosticSpans = this._panels.developer.diagnostic.$.piece
1593+
const diagnosticPiece = this._panels.developer.diagnostic.$.piece;
1594+
const diagnosticSpans = diagnosticPiece
15531595
.create(
15541596
'span', {}, [
15551597
'loading sizes ...',
@@ -1562,9 +1604,42 @@ export default class UserInterface {
15621604
this._stopGoTextNode =
15631605
diagnosticSpans[diagnosticSpans.length - 1].firstChild;
15641606

1607+
const ppmStats = diagnosticPiece.create('span', {}, ' | PPM: loading ...');
1608+
this._ppmStatsTextNode = ppmStats.firstChild;
1609+
15651610
this._diagnosticSpans = diagnosticSpans;
15661611
}
15671612

1613+
_update_ppm_stats_diagnostic(timestamp) {
1614+
if (
1615+
this._ppmStatsTextNode === null ||
1616+
timestamp - this._lastPPMStatsRefresh < 500
1617+
) {
1618+
return;
1619+
}
1620+
this._lastPPMStatsRefresh = timestamp;
1621+
const stats = ppmNewGetPPMStats();
1622+
if (!Array.isArray(stats) || stats.length === 0) {
1623+
this._ppmStatsTextNode.nodeValue = ' | PPM: unavailable';
1624+
return;
1625+
}
1626+
1627+
const summary = stats.map((corpusStats, index) => {
1628+
if (corpusStats === null || typeof corpusStats !== 'object') {
1629+
return `c${index}:n/a`;
1630+
}
1631+
const numNodes = Number.isFinite(corpusStats.numNodes) ?
1632+
corpusStats.numNodes : 0;
1633+
const maxNodes = Number.isFinite(corpusStats.maxNodes) ?
1634+
corpusStats.maxNodes : 0;
1635+
const skippedNodeAdds = Number.isFinite(corpusStats.skippedNodeAdds) ?
1636+
corpusStats.skippedNodeAdds : 0;
1637+
const limit = maxNodes > 0 ? maxNodes : 'inf';
1638+
return `c${index}:${numNodes}/${limit} skip:${skippedNodeAdds}`;
1639+
}).join(' ');
1640+
this._ppmStatsTextNode.nodeValue = ` | PPM: ${summary}`;
1641+
}
1642+
15681643
_load_pointer() {
15691644
// Instantiate the pointer. It will draw the cross hairs and pointer
15701645
// line, always in front of the zoombox as drawn by the viewer.
@@ -1677,6 +1752,7 @@ export default class UserInterface {
16771752
// thousand separators.
16781753
this._heightTextNode.nodeValue = this.zoomBox.height.toLocaleString(
16791754
undefined, {maximumFractionDigits: 0});
1755+
this._update_ppm_stats_diagnostic(Date.now());
16801756
//
16811757
// Update message to be the message of whichever box is across the
16821758
// origin.

browser/vendor/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ This directory contains vendored browser assets that must be served in static de
22

33
Current files:
44
- `ppmpredictor.esm.js` copied from `node_modules/@willwade/ppmpredictor/dist/ppmpredictor.esm.js`
5+
- `ppmpredictor.esm.js.map` copied from `node_modules/@willwade/ppmpredictor/dist/ppmpredictor.esm.js.map`
6+
7+
Current pinned package:
8+
- `@willwade/ppmpredictor@0.0.13`
59

610
Update flow:
711
1. Run `npm ci` in repo root.

0 commit comments

Comments
 (0)