C++\CLI DateTime calculation error - c++-cli

I am trying to predict the estimated completion time of a simulation. I take startTime at the start of the simulation. At the end of each cycle, I take timeNow. The time elapsed timeLapsed is calculated by subtracting these two values. The average cycle time (varies per cycle) is calculated by dividing the elapsed time by the cycle number at that time, i.e. number of cycles run until then. Then I calculate the estimated completion time estimEndTime by adding the number of cycles still to go multiplied by the average cycle time to timeNow.
I think something goes wrong in the data conversion, as the estimEndTime calculation is incorrect. Its prediction is way, way too short / soon. The average cycle time avgCycleTime is calculated at around 30-50 seconds which looks correct. Trial nr of cycles is 20.
I get one warning for the conversion of the cycle number (int i) from int64 to long with possible loss of data, but since the avgCycleTime seems ok, this does not seem to be the cause for the error.
Why doesn't this work?
Code essentials:
long avgCycleTime;
DateTime startTime = DateTime::Now;
f1->textBox9->Text = startTime.ToString("dd/MM/yy HH:mm:ss");
f1->textBox9->Update();
i = 0; // cycle counter
while (i < nCycl)
{
// this is where the simulation occurs
i++;
DateTime timeNow = DateTime::Now;
TimeSpan timeLapsed = timeNow.Subtract(startTime);
avgCycleTime = (timeLapsed.Ticks / i);
DateTime estimEndTime = timeNow.AddTicks(avgCycleTime * (nCycl-i));
f1->textBox10->Text = Convert::ToString(avgCycleTime / 10000000); // cycle time in milliseconds
f1->textBox11->Text = estimEndTime.ToString("dd/MM/yy HH:mm:ss");
f1->Refresh();
}

The problem is that you declared avgCycleTime as long - effectively Int32.
Let's assume that one cycle takes 50 seconds. In ticks it would be 50 * 10,000,000 = 500,000,000 - well fit in Int32. But then you calculate avgCycleTime * (nCycl - i) and it overflows (result will be Int32), thus you get invalid estimEndTime. So you have to declare avgCycleTime as long long or Int64.

Related

How the complexity of the following code is O(nlogn)?

for(i=1;i<=n;i=i*2)
{
for(j=1;j<=i;j++)
{
}
}
How the complexity of the following code is O(nlogn) ?
Time complexity in terms of what? If you want to know how many inner loop operations the algorithm performs, it is not O(n log n). If you want to take into account also the arithmetic operations, then see further below. If you literally are to plug in that code into a programming language, chances are the compiler will notice that your code does nothing and optimise the loop away, resulting in constant O(1) time complexity. But only based on what you've given us, I would interpret it as time complexity in terms of whatever might be inside the inner loop, not counting arithmetic operations of the loops themselves. If so:
Consider an iteration of your inner loop a constant-time operation, then we just need to count how many iterations the inner loop will make.
You will find that it will make
1 + 2 + 4 + 8 + ... + n
iterations, if n is a square number. If it is not square, it will stop a bit sooner, but this will be our upper limit.
We can write this more generally as
the sum of 2i where i ranges from 0 to log2n.
Now, if you do the math, e.g. using the formula for geometric sums, you will find that this sum equals
2n - 1.
So we have a time complexity of O(2n - 1) = O(n), if we don't take the arithmetic operations of the loops into account.
If you wish to verify this experimentally, the best way is to write code that counts how many times the inner loop runs. In javascript, you could write it like this:
function f(n) {
let c = 0;
for(i=1;i<=n;i=i*2) {
for(j=1;j<=i;j++) {
++c;
}
}
console.log(c);
}
f(2);
f(4);
f(32);
f(1024);
f(1 << 20);
If you do want to take the arithmetic operations into account, then it depends a bit on your assumptions but you can indeed get some logarithmic coefficients to account for. It depends on how you formulate the question and how you define an operation.
First, we need to estimate number of high-level operations executed for different n. In this case the inner loop is an operation that you want to count, if I understood the question right.
If it is difficult, you may automate it. I used Matlab for example code since there was no tag for specific language. Testing code will look like this:
% Reasonable amount of input elements placed in array, change it to fit your needs
x = 1:1:100;
% Plot linear function
plot(x,x,'DisplayName','O(n)', 'LineWidth', 2);
hold on;
% Plot n*log(n) function
plot(x, x.*log(x), 'DisplayName','O(nln(n))','LineWidth', 2);
hold on;
% Apply our function to each element of x
measured = arrayfun(#(v) test(v),x);
% Plot number of high level operations performed by our function for each element of x
plot(x,measured, 'DisplayName','Measured','LineWidth', 2);
legend
% Our function
function k = test(n)
% Counter for operations
k = 0;
% Outer loop, same as for(i=1;i<=n;i=i*2)
i = 1;
while i < n
% Inner loop
for j=1:1:i
% Count operations
k=k+1;
end
i = i*2;
end
end
And the result will look like
Our complexity is worse than linear but not worse than O(nlogn), so we choose O(nlogn) as an upper bound.
Furthermore the upper bound should be:
O(n*log2(n))
The worst case is n being in 2^x. x€real numbers
The inner loop is evaluated n times, the outer loop log2 (logarithm basis 2) times.

Long time execution of simple SQL script

When I run below script, the query runs about for 30 seconds but when it finishes then I can get information that elapsed time is equal to 0.1 seconds and compute time is 2ms.
Could you tell me what is the reason why this query is running 30 seconds even though I do not use any table?
declare heads bool;
declare heads_in_a_row int64 default 0; #number of heads in a row
declare nb_of_throws int64 default 0; #number of throws
#How many throws I need to get a 8 heads in a row?
while heads_in_a_row <= 8 DO
set heads = RAND() < 0.5;
set nb_of_throws = nb_of_throws +1;
if heads then
set heads_in_a_row = heads_in_a_row + 1 ;
else
set heads_in_a_row = 0;
end if;
end while;
select nb_of_throws;
This will sometimes be fast and sometimes be slow, it depends on random chance to get to the point of having 8 heads in a row. Try 50 heads in a row, you'll see its much slower, 2 heads in a row will be faster. The 0.1s elapsed time you are seeing is the elapsed time only for the final section of the script which is the select statement which just pulls your stored variable value and is nearly instant.
What is your answer? I have run it a few times and got results in the hundreds and thousands of 'throws'. The odds of getting 8 heads in a row is .39%, so not very likely. BQ (and databases in general) are optimized for set-based and column-based computation, not loop-based operations. Using BQ for this problem is likely not your best option, python would be much faster for example.

Riemann Sum Estimation

I'm trying to calculate the value of n that solves the problem below. I am not exactly sure where I am messing up. I tried using a do while loop also, but I am having trouble figuring out the logic error. Could anyone assist?
If S = √ (6*( 1+1/2^2+1/3^2 +1/4^2 + 1/5^2 + ... ) ) = (pi^2)/6, after how many terms will the sum be equal to PI to 6 decimal places. PI to 6 decimal places is 3.141592. The relevant part of my code is shown below:
double s = 0;
for(int n=1;abs(sqrt(6*s) - 3.141592) >= pow(10,-6);n++) {
s += (1/(pow(n,2)));
NSLog(#"%i",n);
}
int abs(int i)
computes the absolute value of an integer. Therefore in
abs(sqrt(6*s) - 3.141592)
the floating point number sqrt(6*s) - 3.141592 is converted to an int
first, which gives zero as soon as the absolute value of this number is less than one.
You want to use fabs() instead.

Convert float representing hours to integer hours and minutes

I'm using the standard equation of distance / speed = arrival time. This works fine, but the answer is a float number and most people would find it awkward to convert something like 1.75 hrs to be 1 hr and 45 minutes.
I want to take that final float number result and extract the hour(s) separately from the minutes as integers.
Here is what I've tried:
-(IBAction)calculate:(id)sender {
float spd=[speed.text floatValue];
float dist=[distKnots.text floatValue];
//this give me the answer as a float
float arr=(dist/bs);
//this is how I showed it as an answer
//Here I need to convert "arr" and extract the hours & minutes as whole integers
arrivalTime.text=[NSString stringWithFormat:#"%0.02f", arr];
[speed resignFirstResponder];
}
And this is the conversion I tried to do -- and on paper it works, but in code it's full of errors:
int justHours = arr*60;
int justMinutes = (arr*60)-(justHours*60);
//then for the user friendly answer:
arrivalTime.text=[NSString stringWithFormat:#"%n hours and %n minutes", justHours, justMinutes];
I'm new to Objective-C and hoping there is a way to get this to work or a better way altogether to resolve this.
Your arr variable is already measured in hours, so you shouldn't be scaling it, just rounding it down:
int justHours = (int)arr;
and then your minutes is sixty times the (integer) difference between the original and rounded hours (i.e. the fractional part).
int justMinutes = (int)((arr - justHours) * 60);
The int justHours = arr/60; seems to be incorrect, it should be int justHours = arr;.
check the NSNumber numberFormater class. I believe you can wrap your float with time format and the return it to the user.

Time to turn 180 degrees

I have a space ship, and am wanting to calculate how long it takes to turn 180 degrees. This is my current code to turn the ship:
.msngFacingDegrees = .msngFacingDegrees + .ROTATION_RATE * TV.TimeElapsed
My current .ROTATION_RATE is 0.15, but it will change.
I have tried:
Math.Ceiling(.ROTATION_RATE * TV.TimeElapsed / 180)
But always get an answer of 1. Please help.
To explain why you get 1 all the time:
Math.Ceiling simply rounds up to the next integer, so your sum contents must always be < 1.
Rearranging your sum gives TV.TimeElapsed = 180 * (1/.ROTATION_Rate). With a ROTATION_Rate of 0.15 we know that TV.TimeElapsed needs to reach 1200 before your overall function returns > 1.
Is it possible that you're always looking at elapsed times less than this threshold?
Going further to suggest what your sum should be is harder - Its not completely clear without more context.