Creating a matrix that is more time efficient

Hey guys,
My problem is as follows.
I want to create a matrix that has certain logic like so.
% code
n = 50; % Just an arbitrary number
B = rand(1,n);
A = rand(1,n);
% The components of the vectors A and B are not necessary a number between 0 and 1. But a calculated number, but for the purpose of this problem I'd rather use this random generated vector.
for i = 1:n
for j = 1:n
if i == j
C(i, j) = 5*B(1, i) + A(1,j);
else
C(i, j) = -B(1, i) + 3*A(1, j);
end
end
end
The code up above does the works, but it takes quite a long time, since it makes each component individually.
So my question is, is there a more efficient way to create this matrix?

 Accepted Answer

C = 3*A - B(:); % or C = bsxfun(@minus,3*A,B(:))
C(1:n+1:end) = 5*B + A;

7 Comments

Really liked your answer, but if you allow me, lets increase a little bit the difficult. The equation that i'm working with is exactly as follows - when you aren't working with the main diagonal , in another words i =~ j.
C(i,j) = sin(A(j))/((cos(A(j))-cos(A(i)))^2)*(((1-(-1)^(j-i))/(2*(n+1))));
Do you know how to solve that little part that uses "(j-i)"?
And for the main diagonal the equation is as follows.
B(i,j) = -((n+1)/(4*sin(A(i)))+B(i));
But with your solution, I've figured it out.
Thank you very much.
There's no B in your C off-diagonal expression? Or is that a typo? I assume your diagonal line is a typo and should have had C(i,i) on the lhs.
That is correct, there isn't any B in the off diagonal. The problem are those indexes that i don't want to use a for loop to cover than all.
And the main diagonal was a mistake
C(i,j) = -((n+1)/(4*sin(A(i)))+B(i));
What about this:
N = 1:n;
C = sin(A)./((cos(A)-cos(A(:))).^2).*(((1-(-1).^(N-N(:)))/(2*(n+1))));
C(1:n+1:end) = -((n+1)./(4*sin(A))+B);
This assumes you are running with a later version of MATLAB that has implicit expansion for the element-wise operators. If not, then you would have to use bsxfun( ) for a few of those operations.
I'm running the R2016a version. And probably it doesn't work, i'm getting a "Matrix dimension must agree".
So probably somehow bsxfun could a way to do it.
But anyway Thank you very much, at least i've learned some new logic to use in future programs =D
The bsxfun( ) version:
N = 1:n;
% D = sin(A)./((cos(A)-cos(A(:))).^2).*(((1-(-1).^(N-N(:)))/(2*(n+1))));
cosA = cos(A);
sinA = sin(A);
costemp = bsxfun(@minus,cosA,cosA(:));
sincostemp = bsxfun(@rdivide,sinA,costemp.^2);
Ntemp = bsxfun(@minus,N,N(:));
D = sincostemp.*(((1-(-1).^Ntemp)/(2*(n+1))));
D(1:n+1:end) = -((n+1)./(4*sinA)+B);
It worked, man, you are awesome.
Never thought that you could use bsxfun() like that.
once more, thanks, problem solved

Sign in to comment.

More Answers (0)

Categories

Find more on Get Started with MATLAB in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!