Carpalx optimizes keyboard layouts to create ones that require less effort and significantly reduced carpal strain!

Have ideas? Tell me.

# the best layout

Partially optimized QWKRFY and fully optimized QGMLWY layouts are the last word in easier typing.

# the worst layout

A fully anti-optimized TNWMLC layout is a joke and a nightmare to type. It's also the only keyboard layout that has its own fashion line.

# layouts

6 Aug 20 — The search for the world’s best keyboard layout by Paul Guerin

4 May 20 — An interview with Bloomberg's Arianne Cohen Splurge on a Better Keyboard, It's Worth It.

25 May 18 — The BBC article Why we can't give up this off way of typing by Tim McDonald discusses the history and persistence of QWERTY and my Carpalx work.

16 Aug 16 — Ergonomic Keyboard Layout Designed for the Filipino Language at AHFE2016 derives layout for Filipino language using Carpalx

18 Apr 16 — Carpalx layouts soon to appear in freedesktop (package xkeyboard-config) and kbd. Thanks to Perry Thompson.

# NAME

carpalx - given text input, determine optimal keyboard mapping to minimize typing effort based on a typing effort model

# SYNOPSIS

$# all configuration read from etc/carpalx.conf carpalx -keyboard_input keyboard.conf -keyboard_output keyboard-optimized.conf -corpus corpus/words.txt -action loadkeyboard,loadtriads,optimize -conf etc/carpalx.conf [-debug]$

# DESCRIPTION

carpalx is a keyboard layout optimizer. Given a training corpus (e.g. English text) and parameters that describe typing effort, carpalx uses simulated annealing to find a keyboard layout to minimize typing effort.

Typing effort is modeled using three contributions. First, base effort is derived from finger travel distance. Second, row, hand and finger penalties are added to limit use of weaker fingers/hands and distinguish harder-to-reach keys. Third, stroke path effort is used to rate the effort based on finger, row and hand alternation (e.g. asd is much easier to type than sad).

# CONFIGURATION

## Configuration file name and path

carpalx will look in the following locations for a configuration file

$. SCRIPT_BIN/../etc SCRIPT_BIN/etc SCRIPT_BIN/ ~/.carpalx/etc ~/.carpalx$

where SCRIPT_BIN is the location of the carpalx script. If the name of the configuration file is not passed via -conf, then SCRIPT_NAME.conf is tried where SCRIPT_NAME is the name of the script. For example,

$> cd carpalx-0.11 > bin/carpalx$

will attempt to find carpalx.conf in the above paths.

Using -debug -debug will dump the configuration parameters.

$> bin/carpalx -debug -debug$

## Configuration structure

The configuration file comprises variable-value pairs, which may be placed in blocks.

$a = 1 <someblock> b = 2 <anotherblock> c = 3 </anotherblock> </someblock>$

Combinations of related parameters (e.g. base effort, keyboard configuration) are stored in individual files (e.g. etc/mask/letters.conf) which are subsequently imported into the main configuration file using <<include>>

$... <<include etc/mask/letters.conf>> ...$

# HISTORY

• 0.10

Packaged and versioned code.

• 0.11

Adjusted typing model to include weights for base, effort and stroke components.

Improved clarity of effort reports.

Improved consistency in configuration file.

• 0.12

Can now load a cache file basedon parsed corpus instead of original corpus.

Report!

# AUTHOR

Martin Krzywinski <martink@bcgsc.ca> http://mkweb.bcgsc.ca

# CONTACT

$Martin Krzywinski Genome Sciences Centre 100-570 W 7th Ave Vancouver BC V5Z 4S6$

# INTERNAL FUNCTIONS

The content below may be out of date

$$newkeyboard = optimize_keyboard($keytriads,$keyboard);$ Simulated annealing is used to search for a better keyboard layout. The function uses the list of triads, generated from the input text document, and an initial keyboard layout. ## $_swap_keys()$ $$newkeyboard = _swap_keys($keyboard,$reloc_list,$n);$ Swap one or more pairs ($n randomly sampled pairs) of keys on the keyboard. Lower and upper case characters remain on the same key (e.g. no matter where 'a' is, A is always shift+a). This applies to both letter and non-letter characters (e.g. 1 and ! are always on the same key).

This function returns a new keyboard object with the keys swapped.

## $_swap_key_pair()$

$$key1 = [$row1,$col1];$key2 = [$row2,$col2]; _swap_key_pair($keyboard,@$key1,@$key2);$ This function modifies$keyboard in place.

$my $effort = calculate_effort($triads,$keyboard);$ Given a list of triads and the effort matrix, calculate the total carpal effort required to type the document from which the triads were generated. The effort is a non-negative number. The effort is a sum of the efforts for each triad. The total effort is normalized by the number of triads to remove dependency on document size. $abcdefg abc -> effort1 bcd -> effort2 cde -> effort3 efg -> effort4 ------- ------- abcdefg -> total_effort = ( effort1 + effort2 + effort3 + effort4 ) /4$ Given a triad xyz, the effort is calculated by the following empirical expression $effort = e = k1*effort(x) + k2*effort(x)*effort(y) + k3*effort(x)*effort(y)*effort(z) + k4*patheffort(x,y,z) = k1*effort(x)*[1 + effort(y)*(k2 + k3*effort(z))] + k4*patheffort(x,y,z)$ The form of this expression is motivated by the fact that the effort of three keystrokes is dependent on not only the individual identity of the keys but also alternation of hand, finger, row and column within the triad as well as presence of hard-to-type key combinations (e.g. zxc zqz awz ). For example, it is much easier to type "ttt" than "tbt", since the left forefinger must travel quite a distance in the latter example. Thus the insertion of the "b" character should impact the effort. In the first-order approximation k2=k3=k4=0 and the effort is simply the effort of typing the first key, effort(x). The individual effort of a key is defined in the <effort_row> blocks and is optionally modified by (a) shift penalty - CAPS are penalized and (b) hand penalty (e.g. you favour typing with your left hand). Since triads overlap, the first-order approximation for the entire document is the sum of the individual key efforts, without any long-range correlations. The addition of parameters k2 and k3 is designed to raise the effort of repeated difficult-to-type characters. This is where the notion of a triad comes into play. Notice that if effort(x) is zero, then the whole triad effort is zero. The patheffort(x,y,z) is a penalty which makes less desirable triads in which the keys do not follow a monotonic progression of columns, or triads which do not alternate hands. Once you try to type 'edc' on a qwerty keyboard, or 'erd' you will understand what I mean. The patheffort is a combination of two factors: hand alternation and column alternation. First, define a hand and column flag for a triad The definition of path effort here is arbitrary. I find that if the hands alternate between each keystroke, typing is easy (e.g. hf=0x). If both hands are used, but don't alternate then it's not as easy, particuarly when some of the columns in the triad are the same (e.g. same finger has to hit two keys like in "jeu"). If the same hand has to be used for three strokes then you're in trouble, particularly when some of the columns repeat. You can redefine the value of the path effort in <path_efforts> block. ## $read_document()$ $$triads = read_document(); # create hashref to triad frequencies$
$$triads->{aab} = frequency of aab;$triads->{abc} = frequency of abc;$

Read a document from file and create a list of of character triads. Triads are overlapping (more on overlapping below) 3-character combinations. Each triad is stored along with the number of times it appears in the document. All triads are stored, including overlapping triads.

For example, if the document line is

$I am a very lazy dog with big ears.$

$i am iam am a ama m a v mav a ve ave ver ver ery ery ry l ryl y la yla ...$

and so on. Notice that spaces in the document are disregarded during construction of the triads.

Depending on the parse mode, the input document undergoes some transformation before triads are constructed. Each mode must be defined using a <mode_def> block. Three modes are defined and you can add more.

$<triad> maxnum = 1000 # limit number of triads overlap = yes # if set to yes, a triad potentially begins at each character (triads overlap by maximum of 2 characters) # if set to no, triads abut </triad> =over$
mode = perl

If the mode is set to "perl", then all comment lines are disregarded. Comments are identified by lines that begin with #.

mode = english

English mode removes all non-alphanumeric characters before constructing triads.

mode = letter

All non-letter characters are removed and remaining letters are switched to lower case.

## _parse_keyboard_layout

Parse the <keyboard><row> blocks to determine the location of keys on the keyboard.

Keyboard structure is stored as a hashref. Each key is stored by row/col position

## $create_keyboard()$

$my $keyboard = create_keyboard();$ Parses the keyboard layout and creates an array that keeps track of the keys, their positions, character assignments and typing effort. The keyboard array is indexed by row and column of the key and contains a hash $$keyboard->{key}[row][col] {lc} {uc} {row} {col} {effort}$

The keyboard layout is read from the <keyboard><row> blocks. The effort in the {key} part of the keyboard object is the canonical effort for the row,col combination as defined in <effort_row> plus any baseline and hand penalties.

The keymap hash is a direct mapping between a character and its position and hand assignment on the keyboard

$keyboard->{map}{CHAR} {row} {col} {hand} {effort}$

The effort in the {map} part of the keyboard object is the effort for the character, based on its row,col combination and includes the shift penalty.

For the standard qwerty layout, look at the keyboard you're using right now (true for >99% of typists). For Dvorak layout, see http://www.mwbrooks.com/dvorak.