Freivald’s Algorithm to check if a matrix is product of two
Given three matrices A, B and C, find if C is a product of A and B.
Examples:
Input : A = 1 1
1 1
B = 1 1
1 1
C = 2 2
2 2
Output : Yes
C = A x B
Input : A = 1 1 1
1 1 1
1 1 1
B = 1 1 1
1 1 1
1 1 1
C = 3 3 3
3 1 2
3 3 3
Output : No
A simple solution is to find product of A and B and then check if product is equal to C or not. A possible time complexity of this method is O(n2.8874) using Stression’s matrix multiplication.
Freivalds’ algorithm is a probabilistic randomized algorithm that works in time O(n2) with high probability. In O(kn2) time the algorithm can verify a matrix product with probability of failure less than 2-k. Since the output is not always correct, it is a Monte Carlo randomized algorithm.
Steps :
- Generate an n × 1 random 0/1 vector r⃗.
- Compute P⃗ = A × (Br)⃗ – Cr⃗.
- Return true if P⃗ = ( 0, 0, …, 0 )T, return false otherwise.
The idea is based on the fact that if C is actually a product, then value of A × (Br)⃗ – Cr⃗ will always be 0. If the value is non-zero, then C can not be a product. The error condition is that the value may be 0 even when C is not a product.
C++
// CPP code to implement Freivald’s Algorithm #include <bits/stdc++.h> using namespace std; #define N 2 // Function to check if ABx = Cx int freivald(int a[][N], int b[][N], int c[][N]) { // Generate a random vector bool r[N]; for (int i = 0; i < N; i++) r[i] = random() % 2; // Now comput B*r for evaluating // expression A * (B*r) - (C*r) int br[N] = { 0 }; for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) br[i] = br[i] + b[i][j] * r[j]; // Now comput C*r for evaluating // expression A * (B*r) - (C*r) int cr[N] = { 0 }; for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cr[i] = cr[i] + c[i][j] * r[j]; // Now comput A* (B*r) for evaluating // expression A * (B*r) - (C*r) int axbr[N] = { 0 }; for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) axbr[i] = axbr[i] + a[i][j] * br[j]; // Finally check if value of expression // A * (B*r) - (C*r) is 0 or not for (int i = 0; i < N; i++) if (axbr[i] - cr[i] != 0) false; return true; } // Runs k iterations Freivald. The value // of k determines accuracy. Higher value // means higher accuracy. bool isProduct(int a[][N], int b[][N], int c[][N], int k) { for (int i=0; i<k; i++) if (freivald(a, b, c) == false) return false; return true; } // Driver code int main() { int a[N][N] = { { 1, 1 }, { 1, 1 } }; int b[N][N] = { { 1, 1 }, { 1, 1 } }; int c[N][N] = { { 2, 2 }, { 2, 2 } }; int k = 2; if (isProduct(a, b, c, k)) printf("Yes"); else printf("No"); return 0; } |
Java
// Java code to implement // Freivald's Algorithm import java.io.*; import java.util.*; import java.math.*; class GFG { static int N = 2; // Function to check if ABx = Cx static boolean freivald(int a[][], int b[][], int c[][]) { // Generate a random vector int r[] = new int[N]; for (int i = 0; i < N; i++) r[i] = (int)(Math.random()) % 2; // Now comput B*r for evaluating // expression A * (B*r) - (C*r) int br[] = new int[N]; Arrays.fill(br, 0); for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) br[i] = br[i] + b[i][j] * r[j]; // Now comput C*r for evaluating // expression A * (B*r) - (C*r) int cr[] = new int[N]; Arrays.fill(cr, 0); for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cr[i] = cr[i] + c[i][j] * r[j]; // Now comput A* (B*r) for evaluating // expression A * (B*r) - (C*r) int axbr[] = new int[N]; Arrays.fill(axbr, 0); for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) axbr[i] = axbr[i] + a[i][j] * br[j]; // Finally check if value of expression // A * (B*r) - (C*r) is 0 or not for (int i = 0; i < N; i++) if (axbr[i] - cr[i] != 0) return false; return true; } // Runs k iterations Freivald. The value // of k determines accuracy. Higher value // means higher accuracy. static boolean isProduct(int a[][], int b[][], int c[][], int k) { for (int i = 0; i < k; i++) if (freivald(a, b, c) == false) return false; return true; } // Driver code public static void main(String args[]) { int a[][] = { { 1, 1 }, { 1, 1 } }; int b[][] = { { 1, 1 }, { 1, 1 } }; int c[][] = { { 2, 2 }, { 2, 2 } }; int k = 2; if (isProduct(a, b, c, k)) System.out.println("Yes"); else System.out.println("No"); } } /*This code is contributed by Nikita Tiwari.*/ |
Python3
# Python3 code to implement Freivald’s Algorithm from random import *N = 2 # Function to check if ABx = Cx def freivald(a, b, c) : # Generate a random vector r = [0] * N for i in range(0, N) : r[i] = (int)(random()) % 2 # Now comput B*r for evaluating # expression A * (B*r) - (C*r) br = [0] * N for i in range(0, N) : for j in range(0, N) : br[i] = br[i] + b[i][j] * r[j] # Now comput C*r for evaluating # expression A * (B*r) - (C*r) cr = [0] * N for i in range(0, N) : for j in range(0, N) : cr[i] = cr[i] + c[i][j] * r[j] # Now comput A* (B*r) for evaluating # expression A * (B*r) - (C*r) axbr = [0] * N for i in range(0, N) : for j in range(0, N) : axbr[i] = axbr[i] + a[i][j] * br[j] # Finally check if value of expression # A * (B*r) - (C*r) is 0 or not for i in range(0, N) : if (axbr[i] - cr[i] != 0) : return False return True # Runs k iterations Freivald. The value # of k determines accuracy. Higher value # means higher accuracy. def isProduct(a, b, c, k) : for i in range(0, k) : if (freivald(a, b, c) == False) : return False return True # Driver code a = [ [ 1, 1 ], [ 1, 1 ] ] b = [ [ 1, 1 ], [ 1, 1 ] ] c = [ [ 2, 2 ], [ 2, 2 ] ] k = 2 if (isProduct(a, b, c, k)) : print("Yes") else : print("No") # This code is contributed by Nikita Tiwari |
C#
// C# code to implement // Freivald's Algorithm using System; class GFG { static int N = 2; // Function to check // if ABx = Cx static bool freivald(int [,]a, int [,]b, int [,]c) { // Generate a // random vector Random rand = new Random(); int []r = new int[N]; for (int i = 0; i < N; i++) r[i] = (int)(rand.Next()) % 2; // Now compute B*r for // evaluating expression // A * (B*r) - (C*r) int []br = new int[N]; for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) br[i] = br[i] + b[i, j] * r[j]; // Now compute C*r for // evaluating expression // A * (B*r) - (C*r) int []cr = new int[N]; for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cr[i] = cr[i] + c[i, j] * r[j]; // Now compute A* (B*r) for // evaluating expression // A * (B*r) - (C*r) int []axbr = new int[N]; for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) axbr[i] = axbr[i] + a[i, j] * br[j]; // Finally check if value // of expression A * (B*r) - // (C*r) is 0 or not for (int i = 0; i < N; i++) if (axbr[i] - cr[i] != 0) return false; return true; } // Runs k iterations Freivald. // The value of k determines // accuracy. Higher value // means higher accuracy. static bool isProduct(int [,]a, int [,]b, int [,]c, int k) { for (int i = 0; i < k; i++) if (freivald(a, b, c) == false) return false; return true; } // Driver code static void Main() { int [,]a = new int[,]{ { 1, 1 }, { 1, 1 }}; int [,]b = new int[,]{ { 1, 1 }, { 1, 1 }}; int [,]c = new int[,]{ { 2, 2 }, { 2, 2 }}; int k = 2; if (isProduct(a, b, c, k)) Console.WriteLine("Yes"); else Console.WriteLine("No"); } } // This code is contributed // by Manish Shaw(manishshaw1) |
PHP
<?php // PHP code to implement // Freivald’s Algorithm $N = 2; // Function to check // if ABx = Cx function freivald($a, $b, $c) { global $N; // Generate a // random vector $r = array(); $br = array(); $cr = array(); $axbr = array(); for ($i = 0; $i < $N; $i++) { $r[$i] = mt_rand() % 2; $br[$i] = 0; $cr[$i] = 0; $axbr[$i] = 0; } // Now comput B*r for // evaluating expression // A * (B*r) - (C*r) for ($i = 0; $i < $N; $i++) { for ($j = 0; $j < $N; $j++) $br[$i] = $br[$i] + $b[$i][$j] * $r[$j]; } // Now comput C*r for // evaluating expression // A * (B*r) - (C*r) for ($i = 0; $i < $N; $i++) { for ($j = 0; $j < $N; $j++) $cr[$i] = $cr[$i] + $c[$i][$j] * $r[$j]; } // Now comput A* (B*r) for // evaluating expression // A * (B*r) - (C*r) for ($i = 0; $i < $N; $i++) { for ($j = 0; $j < $N; $j++) $axbr[$i] = $axbr[$i] + $a[$i][$j] * $br[$j]; } // Finally check if value // of expression A * (B*r) - // (C*r) is 0 or not for ($i = 0; $i < $N; $i++) if ($axbr[$i] - $cr[$i] != 0) return false; return true; } // Runs k iterations Freivald. // The value of k determines // accuracy. Higher value // means higher accuracy. function isProduct($a, $b, $c, $k) { for ($i = 0; $i < $k; $i++) if (freivald($a, $b, $c) == false) return false; return true; } // Driver code $a = array(array(1, 1), array(1, 1)); $b = array(array(1, 1), array(1, 1)); $c = array(array(2, 2), array(2, 2)); $k = 2; if (isProduct($a, $b, $c, $k)) echo ("Yes"); else echo ("No"); // This code is contributed // by Manish Shaw(manishshaw1) ?> |
Yes
Recommended Posts:
- Check if a pair with given product exists in a Matrix
- Check if matrix can be converted to another matrix by transposing square sub-matrices
- Program to check diagonal matrix and scalar matrix
- Check if it is possible to make the given matrix increasing matrix or not
- Program to check if a matrix is Binary matrix or not
- Product of middle row and column in an odd square matrix
- Maximum product of 4 adjacent elements in matrix
- Strassen’s Matrix Multiplication Algorithm | Implementation
- Kruskal's Algorithm (Simple Implementation for Adjacency Matrix)
- Prim's Algorithm (Simple Implementation for Adjacency Matrix Representation)
- Ways of filling matrix such that product of all rows and all columns are equal to unity
- Check if a given matrix is Hankel or not
- Check if a Matrix is Invertible
- Check if a given matrix is sparse or not
- Check for possible path in 2D matrix
If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.
Improved By : manishshaw1



