4

The forest manual defines two styles: sn edges and nice empty nodes. They are defined as:

sn edges/.style={for tree={parent anchor=south, child anchor=north}}

and

nice empty nodes/.style={for tree={calign=fixed edge angles},delay={where content={}{shape=coordinate,for parent={for children={anchor=north}}}{}} }

respectively.

When both of these styles are used with the following tree, I get the following error:

! Package PGF Math Error: You asked me to calculate `1/0.0', but I cannot divid
e any number by zero.

See the PGF Math package documentation for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.51 \end{forest}

Does anybody know what is going on? How can I fix this?

MWE

\documentclass{article}

\usepackage{forest}
\forestset{
sn edges/.style={for tree={parent anchor=south, child anchor=north}},
nice empty nodes/.style={for tree={calign=fixed edge angles},delay={where content={}{shape=coordinate,for parent={for children={anchor=north}}}{}}}
}

\begin{document}

\begin{forest} nice empty nodes, sn edges
    [TP
        [{the ball} ]
        [
            [T ]
            [PrP
                [{$<$the ball$>$} ]
                [
                    [Pr ]
                    [VoiP
                        [{$<$the ball$>$} ]
                        [
                            [Voi ]
                            [AffP
                                [{to Mary} ]
                                [
                                    [Aff ]
                                    [ThP
                                        [{$<$the ball$>$} ]
                                        [
                                            [Th ]
                                            [AgP
                                                [{by John} ]
                                                [
                                                    [Ag ]
                                                    [$\surd$throw ]
                                                ]
                                            ]
                                        ]
                                    ]
                                ]
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ]
\end{forest}

\end{document}

Update

Interestingly, it compiles without error if everything below the Aff leaf is deleted. That is, the following will compile:

\begin{forest} nice empty nodes, sn edges
    [TP
        [{the ball} ]
        [
            [T ]
            [PrP
                [{$<$the ball$>$} ]
                [
                    [Pr ]
                    [VoiP
                        [{$<$the ball$>$} ]
                        [
                            [Voi ]
                            [AffP
                                [{to Mary} ]
                                [
                                    [Aff ]
                                ]
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ]
\end{forest}
Jason Zentz
  • 4,158
Adam Liter
  • 12,567
  • I'm completely guessing but a coordinate doesn't have any difference between it's anchors. So it might be dividing the distance between north and south. Does it matter when you change the coordinate to node in delay? – percusse Oct 01 '14 at 17:53
  • @percusse You mean change shape=coordinate to shape=node? Then it throws an error Unknown shape \`node.''If you change it toshape=rectangle`, though, it does fix the problem. That is, it will at least compile without an error, but then the tree doesn't look as I want it to look. The empty nodes show white space, rather than being connected to the next branches directly. – Adam Liter Oct 01 '14 at 17:59
  • Yes I meant rectangle. Then keep the coordinate but change the anchor=north to center at the end. That should do it. If it works then you don't need that style anyway. Coordinates only have center anchors. – percusse Oct 01 '14 at 18:00
  • @percusse Then the spine of the tree isn't completely straight. I suppose I can live with that as a workaround though, at least for the time being. – Adam Liter Oct 01 '14 at 18:02
  • 1
    If you use rectangle with inner and outer sep set to 0pt, then it is almost right... – cfr Oct 16 '14 at 01:05
  • I'm experiencing the same problem. I discovered that the only node in your MWE that's causing the problem is the sister of "to Mary." If you put text there, there's no error. I can't figure out why the other empty "bar-level" nodes (on the spine, between XPs) don't have the same problem, since they're coordinates too. – Jason Zentz Dec 08 '14 at 21:30
  • I took @cfr's suggestion and then tweaked a negative outer ysep value until it no longer threw the error. For example, for this MWE it would be -0.550pt. If you zoom in a lot, you can see that the lines aren't quite parallel, but when I print it I can't see the gap. The value has to be tweaked differently depending on the font, font size, and calign angle (e.g., -0.455pt is best for Linux Libertine O at 12pt with calign angle=60). – Jason Zentz Apr 17 '15 at 19:51

2 Answers2

5

First, a remark: the error occurs even without sn edges style.

I believe this is not a forest, but rather a pgf bug. I've tracked the problem down to \pgfintersectionofpaths of pgf's intersections library. The following code replicates the exact error without forest.

\pgfintersectionofpaths{%
  \pgfpathmoveto{\pgfpoint{0.0pt}{-3.53297pt}}
  \pgfpathlineto{\pgfpoint{19.54204pt}{-31.44316pt}}%
}{%
  \pgfpathmoveto{\pgfpoint{34.6372pt}{-53.00208pt}}%
  \pgfpathlineto{\pgfpoint{19.54204pt}{-31.44316pt}}}

I've investigated the matter a bit further. \pgfintersectionofpaths calls \pgfpointintersectionoflines, which computes the intersection of two lines by applying some coordinate transformation to some point. The mathematical details of the two "some"s in the previous sentence are not important, except for the fact that the final step in PGF's calculation of the relevant transformation matrix is inversion of some other matrix, by calling \pgftransforminvert. It is \pgftransforminvert which fails, as the matrix it is trying to invert is near-singular. The PGF manual (p. 641) warns this will happen:

This command will produce an error if the determinant of the matrix is too small, that is, if the matrix is near-singular.

But why is the matrix near-singular? Because the line segments we're trying to intersect are almost parallel. At this point it seemed to me as if the source of the problem was TeX's numerical precision. However ...

Before computing the intersection of lines by calling \pgfpointintersectionoflines, \pgfintersectionofpaths tries to detect if the lines intersect: this is done in the \if-like \pgfiflinesintersect. So I believe the problem is that \pgfiflinesintersect claims that the lines intersect, but \pgfpointintersectionoflines fails during the computation of the intersection. (The code of \pgf@iflinesintersect contains a remark "16384 may not be a robust choice.", where 16384 is a constant used in some internal normalisation process. Could this be the source of the problem?)

Investigating the behaviour of \pgfintersectionofpaths even further, I realized that it is actually inconsistent. One would expect the following calls of \pgfintersectionofpaths to yield the same result (1 intersection, the origin):

\pgfintersectionofpaths
  {\pgfpathmoveto{\pgfpoint{0pt}{0pt}}\pgfpathlineto{\pgfpoint{1pt}{0pt}}}
  {\pgfpathmoveto{\pgfpoint{0pt}{0pt}}\pgfpathlineto{\pgfpoint{0pt}{1pt}}}
\pgfintersectionsolutions

\pgfintersectionofpaths
  {\pgfpathmoveto{\pgfpoint{0pt}{0pt}}\pgfpathlineto{\pgfpoint{1pt}{0pt}}}
  {\pgfpathmoveto{\pgfpoint{0pt}{0pt}}\pgfpathlineto{\pgfpoint{-1pt}{0pt}}}
\pgfintersectionsolutions

However, this is not the case: the first one, where the lines are perpendicular, yields 1 intersection, the other, where the lines are (exactly) parallel, yields 0 intersections.

I would love to fix this, but the issue seems too complex for me, and anyway, I believe it deserves some discussion and that the author of pgf should be notified.

3

I'm not sure why this might be the case, but this error seems to be related to the font being used.

I can replicate your error when I compile your MWE using the following configurations:

  • no font specification (Computer/Latin Modern), compiled with pdfLaTeX or XeLaTeX
  • \usepackage{palatino}, compiled with pdfLaTeX or XeLaTeX
  • \usepackage{libertine}, compiled with pdfLaTeX or XeLaTeX
  • \usepackage{fontspec} \setmainfont{Linux Libertine O}, compiled with XeLaTeX
  • \usepackage{fontspec} \setmainfont{Doulos SIL}, compiled with XeLaTeX
  • \usepackage{fontspec} \setmainfont{TeX Gyre Pagella}, compiled with XeLaTeX

But with these configurations, it compiles without the error:

  • \usepackage{times}, compiled with pdfLaTeX or XeLaTeX
  • \usepackage{kpfonts}, compiled with pdfLaTeX or XeLaTeX
  • \usepackage{fontspec} \setmainfont{Charis SIL}, compiled with XeLaTeX
  • \usepackage{fontspec} \setmainfont{Cambria}, compiled with XeLaTeX
  • \usepackage{fontspec} \setmainfont{Brill}, compiled with XeLaTeX
  • \usepackage{fontspec} \setmainfont{Times New Roman}, compiled with XeLaTeX

With this one, I got a different error (Dimension too large on the \end{forest} line):

  • \usepackage{fontspec} \setmainfont{TeX Gyre Termes}, compiled with XeLaTeX

So if you choose your font right, you can avoid the error. Personally, I would still prefer to have an explanation of how to avoid it regardless of font selection, though.

Jason Zentz
  • 4,158