Suppose there have N vectors X_1, X_2, ..., X_N of length k each. We want all possible sums X_1(i1) + X_2(i2) + ... + X_N(iN), where i1, i2, ..., iN range from 1...k. There are k^N such sums. Is there any other way of doing it in Matlab using the built in functions, other than having N for-loops like below:
counter = 1;
for i1=1:k
for i2=1:k
.
.
.
for iN=1:k
res(counter) = X_1(i1) + X_2(i2) + ... + X_N(iN);
counter = counter + 1;
end
.
.
.
end
end
Also, this code needs to be hard-coded for the value of N, as we need N for-loops. How do we code it for any general value of N ?
A single loop of N iterations should be enough. (here it's unrolled)
sums=zeros(1,k^N);
id = 1:k^N;
i = mod(id, k)+1; id=(id-i) / k;
sums = sums + X_1(i);
i = mod(id, k)+1; id=(id-i) / k;
sums = sums + X_2(i);
...
i = mod(id, k)+1; id=(id-i) / k;
sums = sums + X_N(i);
The answer is to use ndgrid.
[s{1:N}] = ndgrid(-K:K);
res = zeros(k^N,1);
for i=1:N
res = res + s{i}(:)
end
Related
I've tried implementing Jacobi method for compressed sparse row format. But i couldnt obtain the output correctly. Below is the coding i tried. I'm trying with a 4 by 4 sparse matrix which is a tridiagonal matrix stored in compressed form before implementing Jacobi iterative method. Please help.
clear all;
close all;
clc;
H=4;
a=2;
b=-1;
c=-1;
A = diag(a*ones(1,H)) + diag(b*ones(1,H-1),1) + diag(c*ones(1,H-1),-1);%Matrix A
n = size(A,1); % no of rows
m = size(A,2); % no of columns
V = [];
C = [];
R = [];
counter=1;
R= [counter];
for i=1:n
for j=1:m
if (A(i,j) ~= 0)
V = [V A(i,j)];
C = [C j];
counter=counter+1;
end
R(i+1)=counter;
end
end
b = [9,18,24,3];
x_new = [1 ; 1 ; 1 ; 1];
eps = 1e-5; % 1 x 10^(-10).
error = 1000; % use any large value greater than eps to make sure that the loop can work
counter2=1;
while (error > eps)
x_old = x_new;
for i=1:length(R)-1 %modified
t = 0;
for j=R(i):R(i+1)-1 %modified
if (C(j)~=i) %not equal
t = t + x_old(C(j))*A(i,C(j)); %modified
end
end
x_new(i,1) = (b(i) - t)/A(i,C(j)); % is a row vector
end
error = norm(x_new-x_old);
counter2=counter2+1;
end
x_new % print x
Expected output is
[28.1987 47.3978 48.5979 25.7986]
this is the coding i tried and the expected output is above. Thank you for your time and consideration.
The computational cost will only consider how many times c = c+1; is executed.
I want to represent the Big O notation to use n.
count = 0; index = 0; c = 0;
while (index <= n) {
count = count + 1;
index = index + count;
c = c + 1;
}
I think if the "iteration of count" is k and "iteration of index" is n, then k(k+1)/2 = n.
So, I think O(root(n)) is the answer.
Is that right solution about this question?
Is that right solution about this question?
This is easy to test. The value of c when your while loop has finished will be the number of times the loop has run (and, thus, the number of times the c = c + 1; statement is executed). So, let us examine the values of c, for various n, and see how they differ from the posited O(√n) complexity:
#include <stdio.h>
#include <math.h>
int main()
{
printf(" c root(n) ratio\n"); // rubric
for (int i = 1; i < 10; ++i) {
int n = 10000000 * i;
int count = 0;
int index = 0;
int c = 0;
while (index < n) {
count = count + 1;
index = index + count;
c = c + 1;
}
double d = sqrt(n);
printf("%5d %8.3lf %8.5lf\n", c, d, c / d);
}
return 0;
}
Output:
c root(n) ratio
4472 3162.278 1.41417
6325 4472.136 1.41431
7746 5477.226 1.41422
8944 6324.555 1.41417
10000 7071.068 1.41421
10954 7745.967 1.41416
11832 8366.600 1.41419
12649 8944.272 1.41420
13416 9486.833 1.41417
We can see that, even though there are some 'rounding' errors, the last column appears reasonably constant (and, as it happens, an approximation to √2, which will generally improve as n becomes larger) – thus, as we ignore constant coefficients in Big-O notation, the complexity is, as you predicted, O(√n).
Let's first see how index changes for each loop iteration:
index = 0 + 1 = 1
index = 0 + 1 + 2 = 3
index = 0 + 1 + 2 + 3 = 6
...
index = 0 + 1 + ... + i-1 + i = O(i^2)
Then we need to figure out how many times the loop runs, which is equivalent of isolating i in the equation:
i^2 = n =>
i = sqrt(n)
So your algorithm runs in O(sqrt(n)) which also can be written as O(n^0.5).
I have a code that is supposed to do the following:
The first function called on, named CalcNum1.m, will find the sum of all the
values in any sized array using a for loop instead of the sum function. This sum divided
by 2 will be saved to the variable Num1.
Finally, in the second function named PrintTerms.m, reorder your terms using the
built in sort function. Now, find how many terms (starting with the first and the
smallest), when adding upon one another, are necessary to surpass the value of Num1.
Print to the user how many terms are necessary.
Here is my code for the main script:
B = input ('Enter matrix B');
[Num1,sum] = CalcNum1(B);
[Q] = PrintTerms(B, Num1);
And here is my code for the functions
function [sum, Num1] = CalcNum1(B)
n = numel(B);
sum1 =0;
for i = 1:n
sum1 = sum1 + B(i);
end
sum = sum1;
Num1 = sum/2;
end
function [Q] = PrintTerms( B, Num1 )
sort (B)
sum1 = 0;
i = 0;
count = 0;
while sum1<=Num1
i = i+1
sum1 = sum1 + B(i)
count = count+1
end
Q = count;
sum1
fprintf(' This many terms necessary %.2f',Q)
end
Try:
function [Num1, my_sum] = CalcNum1(B)
n = numel(B);
my_sum =0;
for i = 1:n
my_sum = my_sum + B(i);
end
Num1 = my_sum/2;
end
Note that I switched the output order, as you call it [Num1,sum] =
function count = PrintTerms( B, Num1 ) % No need for brackets when only single output
B = sort(B); % Need to save it in a new (or the same variable)
% sort(B) will only print the sorted vector
my_sum = 0;
ii = 0;
count = 0;
while my_sum <= Num1
ii = ii+1; % Use semicolons to supress output
my_sum = my_sum + B(ii);
count = count + 1; % Use space for better readability
end
fprintf(' This many terms necessary %.2f \n', count)
% Include \n to get a line shift
end
Use brackets when you type in B, like this: [1 2 3 4 2 3 4 23 12 32 12 2 3 6]
If you want it simpler, you could also use cumsum and avoid the loops. This is your entire last function (except the print part):
vec_sum = cumsum(sort(B)); % See documentation for explanation
count = find(vec_sum >= Num1,1) ; % the second input 1, is to only include the
% first element larger than Num1
Your PrintTerms function seems to work well. As possible problem is that, asuming Num1 is an arbitrary value, if it's so large that it's not reached even with all elements of B, you will try to pull a non-existent further element from B. To avoid that you can add a condition with if and a flag result to indicate whether you had success or not:
% [...]
success = 1; % for now
while (sum1 <= Num1)
ii = ii+1; % Use semicolons to supress output
if ii>length(B)
success = 0; % we ran out of terms
break; % exit while loop
end
sum1 = sum1 + B(ii);
count = count + 1; % Use space for better readability
end
if success
fprintf(' This many terms necessary %.2f', count)
else
fprintf(' The sum cannot be reached')
end
Also, note that sort(B) does not store the result. Use B = sort(B);
As I wrote in my previous topic: Benchmarking code - am I doing it right? I need to find a way to get benchmark statistics, like average, mean, standard deviation, etc. How can I do this using those methods I posted? Notice that I use a solution to benchmark code with time interval, not by calling a function many times. Any ideas?
I came up with just one, dont know if its correct (pseudocode):
buffsize = 1024;
buffer [buffsize];
totalcycles = 0
// arrays
walltimeresults = []
cputimeresults = []
// benchmarking
for i in (0, iterations):
start = walltime();
fun2measure(args, buffer);
end = walltime();
walltimeresults[i] = end - start;
start = cputime();
fun2measure(args, buffer);
end = cputime();
cputimeresults[i] = end - start;
c1 = cyclecount();
fun2measure(args, buffer);
c2 = cyclecount();
cyclesperbyte = c2-c1/(buffsize);
totalcycles += cyclesperbyte;
for i in range (0, iterations) : sum += walltimeresults[i];
avg_wall_time = sum / iterations;
sum = 0;
for i in range (0, iterations) : sum += cputimeresults[i];
avg_cpu_time = sum / iterations;
avg_cycles = totalcycles / iterations;
Is it correct? How about mean, standard deviation, etc?
Your average looks OK.
Mean (i.e. average) is
mean = 1/N * sum( x[i] )
Standard deviation is square root of variance:
sigma = sqrt( 1/N * sum( (x[i]-mean)^2 )
I know how to simulate a 2d array in a linear array using [x + y * width] as a linear index.
I can extend this to 3d arrays: [x + y * width + z * width * height].
Is there a general formula for N-dimensional array?
I'm looking for a language-agnostic answer.
Sure. Just extending your example gives x + y*width + z*width*height + w*width*height*depth + ...
In other words, dim1 + dim2*size1 + dim3*size1*size2 + dim4*size1*size2*size3 + ...
Eh, if you want some code... :-) C is language-agnostic enough, ya?
Assume input: location[dimensions]
Assume a table exists maxBound[dimensions] that contains the maximum boundaries of each dimension of the table.
int index = 0;
int multiplier = 1;
for (int i = 0;i < dimensions;i++)
{
index += location[i] * multiplier;
multiplier *= maxBound[i];
}
Your index will end up in the index field.
Test:
location = [3,4,5]
maxBound = [10,20,30]
loop initial: index = 0, multiplier = 1.
loop i=0: index = 3, multiplier = 10.
loop i=1: index = 43, multiplier = 200.
loop i=2: index = 1043, multipler = 6000.
I think this makes sense, but this is just coming out of the top of my head.