ドキュメンテーション

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

固定小数点の正弦および余弦の計算

この例では、Fixed-Point Designer™ で利用できる CORDIC ベースのアルゴリズムとルックアップ テーブルに基づくアルゴリズムの両方について、それらを使用して MATLAB® の正弦関数 (SIN) および余弦関数 (COS) を近似する方法を説明します。効率的な固定小数点の正弦および余弦アルゴリズムは、モーター制御、ナビゲーション、信号処理、ワイヤレス通信などの多数の組み込みアプリケーションにとって重要です。

CORDIC アルゴリズムを使用した正弦と余弦の計算

はじめに

関数 cordiccexpcordicsincoscordicsin および cordiccos は、CORDIC ベースのアルゴリズムを使って MATLAB 関数 sin および cos を近似します。CORDIC は、COordinate Rotation DIgital Computer の略語です。ギブンス回転に基づく CORDIC アルゴリズム ([1] および [2] を参照) は、反復的なシフト加算演算だけが必要であるため、ハードウェア効率が最も高いアルゴリズムのうちの 1 つです。CORDIC アルゴリズムは、明示的な乗数を必要とせず、正弦関数、余弦関数、逆正弦関数、逆余弦関数、逆正接関数、ベクトル振幅関数、除算関数、平方根関数、双曲線関数、対数関数など、さまざまな関数の計算に適しています。

CORDIC 回転計算モードを使用すると、正弦と余弦だけでなく、極から直交への変換演算も計算できます。このモードでは、振幅ベクトルおよび回転角がわかっており、座標 (X-Y) コンポーネントが回転後に計算されます。

CORDIC 回転計算モード

CORDIC 回転モード アルゴリズムは、必要な回転角で角度のアキュムレータを初期化することによって開始されます。次に、残差角度のアキュムレータの大きさを減らす方法で、CORDIC の反復ごとに回転判定が行われます。回転判定は、各反復後に、角度のアキュムレータ内の残差角度の符号に基づきます。

回転モードでの CORDIC 方程式は以下のとおりです。

ここで、 の場合は 、それ以外の場合は です。

および は、反復の総数です。

これにより、 に近づくときに以下の結果が得られます。

ここで、

回転モードでは、CORDIC アルゴリズムは の回転角に制限されます。その範囲外の角度をサポートするには、CORDIC 反復の完了後に、関数 cordiccexpcordicsincoscordicsin および cordiccos で象限補正 (範囲外の可能性がある否定も含む) を使用します。

CORDICSINCOS の正弦および余弦コードについて

はじめに

関数 cordicsincos は、CORDIC アルゴリズムを使用して、範囲 [-2*pi 2*pi) 内の入力角の正弦と余弦を計算します。この関数は、入力引数として角度 (ラジアン) および反復回数を取り、正弦および余弦の近似を返します。

CORDIC 計算出力は、回転ゲインによってスケーリングされます。このゲインは、最初の 定数値を事前にスケーリングすることによって考慮されます。

初期化

関数 cordicsincos は以下の初期化手順を実行します。

  • 角度入力ルックアップ テーブル inpLUTatan(2 .^ -(0:N-1)) に設定します。

  • 入力引数値に設定します。

  • に設定します。

  • をゼロに設定します。

適切な開始値を選択することにより、アルゴリズムで正弦と余弦の両方を同時に直接計算できるようになります。 回の反復の後、これらの初期値は に近づくときの以下の出力を導きます。

固定小数点および浮動小数点の共有 CORDIC カーネル コード

CORDIC アルゴリズム (回転モード) のカーネル部分の MATLAB コードは以下のとおりです (スカラー xy、および z の場合)。固定小数点と浮動小数点の両方の演算には同じコードが使用されます。

function [x, y, z] = cordic_rotation_kernel(x, y, z, inpLUT, n)
% Perform CORDIC rotation kernel algorithm for N kernel iterations.
xtmp = x;
ytmp = y;
for idx = 1:n
    if z < 0
        z(:) = z + inpLUT(idx);
        x(:) = x + ytmp;
        y(:) = y - xtmp;
    else
        z(:) = z - inpLUT(idx);
        x(:) = x - ytmp;
        y(:) = y + xtmp;
    end
    xtmp = bitsra(x, idx); % bit-shift-right for multiply by 2^(-idx)
    ytmp = bitsra(y, idx); % bit-shift-right for multiply by 2^(-idx)
end

正弦-余弦回転モードの CORDIC 反復の可視化

CORDIC アルゴリズムは、通常、指定された回数 (定数) の反復を実行します。これは、CORDIC 反復を早期に終了するとパイプライン化されたコードが分断されて が変化するため、CORDIC ゲイン が一定でなくなるためです。

が非常に大きな値の場合、CORDIC アルゴリズムが収束することは保証されますが、常に単調であるとは限りません。以下の例でわかるように、後半の反復に比べ、中間の反復の方がより高い精度の結果を生成することもあります。通常、総反復回数を増やすと精度を上げることができます。

以下の例では、反復 5 は反復 6 より優れた結果の推定を提供し、CORDIC アルゴリズムは後半の反復で収束します。

theta   = pi/5; % input angle in radians
niters  = 10;   % number of iterations
sinTh   = sin(theta); % reference result
cosTh   = cos(theta); % reference result
y_sin   = zeros(niters, 1);
sin_err = zeros(niters, 1);
x_cos   = zeros(niters, 1);
cos_err = zeros(niters, 1);
fprintf('\n\nNITERS \tERROR\n');
fprintf('------\t----------\n');
for n = 1:niters
    [y_sin(n), x_cos(n)] = cordicsincos(theta, n);
    sin_err(n) = abs(y_sin(n) - sinTh);
    cos_err(n) = abs(x_cos(n) - cosTh);
    if n < 10
        fprintf('   %d \t %1.8f\n', n, cos_err(n));
    else
        fprintf('  %d \t %1.8f\n', n, cos_err(n));
    end
end
fprintf('\n');

NITERS 	ERROR
------	----------
   1 	 0.10191021
   2 	 0.13966630
   3 	 0.03464449
   4 	 0.03846157
   5 	 0.00020393
   6 	 0.01776952
   7 	 0.00888037
   8 	 0.00436052
   9 	 0.00208192
  10 	 0.00093798

棒グラフでの CORDIC 近似エラーのプロット

figure(1); clf;
bar(1:niters, cos_err(1:niters));
xlabel('Number of iterations','fontsize',12,'fontweight','b');
ylabel('Error','fontsize',12,'fontweight','b');
title('CORDIC approximation error for cos(pi/5) computation',...
    'fontsize',12,'fontweight','b');
axis([0 niters 0 0.14]);

5 回の反復に対する X-Y 結果のプロット

Niter2Draw = 5;
figure(2), clf, hold on
plot(cos(0:0.1:pi/2), sin(0:0.1:pi/2), 'b--'); % semi-circle
for i=1:Niter2Draw
    plot([0 x_cos(i)],[0 y_sin(i)], 'LineWidth', 2); % CORDIC iteration result
    text(x_cos(i),y_sin(i),int2str(i),'fontsize',12,'fontweight','b');
end
plot(cos(theta), sin(theta), 'r*', 'MarkerSize', 20); % IDEAL result
xlabel('X (COS)','fontsize',12,'fontweight','b')
ylabel('Y (SIN)','fontsize',12,'fontweight','b')
title('CORDIC iterations for cos(pi/5) computation',...
    'fontsize',12,'fontweight','b')
axis equal;
axis square;

cordicsin による固定小数点の正弦の計算

[-2*pi, 2*pi) 間に 1024 ポイントを作成

stepSize = pi/256;
thRadDbl = (-2*pi):stepSize:(2*pi - stepSize);
thRadFxp = sfi(thRadDbl, 12);     % signed, 12-bit fixed-point values
sinThRef = sin(double(thRadFxp)); % reference results

固定小数点 CORDIC 関数と倍精度三角関数の結果比較

12 ビットの量子化された入力を使用し、反復回数を 4 回から 10 回の間で変化させます。

for niters = 4:3:10
    cdcSinTh  = cordicsin(thRadFxp,  niters);
    errCdcRef = sinThRef - double(cdcSinTh);
    figure; hold on; axis([-2*pi 2*pi -1.25 1.25]);
    plot(thRadFxp, sinThRef,  'b');
    plot(thRadFxp, cdcSinTh,  'g');
    plot(thRadFxp, errCdcRef, 'r');
    ylabel('sin(\Theta)','fontsize',12,'fontweight','b');
    set(gca,'XTick',-2*pi:pi/2:2*pi);
    set(gca,'XTickLabel',...
        {'-2*pi', '-3*pi/2', '-pi', '-pi/2', ...
        '0', 'pi/2', 'pi', '3*pi/2','2*pi'});
    set(gca,'YTick',-1:0.5:1);
    set(gca,'YTickLabel',{'-1.0','-0.5','0','0.5','1.0'});
    ref_str = 'Reference: sin(double(\Theta))';
    cdc_str = sprintf('12-bit CORDICSIN; N = %d', niters);
    err_str = sprintf('Error (max = %f)', max(abs(errCdcRef)));
    legend(ref_str, cdc_str, err_str);
    title(cdc_str,'fontsize',12,'fontweight','b');
end

N = 10 についての LSB エラーの計算

figure;
fracLen = cdcSinTh.FractionLength;
plot(thRadFxp, abs(errCdcRef) * pow2(fracLen));
set(gca,'XTick',-2*pi:pi/2:2*pi);
set(gca,'XTickLabel',...
    {'-2*pi', '-3*pi/2', '-pi', '-pi/2', ...
    '0', 'pi/2', 'pi', '3*pi/2','2*pi'});
ylabel(sprintf('LSB Error: 1 LSB = 2^{-%d}',fracLen),'fontsize',12,'fontweight','b');
title('LSB Error: 12-bit CORDICSIN; N=10','fontsize',12,'fontweight','b');
axis([-2*pi 2*pi 0 6]);

ノイズ フロアの計算

fft_mag = abs(fft(double(cdcSinTh)));
max_mag = max(fft_mag);
mag_db  = 20*log10(fft_mag/max_mag);
figure;
hold on;
plot(0:1023, mag_db);
plot(0:1023, zeros(1,1024),'r--');     % Normalized peak (0 dB)
plot(0:1023, -62.*ones(1,1024),'r--'); % Noise floor level
ylabel('dB Magnitude','fontsize',12,'fontweight','b');
title('62 dB Noise Floor: 12-bit CORDICSIN; N=10',...
    'fontsize',12,'fontweight','b');
% axis([0 1023 -120 0]); full FFT
axis([0 round(1024*(pi/8)) -100 10]); % zoom in
set(gca,'XTick',[0 round(1024*pi/16) round(1024*pi/8)]);
set(gca,'XTickLabel',{'0','pi/16','pi/8'});

FIACCEL による固定小数点の関数 CORDICSINCOS の高速化

MATLAB® 関数 fiaccel を使用して、MATLAB コードから MEX 関数を生成できます。通常は、生成した MEX 関数を実行するとシミュレーションの速度が向上しますが、実際にどの程度速度が向上するかは、使用されるシミュレーション プラットフォームによります。以下の例は、fiaccel を使用して固定小数点の関数 cordicsincos を高速化する方法を示します。

関数 fiaccel は、MATLAB コードを MEX 関数にコンパイルします。このステップには、一時ディレクトリの作成とこのディレクトリにおける書き込み権限が必要です。

tempdirObj = fidemo.fiTempdir('fi_sin_cos_demo');

coder.newtype('constant',10) を使用して反復回数が定数 (たとえば、10) になるように宣言すると、コンパイルされた角度ルックアップ テーブルも定数になるため、各反復で計算されません。また、cordicsincos_mex を呼び出すと、反復回数に対する入力引数を指定する必要がなくなります。反復回数を渡すと、MEX 関数はエラーになります。

入力パラメーターのデータ型は、関数 cordicsincos で固定小数点または浮動小数点の計算を行うかどうかを決定します。MATLAB がこのファイルに対してコードを生成すると、コードは特定のデータ型に対してのみ生成されます。たとえば、THETA 入力引数が固定小数点の場合、固定小数点のコードのみが生成されます。

inp = {thRadFxp, coder.newtype('constant',10)}; % example inputs for the function
fiaccel('cordicsincos', '-o', 'cordicsincos_mex',  '-args', inp)

最初に、cordicsincos を呼び出して正弦と余弦を計算します。

tstart = tic;
cordicsincos(thRadFxp,10);
telapsed_Mcordicsincos = toc(tstart);

次に、MEX 関数 cordicsincos_mex を呼び出して正弦と余弦を計算します。

cordicsincos_mex(thRadFxp); % load the MEX file
tstart = tic;
cordicsincos_mex(thRadFxp);
telapsed_MEXcordicsincos = toc(tstart);

ここで、速度を比較します。MATLAB コマンド ラインで次のように入力し、ご使用のプラットフォームで速度が向上したことを確認します。

fiaccel_speedup = telapsed_Mcordicsincos/telapsed_MEXcordicsincos;

一時ディレクトリをクリーンアップするには、次のコマンドを実行します。

clear cordicsincos_mex;
status = tempdirObj.cleanUp;

ルックアップ テーブルを使用した SINCOS の計算

固定小数点の正弦および余弦近似を実装するために使用できるルックアップ テーブルに基づくアプローチは数多く存在します。以下に示すのは、単一の実数値ルックアップ テーブルと単純な最近傍線形内挿に基づく低コストのアプローチです。

単一のルックアップ テーブルに基づくアプローチ

Fixed-Point Designer に含まれる fi オブジェクトの sin メソッドと cos メソッドは、ルックアップ テーブルに基づくアプローチを値間の単純な最近傍線形内挿と共に使用して、MATLAB® の組み込み浮動小数点関数 sin および cos を近似します。このアプローチでは、実数値ルックアップ テーブルを小規模にすることができ、使用する算術も簡単です。

単一の実数値ルックアップ テーブルを使用することで、インデックスの計算と、非常に高い精度の結果を得るために必要な計算全体が単純化されます。これらの単純化により、比較的高速のパフォーマンスが実現し、必要なメモリも比較的少なくなります。

ルックアップ テーブルに基づく SIN および COS の実装について

ルックアップ テーブルのサイズと精度

ルックアップ テーブルの設計で考慮するべき 2 つの重要な点は、サイズと精度です。考え得るすべての入力値 に対応できる table を作成するのは不可能です。また、ルックアップ テーブル値 または の量子化のため、完璧に正確であることも不可能です。

妥協案として、Fixed-Point Designer の FI オブジェクトの SIN および COS メソッドは、実装の一部として 8 ビットのルックアップ テーブルを使用します。8 ビット テーブルの長さはわずか 256 要素なので、小さくて効率的です。さらに、多くのプラットフォームにおける 8 ビットは 1 バイトまたは 1 ワードのサイズと同じです。線形内挿と組み合わせて使用し、出力 (ルックアップ テーブル値) の精度を 16 ビットにすることで、8 ビットでアドレス指定可能なルックアップ テーブルは非常に高い精度とパフォーマンスを両方とも提供します。

定数 SIN のルックアップ テーブル値の初期化

実装の簡素化、テーブル値の均一性、および高速性のために、完全な正弦波テーブルが使用されます。最初に、1/4 波形の関数 SIN が [0, pi/2) ラジアンの範囲内で 64 の等間隔でサンプリングされます。table 値について符号付き 16 ビット小数固定小数点データ型 (つまり tblValsNT = numerictype(1,16,15)) を選択すると、SIN の出力範囲 [-1.0, 1.0) において最善の精度が得られます。オーバーフロー警告を避けるために、値は設定前に量子化されています。

tblValsNT = numerictype(1,16,15);
quarterSinDblFltPtVals  = (sin(2*pi*((0:63) ./ 256)))';
endpointQuantized_Plus1 = 1.0 - double(eps(fi(0,tblValsNT)));

halfSinWaveDblFltPtVals = ...
    [quarterSinDblFltPtVals; ...
    endpointQuantized_Plus1; ...
    flipud(quarterSinDblFltPtVals(2:end))];

fullSinWaveDblFltPtVals = ...
    [halfSinWaveDblFltPtVals; -halfSinWaveDblFltPtVals];

FI_SIN_LUT = fi(fullSinWaveDblFltPtVals, tblValsNT);

アルゴリズム実装の概要

Fixed-Point Designer の fi オブジェクトの sin メソッドと cos メソッドの実装には、最初に固定小数点数の角度入力 (単位はラジアン) を範囲 [0, 2pi] で事前に定義されたデータ型にキャストする操作が含まれます。この目的のために、2pi を法とする演算が実行されて範囲が [0, 2pi] の固定小数点数の入力値 inpValInRange が求められ、精度が最高になるように 2 進小数点スケーリングされた符号なし 16 ビット固定小数点型の numerictype(0,16,13) にキャストされます。

% Best UNSIGNED type for real-world value range [0,  2*pi],
% which maps to fixed-point stored integer vals [0, 51472].
inpInRangeNT = numerictype(0,16,13);

次に、この範囲内の固定小数点 FI 角度値から 16 ビットの符号なし格納整数値を求めます。

idxUFIX16 = fi(storedInteger(inpValInRange), numerictype(0,16,0));

格納整数値と正規化定数 65536/51472 を乗算します。結果の整数値は、フルスケールの uint16 インデックス範囲内の値になります。

normConst_NT = numerictype(0,32,31);
normConstant = fi(65536/51472, normConst_NT);
fullScaleIdx = normConstant * idxUFIX16;
idxUFIX16(:) = fullScaleIdx;

このフルスケールの符号なし 16 ビット インデックス idxUFIX16 の最上位ビット (MSB) 8 個が、8 ビット正弦ルックアップ テーブルに対する直接のインデックスとして使用されます。テーブル ルックアップが 2 回実行されます。1 回は計算されたテーブル インデックス位置 lutValBelow で、もう 1 回は次のインデックス位置 lutValAbove で実行されます。

idxUint8MSBs = storedInteger(bitsliceget(idxUFIX16, 16, 9));
zeroBasedIdx = int16(idxUint8MSBs);
lutValBelow  = FI_SIN_LUT(zeroBasedIdx + 1);
lutValAbove  = FI_SIN_LUT(zeroBasedIdx + 2);

idxUFIX16 の残りの 8 個の最下位ビット (LSB) は、2 つの table 値の間の内挿に使用されます。LSB 値は、8 ビットの小数データ型 rFracNT を伴う正規化されたスケーリング ファクターとして扱われます。

rFracNT      = numerictype(0,8,8); % fractional remainder data type
idxFrac8LSBs = reinterpretcast(bitsliceget(idxUFIX16,8,1), rFracNT);
rFraction    = idxFrac8LSBs;

実数の乗算を使用して、2 点間の重み付き差分を決定します。その結果、内挿された固定小数点正弦の結果を得るための単純な計算 (1 つの積と 2 つの合計) が導かれます。

temp = rFraction * (lutValAbove - lutValBelow);
rslt = lutValBelow + temp;

上記のアルゴリズムを使用して、固定小数点数入力 inpValInRange = 0.425 ラジアンの SIN の値を計算するために使用されるルックアップ テーブルと線形内挿プロセスの例を示します。

% Use an arbitrary input value (e.g., 0.425 radians)
inpInRangeNT  = numerictype(0,16,13);    % best precision, [0, 2*pi] radians
inpValInRange = fi(0.425, inpInRangeNT); % arbitrary fixed-point input angle

% Normalize its stored integer to get full-scale unsigned 16-bit integer index
idxUFIX16     = fi(storedInteger(inpValInRange), numerictype(0,16,0));
normConst_NT  = numerictype(0,32,31);
normConstant  = fi(65536/51472, normConst_NT);
fullScaleIdx  = normConstant * idxUFIX16;
idxUFIX16(:)  = fullScaleIdx;

% Do two table lookups using unsigned 8-bit integer index (i.e., 8 MSBs)
idxUint8MSBs  = storedInteger(bitsliceget(idxUFIX16, 16, 9));
zeroBasedIdx  = int16(idxUint8MSBs);          % zero-based table index value
lutValBelow   = FI_SIN_LUT(zeroBasedIdx + 1); % 1st table lookup value
lutValAbove   = FI_SIN_LUT(zeroBasedIdx + 2); % 2nd table lookup value

% Do nearest-neighbor interpolation using 8 LSBs (treat as fractional remainder)
rFracNT       = numerictype(0,8,8); % fractional remainder data type
idxFrac8LSBs  = reinterpretcast(bitsliceget(idxUFIX16,8,1), rFracNT);
rFraction     = idxFrac8LSBs; % fractional value for linear interpolation
temp          = rFraction * (lutValAbove - lutValBelow);
rslt          = lutValBelow + temp;

以下はアルゴリズムの結果のプロットです。

x_vals = 0:(pi/128):(pi/4);
xIdxLo = zeroBasedIdx - 1;
xIdxHi = zeroBasedIdx + 4;
figure; hold on; axis([x_vals(xIdxLo) x_vals(xIdxHi) 0.25 0.65]);
plot(x_vals(xIdxLo:xIdxHi), double(FI_SIN_LUT(xIdxLo:xIdxHi)), 'b^--');
plot([x_vals(zeroBasedIdx+1) x_vals(zeroBasedIdx+2)], ...
    [lutValBelow lutValAbove], 'k.'); % Closest values
plot(0.425, double(rslt), 'r*'); % Interpolated fixed-point result
plot(0.425, sin(0.425),   'gs'); % Double precision reference result
xlabel('X'); ylabel('SIN(X)');
lut_val_str = 'Fixed-point lookup table values';
near_str    = 'Two closest fixed-point LUT values';
interp_str  = 'Interpolated fixed-point result';
ref_str     = 'Double precision reference value';
legend(lut_val_str, near_str, interp_str, ref_str);
title('Fixed-Point Designer Lookup Table Based SIN with Linear Interpolation', ...
    'fontsize',12,'fontweight','b');

SIN による固定小数点の正弦の計算

[-2*pi, 2*pi) 間に 1024 ポイントを作成

stepSize = pi/256;
thRadDbl = (-2*pi):stepSize:(2*pi - stepSize); % double precision floating-point
thRadFxp = sfi(thRadDbl, 12); % signed, 12-bit fixed-point inputs

固定小数点 SIN 関数と倍精度 SIN 関数の結果比較

fxpSinTh  = sin(thRadFxp); % fixed-point results
sinThRef  = sin(double(thRadFxp)); % reference results
errSinRef = sinThRef - double(fxpSinTh);
figure; hold on; axis([-2*pi 2*pi -1.25 1.25]);
plot(thRadFxp, sinThRef,  'b');
plot(thRadFxp, fxpSinTh,  'g');
plot(thRadFxp, errSinRef, 'r');
ylabel('sin(\Theta)','fontsize',12,'fontweight','b');
set(gca,'XTick',-2*pi:pi/2:2*pi);
set(gca,'XTickLabel',...
    {'-2*pi', '-3*pi/2', '-pi', '-pi/2', ...
    '0', 'pi/2', 'pi', '3*pi/2','2*pi'});
set(gca,'YTick',-1:0.5:1);
set(gca,'YTickLabel',{'-1.0','-0.5','0','0.5','1.0'});
ref_str = 'Reference: sin(double(\Theta))';
fxp_str = sprintf('16-bit Fixed-Point SIN with 12-bit Inputs');
err_str = sprintf('Error (max = %f)', max(abs(errSinRef)));
legend(ref_str, fxp_str, err_str);
title(fxp_str,'fontsize',12,'fontweight','b');

LSB エラーの計算

figure;
fracLen = fxpSinTh.FractionLength;
plot(thRadFxp, abs(errSinRef) * pow2(fracLen));
set(gca,'XTick',-2*pi:pi/2:2*pi);
set(gca,'XTickLabel',...
    {'-2*pi', '-3*pi/2', '-pi', '-pi/2', ...
    '0', 'pi/2', 'pi', '3*pi/2','2*pi'});
ylabel(sprintf('LSB Error: 1 LSB = 2^{-%d}',fracLen),'fontsize',12,'fontweight','b');
title('LSB Error: 16-bit Fixed-Point SIN with 12-bit Inputs','fontsize',12,'fontweight','b');
axis([-2*pi 2*pi 0 8]);

ノイズ フロアの計算

fft_mag = abs(fft(double(fxpSinTh)));
max_mag = max(fft_mag);
mag_db  = 20*log10(fft_mag/max_mag);
figure;
hold on;
plot(0:1023, mag_db);
plot(0:1023, zeros(1,1024),'r--');     % Normalized peak (0 dB)
plot(0:1023, -64.*ones(1,1024),'r--'); % Noise floor level (dB)
ylabel('dB Magnitude','fontsize',12,'fontweight','b');
title('64 dB Noise Floor: 16-bit Fixed-Point SIN with 12-bit Inputs',...
    'fontsize',12,'fontweight','b');
% axis([0 1023 -120 0]); full FFT
axis([0 round(1024*(pi/8)) -100 10]); % zoom in
set(gca,'XTick',[0 round(1024*pi/16) round(1024*pi/8)]);
set(gca,'XTickLabel',{'0','pi/16','pi/8'});

固定小数点近似アルゴリズムのコストの比較

固定小数点 CORDIC アルゴリズムには次の演算が必要です。

  • 反復あたり 1 回のテーブル ルックアップ

  • 反復あたり 2 回のシフト

  • 反復あたり 3 回の加算

最近傍線形内挿を伴う単純化された単一のルックアップ テーブル アルゴリズムには、次の演算が必要です。

  • 2 回のテーブル ルックアップ

  • 1 回の乗算

  • 2 回の加算

実際のアプリケーションでは、固定小数点の三角関数を計算するためのアルゴリズムの選択は、通常、必要な精度、コスト、およびハードウェア制約によって異なります。

close all; % close all figure windows

参考文献

  1. Jack E. Volder, The CORDIC Trigonometric Computing Technique, IRE Transactions on Electronic Computers, Volume EC-8, September 1959, pp330-334.

  2. Ray Andraka, A survey of CORDIC algorithm for FPGA based computers, Proceedings of the 1998 ACM/SIGDA sixth international symposium on Field programmable gate arrays, Feb. 22-24, 1998, pp191-200