How to reshape matrix in MathNet? - c#

I have 1x4 Matrix
[1, 2, 3, 4]
And I want to get 2x2 Matrix
[[1, 2], [3, 4]]. How can achieve this in Math.Net?
I found Resize method, which does not what I need.
Vector<double> vector = Vector<double>.Build.DenseOfArray(new double[] { 1, 2, 3, 4 });
var matrix1x4 = vector1x4.ToRowMatrix();
var matrix2x2 = matrix1x4.Resize(2, 2);
Resize method does not reshape, it copies part "common" part for those two matrices and discards the rest
[[1, 0], [2, 0]]

Related

Solve non square linear system with Math.net

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;

How to get all possible pairs from an 4x4 Array in C#?

Let's say I have an 2x2 Array.
[1, 2]
[3, 4]
And I want to get all pairs possible.
[1, 2] [1, 3] [1, 4] [2, 3] [2, 4] [3, 4]
And I do not want reversed pairs like [2, 1].
Has anyone a good solution for this problem?
You will actually need three nested loops, or to convert your 2d list to 1d list and then to get your Permutations:
List<List<int>> My2DList = new List<List<int>>() { new List<int>(){ 1, 2 }, new List<int>(){ 3, 4 } }; // your initial 2d list
List<int> My1DList = My2DList.Cast<int>().ToList(); // convert to 1d list
List<List<int>> Permutations = new List<List<int>>(); // prepare a container
for (int i = 0; i < My1DList.Count; i++)
for(int j = i; j < My1DList.Count; j++)
Permutations.Add(new List<int>() { My1DList[i], My1DList[j] }); // add your permutations

How to get sub array that has maximum sum of all its items

My test is to solve this following problem:
A zero-indexed array A consisting of N integers is given.
Write a solution to find out the sub array of A, which contains consequent items that has the maximum sum of all its items.
Example:
A = [2, -1, 3, -3, 4, -9, 10, -3, 4, -4, -7, 2, 8]. The answer is [10, -3, 4]
A = [3, 2, -5, 7, 4, -8, 3, -5, 2, 4, -2, 4]. The answer is [7, 4]
A = [-2, 5, 3, 6, -1,-5]. The answer is [-2, 5, 3, 6].
Please help me to give me the way to resolve it.
Basicly, what you need to do is to traverse the array and check for the maximum value of the sum of elements. Once you have found the max sum, you have the last element of your resulting subarray.
Once you have found the max element, you need to traverse back and do the same in order to find the sub array with maximum sum of elements.
int iNewTopHigh = 0;
int iNewTopLow = 0;
int iIndNewTopHigh = 0;
int iIndNewTopLow = 0;
int iSumHigh = 0;
int iSumLow = 0;
int[] iArr = {2, -1, 3, -3, 4, -9, 10, -3, 4, -4, -7, 2, 8};
//{3, 2, -5, 7, 4, -8, 3, -5, 2, 4, -2, 4};
//{-2, 5, 3, 6, -1,-5};
//Get the top
for(int i = 0; i < iArr.Length; i++){
iSumHigh += iArr[i];
if(iSumHigh > iNewTopHigh){
iIndNewTopHigh = i;
iNewTopHigh = iSumHigh;
}
}
//Get the bottom
for(int i = iIndNewTopHigh; i != 0; i--){
iSumLow += iArr[i];
if(iSumLow > iNewTopLow){
iIndNewTopLow = i;
iNewTopLow = iSumLow;
}
}
//Print results
for(int i = iIndNewTopLow ; i <= iIndNewTopHigh; i++){
Console.Write(iArr[i] + ", ");
}

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;
}

How to split array in two arrays?

I have one array and want split it in to two:
Now: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
New_1: [0, 2, 4, 6, 8]
New_2: [1, 3, 5, 7, 9]
So take the one element and skip the next element.
Look easy but how can i do it with C#?
Thanks a lot
You can use linq, Enumerable.Where and get the array with elements that have even and odd indexes.
var New_1 = arr.Where((c,i) => i % 2 == 0).ToArray();
var New_2 = arr.Where((c,i) => i % 2 != 0).ToArray();
You can get the index of element of collection and apply condition to check if index is even or odd and get the arrays according.
Enumerable.Where Method (IEnumerable, Func) filters a sequence of values based on a predicate.
Each element's index is used in the logic of the predicate function.
The first argument of predicate represents the element to test. The
second argument represents the zero-based index of the element within
source, msdn
How about something like
int[] arr = new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int[] arr1 = arr.Where((x, i) => i % 2 == 0).ToArray();
int[] arr2 = arr.Where((x, i) => i % 2 == 1).ToArray();
int[] arr = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int i = 0;
List<int[]> twoArr = arr.GroupBy(x => i++ % 2).Select(g => g.ToArray()).ToList();

Categories

Resources