Determinant of a square binary matrix c++ [duplicate] - c++

Can anyone tell me which is the best algorithm to find the value of determinant of a matrix of size N x N?

Here is an extensive discussion.
There are a lot of algorithms.
A simple one is to take the LU decomposition. Then, since
det M = det LU = det L * det U
and both L and U are triangular, the determinant is a product of the diagonal elements of L and U. That is O(n^3). There exist more efficient algorithms.

Row Reduction
The simplest way (and not a bad way, really) to find the determinant of an nxn matrix is by row reduction. By keeping in mind a few simple rules about determinants, we can solve in the form:
det(A) = α * det(R), where R is the row echelon form of the original matrix A, and α is some coefficient.
Finding the determinant of a matrix in row echelon form is really easy; you just find the product of the diagonal. Solving the determinant of the original matrix A then just boils down to calculating α as you find the row echelon form R.
What You Need to Know
What is row echelon form?
See this [link](http://stattrek.com/matrix-algebra/echelon-form.aspx) for a simple definition
**Note:** Not all definitions require 1s for the leading entries, and it is unnecessary for this algorithm.
You Can Find R Using Elementary Row Operations
Swapping rows, adding multiples of another row, etc.
You Derive α from Properties of Row Operations for Determinants
If B is a matrix obtained by multiplying a row of A by some non-zero constant ß, then
det(B) = ß * det(A)
In other words, you can essentially 'factor out' a constant from a row by just pulling it out front of the determinant.
If B is a matrix obtained by swapping two rows of A, then
det(B) = -det(A)
If you swap rows, flip the sign.
If B is a matrix obtained by adding a multiple of one row to another row in A, then
det(B) = det(A)
The determinant doesn't change.
Note that you can find the determinant, in most cases, with only Rule 3 (when the diagonal of A has no zeros, I believe), and in all cases with only Rules 2 and 3. Rule 1 is helpful for humans doing math on paper, trying to avoid fractions.
Example
(I do unnecessary steps to demonstrate each rule more clearly)
| 2 3 3 1 |
A=| 0 4 3 -3 |
| 2 -1 -1 -3 |
| 0 -4 -3 2 |
R2 R3, -α -> α (Rule 2)
| 2 3 3 1 |
-| 2 -1 -1 -3 |
| 0 4 3 -3 |
| 0 -4 -3 2 |
R2 - R1 -> R2 (Rule 3)
| 2 3 3 1 |
-| 0 -4 -4 -4 |
| 0 4 3 -3 |
| 0 -4 -3 2 |
R2/(-4) -> R2, -4α -> α (Rule 1)
| 2 3 3 1 |
4| 0 1 1 1 |
| 0 4 3 -3 |
| 0 -4 -3 2 |
R3 - 4R2 -> R3, R4 + 4R2 -> R4 (Rule 3, applied twice)
| 2 3 3 1 |
4| 0 1 1 1 |
| 0 0 -1 -7 |
| 0 0 1 6 |
R4 + R3 -> R3
| 2 3 3 1 |
4| 0 1 1 1 | = 4 ( 2 * 1 * -1 * -1 ) = 8
| 0 0 -1 -7 |
| 0 0 0 -1 |
def echelon_form(A, size):
for i in range(size - 1):
for j in range(size - 1, i, -1):
if A[j][i] == 0:
continue
else:
try:
req_ratio = A[j][i] / A[j - 1][i]
# A[j] = A[j] - req_ratio*A[j-1]
except ZeroDivisionError:
# A[j], A[j-1] = A[j-1], A[j]
for x in range(size):
temp = A[j][x]
A[j][x] = A[j-1][x]
A[j-1][x] = temp
continue
for k in range(size):
A[j][k] = A[j][k] - req_ratio * A[j - 1][k]
return A

If you did an initial research, you've probably found that with N>=4, calculation of a matrix determinant becomes quite complex. Regarding algorithms, I would point you to Wikipedia article on Matrix determinants, specifically the "Algorithmic Implementation" section.
From my own experience, you can easily find a LU or QR decomposition algorithm in existing matrix libraries such as Alglib. The algorithm itself is not quite simple though.

I am not too familiar with LU factorization, but I know that in order to get either L or U, you need to make the initial matrix triangular (either upper triangular for U or lower triangular for L). However, once you get the matrix in triangular form for some nxn matrix A and assuming the only operation your code uses is Rb - k*Ra, you can just solve det(A) = Π T(i,i) from i=0 to n (i.e. det(A) = T(0,0) x T(1,1) x ... x T(n,n)) for the triangular matrix T. Check this link to see what I'm talking about. http://matrix.reshish.com/determinant.php

Related

How do optimize my code to find product of all the contiguous subsequences of an array?

This is my try to count the contiguous subsequences of an array with product mod 4 is not equal to 2:
# include <iostream>
using namespace std;
int main() {
long long int n, i, j, s, t, count = 0;
cin>>n;
long long int arr[n];
count = 0;
for(i = 0; i<n; i++) {
cin>>arr[i];
}
for(i = 0; i<n; i++) {
s = 1;
for(j = i; j<n; j++) {
s = s*arr[j];
if(s%4!=2) {
count++;
}
}
}
cout<<count;
return 0;
}
However, I want to reduce the time taken by my code to execute. I am looking for a way to do it. Any help/hint would be appreciated.
Thank you.
What does this definition of contiguous subsequences mean?
Listing all the subsequences
Suppose we have the sequence:
A B C D E F
First of all, we should recognize that there is one substring for every unique start and end point. Let's use the notation C-F to mean all items from C through F: i.e.: C D E F.
We can list all subsequences in a triangular arrangement like this:
A B C D E F
A-B B-C C-D D-E E-F
A-C B-D C-E D-F
A-D B-E C-F
A-E B-F
A-F
The first row lists all the subsequences of length 1.
The second row lists all the subsequences of length 2.
The third row lists all the subsequences of length 3. Etc.
The last row is the full sequence.
Modular arithmetic
Computing the product MOD 4 of a set of numbers
To figure out the product of a bunch of numbers MOD 4, we just need to look at each element of the set MOD 4. Intuitively, this is because when you multiply a bunch of numbers, the last digit of the result is determined entirely by the last digit of each factor. In this case "the last digit base 4" is the number mod 4.
The identity we are using is:
(A * B) MOD N == ((A MOD N) * (B MOD N)) MOD N
The table of products
Now we also have to look at the matrix of possible multiplications that might happen. It's a fairly small table and the interesting entries are given here:
2 * 2 = 4 4 MOD 4 = 0
2 * 3 = 6 6 MOD 4 = 2
3 * 3 = 9 9 MOD 4 = 1
So the results of multiplying any 2 numbers MOD 4 are given by this table:
+--------+---+---+---+---+
| Factor | 0 | 1 | 2 | 3 |
+--------+---+---+---+---+
| 0 | 0 | / | / | / |
| 1 | 0 | 1 | / | / |
| 2 | 0 | 2 | 0 | / |
| 3 | 0 | 3 | 2 | 1 |
+--------+---+---+---+---+
The /'s are omitted because of the symmetry of multiplication (A * B = B * A)
An example sequence
Now for each subsequence, let's compute the product MOD 4 of its elements.
Consider the following list of numbers
242 497 681 685 410 795
The first thing we do is take all these numbers MOD 4 and list them as the first row of our list of all subsequences triangle.
2 0 1 1 2 3
The second row is just the product of the pairs above it.
2 0 1 1 2 3
0 0 1 2 3
In general, the Nth element of each row is the product, MOD 4, of:
the number just to its left in the row above left times and
the element in the first row that is diagonally to its right
For example C = A * B
* * * * B *
* * * / *
* A / *
* C *
* *
*
Again,
A is immediately up and left of C
B is diagonally right all the way to the top row from C
Now we can complete our triangle
2 0 1 1 2 3
0 0 1 2 3
0 0 2 3
0 0 2
0 0
0
This can be computed easily in O(n^2) time.
Optimization
These optimizations do not improve the time complexity of the algorithm in its worse case, but can cause an early exit in the computation, and should therefore be included if time is to be reduced and the input is unknown.
Contageous 0's
Furthermore, as a matter of optimization, notice how contagious the 0's are. Anything times 0 is 0, so you can skip computing products of cells below a 0. In your case those sequences will not equal 2 MOD 4 once the product of one of its subsequences is determined to be equal to 0 MOD 4.
* * * 0 * * // <-- this zero infects all cells below it
* * 0 0 *
* 0 0 0
0 0 0
0 0
0
Need a 2 to make a 2.
Look back at the table of factors and products. Notice that the only way to get a product that is equal to 2 MOD 4 is to have one of the factors be equal to 2 MOD 4. What that means is that there can only be a 2 below another 2. So we are only interested in following computing entries in the table that are below a 2. Other entries in rows below can never become a 2.
You don't have to store more than the whole rows.
You only need O(n) storage to implement this. Working line by line, you can compute the values in a row entirely from the values in the first row and values in the row above.
Reading the answers from the table
Now you can look at the rows of the triangle list as you generate them and read off which subsequences are to be included.
Entries with a 2 are to be excluded. All others are to be included.
2 0 1 1 3 2
0 0 1 3 2
0 0 3 2
0 0 2
0 0
0
The excluded subsequences for the example (which I will list only because there are fewer of them in my example) are:
A
F
E-F
D-F
C-F
Which remember, according to our convention refer to the elements:
A
F
E F
D E F
C D E F
Which are:
242
795
410 795
685 410 795
681 685 410 795
Hopefully it's obvious how to display the "included" sequences, rather than the "excluded" sequences, as I have shown above.
Displaying all the elements makes it take much longer.
Sadly, actually displaying all of the elements of such subsequences is still an O(N^3) operation in the worst case. (Imagine a sequence of all zeros.)
Summary
For me, I feel like an average developer could take the magic bullet observation made in the diagram below and write an implementation that has optimal time complexity.
C = A * B
* * * * B *
* * * / *
* A / *
* C *
* *
*

Armadillo C++ : Linear Combination with modulus calculations

I want to extract linear combinations from matrices but by performing combinations in modulus.
Let us consider the calculation modulus 5, we then have the following for the addition:
+ | 0 1 2 3 4
--+-----------
0 | 0 1 2 3 4
1 | 1 2 3 4 0
2 | 2 3 4 0 1
3 | 3 4 0 1 2
4 | 4 0 1 2 3
and this table for the multiplication:
* | 0 1 2 3 4
--+-----------
0 | 0 0 0 0 0
1 | 0 1 2 3 4
2 | 0 2 4 1 3
3 | 0 3 1 4 2
4 | 0 4 3 2 1
So let us take an example:
Let us consider the following matrix:
E = 2 1 3 2 0
4 3 0 1 1
Then we can obtain the triangulation matrix by applying a LU decomposition (https://en.wikipedia.org/wiki/LU_decomposition) (or a Gaussian Elimination), which is the following:
T = 1 0 0 0 0
2 1 0 0 0
and finally, the matrix that I want to extract, which is the one storing the linear combinations:
CL = 3 2 3 0 3
0 1 1 3 4
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
So basically, the algorithm should work as follows:
Input: a matrix E with n rows and m columns, and p, a prime number.
* We perform a Gaussian elimination/LU decomposition to obtain the lower-triangulation matrix T.
But all the calculus are done modulo 'p'.
Output: T (with the same size as E, n rows m columns).
CL (with a size m rows, m columns),
which is basically the identity matrix on which we
applied all the modifications that were performed on E to obtain T.
Alright, so now we have the context, let me explain the problem.
I started to do it using the Armadillo library (http://arma.sourceforge.net/), but I did not find any solution on the library to perform the calculus on a mathematical Field p. I easily found the LU method to obtain the lower-triangle matrix, but the calculations are performed in the real.
#include <iostream>
#include <armadillo>
using namespace arma;
using namespace std;
int main(int argc,char** argv)
{
mat A = mat({{2,1,3,2,0},{4,3,0,1,1}});
mat L, U, P;
lu(L, U, P, A);
cout << L << endl;
return 0;
}
With the following, you obtain the lower-triangle matrix 'L' but in the real calculus. Thus you obtain:
T' = 1 0
1/2 1
Is there any technique to perform the computation in a modulus way?
EDIT The Armadillo library is not able to do it. I developed my own LU decomposition in modulus but there is still a bug there. I asked a new question here Linear Combination C++ in modulus, hoping to solve it.
First of all: drop the using namespaces, code can become completely unreadable if you do that.
I haven't used Armadillo yet. But I have looked at the documentation, and it seems templated to me.
Now things are getting a bit wild. The type you use, arma::mat seems to be a typedef on arma::Mat<double>.
The high-level function arma::lu isn't properly documented. It obviously does an LU-decomposition, but I don't know if the function is templated. If it is, i.e., you cannot just call it with double mats but also other types, you might have a shot using a custom type representing the field (since 5 is prime, otherwise you'd be completely lost) of calculations modulo 5. Meaning you write a class, let's call it IntMod5 and define all required operators for this class, meaning all operators that IntMod5 uses. For example, you'd need to define operator/(), e.g. by making a table of inverses of 4 of the 5 elements of the field (0 has none), i.e. 1->1, 2->3, 3->2, 4->4, and define
IntMod5 operator/(const IntMod5& o) const
{
return IntMod5((this->value*inverse(o.value))%5);
}
This is just one example, you likely need to define all arithmetic operators, binary and unary, and possibly more such as comparison (LU decomposition might use finding good pivot elements). If you're lucky and the library is written in a way that it works for any field, not just floating point, you have a chance.
Before you go through all the work, you should use a trivial class simply wrapping double and check if arma::Mat or arma::lu do any type checks blocking you out.
If either of these fails, you'll likely have to write your own LU decomposition modulo 5 or find another library that supports it.

Is Dilation/Erosion with fixed kernel for a number of iterations is similar to dilating/eroding with equivalent kernel of bigger size

While going through the OpenCV source code, I noticed that for iterations more than one it just creates a kernel of bigger size and do a single iteration.
So my question is if we take SQUARE structuring element of 3x3 size and dilate/erode it in three iterations, will it be same as dilating/eroding it with a 9x9 kernel once.
if( iterations > 1 && countNonZero(kernel) == kernel.rows*kernel.cols )
{
anchor = Point(anchor.x*iterations, anchor.y*iterations);
kernel = getStructuringElement(MORPH_RECT,
Size(ksize.width + (iterations-1)*(ksize.width-1),
ksize.height + (iterations-1)*(ksize.height-1)),
anchor);
iterations = 1;
}
Refering to Jordi's Answer:
[Quoted] ... Note, however, that this does not hold for all structuring elements...
In fact, it holds, in the following way (not in Jordi's example):
First step, calculate the 5x5 kernel by dilation twice in 3x3 kernel on a single center point 5x5 source image:
00000 00000 00100
00000 010 00100 010 01110
00100 + 111 -> 01110 + 111 -> 11111 ===> this is the equivalent 5x5 kernel for 2x 3x3 dilation
00000 010 00100 010 01110
00000 00000 00100
Then applying twice of 3x3 original dilation kernel is equivalent to applying this 5x5 dilation kernel on a bigger image. For example:
0000000000 0000000000 00100
0000000000 010 010 0000000000 01110
0011100000 + 111 + 111 === 0011100000 + 11111
0000001000 010 010 0000001000 01110
0000000000 0000000000 00100
0000000000 0000000000
This does not directly answer your question though. However, I can not just use 'comment' as it is very hard (if not impossible) to format all these equations/explanations.
In fact, a proof for binary image (image with only value 0 or 1 in each pixel) for the larger combined kernel for dilation is easy:
Let's define the binary operator + to be the dilation operator, where the 1st operand is the kernel, and the second operand is the image to be dilated.. So, if we want to do dilation on image I with kernel K, we write dilated-image = K + I
Let's define binary operator U to be the union operator, or, in other word, the binary 'OR' operator for each pixel, where the two operand of U must be binary images in the same dimension. For example: A U B means doing -OR- on each corresponding pixel of A and B:
A= 0 0 1 B= 0 1 1
1 0 1 1 1 1
1 1 0 0 1 0
Then
A U B = 0 1 1
1 1 1
1 1 0
We also define U A(i), i=1, ..., n to be A(1) U A(2) U ... U A(n).
Let's define K^n to be the dilation-styled larger kernel by applying n times of kernel K on a single center point image.
Note that any image I, we can decompose it into union of single point images. For example,
0 1 0 0 1 0 0 0 0 0 0 0
I = 0 0 0 === 0 0 0 U 0 0 0 U 0 0 0
1 0 1 0 0 0 1 0 0 0 0 1
Now it's time to prove it:
For any image I, we define D(i), i = 1, ..., n to be the single point decomposition of I,
and thus I = U D(i), i = 1, ..., n
By definition of the binary dilation, K + I == K + (U D(i)) == U (K+D(i)).
(Remember that dilation is to mask kernel K on each pixel of I, and mark all corresponding 1's).
Now, let's see what is K + (K + I):
K + (K + I) == K + U (K + D(i))
== U(K + (K + D(i))) (Note: this is tricky. see Theorem 1 below)
== U (K^2 + D(i)) (by definition of K^2)
== K^2 + U D(i) (by definition of the dilation)
== K^2 + I (since I = U D(i))
Now, we already know K + (K + I) == K^2 + I, and it's easy to apply mathematical induction to prove that K + K + K .. + K + I = K^n + I (Note: please apply right association, as I have drop the parenthesis).
Theorem 1: Proof of the deduction from K + U (K + D(i)) to U(K + (K+D(i)))
It's suffice to just prove that for any two binary images A and B in a same dimension,
K + (A U B) = (K+A) U (K+B)
It's quite easy to see that, if we decompose image A and B, and apply kernel K on the decomposed images, those common points (i.e. the intersection points of A and B, or the common 1's point of A and B), will contribute the same resulting points after applying kernel K. And by the definition of dilation, we need to union all points contributed by each decomposed image of A and B. Thus Theorem 1 holds.
=== UPDATE ===
Regarding to kid.abr's comment "27 operations compared to 7x7 kernel with 49 operations":
Generally speaking, it is not 27 operations. It depends. For example, a source image of 100x100 pixels,
with 20 singular point (1's) sparsely distributed. Applying a 3x3 solid kernel (i.e. All 1's) 3 times on it
requires the following steps for each of the 20 singular point:
Loop 1: 9 operations, and generate 9 points.
Loop 2: For each of the 9 points generated, it needs 9 operations => 9 x 9 = 81 steps. And it generates 25 points
Loop 3: For each of the 25 points generated, it needs 9 operations => 25 x 9 = 225 steps.
Total: 9 + 81 + 225 = 315 steps.
Please note that when we visit a pixel with 0 value in the source image, we don't need to apply the kernel
on that point, right?
So, the same case applying the larger kernel, it requires 7x7 = 49 steps.
Yet, if the source image has a large solid area of 1's, the 3-step method wins.
Short answer: with a square structuring element, yes.
Long answer: you need to consider what the erosion/dilation operations do. Dilation, for instance, moves the kernel over the image and sets its centre to 1 whenever any of its grid positions are 1 (I'm assuming binary images, it works the same for greyscale). Increasing the distance between the centre of the structuring element and its edges is then the same as increasing the size of the kernel.
Note, however, that this does not hold for all structuring elements. Suppose you take a structuring element that is just a stretched plus, obviously dilating twice with size 3 is not the same as dilating once with size 5:
00000 00000 00100
00000 010 00100 010 01110
00100 + 111 -> 01110 + 111 -> 11111
00000 010 00100 010 01110
00000 00000 00100
00000 00100 00100
00000 00100 00100
00100 + 11111 -> 11111
00000 00100 00100
00000 00100 00100
Of course, this does work if we define the scaled version of plus as a square without its corners (as it usually would be). I think that in general this shortcut works when the kernel of size k+1 is the dilated version of the kernel of size k, but I have no proof for this.
Short answer for a general kernel: Yes for dilation/erosion, but not necessarily with an equivalent kernel.
From wikipedia:
Dilation: (A⊕B)⊕C = A⊕(B⊕C)
Erosion: (A⊖B)⊖C = A⊖(B⊕C)
Where ⊕ denotes the morphological dilation, and ⊖ denotes the morphological erosion.
Basically, performing erosion/dilation on image A with kernel B and then kernel C is equivalent to performing erosion/dilation on image A with the kernel obtained by dilating B with C. This can easily be expanded to an arbitrary number erosions/dilations.

Queue with mod operation

I'm studying fundamental of data structure (Queue) , so far I understand the flow of Queue but I don't understand whenever queue is applying with Mod operator. There a several question which confusing my brain. How to answer this question (refer to picture)?
The best method for handling circular queues is to draw them out. Since circles don't post very well with ASCII art, I'll use a linear array.
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
0 1 2 3 4
^
Rear
The REAR is at index 4.
Let's perform the operation step by step.
First: Add 1 to REAR. This makes REAR point beyond the array:
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
0 1 2 3 4 5
^
Rear
Applying the modulo operation, %, this will give us the remainder of 5 / 5 which is zero:
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
0 1 2 3 4
^
Rear
Thus the modulo operation wraps around the array, like a circle.
The next question is for you to solve. Remember draw the array or queue. You can use circles (think of a pie sliced or a pizza sliced).
Edit 1: Modulo details
The modulo operation will give a value in the range 0..N, when N is the divisor.
Given N == 4, here are some results for modulo:
Index result
0 0
1 1
2 2
3 3
4 0 --> The remainder of 4 / 4 == 0.
5 1
6 2
7 3
8 0 --> The remainder of 8 / 4 == 0.
Modulus returns the remainder of the two operands. For example, 4%2=0 since 4/2=2 with no remainder, while 4%3=1 since 4/3=1 with remainder 1. Since you can never have a remainder higher than the right operand, you have an effective "range" of answers for any modulus of 0 to (n-1). With that in mind, just plug in the numbers for the variables ((4+1)%5=? and (1+1)%4=?). Usually to find the remainder you would use long division, but one useful thing to remember is that any number divided by itself has a remainder of 0, and any number divided by a larger number will have a remainder equal to itself.

Combinational Circuit with LED Lighting

Combinational Circuit design question.
A
____
| |
F | | B
| |
____
| G |
E | | C
| |
____
D
Suppose this is a LED display. It would take input of 4 bit
(0000)-(1111) and display the Hex of it. For example
if (1100) come in it would display C by turning on AFED and turning off BCG.
If (1010) comes in it would display A by turning on ABCEFG
and turn off D.
These display will all be Capital letters so there is no visual
difference between 0 and D and 8 and B.
Develop a truth table and an optimized expression using Karnaugh Maps.
I'm not exactly sure how to begin. For the truth table would I be using (w,x,y,z) as input variable or just the ABCDEFG variable since it's the one turning on and off?
input (1010)-->A--> ABCEFG~D (~ stand for NOT)
input (1011)-->B--> ABCDEFG
input (1100)-->C--> ADEF~B~C~G
So would I do for all hex 0-F then that would give me the min. term canonical then use Karnaugh Map to optimize it? Any help would be grateful!
1) Map your lights to bits:
ABCDEFG, so truth table will be:
ABCDEFG
input (1010)-->A-->1110110
and so on.
You will have big table (with 16 rows).
2) Then follow sample on wikipedia for every output light.
You need to do 7 of these: Each for one segment in the 7-segment display.
This figure is for illustration only. It doesn't necessarily map to any segment in your problem.
cd=00 01 11 10 <-- where abcd = 0000 for 0 : put '1' if the light is on
ab= 00 1 1 1 1 = 0001 for 1 : put '0' if it's off for
ab= 01 1 1 1 0 = 0010 for 2 ... the given segment
ab= 11 0 1 1 1
ab= 10 1 1 1 0 = 1111 for f
^^^^ = d=1 region
^^^^ = c==1 region
The two middle rows represent "b==1" region and the two last rows are a==1 region.
From that map find maximum size rectangles (that are of size [1,2 or 4] x [1, 2 or 4]); that can be overlapping. The middle 2x4 region is coded as 'd'. The top row is '~a~b'. The top left 2x2 square is '~a~c'. A bottom left square that wraps from row 4 to row 1 is '~b~c'. Finally the small 2x1 region that covers position x=4, y=3 is 'abc'.
This function would thus be 'd + ~a~b + ~a~c + ~b~c + abc'. If there are no redundant squares (that are completely covered by other squares), then this formula should be optimal canonical form. (not counting XOR operation). Repeat for 7 times for the real data!
Any selection/permutation of the variables should give the same logical circuit, whether you use abcd or dcba or acbd etc.