I'm trying to implement a matrix called Gamma in Matlab. It will include smaller matrices called H as seen in the figure below
I am having a trouble implementing this in Matlab.
What I have done is as follows:
I created a function called
function [Gamma] = get_Gamma(N,A,B,Cz)
then I create the H matrices
for i=1:N
H(:,:,i) = Cz*Ad^(i-1)*Bd;
end
Hn = size(H,1);
Hm = size(H,2);
and my problem is how I can do iterations as this:
Gamma = [H(:,:,1) zeros(2,2) zeros(2,2)]
Gamma = [Gamma ; H(:,:,2) H(:,:,1) zeros(2,2)]
Gamma = [Gamma ; H(:,:,3) H(:,:,2) H(:,:,1)]
I have been trying to do something like this
Gamma = [];
counter = 1;
for i=1:N
for j=1:N
if i <= counter
Gamma_update = H(:,:,j);
Gamma = [Gamma Gamma_update];
else
Gamma_update = zeros(Hn,Hm);
Gamma = [Gamma Gamma_update];
end
Gamma = [Gamma ; H(:,:,2) H(:,:,1) zeros(2,2)]
end
end
but I know this is not going to work. I hope you can help me out with this please!
I just managed to find a solution to my problem and it is as follows:
function [Gamma] = get_Gamma(N,Ad,Bd,Czd)
% N: number of impulse response matrices to find Markov Parameters
for i=1:N
H(:,:,i) = Czd*Ad^(i-1)*Bd;
end
Hn = size(H,1);
Hm = size(H,2);
Gamma = [];
counter = 1;
for i=1:N
Gamma_update = [];
for k=N:-1:counter+1
Gamma_update = [zeros(Hn,Hm) Gamma_update];
end
for j=1:counter
Gamma_update = [H(:,:,j) Gamma_update];
end
Gamma = [Gamma ; Gamma_update];
counter = counter + 1;
end
end
Related
I am programming a simple perceptron in matlab but it is not converging and I can't figure out why.
The goal is to binary classify 2D points.
%P1 Generate a dataset of two-dimensional points, and choose a random line in
%the plane as your target function f, where one side of the line maps to +1 and
%the other side to -1. Let the inputs xn 2 R2 be random points in the plane,
%and evaluate the target function f on each xn to get the corresponding output
%yn = f(xn).
clear all;
clc
clear
n = 20;
inputSize = 2; %number of inputs
dataset = generateRandom2DPointsDataset(n)';
[f , m , b] = targetFunction();
signs = classify(dataset,m,b);
weights=ones(1,2)*0.1;
threshold = 0;
fprintf('weights before:%d,%d\n',weights);
mistakes = 1;
numIterations = 0;
figure;
plotpv(dataset',(signs+1)/2);%mapping signs from -1:1 to 0:1 in order to use plotpv
hold on;
line(f(1,:),f(2,:));
pause(1)
while true
mistakes = 0;
for i = 1:n
if dataset(i,:)*weights' > threshold
result = 1;
else
result = -1;
end
error = signs(i) - result;
if error ~= 0
mistakes = mistakes + 1;
for j = 1:inputSize
weights(j) = weights(j) + error*dataset(i,j);
end
end
numIterations = numIterations + 1
end
if mistakes == 0
break
end
end
fprintf('weights after:%d,%d\n',weights);
random points and signs are fine since plotpv is working well
The code is based on that http://es.mathworks.com/matlabcentral/fileexchange/32949-a-perceptron-learns-to-perform-a-binary-nand-function?focused=5200056&tab=function.
When I pause the infinite loop, this is the status of my vairables:
I am not able to see why it is not converging.
Additional code( it is fine, just to avoid answers asking for that )
function [f,m,b] = targetFunction()
f = rand(2,2);
f(1,1) = 0;
f(1,2) = 1;
m = (f(2,2) - f(2,1));
b = f(2,1);
end
function dataset = generateRandom2DPointsDataset(n)
dataset = rand(2,n);
end
function values = classify(dataset,m,b)
for i=1:size(dataset,1)
y = m*dataset(i,1) + b;
if dataset(i,2) >= y, values(i) = 1;
else values(i) = -1;
end
end
end
I am trying to compute the following formula:enter image description here
Basically, I am provided with 2 vectors which contain the values of both cj (constellation elements) and p (probability of said constellation elements). With this information, the computation of the channel capacity should be straight forward employing my code:
clear all;
close all;
load('parametros.mat');
%Code
figure();
plot(elements_constellation,prob);
%Energy/2D of the code
Ec = (1/length(elements_constellation))*sum(elements_constellation.^2);
Es = 2*Ec;
%Define variance values here:
sigma = 0.1;
Q_y_cj = zeros(1,length(elements_constellation));
P_Y = zeros(1,length(elements_constellation));
Q_y_cjprime = zeros(1,length(elements_constellation));
resultsintegral = zeros(1,length(elements_constellation));
cap = 0;
P_Y = 0;
figure();
x=1;
for y = 1:length(elements_constellation)
for ii=-11:11
Q_y_cj(x) = ((1/(sqrt(2*pi)*sigma)))*exp(-((ii-elements_constellation(y)).^2));
x = x+1;
end
x=1;
hold on
plot(elements_constellation,Q_y_cj)
end
x=1;
figure();
for y = 1:length(elements_constellation)
for ii=-11:11
P_Y(x) = prob(y).*((1/(sqrt(2*pi)*sigma)))*exp(-((ii-elements_constellation(y)).^2));
x = x+1;
end
x=1;
hold on
plot(elements_constellation,P_Y)
end
figure();
Q_y_cj_1 = zeros(1,length(elements_constellation));
P_Y = 0;
for y = 1:length(elements_constellation)
x=1;
for ii=-11:11
Q_y_cj_1(x) = ((1/(sqrt(2*pi)*sigma)))*exp(-((ii-elements_constellation(y)).^2));
for s=1:length(elements_constellation)
P_Y = P_Y + prob(s).*((1/(sqrt(2*pi)*sigma)))*exp(-((ii-elements_constellation(s)).^2));
end
Q_y_cjprime(x) = Q_y_cj_1(x)*log10(Q_y_cj_1(x)/P_Y); %% These values are being overwritten
x = x+1;
P_Y = 0;
end
hold on;
plot(elements_constellation,Q_y_cjprime);
resultsintegral(y) = trapz(Q_y_cjprime);
end
figure();
plot(elements_constellation,resultsintegral);
for j=1:length(prob)
cap = cap + prob(j)*resultsintegral(j);
end
However, I am not convinced by the results my code generates for the channel capacity. For low values of sigma (noise variance), the capacity should increase logarithmically, but it grows exponentially when executing my algorithm.
Any help or advice on how to improve the computation of this formula would be greatly appreciated.
I am solving Burger equation with Newton-Raphson method in Mathlab.
For the description of the problem see 1.
My problem is the following this code finds the solution upto time
$t=1$, but at this time a discontinuity develops and then the wave
moves forward (like a step function), but this code does not produce
correct solutions after time $t=1$.
Any suggestions or comments to improve the code.
Here is the Matlab code that I am using
function BurgerFSolve2
clc; clear;
% define a 1D mesh
a = -1; b = 3; Nx = 100;
x = linspace(a,b,Nx);
dx = (b-a)/Nx;
J = length(x);
% Iinitial condition
p_init = zeros(size(x));
p_init(x<=0) = 1;
p_init(x>0 & x<1)= 1-x(x>0 & x<1);
% storing results
P = zeros(length(p_init),3001);
P(:,1) = p_init;
% Boundary condition
pL = 1; pR = 0;
% solver
dt = 0.001;
t = 0;
T = zeros(1,3001);
c = dt/dx;
for i = 1:3000
t = t+dt;
T(i+1) = t;
options=optimset('Display','iter'); % Option to display output
p = fsolve(#(p) myfun1(p, pL, pR, c, J, P(:,i)), p_init, ...
options);
% Call solver
P(:,i+1) = p;
p_init = p;
figure(1);
plot(x, p, '-o');
title(['t= ' num2str(t) ' s']);
drawnow;
end
end
function F = myfun1(p, pL, pR, c, J, p_Old)
% Rewrite the equation in the form F(x) = 0
F(1) = p(1) + c*(p(1)^2 - p(1)*pL) - p_Old(1);
for i=2:J-1
F(i) = p(i) + c*(p(i)^2 - p(i-1)*p(i)) - p_Old(i);
end
F(J) = p(J) + c*(p(J)^2 - p(J-1)*p(J)) - p_Old(J);
end
I'm trying to implement the Prewitt Filter in Matlab. I know that Matlab has already this kind of filter but I need to code it myself. Below is my code, the only problem is that at the end of the filtering I get a bright image instead of seeing the edges.
I'm implementing the filter using the separability property of the Prewitt Filter. Any ideas? I will appreciate very much your help.
%% 3x3 Prewitt Filter
close all
imageIn = imread('images/Bikesgray.jpg');
imageGx = zeros(size(imageIn));
imageGy = zeros(size(imageIn));
imageOut = zeros(size(imageIn));
ny = size(imageIn, 1);
nx = size(imageIn, 2);
average = 3;
imshow(imageIn);
u = [];
v = [];
tic
%Compute Gx
%For every row use the mask (-1 0 1)
for i = 1:ny
u = imageIn(i,:);
v = zeros(1, nx);
for k = 2:nx-1
v(k) = (uint32(-1*u(k-1))+uint32(0*u(k))+uint32(u(k+1)));
end
v(1) = (uint32(-1*u(2))+uint32(0*u(1))+uint32(u(2)));
v(nx) = (uint32(-1*u(nx-1))+uint32(0*u(nx))+uint32(u(nx-1)));
imageGx(i,:) = v;
end
%For every column use the mask (1 1 1)
for j = 1:nx
u = imageGx(:,j);
v = zeros(ny, 1);
for k = 2:ny-1
v(k) = (uint32(u(k-1))+uint32(u(k))+uint32(u(k+1)));
end
v(1) = (uint32(u(2))+uint32(u(1))+uint32(u(2)));
v(ny) = (uint32(u(ny-1))+uint32(u(ny))+uint32(u(ny-1)));
imageGx(:,j) = v;
end
%Compute Gy
%For every row use the mask (1 1 1)
for i = 1:ny
u = imageIn(i,:);
v = zeros(1, nx);
for k = 2:nx-1
v(k) = (uint32(u(k-1))+uint32(u(k))+uint32(u(k+1)));
end
v(1) = (uint32(u(2))+uint32(u(1))+uint32(u(2)));
v(nx) = (uint32(u(nx-1))+uint32(u(nx))+uint32(u(nx-1)));
imageGy(i,:) = v;
end
%For every column use the mask (1 0 -1)
for j = 1:nx
u = imageGy(:,j);
v = zeros(ny, 1);
for k = 2:ny-1
v(k) = (uint32(u(k-1))+uint32(0*u(k))+uint32(-1*u(k+1)));
end
v(1) = (uint32(u(2))+uint32(0*u(1))+uint32(-1*u(2)));
v(ny) = (uint32(u(ny-1))+uint32(0*u(ny))+uint32(-1*u(ny-1)));
imageGy(:,j) = v;
end
toc
figure
imshow(imageGx, [0 255]);
figure
imshow(imageGy, [0 255]);
%Compute the magnitude G = sqrt(Gx^2 + Gy^2);
imageOut(:,:) = sqrt(imageGx(:,:).^2 + imageGy(:,:).^2);
figure
imshow(imageOut, [0 255]);
It's too bad you didn't use convn (convolution), since the weighted sum just screams it.
In a nutshell you produce Gx,Gy by using convn on the image matrix, using the appropriate kernels, as described in wikipedia
The solution was really obvious but took me some time to figure it out.
All I did is change the uint32 to int32 and be sure to perform the operations (e.g. multiplying by -1) after changing the values from uint32 to int32.
I am trying to implement local thresholding in MATLAB 7.7. This is what my original image looks like:
As seen the the word Test is covered in black. This image is a PNG image having dimensions 919x551. I want to apply local thresholding to this image so that I can get the word Test to be visible clearly.
I have implemented the following code that works by dividing the entire image into sub images of 60*60 blocks.
However, when I am doing so, I am not getting the desired output.
My code:
clc;
clear all;
close all;
im = imread('C:\samples\test100.png');
subplot(3,3,1);
imshow(im);
title('original image');
im = rgb2gray(im);
im = double(im);
subplot(3,3,2);
imshow(im);
title('gray scale image');
[row col] = size(im);
max_im = max(max(im));
h = zeros(1,max_im+1);
!1st block
for n = 1:1:60
for m = 1:1:60
a(n,m) = im(n,m);
end
end
a = a+1;
for n = 1:1:60
for m = 1:1:60
t = a(n,m);
h(t) = h(t)+1;
end
end
subplot(3,3,3);
bar(h)
[X,Y] = ginput(1);
for n = 1:1:60
for m = 1:1:60
if a(n,m)<X
a(n,m) = 0;
else
a(n,m) = 255;
end
end
end
subplot(3,3,4);
imshow(uint8(a))
title('1st block image');
!2nd block
for n = 1:1:60
for m = 61:1:60
b(n,m-60) = im(n,m)
end
end
b = b+1;
for n = 1:1:60
for m = 1:1:60
t = b(n,m);
h(t) = h(t)+1;
end
end
figure(2)
bar(h)
[X,Y] = ginput(1);
for n = 1:1:60
if b(n,m)<X
b(n,m) = 0;
else
b(n,m) = 255;
end
end
imshow(uint8(b))
!3rd block
for n = 61:1:120
for m = 1:1:60
c(n-60,m) = im(n,m);
end
end
c = c+1;
for n = 1:1:60
for m = 1:1:60
t = c(n,m);
h(t) = h(t)+1;
end
end
figure(3)
bar(h)
[X,Y] = ginput(1);
for n = 1:1:60
for m = 1:1:60
if c(n,m)< X
c(n,m) = 0;
else
c(n,m) = 255;
end
end
end
imshow(uint8(c))
!final block
for n = 1:1:row
for m = 61:1:col
d(n-60,m-60) = im(n,m);
end
end
d = d+1;
for n = 1:1:60
for m = 1:1:60
t = d(n,m);
h(t) = h(t)+1;
end
end
figure(4);
bar(h);
[X,Y] = ginput(1);
for n = 1:1:60
for m = 1:1:60
if d(n,m)<X
d(n,m) = 0;
else
d(n,m) = 255;
end
end
end
imshow(uint8(d))
s = [a b;c d];
figure(5);
imshow(uint(s))
When I try to run the entire code I get an error as:
??? Undefined function or method 'local' for input arguments of type 'char'
However, when I run only the code for the 1st block I get the following output.
How will I get the word Test visible by creating sub-images and then merging them together?
You can scan the greyscale image horizontally and then find the position of non-zero (or above the threshold) values and set that interval to be filled with white (256 or 1 if using im2double).
for j=1:551
row = im(:,j)
test = 0;
im2=zeros(size(im))
i=0;
%Left black area
while (test == 0 && i<919)
im2(i,j)=0;
if row(i)>threshold
test=1;
end;
i=i+1;
end;
%White inner area
while (test == 1 && i<919)
im2(i,j)=1
if row(i)>threshold
test=0;
end;
i=i+1;
end;
%Left black area
while (i<919)
im2(i,j)=0;
i=i+1;
end;
This doesn't work with letters that have an empty area (such as 'p'), but you can modify the code a little to do that.