Solve non square linear system with Math.net - c#

I'm trying to solve a non square linear system with Math.net.
But I get an error Matrix dimensions must agree: 3x7.
Here is some example code:
using MathNet.Numerics.LinearAlgebra;
var mBuilder = Matrix<double>.Build;
var vBuilder = Vector<double>.Build;
var A = mBuilder.DenseOfArray(new double[,]
{
{ 3, 2, 1, 5, -1, 0, 0 },
{ 2, 1, 1, 2, 0, -1, 0 },
{ 5, 1, 3, 4, 0, 0, -1 }
});
var b = vBuilder.DenseOfArray(new double[] { -3, -5, -2 });
Vector<double> x;
x = A.Solve(b);
Cleary the system has a solution (e.g. X = {0, 0, 0, 0, 3, 5, 2}).
How can I solve such a system with Math.Net?

You can not use the Matrix.Solve function with a non-square matrix because there is no inverse and no unique solutions for a rectangular matrix. Google "inverse of rectangular matrix" for explanations galore. You can use pseudoinverse however, as shown below.
var mBuilder = Matrix<double>.Build;
var A = mBuilder.DenseOfArray(new double[,]
{
{ 3, 2, 1, 5, -1, 0, 0 },
{ 2, 1, 1, 2, 0, -1, 0 },
{ 5, 1, 3, 4, 0, 0, -1 }
});
Matrix<double> b = Matrix<double>.Build.Dense(3, 1);
b[0, 0] = -3.0;
b[1, 0] = -5.0;
b[2, 0] = -2.0;
var p = A.PseudoInverse();
var x = p * b;
// verify
var o = A * x;

Related

Save a matrix of zero and one as a sequence of bits

I have a binary matrix 8x8 represented as an one-dimensional array
byte[] m = { 0, 1, 1, 1, 1, 0, 0, 1,
1, 1, 1, 1, 1, 0, 0, 1,
0, 1, 1, 1, 1, 0, 0, 1,
1, 1, 1, 1, 0, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 1, 1, 0, 0, 1,
1, 1, 1, 1, 1, 0, 0, 1,
1, 1, 1, 1, 1, 0, 0, 1 };
Is there a way how to save it in to binary file which would have total size of 8 bytes? Each 0 and 1 zero would be a 1 bit size.
You can use the following function to compress an array of 0s and 1s to an array of bytes:
IEnumerable<byte> Compress(byte[] a)
{
for (var i = 0; i < a.Length / 8f; i++)
{
var slice = a.Skip(i * 8).Take(8);
byte b = 0;
foreach (var s in slice)
{
b <<= 1;
if (s == 1)
b |= 1;
}
yield return b;
}
}
Then save to file using File.WriteAllBytes.
For example:
var result = Compress(m).ToArray();
File.WriteAllBytes(#"d:\test.bin", result);

How to create single dimensional, two dimensional,three dimensional as well as multi dimensional array using C#?

I am trying to keep all the combinations (5C1, 5C2, 5C3, 5C4, 5C5) of 1,2,3,4,5 into individual array. So I need to create dynamic array using for loop in c#.
Say for example,
Here n = 5 and r = 1 to 5.
if r = 1 then
My array will be single dimensional array, when r = 2 then it will be two dimensional array, when r = 3 then three dimensional, when r = 4 then four dimensional array and it will e continued up to end of 5.
My code is given below
string[] ShipArrayObj;
public frmResult( string[] ShipArray )
{
InitializeComponent();
ShipArrayObj = ShipArray;
}
private void frmResult_Load(object sender, EventArgs e)
{
string[] arr = ShipArrayObj;
int n = ShipArrayObj.Count();
for (int r = 1; r <= n; r++)
{
StoreCombination(arr, n, r);
richTextBox1.Text = richTextBox1.Text + "/";
}
}
void StoreCombination(string[] arr, int n, int r)
{
string[] data = new string[r];
createCombination (arr, data, 0, n - 1, 0, r);
}
private void createCombination(string[] arr, string[] data, int start, int end, int index, int r)
{
if (index == r)
{
int j = 0;
for (j = 0; j < r; j++)
richTextBox1.Text = richTextBox1.Text + data[j].ToString();//Where I want to set array to keep combination values
return;
}
int i = 0;
for (i = start; i <= end && end - i + 1 >= r - index; i++)
{
data[index] = arr[i];
CreateCombination(arr, data, i + 1, end, index + 1, r);
}
}
I am storing all the combination into a Rich Text Box, but want to keep into array. If anybody help me then I will be grateful to you.
If you're used to something like Java then multidimensional arrays are a little different in syntax in C#.
Here's a page describing how to do them in C#. Here's a snippet from said page:
// Two-dimensional array.
int[,] array2D = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
// The same array with dimensions specified.
int[,] array2Da = new int[4, 2] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
// A similar array with string elements.
string[,] array2Db = new string[3, 2] { { "one", "two" }, { "three", "four" },
{ "five", "six" } };
// Three-dimensional array.
int[, ,] array3D = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } },
{ { 7, 8, 9 }, { 10, 11, 12 } } };
// The same array with dimensions specified.
int[, ,] array3Da = new int[2, 2, 3] { { { 1, 2, 3 }, { 4, 5, 6 } },
{ { 7, 8, 9 }, { 10, 11, 12 } } };
If you're interested in different combinations of things with a fixed number of them, something like this should be all you need.
If you're interested in different combinations of things with a dynamic number of them, something like this should be all you need.
(Unless you're trying to optimize performance, it's better to be readable/expressive, generally speaking.)
You may need to consider whether or not order matters (un-ordered set vs. ordered list). I would assume it doesn't from your code (in which case sorting is good to eliminate "duplicates"), but I can't tell for sure.
Here's a good example that's easy to read and modify for variations and isn't so bad for small numbers:
// -1, 0, ..., 5
var choices = Enumerable.Range(-1, 6);
var possibleChoices =
from a in choices
from b in choices
from c in choices
from d in choices
from e in choices
select (IEnumerable<int>)new [] { a, b, c, d, e };
// Remove -1's because they represent not being in the choice.
possibleChoices =
possibleChoices.Select(c => c.Where(d => d >= 0));
// Remove choices that have non-unique digits.
possibleChoices =
possibleChoices.Where(c => c.Distinct().Count() == c.Count());
// Sort the choices to indicate order doesn't matter
possibleChoices =
possibleChoices.Select(c => c.OrderBy(d => d));
// Remove duplicates
possibleChoices =
possibleChoices.Select(c => new
{
Key = string.Join(",", c),
Choice = c
}).
GroupBy(c => c.Key).
Select(g => g.FirstOrDefault().Choice);
foreach (var choice in possibleChoices) {
Console.Out.WriteLine(string.Join(", ", choice));
}
Output:
0
1
2
3
4
0, 1
0, 2
0, 3
0, 4
1, 2
1, 3
1, 4
2, 3
2, 4
3, 4
0, 1, 2
0, 1, 3
0, 1, 4
0, 2, 3
0, 2, 4
0, 3, 4
1, 2, 3
1, 2, 4
1, 3, 4
2, 3, 4
0, 1, 2, 3
0, 1, 2, 4
0, 1, 3, 4
0, 2, 3, 4
1, 2, 3, 4
0, 1, 2, 3, 4
This is probably a little more dense to understand, hard-coded to this specific variation of combination and involves recursion but is a bit more generic/isn't hard-coded to 5 (and took 0.047s on dotnetfiddle.net instead of 0.094s). It's also completely lazy/IEnumerable.
public static void Main()
{
var possibleChoices = Choose(5);
foreach (var choice in possibleChoices) {
Console.Out.WriteLine(string.Join(", ", choice));
}
}
public static IEnumerable<IEnumerable<int>> Choose(int max)
{
var remaining = Enumerable.Range(0, max);
return ChooseRecursive(remaining, Enumerable.Empty<int>());
}
public static IEnumerable<IEnumerable<int>> ChooseRecursive(IEnumerable<int> remaining, IEnumerable<int> chosen)
{
yield return chosen;
foreach (var digit in remaining)
{
var choices = ChooseRecursive(
remaining.Where(d => d > digit),
chosen.Concat(new [] { digit })
);
foreach (var choice in choices)
{
yield return choice;
}
}
}
Output:
0
0, 1
0, 1, 2
0, 1, 2, 3
0, 1, 2, 3, 4
0, 1, 2, 4
0, 1, 3
0, 1, 3, 4
0, 1, 4
0, 2
0, 2, 3
0, 2, 3, 4
0, 2, 4
0, 3
0, 3, 4
0, 4
1
1, 2
1, 2, 3
1, 2, 3, 4
1, 2, 4
1, 3
1, 3, 4
1, 4
2
2, 3
2, 3, 4
2, 4
3
3, 4
4

Fastest algorithm to merge 2 arrays such that elements are interlocked at even intervals

Requirements:
Integer operations only (no floats)
Elements are interlocked at intervals as evenly as possible
Note:
"Intervals as evenly as possible" can be defined as having each length of intervals as close to one value as possible.
Micro-optimizations are welcome and desired.
Example inputs and outputs:
//Inputs
[ 1, 2, 3, 4, 5, 6, 7 ]
[ 10, 20, 30, 40 ]
//Correct output
[ 1, 10, 2, 20, 3, 30, 4, 5, 40, 6, 7]
//Wrong output ([5, 6, 7] is not an optimal interval)
[ 1, 10, 2, 20, 3, 30, 4, 40, 5, 6, 7]
-
//Inputs
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[ 2, 2, 2 ]
//Correct output
[ 1, 1, 1, 3, 1, 1, 1, 3, 1, 1, 3, 1, 1]
//Wrong output (last [1] is not an optimal interval)
[ 1, 1, 1, 3, 1, 1, 1, 3, 1, 1, 1, 3, 1]
Here's my own implementation with as much optimization as I can think of for a managed language. In C++, it may be faster to use a triple XOR swap for the array pointers, but I'm not sure. It may be necessary to look at the JITed assembly to further optimize this particular code.
In the meantime, let's see if other people have better algorithms.
int[] InterlockMerge(int[] a1, int[] a2) {
var longSet = a1;
var shortSet = a2;
//Swap if a2 is longer
if (a1.Length < a2.Length){
longSet = a2;
shortSet = a1;
}
var ll = longSet.Length;
var ls = shortSet.Length;
var totalLength = ll + ls;
int[] res = new int[totalLength]; //The resulting set
int l = ll / (ls + 1); //Initial testing ratio (an int)
int li = 0; //index for longSet
int si = 0; //index for shortSet
for (int i = 0; i < totalLength; i++) {
if (l > 0) {
res[i] = longSet[li++];
l--;
continue;
}
res[i] = shortSet[si++];
l = (ll - li) / (ls - si + 1); //Recalculate the testing ratio
}
return res;
}

Distinct values 2d array

I have a 2D array as follows:
long[,] arr = new long[4, 4] {{ 5, 0, 0, 0 },
{ 8, 1, 1, 1 },
{ 0, 3, 0, 6 },
{ 1, 1, 1, 1 }};
How I can display distinct values form this array?
You can use Enumerable.Distinct method:
var uniqueValues = arr.Cast<long>().Distinct();

Displaying mutiple instances of an image in a 2d array

This is what i have decided to start with a winForm & 1 button called btnCreate and I have 2 images 35px X 35px floor.bmp and wall.bmp
public partial class Form1 : Form
{
int x;
int y;
int[] Row0 = new int[10] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
int[] Row1 = new int[10] { 1, 1, 1, 1, 0, 0, 1, 1, 0, 1 };
int[] Row2 = new int[10] { 1, 1, 0, 0, 0, 0, 1, 1, 0, 1 };
int[] Row3 = new int[10] { 1, 1, 1, 1, 0, 1, 1, 1, 0, 1 };
int[] Row4 = new int[10] { 1, 0, 0, 1, 0, 1, 0, 0, 0, 1 };
int[] Row5 = new int[10] { 1, 0, 0, 1, 0, 0, 0, 1, 0, 1 };
int[] Row6 = new int[10] { 1, 1, 0, 0, 0, 0, 1, 1, 0, 1 };
int[] Row7 = new int[10] { 1, 1, 1, 1, 0, 0, 1, 1, 0, 1 };
int[] Row8 = new int[10] { 1, 1, 0, 0, 0, 0, 1, 1, 0, 1 };
int[] Row9 = new int[10] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
int[,] LevelA = new int[10,10];
private void Form1_Load(object sender, EventArgs e)
{
for (x = 0; x < 10; x++)
{
//load all arrays
LevelA[0, x] = Row0[x];
LevelA[1, x] = Row1[x];
LevelA[2, x] = Row2[x];
LevelA[3, x] = Row3[x];
LevelA[4, x] = Row4[x];
LevelA[5, x] = Row5[x];
LevelA[6, x] = Row6[x];
LevelA[7, x] = Row7[x];
LevelA[8, x] = Row8[x];
LevelA[9, x] = Row9[x];
}
}
private void btnCreate_Click(object sender, EventArgs e)
{
for (int X = 0; X < 10; X++)
{
for (int Y = 0; Y < 10; Y++)
{
//the following is the idea of what I would like to accomplish
//if (LevelA[Y,X] == 0)
//{
//Bitmap myBmp = new Bitmap(Image.FromFile(#"C:\My Documents\floor2.bmp"));
//myBmp.Top == Y * 35;
//myBmp.left == X * 35;
//}
}
}
}
}
Would the CODE above work as I intend it too >? or would the end of the for-loop only display the last tile as it would keep replacing(destroying) the previous one with a new one? In witch case I would need to have 100 myBmp's for a 10 by 10 grid?
You can get the bitmap of an image file by creating a Bitmap object.
Bitmap bmp = new Bitmap(Image.FromFile(#"D:\MyImageFile.bmp"));
You can place that or draw that anywhere as long as you get hold of a Graphics instance.
You can find asimple example here about that.

Categories

Resources