Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

There is a common operation in the sparse-direct literature (see pg. 7) called an "extend-add", and it is usually denoted with a particular symbol that looks like a large plus sign with arrowheads on each tip.

enter image description here

I falsely assumed that I could simply overlap $\updownarrow$ and $\leftrightarrow$ via the mathtools package's \mathllap and friends, but the results were far from pleasing (everything was too jumbled).

Is there a simpler way to generate such a symbol?

share|improve this question
1  
I feel a good solution should ensure that the new sign is exactly as big (wide & high) as the plus sign (and consequently none of the solutions are quite there yet …) –  Konrad Rudolph Oct 22 '12 at 16:43

5 Answers 5

up vote 27 down vote accepted

Simple overlapping

The overlapping of the symbols \leftrightarrow and \updownarrow can be done with \ooalign:

\ooalign{$\leftrightarrow$\cr\hfil$\updownarrow$\hfil}

Some additional work is needed:

  • Adapting to different math styles. The formula above would always use \textstyle.
  • If \mathsurround is set, then the additional space would be added above to the left and right. This can be cured by \m@th that sets \mathsurround to zero.
  • The symbol is used as binary operator, putting it in \mathbin notifies TeX to put additinal space for binary operators.

File:

\documentclass{article}
% \usepackage{txfonts} % similar \usepacakge{pxfonts}
% \usepackage{mathabx}
% \usepackage{MnSymbol}

\makeatletter
\newcommand*{\extendadd}{%
  \mathbin{%
    \mathpalette\extend@add{}%
  }%
}
\newcommand*{\extend@add}[2]{%
  \ooalign{%
    $\m@th#1\leftrightarrow$%
    \vphantom{$\m@th#1\updownarrow$}% fix the height
    \cr
    \hfil$\m@th#1\updownarrow$\hfil
  }%   
}
\makeatother

% for testing the bounding box of the symbol
\setlength{\fboxsep}{0pt}
\setlength{\fboxrule}{.2pt}

\begin{document}
\[
  \mathcal{F}_\mathbf{i} =
  \mathcal{F}_\mathbf{i}^0
  \extendadd
  \mathcal{U}_{\mathbf{c}_1}
  \extendadd
  \mathcal{U}_{\mathbf{c}_2}
  \qquad
  \fbox{$\extendadd$}^{\extendadd^{\extendadd}}
\]
\end{document}

Result for CM fonts:

CM large

Result for package txfonts:

TX large

Result for package mathabx:

mathabx large

Result for package MnSymbol:

MnSymbol large

Observations:

  • The arrow heads are too large.
  • Depending on the font and size \updownarrow might have a smaller total height than the width of \leftrightarrow.

Overlapping with resizing

The idea is to resize \longleftrightarrow to the width of \leftrightarrow to get smaller arrow heads. However, this will also make the lines thinner.

The tricky part is that scaling also changes the vertical position of the symbol. Because of the arrows the height of the character bounding box \leftrightarrow is not too helpful. But we can assume the symbol is vertically centered respective to the mathematical axis. Therefore the code below puts \leftrightarrow to the base line, resizes it and moves it back to the mathematical axis. to the mathematical axis.

The vertical double arrow cannot generated the same way. First the symbol \longupdownarrow is missing. Also we have seen above, that the symbol might be too small in comparison with the \leftrightarrow. Therefore the symbol is generated by rotating the horizontal double arrow.

\documentclass{article}
% \usepackage{txfonts}
% \usepackage{pxfonts}
% \usepackage{mathabx}
% \usepackage{MnSymbol}

\usepackage{graphicx}% (only graphics is needed)

\makeatletter
\newdimen\extend@width
\newdimen\extend@mathaxis
\newcommand*{\extendadd}{%
  \mathbin{%
    \mathpalette\extend@add{}%
  }%
}
\newcommand{\extend@add}[2]{%
  \m@th
  \sbox0{$#1\vcenter{}\smash{\leftrightarrow}$}%
  \extend@width=\wd0 %
  \extend@mathaxis=\ht0 %
  \sbox0{%
    \resizebox{\extend@width}{!}{%
      \raisebox{-\extend@mathaxis}{$#1\longleftrightarrow$}%
    }%
  }%
  \rlap{%
    \raisebox{\extend@mathaxis}{%
      \copy0 %
    }%
  }%
  \dp0=0pt %
  \ht0=0pt %
  \hbox to\extend@width{%
    \hfil
    $#1%
      \vcenter{%
        \hbox{%
          \rotatebox{90}{\copy0}%
        }%
      }%
    $%
    \hfil
  }%
}
\makeatother

% for testing the bounding box of the symbol
\setlength{\fboxsep}{0pt}
\setlength{\fboxrule}{.2pt}

\begin{document}
\[
  \mathcal{F}_\mathbf{i} =
  \mathcal{F}_\mathbf{i}^0
  \extendadd
  \mathcal{U}_{\mathbf{c}_1}
  \extendadd  
  \mathcal{U}_{\mathbf{c}_2}
  \qquad
  \fbox{$\extendadd$}^{\extendadd^{\extendadd}}
\]
\end{document}

Result for CM fonts:

CM scaled

Result for package txfonts:

TX scaled

Result for package mathabx:

mathabx scaled

Result for package MnSymbol:

MnSymbol scaled

It is also possible to have something in between, less scaling, by composing a smaller \longleftrightarrow from \leftarrow and \rightarrow as base for the resized double arrow.

share|improve this answer
4  
Wow! Truely a wizard ;) +1 –  Harish Kumar Oct 22 '12 at 2:11

TikZ solutions

Same sized

Code

\documentclass{article}
\usepackage{amsmath}
\usepackage{graphicx,calc}
\usepackage{tikz}
\usetikzlibrary{calc,arrows}

\makeatletter
%% internal macros
\newlength\jack@depth
\def\jack@factor{0.2} % adjust this for the size of arrows
\def\jack@arrow{to}
\def\jack@arrowshorten{3}

% external macro
\newcommand*\extendadd{\mathbin{\mskip1mu\mathpalette\jack@extendadd{}\mskip1mu}}
\def\jack@extendadd#1{\ifx#1\scriptstyle\def\jack@linewidth{.6pt/\jack@factor}
           \else\ifx#1\scriptscriptstyle\def\jack@linewidth{.62pt/\jack@factor}
           \else                        \def\jack@linewidth{.54pt/\jack@factor}
           \fi\fi
  \setlength{\jack@depth}{\depthof{$#1+$}}
  \raisebox{-\jack@depth}{\resizebox{!}{\heightof{$#1+$}+\depthof{$#1+$}}{\jack@plusarrow}}
}

\def\jack@plusarrow{%
  \begin{tikzpicture}
    \begin{scope}[
      \jack@arrow-\jack@arrow,
      shorten >=-\jack@arrowshorten\pgflinewidth,
      shorten <=-\jack@arrowshorten\pgflinewidth
    ]
      \draw[line width=\jack@linewidth] (1ex/\jack@factor,0) -- (-1ex/\jack@factor,0);
      \draw[line width=\jack@linewidth] (0,1ex/\jack@factor) -- (0,-1ex/\jack@factor);
    \end{scope}
  \end{tikzpicture}%
}
\makeatother

\setlength\fboxsep{0pt}\setlength\fboxrule{.2pt}
\begin{document}\noindent
$ \fbox{+}\fbox{$\extendadd$}_{+\extendadd_{+\extendadd}} $\\
\makeatletter
\foreach \arrow in {to,stealth',angle 90} {+%
    \foreach \factor in {.1,.2,...,1.01} {%
        \renewcommand*\jack@factor{\factor}%
        \renewcommand*\jack@arrow{\arrow}%
        \renewcommand*\jack@arrowshorten{3/\factor*.2}%
        ${\extendadd}$%
    }\\}
\makeatother
\end{document}

Output

same sized

Bigger than normal plus sign

Code

\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{calc}
\def\plusarrowlength{2.5pt}
\newcommand{\plusarrow}{\mathbin{\text{$
\begin{tikzpicture}[
    baseline,
%   opacity=.7 % debugging (doesn't have any effect when \phantom is used)
    ]
    \node[
        inner xsep=-1pt,
        inner ysep=-.5pt,
        outer sep=0pt,
        anchor=base
        ] (plus) {\phantom{+}};
    \begin{scope}[to-to]
        \draw ($(plus.west)+(-\plusarrowlength,0)$) -- ($(plus.east)+(\plusarrowlength,0)$);
        \draw ($(plus.north)+(0,\plusarrowlength)$) -- ($(plus.south)+(0,-\plusarrowlength)$);
    \end{scope}
\end{tikzpicture}$}}}

\begin{document}\noindent
$ \plusarrow_{\plusarrow_{\plusarrow}} $ \\
$ +_{+_+} $
\end{document}

Output

bigger

Extra arrow tip

Code

\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{calc}

\newdimen\arrowsize
\pgfarrowsdeclare{arcs}{arcs}{
    \arrowsize=0.2pt
    \advance\arrowsize by .5\pgflinewidth
    \pgfarrowsleftextend{-4\arrowsize-.5\pgflinewidth}
    \pgfarrowsrightextend{.5\pgflinewidth}
}{
    \arrowsize=2\pgflinewidth
    \pgfsetdash{}{0pt}
    \pgfsetroundjoin
    \pgfsetroundcap
    \pgfpathmoveto{\pgfpoint{-\arrowsize}{\arrowsize}}
    \pgfpatharc{180}{270}{\arrowsize}
    \pgfpatharc{90}{180}{\arrowsize}
    \pgfusepathqstroke
}

\makeatletter
\newcommand\extendadd{\mathbin{\mskip1mu\mathpalette\plusarrow{}\mskip1mu}}
\newcommand{\plusarrow}[1]{
\ifx#1\displaystyle
    \def\jack@innerxsep{-.55pt}
    \def\jack@innerysep{0pt}
    \def\jack@linewidth{.4pt}
\else\ifx#1\textstyle
        \def\jack@innerxsep{-.55pt}
        \def\jack@innerysep{0pt}
        \def\jack@linewidth{.4pt}
    \else\ifx#1\scriptstyle
            \def\jack@innerxsep{-.5pt}
            \def\jack@innerysep{0pt}
            \def\jack@linewidth{.35pt}
        \else
            \def\jack@innerxsep{-.5pt}
            \def\jack@innerysep{0pt}
            \def\jack@linewidth{.3pt}
        \fi
    \fi
\fi
\begin{tikzpicture}[
    baseline,
%   opacity=.7 % debugging (doesn't have any effect when \phantom is used)
    ]
    \node[
        inner xsep=\jack@innerxsep,
        inner ysep=\jack@innerysep,
        outer sep=0pt,
        anchor=base
        ] (plus) {\phantom{$#1+$}};
    \begin{scope}[arcs-arcs]
        \draw[line width=\jack@linewidth] (plus.west) -- (plus.east);
        \draw[line width=\jack@linewidth] (plus.north) -- (plus.south);
    \end{scope}
\end{tikzpicture}}
\makeatother

\begin{document}\noindent
$ \extendadd_{\extendadd_{\extendadd}} $ \\
$ +_{+_+} $
\end{document}

Output

extra arrow

Xe-/LuaLaTeX (without TikZ)

This solution works only for XeLaTeX and LuaLaTeX with the unicode-math package and OpenType fonts that include the symbols \neswarrow and \nwsearrow. (This is my favorite output.)

Code

\documentclass{article}
\usepackage{amsmath}
\usepackage{graphicx}
\usepackage{unicode-math}
\setmathfont{XITS Math}
\newcommand{\plusarrow}{\mathbin{\text{\rotatebox[]{45}{\ooalign{$\nwsearrow$\cr$\neswarrow$}}}}}
\begin{document}
$ 7 \plusarrow 8$ \quad $ \plusarrow_{\plusarrow_{\plusarrow}} $
\end{document}

Output

XeLaTeX solution

share|improve this answer

Another option; no TikZ required and the use of \mathchoice allows correct scaling according to the math style:

\documentclass{article}
\usepackage{graphicx}

\def\ArrPlus{%
\setbox0\hbox{$\longleftrightarrow$}%
\rlap{\hbox to \wd0{\hss\rotatebox[origin=top]{90}{\scalebox{.9}{$\longleftrightarrow$}}\hss}}\raise.15ex\box0}
\def\arrowplus{\mathbin{%
\mathchoice
  {\scalebox{.7}{\ArrPlus}}
  {\scalebox{.7}{\ArrPlus}}
  {\scalebox{.35}{\raisebox{.2ex}{\ArrPlus}}}
  {\scalebox{.25}{\raisebox{.35ex}{\ArrPlus}}}
}}

\begin{document}


$ A \arrowplus B\quad{\displaystyle A \arrowplus B}\quad M_{A \arrowplus B}\quad L_{M_{A \arrowplus B}}$

\end{document}

enter image description here

share|improve this answer

Another solution, non-tikz using one of @egreg's favourite tools, ooalign

enter image description here

For a tutorial on ooalign see

\subseteq + \circ as a single symbol ("open subset")

Note that in the code below I have redefined the commands \leftrightarrow and \updownarrow to take optional arguments that will scale them (default is no scaling). This means that you could use, for example

\newcommand\arrowplus{\mathbin{\ooalign{$\updownarrow[1.1]$\cr\hidewidth$\leftrightarrow$\hidewidth}}}

which will scale the updownarrow by a factor of 1.1.

I've loaded the MnSymbol package simply because I liked the look of its arrows- it does modify other symbols, so use load it carefully.

\documentclass{article}
\usepackage{graphicx}
\usepackage{MnSymbol}

% renew command to scale the leftrightarrow
\let\oldleftrightarrow\leftrightarrow
\renewcommand{\leftrightarrow}[1][3]{\scalebox{#1}{$\oldleftrightarrow$}}

% renew command to scale the updownarrow
\let\oldupdownarrow\updownarrow
\renewcommand{\updownarrow}[1][4]{\scalebox{#1}{$\oldupdownarrow$}}


\newcommand\arrowplus{\mathbin{\ooalign{$\updownarrow$\cr\hidewidth$\leftrightarrow$\hidewidth}}}

\begin{document}

$A\arrowplus B$
\end{document}
share|improve this answer
    
It could probably be done with mathclap from the mathtools package as well, but I don't think it's as elegant –  cmhughes Oct 22 '12 at 1:26

There should be better ways of doing this. But here are some options:

\documentclass[a4paper]{article}
\usepackage{mathtools}
\usepackage{tikz}

\newcommand{\arrowplus}{%
{\mathbin{\text{%
\ensuremath{\begin{tikzpicture}[baseline=-.3em]
  \draw [<->,thin] (0,0) -- (1.1em,0);
  \draw [<->,thin] (.55em,-.55em) -- (.55em,.55em);
\end{tikzpicture}
}}}}}

%
\newcommand{\arowplus}{%
\scalebox{.8}{\raisebox{.35em}{\ensuremath\longleftrightarrow\kern-1.05em\rotatebox[origin=c]{90}
{\ensuremath\longleftrightarrow}\kern.65em
}}}
\def\Arrowplus{\mathbin{%
\mathchoice
  {\scalebox{.7}{\arowplus}}
  {\scalebox{.7}{\arowplus}}
  {\scalebox{.4}{\raisebox{.2ex}{\arowplus}}}
  {\scalebox{.3}{\raisebox{.35ex}{\arowplus}}}
}}


\begin{document}
\[
  \Arrowplus \qquad \arrowplus
\]

\[
 A \arrowplus B\quad{\displaystyle A \arrowplus B}\quad M_{A \arrowplus B}\quad L_{M_{A \arrowplus B}}
 \]
\[
 A \Arrowplus B\quad{\displaystyle A \Arrowplus B}\quad M_{A \Arrowplus B}\quad L_{M_{A \Arrowplus B}}
 \]

\end{document}

enter image description here

share|improve this answer
    
Wouldn't the use of \mathbin be better instead of \,? –  azetina Oct 22 '12 at 0:27

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.