多くの場合52ビットを超える非常に長い2進文字列を数値に変換しようとしています。ニューラルデータのLempel-Ziv複雑度のバージョンを計算するためにこれを行っているため、固定先読みウィンドウを設定できません。
長い文字列を変換しようとすると、bin2decがスローされ、バイナリ文字列は52ビット以下でなければならないというエラーが発生します。
このサイズ制限を回避する方法はありますか?
多くの場合52ビットを超える非常に長い2進文字列を数値に変換しようとしています。ニューラルデータのLempel-Ziv複雑度のバージョンを計算するためにこれを行っているため、固定先読みウィンドウを設定できません。
長い文字列を変換しようとすると、bin2decがスローされ、バイナリ文字列は52ビット以下でなければならないというエラーが発生します。
このサイズ制限を回避する方法はありますか?
dec2bin
シングルはそれほどの精度を保存できないため、そのエラーをスローします。あなたの質問は不可能を問いかけます。2つの選択肢があります。浮動小数点値以外のものに値を格納するか、変換する前にある程度の精度を破棄します。
または、達成しようとしていることをより完全に説明してください。
編集:
あなたの追加情報に基づいて、浮動小数点への変換はあなたがやりたいことではないとさらに確信しています。ストレージサイズをより効率的なものに減らしたい場合は、可能な限り密度の高いバイトのベクトル(uint8)に変換します。reshapeを使用して、バイナリ文字列をそれぞれ8桁のN行に分割するだけです。これは、生物学的データに対して受け入れられているアプローチのようです。
str = char((rand(1, 100)>0.5) + '0'); % test data
data = uint8(bin2dec(reshape(str(1:end-mod(end,8)), [], 8)));
このコードでは、8に均等に分割されないビットをトスします。または、uint8ステップをスキップして、結果のベクトルに対して処理を実行します。ここで、各倍精度浮動小数点数は、シーケンスからの1つの8ビットワードを表します。
独自の実装を展開できます。
len = 60;
string = [];
for i = 1:len
string = [string sprintf('%d', randi([0 1]))];
end
% error
% bin2dec(string);
% roll your own...
value = 0;
for i = length(string):-1:1
value = value + str2num(string(i))*2^(length(string)-i);
end
文字列をループして値を追加しているだけです。最後に、value には文字列の 10 進数値が含まれます。これはうまくいきますか?
注:このソリューションは遅いです。自分のマシンで行った文字列の事前割り当てにより、少し高速化できます。また、番号が 1e6 桁になると問題が発生します。その時点で、それを追跡するために可変精度演算が必要になります。そして、それを計算に追加すると、物事が本当に遅くなりました。もし私があなたなら.mex
、MATLAB の機能が必要な場合は、ファイルからこれをコンパイルすることを強く検討します。
@aardvarkkによるクレジットですが、これは彼のアルゴリズムの高速化されたバージョンです(+-100倍高速):
N=100;
strbin = char(randi(2,1,N)+'0'-1);
pows2 = 2.^(N-1:-1:0);
value=pows2*(strbin-'0')';
double
の範囲はギブまたはテイクのどちらかまでしか1.79769e+308
ありませ2^1024
ん。そこから、またはにvalue
なります。したがって、結果の数値を格納する別の方法を見つける必要があります。Inf
NaN
このアルゴリズムの最後のpows2
長所: 多数のキャッシュを作成し、その一部を長さ N の新しい strbin に使用できます。
Nmax = 1e8; % already 700MB for pows2, watch out!
pows2 = 2.^(Nmax-1:-1:0);
そして使用する
value = pows2(Nmax-N+1:end)*(strbin-'0')';
File Exchange には vpi というツールがあります: http://www.mathworks.com/matlabcentral/fileexchange/22725
2^5000
これにより、非常に大きな整数 ( ? no prob)を使用できます。すべてを計算するのが(かなり)遅いだけです。これで上記の方法を使用することはお勧めしません。でもねえ、あなたはすべてを持つことはできません!
パッケージをダウンロードするaddpath
と、次のように動作する可能性があります。
N=3000;
strbin = char(randi(2,1,N)+'0'-1);
binvals=strbin-'0';
val=0;
twopow=vpi(1);
for ii=1:N
val=val+twopow*binvals(N-ii+1);
twopow=twopow*2;
end