How can I vectorize this "for" loop in octave? - octave

I am working with an image and trying to get the HSV histograms.
I was trying to vectorize this piece of code:
for i = 1 : k
Hh(H(i))++;
Sh(S(i))++;
Vh(Cmax(i))++;
endfor
H, S and Cmax are occurence arrays and Hh, Sh and Vh are the HSV histograms.
I have tried to vectorize like this:
Hh(H(1:k))++;
Sh(S(1:k))++;
Vh(Cmax(1:k))++;
But the problem is that it only does the incrementation once, so instead of having the number of occurences I only have a '1' where there is at least one value.
How can I vectorize that piece of code?

Related

How can i use fsolve to plot the solutions to a function?

I have a variable of a that is equal to (weight./(1360*pi)).^(1/3), where the weight ranges between 4 and 8kg.
I then have guess of the time taken ,which is 14400 seconds.
The function in question is attached, where infinity is replaced by k=22.
Function in question
This function should be equal to 57/80
r/a can be replaced by 0.464, meaning that the multiplication of the summation can be written as 2/(0.464*pi).
alpha will be equal to 0.7*10^-7
How would i be able to plot the times taken for the masses to cook in hours, for weight in the given range?
I have tried to code this function for a couple of days now but it wont seem to work, due to array size issues and the general function just not working.
Any help would be greatly appreciated :)
First, you need a master equation as a function of weight and t, which you want fsolve to find the zero of. Then for each weight, you can capture it in another function that you then solve for t:
alpha = 0.7e-7;
rbya = 0.464;
k = 1:22;
a = #(weight)(weight./(1360*pi)).^(1/3);
eqn = #(weight,t)2/pi/rbya*sum((-1).^(k-1)./k.*sin(k*pi*rbya).*exp(-1.*k.^2.*pi^2.*alpha.*t./(a(weight).^2)))-57/80;
weights = 4:8;
ts = zeros(size(weights));
for i = 1:numel(weights)
sub_eqn = #(t)eqn(weights(i),t);
ts(i)=fsolve(sub_eqn,14400);
end
plot(weights,ts/(60*60))
xlabel("Weight (kg)")
ylabel("Cooking Time (hrs)")
If you want to solve the entire set of equations at once, then you need to be careful of array sizes (as you have experienced, read more here). k should be a column vector so that sum will sum along each column, and weights should be a row vector so that element-wise operations will repeat the k’s for each weight. You also need your list of initial guesses to be the same size as weights so that fsolve can have a guess for each weight:
alpha = 0.7e-7;
rbya = 0.464;
k = (1:22)';
a = #(weight)(weight./(1360*pi)).^(1/3);
weights = 4:8;
eqn = #(t)2/pi/rbya*sum((-1).^(k-1)./k.*sin(k*pi*rbya).*exp(-1.*k.^2.*pi^2.*alpha.*t./(a(weights).^2)))-57/80;
ts=fsolve(eqn,repmat(14400,size(weights)));
plot(weights,ts/(60*60))
xlabel("Weight (kg)")
ylabel("Cooking Time (hrs)")
Note that you do get slightly different answers with the two methods.

How to plot a function that has a integer constant, for different values of the constant?

In MATLAB how do you plot a graph that has a integer constant, say the value is k and you want to get f(x) = (x.k).(exp(k+1) for k between the 1 to 3.
Here is the full question I am stuck on:
This is the result however there should be a simpler way of doing this, correct?
f = #(x,k)2ˆ(k+1)*x.ˆk.*exp(-2*x)/factorial(k);
xs = 0:1e-2:10;
plot(xs,f(xs,1),'r',xs,f(xs,2),'k',xs,f(xs,3),'b')
xlabel('x'); ylabel('f(x)');

Prepping the number of inputs for a function in MATLAB

For example, ndgrid has inputs as n vectors where n is decided by the user.
For my use case, n can change. I would like to prepare the input list before hand, based on n, then feed the inputs to ndgrid. How do I do that please?
For example, say I have 3 row vectors x1, x2, and x3. Then, if n=3 and I put inputs = [x1,x2,x3], and I use ndgrid(inputs) then MATLAB treats this as ndgrid([x1,x2,x3]) instead of ndgrid(x1,x2,x3). I want the latter, not the former. How do I solve this please?
When we use a cell array, for example x = {some,stuff,inside} you can unpack the cell with x{:}, in a function call, each elements of the cell will be passed as an argument: myfunction(x{:}) is equivalent to myfunction(some, stuff, inside).
In your case:
% Number of inputs
k = 3;
% Put your k input in a cell array
x = {1:3,1:3,1:3};
% If needed you can also have a dynamic output variable
X = cell(k,1);
% Get the result
[X{:}] = ndgrid(x{:})

Octave keeps giving results from function although not asked

I created a function in Octave for which I, at this moment, only want one of the possible outputs displayed. The code:
function [pi, time, numiter] = PageRank(pi0,H,v,n,alpha,epsilon);
rowsumvector=ones(1,n)*H';
nonzerorows=find(rowsumvector);
zerorows=setdiff(1:n,nonzerorows); l=length(zerorows);
a=sparse(zerorows,ones(l,1),ones(l,1),n,1);
k=0;
residual=1;
pi=pi0;
tic;
while (residual >= epsilon)
prevpi=pi;
k=k+1;
pi=alpha*pi*H + (alpha*(pi*a)+1-alpha)*v;
residual = norm(pi-prevpi,1);
end
pi;
numiter=k
time=toc;
endfunction
Now I only want numiter returned, but it keeps giving me back pi as well, no matter whether I delete pi;, or not.
It returns it in the following format:
>> PageRank(pi0,H,v,length(H),0.9,epsilon)
numiter = 32
ans =
0.026867 0.157753 0.026867 0.133573 0.315385
To me it seems strange that the pi is not given with its variable, but merely as an ans.
Any suggestions?
I know the Octave documentation for this is not very extensive, but perhaps it gives enough hints to understand that how you think about output variables is wrong.
The call
PageRank(pi0,H,v,length(H),0.9,epsilon)
returns a single output argument, it is equivalent to
ans = PageRank(pi0,H,v,length(H),0.9,epsilon)
ans is always the implied output argument if none is explicitly given. ans will be assigned the value of pi, the first output argument of your function. The variable pi (nor time, nor numiter) in your workspace will be modified or assigned to. These are the names of local variables inside your function.
To obtain other output variables, do this:
[out1,out2,out3] = PageRank(pi0,H,v,length(H),0.9,epsilon)
Now, the variable out1 will be assigned the value that pi had inside your function. out2 will contain the value of time, and out3 the value of numiter,
If you don't want the first two output arguments, and only want the third one, do this:
[~,~,out3] = PageRank(pi0,H,v,length(H),0.9,epsilon)
The ~ indicates to Octave that you want to ignore that output argument.

How to write arbitrary datatypes into Matlab cell array

This is a general question, not related to a particular operation. I would like to be able to write the results of an arbitrary function into elements of a cell array without regard for the data type the function returns. Consider this pseudocode:
zout = cell(n,m);
myfunc = str2func('inputname'); %assume myfunc puts out m values to match zout dimensions
zout(1,:) = myfunc(x,y);
That will work for "inputname" == "strcat" , for example, given that x and y are strings or cells of strings with appropriate dimension. But if "inputname" == "strcmp" then the output is a logical array, and Matlab throws an error. I'd need to do
zout(1,:) = num2cell(strcmp(x,y));
So my question is: is there a way to fill the cell array zout without having to test for the type of variable generated by myfunc(x,y ? Should I be using a struct in the first place (and if so, what's the best way to populate it)?
(I'm usually an R user, where I could just use a list variable without any pain)
Edit: To simplify the overall scope, add the following "requirement" :
Let's assume for now that, for a function which returns multiple outputs, only the first one need be captured in zout . But when this output is a vector of N values or a vector of cells (i.e. Nx1 cell array), these N values get mapped to zout(1,1:N) .
So my question is: is there a way to fill the cell array zout without having to test for the type of variable generated by myfunc(x,y) ? Should I be using a struct in the first place (and if so, what's the best way to populate it)?
The answer provided by #NotBoStyf is almost there, but not quite. Cell arrays are the right way to go. However, the answer very much depends on the number of outputs from the function.
Functions with only one output
The function strcmp has only one output, which is an array. The reason that
zout{1,:} = strcmp(x,y)
gives you an error message, when zout is dimensioned N x 2, is that the left-hand side (zout{1,:}) expects two outputs from the right-hand side. You can fix this with:
[zout{1,:}] = num2cell(strcmp(x,y)); % notice the square brackets on the LHS
However, there's really no reason to do this. You can simply define zout as an N x 1 cell array and capture the results:
zout = cell(1,1);
x = 'a';
y = { 'a', 'b' };
zout{1} = strcmp(x,y);
% Referring to the results:
x_is_y_1 = zout{1}(1);
x_is_y_2 = zout{1}(2);
There's one more case to consider...
Functions with multiple outputs
If your function produces multiple outputs (as opposed to a single output that is an array), then this will only capture the first output. Functions that produce multiple outputs are defined like this:
function [outA,outB] = do_something( a, b )
outA = a + 1;
outB = b + 2;
end
Here, you need to explicitly capture both output arguments. Otherwise, you just get a. For example:
outA = do_something( [1,2,3], [4,5,6] ); % outA is [2,3,4]
[outA,outB] = do_something( [1,2,3], [4,5,6] ); % outA is [2,3,4], outB is [6,7,8]
Z1 = cell(1,1);
Z1{1,1} = do_something( [1,2,3], [4,5,6] ); % Z1{1,1} is [2,3,4]
Z2 = cell(1,2);
Z2{1,1:2} = do_something( [1,2,3], [4,5,6] ); % Same error as above.
% NB: You really never want to have a cell expansion that is not surrounded
% by square brackets.
% Do this instead:
[Z2{1,1:2}] = do_something( [1,2,3], [4,5,6] ); % Z2{1,1} is [2,3,4], Z2{1,2} is [6,7,8]
This can also be done programmatically, with some limits. Let's say we're given function
func that takes one input and returns a constant (but unknown) number of outputs. We
have cell array inp that contains the inputs we want to process, and we want to collect the results in cell around outp:
N = numel(inp);
M = nargout(#func); % number of outputs produced by func
outp = cell(N,M);
for i=1:N
[ outp{i,:} ] = func( inp{i} );
end
This approach has a few caveats:
It captures all of the outputs. This is not always what you want.
Capturing all of the outputs can often change the behavior of the function. For example, the find function returns linear indices if only one output is used, row/column indices if two outputs are used, and row/column/value if three outputs are used.
It won't work for functions that have a variable number of outputs. These functions are defined as function [a,b,...,varargout] = func( ... ). nargout will return a negative number if the function has varargout declared in its output list, because there's no way for Matlab to know how many outputs will be produced.
Unpacking array and cell outputs into a cell
All true so far, but: what I am hoping for is a generic solution. I can't use num2cell if the function produces cell outputs. So what worked for strcmp will fail for strcat and vice versa. Let's assume for now that, for a function which returns multiple outputs, only the first one need be captured in zout – Carl Witthoft
To provide a uniform output syntax for all functions that return either a cell or an array, use an adapter function. Here is an example that handles numeric arrays and cells:
function [cellOut] = cellify(input)
if iscell(input)
cellOut = input;
elseif isnumeric(input)
cellOut = num2cell(input);
else
error('cellify currently does not support structs or objects');
end
end
To unpack the output into a 2-D cell array, the size of each output must be constant. Assuming M outputs:
N = numel(inp);
% M is known and constant
outp = cell(N,M);
for i=1:N
outp(i,:) = cellify( func( inp{i} ) ); % NB: parentheses instead of curlies on LHS
end
The output can then be addressed as outp{i,j}. An alternate approach allows the size of the output to vary:
N = numel(inp);
% M is not necessary here
outp = cell(N,1);
for i=1:N
outp{i} = cellify( func( inp{i} ) ); % NB: back to curlies on LHS
end
The output can then be addressed as outp{i}{j}, and the size of the output can vary.
A few things to keep in mind:
Matlab cells are basically inefficient pointers. The JIT compiler does not always optimize them as well as numeric arrays.
Splitting numeric arrays into cells can cost quite a bit of memory. Each split value is actually a numeric array, which has size and type information associated with it. In numeric array form, this occurs once for each array. When the array is split, this incurs once for each element.
Use curly braces instead when asigning a value.
Using
zout{1,:} = strcmp(x,y);
instead should work.