Institutions ranked by the number of AMS Fellows, 2019 edition

Only those with the count of 3 or greater are included. Not counting the deceased. Considering CUNY as a single institution. Source of data.

    1. Rutgers The State University of New Jersey New Brunswick : 44
    2. University of California, Los Angeles : 38
    3. Massachusetts Institute of Technology : 34
    4. University of California, Berkeley : 34
    5. University of Michigan : 32
    6. Cornell University : 26
    7. Princeton University : 26
    8. University of Illinois, Urbana-Champaign : 24
    9. University of Wisconsin, Madison : 24
    10. Brown University : 23
    11. Stanford University : 22
    12. University of Texas at Austin : 22
    13. New York University, Courant Institute : 21
    14. The City University of New York : 21
    15. University of California, San Diego : 21
    16. University of Illinois at Chicago : 21
    17. University of Chicago : 20
    18. University of Washington : 20
    19. Stony Brook University : 19
    20. Texas A&M University : 19
    21. University of California, Santa Barbara : 19
    22. University of Minnesota-Twin Cities : 18
    23. University of Pennsylvania : 17
    24. Duke University : 16
    25. Indiana University, Bloomington : 16
    26. Purdue University : 16
    27. University of Maryland : 16
    28. Georgia Institute of Technology : 15
    29. Northwestern University : 15
    30. Ohio State University, Columbus : 15
    31. Pennsylvania State University : 15
    32. University of California, Irvine : 13
    33. University of Utah : 13
    34. Johns Hopkins University, Baltimore : 12
    35. University of British Columbia : 12
    36. Boston University : 11
    37. Harvard University : 11
    38. University of Notre Dame : 11
    39. University of Toronto : 11
    40. Eidgenössische Technische Hochschule Zürich (ETH Zürich) : 10
    41. University of North Carolina at Chapel Hill : 10
    42. University of Virginia : 10
    43. Vanderbilt University : 10
    44. Brandeis University : 9
    45. University of California, Davis : 9
    46. University of Georgia : 9
    47. Columbia University : 8
    48. Institute for Advanced Study : 8
    49. Rice University : 8
    50. Tel Aviv University : 8
    51. University of Oregon : 8
    52. California Institute of Technology : 7
    53. Ecole Polytechnique Fédérale de Lausanne (EPFL) : 7
    54. Michigan State University : 7
    55. Microsoft Research : 7
    56. North Carolina State University : 7
    57. University of Nebraska-Lincoln : 7
    58. University of Oxford : 7
    59. University of Southern California : 7
    60. Williams College : 7
    61. Carnegie Mellon University : 6
    62. The Hebrew University of Jerusalem : 6
    63. Université Pierre et Marie Curie (Paris VI) : 6
    64. University of Arizona : 6
    65. University of Rochester : 6
    66. Harvey Mudd College : 5
    67. Northeastern University : 5
    68. Temple University : 5
    69. Université Paris-Diderot : 5
    70. University of California, Riverside : 5
    71. University of Colorado, Boulder : 5
    72. Virginia Polytechnic Institute and State University : 5
    73. Boston College : 4
    74. Florida State University : 4
    75. Louisiana State University, Baton Rouge : 4
    76. NYU Polytechnic School of Engineering : 4
    77. Norwegian University of Science and Technology : 4
    78. Rutgers The State University of New Jersey Newark : 4
    79. University of Cambridge : 4
    80. University of Connecticut, Storrs : 4
    81. University of Missouri-Columbia : 4
    82. University of Tennessee, Knoxville : 4
    83. University of Warwick : 4
    84. Washington University : 4
    85. Weizmann Institute of Science : 4
    86. Yale University : 4
    87. Alfréd Rényi Institute of Mathematics, Hungarian Academy of Sciences : 3
    88. Australian National University : 3
    89. Barnard College, Columbia University : 3
    90. Emory University : 3
    91. Imperial College : 3
    92. Københavns Universitet : 3
    93. KTH Royal Institute of Technology : 3
    94. Mathematical Institute, Oxford University : 3
    95. McGill University : 3
    96. Pomona College : 3
    97. Shanghai Jiao Tong University : 3
    98. Tsinghua University : 3
    99. Tufts University : 3
    100. Università degli Studi di Milano : 3
    101. Université Paris-Sud (Paris XI) : 3
    102. Université de Montréal : 3
    103. University of Iowa : 3
    104. University of Melbourne : 3
    105. University of Memphis : 3


String matching in Google Sheets /Docs /Apps Script

Here I summarize various ways of matching string patterns in selected Google products: Sheets, Docs, and Apps Script. They are ordered from least to most powerful.

  1. String comparison in Sheets, =if(A1 = "cat", "is", "is not") Perhaps surprisingly, this is not literal comparison, but case-insensitive match: the condition also holds true if A1 has “Cat” or “CAT”. This makes one wonder how to actually test strings for equality; I’ll return to this later.
  2. Substring search: find (case sensitive) and search (case-insensitive).
    Example: =find("Cat", A1)
  3. Wildcards in Sheets functions like countif and sumif: ? matches any single character, * matches any number of any characters.
    Example: =countif(A1:A9, "a?b*")
  4. like comparison in query, the Sheets function using the Google Visualization API Query Language. This is similar to the previous: underscore _ matches any single character, percentage symbol % any number of any characters.
    Example: =query(A1:B9, "select A where B like 'a_b%'").
  5. findText method of objects of class Text in Apps Script, extending Google Docs. Documentation says “A subset of the JavaScript regular expression features are not fully supported, such as capture groups and mode modifiers.” In particular, it does not support lookarounds.
    var body = DocumentApp.getActiveDocument().getBody().editAsText();
    var found = body.findText("ar{3,}gh").getElement().asText().getText();

    Yeah… I find Google Docs API clumsy, verbose and generally frustrating; unlike Google Sheets API.
  6. regexmatch function in Sheets and its relatives regexextract and regexreplace. Uses RE2 regex library, which is performance-oriented but somewhat limited, for example it does not support lookarounds. It does support capture groups.
    Example: =regexmatch(A1, "^h[ao]t+\b")
  7. matches comparison in query, the Sheets function using the Google Visualization API Query Language. Supports regular expressions (matching an entire string), including lookaheads but apparently not lookbehinds. Not clear what exactly is supported.
    Example: =query(A1:B9, "select A where B matches 'a.b(?!c).*'").
  8. JavaScript regular expression methods are supported in Apps Script… to the extent that they are supported in whatever version of Rhino JavaScript engine that GAS runs on. For example, non-capturing groups are broken and won’t be fixed. Be sure to test your regexes in Apps Script itself, not in a regular JS environment.

So what about the literal, case-sensitive string comparison in Google Sheets? Apparently, the way to do it is to use regexmatch… Example: =regexmatch(A1, "^cat$") returns True when A1 contains “cat” in lower case.

Maintaining restyled Google Calendar

RESTYLEgc is a pretty old (2008-11) MIT-licensed project by Brian Gibson, which enables, among other things, replacing the default stylesheet of embedded Google Calendar with a custom one.

Due to various changes on Google’s side made since 2011, the version available from Google Code link above no longer works. So I put up a GitHub repo with slightly modified files; only the two PHP scripts and the CSS file are included, the optional resources are not. (February 2017 update: a JS file is added.)

Keeping up with the changes in Google URL structure

Line 120 of restylegc.php changed from

$url = "" . $_SERVER['QUERY_STRING'];


$url = "" . $_SERVER['QUERY_STRING'];

Line 19 of restylegc-js.php changed from

$url = "" . $_SERVER['QUERY_STRING'];


$url = "https:" . $_SERVER['QUERY_STRING'];

Line 42 of restylegc-js.php changed from

$replacement = '"';


$replacement = '"';

February 2017 update

Google changed the link to the JavaScript file that runs the calendar; it is no longer a direct link to a .js file. (This resulted in the iframe erroring out with “window._init is not a function” and such; the function was defined in the JS file that failed to load.)

To correct the issue, I did the following:

Lines 137-138 of restylegc.php changed from

$pattern = '/src="(.*js)"/';
$replacement = 'src="restylegc-js.php?$1"';


$pattern = '/javascript" src="(\/calendar\S*)"/';
$replacement = 'javascript" src="restylegc-js.php?$1"';

Uncommented line 29 of restylegc-js.php, changing it from

//$url = "http://myserver.tld/path/to/archive/e0437df6468589031e718f3606b03917embedcompiled__en.js";


$url = "gcal.js";

Downloaded the JavaScript file used by the calendar, so that it’s served locally. (This is the gcal.js file referred to above.)

The rest of the post describes cosmetic changes made in the GitHub repo, which are not required for the calendar to work.

Better wrapping of text in narrow calendars

Line 1181 of restylegc.css (rules for .agenda .event-summary, .agenda .event-summary-expanded) changed




Line 1263 of restylegc.css (rules for .agenda .event-summary-expanded) changed




Also (line 1323) added


to the rule

.ie6 .agenda .event-title

although in 2015, IE6 isn’t quite as big a deal anymore.

Parsing calculus with regular expressions

As a service* to math students everywhere (especially those taking calculus), I started Mathematics.SE Index. The plan is to have a thematic catalog of common exercises in college-level mathematics, each linked to a solution posted on Math.SE.

As of now, the site has reasonably complete sections on Limits and Series, with a rudimentary section on binomial sums. All lists are automatically generated. Initial filtering was done with Data Explorer SQL query, using tags and keywords in question body. The query also took into account the view count (i.e., how often the problem is searched for), and the existence of upvoted answers.

The results of the query were processed with a Google Sheets script: a bunch of regular expressions extracted LaTeX markup with a desired pattern, checked its integrity [not of academic kind] and transformed into WordPress-compatible markup.

Plans for near future: integrals (especially improper), basic proofs by induction, {\epsilon-\delta}, maybe some group theory and differential equations… depends on how easy it is to teach these topics to regular expressions.

(*) Or disservice, I wouldn’t know.

Life after Google Reader, day 2

Having exported the Shared/Starred items from Google Reader, I considered several ways of keeping them around, and eventually decided to put them right here (see “Reading Lists” in the main navigation bar). My reasons were:

  • This site is unlikely to disappear overnight, since I am paying WordPress to host it.
  • Simple, structured HTML is not much harder for computers to parse than JSON, and is easier for humans to use.
  • Someone else might be interested in the stuff that I find interesting.

First step was to trim down shared.json and starred.json, and flatten them into a comma-separated list. For this I used Google Refine, which, coincidentally, is another tool that Google no longer develops. (It is being continued by volunteers as an open-source project OpenRefine). The only attributes I kept were

  • Title
  • Hyperlink
  • Author(s)
  • Feed name
  • Timestamp
  • Summary

Springer feeds gave me more headache than anything else in this process. They bundled the authors, abstract, and other information into a single string, within which they were divided only by presentational markup. I cleaned up some of Springer-published entries, but also deleted many more than I kept. “Sorry, folks – your paper looks interesting, but it’s in Springer.”

Compared to the clean-up, conversion to HTML (in a Google Spreadsheet) took no time at all. I split the list into chunks 2008-09, 2010-11, 2012, and 2013, the latter being updated periodically. Decided not to do anything about LaTeX markup; much of it would not compile anyway.

Last question: how to keep the 2013 list up-to-date, given that Netvibes offers no export feature for marked items? jQuery to the rescue:

Now with a freehand circle!
Now with a freehand circle!

The script parses the contents of Read Later tab, extracts the items mentioned above, and wraps them into the same HTML format as the existing reading list.

$(document).ready(function() {
  function exportSaved() {
  var html='';
  $('.hentry.readlater').each(function() {
    var title = $('.entry-innerTitle', this).html().split('<span')[0];
    var hyperref = $('.entry-innerTitle', this).attr('href');
    var summary = ($('.entry-content', this).html()+'').replace('\n',' ');
    var timestamp = $('.entry-innerPublished', this).attr('time');
    var feed = $('.entry-innerFeedName', this).html();
    var author = ($('.author', this).html()+'').slice(5);
    var date = new Date(timestamp*1000);
    var month = ('0'+(date.getMonth()+1)).slice(-2);
    var day = ('0'+date.getDate()).slice(-2);
    var readableDate = date.getFullYear()+'-'+month+'-'+day;
        html = html+"<div class='list-item'><h4 class='title'><strong><a href='"+hyperref+"'>"+title+"</a></strong></h4><h4 class='author'>"+author+"</h4><h5 class='source'>"+feed+" : "+readableDate+"</h5><div class='summary' style='font-size:80%;line-height:140%;'>"+summary+"</div></div>";  
   $('export').insertAfter($('#switch-view')).click(function() { exportSaved(); });

The script accesses the page via an extension in Google Chrome. It labels HTML elements with classes for the convenience of future parsing, not for styling. I had to use inline styles to keep WordPress happy. Dates are formatted according to ISO 8601, making it possible to quickly jump to any month using in-page search for “yyyy-mm”. Which would not work with mm/dd/yyyy, of course.

Unfortunately, some publishers still insert the authors’ names in the summary. Unlike arXiv, which serves reasonably structured feeds, albeit with unnecessary hyperlinks in the author field. While I am unhappy with such things (and the state of the web in general), my setup works for me, and this concludes my two-post detour from mathematics.

xkcd 743: Infrastructures

Life after Google Reader

My first reaction to the news was to grab my data and remove Google Reader from bookmarks. I am not in the habit of clinging to doomed platforms. The downloaded zip archive has a few files with self-explanatory names. For example, subscriptions.xml is the list of subscriptions, which can be imported, for example, to Netvibes. Which is what I did, having found the Reader mode of Netvibes a reasonably close approximation. Some of the keyboard shortcuts work the same way (J and K), but most are different:

Netvibes reader shortcuts
Netvibes reader shortcuts

There is no native Android app, and the webapp does not play well with Opera Mobile. At least it works with the stock Android browser:

Netvibes version of “star” is “mark to real later”. But apparently, there is no way to export the list of such items. (Export feeds returns only the list of feeds.) The list of items of interest is more important to me than my collection of feeds.

Besides, I already have two sizable lists of such items, courtesy of Google: shared.json, from back when Google Reader had sensible sharing features; and starred.json from recent years. I guess my next step will be to work out a way to merge this data and keep it up-to-date and under my control in the future.

Web-based LaTeX to WordPress (and something about polynomials)

Recently I began using the excellent Python program LaTeX to WordPress (LaTeX2WP) by Luca Trevisan. Since some of my posts are written on computers where Python is not readily available, I put LaTeX2WP on PythonAnywhere as a web2py application. The downside is that settings are stuck at default (e.g., you get blackboard bold letters using \N, \Z, \R, \C, \Q). The upside is that the process simplifies to copy-paste-click-copy-paste.

The application is here: Web-based LaTeX2WP and it looks like this:


Although my modification of the source code is utterly trivial, according to GPL I should put it here. Namely, I merged and into one file, since web users can’t edit the style file anyway. Also replaced file input/output by a function call, which comes from web2py controller:

def index():
    import convert4
    form=FORM(TEXTAREA(_name='LaTeX', requires=IS_NOT_EMPTY()), BR(), INPUT(_type='submit', _value='Convert to WordPress'))
    produced = ''
    if form.accepts(request,session):
        produced = convert4.mainproc(form.vars.LaTeX)
    form2=FORM(TEXTAREA(_name='WP', value=produced))
    return dict(form=form, form2=form2)

which in turn populates the html file:

Enter LaTeX code here
Get WordPress code here

To beef up this post, I include sample output. It is based on an old write-up of my discussions with Paul Gustafson during REU 2006 at Texas A&M University. Unfortunately, the project was never finished. I would still like to know if {\partial}-equivalence of polynomials appeared in the literature; the definition looks natural enough.

Given two polynomials {p,q \in {\mathbb C}[z_1,\dots,z_n]}, write {q\preccurlyeq p} if there exists a differential operator {\mathcal T\in {\mathbb C}[\frac{\partial}{\partial z_1},\dots, \frac{\partial}{\partial z_n}]} such that {q=\mathcal Tp}. The relation {\preccurlyeq} is reflexive and transitive, but is not antisymmetric. If both {p\preccurlyeq q} and {q\preccurlyeq p} hold, we can say that {p} and {q} are {\partial}-equivalent.

A polynomial is {\partial}-homogeneous if it is {\partial}-equivalent to a homogeneous polynomial.

It turns out that it is easy to check the {\partial}-homogeneity of {p} by decomposing it into homogeneous parts

\displaystyle    p=p_0+p_1+\dots +p_d   \ \ \ \ \ (1)

where {p_k} is homogeneous of degree {k} and {p_d\not\equiv 0}.

Then use the following

Proposition 1.
The polynomial (1) is {\partial}-homogeneous if and only if {p_k\preccurlyeq p_d} for {k=0,\dots, d-1}.

Proof: Exercise. \Box

For example, the polynomial {p(z,w)=z^3-5w^3+2zw} is not {\partial}-homogeneous since {zw\not\preccurlyeq (z^3-5w^3)}. On the other hand, {q(z,w)=z^3-3z^2w+2zw} is {\partial}-homogeneous because {zw\preccurlyeq (z^3-3z^2w)}. In particular, {p} and {q} are not {\partial}-equivalent.

Proposition 1 also makes it clear that every polynomial in one variable is {\partial}-homogeneous. For univariate polynomials {\partial}-equivalence amounts to having the same degree.