I would need a list of n positive integers L that has following properties:
for each possible subset S of L, if I sum all items of S, this sum is not in L
for each possible subset S of L, if I sum all items of S, this sum is unique (each subset can be identified by his sum)
Working example 1:
n = 4
L = [1, 5, 7, 9]
check:
1+5 = 6 ok
5+7 = 12 ok
7+9 = 16 ok
9+1 = 10 ok
1+7 = 8 ok
5+9 = 14 ok
1+5+7 = 13 ok
5+7+9 = 21 ok
1+5+9 = 15 ok
1+7+9 = 17 ok
1+5+7+9 = 22 ok
All sums are unique -> L is OK for n = 4
As an easy to construct sequence, I suggest using power series, e.g.
1, 2, 4, 8, ..., 2**k, ...
1, 3, 9, 27, ..., 3**k, ...
1, 4, 16, 64, ..., 4**k, ...
...
1, n, n**2, n**3,..., n**k, ... where n >= 2
Take, for instance, 2: neither power of 2 is a sum of other 2 powers; given a sum (number) you can easily find out the subset by converting sum into binary representation:
23 = 10111 (binary) = 2**0 + 2**1 + 2**2 + 2**4 = 1 + 2 + 4 + 16
In general case, a simple greedy algorithm will do: given a sum subtract the largest item less or equal to the sum; continue subtracting up to zero:
n = 3
sum = 273
273 - 243 (3**5) = 30
30 - 27 (3**3) = 3
3 - 3 (3**1) = 0
273 = 3**5 + 3**3 + 3**1 = 243 + 27 + 3
Related
I have an array of length n. The array has braking energy values, and the index number represents time in seconds.
The structure of array is as follows:
Index 1 to 140, array has zero values. (Vehicle not braking)
Index 141 to 200, array has random energy values. (Vehicle was braking and regenerating energy)
Index 201 to 325, array has zero values. (Vehicle not braking)
Index 326 to 405, array has random energy values. (Vehicle was braking and regenerating energy)
...and so on for an array of length n.
What I want to do is to get starting and ending index number of each set of energy values.
For example the above sequence gives this result:
141 - 200
326 - 405
...
Can someone please suggest what method or technique can I use to get this result?
Using diff is a quick way to do this.
Here is a demo (see the comments for details):
% Junk data for demo. Indices shown above for reference
% 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
x = [0, 0, 0, 2, 3, 4, 0, 0, 1, 1, 7, 9, 3, 4, 0, 0, 0];
% Logical converts all non-zero values to 1
% diff is x(2:end)-x(1:end-1), so picks up on changes to/from zeros
% Instead of 'logical', you could have a condition here,
% e.g. bChange = diff( x > 0.5 );
bChange = diff( logical( x ) );
% bChange is one of the following for each consecutive pair:
% 1 for [0 1] pairs
% 0 for [0 0] or [1 1] pairs
% -1 for [1 0] pairs
% We inflate startIdx by 1 to index the non-zero value
startIdx = find( bChange > 0 ) + 1; % Indices of [0 1] pairs
endIdx = find( bChange < 0 ); % Indices of [1 0] pairs
I'll leave it as an exercise to capture the edge cases where you add a start or end index if the array starts or ends with a non-zero value. Hint: you could handle each case separately or pad the initial x with additional end values.
Output of the above:
startIdx
>> [4, 9]
endIdx
>> [6, 14]
So you can format this however you like to get the spans 4-6, 9-14.
This task is performed by two methods Both works perfectly.
Wolfie Method:
bChange = diff( EnergyB > 0 );
startIdx = find( bChange > 0 ) + 1; % Indices of [0 1] pairs
endIdx = find( bChange < 0 ); % Indices of [1 0] pairs
Result:
startIdx =
141
370
608
843
endIdx =
212
426
642
912
Second Method:
startends = find(diff([0; EnergyB > 0; 0]));
startends = reshape(startends, 2, [])';
startends(:, 2) = startends(:, 2) - 1
Result:
startends =
141 212
370 426
608 642
843 912
I have a 3D-cell array designated as A{s,i,h}, serving as a store for large amounts of numerical data during a nested-loop portion of my script. Some of the cell entries will be blank [ ], whilst the rest consist of numbers - either singular or in arrays (1 x 10 double etc.):
I want to convert this cell array to a set of 2D matrices.
Specifically, one separate matrix for each value of h (h is always equal 1:3) and one column in each matrix for every value of s. Each column will contain all the numerical data combined - it does not need to be separated by i.
How can I go about this? I ordinarily deal with 3D-cell arrays in this form to produce separate matrices (one for each value of h) using something like this:
lens = sum(cellfun('length',reshape(A,[],size(A,3))),1);
max_length = max(lens);
mat = zeros(max_length,numel(lens));
mask = bsxfun(#le,[1:max_length]',lens);
mat(mask) = [A{:}];
mat(mat==0) = NaN;
mat = sort(mat*100);
Matrix1 = mat(~isnan(mat(:,1)),1);
Matrix2 = mat(~isnan(mat(:,2)),2);
Matrix3 = mat(~isnan(mat(:,3)),3);
However in this instance, each matrix had only a single column. I'm have trouble adding multiple columns to each output matrix.
1. Result in the form of a cell array of matrices (as requested)
Here's one possible approach. I had to use one for loop. However, the loop can be easily avoided if you accept a 3D-array result instead of a cell array of 2D-arrays. See second part of the answer.
If you follow the comments in the code and inspect the result of each step, it's straightforward to see how it works.
%// Example data
A(:,:,1) = { 1:2, 3:5, 6:9; 10 11:12 13:15 };
A(:,:,2) = { 16:18, 19:22, 23; 24:28, [], 29:30 };
%// Let's go
[S, I, H] = size(A);
B = permute(A, [2 1 3]); %// permute rows and columns
B = squeeze(mat2cell(B, I, ones(1, S), ones(1, H))); %// group each col of B into a cell...
B = cellfun(#(x) [x{:}], B, 'uniformoutput', false); %// ...containing a single vector
t = cellfun(#numel, B); %// lengths of all columns of result
result = cell(1,H); %// preallocate
for h = 1:H
mask = bsxfun(#le, (1:max(t(:,h))), t(:,h)).'; %'// values of result{h} to be used
result{h} = NaN(size(mask)); %// unused values will be NaN
result{h}(mask) = [B{:,h}]; %// fill values for matrix result{h}
end
Result in this example:
A{1,1,1} =
1 2
A{2,1,1} =
10
A{1,2,1} =
3 4 5
A{2,2,1} =
11 12
A{1,3,1} =
6 7 8 9
A{2,3,1} =
13 14 15
A{1,1,2} =
16 17 18
A{2,1,2} =
24 25 26 27 28
A{1,2,2} =
19 20 21 22
A{2,2,2} =
[]
A{1,3,2} =
23
A{2,3,2} =
29 30
result{1} =
1 10
2 11
3 12
4 13
5 14
6 15
7 NaN
8 NaN
9 NaN
result{2} =
16 24
17 25
18 26
19 27
20 28
21 29
22 30
23 NaN
2. Result in the form of 3D array
As indicated above, using a 3D array to store the result permits avoiding loops. In the code below, the last three lines replace the loop used in the first part of the answer. The rest of the code is the same.
%// Example data
A(:,:,1) = { 1:2, 3:5, 6:9; 10 11:12 13:15 };
A(:,:,2) = { 16:18, 19:22, 23; 24:28, [], 29:30 };
%// Let's go
[S, I, H] = size(A);
B = permute(A, [2 1 3]); %// permute rows and columns
B = squeeze(mat2cell(B, I, ones(1, S), ones(1, H))); %// group each col of B into a cell...
B = cellfun(#(x) [x{:}], B, 'uniformoutput', false); %// ...containing a single vector
t = cellfun(#numel, B); %// lengths of all columns of result
mask = bsxfun(#le, (1:max(t(:))).', permute(t, [3 1 2])); %'// values of result to be used
result = NaN(size(mask)); %// unused values will be NaN
result(mask) = [B{:}]; %// fill values
This gives (compare with result of the first part):
>> result
result(:,:,1) =
1 10
2 11
3 12
4 13
5 14
6 15
7 NaN
8 NaN
9 NaN
result(:,:,2) =
16 24
17 25
18 26
19 27
20 28
21 29
22 30
23 NaN
NaN NaN
Brute force approach:
[num_s, num_i, num_h] = size(A);
cellofmat = cell(num_h,1);
for matrix = 1:num_h
sizemat = max(cellfun(#numel, A(:,1,matrix)));
cellofmat{matrix} = nan(sizemat, num_s);
for column = 1:num_s
lengthcol = length(A{column, 1, matrix});
cellofmat{matrix}(1:lengthcol, column) = A{column, 1,matrix};
end
end
Matrix1 = cellofmat{1};
Matrix2 = cellofmat{2};
Matrix3 = cellofmat{3};
I don't know what your actual structure looks like but this works for A that is setup using the following steps.
A = cell(20,1,3);
for x = 1:3
for y = 1:20
len = ceil(rand(1,1) * 10);
A{y,1,x} = rand(len, 1);
end
end
Given an array {1,3,5,7}, its subparts are defined as {1357,135,137,157,357,13,15,17,35,37,57,1,3,5,7}.
I have to find the sum of all these numbers in the new array. In this case sum comes out to be 2333.
Please help me find a solution in O(n). My O(n^2) solution times out.
link to the problem is here or here.
My current attempt( at finding a pattern) is
for(I=0 to len) //len is length of the array
{
for(j=0 to len-i)
{
sum+= arr[I]*pow(10,j)*((len-i) C i)*pow(2,i)
}
}
In words - len-i C i = (number of integers to right) C weight. (combinations {from permutation and combination})
2^i = 2 power (number of integers to left)
Thanks
You can easily solve this problem with a simple recursive.
def F(arr):
if len(arr) == 1:
return (arr[0], 1)
else:
r = F(arr[:-1])
return (11 * r[0] + (r[1] + 1) * arr[-1], 2 * r[1] + 1)
So, how does it work? It is simple. Let say we want to compute the sum of all subpart of {1,3,5,7}. Let assume that we know the number of combinatiton of {1,3,5} and the sum of subpart of {1,3,5} and we can easily compute the {1,3,5,7} using the following formula:
SUM_SUBPART({1,3,5,7}) = 11 * SUM_SUBPART({1,3,5}) + NUMBER_COMBINATION({1,3,5}) * 7 + 7
This formula can easily be derived by observing. Let say we have all combination of {1,3,5}
A = [135, 13, 15, 35, 1, 3, 5]
We can easily create a list of {1,3,5,7} by
A = [135, 13, 15, 35, 1, 3, 5] +
[135 * 10 + 7,
13 * 10 + 7,
15 * 10 + 7,
35 * 10 + 7,
1 * 10 + 7,
3 * 10 + 7,
5 * 10 + 7] + [7]
Well, you could look at at the subparts as sums of numbers:
1357 = 1000*1 + 100*3 + 10*5 + 1*7
135 = 100*1 + 10*3 + 1*5
137 = 100*1 + 10*3 + 1*7
etc..
So, all you need to do is sum up the numbers you have, and then according to the number of items work out what is the multiplier:
Two numbers [x, y]:
[x, y, 10x+y, 10y+x]
=> your multiplier is 1 + 10 + 1 = 12
Three numbers [x, y, z]:
[x, y, z,
10x+y, 10x+z,
10y+x, 10y+z,
10z+x, 10z+y,
100x+10y+z, 100x10z+y
.
. ]
=> you multiplier is 1+10+10+1+1+100+100+10+10+1+1=245
You can easily work out the equation for n numbers....
If you expand invisal's recursive solution you get this explicit formula:
subpart sum = sum for k=0 to N-1: 11^(N-k) * 2^k * a[k]
This suggests the following O(n) algorithm:
multiplier = 1
for k from 0 to N-1:
a[k] = a[k]*multiplier
multiplier = multiplier*2
multiplier = 1
sum = 0
for k from N-1 to 0:
sum = sum + a[k]*multiplier
multiplier = multiplier*11
Multiplication and addition should be done modulo M of course.
I have 5 columns x, y, r, g, b with values of line number, column number, red, green and blue. The lines of this n by 5 matrix are not in a particular order, however they are consistent with image(x,y) and the r,g,b.
I would like to do something like I=uint8(zeros(480,640,3) and just change those rgb values based on the n by 5 mat.
Something along the lines of I(mat(:,1), mat(:,2), 1)=mat(:,3) for red etc
The following uses the concept of linear indexing and the versatile bsxfun function:
m = 640; %// number of rows
n = 480; %// number of columns
I = zeros(m, n, 3, 'uint8'); %// initiallize directly as uint8
I(bsxfun(#plus, x(:)+(y(:)-1)*m, (0:2)*m*n)) = [r(:) g(:) b(:)]; %// fill values
Small example: for
m = 2;
n = 3;
x = [1 2 1];
y = [1 1 2];
r = [ 1 2 3];
g = [11 12 13];
b = [21 22 23];
the code produces
I(:,:,1) =
1 3 0
2 0 0
I(:,:,2) =
11 13 0
12 0 0
I(:,:,3) =
21 23 0
22 0 0
An alternative:
INDr = sub2ind([480, 640, 3], mat(:, 1), mat(:,2), ones([numel(mat(:,3)), 1]));
INDg = sub2ind([480, 640, 3], mat(:, 1), mat(:,2), 2*ones([numel(mat(:,3)), 1]));
INDb = sub2ind([480, 640, 3], mat(:, 1), mat(:,2), 3*ones([numel(mat(:,3)), 1]));
I=uint8(zeros(480,640, 3));
I(INDr)=mat(:,3);
I(INDg)=mat(:,4);
I(INDb)=mat(:,5);
Note that in Matlab, the convention between axes is different between images and arrays.
I need help with my code. The code is used to find the minumin of a square-distance problem. I am providing my code through an example, I believe this will be the easiest way to explain what I need.
clear all
clc
x=10.8; % is a fixed value
y=34; % is a fixed value
z=12; % is a fixed value
A = [11 14 1; 5 8 18; 10 8 19; 13 20 16]; % a (4x3) matrix
B = [2 3 10; 6 15 16; 7 3 15; 14 14 19]; % a (4x3) matrix
I create a new matrix C which is composed in this following way:
C1 = bsxfun(#minus, A(:,1)',B(:,1));
C1=C1(:); % this is the first column of the new matrix C
C2 = bsxfun(#minus, A(:,2)',B(:,2));
C2=C2(:); % this is the second column of the new matrix C
C3 = bsxfun(#minus, A(:,3)',B(:,3));
C3=C3(:); % this is the third column of the new matrix C
C = [C1 C2 C3]; % the new matrix C of size (16x3)
C has to be formed in this way! And this is what I meant when I wrote in my title a composed-matrix
Then:
[d,p] = min((C(:,1)-x).^2 + (C(:,2)-y).^2 + (C(:,3)-z).^2);
d = sqrt(d);
outputs:
d = 18.0289;
p = 13;
Gives me the distance (d) and position (p) which satisfies this min problem.
MY PROBLEM:
I need to find which combinations of A and B has given my this p value, in other words I need the index from ´A,B´ which gives me this optimal C1,C2,C3:
C1 = bsxfun(#minus, A(?,1)',B(?,1));
C2 = bsxfun(#minus, A(?,2)',B(?,2));
C3 = bsxfun(#minus, A(?,3)',B(?,3));
The ? is the index position I need, in this case the index position of the matrix A and the index position of B.
Calculated by hand I have the following illustration:
I know that:
C = [9 11 -9
5 -1 -15
4 11 -14
-3 0 -18
3 5 8
-1 -7 2
-2 5 3
-9 -6 -1
8 5 9
4 -7 3
3 5 4
-4 -6 0
11 17 6
7 5 0
6 17 1
-1 6 -3]
And I know that my optimal index is given in the position 13th. This index positions goes back to:
[13-2 20-3 16-10]
Which is A(4,:) - B(1,:)
I need a code which can help me to find this indexes from A and B
Thanks in advance!
PS. I am using the code in parameter estimation problems of ODEs.
First case: vector-matrix case
subvals = bsxfun(#minus,A,[x y z])
[distance,index] = min(sqrt(sum(subvals.^2,2)))
Second case: Two matrices case
subvals = bsxfun(#minus,A,permute(B,[3 2 1]));
[distances,indices] = min(sqrt(sum(subvals.^2,2)),[],3)
Testing for second case:
%%// Get some random data into A and B
A = randi(20,8,3)
B = randi(20,4,3)
%%// Just to test out out code for correctness,
%%// let us make any one one row of B, say 3rd row equal to
%%// any one row of A, say the 6th row -
B(3,:) = A(6,:)
%%// Use the earlier code
subvals = bsxfun(#minus,A,permute(B,[3 2 1]));
[distances,indices] = min(sqrt(sum(subvals.^2,2)),[],3)
%%// Get the minimum row index for A and B
[~,min_rowA] = min(distances)
min_rowB = indices(min_rowA)
Verification
min_rowA =
6
min_rowB =
3
Edit 1 [Response to simple example posted in question]:
The title says you are interested in finding the difference of two matrices and then find the shortest distance between it to a vector [x y z]. So I am hoping this is what you need -
x=10.8;
y=34;
z=12;
A = [11 14 1; 5 8 18; 10 8 19; 13 20 16];
B = [2 3 10; 6 15 16; 7 3 15; 14 14 19];
C = A -B; %%// Distance of two vectors as posted in title
subvals = bsxfun(#minus,C,[x y z])
[distance,index] = min(sqrt(sum(subvals.^2,2)))
Output
distance =
31.0780
index =
3
Edit 2: After you have done this -
[d,p] = min((C(:,1)-x).^2 + (C(:,2)-y).^2 + (C(:,3)-z).^2);
If you are looking to find the corresponding indices of A and B , you may do this -
[minindex_alongB,minindex_alongA] = ind2sub(size(A),p)