Polynomial Evaluation - matlab

I read a Matlab tutorial script and I'm not sure how the function polyvalm works.
The polynomial is as follow: p(X)=X^3 -2*X -5I (where I is the identity matrix)
polynomial coefficients of p(X)is [1 0 -2 -5]
X = [2 4 5; -1 0 3; 7 1 5];
Y = polyvalm(p,X)
My interpretation is X.^3 - 2*X -5*eye(3) but my result is totally different.
Sorry for the ugly typesetting but stack overflow doesn't offer Latex so can't help it

You are using element wise cube (X.^3) which is of course different from actually cubing a matrix. So for your p the polynomial is actually X^3 - 2*X - 5*eye(size(X)):
p = [1 0 -2 -5];
X = [2 4 5; -1 0 3; 7 1 5];
% anonymous function to illustrate
f = #(X,p) p(1)*X^3 + p(2)*X^2 + p(3)*X + p(4)*eye(size(X));
y_polyvalm = polyvalm(p,X)
y_fun = f(X,p)
This results in
y_polyvalm =
377 179 439
111 81 136
490 253 639
y_fun =
377 179 439
111 81 136
490 253 639

Related

Image compression using orthogonal polynomial Transformation [duplicate]

I am working on Image compression based on orthogonal polynomial transformation. My input image is gray scale image of size 256*256. i divide this image into 4 by 4 blocks. and than apply the orthogonal polynomial operator on each block. but I am not getting correct coefficient.
Example:
If I have a block 4x4 of Input image:
I=[5 11 8 10;9 8 4 12; 1 10 11 4;19 6 15 7];
and my polynomial operator for n=4 is:
[M] = [p0 p1 p2 p3]=[1 -3 1 -3;1 -1 -1 9;1 1 -1 -9;1 3 1 3]
After finding the outer product:
[20 -24 24 -16; -24 84 -80 24;24 -80 84 -24;-16 24 -24 20]
when I applied this on input image blocks, my answer is:
[-396 172 88 -104; 1012 -248 -376 616 -972 320 436 -552; 492 -104 4 172]
which is wrong. It should be
[140 0 -6 -10; 32 -112 2 -174; 22 -30 8 -40;34 -54 84 -8]
what I have done wrong?
My MATLAB code to find orthogonal polynomial operator is given below.
clc
clear all
close all
ID=imread('cameraman.tif'); % input image
I=double(ID);
imshow(ID);
[r,c]=size(I);
y1=zeros(r,c);
x=1:4;
n=4;
mu=(n+1)/2;
p0=[1 1 1 1];
p1=x-mu;
p2=(x-mu).^2-(n.^2-1)/12;
p3=(x-mu).^3-((x-mu)*(3*n.^2-7))/20;
P=[p0;p1; p2; p3];
N=[1 1 1 1;-1.5 -0.5 0.5 1.5;1 -1 -1 1;-0.3 0.9 -0.9 0.3];
M=[1 1 1 1;-3 -1 1 3;1 -1 -1 1;-3 9 -9 3]; % after sacling
v=M';
O=M.*v;
T=O'; % Orthogonal polynomial operator
for i=1:4:r
for j=1:4:c
y1(i:i+3,j:j+3)=I(i:i+3,j:j+3).*(double(T));
end
end
figure,imshow(uint8(y1))
y1

How to apply orthogonal polynomial transformation on an image for image compression?

I am working on Image compression based on orthogonal polynomial transformation. My input image is gray scale image of size 256*256. i divide this image into 4 by 4 blocks. and than apply the orthogonal polynomial operator on each block. but I am not getting correct coefficient.
Example:
If I have a block 4x4 of Input image:
I=[5 11 8 10;9 8 4 12; 1 10 11 4;19 6 15 7];
and my polynomial operator for n=4 is:
[M] = [p0 p1 p2 p3]=[1 -3 1 -3;1 -1 -1 9;1 1 -1 -9;1 3 1 3]
After finding the outer product:
[20 -24 24 -16; -24 84 -80 24;24 -80 84 -24;-16 24 -24 20]
when I applied this on input image blocks, my answer is:
[-396 172 88 -104; 1012 -248 -376 616 -972 320 436 -552; 492 -104 4 172]
which is wrong. It should be
[140 0 -6 -10; 32 -112 2 -174; 22 -30 8 -40;34 -54 84 -8]
what I have done wrong?
My MATLAB code to find orthogonal polynomial operator is given below.
clc
clear all
close all
ID=imread('cameraman.tif'); % input image
I=double(ID);
imshow(ID);
[r,c]=size(I);
y1=zeros(r,c);
x=1:4;
n=4;
mu=(n+1)/2;
p0=[1 1 1 1];
p1=x-mu;
p2=(x-mu).^2-(n.^2-1)/12;
p3=(x-mu).^3-((x-mu)*(3*n.^2-7))/20;
P=[p0;p1; p2; p3];
N=[1 1 1 1;-1.5 -0.5 0.5 1.5;1 -1 -1 1;-0.3 0.9 -0.9 0.3];
M=[1 1 1 1;-3 -1 1 3;1 -1 -1 1;-3 9 -9 3]; % after sacling
v=M';
O=M.*v;
T=O'; % Orthogonal polynomial operator
for i=1:4:r
for j=1:4:c
y1(i:i+3,j:j+3)=I(i:i+3,j:j+3).*(double(T));
end
end
figure,imshow(uint8(y1))
y1

Matlab: Remove diagonal from matrix and reform

I would like to remove the diagonal of the following matrix;
[0 1 1
0 0 0
0 1 0]
and put this in a vector as such
[1 1 0 0 0 1]
Is there a one-way function to do this?
Most other solutions I found on Stack Overflow delete all zeros.
If two lines are fine...
x = x.'; %'// transpose because you want to work along 2nd dimension first
result = x(~eye(size(x))).'; %'// index with logical mask to remove diagonal
Here's an almost one-liner -
[m,n] = size(x);
x(setdiff(reshape(reshape(1:numel(x),m,n).',1,[]),1:m+1:numel(x),'stable'))
And I will put up my fav bsxfun here -
xt = x.'; %//'
[m,n] = size(x);
out = xt(bsxfun(#ne,(1:n)',1:m)).'
Sample run -
>> x
x =
52 62 37 88
23 68 98 91
49 40 4 79
>> [m,n] = size(x);
>> x(setdiff(reshape(reshape(1:numel(x),m,n).',1,[]),1:m+1:numel(x),'stable'))
ans =
62 37 88 23 98 91 49 40 79
>> xt = x.';
>> xt(bsxfun(#ne,(1:n)',1:m)).'
ans =
62 37 88 23 98 91 49 40 79

How to classify a matrix within a Matlab parfor loop?

I am looking to classify the values of a matrix. The following example works outside of a parfor loop, however it does not work when used within a parfor loop. What are my options to classify matrices, following the provided example, within a parfor loop?
% Sample data
Imag1 = [ 62 41 169 118 210;
133 158 96 149 110;
211 200 84 194 29;
209 16 15 146 28;
95 144 13 249 170];
% Perform the classification
Imag1(find(Imag1 <= 130)) = 4;
Imag1(find(Imag1 >= 150)) = 1;
Imag1(find(Imag1 > 140)) = 2;
Imag1(find(Imag1 > 130)) = 3;
Results in the following (outside parfor loop):
Imag1 =
62 41 169 118 210
133 158 96 149 110
211 200 84 194 29
209 16 15 146 28
95 144 13 249 170
Imag1 =
4 4 1 4 1
3 1 4 2 4
1 1 4 1 4
1 4 4 2 4
4 2 4 1 1
You can use another matrix to store the result.
Imag2 = zeros(size(Imag1));
% Perform the classification
Imag2(find(Imag1 <= 130)) = 4;
Imag2(find(Imag1 >= 150)) = 1;
Imag2(find(Imag1 > 140)) = 2;
Imag2(find(Imag1 > 130)) = 3;
so you can use a parfor loop somehow. Since parfor doesn't care about order of execution. Your code doesn't work in a parfor loop because right now you are modifying the values of Imag1, then comparing those values again, aka any loop iteration would be be dependent on the prior loop iterations
Here's another approach:
parfor c = 1:size(Imag1,2)
Imag2(:,c) = 4-min(ceil(max((Imag1(:,c) - 130),0)/10),3);
end
Now you can split it up however you like; by rows, by columns, by blocks, by alternate columns...
Edit:
Unfortunately this classifies a value of 150 as 2. So you probably shouldn't use this one.
Take 3
class = [150 141 131 0]; %// minimum values for class 1, 2, 3, 4
[m, n] = size(Imag1);
parfor c=1:n
for r=1:m
Imag3(r,c) = find(Imag1(r,c) >= class, 1);
end
end

MATLAB vectorize

I was wondering if anyone could help me vectorize this piece of code.
fr_bw is a matrix.
for i=1:height
for j=1:width
[min_w, min_w_index] = min(w(i,j,:));
mean(i,j,min_w_index) = double(fr_bw(i,j));
sd(i,j,min_w_index) = sd_init;
end
end
I can't help you with this sif (match == 0) stuff -- if it's supposed to be if (match == 0) you're not changing match so it could be brought outside the loop.
Otherwise, how about this:
[min_w, min_w_index] = min(w, [], 3);
r = repmat((1:height)',1,width);
c = repmat(1:width,height,1);
ind = sub2ind(size(w),r(:),c(:),min_w_index(:));
w_mean(ind) = double(fr_bw);
w_sd(ind) = repmat(sd_init,height,width);
(Please note that mean is a built-in function so I renamed your variables to w_mean and w_sd.)
The sub2ind call gives you linear indices that correspond to subscripts. (Direct subscripts won't work; z([a1 a2 a3],[b1 b2 b3],[c1 c2 c3]) refers to 27 elements in the z array with subscripts that are the cartesian product of the specified subscripts, rather than z(a1,b1,c1) and z(a2,b2,c2) and z(a3,b3,c3) that you might expect.)
Here's an illustration of this technique:
>> height = 6; width = 4;
>> w = randi(1000,height,width,2)
w(:,:,1) =
426 599 69 719
313 471 320 969
162 696 531 532
179 700 655 326
423 639 408 106
95 34 820 611
w(:,:,2) =
779 441 638 696
424 528 958 68
91 458 241 255
267 876 677 225
154 519 290 668
282 944 672 845
>> [min_w, min_w_index] = min(w, [], 3);
>> min_w_index
min_w_index =
1 2 1 2
1 1 1 2
2 2 2 2
1 1 1 2
2 2 2 1
1 1 2 1
>> z = zeros(height,width,2);
>> r = repmat((1:height)',1,width);
>> c = repmat(1:width,height,1);
>> ind = sub2ind(size(w),r(:),c(:),min_w_index(:));
>> z(ind) = 1
z(:,:,1) =
1 0 1 0
1 1 1 0
0 0 0 0
1 1 1 0
0 0 0 1
1 1 0 1
z(:,:,2) =
0 1 0 1
0 0 0 1
1 1 1 1
0 0 0 1
1 1 1 0
0 0 1 0
A few comments on your code:
Did you mean if rather than sif?
The code isn't replicable at the moment, since you haven't provided examples of the variables w, fr_bw and sd_init. This makes it tricky to give an exact answer.
It looks like you are assigning things to a variable named mean. This will shadow the mean function, and probably cause you grief.
I'm just guessing, but I don't think double does what you think it does. You don't need to convert individual elements of a numeric matrix to type double; they are already the correct type. (On the other hand, if fr_bw is a different type, say integers, then you should create a new variable dbl_fr_bw = double(fr_bw); before the loops.
You might need to adjust the dimension over which you calculate the minimums, but the first line of the loop can be replaced with
[min_w, min_w_index] = min(w, [], 3)
The second line with
mean_values(:, :, min_w_index) = double(fr_bw)
Not sure about the third line, since I don't know what sd_init is/does.