c++arraysmatrixvectordeque

# Generalizing a function for matrices of different types (e.g., deque of vectors, array of vectors, and vice versa)

I have created a version that works for vectors, but I am currently at a standstill regarding how to adapt it to work with other types of matrices. I don't know if I should, and if I can give the function pointers or iterators that point to the beginning and the end of the matrices, but I don't know if that works for arrays like int array[]?

``````#include <iostream>
#include <cmath>
#include <vector>
#include <deque>
#include <iterator>
#include <iomanip>

template<typename T,typename T1,typename F>
std::vector<std::vector<T>> GeneralizedKroneckerProduct(std::vector<std::vector<T>>M1, std::vector<std::vector<T>>M2, F &f ){
int m=M1.size();
int n=M1.at(0).size();
int p=M2.size();
int q=M2.at(0).size();
std::vector<std::vector<T1>>result(m*p,std::vector<T1>(n*q));
for(int i=0; i<m;i++){
for(int j=0; j<n;j++){
for(int k=0; k<p;k++){
for(int z=0; z<q;z++){
result.at(i*p+k).at(j*q+z)=f(M1.at(i).at(j),M2.at(k).at(z));
}
}
}
}
return result;
}

int main ()
{
std::cout<<"Enter dimensions of the first matrix: ";
int m=0,n=0;
std::cin>>m>>n;
std::cout<<"Enter elements of the first matrix: ";
std::vector<std::vector<int>>A;
std::vector<int>temp;
int number;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
std::cin>>number;
temp.push_back(number);
}
A.push_back(temp);
temp.clear();
}
std::cout<<"Enter dimensions of the second matrix: ";
int p=0,q=0;
std::cin>>p>>q;
std::cout<<"Enter elements of the second matrix: ";
std::vector<std::vector<int>>B;
for(int i=0;i<p;i++){
for(int j=0;j<q;j++){
std::cin>>number;
temp.push_back(number);
}
B.push_back(temp);
temp.clear();
}

auto f=[](int x, int y){return x*y;};
auto result=GeneralizedKroneckerProduct<int,int,decltype(f)>(A, B,f);
std::cout<<"Their Kronecker product is: "<<std::endl;
for(const auto &row:result){
for(const auto &number:row){
std::cout<<std::setw(5)<<number<<" ";
}
std::cout<<std::endl;
}

return 0;
}
``````

Solution

• I fixed it this is the final version

``````#include <iostream>
#include <cmath>
#include <stdexcept>
#include <vector>
#include <deque>
#include <iterator>
#include <iomanip>

int NumDigits(int n){
int b=0;
if(n<1)b++;
return n==0?1:1+b+int(std::log10(std::abs(n))+1e-10);
}

template<typename T,typename T1,typename F>
auto GeneralizedKroneckerProduct( T &P1,  T1 &P2, const F &f ){
int br1=0,br2=0;
/*
if(std::end(P1)-std::begin(P1)==0)
br1++;
if(std::end(P2)-std::begin(P2)==0)
br2++;
*/
if(std::distance(std::begin(P1),std::end(P1))==0)
br1++;
if(std::distance(std::begin(P2),std::end(P2))==0)
br2++;
if(br1>0 && br2==0)
throw::std::domain_error("First parameter does not have matrix form");
else if(br1==0 && br2>0)
throw::std::domain_error("Second parameter does not have matrix form");
if(br1>0 && br2>0)
throw::std::domain_error("Parameters do not have matrix form");
/*auto m=std::end(P1)-std::begin(P1);
auto n=std::end(P1[0])-std::begin(P1[0]);
auto p=std::end(P2)-std::begin(P2);
auto q=std::end(P2[0])-std::begin(P2[0]);
*/
auto m=std::distance(std::begin(P1),std::end(P1));
auto n=std::distance(std::begin(P1[0]),std::end(P1[0]));
auto p=std::distance(std::begin(P2),std::end(P2));
auto q=std::distance(std::begin(P2[0]),std::end(P2[0]));

for(int i=1;i<m;i++){
if (std::distance(std::begin(P1[i]),std::end(P1[i]))!=n)
br1++;
}
for(int i=1;i<p;i++){
if (std::distance(std::begin(P2[i]),std::end(P2[i]))!=q)
br2++;
}
if(br1>0 && br2==0)
throw::std::domain_error("First parameter does not have matrix form");
else if(br1==0 && br2>0)
throw::std::domain_error("Second parameter does not have matrix form");
if(br1>0 && br2>0)
throw::std::domain_error("Parameters do not have matrix form");

using Tip=typename std::remove_reference<decltype(f(P1[0][0],P2[0][0]))>::type;
std::vector<std::vector<Tip>>result(m*p,std::vector<Tip>(n*q));

try{
for(int i=0; i<m;i++){
for(int j=0; j<n;j++){
for(int k=0; k<p;k++){
for(int z=0; z<q;z++){
result[i*p+k][j*q+z]=f(P1[i][j],P2[k][z]);

}
}
}
}}catch(...){
throw::std::runtime_error("Unexpected problems during calculation");
}
return result;
}

int main ()
{
std::cout<<"Enter dimensions of the first matrix: ";
int m=0,n=0;
std::cin>>m>>n;
std::cout<<"Enter elements of the first matrix: ";
std::vector<std::deque<double>>A(m,std::deque<double>(n));
std::vector<int>temp;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
std::cin>>A[i][j];
}
}
std::cout<<"Enter dimensions of the second matrix: ";
int p=0,q=0;
std::cin>>p>>q;
std::cout<<"Enter elements of the second matrix: ";
std::deque<std::vector<double>>B(p,std::vector<double>(q));
for(int i=0;i<p;i++){
for(int j=0;j<q;j++){
std::cin>>B[i][j];
}
}

auto f=[](double x, double y){return x*y;};
auto result=GeneralizedKroneckerProduct(A, B,f);
std::cout<<"Their Kronecker product is: "<<std::endl;
int max=-1;
for(const auto &row:result){
for(const auto &number:row){
if(max<NumDigits(number))
max=NumDigits(number);

}}
for(const auto &row:result){
for(const auto &number:row){
std::cout<<std::setw(max)<<number<<" ";

}
std::cout<<std::endl;

}

return 0;
}
``````