I have seen that there was an interest in custom interpolation kernels for resize (MATLAB imresize with a custom interpolation kernel). Did anyone implemented the parametric Mitchell-Netravali kernel [1] that is used as default in ImageMagick and is willing to share the Matlab code? Thank you very much!
[1] http://developer.download.nvidia.com/books/HTML/gpugems/gpugems_ch24.html
// Mitchell Netravali Reconstruction Filter
// B = 0 C = 0 - Hermite B-Spline interpolator
// B = 1, C = 0 - cubic B-spline
// B = 0, C = 1/2 - Catmull-Rom spline
// B = 1/3, C = 1/3 - recommended
float MitchellNetravali(float x, float B, float C)
{
float ax = fabs(x);
if (ax < 1) {
return ((12 - 9 * B - 6 * C) * ax * ax * ax +
(-18 + 12 * B + 6 * C) * ax * ax + (6 - 2 * B)) / 6;
} else if ((ax >= 1) && (ax < 2)) {
return ((-B - 6 * C) * ax * ax * ax +
(6 * B + 30 * C) * ax * ax + (-12 * B - 48 * C) *
ax + (8 * B + 24 * C)) / 6;
} else {
return 0;
}
}
Here I got another approach with vectorization; according to my tests with upscaling (1000x1000 -> 3000x3000) this is faster than the standard bicubic even with a large Mitchell radius = 6:
function [outputs] = Mitchell_vect(x,M_B,M_C)
outputs= zeros(size(x,1),size(x,2));
ax = abs(x);
temp = ((12-9*M_B-6*M_C) .* ax.^3 + (-18+12*M_B+6*M_C) .* ax.^2 + (6-2*M_B))./6;
temp2 = ((-M_B-6*M_C) .* ax.^3 + (6*M_B+30*M_C) .* ax.^2 + (-12*M_B-48*M_C) .* ax + (8*M_B + 24*M_C))./6;
index = find(ax<1);
outputs(index)=temp(index);
index = find(ax>=1 & ax<2);
outputs(index)=temp2(index);
end
I got the following proposal for the Mitchel kernel called by imresize with the parameters B and C and a kernel radius using for-loops (and preallocation):
img_resize = imresize(img, [h w], {#(x)Mitchell(x,B,C),radius});
function [outputs] = Mitchell(x,B,C)
outputs= zeros(size(x,1),size(x,2));
for i = 1 : size(x,1)
for j = 1 : size(x,2)
ax = abs(x(i,j));
if ax < 1
outputs(i,j) = ((12-9*B-6*C) * ax^3 + (-18+12*B+6*C) * ax^2 + (6-2*B))/6;
elseif (ax >= 1) && (ax < 2)
outputs(i,j) = ((-B-6*C) * ax^3 + (6*B+30*C) * ax^2 + (-12*B-48*C) * ax + (8*B + 24*C))/6;
else
outputs(i,j) = 0;
end
end
end
end
Related
T = 0.2;
A = [1 T; 0 1];
B = [T^2 / 2 T];
H = [1 0];
G = [0 1]';
Q = 0.00005;
R = 0.006;
x1(1) = 0;
x2(1) = 0;
x1e(1) = 0;
x2e(1) = 0;
xest = [x1e(1) x2e(1)]';
x1p(1) = 0;
x2p(1) = 0;
PE = [R 0; 0 0];
PP = A * PE(1) * A' + Q;
for i= 1:25
if i < 10
u = 0.25;
else
u = 0;
end
x1(i+1) = x1(i) + T * x2(i) + (T^2 / 2) * u;
x2(i+1) = x2(i) + T * u + sqrt(Q) * randn;
y(i+1) = x1(i+1) + sqrt(R) * randn;
PP = A * PE * A' + G * Q * G';
K = PP * H' * inv(H * PP * H' + R);
PE = [eye(2) - K * H] * PP;
xpredict = A * xest + B * u;
xest = xpredict + K * (y(i+1) -H * xpredict);
x1e(i+1) = [1 0] * xest;
x2e(i+1) = [0 1] * xest;
end
Unable to perform assignment because the left and right sides have a different number of elements.
Error in rrrr (line 34)
x1e(i+1) = [1 0] * xest;
how i can solve the error
xpredict must be a 2x1 vector. To solve it, you need to transpose B in line 5 i.e., B = [T^2 / 2 T]',
Since from Newton's laws of motion with constant velocity, we have
I have an equation which goes like this:
Here, I_L(lambdap) is the modified bessel function. This and product with exponential function can be written in matlab as besseli(L,lambdap,1). "i" stands for square root of -1. I want to solve:
1+pt+it=0
where I have to vary 'k' and find values of 'w'. I had posted similar problem at mathematica stack exchange, but I couldn't solve the problem fully, though i have got a clue (please go through the comments at mathematica stack exchange site). I could not convert my equation to the code that has been posted in clue. Any help in this regards will be highly appreciated.
Thanks in advance...
I never attempted this before, but... is this returning a suitable result?
syms w k;
fun = 1 + pt(w,k) + it(w,k);
sol = vpasolve(fun == 0,w,k);
disp(sol.w);
disp(sol.k);
function res = pt(w,k)
eps_l0 = w / (1.22 * k);
lam_k = 0.25 * k^2;
res = sym('res',[5 1]);
res_off = 1;
for L = -2:2
gam = besseli(L,lam_k) * exp(-lam_k);
eps_z = (w - L) / (1.22 * k);
zeta = 1i * sqrt(pi()) * exp(-eps_z^2) * (1 + erfc(1i * eps_z));
res(res_off,:) = ((25000 * gam) / k^2) * (1 + (eps_l0 * zeta));
res_off = res_off + 1;
end
res = sum(res);
end
function res = it(w,k)
eps_l0 = (w - (0.86 * k)) / (3.46 * k);
lam_k = 0.03 * k^2;
res = sym('res',[5 1]);
res_off = 1;
for L = -2:2
gam = besseli(L,lam_k) * exp(-lam_k);
eps_z = (w - (8 * L) - (0.86 * k)) / (3.46 * k);
zeta = 1i * sqrt(pi()) * exp(-eps_z^2) * (1 + erfc(1i * eps_z));
res(res_off,:) = ((2000000 * gam) / k^2) * (1 + (eps_l0 * zeta));
res_off = res_off + 1;
end
res = sum(res);
end
EDIT
For numeric k and symbolic w:
syms w;
for k = -3:3
fun = 1 + pt(w,k) + it(w,k);
sol = vpasolve(fun == 0,w);
disp(sol.w);
end
I am right now stuck on a problem in matlab. What I have done is that I have an equation that is passed on into another function which works by the bisection-method.
But I have a multiplier that I am trying to implement which somehow leads to the function crashing.
Before I introduced the multiplier it all worked, I tried breaking it down by entering the multiplier value manually and it didn't work
P_{1} = 0.6;
P_{2} = 0.2;
P_{3} = 0.2;
a_1 = 4/3;
a_2 = -7/3;
b_1 = -1/3;
b_2 = 4/3;
persistent multiplier
multiplier = exp(a_1 * 44 + a_2 * 14 + 0);
eqn = #(x) ((a_1 * x + b_1)^a_1) * ((a_2 * x + b_2)^a_2) * x ...
-(P_{1}^a_1) * (P_{2}^a_2) * P_{3} * multiplier;
Q_{3} = Bisectionmethod(a_1, a_2, b_1, b_2, eqn);
Here is the calculating part of the bisection method.
x_lower = max(0, -b_1 / a_1);
x_upper = -b_2 / a_2;
x_mid = (x_lower + x_upper)/2;
Conditional statement encompassing the method of bisection
while abs(eqn(x_mid)) > 10^(-10)
if (eqn(x_mid) * eqn(x_upper)) < 0
x_lower = x_mid;
else
x_upper = x_mid;
end
x_mid = (x_lower + x_upper)/2;
end
Based on the information you provided this is what I came up with
function Q = Stackoverflow
persistent multiplier
P{1} = 0.6;
P{2} = 0.2;
P{3} = 0.2;
a1 = 4/3;
a2 = -7/3;
b1 = -1/3;
b2 = 4/3;
multiplier = exp(a1 * 44 + a2 * 14 + 0);
eqn = #(x) ((a1 .* x + b1).^a1) .* ((a2 .* x + b2).^a2) .* x -(P{1}.^a1) .* (P{2}.^a2) .* P{3} .* multiplier;
Q{3} = Bisectionmethod(eqn, max([0, -b1/a1]), -b2/a2, 1E-10);
end
function XOut = Bisectionmethod(f, xL, xH, EPS)
if sign(f(xL)) == sign(f(xH))
XOut = [];
error('Cannot bisect interval because can''t ensure the function crosses 0.')
end
x = [xL, xH];
while abs(diff(x)) > EPS
x(sign(f(mean(x))) == sign(f(x))) = mean(x);
end
XOut = mean(x);
end
The Octave radix-4 FFT code below works fine if I set power of 4 (xp) values case-by-case.
$ octave fft4.m
ans = 1.4198e-015
However, if I uncomment the loop code I get the following error
$ octave fft4.m
error: `stage' undefined near line 48 column 68
error: evaluating argument list element number 1
error: evaluating argument list element number 2
error: called from:
error: r4fftN at line 48, column 22
error: c:\Users\david\Documents\Visual Studio 2010\Projects\mv_fft\fft4.m at line 80, column 7
the "error" refers to a line the in fft function code which otherwise works correctly when xp is not set by a loop ... very strange.
function Z = radix4bfly(x,segment,stageFlag,W)
% For the last stage of a radix-4 FFT all the ABCD multiplers are 1.
% Use the stageFlag variable to indicate the last stage
% stageFlag = 0 indicates last FFT stage, set to 1 otherwise
% Initialize variables and scale to 1/4
a=x(1)*.25;
b=x(2)*.25;
c=x(3)*.25;
d=x(4)*.25;
% Radix-4 Algorithm
A=a+b+c+d;
B=(a-b+c-d)*W(2*segment*stageFlag + 1);
C=(a-b*j-c+d*j)*W(segment*stageFlag + 1);
D=(a+b*j-c-d*j)*W(3*segment*stageFlag + 1);
% assemble output
Z = [A B C D];
end % radix4bfly()
% radix-4 DIF FFT, input signal must be floating point, real or complex
%
function S = r4fftN(s)
% Initialize variables and signals: length of input signal is a power of 4
N = length(s);
M = log2(N)/2;
% Initialize variables for floating point sim
W=exp(-j*2*pi*(0:N-1)/N);
S = complex(zeros(1,N));
sTemp = complex(zeros(1,N));
% FFT algorithm
% Calculate butterflies for first M-1 stages
sTemp = s;
for stage = 0:M-2
for n=1:N/4
S((1:4)+(n-1)*4) = radix4bfly(sTemp(n:N/4:end), floor((n-1)/(4^stage)) *(4^stage), 1, W);
end
sTemp = S;
end
% Calculate butterflies for last stage
for n=1:N/4
S((1:4)+(n-1)*4) = radix4bfly(sTemp(n:N/4:end), floor((n-1)/(4^stage)) * (4^
stage), 0, W);
end
sTemp = S;
% Rescale the final output
S = S*N;
end % r4fftN(s)
% test FFT code
%
xp = 2;
% ERROR if I uncomment loop!
%for xp=1:8
N = 4^xp; % must be power of: 4 16 64 256 1024 4086 ....
x = 2*pi/N * (0:N-1);
x = cos(x);
Y_ref = fft(x);
Y = r4fftN(x);
Y = digitrevorder(Y,4);
%Y = bitrevorder(Y,4);
abs(sum(Y_ref-Y)) % compare fft4 to built-in fft
%end
The problem was the loop-bound for the exponent xp should start from 2 as the fft4 code assumes at least 2 stages of radix-4 butterflies
Sorry folks :(
-David
Please find below a fully worked Matlab implementation of a radix-4 Decimation In Frequency FFT algorithm. I have also provided an overall operations count in terms of complex matrix multiplications and additions. It can be indeed shown that each radix-4 butterfly involves 3 complex multiplications and 8 complex additions. Since there are log_4(N) = log_2(N) / 2 stages and each stage involves N / 4 butterflies, so the operations count is
complex multiplications = (3 / 8) * N * log2(N)
complex additions = N * log2(N)
Here is the code:
% --- Radix-2 Decimation In Frequency - Iterative approach
clear all
close all
clc
% --- N should be a power of 4
N = 1024;
% x = randn(1, N);
x = zeros(1, N);
x(1 : 10) = 1;
xoriginal = x;
xhat = zeros(1, N);
numStages = log2(N) / 2;
W = exp(-1i * 2 * pi * (0 : N - 1) / N);
omegaa = exp(-1i * 2 * pi / N);
mulCount = 0;
sumCount = 0;
M = N / 4;
for p = 1 : numStages;
for index = 0 : (N / (4^(p - 1))) : (N - 1);
for n = 0 : M - 1;
a = x(n + index + 1) + x(n + index + M + 1) + x(n + index + 2 * M + 1) + x(n + index + 3 * M + 1);
b = (x(n + index + 1) - x(n + index + M + 1) + x(n + index + 2 * M + 1) - x(n + index + 3 * M + 1)) .* omegaa^(2 * (4^(p - 1) * n));
c = (x(n + index + 1) - 1i * x(n + index + M + 1) - x(n + index + 2 * M + 1) + 1i * x(n + index + 3 * M + 1)) .* omegaa^(1 * (4^(p - 1) * n));
d = (x(n + index + 1) + 1i * x(n + index + M + 1) - x(n + index + 2 * M + 1) - 1i * x(n + index + 3 * M + 1)) .* omegaa^(3 * (4^(p - 1) * n));
x(n + 1 + index) = a;
x(n + M + 1 + index) = b;
x(n + 2 * M + 1 + index) = c;
x(n + 3 * M + 1 + index) = d;
mulCount = mulCount + 3;
sumCount = sumCount + 8;
end;
end;
M = M / 4;
end
xhat = bitrevorder(x);
tic
xhatcheck = fft(xoriginal);
timeFFTW = toc;
rms = 100 * sqrt(sum(sum(abs(xhat - xhatcheck).^2)) / sum(sum(abs(xhat).^2)));
fprintf('Theoretical multiplications count \t = %i; \t Actual multiplications count \t = %i\n', ...
(3 / 8) * N * log2(N), mulCount);
fprintf('Theoretical additions count \t\t = %i; \t Actual additions count \t\t = %i\n\n', ...
N * log2(N), sumCount);
fprintf('Root mean square with FFTW implementation = %.10e\n', rms);
I am stuck at vectorizing this tricky loop in MATLAB/Octave:
[nr, nc] = size(R);
P = rand(nr, K);
Q = rand(K, nc);
for i = 1:nr
for j = 1:nc
if R(i,j) > 0
eij = R(i,j) - P(i,:)*Q(:,j);
for k = 1:K
P(i,k) = P(i,k) + alpha * (2 * eij * Q(k,j) - beta * P(i,k));
Q(k,j) = Q(k,j) + alpha * (2 * eij * P(i,k) - beta * Q(k,j));
end
end
end
end
The code tries to factorize R into P and Q, and approaching the nearest P and Q with an update rule. For example, let R = [3 4 0 1 1; 0 1 0 4 4; 5 4 3 1 0; 0 0 5 4 3; 5 3 0 2 1], K=2, alpha=0.01 and beta=0.015. In my real case, I will use a huge sparse matrix R (that's why I need vectorization), and K remain small (less than 10). The goal of the whole script is producing a prediction value for every 0 elements in R, based on the non zero elements. I got this code from here, originally written in Python.
This looks like one of those cases that not all code can be vectorized. Still, you can make it a bit better than it is now.
[nr, nc] = size(R);
P = rand(nr, K);
Q = rand(K, nc);
for i = 1:nr
for j = 1:nc
if R(i,j) > 0
eij = R(i,j) - P(i,:)*Q(:,j);
P(i,:) = P(i,:) + alpha * (2 * eij * Q(:,j)' - beta * P(i,:));
Q(:,j) = Q(:,j) + alpha * (2 * eij * P(i,:)' - beta * Q(:,j));
end
end
end
Since the operations on P and Q are serial in nature (iterative updates) I do not think you can do much better. You can save the if in the loop:
[nr, nc] - size(R);
P = rand(nr, K);
Q = rand(K, nc);
[nzi nzj] = find( R > 0 );
for ii=1:numel(nzi)
i = nzi(ii);
j = nzj(ii);
eij = R(i,j) - P(i,:)*Q(:,j);
P(i,:) = P(i,:) + alpha * (2 * eij * Q(:,j)' - beta * P(i,:));
Q(:,j) = Q(:,j) + alpha * (2 * eij * P(i,:)' - beta * Q(:,j));
end