Increase value over time using mathematical algorithm - c#

I am writing a test tool which places a large amount of load on a network service. I would like this tool to start with little load and gradually increase over time. I am sure that there is some triganometry which can do this sort of calculation in one line of code but I am not a math guru (yet). Is there some sort of library (or simple algorithm) which can help with this calculation?
The code would ideally take a few arguments:
algorithm to use (determine how quickly the value increases
starting value
ending value (maximum)
time (amount of time between starting and ending value)
step (granularity in milliseconds)
So every [step] an event would be raised indicating what the value is at that point in time.
This is an ideal implementation though, so I am open to suggestion.
Any input would be greatly appreciated, thank you :)
EDIT:
Let me be more clear ... the amount which the value increases is not linear, it is a curve.

If you desire some form of saturation (see Sigmoid function), have a look at my answer here. Another common function shape would be linear or exponential growth. Just let me know if you need one of the later.

I think what you need is some easing function.
There is a set of famous easing functions created by Robert Penner. You may try to look at:
Tweener transition cheat sheets which visualize Robert Penner's equations.
Robert Penner's original code should be at his webpage.

value = (endValue - StartValue) / (time / stepSize) * currentStep;

heck just add one each time the timer goes off

If I understood correctly, why not do this (using the "variables" you defined):
You need to progress overall ending value - starting value values.
Using the time variable, you can figure out how much of an increase you want every millisecond (let's call this increase-amount).
Step just tells you how much time to "sleep" between each value you raise. Every time a new value is raised, you just do last-value + (milliseconds-since-last_step * increase-amount).
Note: I'm not sure why you need the first variable (algorithm to use), since it seems to me that its role is defined by the other variables.

Are you looking for something like this ? (in python, sorry, my C# is rusted at best)
Given you have a curve f that takes values from 0 to 1:
def my_stepper(f, start, end, time, step_size, current_step):
x = current_step * step_size / time
f_1 = f(1)
f_0 = f(0)
y = start + (end - start) * (f(x)- f_0) / (f_1 - f_0)
return y
for i in xrange(11):
# increment increases over time
print 'exp', my_stepper(math.exp, 100., 200., 10., 1., i)
# increment decreases over time
print 'log', my_stepper(lambda x: math.log(1+x), 100., 200., 10., 1., i)

Pseduo logic to your problem:
let the function be F(a+b*x) for given step x,
let the starting value is start,
let the ending value is end
let the starting time is 0 and final time is time
and InverseF is the inverse function of F.
when x=0, F(a)=start Hence a= InverseF(start)
when x=time, F(a+b*time)=end, Hence b=(InverseF(end)-a)/time which reduces to b= (inverseF(end)-inverseF(start))/time
Finaly for any x=step,
value is F(a+b*step) which is
nothing but
F( inverseF(start)+ (inverseF(end)-inverseF(start))/time * step )
is the answer.
For example if
F(x) is liner ie) f(x)=x
value = start+(end-start)/time*step
if F(x) is x*x, then
value = ( sqrt(start) + (sqrt(end)-sqrt(start))/time * step) * ( sqrt(start) + (sqrt(end)-sqrt(start))/time * step)
if F(x) is exp(x) then
value = Exp ( log(start) + (log(end)-log(start))/time*step )
if F(x) is log(x) then
value = Log( (exp(start) + (exp(end)-exp(start))/time*step )
and so on..
another approach without using inverse function is explained below.
let the function be a+b*F(x) for given step x,
let the starting value is start,
let the ending value is end
let the starting time is 0 and final time is time
then a+ b * F(0) = start and a + b * F(time) = end, on solving a & b,
you will get
value = start + (end-start) / (F(time)-F(0) ) * (F(x)-F(0) )
and for a step x,
value = start + (end-start) / (F(time)-F(0) ) * (F(step)-F(0) )
and I hope, any one of the above will solve your problem..

I'll reuse my answer to another question. The functions given for that answer will not spend much time doing low load, but quickly go to medium-heavy load and then increase load slower to reach maximum. If you need more values on the in the middle of the possible loads, or more values in the low load - just pass appropriate distribution function.
Given your input parameters I would call it like this:
Spread(startingValue, endingValue, time/step, x => 1-(1-x)*(1-x))
Sample algorithm functions:
FocusOnHighLoad = x => 1-(1-x)*(1-x)
FocusOnLowLoad = x => x * x
FocusOnMediumLoad = x => (1 + Math.Pow(x * 2 - 1, 3)) / 2
Sample output:
foreach (double load in Spread(50, 1000, 9, FocusOnHighLoad))
Console.WriteLine("Working with {0} load", load);
Working with 50 load
Working with 272.65625 load
Working with 465.625 load
Working with 628.90625 load
Working with 762.5 load
Working with 866.40625 load
Working with 940.625 load
Working with 985.15625 load
Working with 1000 load

Related

Can anyone Solve for x with c#? floor(x * 1.04) = 258

I'm adding the floor of 4% to an int in this example 249. It will be a different int every time though.
here is my code for that which works fine.
int qty = 249;
qty += Convert.ToInt32(Math.Floor((double)qty * 0.04));
but the problem that comes up is after this sometime later in the program and after I no longer have the original value I need to revert back to the old value using the new value. I cant just subtract 4% because although it works sometimes a lot of the time it is inaccurate. The closest I came to is this
double d = Math.Round((double)qty * 0.036);
qty = Convert.ToInt32((double)qty - d);
which is accurate most of the time with smaller numbers, but not all the time.
I did come up with an equation that should work if I could solve for x and get a whole number but so far I am stumped on how to solve for x. Here is the equation I came up with solve for x, floor(x*1.04) = 258 . Can anyone solve that and have it give me a whole number or does anyone have a better idea on how to do this without storing the old value anywhere?
I am well aware that I could store the old value but if it is easily reversible with a simple math problem then I see no reason to store it. Also this will be done on a large list of items so it wouldn't just be storing one original value it would be thousands.
This comment from #MarkDickinson was the answer I was looking for:
The mapping is injective, so it is reversible. Mathematically, you can
always recover the original quantity by using floor((qty + 1.0) /
1.04). Numerically, it's possible that there are some corner cases that might cause issues, but I didn't discover any for qty up to
10**6.

Recursive function to calculate time of a hierarchy

I'm having problem with a recursive function for calculating the time of an hierarchy. Every item in the hierarchy have list of its subordinates and what I'll like to do is getting the time sum of all the step below when calling the function. The problem is that I have a time driver that the time should be multiplied by. Say for instance that the last step in the hierarchy have the time driver 2 and the step above it the time driver 4, the third step from the bottom should then get the time for 4 of those steps under which each one contains 2 of the first step. Hope you get the idea.
public double getIdealTime(double sum, bool first)
{
if (first)
{
sum += this.idealTime;
first = false;
}
else
{
sum += this.idealTime * this.timeDriverNumber;
}
foreach (var prodel in this.subordinates)
{
sum = prodel.getIdealTime(sum, first);
}
return sum;
}
The "first" true and false is just a solution to not get the time of all the steps (the time x the time drivers) for the actual step but for only one of that instance.
The problem is that the function doesn't give me the right output value. I'm not sure why, but it feels like the function goes "top to bottom" instead of "bottom to top". That is, since one usually only set the time for the last items and then calculate the times using the subordinates and its subordinates, it doesn't multiplicate with any other timedriver than the last one.
An example:
Step 1
step 2 time driver 8
Step 2.1 = 3s time driver 4
Step 2.2 = 4s time driver 3
Should for step 1 generate (4*3 + 3*4) * 8 = 192 seconds but gives me 24 seconds since it doesn't multiply with step twos timedriver of 8. Step 2 gives me 24 seconds as it should since it should give me the time for one of the step 2 only.
Edit: I've tried to work out a working example but I can't simplify the code to build around it enough to get something I could publish here. I'd still really appreciate some help though!

Use convolution to find a reference audio sample in a continuous stream of sound

in my previous question on finding a reference audio sample in a bigger audio sample, it was proposed, that I should use convolution.
Using DSPUtil, I was able to do this. I played a little with it and tried different combinations of audio samples, to see what the result was. To visualize the data, I just dumped the raw audio as numbers to Excel and created a chart using this numbers. A peak is visible, but I don't really know how this helps me. I have these problems:
I don't know, how to infer the starting position of the match in the original audio sample from the location of the peak.
I don't know, how I should apply this with a continuous stream of audio, so I can react, as soon as the reference audio sample occurs.
I don't understand, why picture 2 and picture 4 (see below) differ so much, although, both represent an audio sample convolved with itself...
Any help is highly appreciated.
The following pictures are the result of the analysis using Excel:
A longer audio sample with the reference audio (a beep) near the end:
The beep convolved with itself:
A longer audio sample without the beep convolved with the beep:
The longer audio sample of point 3 convolved with itself:
UPDATE and solution:
Thanks to the extensive help of Han, I was able to achieve my goal.
After I rolled my own slow implementation without FFT, I found alglib which provides a fast implementation.
There is one basic assumption to my problem: One of the audio samples is contained completely within the other.
So, the following code returns the offset in samples in the larger of the two audio samples and the normalized cross-correlation value at that offset. 1 means complete correlation, 0 means no correlation at all and -1 means complete negative correlation:
private void CalcCrossCorrelation(IEnumerable<double> data1,
IEnumerable<double> data2,
out int offset,
out double maximumNormalizedCrossCorrelation)
{
var data1Array = data1.ToArray();
var data2Array = data2.ToArray();
double[] result;
alglib.corrr1d(data1Array, data1Array.Length,
data2Array, data2Array.Length, out result);
var max = double.MinValue;
var index = 0;
var i = 0;
// Find the maximum cross correlation value and its index
foreach (var d in result)
{
if (d > max)
{
index = i;
max = d;
}
++i;
}
// if the index is bigger than the length of the first array, it has to be
// interpreted as a negative index
if (index >= data1Array.Length)
{
index *= -1;
}
var matchingData1 = data1;
var matchingData2 = data2;
var biggerSequenceCount = Math.Max(data1Array.Length, data2Array.Length);
var smallerSequenceCount = Math.Min(data1Array.Length, data2Array.Length);
offset = index;
if (index > 0)
matchingData1 = data1.Skip(offset).Take(smallerSequenceCount).ToList();
else if (index < 0)
{
offset = biggerSequenceCount + smallerSequenceCount + index;
matchingData2 = data2.Skip(offset).Take(smallerSequenceCount).ToList();
matchingData1 = data1.Take(smallerSequenceCount).ToList();
}
var mx = matchingData1.Average();
var my = matchingData2.Average();
var denom1 = Math.Sqrt(matchingData1.Sum(x => (x - mx) * (x - mx)));
var denom2 = Math.Sqrt(matchingData2.Sum(y => (y - my) * (y - my)));
maximumNormalizedCrossCorrelation = max / (denom1 * denom2);
}
BOUNTY:
No new answers required! I started the bounty to award it to Han for his continued effort with this question!
Instead of a convolution you should use a correlation. The size of the correlation peak tells you how much both signals are alike, the position of the peak their relative position in time, or the delay between both signals.
Here we go for the bounty :)
To find a particular reference signal in a larger audio fragment, you need to use a cross-correlation algorithm. The basic formulae can be found in this Wikipedia article.
Cross-correlation is a process by which 2 signals are compared. This is done by multiplying both signals and summing the results for all samples. Then one of the signals is shifted (usually by 1 sample), and the calculation is repeated. If you try to visualize this for very simple signals such as a single impulse (e.g. 1 sample has a certain value while the remaining samples are zero), or a pure sine wave, you will see that the result of the cross-correlation is indeed a measure for for how much both signals are alike and the delay between them. Another article that may provide more insight can be found here.
This article by Paul Bourke also contains source code for a straightforward time-domain implementation. Note that the article is written for a general signal. Audio has the special property that the long-time average is usualy 0. This means that the averages used in Paul Bourkes formula (mx and my) can be left out.
There are also fast implementations of the cross-correlation based on the FFT (see ALGLIB).
The (maximum) value of the correlation depends on the sample values in the audio signals. In Paul Bourke's algorithm however the maximum is scaled to 1.0. In cases where one of the signals is contained entirely within another signal, the maximum value will reach 1. In the more general case the maximum will be lower and a threshold value will have to be determined to decide whether the signals are sufficiently alike.

Extending Karplus-Strong with low pass filter

I have implemented a basic Karplus-Strong algorithm.
Ringbuffer, filling with white noise, output a sample from the front and append the average of first two elements to the end and delete the first element. Repeat last to steps.
For better results and control over them I tried to implement a extended version of the algorithm.
Therefore instead of an averaging filter I need a frequency filter like a low pass filter.
My averaging filter has two inputs and one output: avg(a,b) = (a+b)/2
The sample code on the wikipedia page gives as many outputs as inputs.
http://en.wikipedia.org/wiki/Low-pass_filter
I have found other (mathematic) versions like:
http://cnx.org/content/m15490/latest/
H(z) = (1+(1/z))/2
I guess z is a complex number.
Both version have two inputs but also two outputs.
How do I get one meaningful value out of this?
Or do I have to rewrite bigger parts of the algorithm?
If thats the case where can I find a good explanation of it?
Your filter is a specialization of the Finite Impulse Response filter. You're using the moving average method to select the coefficients, using N = 1. It already is a low-pass filter.
Calculating the coefficient and order for the filter to tune it to a specific frequency response involves tricky math. Best thing to do is to use a software package to calculate the coefficients if moving average doesn't fit your bill. Matlab is the usual choice, GNU Octave is an open source option.
Filters can expressed in a number of ways:
On the complex plain, your example H(z) = (1+(1/z))/2
As a filter, y[i] = h[0]*x[i] + h[1]*x[i-1] + h[2]*x[i-2] + ...
In the frequency domain, Y[f] = H[f] * X[f]
The second of these is actually a convolution of the h and x arrays. This is also the easiest to understand.
The previous answer explained where to start on constructing a filter. Assuming you have your filter coefficients, the h's, then it is simply summing over the non-negative ones.
I believe I see what you are asking. Though you do not need more than one output. From the Wikipedia page the Karplus-Strong string synthesis algorithm needs a buffer of length L. If we have M filter coefficients (h) that gives an output of the form,
y[i] = x[i] + h[0]*y[i-L] + h[1]*y[i-(L+1)] + h[2]*y[i-(L+2)] + ...
The Karplus-Strong synthesis from here uses a ring buffer to hold the last L outputs, y[i-1],...,y[i-L]. This is initialised to be the x[i] noise values for i<=L; however, for i>L x[i]=0. The algorithm will be space efficient as you only store L values. The signal x[i] for i>L is just added to the ring buffer.
Finally, as a note of warning, if you are not careful with both the number of coefficients h and the values the outputs y may not have the desired behaviour.

How can I find the difference between 2 values in C#?

I am working with an Oscillator that fluctuates between 10.000000 and -10.000000
The value changes say every 5 minutes. I want to find the difference between the current value and the value of 5 minutes ago. Here is my logic.
1 bar ago (1BA)= -.2
Current bar (CB) = .3
Wouldn't I get a value of 1 if I did something like:
Abs(CB) - Abs(1BA) = .3 - .2 = 1
Whereas:
Abs(CB- 1BA) = .3 - -.2 = 5
I want to simply calculate the difference between the move of the oscillator from one time frame to another. Am I applying the Abs with the right logic in mind?
Here is my actual code, please assume my method being called is correct:
if (Oscillator(PoFast, PoSlow, PoSmooth)[0] >
Oscillator(PoFast, PoSlow, PoSmooth)[3]
&& Math.Abs(Oscillator(PoFast, PoSlow, PoSmooth)[0] -
Oscillator(PoFast, PoSlow, PoSmooth)[3]) > .25)
Of the two, Abs(CB-1BA) would be correct, since there was a change of .5 between the two readings.
EDIT: To make it more readable, and assuming you're getting double values, you'd do something like this, but with error checking, and probably making the .25 a variable.
double[] values = Oscillator(PoFast, PoSlow, PoSmooth);
double currentBar = values[0];
double oneBarAgo = values[3];
if (currentBar > oneBarAgo && Math.Abs(currentBar - oneBarAgo) > .25)
{
// do something
}
Your logic, Abs(CB-1BA) is correct.
As an aside, if you're not a developer do you really think you should be writing C# code to trade futures contracts? They're risky enough to trade at the best of times, never mind when you're writing code to do it and you're not a developer!!!!

Categories

Resources