67

I'm trying to create symbols \opn for "open subset" and \cls "closed subset". I want them to look like this:

enter image description here

enter image description here

My current solution is:

\def\opn{\!\ensuremath{\subseteq\!\!\!\!\!\raisebox{1pt}{$\circ$}}\,} 
\def\cls{\!\ensuremath{\subseteq\!\!\!\!\!\raisebox{1pt}{$\bullet$}}\,}

But the problem is when I use this, Latex doesn't treat \subseteq and \circ as a single symbol, so the spacing is incorrect when for example I write $U~\!\!\!\opn\!\!\!~X$:

enter image description here

How can I make the position of the circle be fixed in the middle, so that \opn becomes a single symbol that is resizable, i.e. responds well to \huge?

Edit: @egreg @MartinScharrer: When using your command (to define the stalk of a sheaf)

\mathcal{F}_x:=\frac{\bigsqcup\{\mathcal{F}(U);\, x\in U \opn X\}}{s\sim s' 
\,\Longleftrightarrow\, s\in\mathcal{F}(U)\text{ and }s'\in\mathcal{F}(U')\text{ and }
\exists x\in W \opn U\cap U'\!:s|_W=s'|_W}

I get ugly results, namely (egreg's solution) enter image description here
and (Martin Scharrer's solution) enter image description here.

Currently, I like this edited Martin's solution the most aesthetically appealing:

\def\opn{ \ensuremath{\mathrel{\subseteq \!\!\!\!\!\raisebox{1.63pt}{$\scriptstyle\circ$}}}}    %odprta podmnozica
\def\opnn{\ensuremath{\mathrel{\subsetneq\!\!\!\!\!\raisebox{1.63pt}{$\scriptstyle\circ$}}}}    %prava odprta podmnozica
\def\cls{ \ensuremath{\mathrel{\subseteq \!\!\!\!\!\raisebox{1.63pt}{$\scriptstyle\bullet$}}}}  %zaprta podmnozica
\def\clsn{\ensuremath{\mathrel{\subsetneq\!\!\!\!\!\raisebox{1.63pt}{$\scriptstyle\bullet$}}}}  %prava zaprta podmnozica

but there is still a problem in the above code. Could anyone edit this last code to fix the problem with spacing?

1
  • 1
    One should never use negative spacing like \! for something like this; see this answer of mine for details. Commented Jun 15, 2012 at 17:31

7 Answers 7

101

Here is a possibility:

\newcommand\opn{\mathrel{\ooalign{$\subseteq$\cr
  \hidewidth\raise.225ex\hbox{$\circ\mkern.5mu$}\cr}}}
\newcommand\cls{\mathrel{\ooalign{$\subseteq$\cr
  \hidewidth\raise.225ex\hbox{$\bullet\mkern.5mu$}\cr}}}

The symbols will change size according to the context. They don't reduce in subscript or superscripts, for that something more is needed.

This is a case where \ensuremath is superfluous, since the symbols will always be used in math mode, except perhaps in their definition, where adding $ symbols around them is not much of a hassle.

The low level \ooalign command is one of my favorite tools. I'm telling TeX to superimpose the two symbols, the circle or bullet is aligned at right, but pushed left a bit by \mkern.5mu and raised with a font dependent dimension (the amount 0.225ex has been computed by trial and error). Act on \mkern.5mu if you want to push the circles a bit more to the left.

Here's the result of $A\opn B\cls C$

enter image description here

A quick course on \ooalign

Think to \ooalign{...} pretty much like

\begin{tabular}[t]{@{}l@{}}
...
\end{tabular}

where instead of \\ one has to write \cr, but all rows are printed on top of each other. It is customary to use \hidewidth instead of \hfil to get an entry centered with respect to the widest one and actually it has its benefits.

Let's see an example from plain.tex (the LaTeX definition is similar, and this one is simplified): we want to put a cedilla after some non standard character.

\def\c#1{{\ooalign{#1\cr\hidewidth\char24\hidewidth\cr}}}

Here \char24 is the cedilla in the usual Knuth font encoding; it's a character that sits just below the baseline, so for characters that don't have descenders, we can print the character (#1) and superimpose to it the cedilla (it will go under it, of course). With \hidewidth\char24\hidewidth we pretend that the cedilla takes up no horizontal space, so the resulting block will be the same width as the character; we don't even need to know how wide is \char24.

If we want to build a "supinf" symbol, superimposing \land and \lor, we can define

\newcommand{\supinf}{\mathbin{\ooalign{$\lor$\cr$\land$\cr}}}

Here \mathbin says that this command must be used in math mode and the symbol is considered as an operation symbol.

The command \hidewidth just adds a large negative space (it's \hskip -1000pt plus 1fill compensating it with infinite stretchability. A table cell where \hidewidth is present will never be the largest one.

Caution
Always enclose {\ooalign{...}} in a group as shown here and in the definition of \c, otherwise nasty surprises can spoil your masterpiece of typography. In our cases, the braces in \mathbin{...} and \mathrel{...} act as group delimiters.


Here's how you can get size changing according to the math style:

\documentclass{article}
\usepackage{amsmath}

\makeatletter
\newcommand\opn{\mathrel{\opncls@{\circ}}}
\newcommand\cls{\mathrel{\opncls@{\bullet}}}
\newcommand{\opncls@}[1]{%
  \vphantom{\subseteq}% to fix the bounding box
  \mathpalette\opncls@@{#1}%
}
\newcommand{\opncls@@}[2]{%
  \ooalign{$\m@th#1\subseteq$\cr
  \hidewidth\opncls@fix{#1}\hbox{$\m@th#1#2\mkern.5mu$}\cr}}

\newcommand\opncls@fix[1]{%
  \ifx#1\displaystyle
    \raise.225ex
  \else
    \ifx#1\textstyle
      \raise.225ex
    \else
      \ifx#1\scriptstyle
        \raise.180ex
      \else
        \raise.150ex
      \fi
    \fi
  \fi
}
\makeatother

\begin{document}
$
\mathcal{F}_x:=
  \frac{\bigsqcup\{\mathcal{F}(U);\, x\in U \opn X\}}
  {\exists x\in W \opn U\cap U'\!:s|_W=s'|_W}
$

\bigskip

$\displaystyle\opn\cls
 \quad
 \textstyle\opn\cls
 \quad
 \scriptstyle\opn\cls
 \quad
 \scriptscriptstyle\opn\cls$

\end{document}

enter image description here

(I've simplified your formula just to show the effect of the new symbol; however, such a big formula should always be typeset in display style and with \dfrac.)

A couple of further notes. I used \m@th in order to avoid problems if the document class sets a nonzero value for \mathsurround (but it's rare that it's set otherwise).

The \vphantom{\subseteq} is needed because \ooalign sets the bounding box using the first row for the height and the last row for the depth.

15
  • 1
    Great answer, as always. The \ooalign is very interesting. Commented Jul 5, 2011 at 12:53
  • Thank you very much. I'm don't really understand what your code actually does, but I'll study it when the need to construct another sign comes. In the meantime, I'll be happily using this one. Again, thank you very much :).
    – Leo
    Commented Jul 5, 2011 at 12:57
  • 1
    @Leon: It's similar to a tabular (which uses \halign internally), but the alignment is different (overlayed instead table structure). The \cr stands for the line end, i.e. like \\. But egreg can it of course explain better. Commented Jul 5, 2011 at 13:11
  • 2
    I've added some words about \ooalign.
    – egreg
    Commented Jul 5, 2011 at 13:33
  • 1
    @Karlo Sorry, but it's not clear what you mean. Can you ask a fresh question with all the details?
    – egreg
    Commented Mar 12, 2018 at 10:15
20

Obligatory Unicode answer: With XeLaTeX or LuaLaTeX with the unicode-math package, you can use (i.e. U+27C3 OPEN SUBSET) directly (or use the alias \subsetcirc). There is also (U+2ABD SUBSET WITH DOT; \subsetdot) and (U+2ACF CLOSED SUBSET; \csub). Unicode doesn't seem to contain a subset symbol with a bullet inside.

2
  • 3
    can anyone tell me whether the "subset (superset) with dot" has the same meaning as "subset (superset) with bullet" ("closed subset/superset" according to the present question)? i am preparing to submit some requests to unicode, and this is essential information. citations to published references will greatly strengthen the argument for adding the bulleted forms. Commented Jan 28, 2014 at 15:25
  • @barbarabeeton: Personally, I have never used (or seen in publication) either symbol, so I can't really help you. I wonder if mathoverflow allows these kind of questions.
    – Caramdir
    Commented Jan 28, 2014 at 17:48
14

You need to place your symbol inside \mathrel{..} so it is taken as a relation symbol. To support different size you should define \raisebox using the ex unit instead.

\def\opn{\ensuremath{\mathrel{\subseteq\!\!\!\!\!\raisebox{1pt}{$\circ$}}}} 
\def\cls{\ensuremath{\mathrel{\subseteq\!\!\!\!\!\raisebox{1pt}{$\bullet$}}}}

See also the similar question Overlay symbol with another.

2
  • Thank you also, it's good to have different solutions of varying complexity, so it's easier to understand.
    – Leo
    Commented Jul 5, 2011 at 12:59
  • There is a problem (see edit). Would you be willing to fix it?
    – Leo
    Commented Mar 22, 2013 at 5:38
10

[EDITED to show 2nd approach]

This solution has two salient features. First, it uses the inset feature of the stackengine package to overlay the required symbols using a syntax like

\bottominset{\circ}{\subseteq}{.55ex}{}

This will work just fine in \textstyle math, and the macros \TSopn (Text Style opn) and \TScls (Text Style cls) are sufficient, if that is all that is required.

However, when symbols are overlaid, and kerned relative to each other, they frequently will appear out of kilter in different math styles, if that is a needed feature of the solution. This is because smaller math style fonts are not merely scaled down versions of the text-style math.

To deal with this problem, I use the scalerel packages feature of being able to scale a symbol to the size of another symbol, with syntax like

\scalerel*{symbolA}{symbolB}

where "symbolA" is scaled and typeset to the same vertical footprint as "symbolB".

What I do here for \opn and \cls is to force the versions of the symbols in smaller math size to, in fact, be directly scaled versions of the \textstyle symbols that have been properly kerned. The size to which the original (\textstyle) symbols are scaled is the \subseteq symbol in the current math style. In this way, the reduced symbols will have the proper kerning which characterized the original \textstyle symbol definition.

\documentclass{article}
\usepackage{stackengine}
\usepackage{scalerel}
\def\overlayprep{\stackMath\def\stackalignment{l}\def\useanchorwidth{T}}

\newcommand\TSopn{\overlayprep\mathrel{\bottominset{\circ}{\subseteq}{.55ex}{}}}
\newcommand\TScls{\overlayprep\mathrel{\bottominset{\bullet}{\subseteq}{.55ex}{}}}

\newsavebox\TSopnBox\sbox{\TSopnBox}{$\TSopn$}
\newsavebox\TSclsBox\sbox{\TSclsBox}{$\TScls$}

\newcommand\opn{\mathrel{\scalerel*{\usebox{\TSopnBox}}{\subseteq}}}
\newcommand\cls{\mathrel{\scalerel*{\usebox{\TSclsBox}}{\subseteq}}}

\begin{document}
\[U \opn X \quad \scriptstyle U \opn X \quad \scriptscriptstyle U \opn X \]
\[U \cls X \quad \scriptstyle U \cls X \quad \scriptscriptstyle U \cls X \]
\end{document}

enter image description here

One possible quibble with this first approach is that, in \scalereling the \textstyle symbol to the smaller math sizes, the stroke width of the glyphs is altered in a way that the user finds unattractive. If that is the case, the scalerel approach can be dispensed with, and replaced with the \mathchoice approach in which the vertical and horizontal kerning is tuned for each particular math style, but using the glyphs associated with the particular math style in force:

\documentclass{article}
\usepackage{stackengine}
\def\overlayprep{\stackMath\def\stackalignment{l}\def\useanchorwidth{T}}
\newcommand\opn{\opncls{\circ}}
\newcommand\cls{\opncls{\bullet}}
\newcommand\opncls[1]{\overlayprep\mathrel{%
  \mathchoice%
  {\bottominset{#1}{\subseteq}{.55ex}{}}%
  {\bottominset{#1}{\subseteq}{.55ex}{}}%
  {\bottominset{\scriptstyle#1}{\scriptstyle\subseteq}{.49ex}{.40ex}}%
  {\bottominset{\scriptscriptstyle#1}{\scriptscriptstyle\subseteq}{.39ex}{.32ex}}%
}}
\begin{document}

\(U\opn X\quad \scriptstyle U\opn X\quad \scriptscriptstyle U\opn X\)

\(U\cls X\quad \scriptstyle U\cls X\quad \scriptscriptstyle U\cls X\)

\end{document}

enter image description here

I confirmed that both approaches work with the user's problem, as seen here for approaches 1 and 2, respectively:

enter image description here

enter image description here

6

The following example constructs the symbols from \subset/\supset/\subseteq/\supseteq with \circ/\bullet. The constructed symbol can be resized.

  • The horizontal position of the circle/bullet can be configured using \subsetcircfills.
  • And the size of the circle/bullet can be setup with \subsetcircscale. Then the code also tries to take the side bearings into account.

Example file:

\documentclass{article}

% graphics or graphicx is needed, if the circ/bullet should be resized
\usepackage{graphicx}

\makeatletter

% Setup commands
% --------------

% \subsetcircfills{<fill factor/closed side>}{<fill factor/open side>}
% Configures the horizontal placement of the circ/bullet.
% Examples:
% \subsetcircfills{1}{0} -> circ/bullet is moved to the right/open side
% \subsetcircfills{5}{2} -> circ/bullet moved more to the middle
% It also configures the super set symbols.
\newcommand*{\subsetcircfills}[2]{%
  \def\@subsetcircfill@close{#1}%
  \def\@subsetcircfill@open{#2}%
}

% \subsetcircscale{<factor>}
% Resizes the circ/bullet.
% Examples:
% \subsetcircscale{1} -> original size
% \subsetcircscale{.8} -> circ/bullet is smaller by a fifth
\newcommand*{\subsetcircscale}[1]{%
  \def\@subsetcirc@scale{#1}%
}

% Symbols
% -------

\newcommand*{\subsetcirc}{\@subsetcirc@gen000}
\newcommand*{\subsetbullet}{\@subsetcirc@gen001}
\newcommand*{\supsetcirc}{\@subsetcirc@gen100}  
\newcommand*{\supsetbullet}{\@subsetcirc@gen101}

\newcommand*{\subseteqcirc}{\@subsetcirc@gen010}
\newcommand*{\subseteqbullet}{\@subsetcirc@gen011}
\newcommand*{\supseteqcirc}{\@subsetcirc@gen110}  
\newcommand*{\supseteqbullet}{\@subsetcirc@gen111}

% Help macros
% -----------
%
% \@subsetcirc@gen
% #1: 0: subset, 1: supset
% #2: 0: no equals, 1: equals
% #3: 0: circ, 1: bullet
\newcommand*{\@subsetcirc@gen}[3]{%
  \mathrel{%
    \mathpalette{\@subsetcirc@@gen{#1}{#2}{#3}}{}%
  }%
}   

% \@subsetcirc@@gen
% #1: 0: subset, 1: supset
% #2: 0: no equals, 1: equals
% #3: 0: circ, 1: bullet
% #4: math style
% #5: <empty>   
\newcommand*{\@subsetcirc@@gen}[5]{%
  \sbox0{$%
    #4%
    \m@th
    \ifcase#1 %
      \ifcase#2 %
        \subset  
      \else
        \subseteq
      \fi
    \else
      \ifcase#2 %
        \supset  
      \else
        \supseteq
      \fi
    \fi  
  $}%    
  \sbox2{$#4\m@th\ifcase#3 \circ\else\bullet\fi$}%
  \@subsetcirc@resize#4%
  \ifcase#2 \else\@subsetcirc@eqcorr#4\fi
  \rlap{\unhcopy0}%
  \hbox to \wd0{%  
    \hskip 0pt plus %
      \ifcase#1 \@subsetcircfill@close\else\@subsetcircfill@open\fi fil%
    \relax
    \unhbox2 %
    \hskip 0pt plus %
      \ifcase#1 \@subsetcircfill@open\else\@subsetcircfill@close\fi fil%
    \relax
  }%
}   

% \@subsetcirc@resize{<math style>}
% Resizes the circ/bullet in box 2.
% It also tries to take care of the side bearings.
\newcommand*{\@subsetcirc@resize}[1]{%
  \ifdim\@subsetcirc@scale pt=1pt %   
  \else
    \sbox4{$#1\vcenter{}$}%
    \sbox2{\raisebox{-\ht4}[\ht4][\ht4]{\unhcopy2}}%
    \sbox2{$%
      #1\m@th%
      \vcenter{%
        \hbox{% 
          \dimen6=.5\dimexpr\wd2 -2\ht2 + 2\ht4\relax
          \kern\dimen6 %
          \resizebox{!}{\@subsetcirc@scale\height}{%
            \kern-\dimen6 %
            \copy2 %
            \kern-\dimen6 %
          }%
          \kern\dimen6 %
        }%
      }%  
    $}%   
  \fi     
}

% \@subsetcirc@eqcorr{<math style>}
% Corrects the vertical position of circ/bullet in box 2 for
% the symbols with the "equals" line.
\newcommand*{\@subsetcirc@eqcorr}[1]{%
  \sbox6{$#1\subset$}%
  \sbox2{%
    \raise\dimexpr\ht0-\ht6\relax\copy2 %
  }%
}   
\makeatother

% Symbol setup
\subsetcircfills{1}{0}
\subsetcircscale{.8}  

\begin{document}

\[ X \subsetcirc Y \supsetcirc Z\,
   {\scriptstyle X \subsetcirc Y \supsetcirc Z}\,
   {\scriptscriptstyle X \subsetcirc Y \supsetcirc Z}
\]
\[ X \subsetbullet Y \supsetbullet Z\,
   {\scriptstyle X \subsetbullet Y \supsetbullet Z}\,
   {\scriptscriptstyle X \subsetbullet Y \supsetbullet Z}
\]

\[ X \subseteqcirc Y \supseteqcirc Z\,
   {\scriptstyle X \subseteqcirc Y \supseteqcirc Z}\,
   {\scriptscriptstyle X \subseteqcirc Y \supseteqcirc Z}
\]
\[ X \subseteqbullet Y \supseteqbullet Z\,
   {\scriptstyle X \subseteqbullet Y \supseteqbullet Z}\,
   {\scriptscriptstyle X \subseteqbullet Y \supseteqbullet Z}
\]

\end{document}

Result for

\subsetcircfills{1}{0}
\subsetcircscale{.8}  

Result

Result for

\subsetcircfills{5}{2}
\subsetcircscale{1}

Result

5

Unicode symbols:

U+27C3 OPEN SUBSET
U+27C4 OPEN SUPERSET

There are OpenType fonts that contain these symbols. They can be used with LuaTeX or XeTeX and package unicode-math:

\documentclass[fleqn,12pt]{article}
\usepackage{unicode-math}

\begin{document}
\noindent\verb|\subsetcirc|, \verb|\supersetcirc|

\setmathfont{xits-math.otf}
\[^^^^27c3, ^^^^27c4 \quad\mbox{\ttfamily\small xits-math.otf}\]

\setmathfont{Asana-Math.otf}
\[^^^^27c3, ^^^^27c4 \quad\mbox{\ttfamily\small Asana-Math.otf}\]

\end{document}

Result

The symbols can be specified in different ways:

  • As macros: \subsetcirc, \supersetcirc
  • As Unicode characters: ,
  • With (Lua|Xe)TeX's ^^-notation: ^^^^27c3, ^^^^27c4
3
  • 1
    This answer belongs to this question that was already closed as duplicate to this question. Commented Jan 26, 2014 at 13:24
  • it is true that unicode contains only these two symbols, not the similar ones with bullets ("closed circles") and their "equal" counterparts. if a published reference can be provided, i will submit them to unicode for consideration. (i will submit them anyway, but a reference will make a stronger case.) there are unicodes at 2ACF, 2AD0, 2AD1 and 2AD2 for "closed" subset, superset, subset or equal, and superset or equal, but they have different shapes; the forms with bullets may be considered only variants, but who can tell ... Commented Jan 26, 2014 at 16:16
  • Heiko: We can't migrate answers between questions. The best I can suggest is to try to get the other question re-opened, then post the answer there (after deleting it here).
    – Joseph Wright
    Commented Jan 28, 2014 at 8:39
3

I mean that \ooalign is not typical application for this task because this composed operator is right aligned, no center aligned. When \ooalign is used then you must correct the positioning by special constant (.5mu in egregs answer). More straightforward is to use \llap:

$A \mathrel{{\subseteq}\raise.225ex\llap{$\circ$}} B$

Or, if you need to use this in script and scriptscript size too, then you can define the \opn macro as:

\def\opn{\mathrel{{\subseteq}\mathpalette\opnA\circ}}
\def\opnA#1#2{\raise\varpalette#1{.225}{.170}{.130}ex\llap{$#1#2$}}
\def\varpalette#1#2#3#4{%
   \ifx#1\scriptstyle#3\else\ifx#1\scriptscriptstyle#4\else#2\fi\fi}

$C \opn D_{a\opn b_{d\opn e}}$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .