Matrix decomposition

I am trying to get what's on the image:

Mi example looks bigger than the one in the picture, the latter looks more compact and nicer. Also, the matrices in the picture look sharper, meaning, they have a bold effect or something like that.

\documentclass{article}
\usepackage{geometry}
\usepackage{mathtools, nccmath}
\usepackage{nicematrix}
\usetikzlibrary{fit,
shapes.geometric}
\tikzset{highlight/.style={ellipse, draw=red, semithick, inner sep=1pt}}

\usepackage{lipsum}
\begin{document}

\begin{equation*}\medmath{
\begin{NiceArray}{|C|C|C|C|C|C|C|C|C|C|C|C|}%
\hline
1& & 3 &  &  & 5 &  &  & 5 &  & 4 &  \\ \hline
&  & 5 & 4  &  &  &  4&  &  & 2 & 1 & 3 \\ \hline
2  & 4 &  & 1 & 2  &  & 3 &  & 4 & 3 & 5 &  \\ \hline
& 2& 4 &  & 5 &  &  & 4 & &  &  2&  \\ \hline
&  & 4 & 3 & 4 & 2 &  &  &  &  & 2 &5  \\ \hline
1 &  & 3 &  & 3 &  &  &  2&  &  &  4& \\
\hline
\end{NiceArray}
\begin{NiceArray}{|C|C|C|}%
\hline
&  &  \\ \hline
&  &  \\ \hline
&  &  \\ \hline
&  &  \\ \hline
&  &  \\ \hline
&  & \\
\hline
\end{NiceArray}
\begin{NiceArray}{|C|C|C|C|C|C|C|C|C|C|C|C|}%
\hline
&  &  &  &  &  &  &  &  &  &  &  \\ \hline
&  &  &  &  &  &  &  &  &  &  &  \\ \hline
&  &  &  &  &  &  &  &  &  &  & \\ \hline
\end{NiceArray}
}
\medskip
\end{equation*}

\end{document}


• See tex.stackexchange.com/questions/497007/…. Just remove ellipses in my answer and replaces contents of matrices. If you will have problems with adding labels to matrices, ask how to do this.. – Zarko Jun 25 '19 at 3:06
• OKay, let's see if it works. The main thing here is the style of the matrices! – NaveganTeX Jun 25 '19 at 3:07
• you cannot compose an equation with float environments. At list you need to remove all table environments in your MWE. – Zarko Jun 25 '19 at 3:09
• @Zarko Done! Help with the labels. Make them look sharper than Fox Megan – NaveganTeX Jun 25 '19 at 3:23
• In this answer, since version 5.0 of nicematrix one must write c instead of C in the preambles of the {NiceArray} (but there is an option for backward compatibility). – F. Pantigny Jul 18 '20 at 21:16

Just for completeness: some style that allows one to easily draw vertical and horizontal lines, even if the matrix has empty nodes. These additional features are not needed to answer the question, but were very easy to add to the above code. There must, however, be at least one node in every column and row.

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{matrix,calc,positioning,fit,backgrounds}
\makeatletter
\long\def\ifnodedefined#1#2#3{%
\@ifundefined{pgf@sh@ns@#1}{#3}{#2}%
}
\tikzset{matrix vlines/.style={execute at end matrix={
\edef\tikzmatrixname{\tikz@fig@name}
\foreach \XX in {1,...,\the\pgf@matrix@numberofcolumns}
{\xdef\FitList{}
\foreach \YY in {1,...,\the\pgfmatrixcurrentrow}
{\ifnodedefined{\tikzmatrixname-\YY-\XX}{\xdef\FitList{\FitList (\tikzmatrixname-\YY-\XX)}}{}
}
\node[fit=\FitList,draw=none,fill=none,inner sep=0pt,draw=none] (\tikzmatrixname-col-\XX) {};
}
\foreach \XX in {2,...,\the\pgf@matrix@numberofcolumns}
{\draw[#1] ($(\tikzmatrixname-col-\XX.west)!0.5!(\tikzmatrixname-col-\the\numexpr\XX-1\relax.east)$)
coordinate (aux) (aux|-\tikzmatrixname.north)
--  (aux|-\tikzmatrixname.south);
}
}},matrix hlines/.style={execute at end matrix={
\edef\tikzmatrixname{\tikz@fig@name}
\foreach \YY in {1,...,\the\pgfmatrixcurrentrow}
{\xdef\FitList{}
\foreach \XX in {1,...,\the\pgf@matrix@numberofcolumns}
{\ifnodedefined{\tikzmatrixname-\YY-\XX}{\xdef\FitList{\FitList (\tikzmatrixname-\YY-\XX)}}{}
}
\node[fit=\FitList,draw=none,fill=none,inner sep=0pt,draw=none] (\tikzmatrixname-row-\YY) {};
}
\foreach \XX in {2,...,\the\pgfmatrixcurrentrow}
{\draw[#1] ($(\tikzmatrixname-row-\XX)!0.5!(\tikzmatrixname-row-\the\numexpr\XX-1\relax)$)
coordinate (aux) (aux-|\tikzmatrixname.west)
--  (aux-|\tikzmatrixname.east);
}
}},
matrix dividers/.style={matrix vlines=#1,matrix hlines=#1},
matrix frame/.style={execute at end matrix={
\draw[#1] (\tikz@fig@name.south west) rectangle (\tikz@fig@name.north east);
}}}
\makeatother
\begin{document}
\begin{tikzpicture}
\matrix[matrix vlines={blue},matrix of math nodes] (mat1) {
1& & 3 &  &  & 5 &  &  & -5 &  & 4 &  \\
&  & 5 & 4  &  &  &  4&  &  & 2 & 1 & 3 \\
2  & 4 &  & 1 & 2  &  & 3 &  & 4 & 3 & 5 &  \\
& 2& 4 &  & -5 &  &  & 4 & &  &  2&  \\
&  & 4 & 3 & 4 & 2 &  &  &  &  & 2 &5  \\
1 &  & 3 &  & 3 &  &  &  2&  &  &  4& \\
};
\matrix[matrix hlines={red},below=2em of mat1,matrix of math nodes] (mat2) {
1& & 3 &  &  & 5 &  &  & -5 &  & 4 &  \\
&  & 5 & 4  &  &  &  4&  &  & 2 & 1 & 3 \\
2  & 4 &  & 1 & 2  &  & 3 &  & 4 & 3 & 5 &  \\
& 2& 4 &  & -5 &  &  & 4 & &  &  2&  \\
&  & 4 & 3 & 4 & 2 &  &  &  &  & 2 &5  \\
1 &  & 3 &  & 3 &  &  &  2&  &  &  4& \\
};
\matrix[matrix dividers={thin,dashed},below=2em of mat2,matrix of math nodes] (mat3) {
1& & 3 &  &  & 5 &  &  & -5 &  & 4 &  \\
&  & 5 & 4  &  &  &  4&  &  & 2 & 1 & 3 \\
2  & 4 &  & 1 & 2  &  & 3 &  & 4 & 3 & 5 &  \\
& 2& 4 &  & -5 &  &  & 4 & &  &  2&  \\
&  & 4 & 3 & 4 & 2 &  &  &  &  & 2 &5  \\
1 &  & 3 &  & 3 &  &  &  2&  &  &  4& \\
};
\begin{scope}[on background layer,fill opacity=0.3]
\fill[red] (mat3-col-2.west|-mat3.north) rectangle (mat3-col-2.east|-mat3.south);
\fill[orange] (mat3-row-2.north-|mat3.west) rectangle (mat3-row-2.south-|mat3.east);
\end{scope}
\end{tikzpicture}
\end{document}


This answer comes with a new style matrix dividers, which can be passed to a TikZ matrix. It will draw the dividing lines like in a tabular. This style makes use of the execute at end matrix key, which has not yet found its way into the manual. It also finds out the number of rows and columns, see this answer. Notice that this style is not designed for matrices with empty cells or very uneven cells, as these do not occur here. However, it is possible (and not too difficult) to extend this style to this case, too.

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{matrix,calc,positioning}
\definecolor{dgreen}{RGB}{72,127,30}
\makeatletter
\tikzset{matrix dividers/.style={execute at end matrix={
\foreach \XX in {2,...,\the\pgf@matrix@numberofcolumns}
{\draw[#1] ($(\tikz@fig@name-1-\XX)!0.5!(\tikz@fig@name-1-\the\numexpr\XX-1)$)
coordinate (aux) (aux|-\tikz@fig@name.north)
--  (aux|-\tikz@fig@name.south);
}
\foreach \XX in {2,...,\the\pgfmatrixcurrentrow}
{\draw[#1] ($(\tikz@fig@name-\XX-1)!0.5!(\tikz@fig@name-\the\numexpr\XX-1\relax-1)$)
coordinate (aux) (aux-|\tikz@fig@name.west)
--  (aux-|\tikz@fig@name.east);
}
}},matrix frame/.style={execute at end matrix={
\draw[#1] (\tikz@fig@name.south west) rectangle (\tikz@fig@name.north east);
}}}
% from https://tex.stackexchange.com/a/386805/121799
\def\tikz@lib@matrix@empty@cell{\iftikz@lib@matrix@empty\node[name=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn,empty node]{};\fi}
\makeatother
\tikzset{matrix of mathsf nodes/.style={%
matrix of nodes,
nodes={%
execute at begin node=$\mathsf\bgroup,% execute at end node=\egroup$%
}%
}}
\begin{document}
\begin{tikzpicture}[nmat/.style={matrix of mathsf nodes,inner sep=0pt,nodes in empty cells,column sep=-\pgflinewidth,
row sep=-\pgflinewidth,nodes={text height=1.7ex,text depth=0.2ex,inner
sep=2pt,minimum width=1.8ex},matrix dividers={thin},matrix
frame={thick}},font=\sffamily,
empty node/.style={fill=none}]
\matrix[nmat,nodes={fill=yellow}] (mat1) {
1& & 3 &  &  & 5 &  &  & 5 &  & 4 &  \\
&  & 5 & 4  &  &  &  4&  &  & 2 & 1 & 3 \\
2  & 4 &  & 1 & 2  &  & 3 &  & 4 & 3 & 5 &  \\
& 2& 4 &  & 5 &  &  & 4 & &  &  2&  \\
&  & 4 & 3 & 4 & 2 &  &  &  &  & 2 &5  \\
1 &  & 3 &  & 3 &  &  &  2&  &  &  4& \\
};
\node[below=0.2ex of mat1,scale=2.5,dgreen] {$\mathsf{R}$};
\node[rotate=90,left=1.3ex of mat1,xshift=3em,dgreen] {items};
\node[above=0ex of mat1,xshift=1em,dgreen] {users};
\node[right=0.1ex of mat1,scale=2] (approx) {$\approx$};
\matrix[nmat,right=0.1ex of approx] (mat2) {
&  &  \\
&  &  \\
&  &  \\
&  &  \\
&  &  \\
&  & \\
};
\node[rotate=90,left=1.3ex of mat2,xshift=-1em,dgreen] {items};
\node[above=0ex of mat2,dgreen] {factors};
\node[below=0.2ex of mat2,scale=2.5,dgreen] {$\mathsf{Q}$};
\node[right=0.1ex of mat2,scale=2] (cdot) {$\times$};
\matrix[nmat,right=0.1ex of cdot] (mat3) {
&  &  &  &  &  &  &  &  &  &  &  \\
&  &  &  &  &  &  &  &  &  &  &  \\
&  &  &  &  &  &  &  &  &  &  & \\
};
\node[rotate=-90,right=1.5ex of mat3,xshift=-2em,dgreen] {factors};
\node[above=0ex of mat3,dgreen] {users};
\node[below=0.2ex of mat3,scale=2.5,dgreen] {$\mathsf{P^T}$};
\end{tikzpicture}
\end{document}


Update: added the very nice \tikz@lib@matrix@empty@cell trick from this answer.

To me it is more easy to draw your equation as write it with standard math tools since your request is quite demanding. Based on my answer and considering this answer the code for it can be:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix,
positioning}
\tikzset{
mymatrix/.style = {matrix of nodes,
nodes in empty cells,
nodes={minimum height=3ex, minimum width=1em,
inner sep=0pt, outer sep=0pt, anchor=center,
draw, very thin, fill=yellow},
column sep=0pt,
row sep=0pt,
inner sep=0.5\pgflinewidth, outer sep=1pt,
draw, thick},
empty node/.style = {draw,fill=none},
every label/.append style = {font=\large, text=teal}
}
\makeatletter
\def\tikz@lib@matrix@empty@cell{%
\iftikz@lib@matrix@empty%
\node[name=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn,empty node]{};\fi}
\makeatother

\begin{document}
$\begin{tikzpicture}[node distance=0pt] \matrix (m1) [mymatrix, label={[rotate=90, anchor=south]left: items}, label=below:R, label=above:users] { 1 & & 3 & & & 5 & & & 5 & & 4 & \\ & & 5 & 4 & & & 4 & & & 2 & 1 & 3 \\ 2 & 4 & & 1 & 2 & & 3 & & 4 & 3 & 5 & \\ & 2 & 4 & & 5 & & & 4 & & & 2 & \\ & & 4 & 3 & 4 & 2 & & & & & 2 & 5 \\ 1 & & 3 & & 3 & & & 2 & & & 4 & \\ }; \node (approx) [right=of m1] {\approx}; \matrix (m2) [mymatrix=none, right=1em of approx, label={[rotate=90, anchor=south]left: items}, label=below:Q, label=above:factors] { & & \\ & & \\ & & \\ & & \\ & & \\ & & \\ }; \node (times) [right=of m2] {\times}; \matrix (m3) [mymatrix=none, right=of times, label={[rotate=90, anchor=north]right: factors}, label=below:P^T, label=above:users] { & & & & & & & & & & & \\ & & & & & & & & & & & \\ & & & & & & & & & & & \\ }; \end{tikzpicture}$
\end{document}


Addendum If you like to have matrix's labels "items" aove below left its corner, than replace label={[rotate=90, anchor=south]left: items}, with label={[rotate=90, anchor=south east]left: items}, and change label style to every label/.append style = {inner xsep=1em, font=\large, text=teal}. For larger math operators symbols, add font=\larger to their nodes options. For example \node (times) [right=of m2,font=\large] {$\times$};

• Nice! The dot product is missing, as in Marmot's answer. – user189304 Jun 25 '19 at 4:52
• @Delan, it is not present in op first image, however it is simple to add. see edited answer, – Zarko Jun 25 '19 at 4:55
• I would do \node (dot) [right=of m2] {$\cdot$}; \matrix (m3) [mymatrix=none, right=0.5em of dot, – user189304 Jun 25 '19 at 4:56
• I@Delan, I would not. for multiplication is not necessary to have special simbols, i.e. ab has the same meaning as a\cdot b ..., however, considering my answers to previous OP questions, i use \times as OP shows in the second image.. – Zarko Jun 25 '19 at 5:02