How to make the conversion more faster?
2 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Hi. I am trying to convert from decimal to Canonic Signed Digit(CSD). I took the code from this link: http://www.mathworks.com/matlabcentral/fileexchange/9730-canonical-signed-digits
This code takes the decimal input and provides CSD output in string form.
Now i am trying to apply this code for a matrix and took the idea from this link:
Following is the code:
C = [2.336 -1.900; 3.541 -0.219];
range = 5;
resolution = 15;
k = 1;
CC = repmat('', numel(C), range+resolution);
for i = 1 : numel(C)
CC(k,1:(range + resolution )) = csdigit(C(i),range,resolution);
k = k+1;
end
This code used many times by some other codes and the input matrix "C" may have thousands elements. So, if it is possible to reduce the time, it will help my research a lot.
4 Kommentare
Akzeptierte Antwort
Jan
am 11 Mär. 2012
Your function would be faster with a pre-allocation. This:
CC = repmat('', numel(C), range+resolution);
does not pre-allocate CC, because replicating an empty string gives an empty string.
csdigit is not programmed efficiently. The exhaustively celebrated conversion from char to double to char to double to char is a waste of time. E.g. ('0'+0)*ones(size(binNum)) is suboptimal. repmat('0', size(binNum)) would be smarter. bin2dec and dec2bin are slow also, e.g. in bin2dec(char(neg)) * 2 ^ (-resolution). What does a multiplication by 2^-x do with a binary string?? Yes, this can be programmed much faster.
[EDITED] I'm running this code:
function Test(C)
range = 5;
resolution = 15;
CC = repmat('', numel(C), range+resolution);
for i = 1 : numel(C)
CC(i, 1:(range + resolution )) = csdigit(C(i),range,resolution);
end
with these values:
C = floor(rand(100) * 64) / 32;
in Matlab 2009a/64. This needs 5.14 seconds.
The first steop is pre-allocation: repmat('') -> repmat(' '). Result: 4.06 seconds.
Insert a variable pow2res = pow2(resolution) and use them instead of all 2^-resolution and 2^resolution.
Then dec2bin and bin2dec can be replaced by these simplified versions *locally inside csdigit:
function s=dec2bin(d,n)
[f,e] = log2(d);
s=char(rem(floor(d*pow2(1-max(n,e):0)),2)+'0');
function x = bin2dec(s)
x = sum((s - '0') .* pow2(length(s)-1:-1:0), 2);
==> 2.08 seconds.
7 Kommentare
Jan
am 11 Mär. 2012
I'm really impressed by your timings. All I get is
1. The warning: Some precision has been lost. Returned value is truncated!
2. A "Subscripted assignment dimension mismatch." error in the line:
CC(k,1:(range + resolution )) = csdigit(C(i),range,resolution);
Do I miss anything?
Weitere Antworten (2)
Daniel Shub
am 11 Mär. 2012
The easiest thing is probably to use a faster computer.
A quick look at csdigit doesn't reveal anything to me that is obviously multi-threaded. You could try replacing your for loop with a parfor loop. This could give you a speed up proportional to the number of cores. If you have access to a cluster, you can even get a bigger boost.
You could also strip all the error checks, and anything else that you do not need, from csdigit. It is probably not a big boost, but it may help.
You could convert csdigit to a mex and see if that buys you anything.
Siehe auch
Kategorien
Mehr zu Numeric Types finden Sie in Help Center und File Exchange
Produkte
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!