forgetting_curve_utils.cpp revision 70566266be1781100c673addca5af1960a0eedf8
1fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi/* 2fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi * Copyright (C) 2013, The Android Open Source Project 3fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi * 4fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi * Licensed under the Apache License, Version 2.0 (the "License"); 5fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi * you may not use this file except in compliance with the License. 6fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi * You may obtain a copy of the License at 7fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi * 8fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi * http://www.apache.org/licenses/LICENSE-2.0 9fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi * 10fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi * Unless required by applicable law or agreed to in writing, software 11fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi * distributed under the License is distributed on an "AS IS" BASIS, 12fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi * See the License for the specific language governing permissions and 14fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi * limitations under the License. 15fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi */ 16fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi 172fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "suggest/policyimpl/dictionary/utils/forgetting_curve_utils.h" 182fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 197c4dcf1e918c2b9251e7aa907d991a3ab8764bafKeisuke Kuroyanagi#include <cmath> 20c76bbceedc804d1f2988cbf032b530a107a7d561Keisuke Kuroyanagi#include <stdlib.h> 21c76bbceedc804d1f2988cbf032b530a107a7d561Keisuke Kuroyanagi 2257816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi#include "suggest/policyimpl/dictionary/header/header_policy.h" 23fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi#include "suggest/policyimpl/dictionary/utils/probability_utils.h" 242fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "utils/time_keeper.h" 25fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi 26fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanaginamespace latinime { 27fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi 2813d5dc914aae5cb6bf6ef06aa05643514a40318cKeisuke Kuroyanagiconst int ForgettingCurveUtils::MAX_UNIGRAM_COUNT = 12000; 2913d5dc914aae5cb6bf6ef06aa05643514a40318cKeisuke Kuroyanagiconst int ForgettingCurveUtils::MAX_UNIGRAM_COUNT_AFTER_GC = 10000; 3013d5dc914aae5cb6bf6ef06aa05643514a40318cKeisuke Kuroyanagiconst int ForgettingCurveUtils::MAX_BIGRAM_COUNT = 12000; 3113d5dc914aae5cb6bf6ef06aa05643514a40318cKeisuke Kuroyanagiconst int ForgettingCurveUtils::MAX_BIGRAM_COUNT_AFTER_GC = 10000; 32fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi 3313d5dc914aae5cb6bf6ef06aa05643514a40318cKeisuke Kuroyanagiconst int ForgettingCurveUtils::MAX_COMPUTED_PROBABILITY = 127; 3467c855ea6f882190d73df9d3fae0b56929fd6888Keisuke Kuroyanagiconst int ForgettingCurveUtils::DECAY_INTERVAL_SECONDS = 2 * 60 * 60; 35fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi 362fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasaconst int ForgettingCurveUtils::MAX_LEVEL = 3; 372fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasaconst int ForgettingCurveUtils::MIN_VALID_LEVEL = 1; 382fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasaconst int ForgettingCurveUtils::TIME_STEP_DURATION_IN_SECONDS = 6 * 60 * 60; 392fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasaconst int ForgettingCurveUtils::MAX_ELAPSED_TIME_STEP_COUNT = 15; 402fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasaconst int ForgettingCurveUtils::DISCARD_LEVEL_ZERO_ENTRY_TIME_STEP_COUNT_THRESHOLD = 14; 4167c855ea6f882190d73df9d3fae0b56929fd6888Keisuke Kuroyanagi 422fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasaconst ForgettingCurveUtils::ProbabilityTable ForgettingCurveUtils::sProbabilityTable; 437c4dcf1e918c2b9251e7aa907d991a3ab8764bafKeisuke Kuroyanagi 4405113c1847e5c41aab3176eb015aabc2acdc0a51Keisuke Kuroyanagi// TODO: Revise the logic to decide the initial probability depending on the given probability. 452fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa/* static */ const HistoricalInfo ForgettingCurveUtils::createUpdatedHistoricalInfo( 462fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const HistoricalInfo *const originalHistoricalInfo, 4757816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi const int newProbability, const int timestamp, const HeaderPolicy *const headerPolicy) { 482fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (newProbability != NOT_A_PROBABILITY && originalHistoricalInfo->getLevel() == 0) { 492fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return HistoricalInfo(timestamp, MIN_VALID_LEVEL /* level */, 0 /* count */); 502fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } else if (!originalHistoricalInfo->isValid()) { 512fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // Initial information. 522fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return HistoricalInfo(timestamp, 0 /* level */, 1 /* count */); 53fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi } else { 542fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int updatedCount = originalHistoricalInfo->getCount() + 1; 5557816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi if (updatedCount >= headerPolicy->getForgettingCurveOccurrencesToLevelUp()) { 562fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // The count exceeds the max value the level can be incremented. 572fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (originalHistoricalInfo->getLevel() >= MAX_LEVEL) { 582fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // The level is already max. 592fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return HistoricalInfo(timestamp, originalHistoricalInfo->getLevel(), 602fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa originalHistoricalInfo->getCount()); 612fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } else { 622fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // Level up. 632fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return HistoricalInfo(timestamp, originalHistoricalInfo->getLevel() + 1, 642fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 0 /* count */); 652fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 662fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } else { 672fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return HistoricalInfo(timestamp, originalHistoricalInfo->getLevel(), updatedCount); 682fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 69fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi } 70fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi} 71fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi 722fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa/* static */ int ForgettingCurveUtils::decodeProbability( 7357816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi const HistoricalInfo *const historicalInfo, const HeaderPolicy *const headerPolicy) { 742fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int elapsedTimeStepCount = getElapsedTimeStepCount(historicalInfo->getTimeStamp()); 7557816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi return sProbabilityTable.getProbability( 7657816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi headerPolicy->getForgettingCurveProbabilityValuesTableId(), historicalInfo->getLevel(), 772fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa min(max(elapsedTimeStepCount, 0), MAX_ELAPSED_TIME_STEP_COUNT)); 782fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa} 792fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 802fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa/* static */ int ForgettingCurveUtils::getProbability(const int unigramProbability, 812fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int bigramProbability) { 822fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (unigramProbability == NOT_A_PROBABILITY) { 832fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return NOT_A_PROBABILITY; 842fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } else if (bigramProbability == NOT_A_PROBABILITY) { 852fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return min(backoff(unigramProbability), MAX_COMPUTED_PROBABILITY); 86fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi } else { 872fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return min(max(unigramProbability, bigramProbability), MAX_COMPUTED_PROBABILITY); 88fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi } 89fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi} 90fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi 912fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa/* static */ bool ForgettingCurveUtils::needsToKeep(const HistoricalInfo *const historicalInfo) { 922fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return historicalInfo->getLevel() > 0 932fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa || getElapsedTimeStepCount(historicalInfo->getTimeStamp()) 942fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa < DISCARD_LEVEL_ZERO_ENTRY_TIME_STEP_COUNT_THRESHOLD; 95fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi} 96fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi 972fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa/* static */ const HistoricalInfo ForgettingCurveUtils::createHistoricalInfoToSave( 9857816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi const HistoricalInfo *const originalHistoricalInfo, 9957816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi const HeaderPolicy *const headerPolicy) { 1002fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (originalHistoricalInfo->getTimeStamp() == NOT_A_TIMESTAMP) { 1012fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return HistoricalInfo(); 10267c855ea6f882190d73df9d3fae0b56929fd6888Keisuke Kuroyanagi } 1032fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int elapsedTimeStep = getElapsedTimeStepCount(originalHistoricalInfo->getTimeStamp()); 1042fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (elapsedTimeStep <= MAX_ELAPSED_TIME_STEP_COUNT) { 1052fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // No need to update historical info. 1062fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return *originalHistoricalInfo; 1072fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 1082fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // Level down. 1092fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int maxLevelDownAmonut = elapsedTimeStep / (MAX_ELAPSED_TIME_STEP_COUNT + 1); 1102fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int levelDownAmount = (maxLevelDownAmonut >= originalHistoricalInfo->getLevel()) ? 1112fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa originalHistoricalInfo->getLevel() : maxLevelDownAmonut; 1122fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int adjustedTimestamp = originalHistoricalInfo->getTimeStamp() + 1132fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa levelDownAmount * (MAX_ELAPSED_TIME_STEP_COUNT + 1) * TIME_STEP_DURATION_IN_SECONDS; 1142fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return HistoricalInfo(adjustedTimestamp, 1152fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa originalHistoricalInfo->getLevel() - levelDownAmount, 0 /* count */); 11667c855ea6f882190d73df9d3fae0b56929fd6888Keisuke Kuroyanagi} 11767c855ea6f882190d73df9d3fae0b56929fd6888Keisuke Kuroyanagi 11867c855ea6f882190d73df9d3fae0b56929fd6888Keisuke Kuroyanagi/* static */ bool ForgettingCurveUtils::needsToDecay(const bool mindsBlockByDecay, 11957816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi const int unigramCount, const int bigramCount, const HeaderPolicy *const headerPolicy) { 12067c855ea6f882190d73df9d3fae0b56929fd6888Keisuke Kuroyanagi if (unigramCount >= ForgettingCurveUtils::MAX_UNIGRAM_COUNT) { 12167c855ea6f882190d73df9d3fae0b56929fd6888Keisuke Kuroyanagi // Unigram count exceeds the limit. 12267c855ea6f882190d73df9d3fae0b56929fd6888Keisuke Kuroyanagi return true; 12367c855ea6f882190d73df9d3fae0b56929fd6888Keisuke Kuroyanagi } else if (bigramCount >= ForgettingCurveUtils::MAX_BIGRAM_COUNT) { 12467c855ea6f882190d73df9d3fae0b56929fd6888Keisuke Kuroyanagi // Bigram count exceeds the limit. 12567c855ea6f882190d73df9d3fae0b56929fd6888Keisuke Kuroyanagi return true; 12667c855ea6f882190d73df9d3fae0b56929fd6888Keisuke Kuroyanagi } 12767c855ea6f882190d73df9d3fae0b56929fd6888Keisuke Kuroyanagi if (mindsBlockByDecay) { 12867c855ea6f882190d73df9d3fae0b56929fd6888Keisuke Kuroyanagi return false; 12967c855ea6f882190d73df9d3fae0b56929fd6888Keisuke Kuroyanagi } 1302fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (headerPolicy->getLastDecayedTime() + DECAY_INTERVAL_SECONDS 1312fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa < TimeKeeper::peekCurrentTime()) { 13267c855ea6f882190d73df9d3fae0b56929fd6888Keisuke Kuroyanagi // Time to decay. 13367c855ea6f882190d73df9d3fae0b56929fd6888Keisuke Kuroyanagi return true; 134c76bbceedc804d1f2988cbf032b530a107a7d561Keisuke Kuroyanagi } 13567c855ea6f882190d73df9d3fae0b56929fd6888Keisuke Kuroyanagi return false; 136fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi} 137fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi 138c76bbceedc804d1f2988cbf032b530a107a7d561Keisuke Kuroyanagi// See comments in ProbabilityUtils::backoff(). 139c76bbceedc804d1f2988cbf032b530a107a7d561Keisuke Kuroyanagi/* static */ int ForgettingCurveUtils::backoff(const int unigramProbability) { 140c76bbceedc804d1f2988cbf032b530a107a7d561Keisuke Kuroyanagi if (unigramProbability == NOT_A_PROBABILITY) { 141c76bbceedc804d1f2988cbf032b530a107a7d561Keisuke Kuroyanagi return NOT_A_PROBABILITY; 142c76bbceedc804d1f2988cbf032b530a107a7d561Keisuke Kuroyanagi } else { 143c76bbceedc804d1f2988cbf032b530a107a7d561Keisuke Kuroyanagi return max(unigramProbability - 8, 0); 144c76bbceedc804d1f2988cbf032b530a107a7d561Keisuke Kuroyanagi } 145fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi} 146fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi 1472fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa/* static */ int ForgettingCurveUtils::getElapsedTimeStepCount(const int timestamp) { 1482fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return (TimeKeeper::peekCurrentTime() - timestamp) / TIME_STEP_DURATION_IN_SECONDS; 1492fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa} 1502fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 15170566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagiconst int ForgettingCurveUtils::ProbabilityTable::PROBABILITY_TABLE_COUNT = 4; 15270566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagiconst int ForgettingCurveUtils::ProbabilityTable::WEAK_PROBABILITY_TABLE_ID = 0; 15370566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagiconst int ForgettingCurveUtils::ProbabilityTable::MODEST_PROBABILITY_TABLE_ID = 1; 15470566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagiconst int ForgettingCurveUtils::ProbabilityTable::STRONG_PROBABILITY_TABLE_ID = 2; 15570566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagiconst int ForgettingCurveUtils::ProbabilityTable::AGGRESSIVE_PROBABILITY_TABLE_ID = 3; 15670566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagiconst int ForgettingCurveUtils::ProbabilityTable::MODEST_BASE_PROBABILITY = 32; 15770566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagiconst int ForgettingCurveUtils::ProbabilityTable::STRONG_BASE_PROBABILITY = 35; 15870566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagiconst int ForgettingCurveUtils::ProbabilityTable::AGGRESSIVE_BASE_PROBABILITY = 40; 15970566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi 16057816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi 16157816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke KuroyanagiForgettingCurveUtils::ProbabilityTable::ProbabilityTable() : mTables() { 16257816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi mTables.resize(PROBABILITY_TABLE_COUNT); 16357816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi for (int tableId = 0; tableId < PROBABILITY_TABLE_COUNT; ++tableId) { 16457816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi mTables[tableId].resize(MAX_LEVEL + 1); 16557816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi for (int level = 0; level <= MAX_LEVEL; ++level) { 16657816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi mTables[tableId][level].resize(MAX_ELAPSED_TIME_STEP_COUNT + 1); 16770566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi const float initialProbability = getBaseProbabilityForLevel(tableId, level); 16870566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi const float endProbability = getBaseProbabilityForLevel(tableId, level - 1); 16957816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi for (int timeStepCount = 0; timeStepCount <= MAX_ELAPSED_TIME_STEP_COUNT; 17057816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi ++timeStepCount) { 17157816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi if (level == 0) { 17257816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi mTables[tableId][level][timeStepCount] = NOT_A_PROBABILITY; 17357816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi continue; 17457816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi } 17557816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi const int elapsedTime = timeStepCount * TIME_STEP_DURATION_IN_SECONDS; 17657816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi const float probability = initialProbability 17770566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi * powf(initialProbability / endProbability, 17870566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi -1.0f * static_cast<float>(elapsedTime) 17970566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi / static_cast<float>(TIME_STEP_DURATION_IN_SECONDS 18070566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi * (MAX_ELAPSED_TIME_STEP_COUNT + 1))); 18157816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi mTables[tableId][level][timeStepCount] = 18257816c7a8bac1a47913da7a503ece2b5dd7cc0fcKeisuke Kuroyanagi min(max(static_cast<int>(probability), 1), MAX_COMPUTED_PROBABILITY); 1832fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 1842fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 1857c4dcf1e918c2b9251e7aa907d991a3ab8764bafKeisuke Kuroyanagi } 1867c4dcf1e918c2b9251e7aa907d991a3ab8764bafKeisuke Kuroyanagi} 1877c4dcf1e918c2b9251e7aa907d991a3ab8764bafKeisuke Kuroyanagi 18870566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi/* static */ int ForgettingCurveUtils::ProbabilityTable::getBaseProbabilityForLevel( 18970566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi const int tableId, const int level) { 19070566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi if (tableId == WEAK_PROBABILITY_TABLE_ID) { 19170566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi // Max probability is 127. 19270566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi return static_cast<float>(MAX_COMPUTED_PROBABILITY / (1 << (MAX_LEVEL - level))); 19370566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi } else if (tableId == MODEST_PROBABILITY_TABLE_ID) { 19470566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi // Max probability is 128. 19570566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi return static_cast<float>(MODEST_BASE_PROBABILITY * (level + 1)); 19670566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi } else if (tableId == STRONG_PROBABILITY_TABLE_ID) { 19770566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi // Max probability is 140. 19870566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi return static_cast<float>(STRONG_BASE_PROBABILITY * (level + 1)); 19970566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi } else if (tableId == AGGRESSIVE_PROBABILITY_TABLE_ID) { 20070566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi // Max probability is 160. 20170566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi return static_cast<float>(AGGRESSIVE_BASE_PROBABILITY * (level + 1)); 20270566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi } else { 20370566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi return NOT_A_PROBABILITY; 20470566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi } 20570566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi} 20670566266be1781100c673addca5af1960a0eedf8Keisuke Kuroyanagi 207fd02b2d6ee55d4aee7faab89a7a2b72764eafc47Keisuke Kuroyanagi} // namespace latinime 208