Is there function in Math.Net like (MatLab/Octave/numpy)'s linspace() which takes 3 parameters (min, max, length) and creates an vector/array of evenly spaced values between min and max? It is not hard to implement but if there was a function already I would prefer to use that.
There is none exactly like linspace, but the signal generator comes quite close and creates an array:
SignalGenerator.EquidistantInterval(x => x, min, max, len)
I'm not fresh on the VB.net syntax, but I guess it's very close to C#.
In case you need a vector:
new DenseVector(SignalGenerator.EquidistantInterval(x => x, min, max, len))
Or you could implement it e.g. using the static Create function (in practice you may want to precompute the step):
DenseVector.Create(len, i => min + i*(max-min)/(len - 1.0))
Update 2013-12-14:
Since v3.0.0-alpha7 this is covered by two new functions:
Generate.LinearSpaced(length, a, b) -> MATLAB linspace(a, b, length)
Generate.LinearRange(a, [step], b) -> MATLAB a:step:b
I used this C# code to replicate the functionality of linspace (how numpy does it), feel free to use it.
public static float[] linspace(float startval, float endval, int steps)
{
float interval = (endval / MathF.Abs(endval)) * MathF.Abs(endval - startval) / (steps - 1);
return (from val in Enumerable.Range(0,steps)
select startval + (val * interval)).ToArray();
}
Here is the VB Translation I made.
Public Function linspace(startval As Single, endval As Single, Steps As Integer) As Single()
Dim interval As Single = (endval / Math.Abs(endval)) *(Math.Abs(endval - startval)) / (Steps - 1)
Return (From val In Enumerable.Range(0, Steps) Select startval + (val * interval)).ToArray()
End Function
Use examples;
C#
float[] arr = linspace(-4,4,5)
VB
Dim arr as Single() = linspace(-4,4,5)
Result:
-4,-2,0,2,4
I checked the result from the code shown below and MATLAB linspace, it exactly matches. I myself use it for my research work in Monte Carlo implementations.
Below is the code image and the actual code.
static double[] LINSPACE(double StartValue, double EndValue, int numberofpoints)
{
double[] parameterVals = new double[numberofpoints];
double increment = Math.Abs(StartValue - EndValue) / Convert.ToDouble(numberofpoints - 1);
int j = 0; //will keep a track of the numbers
double nextValue = StartValue;
for (int i = 0; i < numberofpoints; i++)
{
parameterVals.SetValue(nextValue, j);
j++;
if (j > numberofpoints)
{
throw new IndexOutOfRangeException();
}
nextValue = nextValue + increment;
}
return parameterVals;
}
Code for creating a linspace function in C#
Related
I am taking an introduction to Java programing class and I have an array list where I need to exclude the first element from my for loop that finds an average. The first element in the array list is a weight for the average (which is why it needs to be excluded). I also need to drop the lowest value from the remainder of the array list hence my second for loop. I have tried to create a copy of the list and also tried to create a sub list but I cannot get it to work.
public static double Avgerage(ArrayList<Double> inputValues) {
double avg;
double sum = 0;
double weightValue = inputValues.get(0);
double lowest = inputValues.get(0);
for (int i = 1; i > inputValues.size(); i++) {
if (inputValues.get(i) < lowest) {
lowest = inputValues.get(i);
}
}
for (int i = 0; i < inputValues.size(); i++) {
sum = sum + inputValues.get(i);
}
double average = (sum - lowest) / (inputValues.size() - 1);
avg = average * weightValue;
return avg;
}
To start with good programming practice, you should work with interfaces rather than classes, where possible. The appropriate interface here is List<Double>, and when you create it in your class, you should use
List<Double> nameOfList = new ArrayList<Double>();
What we're doing is creating an object which has the behaviour of a List, with the underlying implementation of an ArrayList (more info here.
With regards to the question, you don't appear to be excluding the first element, as you said you wished to - both for loops iterate through all values in the list. Remember to treat the ArrayList like an array - accessing an element does not modify it, like it might in a Queue.
I have edited your code below to demonstrate this, and have also included some other optimisations and corrected the sign error on line 7:
public static double average(List<Double> inputValues) {
double sum = 0;
//Exclude the first element, as it contains the weight
double lowest = inputValues.get(1);
for (int i = 2; i < inputValues.size(); i++) {
lowest = Math.min(inputValues.get(i), lowest);
}
for (int i = 1; i < inputValues.size(); i++) {
sum += inputValues.get(i);
}
double average = (sum - lowest) / (inputValues.size() - 1);
//Scale by the weight
avg *= inputValues.get(0);
return avg;
}
Note: The convention in java is to use camelCase for method names, I have adjusted accordingly.
Also, I don't know your requirements, but optimally, you should be providing logical parameters. If possible do the following before calling the function:
int weight = inputValues.get(0);
inputValues.remove(0);
//And then you would call like this, and update your method signature to match
average(inputValues, weight);
I don't do this inside the method, as the context implies that we would not be modifying values.
How would i generate a random double between 1 and a defined max in c++/cli, ive use random_number_distribution and mersenne twister in the random header before but never in cli, will this work in cli with random or system::random, or are there any similar alternatives? Thanks.
Here's how
double randDouble(double fMin, double fMax)
{
double f = (double)rand() / RAND_MAX;
return fMin + f * (fMax - fMin);
}
The System::Random class, with its NextDouble method is what you want. NextDouble will return a double >= 0.0 and < 1.0. So, to return a value between 1 and a max:
double RandOneToMax(double max)
{
Random^ r = ...;
return (r->NextDouble() * (max - 1)) + 1;
}
When you have code like this (written in java, but applicable to any similar language):
public static void main(String[] args) {
int total = 0;
for (int i = 0; i < 50; i++)
total += i * doStuff(i % 2); // multiplies i times doStuff(remainder of i / 2)
}
public static int doStuff(int i) {
// Lots of complicated calculations
}
You can see that there's room for improvement. doStuff(i % 2) only returns two different values - one for doStuff(0) on even numbers and one for doStuff(1) on odd numbers. Therefore you're wasting a lot of computation time/power on recalculating those values each time by saying doStuff(i % 2). You can improve like this:
public static void main(String[] args) {
int total = 0;
boolean[] alreadyCalculated = new boolean[2];
int[] results = new int[2];
for (int i = 0; i < 50; i++) {
if (!alreadyCalculated[i % 2]) {
results[i % 2] = doStuff(i % 2);
alreadyCalculated[i % 2] = true;
}
total += i * results[i % 2];
}
}
Now it accesses a stored value instead of recalculating each time. It might seem silly to keep arrays like that, but for cases like looping from, say, i = 0, i < 500 and you're checking i % 32 each time, or something, an array is an elegant approach.
Is there a term for this kind of code optimization? I'd like to read up more on the different forms and the conventions of it but I'm lacking a concise description.
Is there a term for this kind of code optimization?
Yes, there is:
In computing, memoization is an optimization technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again.
https://en.wikipedia.org/wiki/Memoization
Common-subexpression-elimination (CSE) is related to this. This case is a combination of that and hoisting a loop-invariant calculation out of a loop.
I'd agree with CBroe that you could call this specific form of caching memoization, esp the way you're implementing it with the clunky alreadyCalculated array. You can optimize that away since you know which calls will be new values and which will be repeats. Normally you'd implement memoization with a static array inside the called function, for the benefit of all callers. Ideally there's a sentinel value you can use to mark entries which don't have a result computed yet, instead of maintaining a separate array for that. Or for a sparse set of input values, just use a hash (instead of e.g. an array with 2^32 entries).
You can also avoid the if in the main loop.
public class Optim
{
public static int doStuff(int i) { return (i+5) << 1; }
public static void main(String[] args)
{
int total = 0;
int results[] = new int[2];
// more interesting if we pretend the loop count isn't known to be > 1, so avoiding calling doStuff(1) for n=1 is useful.
// otherwise you'd just do int[] results = { doStuff(0), doStuff(1) };
int n = 50;
for (int i = 0 ; i < Math.min(n, 2) ; i++) {
results[i] = doStuff(i);
total += i * results[i];
}
for (int i = 2; i < n; i++) { // runs zero times if n < 2
total += i * results[i % 2];
}
System.out.print(total);
}
}
Of course, in this case we can optimize a lot further. sum(0..n) = n * (n+1) / 2, so we can use that to get a closed-form (non-looping) solution in terms of doStuff(0) (sum of the even terms) and doStuff(1) (sum of the odd terms). So we only need the two doStuff() results once each, avoiding any need to memoize.
i have created the recursive call tree by applying brute force technique but when i give this algorithm 100 values it takes trillion of years to compute..
what you guys suggest me to do that it runs fast by giving 100 values
here is what i have done so far
function fib(n) {
if (n =< 1) {
return n;
} else {
return fib(n - 1) + fib(n - 2);
}
}
You can do it also with a loop:
int a = 1;
int b = 1;
for(int i = 2; i < 100; i++){
int temp = a + b;
a = b;
b = temp;
}
System.out.println("Fib 100 is: "+b);
The runtime is linear and avoids the overhead caused by the recursive calls.
EDIT: Please note that the result is wrong. Since Fib(100) is bigger than Integer.MAX_VALUE you have to use BigInteger or similar to get the correct output but the "logic" will stay the same.
You could have a "cache", where you save already computed Fibonacci numbers. Every time you try to compute
fib(n-1) /* or */ fib(n-2) ;
You would first look into your array of already computed numbers. If it's there, you save a whole lot of time.
So every time you do compute a fibonacci number, save it into your array or list, at the corresponding index.
function fib(n)
{
if (n =< 1)
{
return n;
}
if(fiboList[n] != defaultValue)
{
return fiboList[n];
}
else
{
int fibo = fib(n-1) + fib(n-2);
fiboList[n] = fibo;
return fibo;
}
}
You can also do it by dynamic programming:
def fibo(n):
dp = [0,1] + ([0]*n)
def dpfib(n):
return dp[n-1] + dp[n-2]
for i in range(2,n+2):
dp[i] = dpfib(i)
return dp[n]
I've inherited a Visual Studio/VB.Net numerical simulation project that has a likely inefficient calculation. Profiling indicates that the function is called a lot (1 million times plus) and spends about 50% of the overall calculation within this function. Here is the problematic portion
Result = (A * (E ^ C)) / (D ^ C * B) (where A-C are local double variables and D & E global double variables)
Result is then compared to a threshold which might have additional improvements as well, but I'll leave them another day
any thoughts or help would be appreciated
Steve
The exponent operator (Math.Pow) isn't very fast, there is no dedicated CPU instruction for calculating it. You mentioned that D and E are global variables. That offers a glimmer of hope to get it faster, if you can isolate their changes. Rewriting the equation using logarithms:
log(r) = log((a x e^c) / (b x d^c))
= log(a x e^c) - log (b x d^c)
= log(a) + log(e^c) - log(b) - log(d^c)
= log(a) + c*log(e) - log(b) - c*log(d)
= log(a) - log(b) + c x (log(e) - log(d))
result = exp(r)
Which provides this function to calculate the result:
Function calculate(ByVal a As Double, ByVal b As Double, ByVal c As Double, ByVal d As Double, ByVal e As Double) As Double
Dim logRes = Math.Log(a) - Math.Log(b) + c * (Math.Log(e) - Math.Log(d))
Return Math.Exp(logRes)
End Function
I timed it with the StopWatch class, it is exactly as fast as your original expression. Not a coincidence of course. You'll get ahead by somehow being able to pre-calculate the Math.Log(e) - Math.Log(d) term.
One easy speed up is that
Result = (A/B) * (E/D)^C
At least you are doing one less exponent.
Depending on what C is, there might be faster ways. Like if C is a small integer.
edit:
adding proof to show this is faster
public static void main(String[] args) {
StopWatch sw = new StopWatch();
float e = 1.123F;
float d = 4.456F;
float c = 453;
sw.start();
int max = 5000;
double result = 0;
for (int a = 1; a < max; a++) {
for (float b = 1; b < max; b++) {
result = (a * (Math.pow(e, c))) / (Math.pow(d, c) * b);
}
}
sw.split();
System.out.println("slow: " + sw.getSplitTime() + " result: " + result);
sw.stop();
sw.reset();
sw.start();
result = 0;
for (int a = 1; a < max; a++) {
for (float b = 1; b < max; b++) {
result = a / b * Math.pow(e/d, c);
}
}
sw.split();
System.out.println("fast: " + sw.getSplitTime() + " result: " + result);
sw.stop();
sw.reset();
}
This is the output
slow: 26062 result: 7.077390271736578E-272
fast: 12661 result: 7.077392136525382E-272
There is some skew in the numbers. I would think that the faster version is more exact (but that's just a feeling since i can't think of exactly why).
Well done for profiling. I would also check that A-C are different on every call. In other words, is it possible the caller is actually calculating the same value over and over again? If so, change it so it caches the answer.
For Math.Floor() function, visit:
http://bitsbyta.blogspot.com/2010/12/math-floor-function-vbnet.html
All functions of math library in vb.net is available at:
http://www.bitsbyta.blogspot.com/