Time complexity Analysis for loop: - amortized-analysis

why is the time complexity, O(n) instead of O(nlogn)? Wouldn't you have to multiply the complexity of outer loop with that of inner loop?
int fun(int n){
int count = 0;
for (int i = n; i > 0; i /= 2)
for (int j = 0; j < i; j++)
count += 1;
return count;
}

In the first iteration of the loop the inner loop covers half of n. The next iteration covers a quarter, then an eighth, and so forth. You can represent the coefficients by the function below. As you can see it's an infinite series that sums to one. Thus the entire function is O(n)

Related

Bit slicing with variable width in SystemVerilog

I am trying to access certain sections of an array using the +: operator however getting the infamous [variable] is not a constant error. The only problem is, the width I would like the get from the array is changing as well.
This is the loop I have:
logic [N-1:0] a;
logic [2**N-2:0] b;
for (i = 0; i < N; i++)
a[i] = b[(2**i)-1 +: 2**i] == {(2**i){1'b1}};
In other words, if N = 4, I want this loop to do this:
a[0] = b[0:0] == 1'b1;
a[1] = b[2:1] == 2'b11;
a[2] = b[6:3] == 4'b1111;
a[3] = b[14:7] == 8'b11111111;
Logically, I'm pretty certain that the loop I provided works however SystemVerilog doesn't allow non-constants to be used for setting the width (after the a:).
How can I utilize the +: operator when my starting index and width are both dependent on a non-constant variable? or is there another way of doing this considering that N can be a large number.
Thanks!
EDIT:
This can be done with shifts, here is a working code:
for (i = 0; i < N; i++)
a[i] <= ((b >> (2**i)-1) << ((2**N) - (2**i) - 1)) ==
{(2**N-1){1'b1}} << ((2**N) - (2**i) - 1);
You cannot use +: with variable widths. It is actually just a short-hand for shifts and masks. For example, something like the following should work in your case:
logic [N-1:0] a;
logic [2**N-2:0] b;
always_comb begin
for (int i = 0; i < N; i++) begin
logic [2**N-2:0] tmpb, tmp1;
tmpb = b >> ((2**i)+1);
tmp1 = ((2**N)'(1) << (2**i)) - 1;
a[i] = (tmpb & tmp1) == 0;
end
end
you just need to figure out exact numbers of shifts and widths.
You can use a combination of '+:` operator with a mask
parameter N = 8; localparam N2 = 2**(N-1);
logic [N-1:0] a;
logic [2**N-1:0] b;
initial begin
b ={8'b000001,4'b1111,2'b01,1'b1};
for (int i = 0; i < N; i++)
a[i] = (b[(2**i)-1 +: N2] | ~N2'((1 << 2**i)- 1)) == '1;
$displayb(a,,b);
end
You can use +: provided that the right hand side is a constant or genvar.
logic [N-1:0] a;
logic [2**N-2:0] b;
for (genvar i = 0; i < N; i++) begin : gen_a
assign a[i] = b[(2**i)-1 +: 2**i] == {(2**i){1'b1}};
end
Note that this for-loop is a generate-for-loop which is not within a procedural block (ie begin-end)

how to implement Softmax function for neural networks in processing 3 environment?

I tried programming a neural network in processing IDE.
I managed to do it quite well, until I tried using the MNIST handwritten digits data set. I tried the iris data set and few others from UCI machine learning repository, but when I used the MNIST data set it didn't worked. for some reason all of the outputs approached zero with time, and that caused the total error to be always equal to 1. I am almost sure that my problem is the activation function; so I tried using softmax for classification, but it wasn't very successful. I got the same results. I think maybe I should have use a different loss function, so I tried the negative log probability according to this video. the results now are the same cost value for each output neuron, and the sum of the outputs is not 1 as it should be.
Here are the functions for each part of the code that I have changed (I prefer not to share the full code because it's long and messy, and not really helpful):
softmax:
float[] softmax(float[] inputVector){
float[] result = new float[inputVector.length];
float sigma = 0;
for(int i = 0; i < inputVector.length; i++){
sigma += exp(inputVector[i]);
}
for(int i = 0; i < result.length; i++){
result[i] = exp(inputVector[i]) / sigma;
}
return result;
}
derivative of softmax:
float[] derivativeSoftmax(float[] inputVector){
float[] result = new float[inputVector.length];
for(int i = 0; i < result.length; i++){
result[i] = softmax(inputVector)[i] * (1 - softmax(inputVector)[i]);
}
return result;
}
loss function:
for(int i = 0; i < outputNeuronsNumber; i++){
float tempSigma = 0;
for(int j = 0; j < outputNeuronsNumber; j++){
tempSigma += target[diffCounter2] * log(outputLayer[j]);
}
cost[i] = -tempSigma;
}
I can't see what is the problem with my code.
float[] derivativeSoftmax(float[] inputVector){
float[] result = new float[inputVector.length];
for(int i = 0; i < result.length; i++){
result[i] = softmax(inputVector)[i] * (1 - softmax(inputVector)[i]);
}
return result;
}
I believe this is wrong, given the derivative of the softmax as defined on wikipedia.
float[] derivativeSoftmax(float[] inputVector, int k){
float[] result = new float[inputVector.length];
for(int i = 0; i < result.length; i++){
result[i] = softmax(inputVector)[i] * ((i==k ? 1 : 0) - softmax(inputVector)[k]);
}
return result;
}
You should be taking the derivative at an index with respect to some other index. The equation as you have it, which is x*(1-x) doesn't make a lot of sense. But I may be wrong.

Smallest integer greater than or equal to harmonic series of input

I'm working on the following problem:
I realize my code is a bit off, but I want to create a for loop that will determine whether or not the integer x (the input value) is at least less than or equal to the sum of a harmonic series.
Here is what I have so far:
function n =one_per_n(x)
if x > 10000
n = -1;
end
total = 0;
i = 0;
for i = 1:10000
if x >= total
n = ceil(total);
else
total = (1/i) + total;
end
end
I've added my attempt at a while loop. I realize it's wrong, but any help would be appreciated.
function n =one_per_n(x)
if x > 10000
n = -1;
end
total = 0;
i = 0;
for i = 1:10000
while total <= x
total = (1/i) + total;
end
end
n = total;
you don't need to use some loops:
function n = one_per_n(x)
lim = min(10000,exp(x));
value = cumsum(1./(1:lim));
n = find(value >= x,1);
if isempty(n)
n = -1;
end
A while loop is a better option in this case I think
function [total, n] = one_per_n(x)
% This is a good initial check, good work
if x > 10000
n = -1;
return;
end
% Initialize the variables
total = 0;
n = 0;
% While not finished
while (total < x)
% Number of terms
n = n + 1;
total = total + 1/n;
end
end

How to count maximum number of recurring elements? [duplicate]

This question already has answers here:
Series of consecutive numbers (different lengths)
(3 answers)
Closed 8 years ago.
Grid_outage(:,1) = 1;
Grid_outage(:,2) = 1;
Grid_outage(:,3) = 1;
Grid_outage(:,4) = 0;
Grid_outage(:,5) = 0;
Grid_outage(:,6) = 0;
Grid_outage(:,7) = 0;
Grid_outage(:,8) = 0;
Grid_outage(:,9) = 0;
Grid_outage(:,10) = 0;
Grid_outage(:,11) = 0;
Grid_outage(:,12) = 1;
Grid_outage(:,13) = 0;
Grid_outage(:,14) = 1;
Grid_outage(:,15) = 0;
Grid_outage(:,16) = 0;
Grid_outage(:,17) = 1;
Grid_outage(:,18) = 0;
Grid_outage(:,19) = 1;
Grid_outage(:,20) = 0;
Grid_outage(:,21) = 0;
Grid_outage(:,22) = 0;
Grid_outage(:,23) = 1;
Grid_outage(:,24) = 0;
I would like to count the maximum number of Zeros that occur in a sequence, for e.g. I would like that above result be 8 which shows the maximum number of zeros that occur together, rather than the total number of zeros which is 16.
How do I code that in matlab
For the purpose of transparency a very simple algoritm.
Assume you can put your sequence in a vector X:
% Create X containing some zeros.
X = round(rand(30,1));
% Use a counter to count the number of sequential zeros.
count = 0;
% Use a variable to keep the maximum.
max_count = 0;
% Loop over every element
for ii=1:length(X);
% If a zero is encountered increase the counter
if(X(ii)==0)
count=count+1;
% If no zero is encountered check if the number of zeros in the last sequence was largest.
elseif count>max_count
max_count=count;
count=0;
% Else just reset the counter
else
count=0;
end
end
% Check if the last number of the vector exceeded the largest sequence.
if(count>max_count)
max_count=count;
end
EDIT: Dan's solution is more efficient starting from approximately ~200 elements.
max(diff(find(diff(Grid_outage))))
Find where a sequence of consecutive numbers changes using diff
Get the actual index numbers of where this happens using find
Use diff again to count the number of elements between each "transition"
Finally call max to get the largest sequence of consecutive numbers.
Note that you might have trouble if the largest sequence occurs at the edges, in this case I suggest that you first prepend and append an inverted bit to your matrix like this: [1-Grid_outage(1), Grid_outage, 1-Grid_outage(end)];
In order to find how many times the parameter x occurs together in a sequence, you can use:
if a(:) == x
result = length(a); % Whole vector has the x parameter
else
result = max(find(a~=x,1,'first') - 1, length(a) - find(a~=x,1,'last')); % Maximum difference in the edge
if ~isempty(max(diff(find(a~=x))) - 1)
if isempty(result)
result = max(diff(find(a~=x))) - 1; % Maximum difference in the body
elseif result < max(diff(find(a~=x))) - 1
result = max(diff(find(a~=x))) - 1; % Maximum difference in the body
end;
end;
end;

loop unrolling for matrix multiplication

I need to make a good implementation for matrix multiplication better than the naive method
here is the methods i used :
1- removed false dependencies which made the performance a lot better
2- used a recursive approach
and then there is something i need to try loop unrolling. The thing is each time i used it , it makes the performance worst i can't find an explanation for it
i need help here is the code
for (i = 0; i < M; i++)
for (j = 0; j < N; j++) {
double sum = 0;
#pragma unroll(5)
for (k = 0; k < K; k++)
{
sum += A[i + k*LDA] * B[k + j*LDB];
}
C[i + j*LDC] = sum ;
}