how can I generate a code based on specific value selection in a matrix?

I want to make a function that search for a value of y in x, either one element or sum of many elements, and return 1 or 0 to matrix Z, which is the same size as X, based on the elements chosen from X.
Example:
y=7;
x=[10 -1 -2 -3];
solution will be:
1) 10-1-2=7 ==> Z=[1 1 1 0];
2) 10-3=7 ==> Z=[1 0 0 1];
Any hints?

 Akzeptierte Antwort

James Tursa
James Tursa am 13 Sep. 2016
Bearbeitet: James Tursa am 13 Sep. 2016
Here is one way as long as x is not too large. This technique will use too much memory if x is too large.
b = dec2bin(0:2^numel(x)-1)=='1'; % Intermediate step of producing all possible patterns
z = b(b*x'==y,:); % Pick off the rows of b that produce the desired sum
The rows of z contain the patterns that produce the desired sum.

8 Kommentare

thank you so much, it really helps. and yes I'm assuming x is not big.
One issue if you can give some hints. if I assume that we have two values and two matrices and want to get the matrix z as sum of them,
Eaxmple,
x=[5 -2 -1 -1];
y1=5; y2=-2;
% using the formula you provided I found solutions for both
z1=[1 0 0 0]; % solution to y1
z2=[0 1 0 0; 0 0 1 1]; % solution to y2
I want to have the first row of z1 merged to rows of z2 as follows:
Z= [1 1 0 0; 1 0 1 1];
I used xor function but I need to match the size before I xor them, is there any other way you think I can follow? by the way, in the solution if 1 appears in the same position in z1 and z2 the solution is ignored/cancelled, Example:
if z1=[ 1 0 0 1] and z2=[0 0 0 1; 0 0 1 0] the first row of z2 need to be ignored and z will be z=[1 0 1 0]
sorry for my long post!
Assuming only z2 has multiple rows:
k = ~any(bsxfun(@and,z1,z2),2); % identify rows where there is no 1's overlap
zxor = bsxfun(@xor,z1,z2(k,:)); % xor z1 with the 'k' rows of z2
For your example result, I assume z = [1 0 1 0] is a typo and should have been z = [1 0 1 1]. True? Also, I used "xor" since you did, but since we have eliminated the 1's overlap I could have simply used "or" instead.
If both z1 and z2 could have multiple rows, then you will need to tell me what you want the result to be.
you are right and that is what I am looking for. It is very short and fast.
z1 and z2 can take multiple rows, I want Z to be the output of xoring z1 and z2 rows except the rows the have 1's overlap; I guess I need to make a for loop?
Example: z of first example is a result of xoring z1 and second raw of z2. First raw of z2 is ignored because of the appearance of 1 in both matrices.
Ex: z1=[1 0 0;0 1 0;1 0 1] z2=[0 1 1;1 0 0;1 1 0] z=xor(z1,z2) raw by raw will give z of 9*3 but if first step of ignoring the overlap is done this would result in only a z matrix of 3*3
Yes, you could put this in a loop (although I get a 2x3 result instead of your claimed 3x3 result):
m = size(z1,1);
zresult = cell(m,1);
for n=1:m
k = ~any(bsxfun(@and,z1(n,:),z2),2); % identify rows where there is no 1's overlap
zresult{n} = bsxfun(@xor,z1(n,:),z2(k,:)); % xor z1 row with the 'k' rows of z2
end
zxor = vertcat(zresult{:});
Thanks James, I really appreciate your swift reply.
Hi friends!
Please accept my small contribution:
z1=[1 0 0;0 1 0;1 0 1];
z2=[0 1 1;1 0 0;1 1 0];
jj = reshape(permute(...
bsxfun(@plus,permute(z1,[3,2,1]),z2),...
[1,3,2]),[],size(z1,2));
zout = jj(all(jj <= 1,2),:);
Thanks Andrei for your input, definitely it helps me.
This is maybe a follow-up question,
if z2 has 2's instead of 1's and I want them to appear in zout matrix, I did it like this:
z1=[1 0 0 1]; z2=[0 0 0 2; 0 0 2 0]; k = ~any(bsxfun(@and,z1,z2),2); zout = bsxfun(@xor,z1,z2(k,:)); % or as Andrei suggested
index=find(z2==2); % to find the index of 2's in z2 for i=1:length(index) j=index(i); zout(j)=zout(j)*2; % changing 1's to 2's in Zout based in position of 2's in z2 end
but did not work because of the size of zout, the index=6 7 while zout is 1*4 matrix, is there any other way?

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

John D'Errico
John D'Errico am 13 Sep. 2016

3 Stimmen

There may be millions, or millions or trillions of solutions, or only a few. Your problem is classically called an integer partition .
https://en.wikipedia.org/wiki/Partition_(number_theory)
For example, the number of distinct ways the number 1000 can be written as the sum of elements from the set [1:1000] is 24061467864032622473692149727991. A BIG number.
You can download my partitions tool from the file exchange, which can generate the entire set (where that is feasible given some rational amount of time and memory.) It allows you to specify the elements to be allowed in the sum.
https://www.mathworks.com/matlabcentral/fileexchange/12009-partitions-of-an-integer

1 Kommentar

interesting topic, I need to look at the theory and understand it.
I appreciate your help Sir.

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Matrices and Arrays finden Sie in Hilfe-Center und File Exchange

Gefragt:

am 13 Sep. 2016

Kommentiert:

am 14 Sep. 2016

Community Treasure Hunt

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

Start Hunting!

Translated by