Matlab: How to create a CDF array - matlab

I am fairly new to Matlab and am trying to learn for school. I have created a vector of values with fixed differences between consecutive values. E.g. A = [1 2.5 4 5.5 7 8.5 10 ...].
I also have another vector of random values, e.g. B = [3 7 1 2 3 4 8 0 ...].
I want to create a new vector of the same size of A, which has numbers indicating the number of values in B which are less than or equal to each value in A.
In this example, C = [2 3 6 6 7 8 ...]
Thanks in advance!
Context: I am working on a CDF function

You can use bsxfun() to implement element-wise comparisons between arrays:
C = sum( bsxfun(#le, B', A) )
Here we're passing bsxfun() the "less than or equal to" function handle, #le . This produces a length(B) by length(A) logical array. We simply sum down the rows to get the total number of TRUE's.

Related

How to add elements of a matrix to create a new matrix?

Say I have a matrix
x = [1 2 3 4 ]
and I want to create a matrix that adds two elements and outputs a third?
y = [1+2 3+4]
y = [3 7]
For four values, I can just do y=[x(1)+x(2) x(3)+x(4)].
How would I go about doing that if x was bigger and variable (say a thousand elements)? How would I program y?
I've been struggling with this for two days now... thanks in advance...
A simple way would be to reshape the original array x into a matrix containing k rows, k being the number of elements you are summing together (here 2, sorry I don't know how to explain this), and then simply call sum on this matrix which will calculate the sum of each column and output it into a new vector y.
Example:
x = [1:10]
block = 2
r = reshape(x,block,[])
So here r looks like this:
r =
1 3 5 7 9
2 4 6 8 10
Therefore calling sum with the 1st dimension on r yields the following:
y = sum(reshape(x,block,[]),1)
y =
3 7 11 15 19

Frequency for cells in Matlab?

I have a cell in Matlab A of dimension mx1, e.g. m=11
A={1 2 2 4 5 5 6 3 1 1 2}
Let D be the vector of unique elements in A, i.e.
D=unique(A,'stable')
that gives
D={1 2 4 5 6 3}
I want to find C that gives the number of repetitions of each element in D, i.e.
C={3 3 1 2 1 1}
I tried
count=histc(A,D);
but it tells me
"Error using histc
First Input must be a real non-sparse numeric array."
If I try to convert A and C in matrices using cell2mat it gives me
"Error using cat
Dimensions of matrices being concatenated are not consistent."
Any idea?
Matlab recommended histcount instead of histc
a = cell2mat(A) ;
count=histcounts(a, max(a) - min(a))

Finding the most recent indices with different values

I am familiar with Matlab but am still having trouble with vectorized methods in my intuition, so I was wondering if anyone could demonstrate how they would manage this problem.
I have an array, for example A = [1 1 2 2 1 3 3 3 4 3 4 4 5].
I want to return an array B such that each element is the index of A's most 'recent' element with a different value than the previous ones.
So for our array A, B would equal [x x 2 2 4 5 5 5 8 9 10 10 12], where the x's can be any consistent value you like, because there is no previous index satisfying those characteristics.
I know how I would code it as a for-loop, and I bet the for-loop is probably faster, but can anyone vectorize this to faster than the for-loop?
Here's my for-loop:
prev=0;
B=zeros(length(A),1);
for i=2:length(A)
if A(i-1)~=A(i)
prev=i-1;
end
B(i)=prev;
end
Find the indices of the entries where the value changes:
ind = find(diff(A) ~= 0);
The values that should appear in B are therefore:
val = [0 ind];
Construct the diff of B: fill in the difference between the values that should appear at the right places:
Bd = zeros(size(B))';
Bd(ind + 1) = diff(val);
Now use cumsum to construct B:
B = cumsum(Bd)
Not sure whether this results in a speed-up though.

Creating a matrix from a function handle (MATLAB)

What I intend to do is very simple but yet I haven't found a proper way to do it. I have a function handle which depends on two variables, for example:
f = #(i,j) i+j
(mine is quite more complicated, though)
What I'd like to do is to create a matrix M such that
M(i,j) = f(i,j)
Of course I could use a nested loop but I'm trying to avoid those. I've already managed to do this in Maple in a quite simple way:
f:=(i,j)->i+j;
M:=Matrix(N,f);
(Where N is the dimension of the matrix) But I need to use MATLAB for this. For now I'm sticking to the nested loops but I'd really appreciate your help!
Use bsxfun:
>> [ii jj] = ndgrid(1:4 ,1:5); %// change i and j limits as needed
>> M = bsxfun(f, ii, jj)
M =
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
If your function f satisfies the following condition:
C = fun(A,B) accepts arrays A and B of arbitrary, but equal size and returns output of the same size. Each element in the output array C is the result of an operation on the corresponding elements of A and B only. fun must also support scalar expansion, such that if A or B is a scalar, C is the result of applying the scalar to every element in the other input array.
you can dispose of ndgrid. Just add a transpose (.') to the first (i) vector:
>> M = bsxfun(f, (1:4).', 1:5)
Function handles can accept matrices as inputs. Simply pass a square matrix of size N where the values corresponds to the row number for i, and a square matrix of size N where the values correspond to the column number for j.
N = 5;
f = #(i,j) i+j;
M = f(meshgrid(1:N+1), meshgrid(1:N+1)')

Averaging every n elements of a vector in matlab

I would like to average every 3 values of an vector in Matlab, and then assign the average to the elements that produced it.
Examples:
x=[1:12];
y=%The averaging operation;
After the operation,
y=
[2 2 2 5 5 5 8 8 8 11 11 11]
Therefore the produced vector is the same size, and the jumping average every 3 values replaces the values that were used to produce the average (i.e. 1 2 3 are replaced by the average of the three values, 2 2 2). Is there a way of doing this without a loop?
I hope that makes sense.
Thanks.
I would go this way:
Reshape the vector so that it is a 3×x matrix:
x=[1:12];
xx=reshape(x,3,[]);
% xx is now [1 4 7 10; 2 5 8 11; 3 6 9 12]
after that
yy = sum(xx,1)./size(xx,1)
and now
y = reshape(repmat(yy, size(xx,1),1),1,[])
produces exactly your wanted result.
Your parameter 3, denoting the number of values, is only used at one place and can easily be modified if needed.
You may find the mean of each trio using:
x = 1:12;
m = mean(reshape(x, 3, []));
To duplicate the mean and reshape to match the original vector size, use:
y = m(ones(3,1), :) % duplicates row vector 3 times
y = y(:)'; % vector representation of array using linear indices