Main diagonal operations problem

2 visualizaciones (últimos 30 días)
Giuseppe Pintori
Giuseppe Pintori el 13 de Sept. de 2019
Editada: Bruno Luong el 14 de Sept. de 2019
Hi guys, I need your help.
I want to create a matrix(4,4) in which the main diagonal have values between 0.3 and 1 and the other cells assume values ​​such as to have a horizontal sum equal to 1.
By now I'm using the following code but the only result is to have a main diagonal composed by the same numbers:
x = eye(4)
x(1,1) = 1+(0.3-1)*rand(1,1)
x(2,2) = x(1,1)
x(3,3) = x(1,1)
x(4,4) = x(1,1)
Any suggestion?
PS : I've tried even with diag
  2 comentarios
Stephen23
Stephen23 el 13 de Sept. de 2019
Editada: Stephen23 el 13 de Sept. de 2019
"...the other cells assume values ​​such as to have a horizontal sum equal to 1"
Are there any other requirements on the other elements? Positive, negative, fractional values, integer, >1, >100, >1e100 ... what values are allowed?
What is the "horizontal sum": do you mean to sum along the 2nd dimension (i.e. along each row) ?
Giuseppe Pintori
Giuseppe Pintori el 13 de Sept. de 2019
the values must be positive and by horizontal sum i mean that the sum of each row must be equal to 1

Iniciar sesión para comentar.

Respuesta aceptada

Stephen23
Stephen23 el 13 de Sept. de 2019
Editada: Stephen23 el 13 de Sept. de 2019
Using Roger Stafford's FEX submission randfixedsum (must be downloaded first):
>> N = 4; % matrix size
>> M = nan(N,N); % preallocate
>> V = 0.3+(1-0.3)*rand(1,1) % diagonal value
V =
0.47505
>> M(~eye(N)) = randfixedsum(N-1,N,1-V,0,1); % other values
>> M = M.'; % transpose
>> M(1:N+1:end) = V % assign diagonal value
M =
0.47505 0.40657 0.0087969 0.10958
0.12917 0.47505 0.21287 0.1829
0.35794 0.15519 0.47505 0.011825
0.41335 0.032696 0.078907 0.47505
Checking the sum of each row:
>> sum(M,2)
ans =
1
1
1
1
and diagonal:
>> diag(M)
ans =
0.47505
0.47505
0.47505
0.47505
  6 comentarios
John D'Errico
John D'Errico el 13 de Sept. de 2019
Editada: John D'Errico el 13 de Sept. de 2019
Yes. I had come to that conclusion after some thought too. But there still seems to be the question of what is the true goal, since only Giuseppe can know that. I think Stephen's solution comes closer than mine.
On the other hand, HAD I generated the diagonal elements using a better distribution than uniform, then my solution would be an avenue to not needing to use a rejection while loop at all.
Bruno Luong
Bruno Luong el 13 de Sept. de 2019
Editada: Bruno Luong el 14 de Sept. de 2019
Oh I see your point. I think you are right by forcing the right PDF to generate D, it's equivalent to rejection method. This I'm pretty sure it's right because of the special property of simplex and barycentric coordinates.
So the right way (I simplify the procedure to a single row without loosing the generality) is
N = 4;
dmin = 0.3;
dmax = 1;
d = dmax-(dmax-dmin)*rand().^(1/(N-1)); % rather than dmin+(dmax-dmin)*rand;
v = (1-d) * randfixedsum(N-1,1,1,0,1);
then insert d to v....

Iniciar sesión para comentar.

Más respuestas (3)

John D'Errico
John D'Errico el 13 de Sept. de 2019
Editada: John D'Errico el 13 de Sept. de 2019
Easy enough, it seems. First, determine the diagonal elements.
x = diag(rand(1,4)*.7 + .3);
Next, you need to choose the other row elements randomly so the sum will be 1. But that sum will now depend on the diagonal element you just chose. Stilll simple, as long as you use randfixedsum, by Roger Stafford, found on the file exchange.
for i = 1:4
x(i,setdiff(1:4,i)) = randfixedsum(3,1,1 - x(i,i),0,1)';
end
Did it work? Of course.
x
x =
0.83586 0.075979 0.057706 0.030454
0.012356 0.85664 0.11425 0.016757
0.13748 0.21163 0.43081 0.22009
0.15838 0.037488 0.16129 0.64284
>> sum(x,2)
ans =
1
1
1
1
Find randfixedsum here:

Matt J
Matt J el 13 de Sept. de 2019
x=eye(4);
x(1:5:end)=0.7*rand(4,1)+0.3
  1 comentario
Giuseppe Pintori
Giuseppe Pintori el 13 de Sept. de 2019
sorry, I forgot to write that the diagonal must be composed of identical values

Iniciar sesión para comentar.


Bruno Luong
Bruno Luong el 13 de Sept. de 2019
Editada: Bruno Luong el 13 de Sept. de 2019
Here is a method that has two advantages:
  • without the need of Roger's FEX randfixedsum
  • Produce matrix with rigourous uniform conditional probability
N = 4; % matrix size
% diagonal lo/up bounds
dmin = 0.3;
dmax = 1;
% random (common) diagonal value
d = dmax-(dmax-dmin)*rand().^(1/(N-1)); % Edit see comment above, equiv to rejection method
% d = dmin+(dmax-dmin)*rand;
% Generate N random vectors of length N-1 required sum == (1-d)
V = -log(rand(N-1,N)); % Marsaglia's [1961] method
V = V .* ((1-d)./sum(V,1));
% Arrange in the final matrix
A = zeros(N);
isdiag = sparse(1:N,1:N,true);
A(isdiag) = d;
A(~isdiag) = V(:);
A = A.';
% Check result
disp(A)
sum(A,2)
EDIT change after this disccusion with John

Categorías

Más información sobre Creating and Concatenating Matrices en Help Center y File Exchange.

Productos

Community Treasure Hunt

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

Start Hunting!

Translated by