Recalc

recalc_example.png

Recalc is short for “recalculate”, and is basically the command that tells AnkiMorphs to work all its magic. When you run Recalc, AnkiMorphs will go through the cards that match any 'Note Filter' and do the following:

  • Update the ankimorphs.db with any new seen morphs, known morphs, etc.
  • Calculate the score of the cards, and then sort the cards based on that score.
  • Update any cards' extra fields and tags.

Basically, when you run Recalc, AnkiMorphs will go through your collection, recalculate the difficulty of your cards based on your new knowledge, and reorder your new cards in a way that’s optimal for the new you: the you who knows more than you did yesterday.

You can run Recalc as often as you like, but you should run it at least once before or after every study session so that your new cards will appear in the optimal order.

It's easy to forget to run recalc, so you can also check the Recalc on sync settings option, which will take care of recalc for you by running it automatically before Anki syncs your collection.

Note: Recalc can potentially reorganize all your cards, which can cause long sync times. The Anki FAQ has some tricks you can try if this poses a significant problem.

Scoring Algorithm

TL;DR: Low scores are good, high scores are bad.

The order in which new cards are displayed depends on their due value: a card with due = 1 will be shown before a card with due = 2, and so on. Leveraging this property, we can implement the following strategy: assign higher due values to cards with more complex text, pushing them further back in the card queue. Here are some examples of what that might look like:

  • "She walked home"
    • due = 600
  • "Asymmetric catalysis for the enantioselective synthesis of chiral molecules"
    • due = 100 000 000

Now, let's define some properties that we want our cards to have:

  • Few unknowns morphs (comprehensibility)
  • High priority morphs (significance)
  • Ideal length (low deviation)

We can now invert these properties to calculate a "penalty" score, which will then replace the due values of the cards. That formula at the highest level is:

Let’s break it down into smaller components.

incomprehensibility

In practice, the comprehensibility of a given text is determined by a combination of known grammar points and vocabulary. However, evaluating grammar is non-trivial, especially in a general language learning context, so we will not make any explicit attempts to do so.

Determining which morphs are known is relatively easy, so our incomprehensibility score will be the product of the number of unknown morphs and a constant penalty factor.

where

insignificance

Each morph has a priority value, which AnkiMorphs aggregates into the following metrics:

where


Note: is not included since it would not have any meaningful impact on 1T cards.

You can customize the algorithm by selecting any combination of these metrics and adjusting their influence on the result by changing their corresponding weights. This is done using two column vectors: one for the weights and one for the aggregated metrics. The final score is computed by taking the scalar product of these vectors:


which gives us:

Example:


Deviation

Learning can be easier with more surrounding context, e.g., other known words. However, if a sentence contains too many words, learning may become more challenging. This is because the complexity of the grammar often increases, along with the likelihood of not perfectly remembering all the surrounding words. Ideally, we want our cards to have sentences within this optimal range.

Having the ability to bias our sentences towards a certain length is also beneficial; you might find it easier to learn from shorter sentences compared to longer ones, or vice versa.

To achieve this, we use a piecewise equation that where we define the following:

  • How much to penalize excessive morphs
  • How much to penalize insufficient morphs
  • The ideal range (target) of morphs

Here is an example of what that might look like: all_taget_diff.png

Playground: https://www.geogebra.org/graphing/ta3eqb8y

This graph shows:

  • Penalty for excessive morphs: squared in relation to the target difference
  • Penalty for insufficient morphs: linear in relation to the target difference
  • Ideal range (target): 4-6 morphs

AnkiMorphs provides the following metrics, whose variables you can adjust, and you can disable or amply them by changing their weights:



where

with the following vectors:

which gives us:

Constraints

We have now refined the formula to:

However, there are a few practical concerns we have to address.

First, we need to ensure that cards are primarily ordered by the number of unknown morphs they contain. This means that all 1T cards should appear before any MT cards, regardless of their insignificance or deviation.

To do this, we apply a min function to ensure that the sum of the last two terms does not exceed

where

Lastly, we have to make sure that the score does not exceed the maximum card due value allowed by Anki. The due value is stored as a signed 32-bit integer, with a maximum value of . To prevent overflow when cards are shifted, we include a safety margin of . This results in the upper bound:

Now we wrap the entire expression in another min function to get our final formula: