1bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi/* 2bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi * Copyright (C) 2017 The Android Open Source Project 3bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi * 4bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi * Licensed under the Apache License, Version 2.0 (the "License"); 5bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi * you may not use this file except in compliance with the License. 6bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi * You may obtain a copy of the License at 7bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi * 8bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi * http://www.apache.org/licenses/LICENSE-2.0 9bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi * 10bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi * Unless required by applicable law or agreed to in writing, software 11bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi * distributed under the License is distributed on an "AS IS" BASIS, 12bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi * See the License for the specific language governing permissions and 14bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi * limitations under the License. 15bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi */ 16bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi 17bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi// Fast approximation for exp. 18bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi 19b23e2125be90bbf6124e9cd5684fc93026c5ec4dLukas Zilka#ifndef LIBTEXTCLASSIFIER_UTIL_MATH_FASTEXP_H_ 20b23e2125be90bbf6124e9cd5684fc93026c5ec4dLukas Zilka#define LIBTEXTCLASSIFIER_UTIL_MATH_FASTEXP_H_ 21bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi 22bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi#include <cassert> 23bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi#include <cmath> 24bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi#include <limits> 25bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi 26bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi#include "util/base/casts.h" 27bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi#include "util/base/integral_types.h" 28bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi#include "util/base/logging.h" 29bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi 3021d8c98fb12bc83dd0e9f5cb8fa9197ef325e074Lukas Zilkanamespace libtextclassifier2 { 31bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi 32bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharificlass FastMathClass { 33bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi private: 34bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi static const int kBits = 7; 35bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi static const int kMask1 = (1 << kBits) - 1; 36bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi static const int kMask2 = 0xFF << kBits; 37bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi static constexpr float kLogBase2OfE = 1.44269504088896340736f; 38bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi 39bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi struct Table { 40bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi int32 exp1[1 << kBits]; 41bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi }; 42bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi 43bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi public: 44bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi float VeryFastExp2(float f) const { 45bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi TC_DCHECK_LE(fabs(f), 126); 46bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi const float g = f + (127 + (1 << (23 - kBits))); 47bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi const int32 x = bit_cast<int32>(g); 48bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi int32 ret = ((x & kMask2) << (23 - kBits)) 49bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi | cache_.exp1[x & kMask1]; 50bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi return bit_cast<float>(ret); 51bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi } 52bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi 53bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi float VeryFastExp(float f) const { 54bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi return VeryFastExp2(f * kLogBase2OfE); 55bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi } 56bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi 57bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi private: 58bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi static const Table cache_; 59bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi}; 60bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi 61bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifiextern FastMathClass FastMathInstance; 62bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi 63bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifiinline float VeryFastExp2(float f) { return FastMathInstance.VeryFastExp2(f); } 64bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifiinline float VeryFastExp(float f) { return FastMathInstance.VeryFastExp(f); } 65bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi 6621d8c98fb12bc83dd0e9f5cb8fa9197ef325e074Lukas Zilka} // namespace libtextclassifier2 67bda09f1da39ce38a5ece4757b82a64776e53214cMatt Sharifi 68b23e2125be90bbf6124e9cd5684fc93026c5ec4dLukas Zilka#endif // LIBTEXTCLASSIFIER_UTIL_MATH_FASTEXP_H_ 69