Do QR/SVD decomposition in ojalgo require as many rows as columns? - java

When doing QR or SVD decomposition on an m x n matrix A in ojalgo, I've hit a snag. My purpose is to find a basis for the column null space. If m >= n, things work fine. For instance, QR decomposition of the transpose A' of a 5 x 4 matrix A with rank 2 gives me a 4 x 4 Q matrix whose last two columns span the null space of A.
On the other hand, if I start with a 5 x 7 matrix A with rank 5 (and do a QR decomposition of A'), I get the correct rank, but Q is 5 x 5 rather than 7 x 7, and I don't get the null space basis. Similarly, SVD with that same matrix A gets me five positive singular values (no zeros), and the Q2 matrix is 5 x 7 rather than 7 x 7 (no null vectors).
Is this expected behavior? I found a work-around for matrices with n > m (adding n-m rows of zeros to A), but it's clunky.

The matrices can be any size/shape, but calculating the economy sized decomposition is the default behaviour. It is what most users need/want. But there is an interface MatrixDecomposition.EconomySize that lets you control this (to optionally get the full size decomposition). Currently the QR, SVD and Bidiagonal decompositions implement it.

Related

How to find Path of Lowest Cost in 2D matrix

i have a Challenge the objective is to get the lowest cost of the path.
The path can proceed horizontally or diagonally. not vertically. like below.
and the first and last row are also adjacent.
for example see below matrix:
output for 1st matrix :
16
1 2 3 4 4 5-->path row number
output for second matrix:
11
1 2 1 5 4 5-->path row number
am doing it in java, am getting the Lowest path but am not getting the path to print the path using row numbers.
int minCost(int cost[r][r], int m, int n)
{
if (n < 0 || m < 0)
return Integer.MAX_VALUE;;
else if ((m == r-1 && n == c-1)|| n+1>=c)
return cost[m][n];
else
return cost[m][n] + min( minCost(cost, m+1>=r?r-1:m+1,n+1),
minCost(cost, m,n+1),
minCost(cost, m-1>=0?m-1:r-1,n+1));
}
// calling it
minCost(cost, 0, 0);
How to get the row numbers for shortest path?
Your algorithm is quite inefficient. The best solution I can think is calculating it backwards(from right to left). Consider the right 2 columns of your second matrix:
8 6
7 4
9 5
2 6
2 3
If now we are on the cell with value 8, the next step can be 6/4/3. Of course we choose 3 because we want a smaller cost. If now we are on the cell with value 7, the next step can be 6/4/5, we will choose 4. So the two columns can merged into one column:
11 //8+3
11 //7+4
13 //9+4
5 //2+3
5 //2+3
Now repeat the last two columns:
2 11
2 11
9 13
3 5
1 5
Finally the matrix will be merged into one column, the smallest value in the column has the lowest cost.
I'll try to expand on fabian's comment:
It's clear that your minCost function will return the same values if called with the same arguments. In your algorithm, it indeed does get called lots of times with the same values. Every call for column zero will generate 3 calls for column 1, which in turn generate 9 calls for column 2, etc. The last column will get a huge number of calls (3^r as fabian pointed), most of them recalculating the very same values for other calls.
The idea is to store these values so they don't need to be recalculated every time they are needed. A very simple way of doing this is to create a new matrix of the same size as the original and calculating, column by column, the minimum sum for getting to each cell. The first column will be trivial (just copy from the original array, as there is only one step involved), and then proceed for the other columns reusing the values already calculated.
After that, you can optimize space usage by replacing the second matrix by only two columns, as you are not going to need column n-1 once you have column n fully calculated. This can be a bit tricky, so if you're unsure I recommend using the full array the first time.

Generate N random numbers in given ranges that sum up to a given sum

first time here at Stackoverflow. I hope someone can help me with my search of an algorithm.
I need to generate N random numbers in given Ranges that sum up to a given sum!
For example: Generatare 3 Numbers that sum up to 11.
Ranges:
Value between 1 and 3.
Value between 5 and 8.
value between 3 and 7.
The Generated numbers for this examle could be: 2, 5, 4.
I already searched alot and couldnt find the solution i need.
It is possible to generate like N Numbers of a constant sum unsing modulo like this:
generate random numbers of which the sum is constant
But i couldnt get that done with ranges.
Or by generating N random values, sum them up and then divide the constant sum by the random sum and afterwards multiplying each random number with that quotient as proposed here.
Main Problem, why i cant adopt those solution is that every of my random values has different ranges and i need the values to be uniformly distributed withing the ranges (no frequency occurances at min/max for example, which happens if i cut off the values which are less/greater than min/max).
I also thought of an soultion, taking a random number (in that Example, Value 1,2 or 3), generate the value within the range (either between min/max or min and the rest of the sum, depending on which is smaller), substracting that number of my given sum, and keep that going until everything is distributed. But that would be horrible inefficiant. I could really use a way where the runtime of the algorithm is fixed.
I'm trying to get that running in Java. But that Info is not that importend, except if someone already has a solution ready. All i need is a description or and idea of an algorithm.
First, note that the problem is equivalent to:
Generate k numbers that sums to a number y, such that x_1, ..., x_k -
each has a limit.
The second can be achieved by simply reducing the lower bound from the number - so in your example, it is equivalent to:
Generate 3 numbers such that x1 <= 2; x2 <= 3; x3 <= 4; x1+x2+x3 = 2
Note that the 2nd problem can be solved in various ways, one of them is:
Generate a list with h_i repeats per element - where h_i is the limit for element i - shuffle the list, and pick the first elements.
In your example, the list is:[x1,x1,x2,x2,x2,x3,x3,x3,x3] - shuffle it and choose first two elements.
(*) Note that shuffling the list can be done using fisher-yates algorithm. (you can abort the algorithm in the middle after you passed the desired limit).
Add up the minimum values. In this case 1 + 5 + 3 = 9
11 - 9 = 2, so you have to distribute 2 between the three numbers (eg: +2,+0,+0 or +0,+1,+1).
I leave the rest for you, it's relatively easy to create a uniform distribution after this transformation.
This problem is equivalent to randomly distributing an excess of 2 over the minimum of 9 on 3 positions.
So you start with the minima (1/5/3) and then cycle 2 times, generating a (pseudo-)random value of [0-2] (3 positions) and increment the indexed value.
e.g.
Start 1/5/3
1st random=1 ... increment index 1 ... 1/6/3
2nd random=0 ... increment index 0 ... 2/6/3
2+6+3=11
Edit
Reading this a second time, I understand, this is exactly what #KarolyHorvath mentioned.

Quickly find matrix in another matrix

if there is a matrix A[][] of order m and another matrix B[][] of order n such that (m>n) you have to find the occurrence of matrix B[][] in matrix A[][].
A[5][5]=
1,2,3,4,5
5,4,1,9,7
2,1,7,3,4
6,4,8,2,7
0,2,4,5,8
B[3][3]=
1,9,7
7,3,4
8,2,7
This matrix B exist in A. I can do it by sliding window algo TC O(p^2*n^2) where p = m-n+1. but I want to do this with minimum time complexity.
You can use the Boyer-Moore string search for problems like this:
Compare right to left. In the first row, you compare 3 with 7. 3 doesn't appear in the first row of B, so you can move your window to the right by 3 elements. When you start the loop again, the window doesn't fit into the remains of A's first row. This means you could process the first row with 2 compares.
In the next row, you compare 1 with 7. 1 appears in B, so you move your window just enough that the 1 in B is over the 1 in A.
The next level would then be to start comparing with the lower right corner of B. That would compare 7 with 7. Since 7 appears three times in B, you have to figure out how to move the window efficiently using similar rules as Boyer-Moore.
There is an abstract which I have found on stack-overflow previously . Hope this should give youwhat are the possible algorithms and approaches you could use . An algorithm for searching for a two dimensional m x m pattern in a two dimensional n x n
text is presented.

Logarithmic way of filtering sparse values..?

I have a situation where I show a matrix. The matrix contain values greater than or equal to 0. So to add convenience to the user I just added a bar slider whose minimum value is 0 and maximum value is the maximum value from the matrix. So when the user slides on the slider I just filter the matrix cells and show only those cells which have value greater than the slider value user has slided.
My issue is that in the matrix table the values are quite sparse like there are a lot of values in the range sometime 1-5 and then 20-25 (can be other ranges also). So when i slider the tables gets reduced a lot.
I want something now that on moving the slider only a few values gets filtered. I was thinking if there is any logarithmic way of solving this problem...or may be some other way..
If your matrix is size M x N consider storing the data in an array like data[L][2] where L = M x N and data[i][0] is the actual value while data[i][1] is the value's position in your original M x N matrix.
If data[i][0] is sorted you can process it faster to find positions with values under a given threshold.
Example:
Matrix
1 2 3
0 7 1
5 1 9
Array (value, position)
0 1 1 1 2 3 5 7 9
4 1 6 8 2 3 7 5 9
Cells with values less than 3: 4 1 6 8 2

Help with a Chemical Balancer? (Conversion from arraylists to matrix) in java

I am making a java application that balances chemical equations. I loop through each term and create two arraylists. In one arraylist, I have the set of all of the elements. For example (in the first term) if the equation is C6H12O6+O2=CO2+H2O, the arraylist will have {C, H, O}. In another, I have the corresponding numbers, so it will contain {6,12,6}. I need to combine all of these to form a matrix (3 by 4), which would be:
(0,0) = 6
(1,0) = 12
(2,0) = 6
(0,1) = 0
(1,1) = 0
(2,1) = 2
(0,2) = 1
(1,2) = 0
(2,2) = 2
(0,3) = 0
(1,3) = 2
(2,3) = 1
The matrix above is designed so that row 0 is C, row 1 is H, and row 2 is O. The columns are the terms (0, 1, 2, and 3)
Any suggestions for converting the arraylists into a matrix?
If you are doing this for fun or a project, fine. If you are doing this for a real extensible application to be used by chemists then you will need to cater for > 100 elements, many reagents and products and fractional amounts. There are a lot of Open Source Java chemistry libraries and I'd be happy to introduce you. Do not re-invent the wheel. See http://www.blueobelisk.org
To do this seriously requires a Bond/Electron matrix as developed by Ugi. Your best place is Ugi's own paper:
www.iupac.org/publications/pac/1978/pdf/5011x1303.pdf
see - e.g. p 1307.
EDIT:
This is overkill for the current problem!
A simple matrix approach would include 2 coupled matrices R (reactants) and P (products) with nelem (say 100) columns for known elements and an indefinite number of rows (nR, nP) as many reactants and products. The matrices would therefore generally not be of equal dimensions. reactant[nR][nelem] and product [nP][nelem]. There would also be two column vectors for the multipliers nreact[nR] and nprod[nP]. Note that in general chemical formulae and multipliers are commonly integral but need not be (may compounds do not have simple integer ratios of elements).
I would use my own CMLFormula and CMLReaction Java classed (see http://www.xml-cml.org) to tackle this. You are welcome to start there - it will make life easier
You can represent a matrix by arrays: think of each row as an array of column data:
[[6 12 6],
[0 0 2],
[1 0 2],
[0 2 1]]
This way, your matrix point is a reference to the array position inside another array at a given point. in other words:
matrix[0][2] == 2
(for the first array (0), second position (1))
I can't speak for or against your logic in the chemistry, though. :)
If you want good matrix operations in java look at JAMA (Java Matrix)

Categories

Resources