I have a problem with a function in matlab - windows

I'm depveloping a function in matlab, but I have the following problem.
When I assign the codigo variable to my function, matlab show me the next message
Error using ContLetrasTexto>shannon
Too many output arguments.
Error in ContLetrasTexto (line 111)
codigos = shannon(1, length(vectorprobabilidad), vectorprobabilidad, codigos);
My code is the following
% create the cell array of codes
codigos = cell(size(letra));
% call the recursive encoder function
codigos = shannon(1, length(vectorprobabilidad), vectorprobabilidad, codigos);
%Método shannon-Fano%
function shannon(inicio, fin, p, codes)
shannon_inicial = inicio;
shannon_final = fin;
suma_arriba = p(inicio);
suma_fin = p(fin);
while(shannon_inicial ~= shannon_final-1)
if (suma_arriba > suma_fin)
shannon_final = shannon_final - 1;
suma_fin = suma_fin + p(shannon_final);
else
shannon_inicial = shannon_inicial + 1;
suma_arriba = suma_arriba + p(shannon_inicial);
end;
end;
for i = inicio:shannon_inicial
p(i) = 0;
end;
for j = shannon_final:fin
p(j) = 1;
end;
if(shannon_inicial-inicio+1 > 1)
shannon(inicio,shannon_inicial,p,codes);
end;
if(fin-shannon_final+1 > 1)
shannon(shannon_final,fin,p,codes);
end;
end
I'll be grateful for your help

Related

Solving Project Euler #12 with Matlab

I am trying to solve Problem #12 of Project Euler with Matlab and this is what I came up with to find the number of divisors of a given number:
function [Divisors] = ND(n)
p = primes(n); %returns a row vector containing all the prime numbers less than or equal to n
i = 1;
count = 0;
Divisors = 1;
while n ~= 1
while rem(n, p(i)) == 0 %rem(a, b) returns the remainder after division of a by b
count = count + 1;
n = n / p(i);
end
Divisors = Divisors * (count + 1);
i = i + 1;
count = 0;
end
end
After this, I created a function to evaluate the number of divisors of the product n * (n + 1) / 2 and when this product achieves a specific limit:
function [solution] = Solution(limit)
n = 1;
product = 0;
while(product < limit)
if rem(n, 2) == 0
product = ND(n / 2) * ND(n + 1);
else
product = ND(n) * ND((n + 1) / 2);
end
n = n + 1;
end
solution = n * (n + 1) / 2;
end
I already know the answer and it's not what comes back from the function Solution. Could someone help me find what's wrong with the coding.
When I run Solution(500) (500 is the limit specified in the problem), I get 76588876, but the correct answer should be:
76576500.
The trick is quite simple while it also bothering me for a while: The iteration in you while loop is misplaced, which would cause the solution a little bigger than the true answer.
function [solution] = Solution(limit)
n = 1;
product = 0;
while(product < limit)
n = n + 1; %%%But Here
if rem(n, 2) == 0
product = ND(n / 2) * ND(n + 1);
else
product = ND(n) * ND((n + 1) / 2);
end
%n = n + 1; %%%Not Here
end
solution = n * (n + 1) / 2;
end
The output of Matlab 2015b:
>> Solution(500)
ans =
76576500

How to Vectorize Dependent For-Loops in Matlab

I was wondering if anyone could help me to vectorize this part of my code. Here, bin_pdf is binomial coefficient function. pb and pd are scalar parameters. Thank You!
for t=0:min(T,r)
for n=0:r-t
pp = (bin_pdf(n,pb,r-t) * bin_pdf(t,pd,min(T,r)));
pt = pt + t/r * pp;
pn = pn + n/r * pp;
pc = pc + (r-t-n)/r * pp;
end
end
where
function p = bin_pdf(x,rho,n)
if (x > n) || (n < 0)
p = 0;
else
p = Choosenk(n,x) * rho^x * (1-rho)^(n-x);
end
and
function C=Choosenk(n,k)
if k>n/2
k=n-k;
end;
C=1;
for i=0:k-1
C=C*(n-i)/(k-i);
end
end
This is the vectorized Choosenk. if you dont call it somewhere else you could integrate it into the bin_pdf.
function C=Choosenk(n,k)
if k>n/2
k=n-k;
end;
C=prod((n-k+1:n)./(1:k));
end

How to remove the for loop in the following MATLAB code?

I need to perform the following computation in an image processing project. It is the logarthmic of the summation of H3. I've written the following code but this loop has a very high computation time. Is there any way to eliminate the for loop?
for k=1:i
for l=1:j
HA(i,j)=HA(i,j)+log2((H3(k,l)/probA).^q);
end;
end;
Thanks in advance!
EDIT:
for i=1:256
for j=1:240
probA = 0;
probC = 0;
subProbA = H3(1:i,1:j);
probA = sum(subProbA(:));
probC = 1-probA;
for k=1:i
for l=1:j
HA(i,j)=HA(i,j)+log2((H3(k,l)/probA).^q);
end;
end;
HA(i,j)=HA(i,j)/(1-q);
for k=i+1:256
for l=j+1:240
HC(i,j)=HC(i,j)+log2((H3(k,l)/probC).^q);
end;
end;
HC(i,j)=HC(i,j)/(1-q);
e1(i,j) = HA(i,j) + HC(i,j);
if e1(i) >= emax
emax = e1(i);
tt1 = i-1;
end;
end;
end;
Assuming the two loops are nested inside some other outer loops that are iterated with i and j (though using i and j as iterators are not the best practices) and also assuming that probA and q are scalars, try this -
HA(i,j) = sum(sum(log2((H3(1:i,1:j)./probA).^q)))
Using the above code snippet, yon can replace your actual code posted in the EDIT section with this -
for i=1:256
for j=1:240
subProbA = H3(1:i,1:j);
probA = sum(subProbA(:));
probC = 1-probA;
HA(i,j) = sum(sum(log2((subProbA./probA).^q)))./(1-q);
HC(i,j) = sum(sum(log2((subProbA./probC).^q)))./(1-q);
e1(i,j) = HA(i,j) + HC(i,j);
if e1(i) >= emax
emax = e1(i);
tt1 = i-1;
end
end
end
Note that in this code, probA = 0; and probC = 0; are removed as they are over-written anyway later in the original code.
Assuming that q is scalar value, this code removes all the four for loops. Also in your given code you are calculating the maximum value of e1 only along the first column. If that is so then you should put in out of the second loop
height = 256;
width = 240;
a = repmat((1:height)',1,width);
b = repmat(1:width,height,1);
probA = arrayfun(#(ii,jj)(sum(sum(H3(1:ii,1:jj)))),a,repmat(1:width,height,1));
probC = 1 - probA;
HA = arrayfun(#(ii,jj)(sum(sum(log2((H3(1:ii,1:jj)/probA(ii,jj)).^q)))/(1-q)),a,b);
HC = arrayfun(#(ii,jj)(sum(sum(log2((H3(ii+1:height,jj+1:width)/probC(ii,jj)).^q)))/(1-q)),a,b);
e1 = HA + HC;
[emax tt_temp] = max(e1(:,1));
tt1 = tt_temp - 1;

Understanding and Implementing Thinning Algorithm in MATLAB

I am trying to implement my own Thinning Algorithm in Matlab to understand the thinning algorithm. I am following http://fourier.eng.hmc.edu/e161/lectures/morphology/node2.html and implementing my own code, but the result is incorrect.
Here is my code:
%for the sake of simplicity, the outermost pixels are ignored.
for x = 2:1:511
for y = 2:1:511
% if this pixel is not black, then, proceed in.
if (frame2(y,x) > 0)
% the pos(1 to 8) here are for the surrounding pixels.
pos(1) = frame2(y-1,x-1);
pos(2) = frame2(y, x-1);
pos(3) = frame2(y+1, x+1);
pos(4) = frame2(y+1, x);
pos(5) = frame2(y+1, x-1);
pos(6) = frame2(y, x-1);
pos(7) = frame2(y-1, x-1);
pos(8) = frame2(y-1, x);
nonZeroNeighbor = 0;
transitSequence = 0;
change = 0;
for n = 1:1:8
% for N(P1)
if (pos(n) >= 1)
nonZeroNeighbor = nonZeroNeighbor + 1;
end
% for S(P1)
if (n > 1)
if (pos(n) ~= change)
change = pos(n);
transitSequence = transitSequence + 1;
end
else
change = pos(n);
end
end
% also for S(P1)
if ((nonZeroNeighbor > 1 && nonZeroNeighbor < 7) || transitSequence >= 2)
markMatrix(y,x) = 1;
fprintf(1, '(%d,%d) nonzero: %d transit: %d\n', y,x, nonZeroNeighbor, transitSequence);
else %this else here is for the reverse.
end
end
end
end
for x = 2:1:511
for y = 2:1:511
if (markMatrix(y,x) > 0)
frame2(y,x) = 0;
end
end
end
savePath = [path header number2 '.bmp'];
imwrite(frame2, savePath, 'bmp'); %output image here, replacing the original
From the site above, it states the function S(P1) as:
"S(P1): number of 0 to 1 (or 1 to 0) transitions in the sequence (P2, P3, ..., P9)"
For this part, my codes are below "% for S(P1)" and "% also for S(P1)" comments. Am I implementing this function correctly? The output image I got is simply blank. Nothing at all.
For the correct output, I am aware that there is a logical problem. Regarding the site, it states:
When part of the shape is only 2-pixel wide, all pixels are boundary points and will be marked and then deleted.
This problem is to be ignored for now.
I've had a go at the problem and think I managed to get the algorithm to work. I've made several small edits along the way (please see the code below for details), but also found two fundamental problems with your initial implementation.
Firstly, you assumed all would be done in the first pass of step 1 and 2, but really you need to let the algorithm work away at the image for some time. This is typical for iterative morphological steps 'eating' away at the image. This is the reason for the added while loop.
Secondly, your way of calculating S() was wrong; it counted both steps from 0 to 1 and 1 to 0, counting twice when it shouldn't and it didn't take care of the symmetry around P(2) and P(9).
My code:
%Preliminary setups
close all; clear all;
set(0,'DefaultFigureWindowStyle','Docked')
%Read image
frame2 = imread('q1.jpg');
%Code for spesific images
%frame2(:,200:end) = [];
%frame2 = rgb2gray(frame2);
%Make binary
frame2(frame2 < 128) = 1;
frame2(frame2 >= 128) = 0;
%Get sizes and set up mark
[Yn Xn] = size(frame2);
markMatrix = zeros(Yn,Xn);
%First visualization
figure();imagesc(frame2);colormap(gray)
%%
%While loop control
cc = 0;
changed = 1;
while changed && cc < 50;
changed = 0;
cc = cc + 1;
markMatrix = zeros(Yn,Xn);
for x = 2:1:Xn-1
for y = 2:1:Yn-1
% if this pixel is not black, then, proceed in.
if (frame2(y,x) > 0)
% the pos(2 to 9) here are for the surrounding pixels.
pos(1) = frame2(y, x);
pos(2) = frame2(y-1, x);
pos(3) = frame2(y-1, x+1);
pos(4) = frame2(y, x+1);
pos(5) = frame2(y+1, x+1);
pos(6) = frame2(y+1, x);
pos(7) = frame2(y+1, x-1);
pos(8) = frame2(y, x-1);
pos(9) = frame2(y-1, x-1);
nonZeroNeighbor = 0;
transitSequence = 0;
change = pos(9);
for n = 2:1:9
%N()
nonZeroNeighbor = sum(pos(2:end));
%S()
if (double(pos(n)) - double(change)) < 0
transitSequence = transitSequence + 1;
end
change = pos(n);
end
%Test if pixel is to be removed
if ~( nonZeroNeighbor == 0 || nonZeroNeighbor == 1 ...
||nonZeroNeighbor == 7 || nonZeroNeighbor == 8 ...
||transitSequence >= 2)
markMatrix(y,x) = 1;
fprintf(1, '(%d,%d) nonzero: %d transit: %d\n', ...
y,x, nonZeroNeighbor, transitSequence);
end
end
end
end
%Mask out all pixels found to be deleted
frame2(markMatrix > 0) = 0;
%Check if anything has changed
if sum(markMatrix(:)) > 0;changed = 1;end
end
%Final visualization
figure();imagesc(frame2);colormap(gray)

Is there a "queue" in MATLAB?

I want to convert a recursive function to a iterative one. What I normally do is, I initialize a queue, put the first job into queue. Then in a while loop I consume jobs from queue and add new ones to the queue. If my recursive function calls itself multiple times (e.g walking a tree with many branches) multiple jobs are added. Pseudo code:
queue = new Queue();
queue.put(param);
result = 0;
while (!queue.isEmpty()) {
param = queue.remove();
// process param and obtain new param(s)
// change result
queue.add(param1);
queue.add(param2);
}
return result;
I cannot find any queue like structure in MATLAB though. I can use vector to simulate queue where adding 3 to queue is like:
a = [a 3]
and removing element is
val = a(1);
a(1) = [];
If I got the MATLAB way right, this method will be a performance killer.
Is there a sane way to use a queue in MATLAB?
What about other data structures?
If you insist on using proper data structures, you can use Java from inside MATLAB:
import java.util.LinkedList
q = LinkedList();
q.add('item1');
q.add(2);
q.add([3 3 3]);
item = q.remove();
q.add('item4');
Ok, here's a quick-and-dirty, barely tested implementation using a MATLAB handle class. If you're only storing scalar numeric values, you could use a double array for "elements" rather than a cell array. No idea about performance.
classdef Queue < handle
properties ( Access = private )
elements
nextInsert
nextRemove
end
properties ( Dependent = true )
NumElements
end
methods
function obj = Queue
obj.elements = cell(1, 10);
obj.nextInsert = 1;
obj.nextRemove = 1;
end
function add( obj, el )
if obj.nextInsert == length( obj.elements )
obj.elements = [ obj.elements, cell( 1, length( obj.elements ) ) ];
end
obj.elements{obj.nextInsert} = el;
obj.nextInsert = obj.nextInsert + 1;
end
function el = remove( obj )
if obj.isEmpty()
error( 'Queue is empty' );
end
el = obj.elements{ obj.nextRemove };
obj.elements{ obj.nextRemove } = [];
obj.nextRemove = obj.nextRemove + 1;
% Trim "elements"
if obj.nextRemove > ( length( obj.elements ) / 2 )
ntrim = fix( length( obj.elements ) / 2 );
obj.elements = obj.elements( (ntrim+1):end );
obj.nextInsert = obj.nextInsert - ntrim;
obj.nextRemove = obj.nextRemove - ntrim;
end
end
function tf = isEmpty( obj )
tf = ( obj.nextRemove >= obj.nextInsert );
end
function n = get.NumElements( obj )
n = obj.nextInsert - obj.nextRemove;
end
end
end
Is a recursive solution really so bad? (always examine your design first).
File Exchange is your friend. (steal with pride!)
Why bother with the trouble of a proper Queue or a class - fake it a bit. Keep it simple:
q = {};
head = 1;
q{head} = param;
result = 0;
while (head<=numel(q))
%process param{head} and obtain new param(s)
head = head + 1;
%change result
q{end+1} = param1;
q{end+1} = param2;
end %loop over q
return result;
If the performance suffers from adding at the end too much - add in chunks:
chunkSize = 100;
chunk = cell(1, chunkSize);
q = chunk;
head = 1;
nextLoc = 2;
q{head} = param;
result = 0;
while (head<endLoc)
%process param{head} and obtain new param(s)
head = head + 1;
%change result
if nextLoc > numel(q);
q = [q chunk];
end
q{nextLoc} = param1;
nextLoc = nextLoc + 1;
q{end+1} = param2;
nextLoc = nextLoc + 1;
end %loop over q
return result;
A class is certainly more elegant and reusable - but fit the tool to the task.
If you can do with a FIFO queue of predefined size without the need for simple direct access, you can simply use the modulo operator and some counter variable:
myQueueSize = 25; % Define queue size
myQueue = zeros(1,myQueueSize); % Initialize queue
k = 1 % Counter variable
while 1
% Do something, and then
% Store some number into the queue in a FIFO manner
myQueue(mod(k, myQueueSize)+1) = someNumberToQueue;
k= k+1; % Iterate counter
end
This approach is super simple, but has the downside of not being as easily accessed as your typical queue. In other words, the newest element will always be element k, not element 1 etc.. For some applications, such as FIFO data storage for statistical operations, this is not necessarily a problem.
Use this code, save the code as a m file, and use the functions such q.pop() etc.
this is the original code with some modifications:
properties (Access = private)
buffer % a cell, to maintain the data
beg % the start position of the queue
rear % the end position of the queue
% the actually data is buffer(beg:rear-1)
end
properties (Access = public)
capacity % ص»µؤبفء؟£¬µ±بفء؟²»¹»ت±£¬بفء؟ہ©³نخھ2±¶،£
end
methods
function obj = CQueue(c) % ³ُت¼»¯
if nargin >= 1 && iscell(c)
obj.buffer = [c(:); cell(numel(c), 1)];
obj.beg = 1;
obj.rear = numel(c) + 1;
obj.capacity = 2*numel(c);
elseif nargin >= 1
obj.buffer = cell(100, 1);
obj.buffer{1} = c;
obj.beg = 1;
obj.rear = 2;
obj.capacity = 100;
else
obj.buffer = cell(100, 1);
obj.capacity = 100;
obj.beg = 1;
obj.rear = 1;
end
end
function s = size(obj) % ¶سءذ³¤¶ب
if obj.rear >= obj.beg
s = obj.rear - obj.beg;
else
s = obj.rear - obj.beg + obj.capacity;
end
end
function b = isempty(obj) % return true when the queue is empty
b = ~logical(obj.size());
end
function s = empty(obj) % clear all the data in the queue
s = obj.size();
obj.beg = 1;
obj.rear = 1;
end
function push(obj, el) % ر¹بëذآشھثطµ½¶سخ²
if obj.size >= obj.capacity - 1
sz = obj.size();
if obj.rear >= obj.beg
obj.buffer(1:sz) = obj.buffer(obj.beg:obj.rear-1);
else
obj.buffer(1:sz) = obj.buffer([obj.beg:obj.capacity 1:obj.rear-1]);
end
obj.buffer(sz+1:obj.capacity*2) = cell(obj.capacity*2-sz, 1);
obj.capacity = numel(obj.buffer);
obj.beg = 1;
obj.rear = sz+1;
end
obj.buffer{obj.rear} = el;
obj.rear = mod(obj.rear, obj.capacity) + 1;
end
function el = front(obj) % ·µ»ط¶ست×شھثط
if obj.rear ~= obj.beg
el = obj.buffer{obj.beg};
else
el = [];
warning('CQueue:NO_DATA', 'try to get data from an empty queue');
end
end
function el = back(obj) % ·µ»ط¶سخ²شھثط
if obj.rear == obj.beg
el = [];
warning('CQueue:NO_DATA', 'try to get data from an empty queue');
else
if obj.rear == 1
el = obj.buffer{obj.capacity};
else
el = obj.buffer{obj.rear - 1};
end
end
end
function el = pop(obj) % µ¯³ِ¶ست×شھثط
if obj.rear == obj.beg
error('CQueue:NO_Data', 'Trying to pop an empty queue');
else
el = obj.buffer{obj.beg};
obj.beg = obj.beg + 1;
if obj.beg > obj.capacity, obj.beg = 1; end
end
end
function remove(obj) % اه؟ص¶سءذ
obj.beg = 1;
obj.rear = 1;
end
function display(obj) % دشت¾¶سءذ
if obj.size()
if obj.beg <= obj.rear
for i = obj.beg : obj.rear-1
disp([num2str(i - obj.beg + 1) '-th element of the stack:']);
disp(obj.buffer{i});
end
else
for i = obj.beg : obj.capacity
disp([num2str(i - obj.beg + 1) '-th element of the stack:']);
disp(obj.buffer{i});
end
for i = 1 : obj.rear-1
disp([num2str(i + obj.capacity - obj.beg + 1) '-th element of the stack:']);
disp(obj.buffer{i});
end
end
else
disp('The queue is empty');
end
end
function c = content(obj) % ب،³ِ¶سءذشھثط
if obj.rear >= obj.beg
c = obj.buffer(obj.beg:obj.rear-1);
else
c = obj.buffer([obj.beg:obj.capacity 1:obj.rear-1]);
end
end
end end
Reference:
list, queue, stack Structures in Matlab
I had a need for queue like data structure as well.
Fortunately I had a limited number of elements (n).
They all get into queue at some point but only once.
If you situation is similar you can adapt the simple algorithm using fixed size array and 2 indices.
queue = zeros( n, 1 );
firstq = 1;
lastq = 1;
while( lastq >= firstq && firstq <= n )
i = queue( firstq ); % pull first element from the queue
% you do not physically remove it from an array,
% thus saving time on memory access
firstq = firstq + 1;
% % % % % % % % % % % % % WORKER PART HERE
% do stuff
%
% % % % % % % % % % % % % % % % % % % % %
queue( lastq ) = j; % push element to the end of the queue
lastq = lastq + 1; % increment index
end;
In the case where you need a queue only to store vectors (or scalars), then it is not difficult to use a matrix along with the circshift() function to implement a basic queue with a fixed length.
% Set the parameters of our queue
n = 4; % length of each vector in queue
max_length = 5;
% Initialize a queue of length of nx1 vectors
queue = NaN*zeros(n, max_length);
queue_length = 0;
To push:
queue = circshift(queue, 1, 2); % Move each column to the right
queue(:,1) = rand(n, 1); % Add new vector to queue
queue_length = min(max_length, queue_length + 1);
To pop:
result = queue(:,last)
queue(:, last) = NaN;
queue_length = max(1, queue_length - 1);

Resources