Matlab Code summing terms of array - arrays

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);

Related

compressed sparse row and Jacobi iterative method

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.

How can i get the Big O Notations in this while loop?

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).

Convert c code to haskell code using recursion instead of loops (no lists)

I want to convert the following c code to haskell code, without using lists. It returns the number of occurrences of two numbers for a given n , where n satisfies n=(a*a)*(b*b*b).
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main(void) {
int n = 46656;
int i,j,counter=0,res=1;
int tr = sqrt(n);
for(i=1; i<=tr; i++) {
for(j=1; j<=tr; j++) {
res = (i*i) * (j*j*j) ;
if(res==n) {
counter=counter+1;
}
printf("%d\n",res);
}
}
printf("%d\n",counter);
}
I've managed to do something similar in haskell in regarding to loops, but only for finding the overall sum. I find difficult implementing the if part and counter part(see on c code) in haskell also. Any help much appreciated! Heres my haskell code also:
sumF :: (Int->Int)->Int->Int
sumF f 0 = 0
sumF f n = sumF f (n-1) + f n
sumF1n1n :: (Int->Int->Int)->Int->Int
sumF1n1n f 0 = 0
sumF1n1n f n = sumF1n1n f (n-1)
+sumF (\i -> f i n) (n-1)
+sumF (\j -> f n j) (n-1)
+f n n
func :: Int->Int->Int
func 0 0 = 0
func a b = res
where
res = (a^2 * b^3)
call :: Int->Int
call n = sumF1n1n func n
I guess an idiomatic translation would look like this:
n = 46656
tr = sqrt n
counter = length
[ ()
| i <- [1..tr]
, j <- [1..tr]
, i*i*j*j*j == n
]
Not that it isn't possible, but definitely not the best looking:
counter n = go (sqrt n) (sqrt n)
where
go 0 _ = 0
go i tr = (go2 tr 0 i) + (go (i - 1) tr)
go2 0 c i = c
go2 j c i = go2 (j - 1) (if i^2 * j^3 == n then c + 1 else c) i
A general and relatively straightforward way to translate imperative code is to replace each basic block with a function, and give it a parameter for every piece of state it uses. If it’s a loop, it will repeatedly tail-call itself with different values of those parameters. If you don’t care about printing the intermediate results, this translates straightforwardly:
The main program prints the result of the outer loop, which begins with i = 1 and counter = 0.
main = print (outer 1 0)
where
These are constants, so we can just bind them outside the loops:
n = 46656
tr = floor (sqrt n)
The outer loop tail-calls itself with increasing i, and counter updated by the inner loop, until i > tr, then it returns the final counter.
outer i counter
| i <= tr = outer (i + 1) (inner 1 counter)
| otherwise = counter
where
The inner loop tail-calls itself with increasing j, and its counter (counter') incremented when i^2 * j^3 == n, until j > tr, then it returns the updated counter back to outer. Note that this is inside the where clause of outer because it uses i to calculate res—you could alternatively make i an additional parameter.
inner j counter'
| j <= tr = inner (j + 1) $ let
res = i ^ 2 * j ^ 3
in if res == n then counter' + 1 else counter'
| otherwise = counter'

Find a run of five or more consecutive zeros in Matlab

This is the code that I had tried to find the consecutive zero which are in the order of 5 or more.
a=[0,0,0,0,0,0,0,0,9,8,5,6,0,0,0,0,0,0,3,4,6,8,0,0,9,8,4,0,0,7,8,9,5,0,0,0,0,0,8,9,0,5,8,7,0,0,0,0,0];
[x,y]=size(a);
for i=0:y
i+1;
k=1;
l=0;
n=i;
count=0;
while (a==0)
count+1;
break;
n+1;
end
if(count>=5)
v([]);
for l=k:l<n
v(m)=l+1;
m+1;
end
end
count=1;
i=n;
end
for i = o : i<m
i+1;
fprintf('index of continous zero more than 5 or equal=%d',v(i));
end
If you want to find the starting indices of runs of n or more zeros:
v = find(conv(double(a==0),ones(1,n),'valid')==n); %// find n zeros
v = v([true diff(v)>n]); %// remove similar indices, indicating n+1, n+2... zeros
In your example, this gives
v =
1 13 34 45
One-liner strfind approach to find the starting indices of 5 consecutive zeros -
out = strfind(['0' num2str(a==0,'%1d')],'011111')
Output -
out =
1 13 34 45
The above code could be generalised like this -
n = 5 %// number of consecutive matches
match = 0 %// match to be used
out = strfind(['0' num2str(a==match,'%1d')],['0' repmat('1',1,n)]) %// starting indices of n consecutive matches
If you are looking to find all the indices where the n consecutive matches were found, you can add this code -
outb = strfind([num2str(a==match,'%1d'),'0'],[repmat('1',1,n) '0'])+n-1
allind = find(any(bsxfun(#ge,1:numel(a),out') & bsxfun(#le,1:numel(a),outb')))
If you want to find the general case of a "run of n or more values x in vector V", you could do the following:
% your particular case:
n = 5;
x = 0;
V = [0,0,0,0,0,0,0,0,9,8,5,6,0,0,0,0, ...
0,0,3,4,6,8,0,0,9,8,4,0,0,7,8,9, ...
5,0,0,0,0,0,8,9,0,5,8,7,0,0,0,0,0];
b = (V == x); % create boolean array: ones and zeros
d = diff( [0 b 0] ); % turn the start and end of a run into +1 and -1
startRun = find( d==1 );
endRun = find( d==-1 );
runlength = endRun - startRun;
answer = find(runlength > n);
runs = runlength(answer);
disp([answer(:) runs(:)]);
This will display the start of the run, and its length, for all runs > n of value x.

multiple vector manipulations in Matlab

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

Resources