void strassen_mm(
    const unsigned int m,
    const unsigned int n,
    const unsigned int k,
    const Dtype *A, const int incRowA,
    const Dtype *B, const int incRowB,
    Dtype *C, const int incRowC){

    int max_length = maxThree(m, n, k);
    int new_length = getNumberLargerThanXAndIsPowerOfTwo(max_length);
    Dtype* newA = pad_matrix(A, m, k, incRowA, new_length, new_length);
    Dtype* newB = pad_matrix(B, k, n, incRowB, new_length, new_length);
    Dtype* newC = pad_matrix(C, m, n, incRowC, new_length, new_length);

    strassen_mm_worker(
        new_length, new_length, new_length,
        newA, new_length,
        newB, new_length,
        newC, new_length);

    matrix_copyTo(newC, new_length, new_length, new_length,
                  C, m, n, incRowC);

    // remove the extra workspace
    remove_matrix(newA);
    remove_matrix(newB);
    remove_matrix(newC);
}
Exemple #2
0
ImplicitSystem::~ImplicitSystem ()
{
  // Clear data
  this->clear();

  remove_matrix("System Matrix");
}
Dtype* strassen_make_M2_submatrix(
    const unsigned int m,
    const unsigned int n,
    const unsigned int k,    
    const Dtype *A_2_1, const int incRowA_2_1,
    const Dtype *A_2_2, const int incRowA_2_2,
    const Dtype *B_1_1, const int incRowB_1_1){

    /*
    construct M2 by the formula
    M2 = (A_2_1 + A_2_2) * B_1_1
    */
    // T1 = A_2_1 + A_2_2
    Dtype* T1 = make_matrix(m, k);

    matrix_addition(m, k,
        A_2_1, incRowA_2_1,
        A_2_2, incRowA_2_2,
        T1, k);

    Dtype* M2 = make_matrix(m, k);
    strassen_mm_worker(
        m, n, k,
        T1, k,
        B_1_1, incRowB_1_1,
        M2, k);

    remove_matrix(T1);
    return M2;
}
Dtype* strassen_make_M5_submatrix(
    const unsigned int m,
    const unsigned int n,
    const unsigned int k,    
    const Dtype *A_1_1, const int incRowA_1_1,
    const Dtype *A_1_2, const int incRowA_1_2,
    const Dtype *B_2_2, const int incRowB_2_2){

    /*
    construct M5 by the formula
    M5 = (A_1_1 + A_1_2) * B_2_2
    */
    // T1 = A_1_1 + A_1_2
    Dtype* T1 = make_matrix(m, k);
    matrix_addition(m, k,
        A_1_1, incRowA_1_1,
        A_1_2, incRowA_1_2,
        T1, k);

    Dtype* M5 = make_matrix(m, k);
    strassen_mm_worker(
        m, n, k,
        T1, k,
        B_2_2, incRowB_2_2,
        M5, k);
    
    remove_matrix(T1);
    return M5;
}
Dtype* strassen_make_M4_submatrix(
    const unsigned int m,
    const unsigned int n,
    const unsigned int k,    
    const Dtype *A_2_2, const int incRowA_2_2,
    const Dtype *B_2_1, const int incRowB_2_1,
    const Dtype *B_1_1, const int incRowB_1_1){

    /*
    construct M4 by the formula
    M4 = A_2_2 * (B_2_1 - B_1_1)
    */
    Dtype* T1 = make_matrix(m, k);
    
    // T1 = B_2_1 - B_1_1
    matrix_subtraction(m, k,
        B_2_1, incRowB_2_1,
        B_1_1, incRowB_1_1,
        T1, k);

    Dtype* M4 = make_matrix(m, k);
    strassen_mm_worker(
        m, n, k,
        A_2_2, incRowA_2_2,
        T1, k,
        M4, k);

    remove_matrix(T1);
    return M4;
}
Dtype* strassen_make_M3_submatrix(
    const unsigned int m,
    const unsigned int n,
    const unsigned int k,    
    const Dtype *A_1_1, const int incRowA_1_1,
    const Dtype *B_1_2, const int incRowB_1_2,
    const Dtype *B_2_2, const int incRowB_2_2){

    /*
    construct M3 by the formula
    M3 = A_1_1 * (B_1_2 - B_2_2)
    */
    // T1 = B_1_2 - B_2_2
    Dtype* T1 = make_matrix(m, k);
    
    matrix_subtraction(m, k,
        B_1_2, incRowB_1_2,
        B_2_2, incRowB_2_2,
        T1, k);

    Dtype* M3 = make_matrix(m, k);
    
    strassen_mm_worker(
        m, n, k,
        A_1_1, incRowA_1_1,
        T1, k,
        M3, k); 

    remove_matrix(T1);
    return M3;
}
Exemple #7
0
void Main_win::clear_clicked()
{
  math_->clear();

  remove_matrix();
  build_matrix(mat_dim_);
  reset_display();
}
Exemple #8
0
void Main_win::load_clicked()
{
  try
  {
    QString q_form = QFileDialog::getOpenFileName(this, tr("Load Matrix"));

    std::ifstream f;
    f.open(q_form.toStdString(), std::ios_base::in);

    if(f.is_open())
    {
      int row = 0;
      int col = 0;
      char c = 0;
      bool flag = true;

      while(f.get(c))
      {
        if(flag && (c == ' '))
          col++;
        if(c == '\n')
        {
          row++;
          flag = false;
        }
      }

      f.clear();
      f.seekg(0, f.beg);

      std::istream_iterator<double> ii{f};
      std::istream_iterator<double> eos{};
      std::vector<double> v{ii, eos};

      f.close();

      remove_matrix();

      build_matrix(row, col);

      mat_dim_.first = row;
      mat_dim_.second = col;

      mat_dim_tmp_.first = row;
      mat_dim_tmp_.second = col;

      display_matrix(row, col, v);
    }
    else throw std::ios_base::failure("cannot open file");
  }
  catch(std::exception& e)
  {
    e.what();
    to_display(e.what());
  }
}
Exemple #9
0
void Main_win::set_dim_clicked()
{
  Set_dim dialog_set_dim(this, mat_dim_tmp_);
  dialog_set_dim.setModal(true);

  dialog_set_dim.show();
  dialog_set_dim.exec();

  remove_matrix();
  build_matrix(mat_dim_tmp_);
  mat_dim_ = mat_dim_tmp_;
}
// M1 = (A_1_1 + A_2_2) * (B_1_1 + B_2_2)
Dtype* strassen_make_M1_submatrix(
    const unsigned int m,
    const unsigned int n,
    const unsigned int k,    
    const Dtype *A_1_1, const int incRowA_1_1,
    const Dtype *A_2_2, const int incRowA_2_2,
    const Dtype *B_1_1, const int incRowB_1_1,
    const Dtype *B_2_2, const int incRowB_2_2){

    /*
    construct M1 by the formula
    M1 = (A_1_1 + A_2_2) * (B_1_1 + B_2_2)
    */
    
    // T1 = (A_1_1 + A_2_2)
    Dtype* T1 = make_matrix(m, k);
    matrix_addition(m, k,
        A_1_1, incRowA_1_1,
        A_2_2, incRowA_2_2,
        T1, k);
   
    // T2 = (B_1_1 + B_2_2)
    Dtype* T2 = make_matrix(m, k);
    matrix_addition(m, k,
        B_1_1, incRowB_1_1,
        B_2_2, incRowB_2_2,
        T2, k);

    // M1 = T1 * T2
    Dtype* M1 = make_matrix(m, k);
    strassen_mm_worker(
        m, n, k,
        T1, k,
        T2, k,
        M1, k);

    remove_matrix(T1);
    remove_matrix(T2);
    return M1;
}
Exemple #11
0
void Main_win::display_result(const Matrix& m)
{
  remove_matrix();
  build_matrix(m.rows(), m.cols());

  mat_dim_.first = m.rows();
  mat_dim_.second = m.cols();

  mat_dim_tmp_.first = m.rows();
  mat_dim_tmp_.second = m.cols();

  display_matrix(m);
}
// M7 = (A_1_2 - A_2_2) * (B_2_1 + B_2_2)
Dtype* strassen_make_M7_submatrix(
    const unsigned int m,
    const unsigned int n,
    const unsigned int k,    
    const Dtype *A_1_2, const int incRowA_1_2,
    const Dtype *A_2_2, const int incRowA_2_2,
    const Dtype *B_2_1, const int incRowB_2_1,
    const Dtype *B_2_2, const int incRowB_2_2){

    /*
    construct M7 by the formula
    M7 = (A_1_2 - A_2_2) * (B_2_1 + B_2_2)
    */
    Dtype* T1 = make_matrix(m, k);
    Dtype* T2 = make_matrix(m, k);    
    // T1 = (A_1_2 - A_2_2)
    matrix_subtraction(m, k,
        A_1_2, incRowA_1_2,
        A_2_2, incRowA_2_2,
        T1, k);
   
    // T2 = (B_2_1 + B_2_2)
    matrix_addition(m, k,
        B_2_1, incRowB_2_1,
        B_2_2, incRowB_2_2,
        T2, k);

    // M7 = T1 * T2
    Dtype* M7 = make_matrix(m, k);
    strassen_mm_worker(
        m, n, k,
        T1, k,
        T2, k,
        M7, k);

    remove_matrix(T1);
    remove_matrix(T2);
    return M7;
}
/* this script only works for square matrices 
   where the length is a power of 2
*/
void strassen_mm_worker(
    const unsigned int m,
    const unsigned int n,
    const unsigned int k,
    const Dtype *A, const int incRowA,
    const Dtype *B, const int incRowB,
    Dtype *C, const int incRowC){

	// the matrices must have positive dimension
	assert(m > 0);
	assert(n > 0);
	assert(k > 0);
    // the matrix must be a square matrix
	assert(m == n);
    assert(m == k);
	/* check if the base case has reached
       the base condition is defined as when all the dimensions are smaller than 256
	*/
	if(m <= limit_X && n <= limit_X && k <= limit_X){
        return matrix_multiplication_base_case(
            m, n, k,
            A, incRowA,
            B, incRowB,
            C, incRowC);
	}
	/*
	We divide A, B, C into subsections as the following:
	A = |A_1_1, A_1_2|   B = |B_1_1, B_1_2|   C = |C_1_1, C_1_2|
	    |A_2_1, A_2_2|       |B_2_1, B_2_2|       |C_2_1, C_2_2|


	We first calculate 7 temporary matrices as the follow:
	M1 = (A_1_1 + A_2_2) * (B_1_1 + B_2_2)
	M2 = (A_2_1 + A_2_2) * B_1_1
	M3 = A_1_1 * (B_1_2 - B_2_2)
	M4 = A_2_2 * (B_2_1 - B_1_1)
	M5 = (A_1_1 + A_1_2) * B_2_2
	M6 = (A_2_1 - A_1_1) * (B_1_1 + B_1_2)
	M7 = (A_1_2 - A_2_2) * (B_2_1 + B_2_2)

	Then, we compute C section by section according to:
	C_1_1 = M1 + M4 - M5 + M7
	C_1_2 = M3 + M5
	C_2_1 = M2 + M4
	C_2_2 = M1 - M2 + M3 + M6 
	*/
	const unsigned int m1 = m / 2;	
	const unsigned int n1 = n / 2;
	const unsigned int k1 = k / 2;
	
	const Dtype* A_1_1 = A;
	const Dtype* A_1_2 = A_1_1 + k1;
	const Dtype* A_2_1 = A_1_1 + incRowA*m1;
	const Dtype* A_2_2 = A_2_1 + k1;

	Dtype* C_1_1 = C;
	Dtype* C_1_2 = C_1_1 + n1;
	Dtype* C_2_1 = C_1_1 + incRowC*m1;
	Dtype* C_2_2 = C_2_1 + n1;

	const Dtype* B_1_1 = B;
	const Dtype* B_1_2 = B_1_1 + n1;
	const Dtype* B_2_1 = B_1_1 + incRowB*k1;
	const Dtype* B_2_2 = B_2_1 + n1;

	/*
	construct M1 by the formula
	M1 = (A_1_1 + A_2_2) * (B_1_1 + B_2_2)
	*/    

    Dtype* M1 = strassen_make_M1_submatrix(
            m1, n1, k1,    
            A_1_1, incRowA,
            A_2_2, incRowA,
            B_1_1, incRowB,
            B_2_2, incRowB);

    /*
	construct M2 by the formula
	M2 = (A_2_1 + A_2_2) * B_1_1
    */
    Dtype* M2 = strassen_make_M2_submatrix(
            m1, n1, k1,    
            A_2_1, incRowA,
            A_2_2, incRowA,
            B_1_1, incRowB);    

    /*
	construct M3 by the formula
	M3 = A_1_1 * (B_1_2 - B_2_2)
    */
    Dtype* M3 = strassen_make_M3_submatrix(
            m1, n1, k1,
            A_1_1, incRowA,
            B_1_2, incRowB,
            B_2_2, incRowB);

    /*
	construct M4 by the formula
	M4 = A_2_2 * (B_2_1 - B_1_1)
    */
    Dtype* M4 = strassen_make_M4_submatrix(
            m1, k1, k1,
            A_2_2, incRowA,
            B_2_1, incRowB,
            B_1_1, incRowB);


    /*
	construct M5 by the formula
	M5 = (A_1_1 + A_1_2) * B_2_2
    */
    Dtype* M5 = strassen_make_M5_submatrix(
            m1, n1, k1,
            A_1_1, incRowA,
            A_1_2, incRowA,
            B_2_2, incRowB);



	/*
	construct M6 by the formula
	M6 = (A_2_1 - A_1_1) * (B_1_1 + B_1_2)
	*/
    Dtype* M6 = strassen_make_M6_submatrix(
            m1, n1, k1,    
            A_2_1, incRowA,
            A_1_1, incRowA,
            B_1_1, incRowB,
            B_1_2, incRowB);

	/*
	construct M7 by the formula
	M7 = (A_1_2 - A_2_2) * (B_2_1 + B_2_2)
	*/
    Dtype* M7 = strassen_make_M7_submatrix(
            m1, n1, k1,    
            A_1_2, incRowA,
            A_2_2, incRowA,
            B_2_1, incRowB,
            B_2_2, incRowB);

    /*
    compute C_1_1 by the formula
    C_1_1 = M1 + M4 - M5 + M7
    */
    strassen_calculate_C_1_1(
        m1, n1, k1,
        M1, M4, M5, M7,
        C_1_1, incRowC);

    /*
    compute C_1_2 by the formula
    C_1_2 = M3 + M5
    */
    strassen_calculate_C_1_2(
        m1, n1, k1,
        M3, M5,
        C_1_2, incRowC);

    /*
    compute C_2_1 by the formula
    C_2_1 = M2 + M4
    */
    strassen_calculate_C_2_1(
        m1, n1, k1,
        M2, M4,
        C_2_1, incRowC);

    /*
    compute C_2_2 by the formula
    C_2_2 = M1 - M2 + M3 + M6
    */
    strassen_calculate_C_2_2(
        m1, n1, k1,
        M1, M2, M3, M6,
        C_2_2, incRowC);

    /*
    remove the working space
    */
    remove_matrix(M1);
    remove_matrix(M2);
    remove_matrix(M3);
    remove_matrix(M4);
    remove_matrix(M5);
    remove_matrix(M6);
    remove_matrix(M7);
}