how to remove array index out of bound error in matlab - matlab

here is my code where i have one error regarding array index out out of bound. plzz help me to rectify it
I = imread('E:\degraded images\village.jpg');
imshow(I)
I = im2double(I);
I = log(1 + I);
M = 2*size(I,1) + 1;
N = 2*size(I,2) + 1;
sigma = 10;
[X, Y] = meshgrid(1:N,1:M);
centerX = ceil(N/2);
centerY = ceil(M/2);
gaussianNumerator = (X - centerX).^2 + (Y - centerY).^2;
H = exp(-gaussianNumerator./(2*sigma.^2));
H = 1 - H;
imshow(H,'InitialMagnification',25)
H = fftshift(H);
If = fft2(I, M, N);
Iout = real(ifft2(H.*If)); ** here the code has error . ??? Error using ==> times Number of array dimensions must match for binary array op.**

H is 2-D while If is 3-D. You can use repmat with H or subset If. I don't know which one is correct for your situation. For instance,
rempat( H, [1, 1, 3 ] ) .* If;
or
H .* If(:,:,ind); % ind is the index of the 2-D array you want to subset

Related

Filling MATLAB array using formula and arrays of values

I want to fill a 10x15 matrix in MATLAB using the formula z(i, j) = 2 * x(i) + 3 * y(j)^2, so that each entry at (i, j) = z(i, j). I have arrays for x and y, which are of size 10 and 15, respectively.
I've accomplished the task using the code below, but I want to do it in one line, since I'm told it's possible. Any thoughts?
x = linspace(0,1,10);
y = linspace(-0.5,0.5,15);
z = zeros(10,15);
m_1 = 2;
m_2 = 3;
for i = 1:length(x)
for j = 1:length(y)
z(i, j) = m_1*x(i) + m_2*y(i)^2;
end
end
It looks like you have a bug in your original loop:
You are using i index twice: m_1*x(i) + m_2*y(i)^2.
The result is that all the columns of z matrix are the same.
For applying the formula z(i, j) = 2*x(i) + 3*y(j)^2 use the following loop:
x = linspace(0,1,10);
y = linspace(-0.5,0.5,15);
z = zeros(10,15);
m_1 = 2;
m_2 = 3;
for i = 1:length(x)
for j = 1:length(y)
z(i, j) = m_1*x(i) + m_2*y(j)^2;
end
end
For implementing the above loop using one line, we may use meshgrid first.
Replace the loop with:
[Y, X] = meshgrid(y, x);
Z = m_1*X + m_2*Y.^2;
For expansions, read the documentation of meshgrid, it is much better than any of the expansions I can write...
The following command gives the same output as your original loop (but it's probably irrelevant):
Z = repmat((m_1*x + m_2*y(1:length(x)).^2)', [1, length(y)]);
Testing:
max(max(abs(Z - z)))
ans =
0

Karhunen Loeve Procedure

I'm trying to apply the Karhunen Loeve procedure to a translation-invariant data set. I understand the KL procedure, and how to create a mask to smooth out missing data. However, I'm having a hard time creating a program to model my Translation invariant data set.
The data set that I need to plot in matlab is:
Translation-Invariant Data Set
And here's the matlab code that I tried to use to model it:
function [fmu] = kLProcedure(N, P, M)
for k = 1:N;
for m = 1:M;
for n = 1:P;
x(m) = ((m-1)*2.*(pi))/M;
t(n) = ((n - 1)*2.*(pi))/P;
k = 1:3;
fmu(x(m),t(n)) = (1/N).*symsum((1/k).*sin(k(x(m)-t(n))),k);
end
end
end
With N=3, P=64, M=64;
I'm trying to use a nested for-loop to calculate each iteration of m, n, and t. and keep getting the error:
Error using /
Matrix dimensions must agree.
Error in kLProcedure (line 28)
fmu(x(m),t(n)) = (1/N).*symsum((1/k).*sin(k(x(m)-t(n))),k);
And advice would be greatly appreciated. Thank you.
Honestly, I don't have an in-depth knowledge of the algorithms you are using, but looking at the formulation of the one you are trying to reproduce, I think the following code is what you are looking for:
fmu = kLProcedure(3,64,64);
plot(fmu);
function [fmu] = kLProcedure(N,M,P)
k = 1:N;
ki = 1 ./ k;
Ni = 1 / N;
m = 1:M;
x = ((m - 1) .* 2 .* pi()) ./ M;
n = 1:P;
t = ((n - 1) .* 2 .* pi()) ./ P;
fmu = zeros(M,P);
for i = m
for j = n
fmu(i,j) = Ni .* sum(ki .* sin(ki .* (x(i) - t(j))));
end
end
end
Output:
Translational-Invariant Data
function [fmu] = kLProcedure(N,M,P)
m = 1:M;
x = ((m - 1) .* 2 .* pi()) ./ M;
n = 1:P;
t = ((n - 1) .* 2 .* pi()) ./ P;
fmu = zeros(M,P);
for i = m
for j = n
fmu(i,j) = 0;
for k = 1:3
fmu(i,j) = fmu(i,j) + (1/3).*sum((1/k).*(sin((k) .* (x(i) - t(j)))));
end
end
end

Precompute weights for multidimensional linear interpolation

I have a non-uniform rectangular grid along D dimensions, a matrix of logical values V on the grid, and a matrix of query data points X. The number of grid points differs across dimensions.
I run the interpolation multiple times for the same grid G and query X, but for different values V.
The goal is to precompute the indexes and weights for the interpolation and to reuse them, because they are always the same.
Here is an example in 2 dimensions, in which I have to compute indexes and values every time within the loop, but I want to compute them only once before the loop. I keep the data types from my application (mostly single and logical gpuArrays).
% Define grid
G{1} = single([0; 1; 3; 5; 10]);
G{2} = single([15; 17; 18; 20]);
% Steps and edges are reduntant but help make interpolation a bit faster
S{1} = G{1}(2:end)-G{1}(1:end-1);
S{2} = G{2}(2:end)-G{2}(1:end-1);
gpuInf = 1e10;
% It's my workaround for a bug in GPU version of discretize in Matlab R2017a.
% It throws an error if edges contain Inf, realmin, or realmax. Seems fixed in R2017b prerelease.
E{1} = [-gpuInf; G{1}(2:end-1); gpuInf];
E{2} = [-gpuInf; G{2}(2:end-1); gpuInf];
% Generate query points
n = 50; X = gpuArray(single([rand(n,1)*14-2, 14+rand(n,1)*7]));
[G1, G2] = ndgrid(G{1},G{2});
for i = 1 : 4
% Generate values on grid
foo = #(x1,x2) (sin(x1+rand) + cos(x2*rand))>0;
V = gpuArray(foo(G1,G2));
% Interpolate
V_interp = interpV(X, V, G, E, S);
% Plot results
subplot(2,2,i);
contourf(G1, G2, V); hold on;
scatter(X(:,1), X(:,2),50,[ones(n,1), 1-V_interp, 1-V_interp],'filled', 'MarkerEdgeColor','black'); hold off;
end
function y = interpV(X, V, G, E, S)
y = min(1, max(0, interpV_helper(X, 1, 1, 0, [], V, G, E, S) ));
end
function y = interpV_helper(X, dim, weight, curr_y, index, V, G, E, S)
if dim == ndims(V)+1
M = [1,cumprod(size(V),2)];
idx = 1 + (index-1)*M(1:end-1)';
y = curr_y + weight .* single(V(idx));
else
x = X(:,dim); grid = G{dim}; edges = E{dim}; steps = S{dim};
iL = single(discretize(x, edges));
weightL = weight .* (grid(iL+1) - x) ./ steps(iL);
weightH = weight .* (x - grid(iL)) ./ steps(iL);
y = interpV_helper(X, dim+1, weightL, curr_y, [index, iL ], V, G, E, S) +...
interpV_helper(X, dim+1, weightH, curr_y, [index, iL+1], V, G, E, S);
end
end
I found a way to do this and posting it here because (as of now) two more people are interested. It takes only a slight modification to my original code (see below).
% Define grid
G{1} = single([0; 1; 3; 5; 10]);
G{2} = single([15; 17; 18; 20]);
% Steps and edges are reduntant but help make interpolation a bit faster
S{1} = G{1}(2:end)-G{1}(1:end-1);
S{2} = G{2}(2:end)-G{2}(1:end-1);
gpuInf = 1e10;
% It's my workaround for a bug in GPU version of discretize in Matlab R2017a.
% It throws an error if edges contain Inf, realmin, or realmax. Seems fixed in R2017b prerelease.
E{1} = [-gpuInf; G{1}(2:end-1); gpuInf];
E{2} = [-gpuInf; G{2}(2:end-1); gpuInf];
% Generate query points
n = 50; X = gpuArray(single([rand(n,1)*14-2, 14+rand(n,1)*7]));
[G1, G2] = ndgrid(G{1},G{2});
[W, I] = interpIW(X, G, E, S); % Precompute weights W and indexes I
for i = 1 : 4
% Generate values on grid
foo = #(x1,x2) (sin(x1+rand) + cos(x2*rand))>0;
V = gpuArray(foo(G1,G2));
% Interpolate
V_interp = sum(W .* single(V(I)), 2);
% Plot results
subplot(2,2,i);
contourf(G1, G2, V); hold on;
scatter(X(:,1), X(:,2), 50,[ones(n,1), 1-V_interp, 1-V_interp],'filled', 'MarkerEdgeColor','black'); hold off;
end
function [W, I] = interpIW(X, G, E, S)
global Weights Indexes
Weights=[]; Indexes=[];
interpIW_helper(X, 1, 1, [], G, E, S, []);
W = Weights; I = Indexes;
end
function [] = interpIW_helper(X, dim, weight, index, G, E, S, sizeV)
global Weights Indexes
if dim == size(X,2)+1
M = [1,cumprod(sizeV,2)];
Weights = [Weights, weight];
Indexes = [Indexes, 1 + (index-1)*M(1:end-1)'];
else
x = X(:,dim); grid = G{dim}; edges = E{dim}; steps = S{dim};
iL = single(discretize(x, edges));
weightL = weight .* (grid(iL+1) - x) ./ steps(iL);
weightH = weight .* (x - grid(iL)) ./ steps(iL);
interpIW_helper(X, dim+1, weightL, [index, iL ], G, E, S, [sizeV, size(grid,1)]);
interpIW_helper(X, dim+1, weightH, [index, iL+1], G, E, S, [sizeV, size(grid,1)]);
end
end
To do the task the whole process of interpolation ,except computing the interpolated values, should be done. Here is a solution translated from the Octave c++ source. Format of the input is the same as the frst signature of the interpn function except that there is no need to the v array. Also Xs should be vectors and should not be of the ndgrid format. Both the outputs W (weights) and I (positions) have the size (a ,b) that a is the number of neighbors of a points on the grid and b is the number of requested points to be interpolated.
function [W , I] = lininterpnw(varargin)
% [W I] = lininterpnw(X1,X2,...,Xn,Xq1,Xq2,...,Xqn)
n = numel(varargin)/2;
x = varargin(1:n);
y = varargin(n+1:end);
sz = cellfun(#numel,x);
scale = [1 cumprod(sz(1:end-1))];
Ni = numel(y{1});
index = zeros(n,Ni);
x_before = zeros(n,Ni);
x_after = zeros(n,Ni);
for ii = 1:n
jj = interp1(x{ii},1:sz(ii),y{ii},'previous');
index(ii,:) = jj-1;
x_before(ii,:) = x{ii}(jj);
x_after(ii,:) = x{ii}(jj+1);
end
coef(2:2:2*n,1:Ni) = (vertcat(y{:}) - x_before) ./ (x_after - x_before);
coef(1:2:end,:) = 1 - coef(2:2:2*n,:);
bit = permute(dec2bin(0:2^n-1)=='1', [2,3,1]);
%I = reshape(1+scale*bsxfun(#plus,index,bit), Ni, []).'; %Octave
I = reshape(1+sum(bsxfun(#times,scale(:),bsxfun(#plus,index,bit))), Ni, []).';
W = squeeze(prod(reshape(coef(bsxfun(#plus,(1:2:2*n).',bit),:).',Ni,n,[]),2)).';
end
Testing:
x={[1 3 8 9],[2 12 13 17 25]};
v = rand(4,5);
y={[1.5 1.6 1.3 3.5,8.1,8.3],[8.4,13.5,14.4,23,23.9,24.2]};
[W I]=lininterpnw(x{:},y{:});
sum(W.*v(I))
interpn(x{:},v,y{:})
Thanks to #SardarUsama for testing and his useful comments.

Translate an equation into a code

Can you help me please translate this equation into a code?
I tried this code but its only the first part
theSum = sum(M(:, y) .* S(:, y) ./ (1 + K(:, y)))
EDIT: sorry, I was having a brainfart. The answer below makes no assumptions on the nature of M, K, etc, which is why I recommended functions like that. But they're clearly matrices. I'll make another answer, I'll leave this here for reference though in case it's useful
I would start by making the M, K, X, L, and O expressions into simple functions, so that you can easily call them as M(z,y), X(z,y) (or X(z,j) depending on the input you need ) etc.
Then you will convert each summation into a for loop and collect the result (you can think about vectorisation later, right now focus on translating the problem). The double summation is essentially a nested for loop, where the result of the inner loop is used in the outer one at each outer iteration.
So your end result should look something like:
Summation1 = 0;
for z = 1 : Z
tmp = M(z,y) / K(z,y) * (X(z,y) / (1 + L(z,y));
Summation1 = Summation1 + tmp;
end
Summation2 = 0;
for j = 1 : Y
if j ~= y
for z = 1 : Z
tmp = (M(z,j) * X(z,j) * O(j)) / (K(z,j)^2 * (1 + L(z,j)) * X(z,y);
Summation2 = Summation2 + tmp;
end
end
end
Result = Summation1 - Summation2;
(Btw, this assumes that all operations are on scalars. If M(z,y) outputs a vector, adjust for elementwise operations appropriately)
IF M, K, etc are all matrices, and all operations are expected to be element-wise, then this is a vectorised approach for this equation.
Left summation is
S1 = M(1:Z,y) ./ K(1:Z,y) .* X(1:Z,y) ./ (1 + L(1:Z,y));
S1 = sum(S1);
Right summation is (assuming (O is a horizontal vector)
S2 = M(1:Z, 1:Y) .* X(1:X, 1:Y) .* repmat(O(1:Y), [Z,1]) ./ ...
(K(1:Z, 1:Y) .^ 2 .* (1 + L(1:Z, 1:Y))) .* X(1:Z, 1:Y);
S2(:,y) = []; % remove the 'y' column from the matrix
S2 = sum(S2(:)); % add all elements
End result: S1 - S2
this is lambda version vectorized:
equation = #(y,M,K,X,L,O) ...
sum(M(:,y)./K(:,y).*X(:,y)./(1+L(:,y))) ...
-sum(sum( ...
bsxfun( ...
#times ...
,M(:,[1:y-1,y+1:end]) ...
.* X(:,[1:y-1,y+1:end]) ...
.* O(:,[1:y-1,y+1:end]) ...
./ (K(:,[1:y-1,y+1:end]) .^ 2 ...
.*(1+ L(:,[1:y-1,y+1:end]))) ...
,X(:,y) ...
) ...
));
%%% example:
y = 3;
Y = 5;
Z = 10;
M = rand(Y, Z);K = rand(Y, Z);X = rand(Y, Z);L = rand(Y, Z);O = rand(Y, Z);
equation(y,M,K,X,L,O)

MATLAB sparse matrices: Gauss Seidel and power method using a sparse matrix with CSR (Compressed Sparse Row)

this is my first time here so I hope that someone can help me.
I'm trying to implementing the Gauss-Seidel method and the power method using a matrix with the storage CSR or called Morse storage. Unfortunately I can't manage to do better then the following codes:
GS-MORSE:
function [y] = gs_morse(aa, diag, col, row, nmax, tol)
[n, n] = size(A);
y = [1, 1, 1, 1];
m = 1;
while m < nmax,
for i = 1: n,
k1 = row(i);
k2 = row(i + 1) - 1;
for k = k1: k2,
y(i) = y(i) + aa(k) * x(col(k));
y(col(k)) = y(col(k)) + aa(k) * diag(i);
end
k2 = k2 + 1;
y(i) = y(i) + aa(k) * diag(i);
end
if (norm(y - x)) < tol
disp(y);
end
m = m + 1;
for i = 1: n,
x(i) = y(i);
end
end
POWER-MORSE:
I was able only to implement the power method but I don't understand how to use the former matrix... so my code for power method is:
function [y, l] = potencia_iterada(A, v)
numiter=100;
eps=1e-10;
x = v(:);
y = x/norm(x);
l = 0;
for k = 1: numiter,
x = A * y;
y = x / norm(x);
l0 = x.' * y;
if abs(l0) < eps
return
end
l = l0;
end
Please anyone can help me for completing these codes or can explain me how can I do that? I really don't understand how to do. Thank you very much