I'm really interested in numerical analysis. I have been using DotNumerics Open Source Application. My linear system is the following:
1 * x + 3 * y <= 150
2 * x + 1 * y <= 100
where x >= 0, y >= 0
z = 10 * x + 15 * y
I am trying to solve z (optimization...)
I can use Simplex method to solve above problem as found in this link. I have also emailed the author, however he has not replied.
using DotNumerics.Optimization;
using DotNumerics;
namespace App.SimplexCalcLinearProgramming
{
class Program
{
static void Main(string[] args)
{
Simplex simplex = new Simplex();
double[] initialGuess = new double[2];
initialGuess[0] = 0.1;
initialGuess[1] = 2;
double[] minimum = simplex.ComputeMin(AmacFunction, initialGuess);
minimum.ToList().ForEach(q => Console.Write(q.ToString() + "\n"));
Console.ReadKey();
}
static double AmacFunction(double[] x)
{
/*
* 1 * x + 3 * y <= 150
* 2 * x + 1 * y <= 100
*
* where x >= 0, y >= 0
*
* z = 10 * x + 15 * y
*
* Solve for z
*/
double f = 0;
f = 10*x[0]+15*x[1];
return f;
}
}
}
I don't think DotNumerics can solve LP problems by itself. As far as I interpret the documentation, the Nelder–Mead (downhill simplex method) implemented is only used to solve simple minimalisation problems, not LP problems.
The last time I've solved LP in c#, I used a .net wrapper to LP_Solve.
If you download the lpsolve package, it should come with an example for .net. You can also plug it into the microsoft solver foundation (see here), but I think MSF has some licensing issues and you can't use it freely for commercial applications. But still, MSF may be interesting to check out as well.
Again, you can simply use lpsolve without MSF. Lpsolve is a pretty good LP solver unless you have massive size problems. Then it may be worth to at least around for alternatives and compare performance/adaptability to your particular problem.
Related
I have a lot of dislikes on this post, I'm not sure why, but for letting you guys help me out with this question, I will give you this script as a gift. This script converts experience to level and from level to experience points given an exponential expression. those constants ensure that level 100 will equal 10 million experience. In Runescape, their level 99 equals 13,032,xxx which is a strange number.
using System.IO;
using System;
class Program
{
const float salt = 2.82842712474619f;
const float factor = 0.64977928f;
const int lvl_100_XP = 10000000;
static void Main()
{
int xp = 9717096;// lvl 99
int lvl = ExperienceToLevel(xp);
Console.WriteLine("LVL: " + lvl.ToString()+ " XP: " + LevelToExperience(lvl).ToString());
}
static public int ExperienceToLevel(int xp){
int lvl = 0;
if (xp == lvl_100_XP){//9999987 is lvl 100 due to roundoff issues so it is fixed to 10mill
lvl = 100;
}
else{
lvl = (int)((1f / salt) * (float)Math.Pow((float)xp, (1f - factor)));
if (lvl == 0){
//lvl = 1;
}
}
if (lvl == 100 && xp < lvl_100_XP){
lvl = 99;
}
return lvl;
}
static public int LevelToExperience(int lvl){
int xp = 0;
if (lvl == 100){//9999987 is lvl 100 due to roundoff issues so it is fixed to 10mill
xp = lvl_100_XP;
}
else{
xp = (int)Math.Exp((float)Math.Log(salt * (float)lvl) / (1f - factor))+1;
if (xp <= 1){
xp= 0;
}
if (lvl == 100){
xp = lvl_100_XP;
}
}
return xp;
}
}
Let's work it out.
Let x be the experience, a and c are constants. L is the level. We notate exponentiation as ^; note that C# does not have such an operator. ^ in C# is XOR.
You have
b = x / a
d = x ^ c
L = b / d
so that's
L = x / (a * x ^ c)
which is
L = (1 / a) * (x / x ^ c)
which is
L = (1 / a) * x ^ (1 - c)
You wish to solve for x. So multiply both sides by 'a':
a * L = x ^ (1 - c)
Take the ln of both sides. (Or whatever logarithm you like best.)
ln (a * L) = (1 - c) ln (x)
Divide both sides by 1 - c
ln (a * L) / (1 - c) = ln x
And eliminate the ln; remember that exp is the inverse of ln. If you used some other logarithm, then use some other exponent.
exp (ln (a * L) / (1 - c)) = x
And we're done.
First of all, exp to level is a many to one relationship. The reverse is a one to many, so what exp are you aiming to return in lvl2exp? The minimum for that level? The maximum? A mean value?
I think your better off just computing once a table with experience brackets for each level (even cache it to a file if its not going to change) and simply doing a binary search to find the corresponding bracket for any given level.
I am trying to implement this without success and I have to do this without using external modules numpy, etc. There are 3 modules in the app I am coding this, Python and C#, C++ but no other fancy libraries other than standard ones.
On a separate application, I used numpy's svd and it works very accurately. So I am using it to match my results. My method is PCA and everything is good up to this point. But after I calculate my symmetric covariance matrix, I don't know how to find the largest eigenvector.
The data set is always 3d points, x, y and z.
vector center;
for(point p in points):
center += p;
center /= points.count;
sumxx = 0;
sumxy = 0;
sumxz = 0;
sumyy = 0;
sumyz = 0;
sumzz = 0;
for(point p in points):
vector s = p - center;
sumxx += s.x * s.x;
sumxy += s.x * s.y;
sumxz += s.x * s.z;
sumyy += s.y * s.y;
sumyz += s.y * s.z;
sumzz += s.z * s.z;
matrix3 mat = invert(matrix3(sumxx, sumxy, sumxz, sumxy, sumyy, sumyz, sumxz, sumyz, sumzz));
vector n;
if (determinant(mat) > 0)
normal = find_largest_eigenvalue
Let us recap what you are asking, to clarify :
Find an eigenvector of a matrix mat
This eigenvector should be associated with the largest eigenvalue of the matrix
The matrix is the symmetric covariance matrix of a principal component analysis. In particular, it is symmetric.
Your matrix is square of size 3 by 3, as shown in your code by matrix3 mat = ... and confirmed in a (now deleted) comment.
Under these very specific circumstances, the following answer applies. However tmyklebu warns against numerical instability of this approach for some pathological matrices, typically when r is close to -1.
Alright, lets start with a bit of reading from wikipedia's page on Characteristic polynomials
In linear algebra, the characteristic polynomial of a square matrix is a polynomial, which is invariant under matrix similarity and has the eigenvalues as roots.
blah blah blah, let's skip directly to the 3x3 matrix section in the page on Eigenvalue algorithms.
If A is a 3×3 matrix, then its characteristic equation can be expressed as:
Followed a few lines later by (more or less) this pseudo-code, for symmetric matrices (which you say you have, if I'm not mistaken -- otherwise you might have complex eigenvalues) :
p1 = A(1,2)^2 + A(1,3)^2 + A(2,3)^2
if (p1 == 0)
% A is diagonal.
eig1 = A(1,1)
eig2 = A(2,2)
eig3 = A(3,3)
else
q = (A(1,1) + A(2,2) + A(3,3)) / 3
p2 = (A(1,1) - q)^2 + (A(2,2) - q)^2 + (A(3,3) - q)^2 + 2 * p1
p = sqrt(p2 / 6)
B = (1 / p) * (A - q * I) % I is the identity matrix
r = determinant(B) / 2
% In exact arithmetic for a symmetric matrix -1 <= r <= 1
% but computation error can leave it slightly outside this range.
if (r <= -1)
phi = pi / 3
elseif (r >= 1)
phi = 0
else
phi = acos(r) / 3
end
% the eigenvalues satisfy eig3 <= eig2 <= eig1
eig1 = q + 2 * p * cos(phi)
eig3 = q + 2 * p * cos(phi + (2*pi/3))
eig2 = 3 * q - eig1 - eig3 % since trace(A) = eig1 + eig2 + eig3
end
So you want max(eig1,eig2,eig3) in the first case, eig1 in the second case. Let us call e this largest eigenvalue.
For the eigenvector, you can now just solve (A-e*I)x=0
There are different algorithms for finding eigenvalues. Some work from smallest to largest, like QR; others work from largest to smallest, like power iteration or Jacobi-Davidson.
Maybe a switch of algorithm is what you want. Try power method and see if that helps.
https://scicomp.stackexchange.com/questions/1681/what-is-the-fastest-way-to-calculate-the-largest-eigenvalue-of-a-general-matrix
I have a loop inside a constructor, that creates and initialises a jagged array of objects. Inside the loop I have it print to the console on each iteration, so that I know how far through the process it is. It only prints to the console on a multiple of 5 (although it's only printing on a multiple of 10 for some reason) so that it doesn't spam the screen. Eg, 15% 20% 25%.
When I run the code on .Net 2.0 on Windows, it prints every 10% (rather than 5%). If I run the same code on Mono on an ARM machine it doesn't print any progress out at all.
What is causing Mono to not give any output?
Why is it printing only in increments of 10% rather than 5%?
Thanks
Here's the code:
public Map(int NumberOfRows, int NumberOfColumns)
{
Rows = NumberOfRows;
Columns = NumberOfColumns;
TileGrid = new Tile[NumberOfRows][];
for (int x = 0; x < TileGrid.Length; x++)
{
TileGrid[x] = new Tile[NumberOfColumns];
for (int y = 0; y < TileGrid[x].Length; y++)
{
TileGrid[x][y] = new Tile();
}
if (((double)x / Rows) * 100 % 5 == 0)
{
Console.WriteLine("{0}%", ((double)x / Rows) * 100);
}
}
}
The problem is basically that you're performing an equality check on a floating point number, which is pretty much never a good idea.
This is better... but still not good:
int percentage = (x * 100) / Rows;
if (percentage % 5 == 0)
{
Console.WriteLine("{0}%", percentage);
}
That's still not going to print the percentage unless you end up exactly at multiples of 5%. So if there are 12 items, it's not going to work. Try this instead:
// Before the loop
int lastPrintedPercentage = -5; // So that we always print on the first loop
// Within the loop
int percentage = (x * 100) / Rows;
if (percentage >= lastPrintedPercentage + 5)
{
Console.WriteLine("{0}%", percentage);
lastPrintedPercentage = percentage;
}
floating point operations must be compared against the machine epsilon because of the floating point rounding errors
http://en.wikipedia.org/wiki/Machine_epsilon
This expression can be never null according to the floating point rounding error
if (((double)x / Rows) * 100 % 5 == 0)
must be
if (Math.Abs(((double)x / Rows) * 100 % 5) < MACHINE_EPSILON)
But there is no definition in the .NET Framework for the machine epsilon. So don't use floating point operations for this at all or use a delta technique like
var step = (double)x / Rows) * 5;
var current = step ;
...
if((double)x / Rows) >= current)
{
current += step;
// Your code here
}
...
I need to do multiple linear regression efficiently. I am trying to use the Math.NET Numerics package but it seems slow - perhaps it is the way I have coded it? For this example I have only simple (1 x value) regression.
I have this snippet:
public class barData
{
public double[] Xs;
public double Mid;
public double Value;
}
public List<barData> B;
var xdata = B.Select(x=>x.Xs[0]).ToArray();
var ydata = B.Select(x => x.Mid).ToArray();
var X = DenseMatrix.CreateFromColumns(new[] { new DenseVector(xdata.Length, 1), new DenseVector(xdata) });
var y = new DenseVector(ydata);
var p = X.QR().Solve(y);
var b = p[0];
var a = p[1];
B[0].Value = (a * (B[0].Xs[0])) + b;
This runs about 20x SLOWER than this pure C#:
double xAvg = 0;
double yAvg = 0;
int n = -1;
for (int x = Length - 1; x >= 0; x--)
{
n++;
xAvg += B[x].Xs[0];
yAvg += B[x].Mid;
}
xAvg = xAvg / B.Count;
yAvg = yAvg / B.Count;
double v1 = 0;
double v2 = 0;
n = -1;
for (int x = Length - 1; x >= 0; x--)
{
n++;
v1 += (B[x].Xs[0] - xAvg) * (B[x].Mid - yAvg);
v2 += (B[x].Xs[0] - xAvg) * (B[x].Xs[0] - xAvg);
}
double a = v1 / v2;
double b = yAvg - a * xAvg;
B[0].Value = (a * B[Length - 1].Xs[0]) + b;
ALSO if Math.NET is the issue, then if anyone knows simple way to alter my pure code for multiple Xs I would be grateful of some help
Using a QR decomposition is a very generic approach that can deliver least squares regression solutions to any function with linear parameters, no matter how complicated it is. It is therefore not surprising that it cannot compete with a very specific straight implementation (on computation time), especially not in the simple case of y:x->a+b*x. Unfortunately Math.NET Numerics does not provide direct regression routines yet you could use instead.
However, there are still a couple things you can try for better speed:
Use thin instead of full QR decompositon, i.e. pass QRMethod.Thin to the QR method
Use our native MKL provider (much faster QR, but no longer purely managed code)
Tweak threading, e.g. try to disable multi-threading completely (Control.ConfigureSingleThread()) or tweak its parameters
If the data set is very large there are also more efficient ways to build the matrix, but that's likely not very relevant beside of the QR (-> perf analysis!).
I would like to generate a digital signal, which'll then be used to implement an ASK(Amplitude Shift Keying) Signal.
Let's say the message bits are 10110, data rate : 3.9 Khz & amplitude A.
What would be the best way to generate a Square signal(Digital).
I tried the following code, but the outcome is not a desired one.
double[] x = new double[1000];
double[] y = new double[1000];
double freq = 3900.0;
for (int k = 0; k < y.Length; k++)
{
x[k] = k;
y[k] = (4 / Math.PI) * (((Math.Sin(((2 * k) - 1) * (2 * Math.PI * freq))) / ((2 * k) - 1)));
}
// Plot Square Wave
plotSquare(x, y, Msg);
The easiest way I can think of is to set y to be sign of a sine wave, making allowances for when it equals zero. I don't know if C# has the triple-operator, but something like this might work:
y[k] = Math.Sin(freq * k)>=0?A:-1*A;
Math.Sin is useful for sine wave, but a square wave should be far, far simpler (i.e. signal is 'high' for a period, then 'low' for a period). If you have a Math.Sin anywhere, you are generate a sine wave, not a square wave. Bearing in mind a square wave can be generated with a condition (is x>y) and a sine wave needs a full mathematical operation, it's far more efficient, too.
C#'s Iterator Block support comes to mind:
IEnumerable<Tuple<double, double>> SquareWave(double freq, double lowAmp, double highAmp)
{
for (var x = 0.0; true; x += 1.0)
{
var y = ((int)(x / freq) % 2) == 0 ? lowAmp : highAmp;
yield return Tuple.Create(x, y);
}
}
use like this:
foreach(var t in SquareWave(10, -5, 5).Take(30))
Console.WriteLine("X: {0:0.0}/Y: {1:0.0}", t.Item1, t.Item2);