Plot of the L0 norm penalty function in matlab - matlab

I am interested to plot the L0-norm penalty function in matlab.
In fact, I know that the L0-norm of a vector x, ||x||_0, returns a value which designates the total number of nonzero elements in x. In other terms, ||x||_0 = #(i | xi !=0).
For example, for the L1-norm of x, it returns the sum of the absolute values of the elements in x. The matlab code to plot the L_1 norm penalty function is:
clear all;
clc;
x = [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5];
penal = zeros (length(x),1);
lambda = 2; % the tuning parameter
for ii = 1 : length(x)
penal(ii) = lambda*abs(x(ii));
end
figure
plot(x(:), penal(:), 'r');
But now what about the L_0 norm??
Any help will be very appreciated!

Replace the line inside the for loop with the following:
penal(ii) = lambda*(x(ii) ~= 0);
This assigns a penalty of lambda for all non-zero values in the vector x.

Related

Problems with Cubic Hermite polynomial in Matlab

I am having trouble with this code for a piecewise cubic Hermite polynomial. In my assignment we are not allowed to use pchip. We are supposed to write a function which takes as it's input arguments an integer n and a 3 by n matrix which contains the x values, the values of a function evaluated at each x, and the values of the derivative evaluated at each x; in the first, second and third rows of the matrix respectively.
With this information we are supposed to calculate the coefficients for each Hermite polynomial on each subinterval of the interval given by the first row of the input matrix, then piece it altogether using mkpp.
Unfortunately, my code produces a very poor interpolating polynomial and I am having trouble figuring out why. For example for the function x^2 we have for instance n = 4 and M = [0,1,2,3; 0,1,4,9; 0,1,4,6] and when plugged into my function produces the following graph
I would really appreciate help with this, it's driving me nuts.
Here is my code:
function [ HP ] = HermiteInter( n,M )
%HermiteInter
% This function constructs a peicewise cubic Hermite polynomial.
% The input areguments are an integer n and M a 3 by n matrix, whose
% first row contains the values of x which a given function will be
% evaluated at. The second row contains the values of a function
% evaluated at those
% points and the third row contains the value of the derivative of
% the function evaluated at those points.
% Divided differences using these values are found by calling the
% function HermiteDD. These divided differences are then passed into the
% function mkpp to create the peicewise polynomial.
X = M(1,:);
Y = M(2,:);
Z = M(3,:);
Q = zeros(n-1,4);
for i = 1 : n-1
Q(i,:) = HermiteDD([X(i),X(i),X(i+1),X(i+1)],[Y(i),Y(i+1)],[Z(i),Z(i+1)]);
end
HP = mkpp(X,Q);
end
function [ HDD ] = HermiteDD(X,Y,Z)
%HermiteDD
% This function creates a table of divided differences for
% Hermite polynomials. The input arguments are X, the values at
% which a function was evaluated at, Y the values of the function at
% these points and Z the values of the derivative of the function at
% these points.
DD = zeros(4, 4);
DD(1, 1) = Y(1);
DD(2, 1) = Y(1);
DD(3, 1) = Y(2);
DD(4, 1) = Y(2);
DD(1, 2) = Z(1);
DD(2, 2) = (Y(1)-Y(2))/(X(1)-X(3));
DD(3, 2) = Z(2);
for j = 3 : 4
for i = 1 : (4 - j+1)
DD(i,j) = (DD(i + 1, j - 1) - DD(i, j - 1)) / (X(i + j-1) - X(i));
end
end
HDD = DD(1,:);
end

Variable determines matrix dimension

Assume that I wish to define a matrix but the number of dimension of the matrix is a variable (v) in Matlab.
If v=1, then
M(1:10) = 0;
if v=2, then
M(1:10, 1:10) = 0;
...
I thought about how to use "reshape" to do this but I am scratching my head on how to do this exactly.
Any help would be appreciated.
For arbitrary v, you can use the vector-input form of zeros. Because of how this function works, the input v=1 needs special treatment if you want it to give a row vector (as seems to be the case from your code):
N = 10;
v = 3;
if v==1
sz = [1 N]; % or [N 1] for column vector
else
sz = repmat(N, 1, v);
end
M = zeros(sz);
Equivalently, if you prefer it in a single line:
M = zeros([repmat(1, 1, v==1) repmat(N, 1, v)]); % v=1 gives a row vector
or
M = zeros([repmat(N, 1, v) 1]); % v=1 gives a column vector
The latter works because Matlab arrays have an infinite number of trailing singleton dimensions.
you can do
switch v
case 1
M=zeros(1,10);%matrix of size 1,10
case 2
M=zeros(10,10);%matrix of size 10,10
end

Split matrix into SubMatrixes of Leading Coefficients

I am working with MATLAB_R2016a, and am currently trying to find the right matrix fraction description of a MIMO system. Suppose I have a matrix of the form:
[s^2+3s+1, s+1, s^3+2s; s^3+3, s^2-6, s-5];
Is there a simple way to generate submatrixes of coefficients for each degree of s? Like so:
[0, 0, 1; 1, 0, 0] s^3 + [0, 0, 0 ; 0, 1, 0] s^2 + [3, 1, 2; 0, 0, 1] s + [1,1,0;3,-6,-5];
I figure it can be done with a loop and extracting the degree of each polynomial element, but wanted to know if people had found easier work-arounds?
I suppose you use symbolic toolbox to work on polynomials. So, as #10a commented you can use coeffs function.
You just need to made some workaround to get final result.
For arbitrary polynomials you can use the next code:
syms x
% find all coefficients for each polynomial. Results are of different sizes!
% because of different degrees of polinomils
coef = arrayfun( #(y) coeffs(y, 'All') , [2*x^2 + 3*x + 5, x^2+3; x^3, x + 7] ,...
'UniformOutput' , false)
% find max degree
max_size = cellfun( #(x) size(x,2), coef)
max_size = max(max_size(:))
% and finally fill with zeros all surplus places in arrays to get unified size
result = cellfun( #(x) [zeros(1, max_size - size(x,2)) x], coef, 'UniformOutput', false)

How to plot this integral function in MATLAB?

Struggling to figure out how to plot this function in MATLAB.
Thanks, any help would be appreciated!
#Rotem 's approach is very good, yet I would love to add few words. Since you haven't mentioned anything about the domain, I suppose function can be defined also for negative numbers. In that case you can use the alternative as:
t = linspace(-10, 10);
func = arrayfun(#(t) integral(#(x) (10*x.*(343-(x).^3))/50421, 0, min(7,t)), t);
plot(t, func);
I have fixed the x axis between -10 and 10 with linspace, you can manually change that to get what you desire. But, note that function will get a fixed value when t is greater than 7, since integral has a bound such as min(t,7).
I really hope my answer is correct...
The integral of x is from 0 to t, when t goes from 0 to 7:
t = linspace(0, 7);
sigma = arrayfun(#(m) integral(#(x) 10*x.*(343 - x.^3)/50421, 0, m), t);
plot(t, sigma);
%Test using for loop:
% y = zeros(size(t));
%
% for i = 1:length(t);
% y(i) = integral(#(x) 10*x.*(343 - x.^3)/50421, 0, t(i));
% end
%
% figure;plot(t, y);

Matlab : Can Conditional plotting done in a loop be vectorized?

I am wanting to do conditional plotting of vertical lines, that change color based on the value of an integer vector. Those values are integers that range from 0-4.
Currently, I am using a loop to go through the tables to plot the lines. This works, but for LARGE amounts of data it takes time, and I'm wondering if it can be vectorized.
Attached is a stripped down version of the script to loop through a data vector(sample) that simply Loops through the vector, and plots a vertical line based on the value of the integer.
I will also attach the simple variable I created called 'SAMPLE' below to paste into your workspace.
for i=1:size(sample,1)
if sample(i)==1
line( [i i] ,[0 10], 'Marker','.','LineStyle','-','Color','r');
elseif sample(i)==2
line( [i i] ,[0 10], 'Marker','.','LineStyle','-','Color','b');
elseif sample(i)==3
line( [i i] ,[0 10], 'Marker','.','LineStyle','-','Color',[1 .5 0]);
elseif sample(i)==4
line( [i i] ,[0 10], 'Marker','.','LineStyle','-','Color','g');
end
end
Variable:
sample=[[3;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;4;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;2;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;3;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;4;0;0;0;0]];
But is is possible to 'vectorize' plotting in this way w/o having to do it iteratively in a loop as I have done?
Take advantage of the fact that when plotting a line, MATLAB will skip points whose value is NaN.
% Your vector
sample=[3;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;4;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;2;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;3;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;4;0;0;0;0];
% Your colors
colors = [
1 0 0
0 0 1
1 .5 0
0 1 0];
for idx = 1:4
% Find the index of each of your integers
X = find(sample == (idx));
% Force X to be a row vector
X = X(:)';
% Stack two X's on top of one another with a third row filled
% with NaNs. Fill in your Y values in the same way while
% you're at it.
Y = [zeros(size(X)); 10 + zeros(size(X)); nan(size(X))];
X = [X; X; nan(size(X))]; %#ok<AGROW>
% Matlab is column major. By using the colon here, you
% produce a vector that is [X1 X1 nan X2 X2 nan ... etc.]
X = X(:);
Y = Y(:);
% Draw the line
line(X, Y, 'Marker', '.', 'LineStyle', '-', 'Color', colors(idx, :))
end
There's still a loop, but now you're just looping over the possible values instead of looping over the each value in the vector. I think you will find that this will scale much better.
Changing input to:
sample = zeros(1, 1e6);
for idx = 1:4
sample(randi(1e6, 1, 1000)) = idx;
end
and benchmarking with timeit gives a time of 0.0065706 seconds on my machine, while the OP code benchmarks at 1.4861 seconds.
I'd change to something like:
colors=[1 0 0,
0 1 0,
1 0.5 0,
0 0 1];
nnsamples=samples(samples~=0);
for ii=1:size(nnsamples,1)
line( [ii ii] ,[0 10], 'Marker','.','LineStyle','-','Color',colors(nnsamples(ii),:));
end