Equivalent of A&(~B) without using ~

I am looking for a way to generate the same output as A&(~B) w/o using the ~ operator. The problem is both A and B are very large sparse matrices with only a few non-zero elements (trues). Evaluating ~B will produce a temporary matrix that cannot fit in memory. What's the best way to circumvent this?

 Respuesta aceptada

Yi-xiao Liu
Yi-xiao Liu el 22 de Jun. de 2022
Editada: Yi-xiao Liu el 22 de Jun. de 2022
Hat tip to @David Goodmanson and @Stephen23. I found 4 solutions:
A=rand(5)<0.6;B=rand(5)>0.2;
ref=A&(~B);
Method1=A;
Method1(B)=false;
Method2=A-(A&B);
Method3=(A-B)>0;
Method4=xor(A,A&B);
all((Method1==ref)&(Method2==ref)&(Method3==ref)&(Method4==ref),"all")
ans = logical
1
rng("shuffle")
t1=nan(10,1);t2=nan(10,1);t3=nan(10,1);t4=nan(10,1);
for ii=1:10
idx=ceil(1e6*rand(2e6,2));
idx=unique(idx,"rows");
i=idx(:,1);j=idx(:,2);
A=sparse(i(1:1e6),j(1:1e6),true(1e6,1),1e6,1e6);
B=sparse(i((1e6+1):end),j((1e6+1):end),true(numel(i)-1e6,1),1e6,1e6);
tic
Method1=A;
Method1(B)=false;
t1(ii)=toc;
tic
Method2=A-(A&B);
t2(ii)=toc;
tic
Method3=(A-B)>0;
t3(ii)=toc;
tic
Method4=xor(A,A&B);
t4(ii)=toc;
end
t1=mean(t1);t2=mean(t2);t3=mean(t3);t4=mean(t4);
bar([t1,t2,t3,t4])
Personally I like the 4th one the most. It's fast, it's short, and it does not invoke type conversion in case you are short on Bytes.

4 comentarios

Note that Method2 returns a double, not logical.
A=rand(5)<0.6;B=rand(5)>0.2;
ref=A&(~B);
Method1=A;
Method1(B)=false;
Method2=A-(A&B);
Method3=(A-B)>0;
Method4=xor(A,A&B);
whos Method*
Name Size Bytes Class Attributes Method1 5x5 25 logical Method2 5x5 200 double Method3 5x5 25 logical Method4 5x5 25 logical
Yi-xiao Liu
Yi-xiao Liu el 22 de Jun. de 2022
Editada: Yi-xiao Liu el 22 de Jun. de 2022
You are correct. However Method2 is a double with only 2 possible values (0 and 1) so this shouldn't matter.
A B A&B A-(A&B)
1 1 1 0
1 0 0 1
0 1 0 0
0 0 0 0
And you can always add logical(Method2)
Paul
Paul el 22 de Jun. de 2022
Editada: Paul el 22 de Jun. de 2022
I thought there was a concern about memory consumption, so thought it worthwile to point out that Method2 requires 8x more memory, in addtion to the need to cast to logical if used later on as logical.
Yi-xiao Liu
Yi-xiao Liu el 22 de Jun. de 2022
@Paul You are absolutely right. This is in fact (one of) the reason I prefer method 4 (see last line of my answer).
On conversion back to logical, my experience is that MATLAB will do the conversion for you if you try to use double as logical. there is no need to do it explicitly.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Elementary Math en Centro de ayuda y File Exchange.

Productos

Versión

R2019b

Preguntada:

el 22 de Jun. de 2022

Comentada:

el 22 de Jun. de 2022

Community Treasure Hunt

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

Start Hunting!

Translated by