В этом примере показано, как реализовать фиксированную точку log2 с использованием таблицы подстановки. Таблицы подстановки генерируют эффективный код для встраиваемых устройств.
Чтобы этот пример не изменял ваши настройки, этот код сохраняет исходное состояние.
originalFormat = get(0,'format'); format long g originalWarningState = warning('off','fixed:fi:underflow'); originalFiprefState = get(fipref); reset(fipref)
Это состояние будет восстановлено в конце примера.
log2 алгоритм, реализованный в функции fi_log2lookup_8_bit_byte ниже, резюмируется здесь.
Объявите количество битов в байте, B, как константа. В этом примере: B=8.
Использовать функцию fi_normalize_unsigned_8_bit_byte() описано в примере Нормализация данных для таблиц поиска для нормализации входных данных u>0 такой, что u = x*2^n и 1 <= x < 2.
Извлечь верхний B-биты x. Давайте x_B обозначать верхний B-биты x.
Создать таблицу подстановки, LOG2LUT, такую, что целое число i = x_B - 2^(B-1) + 1 используется в качестве индекса для LOG2LUT, чтобы log2(x_B) можно оценить путем просмотра индекса log2(x_B) = LOG2LUT(i).
Используйте остаток, r = x - x_B, интерпретируемый как дробь, для линейной интерполяции между LOG2LUT(i) и следующее значение в таблице LOG2LUT(i+1). Остаток, r, создается путем извлечения нижнего w - B биты x, где w обозначает длину слова x. Он интерпретируется как дробь с помощью функции reinterpretcast().
Наконец, вычислите выходные данные с помощью таблицы поиска и линейной интерполяции:
log2(u) = log2(x*2^n)
= n + log2(x)
= n + LOG2LUT(i) + r*(LOG2LUT(i+1) - LOG2LUT(i))
Использовать fi_log2lookup_8_bit_byte() для вычисления log2 с фиксированной точкой с помощью таблицы подстановки. Сравнение результата таблицы поиска с фиксированной точкой с логарифмом, вычисленным с помощью log2 и двойная точность.
u = fi(linspace(0.001,20,100)); y = fi_log2lookup_8_bit_byte(u); y_expected = log2(double(u));
Постройте график результатов.
clf subplot(211) plot(u,y,u,y_expected) legend('Output','Expected output','Location','Best') subplot(212) plot(u,double(y)-y_expected,'r') legend('Error')

figure(gcf)
Восстановите исходное состояние.
set(0,'format',originalFormat);
warning(originalWarningState);
fipref(originalFiprefState);fi_log2lookup_8_bit_byte Определение функцииfunction y = fi_log2lookup_8_bit_byte(u) % Load the lookup table LOG2LUT = log2_lookup_table(); % Remove fimath from the input to insulate this function from math % settings declared outside this function. u = removefimath(u); % Declare the output y = coder.nullcopy(fi(zeros(size(u)),numerictype(LOG2LUT),fimath(LOG2LUT))); B = 8; % Number of bits in a byte w = u.WordLength; for k = 1:numel(u) assert(u(k)>0,'Input must be positive.'); % Normalize the input such that u = x*2^n and 1 <= x < 2 [x,n] = fi_normalize_unsigned_8_bit_byte(u(k)); % Extract the high byte of x high_byte = storedInteger(bitsliceget(x, w, w - B + 1)); % Convert the high byte into an index for LOG2LUT i = high_byte - 2^(B-1) + 1; % Interpolate between points. % The upper byte was used for the index into LOG2LUT % The remaining bits make up the fraction between points. T_unsigned_fraction = numerictype(0, w-B, w-B); r = reinterpretcast(bitsliceget(x,w-B,1), T_unsigned_fraction); y(k) = n + LOG2LUT(i) + ... r*(LOG2LUT(i+1) - LOG2LUT(i)) ; end % Remove fimath from the output to insulate the caller from math settings % declared inside this function. y = removefimath(y); end
Функция log2_lookup_table загружает таблицу подстановки log2 значения. Можно создать таблицу, выполнив следующие действия:
B = 8;
log2_table = log2((2^(B-1):2^(B))/2^(B-1))
function LOG2LUT = log2_lookup_table() B = 8; % Number of bits in a byte % log2_table = log2((2^(B-1) : 2^(B)) / 2^(B - 1)) log2_table = [0.000000000000000 0.011227255423254 0.022367813028454 0.033423001537450 ... 0.044394119358453 0.055282435501190 0.066089190457773 0.076815597050831 ... 0.087462841250339 0.098032082960527 0.108524456778169 0.118941072723507 ... 0.129283016944966 0.139551352398794 0.149747119504682 0.159871336778389 ... 0.169925001442312 0.179909090014934 0.189824558880017 0.199672344836364 ... 0.209453365628950 0.219168520462162 0.228818690495881 0.238404739325079 ... 0.247927513443586 0.257387842692652 0.266786540694901 0.276124405274238 ... 0.285402218862248 0.294620748891627 0.303780748177103 0.312882955284355 ... 0.321928094887362 0.330916878114617 0.339850002884625 0.348728154231078 ... 0.357552004618084 0.366322214245816 0.375039431346925 0.383704292474052 ... 0.392317422778760 0.400879436282184 0.409390936137702 0.417852514885898 ... 0.426264754702098 0.434628227636725 0.442943495848728 0.451211111832329 ... 0.459431618637297 0.467605550082997 0.475733430966398 0.483815777264256 ... 0.491853096329675 0.499845887083205 0.507794640198696 0.515699838284042 ... 0.523561956057013 0.531381460516312 0.539158811108031 0.546894459887637 ... 0.554588851677637 0.562242424221073 0.569855608330948 0.577428828035749 ... 0.584962500721156 0.592457037268080 0.599912842187128 0.607330313749611 ... 0.614709844115208 0.622051819456376 0.629356620079610 0.636624620543649 ... 0.643856189774725 0.651051691178929 0.658211482751795 0.665335917185176 ... 0.672425341971496 0.679480099505446 0.686500527183218 0.693486957499325 ... 0.700439718141092 0.707359132080883 0.714245517666123 0.721099188707185 ... 0.727920454563199 0.734709620225838 0.741466986401147 0.748192849589460 ... 0.754887502163469 0.761551232444479 0.768184324776926 0.774787059601173 ... 0.781359713524660 0.787902559391432 0.794415866350106 0.800899899920305 ... 0.807354922057604 0.813781191217037 0.820178962415188 0.826548487290915 ... 0.832890014164742 0.839203788096944 0.845490050944375 0.851749041416058 ... 0.857980995127572 0.864186144654280 0.870364719583405 0.876516946565000 ... 0.882643049361841 0.888743248898259 0.894817763307943 0.900866807980749 ... 0.906890595608518 0.912889336229962 0.918863237274595 0.924812503605781 ... 0.930737337562886 0.936637939002571 0.942514505339240 0.948367231584678 ... 0.954196310386875 0.960001932068081 0.965784284662087 0.971543553950772 ... 0.977279923499916 0.982993574694310 0.988684686772166 0.994353436858858 ... 1.000000000000000]; % Cast to fixed point with the most accurate rounding method WL = 4*B; % Word length FL = 2*B; % Fraction length LOG2LUT = fi(log2_table,1,WL,FL,'RoundingMethod','Nearest'); % Set fimath for the most efficient math operations F = fimath('OverflowAction','Wrap',... 'RoundingMethod','Floor',... 'SumMode','SpecifyPrecision',... 'SumWordLength',WL,... 'SumFractionLength',FL,... 'ProductMode','SpecifyPrecision',... 'ProductWordLength',WL,... 'ProductFractionLength',2*FL); LOG2LUT = setfimath(LOG2LUT,F); end