How do my review ahead answers affect the new interval's similarity

Let’s say I reviewed a card on the 6th and it was scheduled to be due on the 14th. I review ahead on the 7th. Anki will create a new interval that is close to 8 days (14 minus 6). How do my answers in review ahead mode mathematically affect how similar the new interval is to the old interval of 8 days?

If I instead had reviewed ahead on the 13th, Anki would create a new interval that is similar to the interval that would have been scheduled had I reviewed on the 14th. How do my answers in review ahead mode mathematically affect how similar the new interval is to the interval that would have been scheduled?

If the cards were almost due to be shown, they will be given a new delay similar to what they would have received if you had reviewed them on time. If the cards are reviewed soon after they were scheduled however, their new delay will be similar to their previous delay. This calculation works on a sliding scale.

ease is another thing that you should consider. if you review ahead and press Easy, anki will increase ease for that card by 15% which will affect all future reviews for that card

1 Like

but how do the buttons in review ahead mode create the new interval? when i click on again, easy, etc. i think these buttons have unique properties because they have to take into account the “sliding scale” you mention as well as the review ahead penalty i learned about (no. of days since review*[ease+120]/2). I just don’t know how it takes these things into account.

i have never thought about how review ahead works and i don’t think there’s anything in manual about how review ahead schedules reviews. so if you really wanna know how it works, you’ll have to check the anki source code.

i googled to see if there’s anything about that on manual/support site/anki subreddit and here’s what i found:

this is what a reddit user said about the scheduling in study ahead:

However, if you will look through the source code for the desktop client you’ll notice that this is not the case. Studying ahead requires that you build a filtered deck and allow for rescheduling based on answers in that filtered deck. The way that the desktop client handles filtered decks is different, likely because another use of filtered decks is catching up on a mountain of overdue cards. The formula for card study outside of their due date is:

new interval = MAX[ (days elapsed) × mean(ease, 120%), old interval)]

but this comment is for 4 years ago and the algorithm might have changed now. i’ll go through the source code and will update this when i understand how it works.

nice thanks

def _earlyReviewIvl(self, card: Card, ease: int) -> int:
        assert card.odid and card.type == CARD_TYPE_REV
        assert card.factor
        assert ease > 1

        elapsed = card.ivl - (card.odue -
#// elapsed: number of days that have passed since you reviewed the card
#// card.ivl: card's given interval
#// card.odue: card's original due date
#// today date

        conf = self._revConf(card)

        easyBonus = 1
        # early 3/4 reviews shouldn't decrease previous interval
        minNewIvl = 1

        if ease == BUTTON_TWO:  #// if you press hard
            factor = conf.get("hardFactor", 1.2)
#// hardFactor: should 
            # hard cards shouldn't have their interval decreased by more than 50%
            # of the normal factor
            minNewIvl = factor / 2
        elif ease == BUTTON_THREE:  #// if you press good
            factor = card.factor / 1000
        else:  # ease == BUTTON_FOUR:  #// if you press easy
            factor = card.factor / 1000
            ease4 = conf["ease4"]
#// ease4: should be the ease bonus (review tab in deck options) not sure tho
            # 1.3 -> 1.15
            easyBonus = ease4 - (ease4 - 1) / 2

        ivl_1 = max(elapsed * factor, 1)
#// card.factor: if ease = 250%, card.factor = 2500
#// factor: if ease = 250%, factor = 2.5

        # cap interval decreases
        ivl_2 = max(card.ivl * minNewIvl, ivl_1) * easyBonus

        ivl_3 = self._constrainedIvl(ivl_2, conf, prev=0, fuzz=False)
#// self._constrainedIvl -> applies fuzz,checks for maximum interval cap,
#// checks for previous interval and does one more thing that i honestly don't understand :/
#// for review ahead, fuzz is false (no fuzz applies)
#// previous interval = 0, maximum is always the interval that this function gives it
#// so i'll just assume that it has no effect on the interval and just use this function in my example (:|)

        return ivl_3
#// returns new interval for the card
if you press hard

card.ivl = 20 (days)
elapsed = 9 (days)

easyBonus = 1
minNewIvl = 0.55 (factor = conf.get("hardFactor", 1.2 | then minNewIvl = factor / 2) (my hard factor is 110% -> anki stores it as 1.10 => 1.10/2 = 0.55)
factor = 1.1

ivl_1 = 10
ivl_2 = 11
final interval on hard button = 11 (days)

if you press good

card.ivl = 20 (days)
elapsed = 9 (days)

easyBonus = 1
minNewIvl = 1
factor = 2.5

ivl_1 = 22.5
ivl_2 = 22.5
final interval on good button = 22 (days)

if you press easy

card.ivl = 20 (days)
elapsed = 9 (days)

easyBonus = 1.15 (check out #NOTE)
minNewIvl = 1
factor = 2.5

ivl_1 = 22.5
ivl_2 = 25.8
final interval on easy button = 26 (days)

#NOTE -> how easyBonus was calculated:
ease4 = conf[“ease4”] -> this is the easy bonus that you set on deck options -> review tab | if it’s 130%, anki stores it as 1.3

easyBonus = ease4 - (ease4 - 1) / 2

so if ease4 = 1.3 -> easyBonus = 1.3 - (0.3)/2 => 1.3 - 0.15 = 1.15

I know it’s a mess :expressionless: hope you understand it tho



ivl_1 = max(elapsed * factor, 1)
I don’t understand this line. Why is it 1? What 's the result of elapsed * factor?