I wish to write a code that would give me a [5x5] matrix containing values of "ec" for each step. But here I can only return its last value. Could you please help me?
Thanks for your interest
R = [0.13, 0.131, 0.132, 0.133, 0.134];
k = [1, 1.5, 2, 2.5, 3];
a = 3*60*6/1000;
for i=R
ec = 30 * (i*a + i*a*k/100)
endfor
It looks like you want something like
ec = zeros(5);
R = [0.13, 0.131, 0.132, 0.133, 0.134];
k = [1, 1.5, 2, 2.5, 3];
a = 3*60*6/1000;
for i_=1:length(R)
for j_=1:length(k)
ec(i_,j_) = 30 * (R(i_)*a + R(i_)*a*k(j_)/100);
end
end
unless I'm mistaken about your question. This should return a 5x5 matrix ec.
A note about for loops: you should avoid using i as a counter, because this is predefined as equal to sqrt(-1), and if you reassign it there can be problems. Adding an underscore avoids this problem.
Related
I am trying to pick one number from multiple arraylists and find all possible ways to pick the numbers such that the sum of those numbers is greater than a given number. I can only think of brute force implementation.
For example, I have five arraylists such as
A = [2, 6, 7]
B = [6, 9]
C = [4]
D = [4, 7]
E = [8, 10, 15]
and a given number is 40.
Then after picking one number from each list, all possible ways could be
[7, 9, 4, 7, 15]
[6, 9, 4, 7, 15]
So, these are the two possible ways to pick numbers greater than or equal to 40. In case the given number is small then there could be many solutions. So how can I count them without brute force? Even with brute force how do I devise the solution in Java.
Below is my implementation. It works fine for small numbers but if the numbers are large then it gives me runtime error since the program runs for too long.
public static void numberOfWays(List<Integer> A, List<Integer> B, List<Integer> C, List<Integer> D,
List<Integer> E, int k){
long ways = 0;
for(Integer a:A){
for(Integer b:B){
for(Integer c:C){
for(Integer d:D){
for(Integer e:E){
int sum = a+b+c+d+e;
//System.out.println(a+" "+b+" "+c+" "+d+" "+e+" "+sum);
if(sum > k)
ways++;
}
}
}
}
}
System.out.println(ways);
}
The list can contain up to 1000 elements and the elements can range from 1 to 1000. The threshold value k can range from 1 to 10^9.
I am not a java programmer.But I think its a logical problem.So,I have solved it for you in python.I am pretty sure you can convert it into java.
Here is the code:
x = input('Enter the number:')
a = [2, 6, 7]
b = [6, 9]
c = [4]
d = [4, 7]
e = [8, 10, 15]
i = 0
z = 0
final_list = []
while i <= int(x):
try:
i += a[z]
final_list.append(a[z])
except BaseException:
pass
try:
i += b[z]
final_list.append(b[z])
except BaseException:
pass
try:
i += c[z]
final_list.append(c[z])
except BaseException:
pass
try:
i += d[z]
final_list.append(d[z])
except BaseException:
pass
try:
i += e[z]
final_list.append(e[z])
except BaseException:
pass
z += 1
print(final_list)
One way is this. There has to be at least one solution where you pick one number from each array and add them up to be greater than or equal to another.
Considering the fact that arrays might have random numbers in any order, first use this sort function to have them in decreasing order (largest number first, smallest number last) :
Arrays.sort(<array name>, Collections.reverseOrder());
Then pick the 1st element in the array :
v = A[0]
w = B[0]
x = C[0]
y = D[0]
z = E[0]
Then you can print them like this : v,w,x,y,z
Now your output will be :
7,9,4,7,15
Since it took the largest number of each array, it has to be equal to or greater than the given number, unless the number is greater than all of these combined in which case it is impossible.
Edit : I think I got the question wrong. If you want to know how many of the possible solutions there are, that is much easier.
First create a variable to store the possibilities
var total = 0
Use the rand function to get a random number. In your array say something like :
v=A[Math.random(0,A[].length)]
Do the same thing for all arrays, then add them up
var sum = v+w+x+y+z
Now you have an if statement to see if the sum is greater than or equal to the number given (lets say the value is stored in the variable "given")
if(sum >= given){
total+=1
}else{
<repeat the random function to restart the process and generate a new sum>
}
Finally, you need to repeat this multiple times as incase there are multiple solutions, the code will only find one and give you a false total.
To solve this, create a for loop and put all of this code inside it :
//create a variable outside to store the total number of elements in all the arrays
var elements = A[].length + B[].length + C[].length + D[].length + E[].length
for(var i = 0; i <= elements; i++){
<The code is inside here, except for "total" as otherwise the value will keep resetting>
}
The end result should look something like this :
var total = 0
var elements = A[].length + B[].length + C[].length + D[].length + E[].length
for(var i = 0; i <= elements; i++){
v=A[Math.random(0,A[].length)]
w=B[Math.random(0,B[].length)]
x=C[Math.random(0,C[].length)]
y=D[Math.random(0,D[].length)]
z=E[Math.random(0,E[].length)]
var sum = v+w+x+y+z
if(sum >= given){
total+=1
}else{
v=A[Math.random(0,A[].length)]
w=B[Math.random(0,B[].length)]
x=C[Math.random(0,C[].length)]
y=D[Math.random(0,D[].length)]
z=E[Math.random(0,E[].length)]
}
}
At the end just print the total once the entire cycle is over or just do
console.log(total)
This is just for reference and the code might not work, it probably has a bunch of bugs in it, this was just my 1st draft attempt at it. I have to test it out on my own but i hope you see where I'm coming from. Just look at the process, make your own amendments and this should work fine.
I have not deleted the first part of my answer even though it isn't the answer to this question just so that if you're having trouble in that part as well, where you select the highest possible number, it might help you
Good luck!
I coded a conversion tool from binary to integer, but it had a limit on how large the number can be. So, I tried to code a formula for binary. I came up with an equation, so I tried to put it into code. Everything worked, except for applying the equation to each digit. This is the equation I came up with:
Let d represent the integer
Let z represent any (and every) digit
d = z[2^(z-1)]
This is what I've coded so far:
answer = gets.chomp
n = answer.reverse # reverses the answer
y1 = answer.size # the amount of digits in the answer
x1 = answer
z = (1..y1).each { |z| puts z } # every number between 1 and number of digits
w = (1..1).each.to_a * y1.to_i #in case I need to multiply the entire array
s = x1 # [z] - 1 # any given digit minus one
v = 2 ** s.to_i # exponent
u = z.zip(w).map{|x, y| x * y} # an array: [1, 2, 3]
print u
t = u.to_i # Tried converting to integer
puts x1[t]
But when I ran that, for example, with the number 1011, I got this error:
[1, 2, 3, 4]
undefined method `to_i' for [1, 2, 3, 4]:Array
Did you mean? to_s
to_a
to_h
(repl):16:in `<main>'
I feel like I have tried everything, but if you somehow find a way to apply the equation to every digit, or if you come up with a simpler equation, please tell me.
This return an array u = z.zip(w).map{|x, y| x * y} so you are triying to conver an array to integer. If you want, you can do something like this:
array = [1,0,1] #your binary in array form
s = array.join('') #transform it into string
s.to_i(2) #this return the integer and result (2) represents base
Check this link
And for better: array.join('').to_i(2)
Imagine you have integers split into arrays like 100 -> [1, 0, 0]
How do you write a recursive function that increments the long integer. eg incr([9, 9]) -> [1, 0, 0]?
I know how to do it non recursively.
This is a sample implementation of #Mbo's algorithm in Python:
def addOne(a, ind, carry):
if ind<0:
if carry > 0:
a.insert(0, carry)
else:
n = a[ind] + carry
a[ind] = n%10
carry = n/10
addOne(a, ind-1, carry)
n = int(raw_input("Enter a number: "))
a = []
if n == 0:
a.append(0)
while n>0:
a.append(n%10)
n = n/10
a = list(reversed(a))
print "Array", a
# performing addition operation
addOne(a,len(a)-1,1)
print "New Array", a
Note: I am sending 1 as the carry initially, because we want to add 1 to the number.
Sample Input/Output
Enter a number: 99
Array [9, 9]
New Array [1, 0, 0]
pseudocode
function Increment(A[], Index)
if Index < 0
A = Concatenation(1, A)
else
if (A[Index] < 9)
A[Index] = A[Index] + 1
else
A[Index] = 0
Increment(A, Index - 1)
call
Increment(A, A.Length - 1)
You might do with the following JS function, which is even a tail call optimized recursive one.
var arr = [7,8,9],
brr = [9,9,9];
function increment(a,r = []){
return a.length ? (a[a.length-1] + 1) % 10 ? (a[a.length-1]++,a.concat(r))
: increment(a.slice(0,a.length-1),r.concat(0))
: [1].concat(r);
}
console.log(increment(arr))
console.log(increment(brr))
Please keep in mind that for easy readability purposes i have used increment(a.slice(0,a.length-1),r.concat(0)) however best would be to do the job like increment(a.slice(0,a.length-1),(r.push(0),r)) which would boost the speed of incrementing a 10K 9 items array i.e. [9,9,...9] from ~1800msec to ~650msec. Also instead of [1].concat(r) you may choose use (r.unshift(1),r) which has a slight performance boost on FF (figures below 600msec) but may be not so in Chrome, yet more over you will not be creating a new array but pass a reference to r.
This is a follow up to the question: Overlapping sliding window over an image using blockproc or im2col?
So by using the code :
B = blockproc(A, [1 1], #block_fun, 'BorderSize', [2 2], 'TrimBorder', false, 'PadPartialBlocks', true)
I was able to create an overlapping sliding window over my image and calculate the dct2 for each window. But the problem is that blockproc concatenates the output in a way that I cannot use. The output greatly depends on the block size and the size of the output matrix is different because of it every time.
My dct2 function creates a 1 x 200 vector for every block or window. So I assumed that if there are 64 blocks I should get something like 64 x 200 or 200 x 64 output, but I get something like 64 x 1600 or in case of larger blocks I get 15 x 400.
Looking into the blockproc function the problem is caused by
% write 4 corner blocks
b(1:ul_output_size(1),1:ul_output_size(2),:) = ul_output;
if ll_processed
last_row_start = final_rows - size(ll_output,1) + 1;
last_row_width = size(ll_output,2);
b(last_row_start:end,1:last_row_width,:) = ll_output;
end
if ur_processed
last_col_start = final_cols - size(ur_output,2) + 1;
last_col_height = size(ur_output,1);
b(1:last_col_height,last_col_start:end,:) = ur_output;
end
if lr_processed
last_row_start = final_rows - size(ll_output,1) + 1;
last_col_start = final_cols - size(ur_output,2) + 1;
b(last_row_start:end,last_col_start:end,:) = lr_output;
end
Apparently, blockproc further divides the blocks into upper left, upper right, lower left and lower right and concatenates that result. And that is why I am getting all this mixed outputs.
I need the output of each block in its each row, for each window. Each window should just give me a 1x200 output, that I can feed into my classifier.
Can I force the output of blockproc in the way that I want it, just give the output of each block.
If not, I would really appreciate an alternative solution to have an overlapping sliding window over the image.
edit: would it be possible to save the blocks data using block_struct.data for every block into a cell array inside the function block_fun and then use that array to extract my features?
Thank you
edit:
B = blockproc(images_m{1}, [64 64], #(x)reshape(x.data(:),[1 1 numel(x.data)]), 'BorderSize', [10 10], 'TrimBorder', false, 'PadPartialBlocks', true, 'PadMethod', 'replicate');
imgs = {};
for i = 1:size(B,1)
for j = 1:size(B,2)
tempy = squeeze(B(i,j,:));
tempy2 = reshape(tempy, [84 84]);
feats{end+1} = block_dct2(tempy2); %calculates dct2 for the block and returns a 1*200 vector
end
end
Maybe reshape you data in the third dimension?
>> A = magic(3)
A =
8 1 6
3 5 7
4 9 2
>> B = blockproc(A, [1 1], #(x)reshape(x.data(:),[1 1 numel(x.data)]), 'BorderSize', [1 1], 'TrimBorder', false, 'PadPartialBlocks', true);
>> whos B
Name Size Bytes Class Attributes
B 3x3x9 648 double
>> squeeze(B(1,1,:))
ans =
0
0
0
0
8
3
0
1
5
>>
An alternate using MAT2CELL:
function extractFeatures
images_m{1} = rand(128);
B = blockproc(images_m{1}, [64 64], #processBlock,...
'BorderSize', [10 10], 'TrimBorder', false,...
'PadPartialBlocks', true, 'PadMethod', 'replicate');
%B is 2x400 i.e 2x2 blocks of each block being a 1x200 feature vector
m = ones(1,size(B,1));
n = 200*ones(1,size(B,2)/200);
% The MAT2CELL help does a good job, just read it carefully and run the
% examples
feats = mat2cell(B,m,n);
feats = feats(:);
end
function feature = processBlock(bstruct)
% I dont know what block_dct2 does:
%feature = block_dct2(bstruct.data);
% So I'll put in a place holder which returns a 1x200 'feature'
% for each overlapping image block
feature = repmat(mean(bstruct.data(:)), [1 200]);
end
I need help optimizing this loop. matrix_1 is a (nx 2) int matrix and matrix_2 is a (m x 2), m & n very.
index_j = 1;
for index_k = 1:size(Matrix_1,1)
for index_l = 1:size(Matrix_2,1)
M2_Index_Dist(index_j,:) = [index_l, sqrt(bsxfun(#plus,sum(Matrix_1(index_k,:).^2,2),sum(Matrix_2(index_l,:).^2,2)')-2*(Matrix_1(index_k,:)*Matrix_2(index_l,:)'))];
index_j = index_j + 1;
end
end
I need M2_Index_Dist to provide a ((n*m) x 2) matrix with the index of matrix_2 in the first column and the distance in the second column.
Output example:
M2_Index_Dist = [ 1, 5.465
2, 56.52
3, 6.21
1, 35.3
2, 56.52
3, 0
1, 43.5
2, 9.3
3, 236.1
1, 8.2
2, 56.52
3, 5.582]
Here's how to apply bsxfun with your formula (||A-B|| = sqrt(||A||^2 + ||B||^2 - 2*A*B)):
d = real(sqrt(bsxfun(#plus, dot(Matrix_1,Matrix_1,2), ...
bsxfun(#minus, dot(Matrix_2,Matrix_2,2).', 2 * Matrix_1*Matrix_2.')))).';
You can avoid the final transpose if you change your interpretation of the matrix.
Note: There shouldn't be any complex values to handle with real but it's there in case of very small differences that may lead to tiny negative numbers.
Edit: It may be faster without dot:
d = sqrt(bsxfun(#plus, sum(Matrix_1.*Matrix_1,2), ...
bsxfun(#minus, sum(Matrix_2.*Matrix_2,2)', 2 * Matrix_1*Matrix_2.'))).';
Or with just one call to bsxfun:
d = sqrt(bsxfun(#plus, sum(Matrix_1.*Matrix_1,2), sum(Matrix_2.*Matrix_2,2)') ...
- 2 * Matrix_1*Matrix_2.').';
Note: This last order of operations gives identical results to you, rather than with an error ~1e-14.
Edit 2: To replicate M2_Index_Dist:
II = ndgrid(1:size(Matrix_2,1),1:size(Matrix_2,1));
M2_Index_Dist = [II(:) d(:)];
If I understand correctly, this does what you want:
ind = repmat((1:size(Matrix_2,1)).',size(Matrix_1,1),1); %'// first column: index
d = pdist2(Matrix_2,Matrix_1); %// compute distance between each pair of rows
d = d(:); %// second column: distance
result = [ind d]; %// build result from first column and second column
As you see, this code calls pdist2 to compute the distance between every pair of rows of your matrices. By default this function uses Euclidean distance.
If you don't have pdist2 (which is part of the the Statistics Toolbox), you can replace line 2 above with bsxfun:
d = squeeze(sqrt(sum(bsxfun(#minus,Matrix_2,permute(Matrix_1, [3 2 1])).^2,2)));