generalizing scalar inputs to array inputs for user-defined fucntions - arrays

The round function can take a scalar and operate on it. However it can also take an array and operate on it in expected manner.
>> round(2.3)
ans =
2
>> round([2.3,3.4])
ans =
2 3
I similarly have a function and want it to work in the ""expected"" manner for array inputs. It works well for scalar inputs. I could run a for loop and evaluate my function on each element of the array but what other smarter ways do i have available?
For further concreteness, i have:
function [a,b]=func(c,d,e,f)
And i have d,e,f but i want to evaluate the function to several values of c:-
g=[];
for i=1:10
[a,b]=func(c(i),d,e,f);
g=[g;[a,b]];
end
I am not fully sure how to apply arrayfun though i believe it is what i should use.

What you are looking for is the arrayfun function.
Here is the documentation: http://www.mathworks.com/help/matlab/ref/arrayfun.html
Say, I have this function:
function res = myTest(a,b)
size(a) % for checking that we work on each element
res = a+1;
res = res +b;
I have a matrix A
A = magic(3);
I want to apply myTest with a equal to each element in A
A1 = arrayfun(#(x) myTest(x,2),A)
(x is replaced by the elements of the array declared after the comma)

Related

how to check in matlab if a 3D array has at least one non zero element?

I tried to check if a 3D array is not all zeros using the next code:
notAll_n0_GreaterThan_ni=1;
while notAll_n0_GreaterThan_ni
notAll_n0_GreaterThan_ni=0;
mask=(n0<ni);
numDimensions=ndims(mask);
for dim_ind=1:numDimensions
if any(mask,dim_ind)
notAll_n0_GreaterThan_ni=1;
break;
end
end
if notAll_n0_GreaterThan_ni
n0(mask)=n0(mask)+1;
end
end
It seems I have error in the code because at the end I get for example: n_0(11,3,69)=21 while ni(11,3,69)=21.1556.
I can't find the error. I'll appreciate if someone shows me where I'm wrong and also if there is a simpler way to check existence of nonzero elements in a 3D array.
Let x denote an n-dimensional array. To check if it contains at least one non-zero element, just use
any(x(:))
For example:
>> x = zeros(2,3,4);
>> any(x(:))
ans =
0
>> x(1,2,2) = 5;
>> any(x(:))
ans =
1
Other, more exotic possibilities include:
sum(abs(x(:)))>0
and
nnz(x)>0
This is what you looking for
B = any(your_Array_name_here(:) ==0); no need for loops
the (:) turns the elements of your_Array into a single column vector, so you can use this type of statement on an array of any size
I 've tested this and it works
A = rand(3,7,5) * 5;
B = any(A(:) ==0);

Arrays operations in Matlab

I would like a function to compute the following operation:
I made this function that requires a matrix at its input, and returns the distances between every two lines of it in another matrix.
RGB_dist_full definition:
function[D]=RGB_dist_full(x)
I = nchoosek(1:size(x,1),2);
D = RGB_dist(x(I(:,1),:), x(I(:,2),:));
squareform(D)
end
RGB_dist definition:
function[distance]=RGB_dist(x,y)
distance=sqrt(sum((x-y).^2*[3;4;2],2));
end
Main program looks like this:
clc
clear all
rgbImage = imread('peppers.png');
K=6;
N=uint64(K*2);
rgb_columns = reshape(rgbImage, [], 3);
[unique_colors, m, n] = unique(rgb_columns, 'rows','stable');
color_counts = accumarray(n, 1);
[max_count, idx] = max(color_counts);
Imgsize=size(rgbImage);
U=unique_colors(1:N,:)
size(U)
x=[62,29,64;
63,31,62;
65,29,60;
63,29,62;
63,31,62;];
RGB_dist_full(x);
RGB_dist_full(U);
Why do I get 'Error using *
MTIMES is not fully supported for
integer classes. At least one input
must be scalar.
To compute elementwise TIMES, use
TIMES (.*) instead.' for the second call of the function, whereas the first one returns the desired output?
For these types of calculations you want to cast to double precision , because sqrt(integer) is usually not an integer. For that just double(rgbImage) immediately after reading the image will do.

How to build an array by function handle

I am trying to produce something like this in MATLAB with function handle
f=#(x,y)(x(1)*x(2)+y);
c=[2 3 4;5 9 2];
h=[5 1 2];
f(c,h)
The answer should be:
15 11 12
But when I write this code below, it just builds a number not an array.
f=#(x)(x(1)*x(2))
f(c)
answer:
10
Can someone explain me where I went wrong?
I do not know what you expected here. The cause of the problem is quite clear.
a = 1;
b = 2;
c = [3 4];
d = a*b+c;
is a scalar + vector operation which always returns
ans = [a*b+c(1), a*b+c(2)];
however scalar*scalar which was the second case always returns a scalar. What you do is that you multiply the first matrix element of x (or c) with the second element. That is to say element c(1,1)*c(2,1) since matlab works columnwise. If you looks at your values you would probably notice the answer is incorrect as well, if you are trying to do what I think you are. You could try this instead,
f=#(x,y)(x(1,:).*x(2,:)+y);
c=[2 3 4;5 9 2];
h=[5 1 2];
f(c,h)
which multipies the elements on the first row of x with the same column on the second row and then adds y. An anonymous function takes a number of inputs and perform a defined operation, the same as ordinary functions or ordinary codes. You can see them as functions that does not require a call to another m file. The main differences (except that ordinary functions gives more freedom), are how they are handled by matlab and not in the syntax.

Pass argument multiple times in MATLAB

Is there a way to pass an argument multiple times to different arrays?
What I want to do is:
r = '1:10:end'; % This doesn't work for me
plot(x1(r), y1(r));
plot(x2(r), y2(r));
...
and pass r to different arrays (with different lengths) in many plot functions. I tried with [r] but no success.
As I understand it, you want to plot every 10th element of possibly different sized arrays. There are a few ways you could do this. One way would be to write a short function to filter your arrays for you, for instance:
plot_10 = #(x,y) plot(x(1:10:end),y(1:10:end));
plot_10(x1,y1);
plot_10(x2,y2);
...
EDIT: Just an additional thought. If you wanted to enable the extended functionality of plot (e.g. passing line/colour arguments, etc). You could do something like this:
plot_10 = #(x,y,varargin) plot(x(1:10:end),y(1:10:end),varargin{:});
plot_10(x1,t1,'k+');
To use the "end" operator, it needs to be inside an array access call;
n = 10;
r = 1 : 1 : n;
r(1:end) % is legal
r(1:floor(end/2)) % is legal
So you could do something like this:
s = rand(1,2*n);
s(r)
% to compare...
s( 1:1:n )

Matlab - running a function with parameters for every element of an array?

Matlab has a nice property that scalar functions (such as sin) can work on arrays, operating on any element of the array and returning an array as result.
I have a scalar function f(x,p) where x is a scalar, and p is a parameter (actually an array of parameters). Given a fixed parameter p, I wish to run f(x,p) on an array A. In a language like Ruby it would look like this:
A.collect{|x| f(x,p)}
But I have no idea how to do it in Matlab for functions that accept parameters and not only the scalar from the array I want to operate on.
The MATLAB equivalent is to supply a function handle taking only a single argument, and sending it to arrayfun.
arrayfun( #(x) f(x, p), A )
For example,
A = 1:10;
p = 2;
arrayfun( #(x) x.^p, A )
Note that the anonymous function creates a closure, capturing the value of p.

Resources