I am working on B-spline, this code is to get a matrix as an output.
function [M] = Iterations(N) % N is an input variable
I=eye(N+1);M=zeros(N+1,N+1); % I is a diagnal matrix and M is inicially a zero matrix
for i=0:N/2 % interations
n=i:N-i;
b=(-1).^(N-n-i).*factorial(N-i)./factorial(n)./factorial(N-n-i).*(factorial(N)./factorial(N-i)./factorial(i));
M(i+1,i+1:N+1-i)=b;
end
M = rot90(fliplr(M),1)+M-diag(M).*I; % Output matrix
end
Ans
M =
-1 3 -3 1
3 -6 3 0
-3 3 0 0
1 0 0 0
I was wondering is there anyway i can remove a loop from inside the function here?

답변 (2개)

Walter Roberson
Walter Roberson 2021년 2월 4일

0 개 추천

[M] = Iterations(3)
M = 4×4
-1 3 -3 1 3 -6 3 0 -3 3 0 0 1 0 0 0
function [M] = Iterations(N) % N is an input variable
I=eye(N+1);M=zeros(N+1,N+1); % I is a diagnal matrix and M is inicially a zero matrix
i=0:N/2; % interations
n=(0:N).';
b = (-1).^(N-n-i).*gamma(N-i+1)./factorial(n)./gamma(N-n-i+1).*(factorial(N)./gamma(N-i+1)./factorial(i));
M = [tril(b).'; zeros(size(b.'))];
M = rot90(fliplr(M),1)+M-diag(M).*I;
end

댓글 수: 1

This fails for even N:
Matrix dimensions must agree.
Error in kjh>Iterations_4 (line 84)
M = rot90(fliplr(M),1)+M-diag(M).*I;

댓글을 달려면 로그인하십시오.

Jan
Jan 2021년 2월 5일
편집: Jan 2021년 2월 5일

0 개 추천

Why do you want to do this without a loop? When the purpose is an acceleration, omit the expensive factorial and power operations at first:
function M = Iterations(N)
F = [1, cumprod(1:21)]; % Emulated factorial()
sF = F;
sF(2:2:22) = -sF(2:2:22); % Include expensive power operation -1^(N-n-i)
FN = F(N+1);
M = zeros(N+1, N+1);
for i = 0:N/2
t = N - i + 1;
b = F(t) ./ F(i+1:t) ./ sF(t-i:-1:1) .* (FN ./ F(t) ./ F(i+1));
M(i+1, i+1:t) = b;
M(i+1:t, i+1) = b;
end
end
For N = 10 this is needs 16% of the runtime of the original.
But due to the factorial the output will be accurate for N <= 21. If you need such a small set of inputs only, it would be more efficient, to create a list of possible values once and store it in a persistent varibale.
function M = IterationsX(N)
persistent List
if isempty(List)
List = cell(1, 21);
for k = 1:21
List{k} = Iterations(k);
end
end
M = List{N};
end

댓글 수: 7

hyder abedi
hyder abedi 2021년 2월 5일
Thanks for improving the code and giving me a different way of writing it. I was just curious whether this or any iteration can be done without a loop at all. yet the question remains.
And how did you calculate the runtime?
Image Analyst
Image Analyst 2021년 2월 5일
You can use tic and toc to measure elasped seconds.
For loops are not always slow. How big is your N? Unless your N is like hundreds of millions, I doubt the loop will take more than a fraction of a second. For N = 10 or 21, you're looking at an elapsed time of like microseconds.
hyder abedi
hyder abedi 2021년 2월 5일
It depends on number of variables in my dataset, right now its 8 but it can be 100 or more.
Jan
Jan 2021년 2월 5일
factorial(100) is 9.3e157. BSplines with so many points cannot be calculated accurately anymore, because the double values contain the first 16 digits only.
Walter Roberson
Walter Roberson 2021년 2월 5일
When you have factorial divided by factorial, consider using pochhammer; https://www.mathworks.com/help/symbolic/pochhammer.html
hyder abedi
hyder abedi 2021년 2월 5일
Thanks again Jan i wasn't aware that double values contain the first 16 digits only.
hyder abedi
hyder abedi 2021년 2월 5일
Thanks Walter Roberson.

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Elementary Math에 대해 자세히 알아보기

제품

릴리스

R2020a

질문:

2021년 2월 4일

댓글:

2021년 2월 5일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by