+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
An Interactive Version of colorcubes
+
A 231-character static version of colorcubes in the current MiniHack generated quite a bit of interest. So I am posting the full version, where you can change number of cubes and the view point, at this link.
+
+
+
+
+
diff --git a/_posts/mathworks/2022-7-21-p=8810.md b/2022/an-interesting-and-perhaps-new-matrix/index.html
similarity index 62%
rename from _posts/mathworks/2022-7-21-p=8810.md
rename to 2022/an-interesting-and-perhaps-new-matrix/index.html
index 517ead2..88c2ae4 100644
--- a/_posts/mathworks/2022-7-21-p=8810.md
+++ b/2022/an-interesting-and-perhaps-new-matrix/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2022-07-21 04:38:23'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2022/07/20/an-interesting-and-perhaps-new-matrix/?s_tid=feedtopost
-slug: an-interesting-and-perhaps-new-matrix
-title: An Interesting, and Perhaps New, Matrix
----
-
-
I do not recall having seen this matrix before, but I will not be surprised to learn that somebody else already knows all about it, especially if that person's name is Nick.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
An Interesting, and Perhaps New, Matrix
+
I do not recall having seen this matrix before, but I will not be surprised to learn that somebody else already knows all about it, especially if that person's name is Nick.
I've be
% Comments in the Comments, or in email to me, are welcome.
##### SOURCE END ##### 4c513405f3644e5fbcae1bf70683cb1d
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2022-10-23-p=9417.md b/2022/christian-reinsch-roland-bulirsch-and-the-svd/index.html
similarity index 69%
rename from _posts/mathworks/2022-10-23-p=9417.md
rename to 2022/christian-reinsch-roland-bulirsch-and-the-svd/index.html
index 647cf11..92c7bb0 100644
--- a/_posts/mathworks/2022-10-23-p=9417.md
+++ b/2022/christian-reinsch-roland-bulirsch-and-the-svd/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2022-10-23 23:41:27'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2022/10/23/christian-reinsch-roland-bulirsch-and-the-svd/?s_tid=feedtopost
-slug: christian-reinsch-roland-bulirsch-and-the-svd
-title: Christian Reinsch, Roland Bulirsch, and the SVD
----
-
-
Christian Reinsch and Roland Bulirsch both passed away recently, Reinsch on October 8 and Bulirsch on September 21. Reinsch was 88 years old and Bulirsch was 89. Both of them were retired professors of numerical analysis at the Technical University of Munich. Both of them were friends of mine. But in almost all other ways, they were very different people.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Christian Reinsch, Roland Bulirsch, and the SVD
+
Christian Reinsch and Roland Bulirsch both passed away recently, Reinsch on October 8 and Bulirsch on September 21. Reinsch was 88 years old and Bulirsch was 89. Both of them were retired professors of numerical analysis at the Technical University of Munich. Both of them were friends of mine. But in almost all other ways, they were very different people.
The Handbook for Automatic Computation, Volume II, Linear Algebra, is a research monograph published in 1971 by Springer-Verlag. This Handbook was edited by J. H. Wilkinson and Christian Reinsch and includes dozens of Algol procedures by 19 different authors for solving systems of simultaneous equations and computing matrix eigenvalues and singular values.
Wilkinson and colleagues at the National Physical Laboratory in Teddington, England wrote around half of the Algol procedures in the Handbook. Reinsch authored several procedures himself and reviewed and tested most, if not all, of the entire Handbook.
@@ -261,4 +328,76 @@
Munich Visit
My la
% to polish off a few of those one-liter German beer steins before
% closing down the place.
##### SOURCE END ##### f2dde2cc84e245d09b99f58b9781b0eb
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2022-12-10-p=9491.md b/2022/color-cube-meets-rubik-s-cube/index.html
similarity index 53%
rename from _posts/mathworks/2022-12-10-p=9491.md
rename to 2022/color-cube-meets-rubik-s-cube/index.html
index d510a65..52d127a 100644
--- a/_posts/mathworks/2022-12-10-p=9491.md
+++ b/2022/color-cube-meets-rubik-s-cube/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2022-12-10 02:41:01'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2022/12/09/color-cube-meets-rubiks-cube/?s_tid=feedtopost
-slug: color-cube-meets-rubik-s-cube
-title: Color Cube Meets Rubik’s Cube
----
-
-
I have made a half dozen blog posts about Rubik's Cube so far this year. And, during the MATLAB Central Mini Hack in October, I resurrected an old code about the Color Cube. Now, a combination of the two, Rubik/Color Qube, creates an elegant tool for investigating Matrices in Action.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Color Cube Meets Rubik’s Cube
+
I have made a half dozen blog posts about Rubik's Cube so far this year. And, during the MATLAB Central Mini Hack in October, I resurrected an old code about the Color Cube. Now, a combination of the two, Rubik/Color Qube, creates an elegant tool for investigating Matrices in Action.
Here is the opening screen shot of Rubik/Color Qube, one of the most elaborate MATLAB programs that I have ever written.
@@ -197,4 +264,76 @@
Software
Qube<
% |Qube| is available as a self-extracting MATLAB archive at this link,
% .
##### SOURCE END ##### ce9c453c88254608ad0e691ca4711df7
--->
\ No newline at end of file
+-->
+
+
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
modfun, A Short Program Produces Impressive Graphics
+
This nifty graphics gem started with a contribution by Paul Villain to the MATLAB 2022 Mini Hack, currently taking place on MATLAB Central.
Villain's contribution is 102 mod 500 . My rewrite is modfun. Villain's 102 and 500 become the parameters m and n.
+
modfun(m,n) connects n points, z(j), equally spaced
+ around the complex unit circle, by n+1 straight lines.
+ The j-th line connects z(j+1) to z(mod(j*m,n)+1).
code
The basic code uses complex arithmetic and is only eight lines long. When the graphics is done with line instead of plot, it is not necessary to use hold on.
+
function modfun(m,n)
+ init_fig
+ z = exp(2i*pi*(0:n)/n);
+ for j = 0:n
+ zj = [z(j+1),z(mod(j*m,n)+1)];
+ line(real(zj),imag(zj))
+ end
+ end
The initialization makes line possible.
+
function init_fig
+ axis([-1 1 -1 1])
+ axis square
+ axis off
+ end
Animation
This animation of modfun(105,200) has one frame for every five lines.
+
+
Gallery
A sample.
+
+
+
Quiz
Match these calls to modfun to the plots in the Gallery.
+
+
+
+
+
diff --git a/_posts/mathworks/2022-8-21-p=8840.md b/2022/polygons-polyshapes-and-puzzles/index.html
similarity index 66%
rename from _posts/mathworks/2022-8-21-p=8840.md
rename to 2022/polygons-polyshapes-and-puzzles/index.html
index 3892a8b..c062bd6 100644
--- a/_posts/mathworks/2022-8-21-p=8840.md
+++ b/2022/polygons-polyshapes-and-puzzles/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2022-08-21 15:42:36'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2022/08/21/polygons-polyshapes-and-puzzles/?s_tid=feedtopost
-slug: polygons-polyshapes-and-puzzles
-title: Polygons, Polyshapes and Puzzles
----
-
-
Until recently, I knew nothing about the polyshape object in MATLAB. Now I can use polyshape to simulate an extraordinary puzzle.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Polygons, Polyshapes and Puzzles
+
Until recently, I knew nothing about the polyshape object in MATLAB. Now I can use polyshape to simulate an extraordinary puzzle.
The Web site Art of Play, from some folks in San Diego, has well over two-hundred puzzles. Recently, one of their most popular puzzles, Mighty Cheese, caught my attention. The idea is to move the slices of plastic cheese around within the frame in order to create a hole large enough to hold the little plastic mouse. However, when I last checked, Mighty Cheese was sold out. Not wanting to be dissuaded by the unavailability of the puzzle itself, and not knowing the solution, I set out to build a simulator.
@@ -250,4 +317,76 @@
Software
My code i
% .
##### SOURCE END ##### 2f68df87f4004e7ea2832e4310206744
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2022-5-18-p=8651.md b/2022/rotation-matrices/index.html
similarity index 65%
rename from _posts/mathworks/2022-5-18-p=8651.md
rename to 2022/rotation-matrices/index.html
index aaa9f05..f94663a 100644
--- a/_posts/mathworks/2022-5-18-p=8651.md
+++ b/2022/rotation-matrices/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2022-05-18 23:50:24'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2022/05/18/rotation-matrices/?s_tid=feedtopost
-slug: rotation-matrices
-title: Rotation Matrices
----
-
-
The matrices in the following animations are at the heart of computer graphics. They describe objects moving in three-dimensional space and are essential to MATLAB's Handle Graphics, to Computer Added Design packages, to Computer Graphics Imagery in films, and to most popular video games. Many modern computers contain GPUs, Graphic Processing Units, which are optimized to compute the product of these matrices.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Rotation Matrices
+
The matrices in the following animations are at the heart of computer graphics. They describe objects moving in three-dimensional space and are essential to MATLAB's Handle Graphics, to Computer Added Design packages, to Computer Graphics Imagery in films, and to most popular video games. Many modern computers contain GPUs, Graphic Processing Units, which are optimized to compute the product of these matrices.
The homogeneous coordinates system used in today's computer graphics software and hardware makes it possible to describe rotations, translations and many other operations with 3-by-3 and 4-by-4 matrices. These matrices operate on vectors with the position of an object, x, y and z , in the first three components.
Rotations about the coordinate axes are described by three matrices. Rotations about the x -axis are produced by $R_x$, which rotates y and z, while leaving x unchanged.
@@ -264,4 +331,74 @@
Software
The sourc
##### SOURCE END ##### fac94086e84b4ca1b5df2dbc8d19f63c
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2022-9-6-p=9032.md b/2022/rubik-s-cube-superflips-and-god-s-number/index.html
similarity index 63%
rename from _posts/mathworks/2022-9-6-p=9032.md
rename to 2022/rubik-s-cube-superflips-and-god-s-number/index.html
index d61846a..0b127b4 100644
--- a/_posts/mathworks/2022-9-6-p=9032.md
+++ b/2022/rubik-s-cube-superflips-and-god-s-number/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2022-09-06 02:00:24'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2022/09/05/rubiks-cube-superflips-and-gods-number/?s_tid=feedtopost
-slug: rubik-s-cube-superflips-and-god-s-number
-title: Rubik’s Cube Superflips and God’s Number
----
-
-
How hard is it to solve a Rubik's Cube?
When can you say that your Rubik's Cube is completely scrambled?
Why might the answer depend on where you went to school?
What interesting mathematical questions are involved?
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Rubik’s Cube Superflips and God’s Number
+
How hard is it to solve a Rubik's Cube?
When can you say that your Rubik's Cube is completely scrambled?
Why might the answer depend on where you went to school?
What interesting mathematical questions are involved?
The difficulty of solving any configuration of a Rubik's Cube is the smallest number of moves required to return to the intial configuration where each face is showing a single color.
But what, exactly, is a move? The so-called quarter-turn metric says a move is turning any face by 90 degrees. The half-turn metric says turning any face by either 90 or 180 degrees is a single move. For example, using Singmaster notation and the quarter-turn metric, the sequence "L L", which turns the left face twice in the same direction, is two moves. But in the half-move metric, the sequence becomes "L2" and counts as a single move.
@@ -262,4 +329,76 @@
Compare
Let's comp
%
%
##### SOURCE END ##### 552a77033bf74984addf11ae10f9bb2e
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2022-6-10-p=8768.md b/2022/the-soma-cube-again/index.html
similarity index 51%
rename from _posts/mathworks/2022-6-10-p=8768.md
rename to 2022/the-soma-cube-again/index.html
index bae44b8..b9f654b 100644
--- a/_posts/mathworks/2022-6-10-p=8768.md
+++ b/2022/the-soma-cube-again/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2022-06-10 09:07:52'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2022/06/10/the-soma-cube-again/?s_tid=feedtopost
-slug: the-soma-cube-again
-title: The Soma Cube, Again
----
-
-
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
Piet Hein (1905-1996) was an extraordinary Danish inventor, mathematician, poet and philosopher. He invented the Soma Cube puzzle in 1933. I wrote a blog post about Hein and some of his creations several years ago, Soma Cube 2016.
The Soma Cube puzzle has seven pieces. One of them is a V-shaped piece made from three cubelets. The other six pieces are L, T, Z, R, S, and Y with four cubelets each. That's a total of 27 cubelets, just enough to make a 3-by-3-by-3 cube. Sound familiar?
@@ -136,4 +203,76 @@
Update
I have comb
% https://blogs.mathworks.com/cleve/files/Soma_osf.m>
##### SOURCE END ##### ba03413b3d6846149e5b9f9e92eb3300
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2022-9-25-p=9227.md b/2022/trio-a-wooden-puzzle-from-the-czech-republic/index.html
similarity index 58%
rename from _posts/mathworks/2022-9-25-p=9227.md
rename to 2022/trio-a-wooden-puzzle-from-the-czech-republic/index.html
index 1f5c05b..5a56d10 100644
--- a/_posts/mathworks/2022-9-25-p=9227.md
+++ b/2022/trio-a-wooden-puzzle-from-the-czech-republic/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2022-09-25 17:00:41'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2022/09/25/trio-a-wooden-puzzle-from-the-czech-republic/?s_tid=feedtopost
-slug: trio-a-wooden-puzzle-from-the-czech-republic
-title: Trio, A Wooden Puzzle from the Czech Republic
----
-
-
"Clever Toys" is a puzzle company in the Czech Republic. Their Web site describes five different hand-made, wooden puzzles that are related mathematically to the Rubik's Cube.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Trio, A Wooden Puzzle from the Czech Republic
+
"Clever Toys" is a puzzle company in the Czech Republic. Their Web site describes five different hand-made, wooden puzzles that are related mathematically to the Rubik's Cube.
Thanks to S
%% Thanks
% Thanks to Steve Eddins and Tom Lane for help with this post.
##### SOURCE END ##### 233d0111a3a04a7896bd6aac6263df7c
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2023-6-17-p=10373.md b/2023/arls-automatically-regularized-least-squares/index.html
similarity index 66%
rename from _posts/mathworks/2023-6-17-p=10373.md
rename to 2023/arls-automatically-regularized-least-squares/index.html
index b2a9104..9022ccd 100644
--- a/_posts/mathworks/2023-6-17-p=10373.md
+++ b/2023/arls-automatically-regularized-least-squares/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2023-06-17 00:57:05'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2023/06/16/arls-automatically-regularized-least-squares/?s_tid=feedtopost
-slug: arls-automatically-regularized-least-squares
-title: ARLS, Automatically Regularized Least Squares
----
-
-
(I have a guest blogger today. Ron Jones worked with me in 1985 for his Ph. D. from the University of New Mexico. He retired recently after nearly 40 years at Sandia National Labs in Albuquerque and now has a chance to return to the problem he studied in his thesis. -- CBM)
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
ARLS, Automatically Regularized Least Squares
+
(I have a guest blogger today. Ron Jones worked with me in 1985 for his Ph. D. from the University of New Mexico. He retired recently after nearly 40 years at Sandia National Labs in Albuquerque and now has a chance to return to the problem he studied in his thesis. -- CBM)
Our interest is in automatically solving difficult linear systems,
A*x = b
Such systems often arise, for example, in "inverse problems" in which the analyst is trying to reverse the effects of natural smoothing processes such as heat dissipation, optical blurring, or indirect sensing. These problems exhibit "ill-conditioning", which means that the solution results are overly sensitive to insignificant changes to the observations, which are given in the right-hand-side vector, b .
@@ -242,4 +309,76 @@
% .
##### SOURCE END ##### 95d95d5b92ad4c4ca262dfdb5ff7efe9
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2023-12-13-p=10855.md b/2023/blog-post-number-300-vibrating-logo/index.html
similarity index 64%
rename from _posts/mathworks/2023-12-13-p=10855.md
rename to 2023/blog-post-number-300-vibrating-logo/index.html
index 76c0c8e..1b91edf 100644
--- a/_posts/mathworks/2023-12-13-p=10855.md
+++ b/2023/blog-post-number-300-vibrating-logo/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2023-12-13 18:23:26'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2023/12/13/blog-post-number-300-vibrating-logo/?s_tid=feedtopost
-slug: blog-post-number-300-vibrating-logo
-title: Blog Post Number 300, Vibrating Logo
----
-
-
This is post number 300 of Cleve's Corner blog. The first post was on June 6, 2012, which is 600 weeks ago. So, I have averaged one post every two weeks for over a decade. The posts were more frequent in the early days and are less frequent today.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Blog Post Number 300, Vibrating Logo
+
This is post number 300 of Cleve's Corner blog. The first post was on June 6, 2012, which is 600 weeks ago. So, I have averaged one post every two weeks for over a decade. The posts were more frequent in the early days and are less frequent today.
For my 300-th post, I want to take another look at our MathWorks logo. Here is a modified version of one of the animations that I entered in the recent MATLAB Flipbook Mini Hack.
+
+
+
+
+
diff --git a/_posts/mathworks/2023-11-16-p=10812.md b/2023/bouncing-bucky-ball-at-flipbook-mini-hack/index.html
similarity index 56%
rename from _posts/mathworks/2023-11-16-p=10812.md
rename to 2023/bouncing-bucky-ball-at-flipbook-mini-hack/index.html
index f269c1d..5720cb1 100644
--- a/_posts/mathworks/2023-11-16-p=10812.md
+++ b/2023/bouncing-bucky-ball-at-flipbook-mini-hack/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2023-11-16 23:01:49'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2023/11/16/bouncing-bucky-ball-at-flipbook-mini-hack/?s_tid=feedtopost
-slug: bouncing-bucky-ball-at-flipbook-mini-hack
-title: Bouncing Bucky Ball at Flipbook Mini Hack
----
-
-
The 2023 MATLAB Central Flipbook Mini Hack contest runs from November 6 until December 3. Over 200 entries have been submitted in the first two weeks.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Bouncing Bucky Ball at Flipbook Mini Hack
+
The 2023 MATLAB Central Flipbook Mini Hack contest runs from November 6 until December 3. Over 200 entries have been submitted in the first two weeks.
This year's mini hack features short animations. The contest software runs the program you submit to make an animated GIF file with exactly 48 frames and an inner-frame delay time of 1/24 second. So, your animation will run for two seconds, then continuously repeat. If you want periodic motion, you need to be back where you started by frame 48.
In previous mini hacks, programs had to be Twitter length -- at most 255 characters long. Now, the new limit is 2,000 characters. Comments and formatting blanks are not counted. Remixes and reuse of other submissions is encouraged.
@@ -196,4 +263,76 @@
Thanks
Chen Lin, D
% Chen Lin, David Wey and Vinay Ramesh are running the Mini Hack this year,
##### SOURCE END ##### 65f76a589bbd4188bfa9698c4a4437a7
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2023-9-25-p=10694.md b/2023/exploring-matrices-exercises/index.html
similarity index 61%
rename from _posts/mathworks/2023-9-25-p=10694.md
rename to 2023/exploring-matrices-exercises/index.html
index 7762dad..4b2f0b5 100644
--- a/_posts/mathworks/2023-9-25-p=10694.md
+++ b/2023/exploring-matrices-exercises/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2023-09-25 17:57:28'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2023/09/25/exploring-matrices-exercises/?s_tid=feedtopost
-slug: exploring-matrices-exercises
-title: Exploring Matrices Exercises
----
-
-
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
+
+
diff --git a/_posts/mathworks/2023-9-12-p=10526.md b/2023/exploring-matrices/index.html
similarity index 74%
rename from _posts/mathworks/2023-9-12-p=10526.md
rename to 2023/exploring-matrices/index.html
index 9a9ef2c..33fc386 100644
--- a/_posts/mathworks/2023-9-12-p=10526.md
+++ b/2023/exploring-matrices/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2023-09-12 03:11:52'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2023/09/11/exploring-matrices/?s_tid=feedtopost
-slug: exploring-matrices
-title: Exploring Matrices
----
-
-
I have spent much of my career working to bring abstract linear algebra and practical matrix computation closer together. This project is my latest effort.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Exploring Matrices
+
I have spent much of my career working to bring abstract linear algebra and practical matrix computation closer together. This project is my latest effort.
Over sixty years ago, as a sophomore contemplating a major in mathematics, I took a course entitled Survey of Modern Algebra. We used a now-classic textbook by MacLane and Birkhoff that featured abstract theorems about groups, rings, fields, vector spaces and linear algebra. I remember the colorful terms alias and alibi had something to do with change of basis and change of position, but I have never seen those terms again.
The next year, I took Numerical Analysis. We did some of the homework on a Burroughhs 205 Datatron and I wrote a machine language program to solve simultaneous linear equations. I was hooked.
@@ -360,4 +427,76 @@
Dedication
We dedi
% he acquired the virus from a mosquito bite at his family's cabin
% in Canada.
##### SOURCE END ##### 77d29507140c40a1a497777d9fd035e6
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2023-2-10-p=9678.md b/2023/grafix-users-guide/index.html
similarity index 70%
rename from _posts/mathworks/2023-2-10-p=9678.md
rename to 2023/grafix-users-guide/index.html
index 2412980..ced26de 100644
--- a/_posts/mathworks/2023-2-10-p=9678.md
+++ b/2023/grafix-users-guide/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2023-02-10 18:36:06'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2023/02/10/grafix-users-guide/?s_tid=feedtopost
-slug: grafix-users-guide
-title: Grafix Users Guide
----
-
-
This is a quick look at Grafix, our tool for exploring matrices via 3-D computer graphics.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Grafix Users Guide
+
This is a quick look at Grafix, our tool for exploring matrices via 3-D computer graphics.
The word matrix comes from the Latin word mater, which means mother or origin. Matrices provide the origins of much of modern applied mathematics and computational science.
@@ -308,4 +375,76 @@
Software
The MATLA
% The MATLAB code for |Grafix|
%
##### SOURCE END ##### c11525de7f124cdcb5896c8c3f89d4a8
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2023-6-7-p=10349.md b/2023/happy-birthday-john-gilbert/index.html
similarity index 54%
rename from _posts/mathworks/2023-6-7-p=10349.md
rename to 2023/happy-birthday-john-gilbert/index.html
index ea99eab..6a1a1a1 100644
--- a/_posts/mathworks/2023-6-7-p=10349.md
+++ b/2023/happy-birthday-john-gilbert/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2023-06-07 14:48:32'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2023/06/07/happy-birthday-john-gilbert/?s_tid=feedtopost
-slug: happy-birthday-john-gilbert
-title: Happy Birthday, John Gilbert
----
-
-
I have just returned from a one-day workshop at U. C. Santa Barbara honoring John Gilbert on his 70th birthday and his official retirement after 20 years on the UCSB faculty.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Happy Birthday, John Gilbert
+
I have just returned from a one-day workshop at U. C. Santa Barbara honoring John Gilbert on his 70th birthday and his official retirement after 20 years on the UCSB faculty.
+
+
+
+
+
diff --git a/_posts/mathworks/2023-2-4-p=9612.md b/2023/matrices-in-action-grafix-2-0/index.html
similarity index 65%
rename from _posts/mathworks/2023-2-4-p=9612.md
rename to 2023/matrices-in-action-grafix-2-0/index.html
index 4b4ff5d..5fe9196 100644
--- a/_posts/mathworks/2023-2-4-p=9612.md
+++ b/2023/matrices-in-action-grafix-2-0/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2023-02-04 13:00:33'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2023/02/04/matrices-in-action-grafix-2-0/?s_tid=feedtopost
-slug: matrices-in-action-grafix-2-0
-title: Matrices In Action, Grafix 2.0
----
-
-
The 4-by-4 matrices in the panels on the following screenshots are at the heart of computer graphics. They describe objects moving in three-dimensional space and are essential to MATLAB's Handle Graphics, to CAD (Computer Added Design) packages, to CGI (Computer Graphics Imagery) in films, and to most popular video games.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Matrices In Action, Grafix 2.0
+
The 4-by-4 matrices in the panels on the following screenshots are at the heart of computer graphics. They describe objects moving in three-dimensional space and are essential to MATLAB's Handle Graphics, to CAD (Computer Added Design) packages, to CGI (Computer Graphics Imagery) in films, and to most popular video games.
Here is the opening screen from version 2.0 of Grafix, my tool for investigating the matrices involved in 3-D computer graphics. The MATLAB code for Grafixis availble here.
I am interested in the matrix in the panel, which I call M. Many matrices like this one describe the dyamic transformations to be made on a set of target objects in a complex three-dimensional scene. This particular M is the product of a scaling and a rotation that results in the size and orientation of the plane shown.
@@ -308,4 +375,76 @@
Suggestions
Refres
% *
%
##### SOURCE END ##### b13c7ab1c73c4ad7909fa2d7cd9764f2
--->
\ No newline at end of file
+-->
+
+
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
MiniGallery, Sampler of MATLAB Test Matrices
+
MATLAB has dozens of test matrices. Here are a few.
+
+
+
+
+
diff --git a/_posts/mathworks/2023-2-22-p=9816.md b/2023/my-chat-with-chatgpt/index.html
similarity index 55%
rename from _posts/mathworks/2023-2-22-p=9816.md
rename to 2023/my-chat-with-chatgpt/index.html
index 844a539..6fe1c67 100644
--- a/_posts/mathworks/2023-2-22-p=9816.md
+++ b/2023/my-chat-with-chatgpt/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2023-02-22 02:06:53'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2023/02/21/my-chat-with-chatgpt/?s_tid=feedtopost
-slug: my-chat-with-chatgpt
-title: My Chat With ChatGPT
----
-
-
While it is still fresh in my mind, I want to describe the conversation I had with a publicly available version of ChatGPT, the much-discussed large language model, LLM, for conversational artificial intelligence.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
My Chat With ChatGPT
+
While it is still fresh in my mind, I want to describe the conversation I had with a publicly available version of ChatGPT, the much-discussed large language model, LLM, for conversational artificial intelligence.
A newer version of ChatGPT than the one I used is available to selected journalists and computer industry observers. Their reaction has been, shall I say, mixed. At first, some of the reports were positive and even ecstatic. Most of these early reports were from people whose primary concern is the stock market, not AI technology. Many of the more recent and more careful reports have been negative and critical.
Where Is Sydney?
I have given ChatGPT the nickname "Chad". Some early users of one of Chad's competitors asked deliberately provocative questions and encountered a cranky alter-ego named "Sydney". I didn't ask my Chad any unfair questions and didn't encounter any Sydney's.
@@ -181,4 +248,76 @@
Truth
Steve Eddins
%
% <>
##### SOURCE END ##### 49d101acd4414820a4f6fe4b080b1113
--->
\ No newline at end of file
+-->
+
+
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
My Chat with Ernie, a Chinese Chat Bot
+
I recently had an opportunity to chat with Ernie, the Large Language Model currently under development at the Chinese internet search giant, Baidu. As I expected, Ernie's responses are in Chinese. I don't speak Chinese, so I have asked Google Translate for the response in English.
One of my questions that Microsoft's ChatGPT answered incorrectly was
+
Who coined the term "embarrassingly parallel?"
Ernie's response to the same question was
+
+
Goggle translate:
+
Who coined the embarrassing word parallel?
Well that's a very unfortunate misunderstanding. And, it's just repeating the question. That's an old trick; the mother of all chat bots, Eliza , used it over sixty years ago.
+
Love MATLAB?
One of the questions I often ask when I meet someone for the first time is
+
Do you use MATLAB?
Earnie's reply was
+
+
Google translation is
+
I think I love you.
Well, that's nice, but doesn't really answer my question.
+
Cleve's Corner
Can a chat bot assist with writing this blog? I don't expect help with the MATLAB code, or with the graphics, or with any mathematics. How about the prose, if it isn't too technical.
The 4-by-4 matrices in the panels on the following screenshots
+ are at the heart of computer graphics.
I asked Ernie how that would look in Chinese. Ernie responded with
+
+
When Google translates that back to English, we get
+
The 4×4 matrix in the screenshot panel below is at the heart of
+ computer graphics.
Ernie decided to make the sentence singular, which happens to shorten it. But I am afraid that isn't much help for this blog.
+
Conclusion
I have already described my chat with ChatGPT. This Chinese competitor is certainly not an improvement. For now, I will continue to produce this blog the old fashioned way, without any "help" from AI.
+
+
+
+
+
diff --git a/_posts/mathworks/2023-3-3-p=9867.md b/2023/r2-d2-rotations-and-dilations-in-two-dimensions/index.html
similarity index 54%
rename from _posts/mathworks/2023-3-3-p=9867.md
rename to 2023/r2-d2-rotations-and-dilations-in-two-dimensions/index.html
index 4180247..d4d618f 100644
--- a/_posts/mathworks/2023-3-3-p=9867.md
+++ b/2023/r2-d2-rotations-and-dilations-in-two-dimensions/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2023-03-03 19:50:25'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2023/03/03/r2-d2-rotations-and-dilations-in-two-dimensions/?s_tid=feedtopost
-slug: r2-d2-rotations-and-dilations-in-two-dimensions
-title: R2-D2, Rotations and Dilations in Two Dimensions
----
-
-
R2_D2 is is the name I've given a new MATLAB program that provides animations of 2-by-2 rotation and dilation matrices. I admit I chose "dilations" so the acronym would be memorable, but otherwise the code has little to do with the famous Star Wars droid.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
R2-D2, Rotations and Dilations in Two Dimensions
+
R2_D2 is is the name I've given a new MATLAB program that provides animations of 2-by-2 rotation and dilation matrices. I admit I chose "dilations" so the acronym would be memorable, but otherwise the code has little to do with the famous Star Wars droid.
This outline of a house is featured in Experiments with MATLAB. The data are the 11 blue dots. The coordinates of each dot form a 2-by-1 vector; the 2-by-2 rotation and dilation matrices multiply each of these vectors separately. (The lines between the dots complete the picture and are not involved in any computation.)
@@ -199,4 +266,76 @@
Further Reading
If
% _Experiments with MATLAB_>.
% Exercise 4.14 is particularly handy.
##### SOURCE END ##### 0fd9ed7550fd4ba3911f9d86fad47cd5
--->
\ No newline at end of file
+-->
+
+
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
+
+
diff --git a/_posts/mathworks/2023-1-10-p=9596.md b/2023/singular-matrix-pencils-and-the-qz-algorithm-update/index.html
similarity index 65%
rename from _posts/mathworks/2023-1-10-p=9596.md
rename to 2023/singular-matrix-pencils-and-the-qz-algorithm-update/index.html
index 240258f..2df5bfd 100644
--- a/_posts/mathworks/2023-1-10-p=9596.md
+++ b/2023/singular-matrix-pencils-and-the-qz-algorithm-update/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2023-01-10 21:45:12'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2023/01/10/singular-matrix-pencils-and-the-qz-algorithm-update/?s_tid=feedtopost
-slug: singular-matrix-pencils-and-the-qz-algorithm-update
-title: Singular Matrix Pencils and the QZ Algorithm, Update
----
-
-
(The January 5 posting was premature and incomplete.)
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Singular Matrix Pencils and the QZ Algorithm, Update
+
(The January 5 posting was premature and incomplete.)
This year, 2023, is the 50-th anniversary of the QZ algorithm for the generalized matrix eigenvalue problem,
Ax = λBx
The algorithm avoids inverting either A or B. And, importantly, the QZ algorithm can be used to detect and analyze exceptional instances of the problem known as singular pencils. These pencils do not occur in the standard eigenvalue problem where B is the identity matrix.
+
+
+
+
+
diff --git a/_posts/mathworks/2023-1-5-p=9569.md b/2023/singular-matrix-pencils-and-the-qz-algorithm/index.html
similarity index 54%
rename from _posts/mathworks/2023-1-5-p=9569.md
rename to 2023/singular-matrix-pencils-and-the-qz-algorithm/index.html
index 1cd52ce..76c541b 100644
--- a/_posts/mathworks/2023-1-5-p=9569.md
+++ b/2023/singular-matrix-pencils-and-the-qz-algorithm/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2023-01-05 16:37:04'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2023/01/05/singular-matrix-pencils-and-the-qz-algorithm/?s_tid=feedtopost
-slug: singular-matrix-pencils-and-the-qz-algorithm
-title: Singular Matrix Pencils and the QZ Algorithm
----
-
-
This year, 2023, is the 50-th anniversary of the QZ algorithm for generalized matrix eignenvalue problems,
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Singular Matrix Pencils and the QZ Algorithm
+
This year, 2023, is the 50-th anniversary of the QZ algorithm for generalized matrix eignenvalue problems,
Ax = λBx
The algorithm computes these eigevalues without inverting either A or B. And, the QZ-algorithm can help detect and analyze exceptional situaions known as singular pencils.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Special Notice
+
Special Notice
+
If you have been following my posts about Wordle, be sure to see the puzzle in today's New York Times, Tuesday, April 4.
+
+
+
+
+
diff --git a/_posts/mathworks/2023-3-28-p=10191.md b/2023/three-wordle-assistants/index.html
similarity index 66%
rename from _posts/mathworks/2023-3-28-p=10191.md
rename to 2023/three-wordle-assistants/index.html
index 1ec85b5..50ba16e 100644
--- a/_posts/mathworks/2023-3-28-p=10191.md
+++ b/2023/three-wordle-assistants/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2023-03-28 03:00:55'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2023/03/27/three-wordle-assistants/?s_tid=feedtopost
-slug: three-wordle-assistants
-title: Three Wordle Assistants
----
-
-
When I tackle a Wordle puzzle, I like to make all the key decisions myself. My three assistants set up puzzles and suggest words when I ask for help, but I guide the actual solution. My assistants also make it possible for me to play Wordle anywhere, anytime, even when my laptop is in airplane mode. I don't need the New York Times or access to the Web.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Three Wordle Assistants
+
When I tackle a Wordle puzzle, I like to make all the key decisions myself. My three assistants set up puzzles and suggest words when I ask for help, but I guide the actual solution. My assistants also make it possible for me to play Wordle anywhere, anytime, even when my laptop is in airplane mode. I don't need the New York Times or access to the Web.
Wordler, Words and Wordie are the three assistants. Wordler replaces the Times by generating puzzles and evaluating responses. Words provides lists of possible responses. Wordie handles the Wordler Window and colors the letters gray, green or gold.
Vocabulary
Words has a vocabulary of 4665 five-letter English words. Any of them are acceptable responses. The vocabulary begins with
@@ -269,4 +336,76 @@
Software
Working o
% and running it yourself.
##### SOURCE END ##### 5b2bc84c600a4474a0eabbc4d9bb6ab8
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2023-3-11-p=10023.md b/2023/wordbot-and-words-my-wordle-assistants/index.html
similarity index 58%
rename from _posts/mathworks/2023-3-11-p=10023.md
rename to 2023/wordbot-and-words-my-wordle-assistants/index.html
index 69a80a9..46fe372 100644
--- a/_posts/mathworks/2023-3-11-p=10023.md
+++ b/2023/wordbot-and-words-my-wordle-assistants/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2023-03-11 19:07:02'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2023/03/11/wordbot-and-words-my-wordle-assistants/?s_tid=feedtopost
-slug: wordbot-and-words-my-wordle-assistants
-title: WordBot and Words, My Wordle Assistants
----
-
-
I am late joining the Wordle craze. Over a year ago, MATLAB programs for solving Wordle puzzles were described by Adam Filion as a guest blogger on Loren's blog and by Matt Tearle with a YouTube video. But my programs for Wordle Assistants are different. WordBot doesn't try to solve any puzzles and Words just supplies lists of possible words. I enjoy providing the solution logic myself.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
WordBot and Words, My Wordle Assistants
+
I am late joining the Wordle craze. Over a year ago, MATLAB programs for solving Wordle puzzles were described by Adam Filion as a guest blogger on Loren's blog and by Matt Tearle with a YouTube video. But my programs for Wordle Assistants are different. WordBot doesn't try to solve any puzzles and Words just supplies lists of possible words. I enjoy providing the solution logic myself.
Here are two examples, taken from recent Wordle puzzles in the New York Times.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
There several sites on the Web that reveal the solution to the Wordle puzzle in the New York Times while it is still in play. Some of these sites are in India, where India Standard Time is 9-1/2 hours ahead of Eastern Daylight Time, so India sees the puzzle long before the USA does. These sites surround their puzzle clues with ads and are trying to get more visitors.
+
For a while, whenever I get a chance, I intend try to update this animation with the latest reveals. I don't have any obvious ads, but I have to admit that my own motivation is similar to the other sites.
+
+
+
+
+
diff --git a/_posts/mathworks/2024-5-19-p=11276.md b/2024/a-sixty-year-old-program-for-predicting-the-future/index.html
similarity index 69%
rename from _posts/mathworks/2024-5-19-p=11276.md
rename to 2024/a-sixty-year-old-program-for-predicting-the-future/index.html
index 11b3c1c..bc1cb58 100644
--- a/_posts/mathworks/2024-5-19-p=11276.md
+++ b/2024/a-sixty-year-old-program-for-predicting-the-future/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2024-05-19 16:55:03'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2024/05/19/a-sixty-year-old-program-for-predicting-the-future/?s_tid=feedtopost
-slug: a-sixty-year-old-program-for-predicting-the-future
-title: A Sixty-Year Old Program for Predicting the Future
----
-
-
+
+
+
+
+
+
+ A Sixty-Year Old Program for Predicting the Future - hpc.social - Aggregated Commercial Blog
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
A Sixty-Year Old Program for Predicting the Future
+
The graphics in my post about R^2 were produced by an updated version of a sixty-year old program involving the U.S. census. Originally, the program was based on census data from 1900 to 1960 and sought to predict the population in 1970. The software back then was written in Fortran, the predominate technical programming language a half century ago. I have updated the MATLAB version of the program so that it now uses census data from 1900 to 2020.
@@ -397,4 +464,76 @@
Software
% .
##### SOURCE END ##### 02c7b1cd1f114211a874bb3dcae61323
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2024-7-15-p=11379.md b/2024/a-treacherous-svd/index.html
similarity index 60%
rename from _posts/mathworks/2024-7-15-p=11379.md
rename to 2024/a-treacherous-svd/index.html
index 2af96db..3e9c9d8 100644
--- a/_posts/mathworks/2024-7-15-p=11379.md
+++ b/2024/a-treacherous-svd/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2024-07-15 15:39:04'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2024/07/15/a-treacherous-svd/?s_tid=feedtopost
-slug: a-treacherous-svd
-title: A Treacherous SVD
----
-
-
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
A Treacherous SVD
+
A few days ago, a bug report from our office in Cambridge caught my attention. Computing the singular values and singular vectors of a particular matrix would sometimes cause MATLAB to crash.
@@ -359,4 +426,76 @@
Now what?
##### SOURCE END ##### e32dbb50b2604a45be30742645bd3bea
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2024-2-20-p=11022.md b/2024/chaotic-swinging-sticks/index.html
similarity index 51%
rename from _posts/mathworks/2024-2-20-p=11022.md
rename to 2024/chaotic-swinging-sticks/index.html
index 68947b2..8e2afc2 100644
--- a/_posts/mathworks/2024-2-20-p=11022.md
+++ b/2024/chaotic-swinging-sticks/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2024-02-20 16:24:41'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2024/02/20/chaotic-swinging-sticks/?s_tid=feedtopost
-slug: chaotic-swinging-sticks
-title: Chaotic Swinging Sticks
----
-
-
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Chaotic Swinging Sticks
+
The Swinging Sticks is a kinetic sculpture that exhibits chaotic motion. The device became very popular after it upstaged Tony Stark in Iron Man 2. My daughter Carolyn gave me a desktop version of Swinging Sticks for Christmas. I immediately set out to simulate it.
@@ -194,4 +261,76 @@
Code
%% Code
%
##### SOURCE END ##### 3007bf720ec7402cb273ace1e6e2d61e
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2024-3-28-p=11120.md b/2024/closest-pair-of-points-problem/index.html
similarity index 63%
rename from _posts/mathworks/2024-3-28-p=11120.md
rename to 2024/closest-pair-of-points-problem/index.html
index ca2b224..ae28099 100644
--- a/_posts/mathworks/2024-3-28-p=11120.md
+++ b/2024/closest-pair-of-points-problem/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2024-03-28 20:00:00'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2024/03/28/closest-pair-of-points-problem/?s_tid=feedtopost
-slug: closest-pair-of-points-problem
-title: Closest Pair of Points Problem
----
+
+
+
+
+
+
+ Closest Pair of Points Problem - hpc.social - Aggregated Commercial Blog
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
The Closest Pair of Points problem is a standard topic in an algorithms course today, but when I taught such a course fifty years ago, the algorithm was not yet known.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Closest Pair of Points Problem
+
The Closest Pair of Points problem is a standard topic in an algorithms course today, but when I taught such a course fifty years ago, the algorithm was not yet known.
Imagine you are driving a car on the Harbor Freeway in southern California with typical Los Angeles traffic conditions. Among the many things you might want to know is which pair of vehicles is nearest each other.
This is an instance of the Closest Pair of Points problem:
@@ -309,4 +376,76 @@
References
Ling Qi
% Stein, Clifford. _Introduction to Algorithms (4th ed.)_.
% MIT Press and McGraw-Hill. ISBN 0-262-04630-X. 1312 pp.
##### SOURCE END ##### fc0430dede624952a83439140fe547ff
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2024-10-7-p=11696.md b/2024/experience-with-chatbots-generating-matlab/index.html
similarity index 59%
rename from _posts/mathworks/2024-10-7-p=11696.md
rename to 2024/experience-with-chatbots-generating-matlab/index.html
index acdcf79..b65a793 100644
--- a/_posts/mathworks/2024-10-7-p=11696.md
+++ b/2024/experience-with-chatbots-generating-matlab/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2024-10-07 14:31:38'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2024/10/07/experience-with-chatbots-generating-matlab/?s_tid=feedtopost
-slug: experience-with-chatbots-generating-matlab
-title: Experience With Chatbots Generating MATLAB
----
-
-
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Experience With Chatbots Generating MATLAB
+
A friend is investigating the use of generative AI in his classes. I asked two different popular chatbots to write MATLAB programs for a mathematically nontrivial problem. Both chatbots understood my query and both wrote plausible MATLAB programs, but one of the programs was not correct. My recommendation for coursework: carefully read and test programs produced by generative AI and repair any incorrect ones.
@@ -331,4 +398,76 @@
Happy Ending
% challenge students to check the results carefully
% and repair any incorrect programs.
##### SOURCE END ##### b5785d3ceb4b4ff38b92ec4f957e13e3
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2024-1-12-p=10964.md b/2024/exponential-fitting-separable-least-squares-and-quahogs/index.html
similarity index 67%
rename from _posts/mathworks/2024-1-12-p=10964.md
rename to 2024/exponential-fitting-separable-least-squares-and-quahogs/index.html
index 4c296e2..8ccb1e0 100644
--- a/_posts/mathworks/2024-1-12-p=10964.md
+++ b/2024/exponential-fitting-separable-least-squares-and-quahogs/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2024-01-12 16:35:32'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2024/01/12/exponential-fitting-separable-least-squares-and-quahogs/?s_tid=feedtopost
-slug: exponential-fitting-separable-least-squares-and-quahogs
-title: Exponential Fitting, Separable Least Squares, and Quahogs
----
-
-
We have been investigating a recent bug report about fitnlm, the Statistics and Machine Learning Toolbox function for robust fitting of nonlinear models.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Exponential Fitting, Separable Least Squares, and Quahogs
+
We have been investigating a recent bug report about fitnlm, the Statistics and Machine Learning Toolbox function for robust fitting of nonlinear models.
The bug report comes from Greg Pelletier, an independent research scientist and biogeochemical modeler in Olympia, Washington. Greg has been studying the vulnerability of sensitive marine organisms to increases in ocean acidification. One of the most important of these organisms is Mercenaria mercenaria, the hard clam.
@@ -309,4 +376,76 @@
Thanks
Thanks to G
% to Tom Lane for his statistical expertise.
##### SOURCE END ##### 0a292e90c48540ba9ef9da619b32e8e7
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2024-5-25-p=11324.md b/2024/ibm-hexadecimal-floating-point/index.html
similarity index 66%
rename from _posts/mathworks/2024-5-25-p=11324.md
rename to 2024/ibm-hexadecimal-floating-point/index.html
index a20a4ec..1a00f02 100644
--- a/_posts/mathworks/2024-5-25-p=11324.md
+++ b/2024/ibm-hexadecimal-floating-point/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2024-05-25 15:51:21'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2024/05/25/ibm-hexadecimal-floating-point/?s_tid=feedtopost
-slug: ibm-hexadecimal-floating-point
-title: IBM Hexadecimal Floating Point
----
-
-
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
IBM Hexadecimal Floating Point
+
Our technical support group recently received a request for a tool that would convert IBM System/360 hexadecimal floating point numbers to the IEEE-754 format. I am probably the only one left at MathWorks that actually used IBM mainframe computers. I thought we had seen the last of hexadecimal arithmetic years ago. But, it turns out that the hexadecimal floating point format is alive and well.
@@ -413,4 +480,76 @@
Software
##### SOURCE END ##### 54dd3908d741477c9a1ad45b553487d5
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2024-10-23-p=11813.md "b/2024/m\303\266bius-mertens-and-redheffer/index.html"
similarity index 76%
rename from _posts/mathworks/2024-10-23-p=11813.md
rename to "2024/m\303\266bius-mertens-and-redheffer/index.html"
index c38f1f4..3e15cf2 100644
--- a/_posts/mathworks/2024-10-23-p=11813.md
+++ "b/2024/m\303\266bius-mertens-and-redheffer/index.html"
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2024-10-23 00:53:53'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2024/10/22/mobius-mertens-and-redheffer/?s_tid=feedtopost
-slug: möbius-mertens-and-redheffer
-title: Möbius, Mertens and Redheffer
----
-
-
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Möbius, Mertens and Redheffer
+
Recently, I have made a series of blog posts about Redheffer matrices and the Mertens conjecture. After each of the posts, readers and colleagues offered suggestions to speed up the calculations. Here is a summary of what I have learned.
@@ -621,4 +688,74 @@
Performance
##### SOURCE END ##### a7956cd39e4e4b2da601dae253a9ad13
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2024-8-31-p=11437.md b/2024/na-digest-and-na-net/index.html
similarity index 76%
rename from _posts/mathworks/2024-8-31-p=11437.md
rename to 2024/na-digest-and-na-net/index.html
index 3627617..575fa54 100644
--- a/_posts/mathworks/2024-8-31-p=11437.md
+++ b/2024/na-digest-and-na-net/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2024-08-31 21:44:36'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2024/08/31/na_digest-and-na_net/?s_tid=feedtopost
-slug: na-digest-and-na-net
-title: NA_Digest and NA_Net
----
-
-
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
NA_Digest and NA_Net
+
The NA-Digest is an electronic newsletter for the numerical analysis and scientific software community. The NA-Digest is one of world's first examples of social networking. The Digest is one of the forces that makes our community a living, viable community.
The Digest is part of NA-Net, which also includes Netlib, a collection of mathematical software, papers, and databases.
@@ -535,4 +602,76 @@
References
% Zurich, Institut fuer Informatik, 1988.
##### SOURCE END ##### ad3526f9a6bc4fedb6f2b87f8bc0de10
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2024-1-25-p=10982.md b/2024/nick-higham-1961-2024/index.html
similarity index 55%
rename from _posts/mathworks/2024-1-25-p=10982.md
rename to 2024/nick-higham-1961-2024/index.html
index 15373c6..d3b9772 100644
--- a/_posts/mathworks/2024-1-25-p=10982.md
+++ b/2024/nick-higham-1961-2024/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2024-01-25 16:36:37'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2024/01/25/nick-higham-1961-2024/?s_tid=feedtopost
-slug: nick-higham-1961-2024-
-title: Nick Higham (1961-2024)
----
-
-
Nick Higham passed away last Saturday. Nick was a close friend of mine and a great friend of MATLAB. I will leave it to others to describe his research and teaching, his many honors, and his service to our community, especially SIAM. I have just a few, more personal, comments.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Nick Higham (1961-2024)
+
Nick Higham passed away last Saturday. Nick was a close friend of mine and a great friend of MATLAB. I will leave it to others to describe his research and teaching, his many honors, and his service to our community, especially SIAM. I have just a few, more personal, comments.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
R-squared. Is Bigger Better?
+
+
The coefficient of determination, R-squared or R^2, is a popular statistic that describes how well a regression model fits data. It measures the proportion of variation in data that is predicted by a model. However, that is all that R^2 measures. It is not appropriate for any other use. For example, it does not support extrapolation beyond the domain of the data. It does not suggest that one model is preferable to another.
+
+
I recently watched high school students participate in the final round of a national mathematical modeling competition. The teams' presentations were excellent; they were well-prepared, mathematically sophisticated, and informative. Unfortunately, many of the presentations abused R^2. It was used to compare different fits, to justify extrapolation, and to recommend public policy.
+
+
This was not the first time that I have seen abuses of R^2. As educators and authors of mathematical software, we must do more to expose its limitations. There are dozens of pages and videos on the web describing R^2, but few of them warn about possible misuse.
+
+
+R^2 is easily computed. If y is a vector of observations, f is a fit to the data and ybar = mean(y), then
+
+
R^2 = 1 - norm(y-f)^2/norm(y-ybar)^2
+
If the data are centered, then ybar = 0 and R^2 is between zero and one.
+
+
+
One of my favorite examples is the United States Census. Here is the population, in millions, every ten years since 1900.
There are 13 observations. So, we can do a least-squares fit by a polynomial of any degree less than 12 and can interpolate by a polynomial of degree 12. Here are four such fits and the corresponding R^2 values. As the degree increases, so does R^2. Interpolation fits the data exactly and earns a perfect core.
+
+
Which fit would you choose to predict the population in 2030, or even to estimate the population between census years?
+
+
R2_census
+
+
Thanks to Peter Perkins and Tom Lane for help with this post.
+
+
+
+
+
diff --git a/_posts/mathworks/2024-9-30-p=11648.md b/2024/redheffer-and-mertens-accelerated/index.html
similarity index 57%
rename from _posts/mathworks/2024-9-30-p=11648.md
rename to 2024/redheffer-and-mertens-accelerated/index.html
index a9d543d..8d0a17d 100644
--- a/_posts/mathworks/2024-9-30-p=11648.md
+++ b/2024/redheffer-and-mertens-accelerated/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2024-09-30 14:28:40'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2024/09/30/redheffer-and-mertens-accelerated/?s_tid=feedtopost
-slug: redheffer-and-mertens-accelerated
-title: Redheffer and Mertens, Accelerated
----
-
-
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Redheffer and Mertens, Accelerated
+
Shortly after I published the second post about the Mertens conjecture, a reader's comment suggested a new approach to computing Redheffer determinants and the Mertens function. It is now possible to compute a half-million values of the Mertens function in about five hours.
@@ -316,4 +383,76 @@
mertens_plot
% determinants. They have been replaced by a good friend, backslash.
##### SOURCE END ##### 3267a823a3ca4544ace75a24a1cc6636
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2024-9-27-p=11609.md b/2024/redheffer-and-mertens-continued/index.html
similarity index 51%
rename from _posts/mathworks/2024-9-27-p=11609.md
rename to 2024/redheffer-and-mertens-continued/index.html
index 34b4ecf..d152a9a 100644
--- a/_posts/mathworks/2024-9-27-p=11609.md
+++ b/2024/redheffer-and-mertens-continued/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2024-09-27 12:28:39'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2024/09/27/redheffer-and-mertens-continued/?s_tid=feedtopost
-slug: redheffer-and-mertens-continued
-title: Redheffer and Mertens, Continued
----
-
-
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Redheffer and Mertens, Continued
+
Shortly after I posted Redheffer, Mertens and One-Million Dollars a few days ago, Mathworks' Pat Quillen made an important observation about computing the Mertens function.
@@ -207,4 +274,76 @@
Mertens conjecture
% million-dollar prize.
##### SOURCE END ##### 1007044f00b340cd8467bc0b1324ad0e
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2024-9-23-p=11534.md b/2024/redheffer-mertens-and-one-million-dollars/index.html
similarity index 75%
rename from _posts/mathworks/2024-9-23-p=11534.md
rename to 2024/redheffer-mertens-and-one-million-dollars/index.html
index 4c44240..cac7637 100644
--- a/_posts/mathworks/2024-9-23-p=11534.md
+++ b/2024/redheffer-mertens-and-one-million-dollars/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2024-09-23 17:12:35'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2024/09/23/redheffer-mertens-and-one-million-dollars/?s_tid=feedtopost
-slug: redheffer-mertens-and-one-million-dollars
-title: Redheffer, Mertens and One-Million Dollars
----
-
-
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Redheffer, Mertens and One-Million Dollars
+
I didn't know anything about these topics until a couple of weeks ago. Now I can't stop thinking about them.
@@ -608,4 +675,76 @@
References
##### SOURCE END ##### 500e91acec4e4151a58ba494fb74b941
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2024-6-27-p=11345.md b/2024/supersum-in-defense-of-floating-point-arithmetic/index.html
similarity index 64%
rename from _posts/mathworks/2024-6-27-p=11345.md
rename to 2024/supersum-in-defense-of-floating-point-arithmetic/index.html
index d46b6b7..6ee7c3c 100644
--- a/_posts/mathworks/2024-6-27-p=11345.md
+++ b/2024/supersum-in-defense-of-floating-point-arithmetic/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2024-06-27 17:54:38'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2024/06/27/supersum-in-defense-of-floating-point-arithmetic/?s_tid=feedtopost
-slug: supersum-in-defense-of-floating-point-arithmetic
-title: SuperSum, In Defense of Floating Point Arithmetic
----
-
-
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
SuperSum, In Defense of Floating Point Arithmetic
+
Floating point arithmetic doesn't get the respect it deserves. Many people consider it mysterious, fuzzy, unpredictable. These misgivings often occur in discussion of vector sums. Our provocatively named SuperSum is intended to calm these fears.
@@ -425,4 +492,76 @@
Conclusion
% However, for complete reliability, use |SuperSum|. There is no
% substitute for the right answer.
##### SOURCE END ##### 7bd084f1e3e84c86b0c419e2b2dcd8b5
--->
\ No newline at end of file
+-->
+
+
+
+
+
+
+
diff --git a/_posts/mathworks/2024-3-15-p=11077.md b/2024/twenty-years-of-parallel-matlab/index.html
similarity index 53%
rename from _posts/mathworks/2024-3-15-p=11077.md
rename to 2024/twenty-years-of-parallel-matlab/index.html
index 25d633a..6f7060b 100644
--- a/_posts/mathworks/2024-3-15-p=11077.md
+++ b/2024/twenty-years-of-parallel-matlab/index.html
@@ -1,20 +1,87 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2024-03-15 18:05:58'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2024/03/15/twenty-years-of-parallel-matlab/?s_tid=feedtopost
-slug: twenty-years-of-parallel-matlab
-title: Twenty Years of Parallel MATLAB
----
-
-
I have just returned from the MathWorks company meeting celebrating our 40th Anniversary. In one of the presentations, Jos Martin described how Parallel MATLAB was introduced almost twenty years ago. Here are a few slides from Jos's talk.
+ This is a crosspost from Cleve’s Corner: Cleve Moler on Mathematics and Computing Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics.. See the original post here.
+
+
+
Twenty Years of Parallel MATLAB
+
I have just returned from the MathWorks company meeting celebrating our 40th Anniversary. In one of the presentations, Jos Martin described how Parallel MATLAB was introduced almost twenty years ago. Here are a few slides from Jos's talk.
In MATLAB News and Notes for spring 1995, I wrote a one-page Cleve's Corner titled "Why there isn't any parallel MATLAB." There were three reasons.
Memory model. MATLAB would generate a matrix on a host machine, split it into roughly equally sized submatrices, and distribute each submatrix to a node. But it took far longer to distribute the data then it did to do the computation. Any matrix that would fit into memory on the host was too small to make effective use of the parallel computer itself.
Whoops! We couldn’t find that link! Go home or just admire this cute animation.
+
+
+
+
+
+
+
+
+
+
diff --git a/Gemfile b/Gemfile
deleted file mode 100644
index 3faaee2..0000000
--- a/Gemfile
+++ /dev/null
@@ -1,15 +0,0 @@
-source "https://rubygems.org"
-gem 'jekyll'
-gem 'jekyll-feed'
-gem 'jekyll-paginate'
-gem 'jekyll-sitemap'
-gem 'jekyll-relative-links'
-gem "tzinfo-data", "~> 1.2021"
-gem 'github-pages'
-gem "hpc-social-blog-theme", :git => "https://github.com/hpc-social/hpc-social-blog-theme.git", :branch => "main"
-
-# windows specific
-gem 'wdm', '>= 0.1.0'
-
-# update ruby version
-gem 'webrick'
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 10d0126..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2022 Vanessa Sochat, HPC Social Community
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/README.md b/README.md
deleted file mode 100644
index e0545cf..0000000
--- a/README.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# hpc.social Commercial Syndicated Blog
-
-![assets/images/blog.png](assets/images/blog.png)
-
-This is the repository for the [syndicated blog](https://hpc.social/projects/blog/) for the hpc.social community!
-Note that we have three flavors of blogs - an aggregated [personal blog](https://hpc.social/personal-blog/) along with a collection
-of community blogs served from [syndicated community blog](https://hpc.social/community-blog/), and the blog
-here for commercial entities. The criteria for adding content feeds here is the following:
-
-> The commercial blog space is for vendor and company voices that don't fit in the personal or community spaces. We advocate for learning resources, tutorials, and related content, and encourage contributors to not use this as an advertising space.
-
-You can see the background for this discussion in [this thread](https://github.com/hpc-social/blog/pull/13).
-Contribution steps are the equivalent across our community blogs, and you can
-read about them [here](https://github.com/hpc-social/blog).
-
-## Development
-
-Note that we develop with a [shared theme](https://github.com/hpc-social/hpc-social-blog-theme)
-you can generally update here via:
-
-```bash
-$ bundle install
-$ bundle update
-```
-
-And any changes to the theme should bed one there (and thus consistent across the sites).
diff --git a/_config.yml b/_config.yml
deleted file mode 100644
index b7ff375..0000000
--- a/_config.yml
+++ /dev/null
@@ -1,98 +0,0 @@
-title: hpc.social - Aggregated Commercial Blog
-description: Vendor and commercial posts in the hpc.social community
-author: vsoch
-baseurl: "/commercial-blog"
-url: "https://hpc.social"
-keywords: hpc, community
-lang: en-US
-timezone: America/Denver
-repo: https://github.com/hpc-social/commercial-blog
-
-# Social Profiles
-twitter_username: hpc_social
-github_username: hpc-social
-logo: assets/images/hpc-social-blue.png
-
-# We use the aqua color for this one
-badge_color: "#e0e0e1"
-
-# And our theme!
-theme: hpc-social-blog-theme
-
-
-author:
- name: hpc.social
- bio: High Performance Computing Practitioners and friends /#hpc
- picture: assets/images/hpc-social-blue.png
- github: hpc-social
- twitter: hpc_social
- email: info@hpc.social
-
-collections:
- pages:
- output: true
- permalink: /:name
- posts:
- output: true
- permalink: /:year/:title/
-
-
-defaults:
- -
- scope:
- path: ""
- values:
- layout: "default"
- -
- scope:
- path: ""
- type: "pages"
- values:
- layout: "page"
- -
- scope:
- path: ""
- type: "posts"
- values:
- layout: "post"
- comments: true
-
-# Navigation
-navbar-links:
- Home: "https://hpc.social/"
- Community:
- - About: "about"
- Posts:
- - All Posts: "posts"
- - Archive: "archive"
-
-# Build settings
-exclude: ["_site", "vendor", ".github"]
-
-
-markdown: kramdown
-kramdown:
- input: GFM
- syntax_highlighter: rouge
-
-comments: true
-paginate: 20
-paginate_path: "/page/:num"
-
-plugins:
- - jekyll-feed
- - jekyll-paginate
- - jekyll-sitemap
- - jekyll-relative-links
-
-exclude:
- - .jekyll-cache
- - Gemfile
- - Gemfile.lock
- - LICENSE
- - README.md
- - vendor
-
-relative_links:
- enabled: true
- collections: false
diff --git a/_data/authors.yml b/_data/authors.yml
deleted file mode 100644
index 34e40b3..0000000
--- a/_data/authors.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-- name: "MathWorks Blogs"
- tag: "mathworks"
- feeds:
- - https://feeds.feedburner.com/mathworks/moler
- url: https://blogs.mathworks.com/matlab/
- image: https://www.mathworks.com/images/responsive/global/pic-header-mathworks-logo.svg
diff --git a/_posts/mathworks/2022-10-17-p=9309.md b/_posts/mathworks/2022-10-17-p=9309.md
deleted file mode 100644
index 7c91f7c..0000000
--- a/_posts/mathworks/2022-10-17-p=9309.md
+++ /dev/null
@@ -1,170 +0,0 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2022-10-17 23:17:12'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2022/10/17/modfun-a-short-program-produces-impressive-graphics/?s_tid=feedtopost
-slug: modfun-a-short-program-produces-impressive-graphics
-title: modfun, A Short Program Produces Impressive Graphics
----
-
-
This nifty graphics gem started with a contribution by Paul Villain to the MATLAB 2022 Mini Hack, currently taking place on MATLAB Central.
Villain's contribution is 102 mod 500 . My rewrite is modfun. Villain's 102 and 500 become the parameters m and n.
-
modfun(m,n) connects n points, z(j), equally spaced
- around the complex unit circle, by n+1 straight lines.
- The j-th line connects z(j+1) to z(mod(j*m,n)+1).
code
The basic code uses complex arithmetic and is only eight lines long. When the graphics is done with line instead of plot, it is not necessary to use hold on.
-
function modfun(m,n)
- init_fig
- z = exp(2i*pi*(0:n)/n);
- for j = 0:n
- zj = [z(j+1),z(mod(j*m,n)+1)];
- line(real(zj),imag(zj))
- end
- end
The initialization makes line possible.
-
function init_fig
- axis([-1 1 -1 1])
- axis square
- axis off
- end
Animation
This animation of modfun(105,200) has one frame for every five lines.
-
-
Gallery
A sample.
-
-
-
Quiz
Match these calls to modfun to the plots in the Gallery.
-
\ No newline at end of file
diff --git a/_posts/mathworks/2022-10-21-p=9375.md b/_posts/mathworks/2022-10-21-p=9375.md
deleted file mode 100644
index 6742c5e..0000000
--- a/_posts/mathworks/2022-10-21-p=9375.md
+++ /dev/null
@@ -1,91 +0,0 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2022-10-21 20:58:02'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2022/10/21/an-interactive-version-of-colorcubes/?s_tid=feedtopost
-slug: an-interactive-version-of-colorcubes
-title: An Interactive Version of colorcubes
----
-
-
A 231-character static version of colorcubes in the current MiniHack generated quite a bit of interest. So I am posting the full version, where you can change number of cubes and the view point, at this link.
-
\ No newline at end of file
diff --git a/_posts/mathworks/2023-12-20-p=10936.md b/_posts/mathworks/2023-12-20-p=10936.md
deleted file mode 100644
index b709e31..0000000
--- a/_posts/mathworks/2023-12-20-p=10936.md
+++ /dev/null
@@ -1,74 +0,0 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2023-12-20 14:13:20'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2023/12/20/seasons-greetings-2/?s_tid=feedtopost
-slug: season-s-greetings
-title: Season’s Greetings
----
-
-
-
\ No newline at end of file
diff --git a/_posts/mathworks/2023-3-24-p=10155.md b/_posts/mathworks/2023-3-24-p=10155.md
deleted file mode 100644
index bc9ce18..0000000
--- a/_posts/mathworks/2023-3-24-p=10155.md
+++ /dev/null
@@ -1,91 +0,0 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2023-03-24 19:18:10'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2023/03/24/wordle-sneak-previews/?s_tid=feedtopost
-slug: wordle-sneak-previews
-title: Wordle Sneak Previews
----
-
-
There several sites on the Web that reveal the solution to the Wordle puzzle in the New York Times while it is still in play. Some of these sites are in India, where India Standard Time is 9-1/2 hours ahead of Eastern Daylight Time, so India sees the puzzle long before the USA does. These sites surround their puzzle clues with ads and are trying to get more visitors.
-
For a while, whenever I get a chance, I intend try to update this animation with the latest reveals. I don't have any obvious ads, but I have to admit that my own motivation is similar to the other sites.
-
\ No newline at end of file
diff --git a/_posts/mathworks/2023-4-1-p=10251.md b/_posts/mathworks/2023-4-1-p=10251.md
deleted file mode 100644
index 0e83f35..0000000
--- a/_posts/mathworks/2023-4-1-p=10251.md
+++ /dev/null
@@ -1,166 +0,0 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2023-04-01 05:00:26'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2023/04/01/my-chat-with-ernie-a-chinese-chat-bot/?s_tid=feedtopost
-slug: my-chat-with-ernie-a-chinese-chat-bot
-title: My Chat with Ernie, a Chinese Chat Bot
----
-
-
I recently had an opportunity to chat with Ernie, the Large Language Model currently under development at the Chinese internet search giant, Baidu. As I expected, Ernie's responses are in Chinese. I don't speak Chinese, so I have asked Google Translate for the response in English.
One of my questions that Microsoft's ChatGPT answered incorrectly was
-
Who coined the term "embarrassingly parallel?"
Ernie's response to the same question was
-
-
Goggle translate:
-
Who coined the embarrassing word parallel?
Well that's a very unfortunate misunderstanding. And, it's just repeating the question. That's an old trick; the mother of all chat bots, Eliza , used it over sixty years ago.
-
Love MATLAB?
One of the questions I often ask when I meet someone for the first time is
-
Do you use MATLAB?
Earnie's reply was
-
-
Google translation is
-
I think I love you.
Well, that's nice, but doesn't really answer my question.
-
Cleve's Corner
Can a chat bot assist with writing this blog? I don't expect help with the MATLAB code, or with the graphics, or with any mathematics. How about the prose, if it isn't too technical.
The 4-by-4 matrices in the panels on the following screenshots
- are at the heart of computer graphics.
I asked Ernie how that would look in Chinese. Ernie responded with
-
-
When Google translates that back to English, we get
-
The 4×4 matrix in the screenshot panel below is at the heart of
- computer graphics.
Ernie decided to make the sentence singular, which happens to shorten it. But I am afraid that isn't much help for this blog.
-
Conclusion
I have already described my chat with ChatGPT. This Chinese competitor is certainly not an improvement. For now, I will continue to produce this blog the old fashioned way, without any "help" from AI.
-
\ No newline at end of file
diff --git a/_posts/mathworks/2023-4-4-p=10302.md b/_posts/mathworks/2023-4-4-p=10302.md
deleted file mode 100644
index 3c5d191..0000000
--- a/_posts/mathworks/2023-4-4-p=10302.md
+++ /dev/null
@@ -1,78 +0,0 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2023-04-04 15:12:36'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2023/04/04/special-notice/?s_tid=feedtopost
-slug: special-notice
-title: Special Notice
----
-
-
Special Notice
-
If you have been following my posts about Wordle, be sure to see the puzzle in today's New York Times, Tuesday, April 4.
-
\ No newline at end of file
diff --git a/_posts/mathworks/2023-6-28-p=10382.md b/_posts/mathworks/2023-6-28-p=10382.md
deleted file mode 100644
index b2df95b..0000000
--- a/_posts/mathworks/2023-6-28-p=10382.md
+++ /dev/null
@@ -1,117 +0,0 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2023-06-28 16:34:09'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2023/06/28/minigallery-sampler-of-matlab-test-matrices/?s_tid=feedtopost
-slug: minigallery-sampler-of-matlab-test-matrices
-title: MiniGallery, Sampler of MATLAB Test Matrices
----
-
-
MATLAB has dozens of test matrices. Here are a few.
-
\ No newline at end of file
diff --git a/_posts/mathworks/2024-5-4-p=11136.md b/_posts/mathworks/2024-5-4-p=11136.md
deleted file mode 100644
index 806e372..0000000
--- a/_posts/mathworks/2024-5-4-p=11136.md
+++ /dev/null
@@ -1,185 +0,0 @@
----
-author: MathWorks Blogs
-author_tag: mathworks
-blog_subtitle: Cleve Moler is the author of the first MATLAB, one of the founders
- of MathWorks, and is currently Chief Mathematician at the company. He writes here
- about MATLAB, scientific computing and interesting mathematics.
-blog_title: 'Cleve’s Corner: Cleve Moler on Mathematics and Computing'
-blog_url: https://blogs.mathworks.com/cleve
-category: mathworks
-date: '2024-05-04 14:33:38'
-layout: post
-original_url: https://blogs.mathworks.com/cleve/2024/05/04/r-squared-is-bigger-better/?s_tid=feedtopost
-slug: r-squared-is-bigger-better-
-title: R-squared. Is Bigger Better?
----
-
-
-
The coefficient of determination, R-squared or R^2, is a popular statistic that describes how well a regression model fits data. It measures the proportion of variation in data that is predicted by a model. However, that is all that R^2 measures. It is not appropriate for any other use. For example, it does not support extrapolation beyond the domain of the data. It does not suggest that one model is preferable to another.
-
-
I recently watched high school students participate in the final round of a national mathematical modeling competition. The teams' presentations were excellent; they were well-prepared, mathematically sophisticated, and informative. Unfortunately, many of the presentations abused R^2. It was used to compare different fits, to justify extrapolation, and to recommend public policy.
-
-
This was not the first time that I have seen abuses of R^2. As educators and authors of mathematical software, we must do more to expose its limitations. There are dozens of pages and videos on the web describing R^2, but few of them warn about possible misuse.
-
-
-R^2 is easily computed. If y is a vector of observations, f is a fit to the data and ybar = mean(y), then
-
-
R^2 = 1 - norm(y-f)^2/norm(y-ybar)^2
-
If the data are centered, then ybar = 0 and R^2 is between zero and one.
-
-
-
One of my favorite examples is the United States Census. Here is the population, in millions, every ten years since 1900.
There are 13 observations. So, we can do a least-squares fit by a polynomial of any degree less than 12 and can interpolate by a polynomial of degree 12. Here are four such fits and the corresponding R^2 values. As the degree increases, so does R^2. Interpolation fits the data exactly and earns a perfect core.
-
-
Which fit would you choose to predict the population in 2030, or even to estimate the population between census years?
-
-
R2_census
-
-
Thanks to Peter Perkins and Tom Lane for help with this post.
This belongs in the hpc.social family of blogs. In particular, this is an aggregated feed of commercial posts that meet the following criteria:
+
+
+
The commercial blog space is for vendor and company voices that don’t fit in the personal or community spaces. We advocate for learning resources, tutorials, and related content, and encourage contributors to not use this as an advertising space.
+
+
+
The hpc.social blogs aims to share ideas, news, and stories from diverse people, centers and groups across the High Performance Computing (HPC) community.
+Whether you are an advanced practitioner, a developer that touches HPC, or a novice, your voice is welcome here. This community blog reflects exactly that - a syndicated feed of our community voices. It’s one places that you can subscribe to via a variety of channels (below) and also follow instructions to contribute a commercial feed.
+
+
+
+
+
+
As a word of caution, we curate authors at the point of adding the blog, but do not regularly curate individual posts that are added nightly via automation. The opinions expressed here are owned by the authors and do not reflect the opinion of the hpc.social community at large. Offensive or inappropriate posts should be reported to info@hpc.social if you wish to report anonymously. You can also submit a pull request to remove the offending feed if you are comfortable doing so publicly.
+
+
+
+
+
diff --git a/assets/css/highlight.css b/assets/css/highlight.css
new file mode 100644
index 0000000..92791bb
--- /dev/null
+++ b/assets/css/highlight.css
@@ -0,0 +1,199 @@
+.highlight table td { padding: 5px; }
+.highlight table pre { margin: 0; }
+.highlight .gh {
+ color: #999999;
+}
+.highlight .sr {
+ color: #f6aa11;
+}
+.highlight .go {
+ color: #888888;
+}
+.highlight .gp {
+ color: #555555;
+}
+.highlight .gs {
+}
+.highlight .gu {
+ color: #aaaaaa;
+}
+.highlight .nb {
+ color: #f6aa11;
+}
+.highlight .cm {
+ color: #75715e;
+}
+.highlight .cp {
+ color: #75715e;
+}
+.highlight .c1 {
+ color: #75715e;
+}
+.highlight .cs {
+ color: #75715e;
+}
+.highlight .c, .highlight .ch, .highlight .cd, .highlight .cpf {
+ color: #75715e;
+}
+.highlight .err {
+ color: #960050;
+}
+.highlight .gr {
+ color: #960050;
+}
+.highlight .gt {
+ color: #960050;
+}
+.highlight .gd {
+ color: #49483e;
+}
+.highlight .gi {
+ color: #49483e;
+}
+.highlight .ge {
+ color: #49483e;
+}
+.highlight .kc {
+ color: #66d9ef;
+}
+.highlight .kd {
+ color: #66d9ef;
+}
+.highlight .kr {
+ color: #66d9ef;
+}
+.highlight .no {
+ color: #66d9ef;
+}
+.highlight .kt {
+ color: #66d9ef;
+}
+.highlight .mf {
+ color: #ae81ff;
+}
+.highlight .mh {
+ color: #ae81ff;
+}
+.highlight .il {
+ color: #ae81ff;
+}
+.highlight .mi {
+ color: #ae81ff;
+}
+.highlight .mo {
+ color: #ae81ff;
+}
+.highlight .m, .highlight .mb, .highlight .mx {
+ color: #ae81ff;
+}
+.highlight .sc {
+ color: #ae81ff;
+}
+.highlight .se {
+ color: #ae81ff;
+}
+.highlight .ss {
+ color: #ae81ff;
+}
+.highlight .sd {
+ color: #e6db74;
+}
+.highlight .s2 {
+ color: #e6db74;
+}
+.highlight .sb {
+ color: #e6db74;
+}
+.highlight .sh {
+ color: #e6db74;
+}
+.highlight .si {
+ color: #e6db74;
+}
+.highlight .sx {
+ color: #e6db74;
+}
+.highlight .s1 {
+ color: #e6db74;
+}
+.highlight .s, .highlight .sa, .highlight .dl {
+ color: #e6db74;
+}
+.highlight .na {
+ color: #a6e22e;
+}
+.highlight .nc {
+ color: #a6e22e;
+}
+.highlight .nd {
+ color: #a6e22e;
+}
+.highlight .ne {
+ color: #a6e22e;
+}
+.highlight .nf, .highlight .fm {
+ color: #a6e22e;
+}
+.highlight .vc {
+ color: #ffffff;
+ background-color: #272822;
+}
+.highlight .nn {
+ color: #ffffff;
+ background-color: #272822;
+}
+.highlight .nl {
+ color: #ffffff;
+ background-color: #272822;
+}
+.highlight .ni {
+ color: #ffffff;
+ background-color: #272822;
+}
+.highlight .bp {
+ color: #ffffff;
+ background-color: #272822;
+}
+.highlight .vg {
+ color: #ffffff;
+ background-color: #272822;
+}
+.highlight .vi {
+ color: #ffffff;
+ background-color: #272822;
+}
+.highlight .nv, .highlight .vm {
+ color: #ffffff;
+ background-color: #272822;
+}
+.highlight .w {
+ color: #ffffff;
+ background-color: #272822;
+}
+.highlight {
+ color: #ffffff;
+ padding: 5px;
+ background-color: #272822;
+}
+.highlight .n, .highlight .py, .highlight .nx {
+ color: #ffffff;
+ background-color: #272822;
+}
+.highlight .ow {
+ color: #f92672;
+}
+.highlight .nt {
+ color: #f92672;
+}
+.highlight .k, .highlight .kv {
+ color: #f92672;
+}
+.highlight .kn {
+ color: #f92672;
+}
+.highlight .kp {
+ color: #f92672;
+}
+.highlight .o {
+ color: #f92672;
+}
diff --git a/assets/css/style.css b/assets/css/style.css
new file mode 100644
index 0000000..a619c05
--- /dev/null
+++ b/assets/css/style.css
@@ -0,0 +1,219 @@
+:root {
+ --bg-color: #161f29;
+ --bg-hover-color:#36404c;
+ --body-bg: #10171e;
+ --primary-font-color: #bfbfbf;
+ --primary-link-color: aqua;
+ --border-color: #6a6a6a;
+}
+
+[data-theme="light"] {
+ --bg-color: #fafafa;
+ --bg-hover-color: #ececec;
+ --body-bg: #fff;
+ --primary-font-color: #000;
+ --primary-link-color: darkred;
+ --border-color: #dadada;
+}
+
+[data-theme="dark"] {
+ --bg-color: #161f29;
+ --bg-hover-color:#36404c;
+ --body-bg: #10171e;
+ --primary-font-color: #bfbfbf;
+ --border-color: #6a6a6a;
+}
+
+.author-badge {
+ background-color: #e0e0e1;
+ margin-right: 5px;
+ color: black;
+ padding:0px 5px;
+ border-radius:2px;
+}
+
+.btn {
+ cursor: pointer;
+}
+
+body{
+ font-family: 'Catamaran', sans-serif;
+ font-weight: 300;
+ background: var(--body-bg);
+ color: var(--primary-font-color);
+ margin: 0;
+ padding: 5px;
+}
+.container{
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ width: 60%;
+ margin-left: auto;
+ margin-right: auto;
+}
+.post-container{
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ width: 100%;
+}
+
+.footer{
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ width: 100%;
+ padding: 5px 10px;
+ background: var(--bg-color);
+ border:1px var(--border-color);
+}
+
+.post-list{
+ width: 100%;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px 10px;
+ margin-bottom: 5px;
+ background:var(--bg-color);
+ border: 1px var(--border-color);
+}
+
+.post-list:hover{
+ background: var(--bg-hover-color);
+}
+
+.post-list .post-title{width: 80%; color: var(--primary-font-color); font-weight: 600;}
+.post-list .post-date{width: 20%; text-align: right;}
+
+.post-header{
+ width: 100%;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px 10px;
+ margin-bottom: 5px;
+ background:var(--bg-color);
+ border:1px var(--border-color);
+}
+
+.post-header .post-share{font-weight: 600; color: var(--primary-font-color); display: flex; justify-content: flex-end; align-items: center;}
+.post-header .post-date{font-weight: 600;}
+.post-header .post-share a{display: flex;}
+
+.tags-container{
+ width: 100%;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ align-items: center;
+ margin-top: 20px;
+ margin-bottom: 20px;
+}
+
+.post-tag{margin-bottom: 5px;}
+
+.tags{display: flex; flex-wrap: wrap; justify-content: space-between;}
+.tag{background: var(--bg-color); padding: 5px 10px; margin-right: 10px; margin-bottom: 10px; display: flex; align-items: center;}
+
+.navigation{
+ width: 100%;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 5px;
+ background:var(--bg-color);
+ border:1px var(--border-color);
+
+}
+.navigation .prev{width: 45%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; color: var(--primary-font-color); font-weight: 600; padding: 5px 10px;}
+.navigation .next{width: 45%; color: var(--primary-font-color); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-weight: 600; text-align: right; padding: 5px 10px;}
+
+.pagination{
+ width: 100%;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px 10px;
+ margin-bottom: 5px;
+}
+.pagination .prev{color: var(--primary-font-color); font-weight: 600;}
+.pagination .next{color: var(--primary-font-color); font-weight: 600; text-align: right;}
+
+.blog-post-content{
+ width: 100%;
+ font-size: 18px;
+}
+
+.post-tag{background: var(--bg-color); color:var(--primary-font-color); padding: 5px 10px;}
+
+.profile{
+ width: 100%;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px 10px;
+ margin-bottom: 20px;
+}
+.profile-image-container{width: 40%;}
+.profile-image{width: 128px; height: 128px; border-radius: 50%; transition: transform .2s;}
+.profile-image:hover{transform: scale(1.05);}
+.profile-about{width:60%; text-align: right;}
+
+.font-2{font-size: 2rem;}
+.font-1-5{font-size: 1.5rem;}
+.font-1-2{font-size: 1.2rem;}
+.font-0-8{font-size: .8rem;}
+
+.text-right{text-align: right;}
+.w-100{width: 100%!important;}
+
+a:hover{text-decoration: none;}
+a{color: var(--primary-link-color); text-decoration: none;}
+.footer a{color: var(--primary-font-color); text-decoration: none;}
+img{max-width: 100%;}
+figure{margin:0; padding: 15px;}
+pre{font-size: 14px; max-width: 90vw; overflow: auto;}
+.social-icon{height: 24px;}
+
+@media (min-width: 1200px){
+ .container, .container-lg, .container-md, .container-sm, .container-xl {
+ max-width: 800px;
+ }
+}
+
+@media (min-width: 1440px){
+ .container, .container-lg, .container-md, .container-sm, .container-xl {
+ max-width: 960px;
+ }
+}
+@media only screen and (max-width: 768px) {
+ .container{width: 100%;}
+ .mode:after {
+ line-height: 22px;
+ left: 1px;
+ }
+ h1{font-size: 1.5rem;}
+ .profile-image{width: 96px; height: 96px;}
+}
+
+[data-theme="dark"] .social-icon{filter: invert(100%) sepia(50%) saturate(0%) hue-rotate(360deg) brightness(100%) contrast(100%);}
+.mode {float: right;position: relative;margin: auto;width: 42px;height: 22px;background: #F1F2F4;border-radius: 20px;cursor: pointer;}
+.mode:after {content: "☀️";position: absolute;top: 0;left: 4px;font-size: 14px;height: 22px;line-height: 23px;text-align: center;transition: all 0.3s ease;}
+.mode.active {background: #0771ca;}
+.mode.active:after {content: "🌛";transform: translateX(20px);}
+.mode.active span {transform: translateX(0);}
+.mode span {position: absolute;z-index: 1;margin: 2px;display: block;width: 18px;height: 18px;background: white;border-radius: 50%;box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);transform: translateX(20px);transition: all 0.4s ease;}
diff --git a/assets/images/favicon.png b/assets/images/favicon.png
new file mode 100644
index 0000000..9918eed
Binary files /dev/null and b/assets/images/favicon.png differ
diff --git a/assets/images/hpc-social-blue.png b/assets/images/hpc-social-blue.png
new file mode 100644
index 0000000..9918eed
Binary files /dev/null and b/assets/images/hpc-social-blue.png differ
diff --git a/assets/images/icon/facebook.svg b/assets/images/icon/facebook.svg
new file mode 100644
index 0000000..9952c15
--- /dev/null
+++ b/assets/images/icon/facebook.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/assets/images/icon/github.svg b/assets/images/icon/github.svg
new file mode 100644
index 0000000..22590d3
--- /dev/null
+++ b/assets/images/icon/github.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/assets/images/icon/instagram.svg b/assets/images/icon/instagram.svg
new file mode 100644
index 0000000..04baeca
--- /dev/null
+++ b/assets/images/icon/instagram.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/assets/images/icon/linkedin.svg b/assets/images/icon/linkedin.svg
new file mode 100644
index 0000000..6266267
--- /dev/null
+++ b/assets/images/icon/linkedin.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/assets/images/icon/me.svg b/assets/images/icon/me.svg
new file mode 100644
index 0000000..7331b5e
--- /dev/null
+++ b/assets/images/icon/me.svg
@@ -0,0 +1,65 @@
+
+
diff --git a/assets/images/icon/twitter.svg b/assets/images/icon/twitter.svg
new file mode 100644
index 0000000..69511c4
--- /dev/null
+++ b/assets/images/icon/twitter.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/assets/images/icon/whatsapp.svg b/assets/images/icon/whatsapp.svg
new file mode 100644
index 0000000..3b91dd0
--- /dev/null
+++ b/assets/images/icon/whatsapp.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/assets/images/icon/youtube.svg b/assets/images/icon/youtube.svg
new file mode 100644
index 0000000..d951b94
--- /dev/null
+++ b/assets/images/icon/youtube.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/assets/scripts.js b/assets/scripts.js
new file mode 100644
index 0000000..c71f5ce
--- /dev/null
+++ b/assets/scripts.js
@@ -0,0 +1,12 @@
+function toggleNightMode(){
+ if(document.documentElement.getAttribute('data-theme') == 'light'){
+ document.documentElement.setAttribute('data-theme', 'dark');
+ document.getElementById('mode-switcher').classList.add('active');
+ localStorage.setItem("theme","dark");
+ }
+ else{
+ document.documentElement.setAttribute('data-theme', 'light');
+ document.getElementById('mode-switcher').classList.remove('active');
+ localStorage.setItem("theme","");
+ }
+}
diff --git a/atom.xml b/atom.xml
new file mode 100644
index 0000000..a0b00a3
--- /dev/null
+++ b/atom.xml
@@ -0,0 +1,11994 @@
+
+
+
+ hpc.social - Aggregated Commercial Blog
+
+
+ 2024-10-24T21:02:55-06:00
+ https://hpc.social
+
+ hpc.social
+ info@hpc.social
+
+
+
+
+ Möbius, Mertens and Redheffer
+
+ 2024-10-23T00:53:53-06:00
+ https://hpc.social/2024/möbius-mertens-and-redheffer
+ <div class="content"><!--introduction-->
+<p>Recently, I have made <a href="https://blogs.mathworks.com/cleve/">a series of blog posts</a> about Redheffer matrices and the Mertens conjecture. After each of the posts, readers and colleagues offered suggestions to speed up the calculations. Here is a summary of what I have learned.</p>
+
+<!--/introduction-->
+<h3>Contents</h3>
+<div>
+<ul>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#32215cb4-c6e7-4c82-a09c-be2a0e403218">Möbius Function</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#2421ff74-677d-4dda-9728-8ad0f481f610">Mertens Function</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#fbbf8ec1-839c-4bd7-9416-f48ae24df402">Redheffer Matrices</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#2c3c2db6-e1d2-41c4-8a2b-d1efbabe86e7">OEIS</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#a6e6f284-1b69-42f0-a04f-f9e20891cdbc">Ten Million</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#888c9931-3060-4b47-8405-ed484be2f796">Mertens Conjecture</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#21f44074-f0af-4aa2-b6a3-adb1a2756ea2">Conjecture is False</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#e485344f-bda2-4d4d-9fd0-e7102df79117">Matrices</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#5ffa1b4e-3fe8-4908-a32c-b41a2d162cd6">Sparsity</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#39aa4540-d55c-47d1-882b-33b04368d495">Computing Mertens</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#25c55aa9-7b26-4eb8-ae66-fbfbefea38b1">#1</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#4c32719f-3698-4320-a518-3b9d554916f9">#2</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#1d535f36-08d5-4044-87d1-b3aa7094574a">#3</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#4b32160d-f00c-46f0-861a-4fe8cf231394">#4</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#e624ea53-1063-4c25-a75f-c186f877d82c">#5</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#75297d30-41f2-45ca-ad62-8e710261ee95">Performance</a>
+</li>
+</ul>
+</div>
+
+<h4>Möbius Function<a name="32215cb4-c6e7-4c82-a09c-be2a0e403218"></a>
+</h4>
+<p>
+<img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Mobius.jpg" vspace="5" /> </p>
+
+<p>The function named after the mid-nineteenth century German mathematician <a href="https://en.wikipedia.org/wiki/August_Ferdinand_M%C3%B6bius">August Möbius</a> is fundamental to the study of prime numbers. The Möbius function maps the positive integers onto -1,0 and +1.</p>
+
+<pre> mu(n) = 0 if n has a repeated prime factor,
+ = (-1)^(number prime factors) if the factors of n are not repeated</pre>
+<p>Here is my code for the Möbius function. It relies on <tt>factor(n)</tt> which uses a sieve to find the prime factors of <tt>n</tt>.</p>
+
+<pre> function mu = mobius(n)
+ % mu = mobius(n) returns mu(1:n).
+ mu = -eye(1,n);
+ for k = 2:n
+ f = factor(k);
+ d = diff([1 f]);
+ if any(d == 0)
+ mu(k) = 0;
+ else
+ mu(k) = (-1)^length(f);
+ end
+ end
+ end</pre>
+<p>Here is a graph of <tt>mu(n)</tt> for <tt>n</tt> = 1:40. For example, <tt>mu(29:31)</tt> are all -1 because 29 and 31 are both prime and 30 has an odd number of prime factors, 2, 3 and 5.</p>
+
+<pre class="language-matlab">
+ mu = moebius(40);
+ plot(1:40,mu,<span class="string">'.-'</span>,<span class="string">'linewidth'</span>,1.5,<span class="string">'markersize'</span>,16)
+ axis([-242-1.51.5])
+ title(<span class="string">'Möbius function'</span>)
+</pre>
+<img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Mertens_finale_blog_01.png" vspace="5" /> <h4>Mertens Function<a name="2421ff74-677d-4dda-9728-8ad0f481f610"></a>
+</h4>
+<p>
+<img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Mertens.jpg" vspace="5" /> </p>
+
+<p>The Mertens function is named after the late-nineteenth century Polish mathematician <a href="https://en.wikipedia.org/wiki/Franz_Mertens">Franz Mertens</a>. The function, which we denote by <tt>M(n)</tt>, is simply the partial sums of the Möbius function. The MATLAB code is very short.</p>
+
+<pre> function M = mertens(n)
+ % M = mertens(n) returns Mertens(1:n).
+ mu = moebius(n);
+ M = cumsum([1 mu(2:n)]);
+ end</pre>
+<p>Here is a graph of <tt>M(n)</tt> for <tt>n</tt> = 1:40.</p>
+
+<pre class="language-matlab">
+ M = mertens(40);
+ plot(1:40,M,<span class="string">'.-'</span>,<span class="string">'linewidth'</span>,1.5,<span class="string">'markersize'</span>,16)
+ axis([-242-4.51.5])
+ title(<span class="string">'Mertens function'</span>)
+</pre>
+<img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Mertens_finale_blog_02.png" vspace="5" /> <h4>Redheffer Matrices<a name="fbbf8ec1-839c-4bd7-9416-f48ae24df402"></a>
+</h4>
+<p>
+<img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Redheffer.jpg" vspace="5" /> </p>
+
+<p>The twentieth-century American mathematician <a href="https://en.wikipedia.org/wiki/Raymond_Redheffer">Ray Redheffer</a>, who was a professor at UCLA for 55 years, had a wide range of interests. He was the author of several popular textbooks, the inventor of the electronic game <a href="https://en.wikipedia.org/wiki/Nim">Nim</a> and, with Ray and Charles Eames, the creator of a four-meter long poster <a href="https://www.worthpoint.com/worthopedia/1966-ray-charles-eames-office-men-1724813663">Men of Modern Mathematics</a>.</p>
+
+<p>The n-by-n Redheffer's matrix <tt>R(n)</tt> is a matrix of zeros and ones. For <tt>j > 1</tt>, the element <tt>R(k,j)</tt> equals one if <tt>j</tt> is a divisor of <tt>k</tt>. And importantly, for <tt>j = 1</tt>, the first column <tt>R(:,1)</tt> is all ones.</p>
+
+<pre> function R = redheffer(n)
+ k = 1:n;
+ j = k';
+ R = (mod(k,j) == 0);
+ R(:,1) = 1;
+ end</pre>
+<p>Nick Higham put Redheffer's matrix in the <a href="https://blogs.mathworks.com/cleve/2019/06/24/bohemian-matrices-in-the-matlab-gallery/">MATLAB Gallery</a> several years ago. Here is a spy plot of the 200-by-200.</p>
+
+<pre class="language-matlab">
+ R = gallery(<span class="string">'redheff'</span>,200);
+ spy(R)
+ title(<span class="string">'Redheffer'</span>)
+</pre>
+<img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Mertens_finale_blog_03.png" vspace="5" /> <h4>OEIS<a name="2c3c2db6-e1d2-41c4-8a2b-d1efbabe86e7"></a>
+</h4>
+<p>In the Online Encyclopedia of Integer Sequences, the Mertens function is <a href="http://oeis.org/A002321">OEIS/A002321</a>. One of the many cool features of the OEIS is "listen", which generates music driven by the sequences. Take a look -- and a listen -- to my 63 second movie about A002321.</p>
+
+<p>
+<a href="https://blogs.mathworks.com/cleve/files/mertens_plot.mp4">https://blogs.mathworks.com/cleve/files/mertens_plot.mp4</a>
+</p>
+
+<h4>Ten Million<a name="a6e6f284-1b69-42f0-a04f-f9e20891cdbc"></a>
+</h4>
+<p>Here are plots of <tt>M(1:n)</tt> with <tt>n</tt> ranging from 100 to 10 million. Each plot after the first also shows the range of the previous plot. I will discuss the red lines in the next section</p>
+
+<pre class="language-matlab">
+ load<span class="string"> mertens</span><span class="string"> M</span>
+ tiledlayout(2,3)
+ <span class="keyword">for</span> n = 10.^(2:7)
+ nexttile
+ mertens_plot(M(1:n))
+ <span class="keyword">end</span>
+</pre>
+<img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Mertens_finale_blog_04.png" vspace="5" /> <h4>Mertens Conjecture<a name="888c9931-3060-4b47-8405-ed484be2f796"></a>
+</h4>
+<p>The red lines above are plots of <tt>±sqrt(n)</tt>. They clearly bound <tt>M(n)</tt> for <tt>n</tt> up to 10 million. The Mertens Conjecture is that this holds for all <tt>n</tt>.</p>
+
+<pre> |M(n)| < sqrt(n) for all n > 0</pre>
+<p>The conjecture appears in a 1885 letter from Thomas Stieltjes to Charles Hermite and in a 1897 paper by Mertens.</p>
+
+<p>
+<a href="https://en.wikipedia.org/wiki/Mertens_conjecture">Wikipedia</a> says</p>
+
+<pre> It is a striking example of a mathematical conjecture proven false
+ despite a large amount of computational evidence in its favor.</pre>
+<h4>Conjecture is False<a name="21f44074-f0af-4aa2-b6a3-adb1a2756ea2"></a>
+</h4>
+<p>In 1985, 100 years after the Stieltjes letter, Andrew Odlyzko and Herman te Riele proved that the conjecture is false. Their proof is indirect. They prove the existence of infinitely many <tt>n</tt> for which</p>
+
+<pre> |M(n)|/sqrt(n) > 1.06</pre>
+<p>But they do not know the value of any particular <tt>n</tt>. They informally estimate that such an <tt>n</tt> would be greater than 10^30 and probably much larger.</p>
+
+<h4>Matrices<a name="e485344f-bda2-4d4d-9fd0-e7102df79117"></a>
+</h4>
+<p>Let's get back to the world of matrices. It is not obvious, but is true, that the determinants of Redheffer matrices are equal to the Mertens function.</p>
+
+<pre> det(R(n)) = M(n)</pre>
+<p>So, if I could have proved that</p>
+
+<pre> |det(R(n))| < sqrt(n) for all n > 0</pre>
+<p>I would have had a proof of the Riemann Hypothesis.</p>
+
+<p>It might appear that I am out of the clutches of number theory and safely back to matrix computation. But that illusion does not last for long.</p>
+
+<h4>Sparsity<a name="5ffa1b4e-3fe8-4908-a32c-b41a2d162cd6"></a>
+</h4>
+<p>The <tt>0(n^3)</tt> memory required by the Redheffer matrix from the gallery runs out of steam quickly. We need to take advantage of sparsity. This function generates the sparse representation of a Redheffer matrix directly.</p>
+
+<pre> function R = spredheffer(n)
+ j = (1:n)';
+ k = ones(n,1);
+ m = n;
+ for i = 2:n
+ t = [1 i:i:n];
+ p = length(t);
+ j(m+(1:p)) = t;
+ k(m+(1:p)) = i;
+ m = m+p;
+ end
+ R = sparse(k,j,1,n,n);
+ end</pre>
+<h4>Computing Mertens<a name="39aa4540-d55c-47d1-882b-33b04368d495"></a>
+</h4>
+<p>Here are five methods for computing the Mertens function.</p>
+
+<h4>#1<a name="25c55aa9-7b26-4eb8-ae66-fbfbefea38b1"></a>
+</h4>
+<p>The first simply takes the determinant of the Redheffer matrix in the <tt>gallery</tt>.</p>
+
+<pre> M = det(gallery('redheff',n))</pre>
+<h4>#2<a name="4c32719f-3698-4320-a518-3b9d554916f9"></a>
+</h4>
+<p>The sparse Gaussian elimination function <tt>lu</tt> with one input and four sparse outputs is designed for solving sparse linear systems. Written primarily by Tim Davis and included in his UMFPACK package, the function uses an unsymmetric pattern multifrontal pivoting strategy to reduce fill-in while maintaining numerical stability. The determinant of the input matrix is the product of the four determinants of the output matrices. Two them are triangular and two are permutations, so it is easy, and quick, to compute their determinants.</p>
+
+<pre> R = spredheffer(n);
+ [L,U,P,Q] = lu(R)
+ M = det(L)*det(U)*det(P)*det(Q);</pre>
+<h4>#3<a name="1d535f36-08d5-4044-87d1-b3aa7094574a"></a>
+</h4>
+<p>Pat Quillen realized that by interchanging the first and last columns, there would be little fill-in. We need only one determinant.</p>
+
+<pre> R = spredheffer(n);
+ R(:,[1 n]) = R(:,[n 1]);
+ M = -det(R);</pre>
+<h4>#4<a name="4b32160d-f00c-46f0-861a-4fe8cf231394"></a>
+</h4>
+<p>A thoughtful reader of the blog submitted a suggestion based on the Schur complement. Suppose <tt>E</tt> is a block matrix,</p>
+
+<pre> E = [A B
+ C D]</pre>
+<p>Schur's formula for the determinant of <tt>E</tt> is</p>
+
+<pre> det(E) = det(D)*det(A - B*(D\C))</pre>
+<p>Apply this to <tt>R(n)</tt> with <tt>A</tt> the (1,1) entry, which is 1, and <tt>D</tt> the lower (n-1)-by-(n-1) submatrix, which is upper triangular with ones on the diagonal and determinant equal 1. This leads to method #4 which uses backslash with a sparse, unit, upper triangular matrix. There is a Redheffer matrix, but no determinant.</p>
+
+<pre> S = spredheffer(n);
+ e = ones(n-1,1);
+ M = 1 - e'*(S(2:n,2:n)\e);</pre>
+<h4>#5<a name="e624ea53-1063-4c25-a75f-c186f877d82c"></a>
+</h4>
+<p>Once we have generated <tt>R(n)</tt> and computed <tt>M(n)</tt>, how do we get <tt>R(n+1)</tt> and <tt>M(n+1)</tt>? After several iterations of this approach, I found myself without any matrices and only the original definitions of Möbius and Mertens.</p>
+
+<pre> mu = mobius(n);
+ M = cumsum([1 mu(2:n)]);</pre>
+<h4>Performance<a name="75297d30-41f2-45ca-ad62-8e710261ee95"></a>
+</h4>
+<p>Let's summarize the five methods. The first four generate a single, isolated value of <tt>M(n)</tt>. Method #5 generates <tt>M(n)</tt> for all <tt>n</tt> from 1 to any specified maximum.</p>
+
+<pre> matrix function dets M</pre>
+<pre> #1 full gallery 1 1
+ #2 sparse lu 4 1
+ #3 sparse swap 1 1
+ #4 sparse \ 0 1
+ #5 none factor 0 many</pre>
+<p>Time in seconds to compute <tt>M(n)</tt> on my Lenovo T14 laptop running Windows.</p>
+
+<pre> n 2e4 2e5 2e6 2e7</pre>
+<pre> #1 28.652 - - -
+ #2 0.344 21.77 - -
+ #3 0.086 1.29 16.4
+ #4 0.055 0.65 6.7 70.1
+ #5 0.075 0.80 10.7 204.5</pre>
+<!--
+ function grabCode_a7956cd39e4e4b2da601dae253a9ad13() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='a7956cd39e4e4b2da601dae253a9ad13 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' a7956cd39e4e4b2da601dae253a9ad13';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2024 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ -->
+<p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;">
+<br />
+<a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript>
+</span></a>
+<br />
+<br />
+ Published with MATLAB® R2024a<br />
+</p>
+
+</div>
+
+<!--
+a7956cd39e4e4b2da601dae253a9ad13 ##### SOURCE BEGIN #####
+%% Möbius, Mertens and Redheffer
+% Recently, I have made
+% <https://blogs.mathworks.com/cleve/ a series of blog posts>
+% about Redheffer matrices and the Mertens conjecture.
+% After each of the posts, readers and colleagues
+% offered suggestions to speed up the calculations.
+% Here is a summary of what I have learned.
+
+%% Möbius Function
+%
+% <<Mobius.jpg>>
+%
+% The function named after the mid-nineteenth century German
+% mathematician
+% <https://en.wikipedia.org/wiki/August_Ferdinand_M%C3%B6bius
+% August Möbius>
+% is fundamental to the study of prime numbers.
+% The Möbius function maps the positive integers onto -1,0 and +1.
+%
+% mu(n) = 0 if n has a repeated prime factor,
+% = (-1)^(number prime factors) if the factors of n are not repeated
+%
+% Here is my code for the Möbius function. It relies on |factor(n)|
+% which uses a sieve to find the prime factors of |n|.
+%
+% function mu = mobius(n)
+% % mu = mobius(n) returns mu(1:n).
+% mu = -eye(1,n);
+% for k = 2:n
+% f = factor(k);
+% d = diff([1 f]);
+% if any(d == 0)
+% mu(k) = 0;
+% else
+% mu(k) = (-1)^length(f);
+% end
+% end
+% end
+%
+% Here is a graph of |mu(n)| for |n| = 1:40. For example,
+% |mu(29:31)| are all -1 because 29 and 31 are both prime
+% and 30 has an odd number of prime factors, 2, 3 and 5.
+%
+ mu = moebius(40);
+ plot(1:40,mu,'.-','linewidth',1.5,'markersize',16)
+ axis([-2 42 -1.5 1.5])
+ title('Möbius function')
+
+%% Mertens Function
+%
+% <<Mertens.jpg>>
+%
+% The Mertens function is named after the late-nineteenth century Polish
+% mathematician
+% <https://en.wikipedia.org/wiki/Franz_Mertens Franz Mertens>.
+% The function, which we denote by |M(n)|, is simply the partial sums
+% of the Möbius function. The MATLAB code is very short.
+%
+% function M = mertens(n)
+% % M = mertens(n) returns Mertens(1:n).
+% mu = moebius(n);
+% M = cumsum([1 mu(2:n)]);
+% end
+%
+% Here is a graph of |M(n)| for |n| = 1:40.
+%
+ M = mertens(40);
+ plot(1:40,M,'.-','linewidth',1.5,'markersize',16)
+ axis([-2 42 -4.5 1.5])
+ title('Mertens function')
+
+%% Redheffer Matrices
+%
+% <<Redheffer.jpg>>
+%
+% The twentieth-century American mathematician
+% <https://en.wikipedia.org/wiki/Raymond_Redheffer Ray Redheffer>,
+% who was a professor at UCLA for 55 years,
+% had a wide range of interests.
+% He was the author of several popular textbooks, the inventor
+% of the electronic game <https://en.wikipedia.org/wiki/Nim Nim>
+% and, with Ray and Charles Eames, the creator of a four-meter long poster
+% <https://www.worthpoint.com/worthopedia/1966-ray-charles-eames-office-men-1724813663
+% Men of Modern Mathematics>.
+%
+% The n-by-n Redheffer's matrix |R(n)| is a matrix of zeros and ones.
+% For |j > 1|, the element |R(k,j)| equals one if |j| is a divisor of |k|.
+% And importantly, for |j = 1|, the first column |R(:,1)| is all ones.
+%
+% function R = redheffer(n)
+% k = 1:n;
+% j = k';
+% R = (mod(k,j) == 0);
+% R(:,1) = 1;
+% end
+%
+% Nick Higham put Redheffer's matrix in the
+% <https://blogs.mathworks.com/cleve/2019/06/24/bohemian-matrices-in-the-matlab-gallery/
+% MATLAB Gallery> several years ago.
+% Here is a spy plot of the 200-by-200.
+%
+ R = gallery('redheff',200);
+ spy(R)
+ title('Redheffer')
+
+%% OEIS
+% In the Online Encyclopedia of Integer Sequences, the Mertens function
+% is <http://oeis.org/A002321 OEIS/A002321>. One of the many cool
+% features of the OEIS is "listen", which generates music driven by
+% the sequences.
+% Take a look REPLACE_WITH_DASH_DASH and a listen REPLACE_WITH_DASH_DASH to my 63 second movie about A002321.
+%
+% <https://blogs.mathworks.com/cleve/files/mertens_plot.mp4>
+
+%% Ten Million
+% Here are plots of |M(1:n)| with |n| ranging from 100 to 10 million.
+% Each plot after the first also shows the range of the previous plot.
+% I will discuss the red lines in the next section
+%
+ load mertens M
+ tiledlayout(2,3)
+ for n = 10.^(2:7)
+ nexttile
+ mertens_plot(M(1:n))
+ end
+
+%% Mertens Conjecture
+% The red lines above are plots of |±sqrt(n)|.
+% They clearly bound |M(n)| for |n| up to 10 million.
+% The Mertens Conjecture is that this holds for all |n|.
+%
+% |M(n)| < sqrt(n) for all n > 0
+%
+% The conjecture appears in a 1885 letter from Thomas Stieltjes to
+% Charles Hermite and in a 1897 paper by Mertens.
+%
+% <https://en.wikipedia.org/wiki/Mertens_conjecture Wikipedia> says
+%
+% It is a striking example of a mathematical conjecture proven false
+% despite a large amount of computational evidence in its favor.
+
+%% Conjecture is False
+% In 1985, 100 years after the Stieltjes letter, Andrew Odlyzko
+% and Herman te Riele proved that the conjecture is false.
+% Their proof is indirect. They prove the existence of
+% infinitely many |n| for which
+%
+% |M(n)|/sqrt(n) > 1.06
+%
+% But they do not know the value of any particular |n|. They informally
+% estimate that such an |n| would be greater than 10^30 and probably
+% much larger.
+
+%% Matrices
+% Let's get back to the world of matrices. It is not obvious,
+% but is true, that the determinants of Redheffer matrices
+% are equal to the Mertens function.
+%
+% det(R(n)) = M(n)
+%
+% So, if I could have proved that
+%
+% |det(R(n))| < sqrt(n) for all n > 0
+%
+% I would have had a proof of the Riemann Hypothesis.
+%
+% It might appear that I am out of the clutches of number theory
+% and safely back to matrix computation. But that illusion does
+% not last for long.
+
+%% Sparsity
+% The |0(n^3)| memory required by the Redheffer matrix
+% from the gallery runs out of steam quickly.
+% We need to take advantage of sparsity.
+% This function generates the sparse representation of
+% a Redheffer matrix directly.
+%
+% function R = spredheffer(n)
+% j = (1:n)';
+% k = ones(n,1);
+% m = n;
+% for i = 2:n
+% t = [1 i:i:n];
+% p = length(t);
+% j(m+(1:p)) = t;
+% k(m+(1:p)) = i;
+% m = m+p;
+% end
+% R = sparse(k,j,1,n,n);
+% end
+%
+%% Computing Mertens
+% Here are five methods for computing the Mertens function.
+%
+
+%% #1
+% The first simply takes the determinant of the Redheffer matrix
+% in the |gallery|.
+%
+% M = det(gallery('redheff',n))
+%
+
+%% #2
+% The sparse Gaussian elimination function |lu| with one
+% input and four sparse outputs is designed for solving sparse linear
+% systems. Written primarily
+% by Tim Davis and included in his UMFPACK package, the function
+% uses an unsymmetric pattern multifrontal pivoting strategy
+% to reduce fill-in while maintaining numerical stability.
+% The determinant of the input matrix is the product of the four
+% determinants of the output matrices. Two them are triangular and two
+% are permutations, so it is easy, and quick, to compute their determinants.
+%
+% R = spredheffer(n);
+% [L,U,P,Q] = lu(R)
+% M = det(L)*det(U)*det(P)*det(Q);
+%
+
+%% #3
+% Pat Quillen realized that by interchanging the first and last
+% columns, there would be little fill-in. We need only one determinant.
+%
+% R = spredheffer(n);
+% R(:,[1 n]) = R(:,[n 1]);
+% M = -det(R);
+%
+
+%% #4
+%
+% A thoughtful reader of the blog submitted a suggestion based on the
+% Schur complement. Suppose |E| is a block matrix,
+%
+% E = [A B
+% C D]
+%
+% Schur's formula for the determinant of |E| is
+%
+% det(E) = det(D)*det(A - B*(D\C))
+%
+% Apply this to |R(n)| with |A| the (1,1) entry, which is 1,
+% and |D| the lower (n-1)-by-(n-1) submatrix, which is upper triangular
+% with ones on the diagonal and determinant equal 1. This leads to method
+% #4 which uses backslash with a sparse, unit, upper triangular matrix.
+% There is a Redheffer matrix, but no determinant.
+%
+% S = spredheffer(n);
+% e = ones(n-1,1);
+% M = 1 - e'*(S(2:n,2:n)\e);
+%
+
+%% #5
+% Once we have generated |R(n)| and computed |M(n)|, how do we get
+% |R(n+1)| and |M(n+1)|? After several iterations of this approach,
+% I found myself without any matrices and only the original definitions
+% of Möbius and Mertens.
+%
+% mu = mobius(n);
+% M = cumsum([1 mu(2:n)]);
+%
+
+%% Performance
+% Let's summarize the five methods. The first four generate
+% a single, isolated value of |M(n)|. Method #5 generates
+% |M(n)| for all |n| from 1 to any specified maximum.
+%
+% matrix function dets M
+%
+% #1 full gallery 1 1
+% #2 sparse lu 4 1
+% #3 sparse swap 1 1
+% #4 sparse \ 0 1
+% #5 none factor 0 many
+%
+% Time in seconds to compute |M(n)| on my Lenovo T14 laptop
+% running Windows.
+%
+% n 2e4 2e5 2e6 2e7
+%
+% #1 28.652 - - -
+% #2 0.344 21.77 - -
+% #3 0.086 1.29 16.4
+% #4 0.055 0.65 6.7 70.1
+% #5 0.075 0.80 10.7 204.5
+
+
+##### SOURCE END ##### a7956cd39e4e4b2da601dae253a9ad13
+-->
+
+
+
+
+ Experience With Chatbots Generating MATLAB
+
+ 2024-10-07T14:31:38-06:00
+ https://hpc.social/2024/experience-with-chatbots-generating-matlab
+ <div class="content"><!--introduction-->
+<p>A friend is investigating the use of generative AI in his classes. I asked two different popular chatbots to write MATLAB programs for a mathematically nontrivial problem. Both chatbots understood my query and both wrote plausible MATLAB programs, but one of the programs was not correct. My recommendation for coursework: carefully read and test programs produced by generative AI and repair any incorrect ones.</p>
+
+<!--/introduction-->
+<h3>Contents</h3>
+<div>
+<ul>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#0c48695a-3a4f-46a2-9d9c-23506fc3aae1">Redheffer, Mertens and Ahalt</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#40ba61bb-33a4-43e5-9193-7a3889fb91f5">Program number one</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#8d0098c5-f272-4317-8eef-f58166e680af">Program number two</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#a1a49807-f649-4010-af50-85a315d67540">Program number three</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#c38da925-a549-4542-bb35-198572a00c66">Happy Ending</a>
+</li>
+</ul>
+</div>
+
+<h4>Redheffer, Mertens and Ahalt<a name="0c48695a-3a4f-46a2-9d9c-23506fc3aae1"></a>
+</h4>
+<p>Frequent readers of this blog know about my recent obsession with Redheffer matrices and the Mertens conjecture. So, when my friend Stan Ahalt visited from North Carolina State a few days ago, and wanted to discuss the use of generative AI in the new Data Science curriculum, I suggested asking chatbots to write MATLAB programs that check the Mertens conjecture.</p>
+
+<p>We logged onto the web sites for two different AI companies. Our query was the same at both sites.</p>
+
+<pre>Please write a MATLAB program to test the Mertens conjecture.</pre>
+<p>I was pleasantly surprised when both systems knew about MATLAB and understood the query. One of the systems replied:</p>
+
+<pre>Certainly! I'll create a MATLAB program to test the Mertens
+conjecture. First, let me briefly explain what the Mertens
+conjecture is, and then I'll provide the code.
+The Mertens conjecture states that the Mertens function M(n)
+is bounded by √n for all positive integers n. Mathematically,
+it can be expressed as:</pre>
+<pre>|M(n)| ≤ √n for all n > 1</pre>
+<pre>Where M(n) is the Mertens function, defined as the sum of
+the Möbius function μ(k) for all positive integers k up to n:</pre>
+<pre>M(n) = Σ μ(k) for k = 1 to n</pre>
+<pre>Here's a MATLAB program to test this conjecture.</pre>
+<h4>Program number one<a name="40ba61bb-33a4-43e5-9193-7a3889fb91f5"></a>
+</h4>
+<p>The program from one of the web sites begins:</p>
+
+<pre>function M = test_Mertens(n)
+ % Function to test the Mertens conjecture for a given n
+ % Returns true if the conjecture holds for all values up to n, false otherwise</pre>
+<p>This is followed by code to sum the Möbius function and verify that <tt>abs(M) < sqrt(n)</tt>. The crucial <tt>mobius</tt> is a straight-forward implementation of the definition. The code relies on MATLAB intrinsics, <tt>factor</tt> and <tt>unique</tt>.</p>
+
+<pre>function mu = mobius(k)
+ % Function to calculate the Möbius function of k
+ % Factorize k
+ p = factor(k);
+ % Check for square factors
+ if length(p) ~= length(unique(p))
+ mu = 0;
+ else
+ mu = (-1)^length(p);
+ end
+end</pre>
+<p>I was very pleased. The entire program is only 40 lines long, eminently readable, and correct.</p>
+
+<h4>Program number two<a name="8d0098c5-f272-4317-8eef-f58166e680af"></a>
+</h4>
+<p>The program from the other web site is more sophisticated. It knows enough about MATLAB to use its cumulative summation.</p>
+
+<pre>M = cumsum(mu);</pre>
+<p>Here is the crucial <tt>mobius</tt> function. At first glance, it looks OK. Is it?</p>
+
+<pre>function mu = mobius(n)
+ % Calculate Möbius function values up to n
+ mu = ones(1, n);
+ for i = 2:sqrt(n)
+ if mu(i) == 1
+ for j = i^2:i:n
+ if mod(j, i^2) == 0
+ mu(j) = 0;
+ else
+ mu(j) = -mu(j);
+ end
+ end
+ end
+ end
+end</pre>
+<p>As you have guessed, program number two is not correct. Even its own plot reveals that something is amiss.</p>
+
+<h4>Program number three<a name="a1a49807-f649-4010-af50-85a315d67540"></a>
+</h4>
+<p>Let's return to the second Web site and make a more specific query.</p>
+
+<pre>Please write a MATLAB program that uses Redheffer
+matrices to test the Mertens conjecture.</pre>
+<p>The resulting program generates a Redheffer matrix with</p>
+
+<pre>R = zeros(n,n);
+for i = 1:n
+ for j = 1:n
+ if mod(i, j) == 0
+ R(i, j) = 1;
+ end
+ end
+end</pre>
+<p>It computes the determinant to obtain the Mertens value, <tt>M(n)</tt>. It is able to confirm the conjecture for all the <tt>n</tt> in the given range.</p>
+
+<p>What's wrong now? Look at the plot. The computed <tt>M(n)</tt> is always equal to one. Why?</p>
+
+<p>
+<img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/program3.png" vspace="5" /> </p>
+
+<h4>Happy Ending<a name="c38da925-a549-4542-bb35-198572a00c66"></a>
+</h4>
+<p>Program number three can be repaired by adding one line to the code that generates <tt>R</tt>. What is that line? Respond in the comments.</p>
+
+<p>Look at the good side. Instead of just using AI to do homework, we can challenge students to check the results carefully and repair any incorrect programs.</p>
+
+<!--
+ function grabCode_b5785d3ceb4b4ff38b92ec4f957e13e3() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='b5785d3ceb4b4ff38b92ec4f957e13e3 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' b5785d3ceb4b4ff38b92ec4f957e13e3';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2024 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ -->
+<p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;">
+<br />
+<a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript>
+</span></a>
+<br />
+<br />
+ Published with MATLAB® R2024a<br />
+</p>
+
+</div>
+
+<!--
+b5785d3ceb4b4ff38b92ec4f957e13e3 ##### SOURCE BEGIN #####
+%% Experience With Chatbots Generating MATLAB
+% A friend is investigating the use of generative AI in his classes.
+% I asked two different popular chatbots to write
+% MATLAB programs for a mathematically nontrivial problem.
+% Both chatbots understood my query and both wrote plausible
+% MATLAB programs, but one of the programs was not correct.
+% My recommendation for coursework: carefully read and test
+% programs produced by generative AI and repair any incorrect ones.
+
+%% Redheffer, Mertens and Ahalt
+% Frequent readers of this blog know about my recent obsession
+% with Redheffer matrices and the Mertens conjecture.
+% So, when my friend Stan Ahalt visited from North Carolina State
+% a few days ago, and wanted to discuss the use of generative AI in
+% the new Data Science curriculum, I suggested asking chatbots
+% to write MATLAB programs that check the Mertens conjecture.
+
+%%
+% We logged onto the web sites for two different AI companies.
+% Our query was the same at both sites.
+%
+% Please write a MATLAB program to test the Mertens conjecture.
+%
+% I was pleasantly surprised when both systems knew about MATLAB
+% and understood the query.
+% One of the systems replied:
+%
+% Certainly! I'll create a MATLAB program to test the Mertens
+% conjecture. First, let me briefly explain what the Mertens
+% conjecture is, and then I'll provide the code.
+% The Mertens conjecture states that the Mertens function M(n)
+% is bounded by √n for all positive integers n. Mathematically,
+% it can be expressed as:
+%
+% |M(n)| ≤ √n for all n > 1
+%
+% Where M(n) is the Mertens function, defined as the sum of
+% the Möbius function μ(k) for all positive integers k up to n:
+%
+% M(n) = Σ μ(k) for k = 1 to n
+%
+% Here's a MATLAB program to test this conjecture.
+%
+
+%% Program number one
+% The program from one of the web sites begins:
+%
+% function M = test_Mertens(n)
+% % Function to test the Mertens conjecture for a given n
+% % Returns true if the conjecture holds for all values up to n, false otherwise
+%
+% This is followed by code to sum the Möbius function and verify that
+% |abs(M) < sqrt(n)|.
+% The crucial |mobius| is a straight-forward implementation
+% of the definition. The code relies on MATLAB intrinsics, |factor|
+% and |unique|.
+%
+% function mu = mobius(k)
+% % Function to calculate the Möbius function of k
+% % Factorize k
+% p = factor(k);
+% % Check for square factors
+% if length(p) ~= length(unique(p))
+% mu = 0;
+% else
+% mu = (-1)^length(p);
+% end
+% end
+
+%%
+% I was very pleased. The entire program is only 40 lines long,
+% eminently readable, and correct.
+
+%% Program number two
+% The program from the other web site is more sophisticated.
+% It knows enough about MATLAB to use its cumulative summation.
+%
+% M = cumsum(mu);
+%
+% Here is the crucial |mobius| function. At first glance, it looks OK.
+% Is it?
+%
+% function mu = mobius(n)
+% % Calculate Möbius function values up to n
+% mu = ones(1, n);
+% for i = 2:sqrt(n)
+% if mu(i) == 1
+% for j = i^2:i:n
+% if mod(j, i^2) == 0
+% mu(j) = 0;
+% else
+% mu(j) = -mu(j);
+% end
+% end
+% end
+% end
+% end
+%
+% As you have guessed, program number two is not correct.
+% Even its own plot reveals that something is amiss.
+
+%% Program number three
+% Let's return to the second Web site and make a more specific query.
+%
+% Please write a MATLAB program that uses Redheffer
+% matrices to test the Mertens conjecture.
+%
+% The resulting program generates a Redheffer matrix with
+%
+% R = zeros(n,n);
+% for i = 1:n
+% for j = 1:n
+% if mod(i, j) == 0
+% R(i, j) = 1;
+% end
+% end
+% end
+%
+% It computes the determinant to obtain the Mertens value, |M(n)|.
+% It is able to confirm the conjecture for all the |n|
+% in the given range.
+%
+% What's wrong now? Look at the plot. The computed |M(n)| is always
+% equal to one. Why?
+%
+% <<program3.png>>
+%
+
+%% Happy Ending
+% Program number three can be repaired by adding one line to the code that
+% generates |R|. What is that line? Respond in the comments.
+%
+% Look at the good side. Instead of just using AI
+% to do homework, we can
+% challenge students to check the results carefully
+% and repair any incorrect programs.
+##### SOURCE END ##### b5785d3ceb4b4ff38b92ec4f957e13e3
+-->
+
+
+
+
+ Redheffer and Mertens, Accelerated
+
+ 2024-09-30T14:28:40-06:00
+ https://hpc.social/2024/redheffer-and-mertens-accelerated
+ <div class="content"><!--introduction-->
+<p>Shortly after I published the second post about the <a href="https://blogs.mathworks.com/cleve/2024/09/27/redheffer-and-mertens-continued/">Mertens conjecture</a>, a reader's comment suggested a new approach to computing Redheffer determinants and the Mertens function. It is now possible to compute a half-million values of the Mertens function in about five hours.</p>
+
+<!--/introduction-->
+<h3>Contents</h3>
+<div>
+<ul>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#7d362761-695e-4474-88df-0a49bd91d0a1">Block matrices</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#3237700b-50f8-4cce-a2a4-ce2a67875d0f"><tt>redmert</tt></a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#c59e3dbe-0a74-4f7c-839b-a92e38cb63c3">Inside <tt>redmert</tt></a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#6c005e64-ccd7-4f61-bab0-eec89c74cdd4">mertens_plot</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#dc3123c4-88e4-4acc-87ef-5dce4750f795">Postscript</a>
+</li>
+</ul>
+</div>
+
+<h4>Block matrices<a name="7d362761-695e-4474-88df-0a49bd91d0a1"></a>
+</h4>
+<p>The comment references the <a href="https://en.wikipedia.org/wiki/Determinant#Block_matrices">Wikipedia article</a> on block matrices.</p>
+
+<pre> You could also consider the matrix as a 2x2 block matrix and
+ use the formula for the determinant of a block matrix [1].
+ A = redheffer(n);
+ M = full(A(1,1) - A(1, 2:end) * (A(2:end,2:end) \ A(2:end, 1)));
+ Since the (n-1)x(n-1) block is upper triangular, the solve becomes
+ a back-substitution.</pre>
+<h4>
+<tt>redmert</tt><a name="3237700b-50f8-4cce-a2a4-ce2a67875d0f"></a>
+</h4>
+<p>My new program is named <tt>redmert</tt>, an abbreviation of Redheffer-Mertens. It uses the fact that <tt>redheffer(n)</tt> is obtained from <tt>redheffer(n-1)</tt> by appending the last column.</p>
+
+<p>Let <tt>R(n)</tt> denote the upper or right-triangular part of <tt>redheffer(n)</tt>.</p>
+
+<pre> R(n) = triu(redheffer(n))</pre>
+<p>
+<tt>R(n)</tt> is sparse, upper triangular and has ones on the diagonal. The indices of the nonzeros in the last column of <tt>R(n)</tt> are the factors of <tt>n</tt>. For example, here is <tt>R(8)</tt>.</p>
+
+<pre class="codeinput">
+R8 = full(triu(redheffer(8)))
+</pre>
+<pre class="codeoutput">R8 =
+ 1 1 1 1 1 1 1 1
+ 0 1 0 1 0 1 0 1
+ 0 0 1 0 0 1 0 0
+ 0 0 0 1 0 0 0 1
+ 0 0 0 0 1 0 0 0
+ 0 0 0 0 0 1 0 0
+ 0 0 0 0 0 0 1 0
+ 0 0 0 0 0 0 0 1
+</pre>
+<p>The idea behind <tt>redmert</tt> is to compute a sequence of Redheffer matrices, <tt>R</tt>, and associated values of the Mertens function, <tt>M</tt>.</p>
+
+<pre> [M,R] = redmert(p,R)</pre>
+<p>The input is a scalar integer <tt>p</tt>, the desired sequence length, and a sparse matrix <tt>R</tt>, the upper triangle of a Redheffer matrix of some order, <tt>n</tt>. The output is an integer vector of values <tt>M(n+1:n+p)</tt> and the upper triangle of the Redheffer matrix of order <tt>n+p</tt>. This output <tt>R</tt> can then be used as the input <tt>R</tt> in another call to <tt>redmert</tt>.</p>
+
+<p>The sequence is started with an empty <tt>R</tt>.</p>
+
+<p>For example,</p>
+
+<pre class="codeinput">
+[M,R] = redmert(8,[]);
+</pre>
+<p>The output is <tt>mertens(n), n = 1:8</tt>, and <tt>R8</tt> from the example above.</p>
+
+<pre class="codeinput">
+MR8 = full(R)
+</pre>
+<pre class="codeoutput">
+M =
+ 1
+ 0
+ -1
+ -1
+ -2
+ -1
+ -2
+ -2
+R8 =
+ 1 1 1 1 1 1 1 1
+ 0 1 0 1 0 1 0 1
+ 0 0 1 0 0 1 0 0
+ 0 0 0 1 0 0 0 1
+ 0 0 0 0 1 0 0 0
+ 0 0 0 0 0 1 0 0
+ 0 0 0 0 0 0 1 0
+ 0 0 0 0 0 0 0 1
+</pre>
+<h4>Inside <tt>redmert</tt><a name="c59e3dbe-0a74-4f7c-839b-a92e38cb63c3"></a>
+</h4>
+<p>The entire code for <tt>redmert</tt> is twelve lines long. It manipulates sparse matrices and uses sparse backslash to solve a triangular system. Nothing else is required.</p>
+
+<p>Lines 7 and 8 generate the last column of <tt>R</tt> and lines 9 and 10 implement the new idea about block matrices.</p>
+
+<pre class="codeinput">
+dbtype <span class="string">redmert</span>
+</pre>
+<pre class="codeoutput">
+1 function [M,R] = redmert(p,Rin)
+2 M = zeros(p,1);
+3 R = sparse(triu(Rin));
+4 n = size(R,1);
+5 for q = 1:p
+6 n = n+1;
+7 k = (mod(n,1:n) == 0);
+8 R(k,n) = 1;
+9 e = ones(n-1,1);
+10 M(q) = R(1,1) - e'*(R(2:n,2:n)\e);
+11 end
+12 end
+</pre>
+<h4>mertens_plot<a name="6c005e64-ccd7-4f61-bab0-eec89c74cdd4"></a>
+</h4>
+<p>It takes about five hours for <tt>redmert</tt> to compute half a million values on my laptop.</p>
+
+<pre> n = 0.5e6;
+ p = 0.5e4;
+ R = sparse([]);
+ M = [];
+ for k = p:p:n
+ disp(k)
+ [Mout,R] = redmert(p,R);
+ M = [M; Mout];
+ mertens_plot(M)
+ end</pre>
+<pre class="codeinput">
+mertens_plot
+</pre>
+<img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/redmert_blog_01.png" vspace="5" /> <h4>Postscript<a name="dc3123c4-88e4-4acc-87ef-5dce4750f795"></a>
+</h4>
+<p>I started this project by being surprised to find myself computing determinants. Now I am back to my long-time position disparaging determinants. They have been replaced by a good friend, backslash.</p>
+
+<!--
+ function grabCode_3267a823a3ca4544ace75a24a1cc6636() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='3267a823a3ca4544ace75a24a1cc6636 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 3267a823a3ca4544ace75a24a1cc6636';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2024 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ -->
+<p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;">
+<br />
+<a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript>
+</span></a>
+<br />
+<br />
+ Published with MATLAB® R2024a<br />
+</p>
+
+</div>
+
+<!--
+3267a823a3ca4544ace75a24a1cc6636 ##### SOURCE BEGIN #####
+%% Redheffer and Mertens, Accelerated
+% Shortly after I published the second post about the
+% <https://blogs.mathworks.com/cleve/2024/09/27/redheffer-and-mertens-continued/
+% Mertens conjecture>,
+% a reader's comment suggested a new approach to
+% computing Redheffer determinants and the Mertens function.
+% It is now possible to compute a half-million values of the
+% Mertens function in about five hours.
+
+%% Block matrices
+% The comment references the
+% <https://en.wikipedia.org/wiki/Determinant#Block_matrices
+% Wikipedia article> on block matrices.
+%
+% You could also consider the matrix as a 2x2 block matrix and
+% use the formula for the determinant of a block matrix [1].
+% A = redheffer(n);
+% M = full(A(1,1) - A(1, 2:end) * (A(2:end,2:end) \ A(2:end, 1)));
+% Since the (n-1)x(n-1) block is upper triangular, the solve becomes
+% a back-substitution.
+
+%% |redmert|
+% My new program is named |redmert|, an abbreviation of
+% Redheffer-Mertens. It uses the fact that
+% |redheffer(n)| is obtained from |redheffer(n-1)| by appending
+% the last column.
+%
+% Let |R(n)| denote the upper or right-triangular
+% part of |redheffer(n)|.
+%
+% R(n) = triu(redheffer(n))
+%
+% |R(n)| is sparse, upper triangular and has ones on the
+% diagonal.
+% The indices of the nonzeros in the last column of |R(n)|
+% are the factors of |n|.
+% For example, here is |R(8)|.
+
+ R8 = full(triu(redheffer(8)))
+
+%%
+% The idea behind |redmert| is to compute a sequence
+% of Redheffer matrices, |R|, and associated values of the
+% Mertens function, |M|.
+%
+% [M,R] = redmert(p,R)
+%
+% The input is a scalar integer |p|, the desired sequence length,
+% and a sparse matrix |R|, the upper triangle of a Redheffer
+% matrix of some order, |n|.
+% The output is an integer vector of values |M(n+1:n+p)| and
+% the upper triangle of the Redheffer matrix of order |n+p|.
+% This output |R| can then be used as the input |R| in another
+% call to |redmert|.
+%
+% The sequence is started with an empty |R|.
+%
+% For example,
+%
+ [M,R] = redmert(8,[]);
+
+%%
+% The output is |mertens(n), n = 1:8|, and |R8| from the example
+% above.
+
+ M
+ R8 = full(R)
+
+%% Inside |redmert|
+% The entire code for |redmert| is twelve lines long.
+% It manipulates sparse matrices and uses sparse backslash
+% to solve a triangular system. Nothing else is required.
+%
+% Lines 7 and 8 generate the last column of |R| and lines 9 and 10
+% implement the new idea about block matrices.
+
+ dbtype redmert
+
+%% mertens_plot
+% It takes about five hours for |redmert|
+% to compute half a million values on my laptop.
+%
+% n = 0.5e6;
+% p = 0.5e4;
+% R = sparse([]);
+% M = [];
+% for k = p:p:n
+% disp(k)
+% [Mout,R] = redmert(p,R);
+% M = [M; Mout];
+% mertens_plot(M)
+% end
+
+ mertens_plot
+
+%% Postscript
+% I started this project by being surprised to find
+% myself computing determinants.
+% Now I am back to my long-time position disparaging
+% determinants. They have been replaced by a good friend, backslash.
+
+##### SOURCE END ##### 3267a823a3ca4544ace75a24a1cc6636
+-->
+
+
+
+
+ Redheffer and Mertens, Continued
+
+ 2024-09-27T12:28:39-06:00
+ https://hpc.social/2024/redheffer-and-mertens-continued
+ <div class="content"><!--introduction-->
+<p>Shortly after I posted <a href="https://blogs.mathworks.com/cleve/2024/09/23/redheffer-mertens-and-one-million-dollars/">Redheffer, Mertens and One-Million Dollars</a> a few days ago, Mathworks' Pat Quillen made an important observation about computing the Mertens function.</p>
+
+<!--/introduction-->
+<h3>Contents</h3>
+<div>
+<ul>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#f3fcd244-9ad3-4849-93ca-a831a5999c61"><tt>mertens</tt></a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#22db8fd3-aa25-4f76-9360-af77b6b20726">Mertens function</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#9ebbd5e7-4600-435d-8b80-56634f314af3">Mertens computation</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#d25d727c-f7fb-41b5-a32e-eab8c9e0caae">Mertens conjecture</a>
+</li>
+</ul>
+</div>
+
+<h4>
+<tt>mertens</tt><a name="f3fcd244-9ad3-4849-93ca-a831a5999c61"></a>
+</h4>
+<p>The elements in the first column of the Redheffer matrix, <tt>A = redheffer(n)</tt>, are all equal to one. That dense column does not make MATLAB happy about computing <tt>det(A)</tt> . However, the last column of <tt>A</tt> has only a few nonzero elements and so Pat suggested interchanging the first and last columns before computing the determinant. This makes a world of difference. (Thanks, Pat.)</p>
+
+<pre class="codeinput">type<span class="string">mertens</span>
+</pre>
+<pre class="codeoutput">
+function M = mertens(n)
+ if n > 1
+ A = redheffer(n);
+ A(:,[1 n]) = A(:,[n 1]);
+ M = -round(det(A));
+ else
+ M = 1;
+ end
+end
+</pre>
+<p>The time required to compute <tt>det(A)</tt> varies with the sparsity of the last column, but it is only a little more than the time to compute <tt>redheffer(n)</tt> in the first place.</p>
+
+<pre class="codeinput">mertens2_time
+</pre>
+<img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/mertens2_blog_01.png" vspace="5" /> <h4>Mertens function<a name="22db8fd3-aa25-4f76-9360-af77b6b20726"></a>
+</h4>
+<p>Pat's change makes it possible to take <tt>n</tt> up to a quarter of a million, and beyond. Here is a new plot of the Mertens function <tt>M(n)</tt> and the <tt>sqrt(n)</tt> bounds of the Mertens conjecture.</p>
+
+<pre class="codeinput">mertens_plot
+</pre>
+<img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/mertens2_blog_02.png" vspace="5" /> <p>There are a quarter of a million points in the data for this plot. Fortunately, the .PNG file used for the blog only needs to sample the data.</p>
+
+<h4>Mertens computation<a name="9ebbd5e7-4600-435d-8b80-56634f314af3"></a>
+</h4>
+<p>The job that I ran on my laptop to compute one-quarter of a million values of <tt>M(n)</tt> is still running. It currently is past 0.35 million and takes less than two seconds for each value. I may keep the job running over the weekend, just to see how far it gets.</p>
+
+<p>The task is embarrassingly parallel. If I had a pool with a million processors, I could have each processor compute one value. I would then just have to collect the results, but that doesn't involve any arithmetic.</p>
+
+<h4>Mertens conjecture<a name="d25d727c-f7fb-41b5-a32e-eab8c9e0caae"></a>
+</h4>
+<p>You can see from the plot why late 19th- and early 20th-century mathematicians believed that the Mertens conjecture,</p>
+
+<pre> |M(n)| < sqrt(n) for all n,</pre>
+<p>might be true. It is hard to imagine that the plot of <tt>M(n)</tt> ever escapes <tt>sqrt(n)</tt>.</p>
+
+<p>We now know that <tt>M(n)</tt> eventually does escape, but only barely and only briefly. We also know that all the computation we can do with determinants of Redheffer's matrix will never prove or disprove the conjecture or win that million-dollar prize.</p>
+
+<!--
+ function grabCode_1007044f00b340cd8467bc0b1324ad0e() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='1007044f00b340cd8467bc0b1324ad0e ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 1007044f00b340cd8467bc0b1324ad0e';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2024 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ -->
+<p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;">
+<br />
+<a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript>
+</span></a>
+<br />
+<br />
+ Published with MATLAB® R2024a<br />
+</p>
+
+</div>
+
+<!--
+1007044f00b340cd8467bc0b1324ad0e ##### SOURCE BEGIN #####
+%% Redheffer and Mertens, Continued
+% Shortly after I posted
+% <https://blogs.mathworks.com/cleve/2024/09/23/redheffer-mertens-and-one-million-dollars/
+% Redheffer, Mertens and One-Million Dollars>
+% a few days ago, Mathworks' Pat Quillen made an important observation
+% about computing the Mertens function.
+
+%% |mertens|
+% The elements in the first column of the Redheffer matrix,
+% |A = redheffer(n)|, are all equal to one. That dense column
+% does not make MATLAB happy about computing |det(A)| .
+% However, the last column of |A| has only a few nonzero elements and so
+% Pat suggested interchanging the first and last columns
+% before computing the determinant. This makes a world of difference.
+% (Thanks, Pat.)
+
+ type mertens
+
+%%
+% The time required to compute |det(A)| varies with the sparsity of
+% the last column, but it is only a little more than the time
+% to compute |redheffer(n)| in the first place.
+
+ mertens2_time
+
+%% Mertens function
+% Pat's change makes it possible to take |n| up to a quarter of a million,
+% and beyond. Here is a new plot of the Mertens function |M(n)| and the
+% |sqrt(n)| bounds of the Mertens conjecture.
+
+ mertens_plot
+
+%%
+% There are a quarter of a million points in the data for this plot.
+% Fortunately, the .PNG file used for the blog only needs to sample
+% the data.
+
+%% Mertens computation
+% The job that I ran on my laptop to compute one-quarter of
+% a million values of |M(n)| is still running. It currently
+% is past 0.35 million and takes less than two seconds for each value.
+% I may keep the job running over the weekend, just to see how
+% far it gets.
+%
+% The task is embarrassingly parallel. If I had a pool with
+% a million processors, I could have each processor compute one
+% value. I would then just have to collect the results, but that
+% doesn't involve any arithmetic.
+
+%% Mertens conjecture
+% You can see from the plot why late 19th- and early 20th-century
+% mathematicians believed that the Mertens conjecture,
+%
+% |M(n)| < sqrt(n) for all n,
+%
+% might be true.
+% It is hard to imagine that the plot of |M(n)| ever escapes
+% |sqrt(n)|.
+%
+% We now know that |M(n)| eventually does escape,
+% but only barely and only briefly. We also know that all the
+% computation we can do with determinants of Redheffer's matrix
+% will never prove or disprove the conjecture or win that
+% million-dollar prize.
+
+##### SOURCE END ##### 1007044f00b340cd8467bc0b1324ad0e
+-->
+
+
+
+
+ Redheffer, Mertens and One-Million Dollars
+
+ 2024-09-23T17:12:35-06:00
+ https://hpc.social/2024/redheffer-mertens-and-one-million-dollars
+ <div class="content"><!--introduction-->
+<p>I didn't know anything about these topics until a couple of weeks ago. Now I can't stop thinking about them.</p>
+
+<div>
+<ul>
+<li>Redheffer's matrix has been in the <a href="https://blogs.mathworks.com/cleve/2019/06/24/bohemian-matrices-in-the-matlab-gallery/">MATLAB Gallery</a> for a long time, but I have ignored it .</li>
+<li>Redheffer's matrix can be used to compute Mertens function and investigate the <a href="https://en.wikipedia.org/wiki/Mertens_conjecture">Mertens conjecture</a>.</li>
+<li>A proof of the Mertens conjecture would also provide a proof of the <a href="https://en.wikipedia.org/wiki/Riemann_hypothesis">Riemann hypothesis</a>.</li>
+<li>For nearly a century, all the available computational evidence indicated that the Mertens conjecture was likely to be true.</li>
+<li>The Riemann hypothesis is the most important unsolved problem in mathematics and wins a Clay prize worth <a href="https://www.claymath.org/millennium/riemann-hypothesis">one-million dollars</a>.</li>
+<li>MATLAB's sparse matrix functions turn out to be useful in an investigation of Redheffer's matrix and the Mertens conjecture.</li>
+<li>However, it has been known since 1985 that the Mertens conjecture is false.</li>
+</ul>
+</div>
+
+<!--/introduction-->
+<h3>Contents</h3>
+<div>
+<ul>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#82c24739-64fc-4329-b610-b923ff740e51">Redheffer's Matrix</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#fdc9a386-44e5-43bb-a9c1-8580cdb11520">Möbius Function</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#ebef8c86-e7dd-4ca8-9f35-7da51c2313c4">Mertens Function</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#36e351c3-4c49-43ab-8776-9f5f5e7011f6">Mertens Conjecture</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#4b56c506-95ad-4d6b-8f23-569f167616b7">Mertens Meets Redheffer</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#f8ff3cc0-f3e0-4d4d-84f5-b3049b3af76f">Redheffer Sparsity</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#3cf9c9a2-aba7-4a78-b8f2-96522c7fc05d"><tt>redheffer</tt></a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#221d2a42-3916-44d9-b314-debfbcfbaced">Sparse LU</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#c293a71a-bd97-4107-8fc8-3063376e0ea7"><tt>mertens</tt></a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#5dc1b513-cf9c-43c7-a3b7-06e75d99e97e">Mertens Conjecture Is False</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#4247c5bb-c39a-4a0a-88a9-4859dcc0e793">Postscripts</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#8b8af9b2-9248-420a-9072-b53f5d344050">References</a>
+</li>
+</ul>
+</div>
+
+<h4>Redheffer's Matrix<a name="82c24739-64fc-4329-b610-b923ff740e51"></a>
+</h4>
+<p>
+<a href="https://en.wikipedia.org/wiki/Raymond_Redheffer">Raymond Redheffer</a> (1921-2005) was an American mathematician, a professor at UCLA for 55 years, the author of several popular textbooks, the inventor of the electronic game <a href="https://en.wikipedia.org/wiki/Nim">Nim</a> and, with Ray and Charles Eames, the creator of a four-meter long poster <a href="https://www.worthpoint.com/worthopedia/1966-ray-charles-eames-office-men-1724813663">Men of Modern Mathematics</a>.</p>
+
+<p>Redheffer's matrix is a matrix of zeros and ones. <tt>A(k,j)</tt> equals one if <tt>j</tt> is a divisor of <tt>k</tt>. In addition, the first column is all ones.</p>
+
+<pre> function A = redheffer(n)
+ k = 1:n;
+ j = k';
+ A = (mod(k,j) == 0);
+ A(:,1) = 1;
+ end</pre>
+<p>Or</p>
+
+<pre> A = gallery('redheff',n)</pre>
+<p>Here is the 10-by-10.</p>
+
+<pre class="codeinput">
+ A = redheffer(10);
+ disp(full(A))
+</pre>
+<pre class="codeoutput">
+ 1 1 1 1 1 1 1 1 1 1
+ 1 1 0 1 0 1 0 1 0 1
+ 1 0 1 0 0 1 0 0 1 0
+ 1 0 0 1 0 0 0 1 0 0
+ 1 0 0 0 1 0 0 0 0 1
+ 1 0 0 0 0 1 0 0 0 0
+ 1 0 0 0 0 0 1 0 0 0
+ 1 0 0 0 0 0 0 1 0 0
+ 1 0 0 0 0 0 0 0 1 0
+ 1 0 0 0 0 0 0 0 0 1
+</pre>
+<p>And here is a spy plot of the 200-by-200.</p>
+
+<pre class="codeinput">
+ A = redheffer(200);
+ spy(A)
+ title(<span class="string">'redheffer(200)'</span>)
+</pre>
+<img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/mertens_blog2_01.png" vspace="5" /> <h4>Möbius Function<a name="fdc9a386-44e5-43bb-a9c1-8580cdb11520"></a>
+</h4>
+<p>The Möbius function was introduced in 1832 by German mathematician August Möbius and is ubiquitous in the study of prime numbers. For positive integers <tt>n</tt>, <tt>μ(n)</tt> is</p>
+
+<div>
+<ul>
+<li>
+<tt>0</tt> if <tt>n</tt> has a squared prime factor,</li>
+<li>
+<tt>+1</tt> if <tt>n</tt> is square-free and has an even number of prime factors,</li>
+<li>
+<tt>-1</tt> if <tt>n</tt> is square-free and has an odd number of prime factors.</li>
+</ul>
+</div>
+
+<h4>Mertens Function<a name="ebef8c86-e7dd-4ca8-9f35-7da51c2313c4"></a>
+</h4>
+<p>
+<a href="https://en.wikipedia.org/wiki/Franz_Mertens">Franz Mertens</a> (1840-1927) was a Polish mathematician who spent most of his career in Austria at the University of Vienna. Here is a <a href="https://mathshistory.st-andrews.ac.uk/Biographies/Mertens/">link</a> to a biography of Mertens at the University of St. Andrews MacTutor project.</p>
+
+<p>The Mertens function is sum of values of the Möbius function. For a positive integer <tt>n</tt>, the Mertens function is</p>
+
+<pre> M(n) = sum(μ(1:n))</pre>
+<p>So <tt>M(n)</tt> is the difference between the number of square-free integers with an even number of prime factors and those with an odd number.</p>
+
+<p>This graphic shows <tt>M(n)</tt> for <tt>n = 1:100000</tt>.</p>
+
+<pre class="codeinput">
+ mertens_plot_2
+</pre>
+<img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/mertens_blog2_02.png" vspace="5" /> <h4>Mertens Conjecture<a name="36e351c3-4c49-43ab-8776-9f5f5e7011f6"></a>
+</h4>
+<p>The Mertens function <tt>M(n)</tt> fluctuates wildly and grows slowly with increasing <tt>n</tt>. The graphic shows that M(n) is easily bounded by of <tt>sqrt(n)</tt> and <tt>-sqrt(n)</tt>, at least for <tt>n</tt> less than <tt>100k</tt>. The Mertens conjecture is that this continues for larger <tt>n</tt>.</p>
+
+<pre> -sqrt(n) < M(n) < sqrt(n) for all n</pre>
+<p>The conjecture was included in a letter from Stieltjes to Hermite in 1895 and in a paper by Mertens in 1897. The result is important since a proof of the Mertens conjecture would imply the truth of the Riemann hypothesis.</p>
+
+<h4>Mertens Meets Redheffer<a name="4b56c506-95ad-4d6b-8f23-569f167616b7"></a>
+</h4>
+<p>I became interested in all this when I learned that the determinant of the MATLAB Gallery matrix which I have ignored for years is related to the Riemann hypothesis and the million-dollar prize.</p>
+
+<pre> M(n) = det(gallery('redheff',n))</pre>
+<p>I know very little about the distribution of prime numbers and computing values of the Möbius function. On the other hand, I know a lot about numerical linear algebra and computing determinants.</p>
+
+<p>In general, I am dead set against computing determinants. They are often used to check for singularity or to somehow compute eigenvalues. But here the determinant is an integer counter of modest size.</p>
+
+<h4>Redheffer Sparsity<a name="f8ff3cc0-f3e0-4d4d-84f5-b3049b3af76f"></a>
+</h4>
+<p>Computing <tt>M(n)</tt> directly with <tt>det(redheffer(n))</tt> requires <tt>O(n^2)</tt> space and <tt>O(n^3)</tt> time and is not practical for large <tt>n</tt>.</p>
+
+<p>However, <tt>A = redheffer(n)</tt> is modestly sparse. Here is the fraction of nonzeros.</p>
+
+<pre> s = nnz(A)/n^2</pre>
+<pre class="codeinput">
+ disp(sparsity)
+</pre>
+<pre class="codeoutput">
+ n s
+ _____ ________
+ 10000 0.001037
+ 20000 0.000553
+ 30000 0.000382
+ 40000 0.000294
+ 50000 0.000239
+ 60000 0.000203
+ 70000 0.000176
+ 80000 0.000156
+ 90000 0.000139
+ 1e+05 0.000127
+</pre>
+<p>Taking advantage of this sparsity and the MATLAB tools for sparse matrix computation provide linear space complexity and perhaps <tt>O(n^2)</tt> time complexity.</p>
+
+<h4>
+<tt>redheffer</tt><a name="3cf9c9a2-aba7-4a78-b8f2-96522c7fc05d"></a>
+</h4>
+<p>Here is MATLAB code to generate a sparse <tt>redheffer(n)</tt> without creating any full intermediate matrices.</p>
+
+<pre class="codeinput">type<span class="string"> redheffer</span>
+</pre>
+<pre class="codeoutput">
+ function A = redheffer(n)
+ j(1:n) = (1:n)';
+ k(1:n) = 1;
+ m = n;
+ for i = 2:n
+ t = [1 i:i:n]';
+ p = length(t);
+ j(m+(1:p)) = t;
+ k(m+(1:p)) = i;
+ m = m+p;
+ end
+ A = sparse(k,j,1,n,n);
+ end
+</pre>
+<p>As expected, we see that the execution time for <tt>redheffer(n)</tt> is a linear function of <tt>n</tt>. (The space required also grows linearly.)</p>
+
+<pre class="codeinput">
+ redheffer_time
+</pre>
+<img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/mertens_blog2_03.png" vspace="5" /> <h4>Sparse LU<a name="221d2a42-3916-44d9-b314-debfbcfbaced"></a>
+</h4>
+<p>The MATLAB Gaussian elimination function <tt>lu</tt> with one sparse input and four sparse outputs is designed for solving sparse linear systems.</p>
+
+<pre> [L,U,P,Q] = lu(A)</pre>
+<p>Written primarily by Tim Davis and included in his UMFPACK package, the function uses an unsymmetric pattern multifrontal pivoting strategy to find permutations <tt>P</tt> and <tt>Q</tt> so that <tt>L</tt> is lower triangular, <tt>U</tt> is upper triangular and</p>
+
+<pre> P*A*Q = L*U</pre>
+<p>Consequently, the determinant of <tt>A</tt> is the product of four easily computed determinants.</p>
+
+<pre> det(A) = det(L)*det(U)*det(P)*det(Q)</pre>
+<p>The pivoting strategy aims to reduce fill-in while maintaining numerical stability.</p>
+
+<p>For example, here are <tt>L</tt> and <tt>U</tt> for the Redheffer matrix in the spy plot near the top of this blog post.</p>
+
+<pre class="codeinput">
+ close
+ A = redheffer(200);
+ [L,U,P,Q] = lu(A);
+ spy(L|U)
+ title(<span class="string">'L|U'</span>)
+</pre>
+<img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/mertens_blog2_04.png" vspace="5" /> <p>And here are the four determinants.</p>
+
+<pre class="codeinput">
+ dets = [det(L),det(U),det(P),det(Q)];
+ disp(dets)
+</pre>
+<pre class="codeoutput">
+ 1 -8 -1 -1
+</pre>
+<p>Finally, <tt>M(200)</tt> is</p>
+
+<pre class="codeinput">
+ M_200 = det(L)*det(U)*det(P)*det(Q)
+</pre>
+<pre class="codeoutput">
+ M_200 =
+ -8
+</pre>
+<h4>
+<tt>mertens</tt><a name="c293a71a-bd97-4107-8fc8-3063376e0ea7"></a>
+</h4>
+<p>Mertens function can be computed with four lines of code.</p>
+
+<pre class="codeinput">
+ type<span class="string"> mertens</span>
+</pre>
+<pre class="codeoutput">
+ function M = mertens(n)
+ der = @(x) full(round(prod(diag(x))));
+ A = redheffer(n);
+ [L,U,P,Q] = lu(A);
+ M = der(L)*der(U)*det(P)*det(Q);
+ end
+</pre>
+<p>Execution time for <tt>mertens</tt> is dominated by the time in sparse <tt>lu</tt>. The time required to compute the four determinants is an order of magnitude smaller than the other two.</p>
+
+<p>Experimentally, we see that the time complexity of sparse <tt>lu</tt> is <tt>O(n^2)</tt>, but we have no proof.</p>
+
+<pre class="codeinput">
+ mertens_time
+</pre>
+<img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/mertens_blog2_05.png" vspace="5" /> <h4>Mertens Conjecture Is False<a name="5dc1b513-cf9c-43c7-a3b7-06e75d99e97e"></a>
+</h4>
+<p>The Mertens conjecture stood for nearly 100 years before it was proved false in 1985 by Andrew Odlyzko and Herman te Riele. The authors present indirect proofs that</p>
+
+<pre> lim sup (n -> inf) M(n)/sqrt(n) > 1.06</pre>
+<pre> lim inf (n -> inf) M(n)/sqrt(n) < -1.009</pre>
+<p>Odlyzko and te Riele do not actually produce any value of <tt>n</tt> for which <tt>M(n) > sqrt(x)</tt>. They suspect that any Mertens conjecture counterexample requires <tt>n</tt> > $10^{30}$, which is far beyond any computation possible today.</p>
+
+<p>Odlyzko and te Riele also describe several complete tabulations of <tt>M(n)</tt> for <tt>n</tt> as large as $7.8 \cdot 10^{9}$ . These computations do not use Redheffer determinants.</p>
+
+<h4>Postscripts<a name="4247c5bb-c39a-4a0a-88a9-4859dcc0e793"></a>
+</h4>
+<p>To tell the truth, I did not really expect to find any Mertens or Riemann counterexamples. I did, however, enjoy computing determinants for the first time and discovering an unexpected use for sparse LU.</p>
+
+<p>Thanks a lot to Tim Davis for his help with this post.</p>
+
+<h4>References<a name="8b8af9b2-9248-420a-9072-b53f5d344050"></a>
+</h4>
+<p>A. M. Odlyzko and H. J. J. te Riele, "Disproof of the Mertens conjecture", <i>Journal für die reine und angewandte Mathematik</i>, Vol. 357 (1985), Pages138-160. <a href="https://eudml.org/doc/152712">https://eudml.org/doc/152712</a>.</p>
+
+<p>Timothy A. Davis, "A Column Pre-Ordering Strategy for the Unsymmetric-Pattern Multifrontal Method", <i>ACM Transactions on Mathematical Software</i>, Vol. 30, No. 2, June 2004, Pages 165–195. <a href="https://dl.acm.org/doi/abs/10.1145/992200.992205">https://dl.acm.org/doi/abs/10.1145/992200.992205</a>.</p>
+
+<!--
+ function grabCode_500e91acec4e4151a58ba494fb74b941() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='500e91acec4e4151a58ba494fb74b941 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 500e91acec4e4151a58ba494fb74b941';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2024 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ -->
+<p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;">
+<br />
+<a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript>
+</span></a>
+<br />
+<br />
+ Published with MATLAB® R2024a<br />
+</p>
+
+</div>
+
+<!--
+500e91acec4e4151a58ba494fb74b941 ##### SOURCE BEGIN #####
+%% Redheffer, Mertens, Riemann and $1M
+% I didn't know anything about these topics until a couple of
+% weeks ago. Now I can't stop thinking about them.
+%
+% * Redheffer's matrix has been in the
+% <https://blogs.mathworks.com/cleve/2019/06/24/bohemian-matrices-in-the-matlab-gallery/
+% MATLAB Gallery> for a long time, but I have ignored it .
+% * Redheffer's matrix can be used to compute Mertens function and
+% investigate the
+% <https://en.wikipedia.org/wiki/Mertens_conjecture
+% Mertens conjecture>.
+% * A proof of the Mertens conjecture would also provide a proof of the
+% <https://en.wikipedia.org/wiki/Riemann_hypothesis Riemann hypothesis>.
+% * For nearly a century, all the available computational evidence
+% indicated that the Mertens conjecture was likely to be true.
+% * The Riemann hypothesis is the most important unsolved problem in
+% mathematics and wins a Clay prize worth
+% <https://www.claymath.org/millennium/riemann-hypothesis
+% one-million dollars>.
+% * MATLAB's sparse matrix functions turn out to be useful
+% in an investigation of Redheffer's matrix and the Mertens conjecture.
+% * However, it has been known since 1985 that the Mertens
+% conjecture is false.
+
+%% Redheffer's Matrix
+% <https://en.wikipedia.org/wiki/Raymond_Redheffer Raymond Redheffer>
+% (1921-2005) was an American mathematician, a professor at UCLA for
+% 55 years, the author of several popular textbooks, the inventor
+% of the electronic game <https://en.wikipedia.org/wiki/Nim Nim>
+% and, with Ray and Charles Eames, the creator of a four-meter long poster
+% <https://www.worthpoint.com/worthopedia/1966-ray-charles-eames-office-men-1724813663
+% Men of Modern Mathematics>.
+%
+% Redheffer's matrix is a matrix of zeros and ones.
+% |A(k,j)| equals one if |j| is a divisor of |k|.
+% In addition, the first column is all ones.
+%
+% function A = redheffer(n)
+% k = 1:n;
+% j = k';
+% A = (mod(k,j) == 0);
+% A(:,1) = 1;
+% end
+%
+% Or
+%
+% A = gallery('redheff',n)
+%
+% Here is the 10-by-10.
+
+ A = redheffer(10);
+ disp(full(A))
+
+%%
+% And here is a spy plot of the 200-by-200.
+
+ A = redheffer(200);
+ spy(A)
+ title('redheffer(200)')
+
+%% Möbius Function
+% The Möbius function was introduced in 1832 by German mathematician
+% August Möbius and is ubiquitous in the study of prime numbers.
+% For positive integers |n|, |μ(n)| is
+%
+% * |0| if |n| has a squared prime factor,
+% * |+1| if |n| is square-free and has an even number of prime factors,
+% * |-1| if |n| is square-free and has an odd number of prime factors.
+%
+%% Mertens Function
+% <https://en.wikipedia.org/wiki/Franz_Mertens Franz Mertens>
+% (1840-1927) was a Polish mathematician who spent most of his
+% career in Austria at the University of Vienna.
+% Here is a
+% <https://mathshistory.st-andrews.ac.uk/Biographies/Mertens/
+% link> to a biography of Mertens at the University of St. Andrews
+% MacTutor project.
+%
+% The Mertens function is sum of values of the Möbius function.
+% For a positive integer |n|, the Mertens function is
+%
+% M(n) = sum(μ(1:n))
+%
+% So |M(n)| is the difference between the number of square-free
+% integers with an even number of prime factors and those with an
+% odd number.
+%
+% This graphic shows |M(n)| for |n = 1:100000|.
+
+ mertens_plot_2
+
+%% Mertens Conjecture
+% The Mertens function |M(n)| fluctuates wildly and grows slowly with
+% increasing |n|. The graphic shows that M(n) is easily bounded
+% by of |sqrt(n)| and |-sqrt(n)|, at least for |n| less than |100k|.
+% The Mertens conjecture is that this continues for larger |n|.
+%
+% -sqrt(n) < M(n) < sqrt(n) for all n
+%
+% The conjecture was included in a letter from Stieltjes to
+% Hermite in 1895 and in a paper by Mertens in 1897.
+% The result is important since a proof of the Mertens conjecture
+% would imply the truth of the Riemann hypothesis.
+
+%% Mertens Meets Redheffer
+% I became interested in all this when I learned that
+% the determinant of the MATLAB Gallery matrix which I have
+% ignored for years is related to the Riemann hypothesis and
+% the million-dollar prize.
+%
+% M(n) = det(gallery('redheff',n))
+%
+% I know very little about the distribution of prime numbers and
+% computing values of the Möbius function. On the other hand,
+% I know a lot about numerical linear algebra and computing determinants.
+%
+% In general, I am dead set against computing determinants.
+% They are often used to check for singularity or to somehow
+% compute eigenvalues. But here the determinant is an
+% integer counter of modest size.
+
+%% Redheffer Sparsity
+% Computing |M(n)| directly with |det(redheffer(n))| requires
+% |O(n^2)| space and |O(n^3)| time and is not practical for
+% large |n|.
+%
+% However, |A = redheffer(n)| is modestly sparse.
+% Here is the fraction of nonzeros.
+%
+% s = nnz(A)/n^2
+
+ disp(sparsity)
+
+%%
+% Taking advantage of this sparsity and the MATLAB tools for
+% sparse matrix computation provide
+% linear space complexity and perhaps |O(n^2)| time complexity.
+
+%% |redheffer|
+% Here is MATLAB code to generate a sparse |redheffer(n)| without
+% creating any full intermediate matrices.
+
+
+ type redheffer
+
+%%
+% As expected, we see that the execution time for |redheffer(n)|
+% is a linear function of |n|. (The space required also grows linearly.)
+
+ redheffer_time
+
+%% Sparse LU
+% The MATLAB Gaussian elimination function |lu| with one sparse
+% input and four sparse outputs
+% is designed for solving sparse linear systems.
+%
+% [L,U,P,Q] = lu(A)
+%
+% Written primarily
+% by Tim Davis and included in his UMFPACK package, the function
+% uses an unsymmetric pattern multifrontal pivoting strategy to
+% find permutations |P| and |Q| so that |L| is lower triangular,
+% |U| is upper triangular and
+%
+% P*A*Q = L*U
+%
+% Consequently, the determinant of |A| is the product of four easily
+% computed determinants.
+%
+% det(A) = det(L)*det(U)*det(P)*det(Q)
+%
+% The pivoting strategy aims to reduce fill-in while maintaining
+% numerical stability.
+
+%%
+% For example, here are |L| and |U| for the Redheffer matrix
+% in the spy plot near the top of this blog post.
+
+ close
+ A = redheffer(200);
+ [L,U,P,Q] = lu(A);
+ spy(L|U)
+ title('L|U')
+
+%%
+% And here are the four determinants.
+
+ dets = [det(L), det(U), det(P), det(Q)];
+ disp(dets)
+
+%%
+% Finally, |M(200)| is
+
+ M_200 = det(L)*det(U)*det(P)*det(Q)
+
+%% |mertens|
+% Mertens function can be computed with four lines of code.
+
+ type mertens
+
+%%
+% Execution time for |mertens| is dominated by the time in sparse |lu|.
+% The time required to compute the four determinants is an order of
+% magnitude smaller than the other two.
+%
+% Experimentally, we see that the time complexity of sparse |lu| is
+% |O(n^2)|, but we have no proof.
+
+ mertens_time
+
+%% Mertens Conjecture Is False
+% The Mertens conjecture stood for nearly 100 years before it was
+% proved false in 1985 by Andrew Odlyzko and Herman te Riele.
+% The authors present indirect proofs that
+%
+% lim sup (n -> inf) M(n)/sqrt(n) > 1.06
+%
+% lim inf (n -> inf) M(n)/sqrt(n) < -1.009
+%
+% Odlyzko and te Riele do not actually produce any value of |n| for
+% which |M(n) > sqrt(x)|. They suspect that any Mertens conjecture
+% counterexample requires |n| > $10^{30}$, which is far beyond any
+% computation possible today.
+%
+% Odlyzko and te Riele also describe several complete tabulations of
+% |M(n)| for |n| as large as $7.8 \cdot 10^{9}$ . These computations
+% do not use Redheffer determinants.
+
+%% Postscripts
+% To tell the truth, I did not really expect to find any Mertens or
+% Riemann counterexamples. I did, however, enjoy computing determinants
+% for the first time and discovering an unexpected use for sparse LU.
+%
+% Thanks a lot to Tim Davis for his help with this post.
+
+%% References
+% A. M. Odlyzko and H. J. J. te Riele,
+% "Disproof of the Mertens conjecture",
+% _Journal für die reine und angewandte Mathematik_,
+% Vol. 357 (1985), Pages138-160. <https://eudml.org/doc/152712>.
+%
+% Timothy A. Davis,
+% "A Column Pre-Ordering Strategy for the Unsymmetric-Pattern Multifrontal
+% Method",
+% _ACM Transactions on Mathematical Software_,
+% Vol. 30, No. 2, June 2004, Pages 165–195.
+% <https://dl.acm.org/doi/abs/10.1145/992200.992205>.
+%
+
+
+##### SOURCE END ##### 500e91acec4e4151a58ba494fb74b941
+-->
+
+
+
+
+ NA_Digest and NA_Net
+
+ 2024-08-31T21:44:36-06:00
+ https://hpc.social/2024/na-digest-and-na-net
+ <div class="content"><!--introduction-->
+<p>The <a href="https://www.netlib.org/na-digest-html/">NA-Digest</a> is an electronic newsletter for the numerical analysis and scientific software community. The NA-Digest is one of world's first examples of social networking. The Digest is one of the forces that makes our community a living, viable community.</p>
+
+<p>The Digest is part of NA-Net, which also includes <a href="https://www.netlib.org/">Netlib</a>, a collection of mathematical software, papers, and databases.</p>
+
+<p>For its first forty years, the NA-Digest has had only four editors. Now, we are <a href="https://www.netlib.org/na-digest-html/24/v24n11.html">adding two more</a>. As we do that, I would like to take a personal look back at the history of the NA-Digest.</p>
+
+<!--/introduction-->
+<h3>Contents</h3>
+<div>
+<ul>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#42644b1c-8ee9-4edf-8399-1ffb5ba7f590">Gene and Mark</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#22096a5c-5e18-461e-9393-60f6a3bbb50c">Jack and Eric</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#1fd1e215-f726-417a-aa69-971302131b6f">Tammy and Danny</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#7c1ce1c2-47b9-4c04-a89b-6f5b35367817">David and Alex</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#a8dab39f-1171-4d72-8485-cc39142450cd">Archive</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#319b8bc4-61b1-47d7-a372-6ea6ffd20197">Members</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#82cfa35d-28ab-4312-984e-623267f106d4">Important Postings</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#2e3065dc-2d44-4a9f-96fc-d8376c9b2490">Thanks</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#8f0306a7-58c2-424a-bae9-f87fb1ae7dc5">References</a>
+</li>
+</ul>
+</div>
+
+<h4>Gene and Mark<a name="42644b1c-8ee9-4edf-8399-1ffb5ba7f590"></a>
+</h4>
+<p>Like many other developments in the numerical analysis world, the Digest began with <a href="https://en.wikipedia.org/wiki/Gene_H._Golub">Gene Golub</a>. In the early 1980's, Golub was chair of Stanford's Computer Science Department. Email was a new thing and Gene maintained a list of email addresses for his many friends around the world. Email addresses came in many different formats; today's system of domain names was not yet in wide spread use.</p>
+
+<p>In 1984, Mark Kent, one of Gene's grad students, with help from Ray Tuminaro, Mark Crispin and Dan Kolkowitz, wrote software that used Gene's list in an email forwarding service. Mail sent to</p>
+
+<p>
+<tt>na.</tt><i>name</i><tt>@su-score</tt>
+</p>
+
+<p>would be forwarded to the person with that last name. And email sent to</p>
+
+<p>
+<tt>na@su-score</tt>
+</p>
+
+<p>would be forwarded to everyone on the list.</p>
+
+<p>Gene and Mark Kent began to gather contributions together and send the collection out periodically. By February 1987, this had evolved into a moderated weekly newsletter. Gene dubbed these email services the <i>NA-Net</i>.</p>
+
+<p>Nick Trefethen has this memory.</p>
+
+<pre> Early in the days of email, domain names were all over the place.
+ I think there was a period when Gene was using xxx.na for the
+ names of numerical analysts. Then somebody decided addresses should
+ end with the country, giving us .uk and .fr and .ch and all
+ that. For a period, we found that a lot of our numerical
+ analysis emails were being directed to Namibia!</pre>
+<p>In 1987, Gene asked me to moderate NA-Digest temporarily while he went on a sabbatical. That temporary position ultimately lasted 18 years, until 2005.</p>
+
+<h4>Jack and Eric<a name="22096a5c-5e18-461e-9393-60f6a3bbb50c"></a>
+</h4>
+<p>
+<a href="https://history.siam.org/oralhistories/dongarra.htm">Jack Dongarra</a> began his career at Argonne National Laboratory. Jack's colleague, Eric Grosse, began his career at Bell Labs. In 1984, Jack and Eric created Netlib, a software repository and distribution service, and merged it with NA-Net. In 1989, Jack and the NA-Net system moved from Argonne to Oak Ridge National Lab and the University of Tennessee.</p>
+
+<p>Keith Moore, at the University of Tennessee, rewrote the NA-Net software and maintained the servers for many years.</p>
+
+<p>Gerald Ragghianti, the Technical Services Leader at Tennessee's Innovative Computer Lab, currently maintains the NA-Net software and servers.</p>
+
+<h4>Tammy and Danny<a name="1fd1e215-f726-417a-aa69-971302131b6f"></a>
+</h4>
+<p>In 2005, I asked Tammy Kolda, who was then at Sandia Labs in Livermore, to be the NA-Digest editor. Tammy's <a href="https://www.google.com/search?q=tamara+kolda">Wikipedia page</a> reveals that her given name is "Tamara", but everybody calls her "Tammy". She left Sandia is 2021 and now has her own consulting company, <a href="https://www.mathsci.ai/">MathSci.ai</a>.</p>
+
+<p>In 2010, Tammy recommended that Danny Dunlavy, from Sandia Labs in Albuquerque, take over as editor. He has been the editor for 14 years. Danny's day job at Sandia's <a href="https://www.sandia.gov/ccr">Center for Computing Research</a> involves a wide range of fields including computer architecture, cognitive modeling and discrete mathematics.</p>
+
+<p>
+<img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/OldEditors.png" vspace="5" /> </p>
+
+<h4>David and Alex<a name="7c1ce1c2-47b9-4c04-a89b-6f5b35367817"></a>
+</h4>
+<p>
+<img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/NewEditors.png" vspace="5" /> </p>
+
+<p>
+<a href="https://www.netlib.org/na-digest-html/24/v24n11.html">Starting next week</a>, NA-Digest and NA-Net will move <a href="https://en.wikipedia.org/wiki/Lock,_stock,_and_barrel">lock, stock, and barrel</a> to Cornell University. The new editors are <a href="https://www.cs.cornell.edu/~bindel/bio">David Bindell</a> and <a href="https://pi.math.cornell.edu/~ajt/">Alex Townsend</a>. Cornell's IT organization will be taking over the logistics.</p>
+
+<p>David, Alex and <a href="https://www.cs.cornell.edu/~damle/#About">Anil Damle</a> are also the hosts for <a href="https://householder-symposium.github.io">Householder XXII</a>, June 8-13, 2025.</p>
+
+<h4>Archive<a name="a8dab39f-1171-4d72-8485-cc39142450cd"></a>
+</h4>
+<p>Every issue of NA-Digest since February 1987 is available at <a href="https://www.netlib.org/na-digest-html">https://www.netlib.org/na-digest-html</a>.</p>
+
+<h4>Members<a name="319b8bc4-61b1-47d7-a372-6ea6ffd20197"></a>
+</h4>
+<p>When I succeeded Gene as editor in 1987, there were about 800 names on the NA-Net mailing list. Today, in 2024, there are a little over 10,000. Discontinuities in the size of the list result when unused and illegitimate names are removed.</p>
+
+<p>
+<img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/NA_Digs.png" vspace="5" /> </p>
+
+<h4>Important Postings<a name="82cfa35d-28ab-4312-984e-623267f106d4"></a>
+</h4>
+<p>I have made three personally important announcements in the Digest over the years.</p>
+
+<p>
+<b>October 29, 1989</b>
+</p>
+
+<p>In 1989 I was working at <a href="https://blogs.mathworks.com/cleve/2013/11/25/the-ardent-titan-part-1/">Ardent Computer</a>, a startup in Silicon Valley. I announced in NA-Digest that MathWorks was looking for a numerical analyst. (Note the MathWorks telephone number near the end of this announcement.)</p>
+
+<pre> From: Cleve Moler <na.moler@na-net.stanford.edu>
+ Date: Sun Oct 29 10:39:38 PST 1989
+ Subject: Positions at The MathWorks</pre>
+<pre> The MathWorks is the company which develops and markets MATLAB.
+ The company currently employs about 30 people and expects to
+ add three or four more soon. The company headquarters is in
+ East Natick, Massachusetts, which is about a half hour drive
+ west of Boston.</pre>
+<pre> The background and interests expected for the various positions
+ available range from numerical linear algebra and matrix computation
+ to systems programming and graphics. Educational level and
+ experience expected range from inexperienced beginner willing
+ to learn to seasoned Ph.D. with a personal library of M-files.</pre>
+<pre> For more information, send email to na.moler@na-net.stanford.edu
+ or phone me at 408-732-0400. Or, contact the MathWorks' president,
+ John Little, with email to jnl@mathworks.com, phone 508-653-1415,
+ or write to:</pre>
+<pre> The MathWorks
+ 21 Eliot Street
+ South Natick, MA 01760</pre>
+<p>
+<b>November 26, 1989</b>
+</p>
+
+<p>Shortly after that announcement, <a href="https://en.wikipedia.org/wiki/Stardent_Inc.">Ardent imploded</a> and I said that I was taking the job myself.</p>
+
+<pre> From: Cleve Moler <moler@mathworks.com>
+ Date: Sun Nov 26 09:16:32 PST 1989
+ Subject: Change of Address for Moler</pre>
+<pre> A couple of weeks ago, I made an announcement here that
+ The MathWorks, the MATLAB company, was looking to fill several
+ positions, including one for a numerical analyst. Now, I've
+ decided to take that slot myself. I'm one of the founders of
+ MathWorks, and have always been a consultant to the company, but
+ now I'll be a full time employee. For a while at least, I'll
+ be working out of my home in California, even though MathWorks
+ headquarters is in Massachusetts. (There are already a couple
+ of other MathWorks developers in the Bay Area.)
+ . . .
+ My electronic address is "moler@mathworks.com". If your mailer
+ can't find the route via uunet to mathworks.com, you can still
+ use "na.moler@na-net.stanford.edu".</pre>
+<p>
+<b>November 16, 2007</b>
+</p>
+
+<p>In November 2007 I was attending the Super Computing conference in Reno. I had rented a car and intended to drive to the Bay Area after the conference. But my wife called me and said, "Hey Cleve, have you heard that Gene is in the hospital?" I left SC immediately and drove to Palo Alto. Two days later we sent out a special issue of the Digest:</p>
+
+<pre> From: Cleve Moler <Cleve.Moler@mathworks.com>
+ Date: Fri, 16 Nov 2007 17:55:42 -0500
+ Subject: Gene Golub, 1932 - 2007</pre>
+<pre> Gene Golub, founder of the NA Digest, passed away today, Friday, November 16,
+ at the Stanford University Hospital. He was 75 years old.</pre>
+<pre> Gene returned home to Stanford recently from a trip to Hong Kong. He was
+ planning to leave again Tuesday on another trip, this one to Zurich where the
+ ETH was to honor him with a special degree. Instead, Sunday night he went to
+ the emergency room because he was "feeling lousy". On Tuesday, he was found
+ to have AML, acute myelogenous leukemia, a form of cancer that affects the
+ white blood cells. This is a potentially curable disease and he was expecting
+ to begin chemotherapy today. But serious complications developed suddenly
+ over night.</pre>
+<pre> I was able to see Gene for an hour last night and he was in reasonably good
+ spirits. Mike Saunders was trying to get Gene's laptop to use dial-up over
+ the hospital's phone system because Gene said he was a couple of days behind
+ on his email. I was planning to get a wireless card for his machine today.
+ None of us had any idea how suddenly the situation would worsen.</pre>
+<pre> The Stanford ICME students have created a memorial blog at
+ http://genehgolub.blogspot.com .</pre>
+<pre> Our community has lost its foremost member. He was a valued colleague and
+ friend. Goodbye, Gene.</pre>
+<pre> -- Cleve Moler</pre>
+<h4>Thanks<a name="2e3065dc-2d44-4a9f-96fc-d8376c9b2490"></a>
+</h4>
+<div>
+<ul>
+<li>Gene Golub and Mark Kent for creating NA-Digest and NA-Net.</li>
+<li>Tammy Kolda and Danny Dunlavy for editing the Digest for two decades.</li>
+<li>Jack Dongarra, Eric Grosse, Keith Moore and Geri Ragghianti for creating Netlib and for hosting the system for four decades.</li>
+<li>David Bindel and Alex Townsend for joining this team.</li>
+</ul>
+</div>
+
+<h4>References<a name="8f0306a7-58c2-424a-bae9-f87fb1ae7dc5"></a>
+</h4>
+<p>Jack Dongarra, Gene Golub, Eric Grosse, Cleve Moler and Keith Moore. "Netlib and NA-Net: Building a Scientific Computing Community", <a href="https://ieeexplore.ieee.org/document/4544554"><i>IEEE Annals of the History of Computing</i></a>, (Volume: 30, Issue: 2, April-June 2008). <a href="https://blogs.mathworks.com/cleve/files/icl-utk-351-2008.pdf">A PDF is available here</a>.</p>
+
+<p>Mark Kent, <a href="https://www.research-collection.ethz.ch/handle/20.500.11850/68968">The Numerical Analysis Net (NA-NET)</a>, Technical Report 85, ETH Zurich, Institut fuer Informatik, 1988.</p>
+
+<!--
+ function grabCode_ad3526f9a6bc4fedb6f2b87f8bc0de10() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='ad3526f9a6bc4fedb6f2b87f8bc0de10 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' ad3526f9a6bc4fedb6f2b87f8bc0de10';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2024 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ -->
+<p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;">
+<br />
+<a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript>
+</span></a>
+<br />
+<br />
+ Published with MATLAB® R2024a<br />
+</p>
+
+</div>
+
+<!--
+ad3526f9a6bc4fedb6f2b87f8bc0de10 ##### SOURCE BEGIN #####
+%% NA_Digest and NA_Net
+% The <https://www.netlib.org/na-digest-html/ NA-Digest>
+% is an electronic newsletter for the numerical analysis and
+% scientific software community.
+% The NA-Digest is one of world's first examples of social networking.
+% The Digest is one of the forces that makes our community
+% a living, viable community.
+%
+% The Digest is part of NA-Net, which also includes
+% <https://www.netlib.org/ Netlib>, a collection of mathematical software,
+% papers, and databases.
+%
+% For its first forty years, the NA-Digest has had only four editors.
+% Now, we are
+% <https://www.netlib.org/na-digest-html/24/v24n11.html
+% adding two more>.
+% As we do that, I would like to take a personal look back at the
+% history of the NA-Digest.
+
+%% Gene and Mark
+% Like many other developments in the numerical analysis world,
+% the Digest began with <https://en.wikipedia.org/wiki/Gene_H._Golub
+% Gene Golub>. In the early 1980's, Golub was chair of Stanford's
+% Computer Science Department. Email was a new thing and Gene
+% maintained a list of email addresses for his many friends
+% around the world. Email addresses came in many different formats;
+% today's system of domain names was not yet in wide spread use.
+%
+% In 1984, Mark Kent, one of Gene's grad students,
+% with help from Ray Tuminaro, Mark Crispin and Dan Kolkowitz,
+% wrote software that used Gene's list in an email
+% forwarding service. Mail sent to
+%
+% |na.|_name_|@su-score|
+%
+% would be forwarded to the person with that last name. And email sent to
+%
+% |na@su-score|
+%
+% would be forwarded to everyone on the list.
+%
+% Gene and Mark Kent
+% began to gather contributions together
+% and send the collection out periodically. By February 1987, this
+% had evolved into a moderated weekly newsletter.
+% Gene dubbed these email services the _NA-Net_.
+%
+% Nick Trefethen has this memory.
+%
+% Early in the days of email, domain names were all over the place.
+% I think there was a period when Gene was using xxx.na for the
+% names of numerical analysts. Then somebody decided addresses should
+% end with the country, giving us .uk and .fr and .ch and all
+% that. For a period, we found that a lot of our numerical
+% analysis emails were being directed to Namibia!
+%
+% In 1987, Gene asked me to moderate NA-Digest temporarily while he
+% went on a sabbatical. That temporary position ultimately
+% lasted 18 years, until 2005.
+%
+
+%% Jack and Eric
+% <https://history.siam.org/oralhistories/dongarra.htm Jack Dongarra>
+% began his career at Argonne National Laboratory. Jack's colleague,
+% Eric Grosse, began his career at Bell Labs.
+% In 1984, Jack and Eric created Netlib, a software repository and
+% distribution service, and merged it with NA-Net.
+% In 1989, Jack and the NA-Net system moved from Argonne to
+% Oak Ridge National Lab and the University of Tennessee.
+%
+% Keith Moore, at the University of Tennessee,
+% rewrote the NA-Net software and maintained the servers for many years.
+%
+% Gerald Ragghianti, the Technical Services Leader at
+% Tennessee's Innovative Computer Lab, currently maintains the NA-Net
+% software and servers.
+
+%% Tammy and Danny
+% In 2005, I asked Tammy Kolda, who was then at Sandia Labs
+% in Livermore, to be the NA-Digest editor.
+% Tammy's <https://www.google.com/search?q=tamara+kolda Wikipedia page>
+% reveals that her given name is "Tamara", but everybody calls her "Tammy".
+% She left Sandia is 2021 and now has her own consulting company,
+% <https://www.mathsci.ai/ MathSci.ai>.
+%
+% In 2010, Tammy recommended that Danny Dunlavy, from Sandia Labs in
+% Albuquerque, take over as editor. He has been the editor for 14 years.
+% Danny's day job at Sandia's
+% <https://www.sandia.gov/ccr Center for Computing Research>
+% involves a wide range of fields including computer architecture,
+% cognitive modeling and discrete mathematics.
+%
+% <<OldEditors.png>>
+%
+
+%% David and Alex
+%
+% <<NewEditors.png>>
+%
+% <https://www.netlib.org/na-digest-html/24/v24n11.html
+% Starting next week>, NA-Digest and NA-Net will move
+% <https://en.wikipedia.org/wiki/Lock,_stock,_and_barrel
+% lock, stock, and barrel> to Cornell University.
+% The new editors are
+% <https://www.cs.cornell.edu/~bindel/bio David Bindell>
+% and
+% <https://pi.math.cornell.edu/~ajt/ Alex Townsend>.
+% Cornell's IT organization will be taking over the logistics.
+%
+% David, Alex and <https://www.cs.cornell.edu/~damle/#About Anil Damle>
+% are also the hosts for
+% <https://householder-symposium.github.io Householder XXII>,
+% June 8-13, 2025.
+
+%% Archive
+% Every issue of NA-Digest since February 1987
+% is available at
+% <https://www.netlib.org/na-digest-html>.
+
+%% Members
+% When I succeeded Gene as editor in 1987, there were about 800 names
+% on the NA-Net mailing list. Today, in 2024, there are a little
+% over 10,000.
+% Discontinuities in the size of the list result when
+% unused and illegitimate names are removed.
+%
+% <<NA_Digs.png>>
+
+%% Important Postings
+% I have made three personally important announcements in the Digest over
+% the years.
+%
+% *October 29, 1989*
+%
+% In 1989 I was working at
+% <https://blogs.mathworks.com/cleve/2013/11/25/the-ardent-titan-part-1/
+% Ardent Computer>, a startup in Silicon Valley.
+% I announced in NA-Digest that MathWorks was looking for a numerical
+% analyst. (Note the MathWorks telephone number near the end of this
+% announcement.)
+%
+% From: Cleve Moler <na.moler@na-net.stanford.edu>
+% Date: Sun Oct 29 10:39:38 PST 1989
+% Subject: Positions at The MathWorks
+%
+% The MathWorks is the company which develops and markets MATLAB.
+% The company currently employs about 30 people and expects to
+% add three or four more soon. The company headquarters is in
+% East Natick, Massachusetts, which is about a half hour drive
+% west of Boston.
+%
+% The background and interests expected for the various positions
+% available range from numerical linear algebra and matrix computation
+% to systems programming and graphics. Educational level and
+% experience expected range from inexperienced beginner willing
+% to learn to seasoned Ph.D. with a personal library of M-files.
+%
+% For more information, send email to na.moler@na-net.stanford.edu
+% or phone me at 408-732-0400. Or, contact the MathWorks' president,
+% John Little, with email to jnl@mathworks.com, phone 508-653-1415,
+% or write to:
+%
+% The MathWorks
+% 21 Eliot Street
+% South Natick, MA 01760
+%
+% *November 26, 1989*
+%
+% Shortly after that announcement,
+% <https://en.wikipedia.org/wiki/Stardent_Inc. Ardent imploded>
+% and I said that I was taking the job myself.
+%
+% From: Cleve Moler <moler@mathworks.com>
+% Date: Sun Nov 26 09:16:32 PST 1989
+% Subject: Change of Address for Moler
+%
+% A couple of weeks ago, I made an announcement here that
+% The MathWorks, the MATLAB company, was looking to fill several
+% positions, including one for a numerical analyst. Now, I've
+% decided to take that slot myself. I'm one of the founders of
+% MathWorks, and have always been a consultant to the company, but
+% now I'll be a full time employee. For a while at least, I'll
+% be working out of my home in California, even though MathWorks
+% headquarters is in Massachusetts. (There are already a couple
+% of other MathWorks developers in the Bay Area.)
+% . . .
+% My electronic address is "moler@mathworks.com". If your mailer
+% can't find the route via uunet to mathworks.com, you can still
+% use "na.moler@na-net.stanford.edu".
+%
+% *November 16, 2007*
+%
+% In November 2007 I was attending the Super Computing conference in
+% Reno. I had rented a car and intended to drive to the Bay Area
+% after the conference. But my wife called me and said,
+% "Hey Cleve, have you heard that Gene is in the hospital?"
+% I left SC immediately and drove to Palo Alto. Two days later
+% we sent out a special issue of the Digest:
+%
+% From: Cleve Moler <Cleve.Moler@mathworks.com>
+% Date: Fri, 16 Nov 2007 17:55:42 -0500
+% Subject: Gene Golub, 1932 - 2007
+%
+% Gene Golub, founder of the NA Digest, passed away today, Friday, November 16,
+% at the Stanford University Hospital. He was 75 years old.
+%
+% Gene returned home to Stanford recently from a trip to Hong Kong. He was
+% planning to leave again Tuesday on another trip, this one to Zurich where the
+% ETH was to honor him with a special degree. Instead, Sunday night he went to
+% the emergency room because he was "feeling lousy". On Tuesday, he was found
+% to have AML, acute myelogenous leukemia, a form of cancer that affects the
+% white blood cells. This is a potentially curable disease and he was expecting
+% to begin chemotherapy today. But serious complications developed suddenly
+% over night.
+%
+% I was able to see Gene for an hour last night and he was in reasonably good
+% spirits. Mike Saunders was trying to get Gene's laptop to use dial-up over
+% the hospital's phone system because Gene said he was a couple of days behind
+% on his email. I was planning to get a wireless card for his machine today.
+% None of us had any idea how suddenly the situation would worsen.
+%
+% The Stanford ICME students have created a memorial blog at
+% http://genehgolub.blogspot.com .
+%
+% Our community has lost its foremost member. He was a valued colleague and
+% friend. Goodbye, Gene.
+%
+% REPLACE_WITH_DASH_DASH Cleve Moler
+
+%% Thanks
+%
+% * Gene Golub and Mark Kent for creating NA-Digest and NA-Net.
+% * Tammy Kolda and Danny Dunlavy for editing the Digest for two decades.
+% * Jack Dongarra, Eric Grosse, Keith Moore and Geri Ragghianti for
+% creating Netlib and for hosting the system for four decades.
+% * David Bindel and Alex Townsend for joining this team.
+
+%% References
+%
+% Jack Dongarra, Gene Golub, Eric Grosse, Cleve Moler and Keith Moore.
+% "Netlib and NA-Net: Building a Scientific Computing Community",
+% <https://ieeexplore.ieee.org/document/4544554
+% _IEEE Annals of the History of Computing_>,
+% (Volume: 30, Issue: 2, April-June 2008).
+% <https://blogs.mathworks.com/cleve/files/icl-utk-351-2008.pdf
+% A PDF is available here>.
+%
+% Mark Kent,
+% <https://www.research-collection.ethz.ch/handle/20.500.11850/68968
+% The Numerical Analysis Net (NA-NET)>, Technical Report 85, ETH
+% Zurich, Institut fuer Informatik, 1988.
+
+##### SOURCE END ##### ad3526f9a6bc4fedb6f2b87f8bc0de10
+-->
+
+
+
+
+ A Treacherous SVD
+
+ 2024-07-15T15:39:04-06:00
+ https://hpc.social/2024/a-treacherous-svd
+ <div class="content"><!--introduction-->
+<p>A few days ago, a bug report from our office in Cambridge caught my attention. Computing the singular values and singular vectors of a particular matrix would sometimes cause MATLAB to crash.</p>
+
+<!--/introduction-->
+<h3>Contents</h3>
+<div>
+<ul>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#687983f8-4f5c-4ab6-8c9a-670d933db516">Two Computers</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#bb7d2817-a6f9-4636-b9a4-ec93834d3c2f">Math Libraries</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#b76d6ed5-ea1c-4dc5-876b-9e32dd95c51e">G3366394</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#66e487ba-0c85-4c88-a56d-87408f340dd4">Rank</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#0848e46c-23e0-40b5-9f63-5d781d53d2d0">Zero rows</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#b08e8c96-055a-4909-8778-d590028d1cb3">Fuzz</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#f72bffb3-25d4-4136-a01c-35ce3294dcc5">Flip</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#0a7fccdf-a476-4cd7-b66e-e52d0349aa3b">Now what?</a>
+</li>
+</ul>
+</div>
+
+<h4>Two Computers<a name="687983f8-4f5c-4ab6-8c9a-670d933db516"></a>
+</h4>
+<p>I use two different two computers regularly. The machine in my home office is a Lenovo ThinkPad® model T14, loaded with two external monitors, several external disc drives, a sound bar and a dedicated internet connection. My traveling machine is a Lenovo ThinkPad X1 Nano with no external hardware.</p>
+
+<p>The report of a crash in the SVD became even more interesting when I found that it happens on my office computer, but not on the portable. A quick check revealed that the CPUs on the two machines come from different manufacturers. The office computer uses an AMD® Ryzen Pro 5 while the traveling machine uses an Intel® Core i7.</p>
+
+<h4>Math Libraries<a name="bb7d2817-a6f9-4636-b9a4-ec93834d3c2f"></a>
+</h4>
+<p>The crash occurs several software layers deep in <a href="https://netlib.org/lapack/explore-3.3.0-html/d5/d1f/cgesvd_8f_source.html">CGESVD</a>, the LAPACK driver for single precision complex SVD. Various chip manufacturers provide math libraries that have been optimized for their CPUs. However, by default, MATLAB uses the reportedly faster Intel Math Kernel Library, MKL. It is possible to switch to other math libraries.</p>
+
+<p>We have experts at MathWorks who know far more about the details of these libraries than I do. They will soon sort this all out. In the meantime, here is what I have learned about the offending matrix.</p>
+
+<h4>G3366394<a name="b76d6ed5-ea1c-4dc5-876b-9e32dd95c51e"></a>
+</h4>
+<p>We refer to the matrix in the crash report by its case number in our bug tracking system. The matrix is of modest size but is otherwise unusual for several reasons. It is rectangular with fewer rows than columns, it is in single precision, and it is complex.</p>
+
+<pre> clear
+ load g3366394 X
+ whos</pre>
+<pre> Name Size Bytes Class Attributes
+ X 219x384 672768 single complex</pre>
+<p>The following code calling SVD with three outputs will crash MATLAB on my T14, but not on my X1.</p>
+
+<pre> trysvd = false
+ if trysvd
+ [U,S,V] = svd(X);
+ R = U*S*V' - X;
+ relres = norm(R)/norm(X)
+ end</pre>
+<pre> trysvd =
+ logical
+ 0</pre>
+<h4>Rank<a name="66e487ba-0c85-4c88-a56d-87408f340dd4"></a>
+</h4>
+<p>Computing the singular values without the vectors can be done on either machine. The following code uses double precision and then plots the singular values on a logarithmic scale with a line at single precision roundoff level.</p>
+
+<pre> S = svd(X);
+ semilogy(S,'.-')
+ ep = eps('single');
+ line([0 230],[ep ep])
+ axis([0 230 1e-15 10])
+ legend({'singular values','eps(''single'')'})</pre>
+<p>
+<img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/semilogy.png" vspace="5" /> </p>
+
+<p>We see that the matrix is far from full rank. About half of its singular values are negligible. This is confirmed by</p>
+
+<pre> xrank = rank(X)</pre>
+<pre> xrank =
+ 110</pre>
+<h4>Zero rows<a name="0848e46c-23e0-40b5-9f63-5d781d53d2d0"></a>
+</h4>
+<p>The cause of the low rank is easy to find. This surf plot reveals that almost half of the rows are flat zero.</p>
+
+<p>
+<img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/full.png" vspace="5" /> </p>
+
+<p>Let's remove the zero rows.</p>
+
+<pre> c = sum(abs(X),2)==0;
+ nnzc = nnz(c)
+ X(c>0,:) = [];</pre>
+<pre> nnzc =
+ 109</pre>
+<p>
+<img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/reduced.png" vspace="5" /> </p>
+
+<p>The remaining matrix is full rank and it is safe to compute its singular vectors.</p>
+
+<pre> [U,S,V] = svd(X);
+ R = U*S*V' - X;
+ resnorm = norm(R)</pre>
+<pre> resnorm =
+ 2.8191e-06</pre>
+<h4>Fuzz<a name="b08e8c96-055a-4909-8778-d590028d1cb3"></a>
+</h4>
+<p>Removing the zero rows was the first work-around that I tried. There are many others. You can replace the zeros with any nonzero "fuzz".</p>
+
+<pre> fuzz = 1.e-20;
+ [U,S,V] = svd(X + fuzz*randn(size(X)));</pre>
+<pre> resnorm = norm(U*S*V'-X)</pre>
+<pre> resnorm =
+ 2.8222e-06</pre>
+<h4>Flip<a name="f72bffb3-25d4-4136-a01c-35ce3294dcc5"></a>
+</h4>
+<p>You can reorder the matrix so that the zero rows are not at the beginning.</p>
+
+<pre> [U,S,V] = svd(flipud(X));
+ U = flipud(U);</pre>
+<pre> resnorm = norm(U*S*V'-X)</pre>
+<pre> resnorm =
+ 2.3809e-06</pre>
+<h4>Now what?<a name="0a7fccdf-a476-4cd7-b66e-e52d0349aa3b"></a>
+</h4>
+<p>How to avoid the crash is not the most important question. What causes the crash with the original matrix? We will find out and get it fixed.</p>
+
+<!--
+ function grabCode_e32dbb50b2604a45be30742645bd3bea() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='e32dbb50b2604a45be30742645bd3bea ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' e32dbb50b2604a45be30742645bd3bea';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2024 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ -->
+<p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;">
+<br />
+<a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript>
+</span></a>
+<br />
+<br />
+ Published with MATLAB® R2024a<br />
+</p>
+
+</div>
+
+<!--
+e32dbb50b2604a45be30742645bd3bea ##### SOURCE BEGIN #####
+%% A Treacherous SVD
+% A few days ago, a bug report from our office in Cambridge
+% caught my attention. Computing the singular values and singular
+% vectors of a particular matrix would sometimes cause MATLAB to crash.
+
+%% Two Computers
+% I use two different two computers regularly.
+% The machine in my home office is a Lenovo ThinkPad(R)
+% model T14, loaded with two external monitors, several external
+% disc drives, a sound bar and a dedicated internet connection.
+% My traveling machine is a Lenovo ThinkPad X1 Nano with no external
+% hardware.
+%
+% The report of a crash in the SVD became even more interesting when
+% I found that it happens on my office computer, but not on the portable.
+% A quick check revealed that the CPUs on the two machines come from
+% different manufacturers.
+% The office computer uses an AMD(R) Ryzen Pro 5
+% while the traveling machine uses an Intel(R) Core i7.
+%
+
+%% Math Libraries
+% The crash occurs several software layers deep in
+% <https://netlib.org/lapack/explore-3.3.0-html/d5/d1f/cgesvd_8f_source.html
+% CGESVD>, the LAPACK driver for single precision complex SVD.
+% Various chip manufacturers provide math libraries that have been
+% optimized for their CPUs. However, by default, MATLAB uses
+% the reportedly faster Intel Math Kernel Library, MKL.
+% It is possible to switch to other math libraries.
+%
+% We have experts at MathWorks who know far more about the details
+% of these libraries than I do. They will soon sort this all out.
+% In the meantime, here is what I have learned about the offending
+% matrix.
+
+%% G3366394
+% We refer to the matrix in the crash report by its case
+% number in our bug tracking system.
+% The matrix is of modest size but
+% is otherwise unusual for several reasons.
+% It is rectangular with fewer rows than columns,
+% it is in single precision, and it is complex.
+%
+% clear
+% load g3366394 X
+% whos
+%
+% Name Size Bytes Class Attributes
+% X 219x384 672768 single complex
+
+
+%%
+% The following code calling SVD with three outputs
+% will crash MATLAB on my T14, but not on my X1.
+%
+% trysvd = false
+% if trysvd
+% [U,S,V] = svd(X);
+% R = U*S*V' - X;
+% relres = norm(R)/norm(X)
+% end
+%
+% trysvd =
+% logical
+% 0
+
+%% Rank
+% Computing the singular values without the vectors can be done
+% on either machine. The following code uses double precision and
+% then plots the singular values on a logarithmic scale with a
+% line at single precision roundoff level.
+%
+% S = svd(X);
+% semilogy(S,'.-')
+% ep = eps('single');
+% line([0 230],[ep ep])
+% axis([0 230 1e-15 10])
+% legend({'singular values','eps(''single'')'})
+%
+% <<semilogy.png>>
+
+%%
+% We see that the matrix is far from full rank.
+% About half of its singular values are negligible.
+% This is confirmed by
+%
+% xrank = rank(X)
+%
+% xrank =
+% 110
+
+%% Zero rows
+% The cause of the low rank is easy to find.
+% This surf plot reveals that almost half of the rows are flat zero.
+%
+% <<full.png>>
+%
+
+%%
+% Let's remove the zero rows.
+%
+% c = sum(abs(X),2)==0;
+% nnzc = nnz(c)
+% X(c>0,:) = [];
+%
+% nnzc =
+% 109
+
+%%
+% <<reduced.png>>
+%
+
+%%
+% The remaining matrix is full rank and it is safe to compute its
+% singular vectors.
+%
+% [U,S,V] = svd(X);
+% R = U*S*V' - X;
+% resnorm = norm(R)
+%
+% resnorm =
+% 2.8191e-06
+
+%% Fuzz
+% Removing the zero rows was the first work-around that I tried.
+% There are many others. You can replace the zeros with any
+% nonzero "fuzz".
+%
+% fuzz = 1.e-20;
+% [U,S,V] = svd(X + fuzz*randn(size(X)));
+%
+% resnorm = norm(U*S*V'-X)
+%
+% resnorm =
+% 2.8222e-06
+
+%% Flip
+% You can reorder the matrix so that the zero rows are not at the
+% beginning.
+%
+% [U,S,V] = svd(flipud(X));
+% U = flipud(U);
+%
+% resnorm = norm(U*S*V'-X)
+%
+% resnorm =
+% 2.3809e-06
+
+%% Now what?
+% How to avoid the crash is not the most important question.
+% What causes the crash with the original matrix?
+% We will find out and get it fixed.
+
+
+##### SOURCE END ##### e32dbb50b2604a45be30742645bd3bea
+-->
+
+
+
+
+ SuperSum, In Defense of Floating Point Arithmetic
+
+ 2024-06-27T17:54:38-06:00
+ https://hpc.social/2024/supersum-in-defense-of-floating-point-arithmetic
+ <div class="content"><!--introduction-->
+<p>Floating point arithmetic doesn't get the respect it deserves. Many people consider it mysterious, fuzzy, unpredictable. These misgivings often occur in discussion of vector sums. Our provocatively named <i>SuperSum</i> is intended to calm these fears.</p>
+
+<!--/introduction-->
+<h3>Contents</h3>
+<div>
+<ul>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#6cc58603-9b70-4a29-bc08-fae5fe3d5db0">Ledgers</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#cc3635b6-5a76-4420-baeb-94c5b36a6573">Checksums</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#71f16826-8ff1-4a14-bc85-146da594d56f">Order</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#5356ff4e-b231-4d40-9404-17b0d0d882af">Speed</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#52953716-f4f9-4698-9680-8a5d38254f1e">Three Sums</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#f8a4c9a1-edd5-4ac3-9dca-bc7306b7de0f">Toy Example</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#8acba015-e19b-413e-8817-1e093e31ee2d">Second Test</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#e0e62ed1-a352-49ea-ac59-31107304d71e">Conclusion</a>
+</li>
+</ul>
+</div>
+
+<h4>Ledgers<a name="6cc58603-9b70-4a29-bc08-fae5fe3d5db0"></a>
+</h4>
+<p>A <i>ledger</i> is a list of transactions in an account. <i>Auditing</i> the ledger involves comparing the total of the items with the change in the account balance.</p>
+
+<p>If <i>v</i> is a vector of transaction amounts, then we need to compute</p>
+
+<pre>sum(v)</pre>
+<p>If this sum is equal to the change in the balance, then it is reasonable to assume that the ledger is correct. If not, the ledger must be examined line-by-line.</p>
+
+<h4>Checksums<a name="cc3635b6-5a76-4420-baeb-94c5b36a6573"></a>
+</h4>
+<p>Have you ever used a checksum for a file transfer? One checksum is computed before the file is sent. After the file has been sent over a questionable channel, a second checksum is computed on the receiving end. If the two checksums agree, the transmission was probably okay. If not, the file must be sent again.</p>
+
+<h4>Order<a name="71f16826-8ff1-4a14-bc85-146da594d56f"></a>
+</h4>
+<p>Floating point addition is not <i>associative</i>. This means</p>
+
+<pre>(a + b) + c</pre>
+<p>is not necessarily the same as</p>
+
+<pre class="language-matlab">a+(b+c).
+</pre>
+<p>So the <i>order</i> of doing a computation is important.</p>
+
+<p>Computers are deterministic devices. If the same computation is done <i>in the same order</i> more than once, the results must be the same. If you get different sums from different runs on a fixed computer, then it must be because the order has been changed.</p>
+
+<h4>Speed<a name="5356ff4e-b231-4d40-9404-17b0d0d882af"></a>
+</h4>
+<p>In recent years, we have made the built-in function <tt>sum(x)</tt> faster by parallelizing it. The input vector is broken into several pieces, the sum of each piece is computed separately and simultaneously, then the partial sums are combined to give the final result. If the number and size of the pieces varies from run to run, the order varies and consequently the computed sums may vary.</p>
+
+<h4>Three Sums<a name="52953716-f4f9-4698-9680-8a5d38254f1e"></a>
+</h4>
+<p>Here are three replacements for <tt>nansum(x)</tt>, the version of <tt>sum(x)</tt> that skips over <tt>NaNs</tt> and <tt>infs</tt>.</p>
+
+<p>
+<b>simplesum</b>
+</p>
+
+<p>Avoid the effect of blocking in the built-in sum(x).</p>
+
+<pre>function s = simplesum(x)
+ % simplesum. s = simplesum(x), for vector(x).
+ % Force sequential order for sum(x).
+ % Skips NaNs and infs.</pre>
+<pre> s = 0;
+ for k = 1:length(x)
+ if isfinite(x(k))
+ s = s + x(k);
+ end
+ end
+end</pre>
+<p>
+<b>KahanSum</b>
+</p>
+
+<p>This is the Kahan summation algorithm. The sum is accumulated in two words, the more significant <tt>s</tt> and the correction <tt>c</tt>. If you were able to form <tt>s + c</tt> exactly, it would be more accurate than <tt>s</tt> alone.</p>
+
+<pre>function s = KahanSum(x)
+ % KahanSum. s = KahanSum(x), for vector(x).
+ % More accurate, but slower, than sum(x).
+ % Skips NaNs and infs.
+ % https://en.wikipedia.org/wiki/Kahan_summation_algorithm.</pre>
+<pre> s = 0; % sum
+ c = 0; % correction
+ for k = 1:length(x)
+ if isfinite(x(k))
+ y = x(k) - c;
+ t = s + y;
+ c = (t - s) - y;
+ s = t;
+ end
+ end
+end</pre>
+<p>
+<b>SuperSum</b>
+</p>
+
+<p>I gave it a pretentious name to grab attention. Use extended precision, with enough digits to hold any MATLAB double.</p>
+
+<pre>function s = SuperSum(x)
+ % SuperSum. s = SuperSum(x), for vector(x).
+ % Symbolic Math Toolbox extended precision.
+ % Skips NaNs and infs.
+ %
+ % 632 decimal digits holds every IEEE-754 double.
+ % 632 = ceil(log10(realmax) - log10(eps*realmin));
+ %
+ din = digits(632); % Remember current setting
+ s = double(sum(sym(x(isfinite(x)),'D')));
+ digits(din) % Restore
+end</pre>
+<h4>Toy Example<a name="f8a4c9a1-edd5-4ac3-9dca-bc7306b7de0f"></a>
+</h4>
+<p>A test case here at MathWorks, known by a French-Canadian name that translates to "toy example", has a vector <tt>e2</tt> of length 4243 and values that range from -3.3e7 to 6.8e9.</p>
+
+<p>When running tests involving floating point numbers it is a good idea to set the output format to <tt>hex</tt> so we can see every last bit.</p>
+
+<pre>format hex
+load jeuTest e2
+x = e2;</pre>
+<pre>[nansum(x)
+ simplesum(x)
+ KahanSum(x)
+ SuperSum(x)]</pre>
+<pre>ans =
+ 423785e8206150e2
+ 423785e8206150e0
+ 423785e8206150e1
+ 423785e8206150e1</pre>
+<p>For <tt>jeuTest</tt>, Kahan summation gets the same result as <tt>SuperSum</tt>, while <tt>nansum</tt> and <tt>simplesum</tt> differ in the last bit or two.</p>
+
+<h4>Second Test<a name="8acba015-e19b-413e-8817-1e093e31ee2d"></a>
+</h4>
+<p>The vector length is only three, but the third term completely cancels the first, and the second term rises from obscurity. In this situation, <tt>KahanSum</tt> is no more accurate than <tt>sum</tt>.</p>
+
+<pre>format hex
+x = [1 1e-14 -1]'</pre>
+<pre>[nansum(x)
+ simplesum(x)
+ KahanSum(x)
+ SuperSum(x)]</pre>
+<pre>x =
+ 3ff0000000000000
+ 3d06849b86a12b9b
+ bff0000000000000</pre>
+<pre>ans =
+ 3d06800000000000
+ 3d06800000000000
+ 3d06800000000000
+ 3d06849b86a12b9b</pre>
+<h4>Conclusion<a name="e0e62ed1-a352-49ea-ac59-31107304d71e"></a>
+</h4>
+<p>I will leave careful timing for another day. Let's just say that in situations like <tt>jeuTest</tt>, <tt>KahanSum</tt> is probably all you need. It is usually more accurate than <tt>sum</tt>, and not much slower.</p>
+
+<p>However, for complete reliability, use <tt>SuperSum</tt>. There is no substitute for the right answer.</p>
+
+<!--
+ function grabCode_7bd084f1e3e84c86b0c419e2b2dcd8b5() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='7bd084f1e3e84c86b0c419e2b2dcd8b5 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 7bd084f1e3e84c86b0c419e2b2dcd8b5';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2024 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ -->
+<p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;">
+<br />
+<a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript>
+</span></a>
+<br />
+<br />
+ Published with MATLAB® R2024a<br />
+</p>
+
+</div>
+
+<!--
+7bd084f1e3e84c86b0c419e2b2dcd8b5 ##### SOURCE BEGIN #####
+%% SuperSum, In Defense of Floating Point Arithmetic
+% Floating point arithmetic doesn't get the respect it deserves.
+% Many people consider it mysterious, fuzzy, unpredictable.
+% These misgivings often occur in
+% discussion of vector sums. Our provocatively named
+% _SuperSum_ is intended to calm these fears.
+
+%% Ledgers
+% A _ledger_ is a list of transactions in an account.
+% _Auditing_ the ledger involves comparing the total of
+% the items with the change in the account balance.
+%
+% If _v_ is a vector of transaction amounts, then we
+% need to compute
+%
+% sum(v)
+%
+% If this sum is equal to the change in the balance, then it is
+% reasonable to assume that the ledger is correct.
+% If not, the ledger must be examined line-by-line.
+%
+%% Checksums
+% Have you ever used a checksum for a file transfer?
+% One checksum is computed before the file is sent. After the file
+% has been sent over a questionable channel, a second checksum is
+% computed on the receiving end. If the two checksums agree,
+% the transmission was probably okay. If not, the file must be
+% sent again.
+
+%% Order
+% Floating point addition is not _associative_. This means
+%
+% (a + b) + c
+%
+% is not necessarily the same as
+%
+% a + (b + c).
+%
+% So the _order_ of doing a computation is important.
+%
+% Computers are deterministic devices. If the same
+% computation is done _in the same order_ more than once,
+% the results must be the same.
+% If you get different sums from different runs on a fixed
+% computer, then it must be because the order has been
+% changed.
+
+%% Speed
+% In recent years, we have made the built-in function |sum(x)|
+% faster by parallelizing it. The input vector is broken into
+% several pieces, the sum of each piece is computed separately
+% and simultaneously, then the partial sums are combined to give
+% the final result. If the number and size of the pieces varies
+% from run to run, the order varies and consequently the computed
+% sums may vary.
+
+%% Three Sums
+% Here are three replacements for |nansum(x)|,
+% the version of |sum(x)| that skips over |NaNs| and |infs|.
+%
+% *simplesum*
+%
+% Avoid the effect of blocking in the built-in sum(x).
+%
+% function s = simplesum(x)
+% % simplesum. s = simplesum(x), for vector(x).
+% % Force sequential order for sum(x).
+% % Skips NaNs and infs.
+%
+% s = 0;
+% for k = 1:length(x)
+% if isfinite(x(k))
+% s = s + x(k);
+% end
+% end
+% end
+%
+% *KahanSum*
+%
+% This is the Kahan summation algorithm.
+% The sum is accumulated in two words, the more significant
+% |s| and the correction |c|.
+% If you were able to form |s + c| exactly, it would be more
+% accurate than |s| alone.
+%
+% function s = KahanSum(x)
+% % KahanSum. s = KahanSum(x), for vector(x).
+% % More accurate, but slower, than sum(x).
+% % Skips NaNs and infs.
+% % https://en.wikipedia.org/wiki/Kahan_summation_algorithm.
+%
+% s = 0; % sum
+% c = 0; % correction
+% for k = 1:length(x)
+% if isfinite(x(k))
+% y = x(k) - c;
+% t = s + y;
+% c = (t - s) - y;
+% s = t;
+% end
+% end
+% end
+%
+% *SuperSum*
+%
+% I gave it a pretentious name to grab attention.
+% Use extended precision, with enough digits to hold any MATLAB double.
+%
+% function s = SuperSum(x)
+% % SuperSum. s = SuperSum(x), for vector(x).
+% % Symbolic Math Toolbox extended precision.
+% % Skips NaNs and infs.
+% %
+% % 632 decimal digits holds every IEEE-754 double.
+% % 632 = ceil(log10(realmax) - log10(eps*realmin));
+% %
+% din = digits(632); % Remember current setting
+% s = double(sum(sym(x(isfinite(x)),'D')));
+% digits(din) % Restore
+% end
+
+%% Toy Example
+% A test case here at MathWorks, known by a French-Canadian name that
+% translates to "toy example", has a vector |e2|
+% of length 4243 and values that range from -3.3e7 to 6.8e9.
+%
+% When running tests involving floating point numbers
+% it is a good idea to set the output format to |hex|
+% so we can see every last bit.
+%
+% format hex
+% load jeuTest e2
+% x = e2;
+%
+% [nansum(x)
+% simplesum(x)
+% KahanSum(x)
+% SuperSum(x)]
+%
+% ans =
+% 423785e8206150e2
+% 423785e8206150e0
+% 423785e8206150e1
+% 423785e8206150e1
+%
+% For |jeuTest|, Kahan summation gets the same result as |SuperSum|,
+% while |nansum| and |simplesum| differ in the last bit or two.
+%
+
+%% Second Test
+% The vector length is only three, but the third term completely
+% cancels the first, and the second term rises from obscurity.
+% In this situation, |KahanSum| is no more accurate than |sum|.
+%
+% format hex
+% x = [1 1e-14 -1]'
+%
+% [nansum(x)
+% simplesum(x)
+% KahanSum(x)
+% SuperSum(x)]
+%
+% x =
+% 3ff0000000000000
+% 3d06849b86a12b9b
+% bff0000000000000
+%
+% ans =
+% 3d06800000000000
+% 3d06800000000000
+% 3d06800000000000
+% 3d06849b86a12b9b
+
+%% Conclusion
+% I will leave careful timing for another day. Let's just say that
+% in situations like |jeuTest|, |KahanSum| is probably all you need.
+% It is usually more accurate than |sum|, and not much slower.
+%
+% However, for complete reliability, use |SuperSum|. There is no
+% substitute for the right answer.
+##### SOURCE END ##### 7bd084f1e3e84c86b0c419e2b2dcd8b5
+-->
+
+
+
+
+ IBM Hexadecimal Floating Point
+
+ 2024-05-25T15:51:21-06:00
+ https://hpc.social/2024/ibm-hexadecimal-floating-point
+ <div class="content"><!--introduction-->
+<p>Our technical support group recently received a request for a tool that would convert IBM System/360 hexadecimal floating point numbers to the IEEE-754 format. I am probably the only one left at MathWorks that actually used IBM mainframe computers. I thought we had seen the last of hexadecimal arithmetic years ago. But, it turns out that the hexadecimal floating point format is alive and well.</p>
+
+<!--/introduction-->
+<h3>Contents</h3>
+<div>
+<ul>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#927291b6-bb83-4c85-937c-8f20844b3c74">IBM System/360</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#43cbbb43-f2f5-4415-99df-f6a6c114c912">Formats</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#5d482994-2d0d-42fa-86e2-c98bc728ebbe">Data</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#099df223-ed1e-405e-917f-0cccd1d54a26"><tt>Hex_ieee</tt></a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#126c1d80-75f5-4879-841f-de925f083fc1"><tt>ieee2ibm</tt></a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#88d3bc9c-b626-4578-872e-b95f02057e43"><tt>ibm2ieee</tt></a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#64f8c2ec-011c-40a2-a2f3-a2926ee929ac">Examples</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#41ed0fce-64bf-4471-b2c3-e22645d184f5">Comparison</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#9e4ce83f-58b7-498d-b480-9f17c5c1f6e0">Software</a>
+</li>
+</ul>
+</div>
+
+<h4>IBM System/360<a name="927291b6-bb83-4c85-937c-8f20844b3c74"></a>
+</h4>
+<p>The System/360 is a family of mainframe computers that IBM introduced in 1965 and that dominated the computer industry until PCs came along twenty years later. They range in size from desk-sized to systems that fill a large room.</p>
+
+<p>Here is a photo of a mid-sized model.</p>
+
+<p>
+<img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/ibm-360-60.png" vspace="5" /> </p>
+
+<p>
+<i>System/360, Model 60.</i> <i>Photo from Ken Shirrif's blog, IBM 360/System Summary</i>.</p>
+
+<p>The System/360 architecture is byte-oriented, so it can handle business data processing as well as scientific and engineering computation. This leads to base-16, rather than base-2 or base-10, floating point arithmetic.</p>
+
+<pre>* Binary f*2^e 1/2<=f<1
+* Decimal f*10^e 1/10<=f<1
+* Hexadecimal f*16^e 1/16<=f<1</pre>
+<h4>Formats<a name="43cbbb43-f2f5-4415-99df-f6a6c114c912"></a>
+</h4>
+<p>Floating point formats played an important role in technical computing in the early days. This table from <a href="https://www.amazon.com/exec/obidos/ASIN/0131653326/acmorg-20">FMM</a> lists formats that were in use in the 1970s, before IEEE-754 was introduced in 1985.</p>
+
+<p>
+<img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/fmm2.png" vspace="5" /> </p>
+
+<h4>Data<a name="5d482994-2d0d-42fa-86e2-c98bc728ebbe"></a>
+</h4>
+<p>The System/360 hexadecimal format is used in many industries for the preservation of data files.</p>
+
+<p>
+<a href="https://www.crewes.org/ResearchLinks/FreeSoftware">CREWES</a>. Teaching exploration seismology. Comprehensive MATLAB toolbox for use with the textbook "Numerical Methods of Exploration Seismology with algorithms in Matlab" by Gary F. Margrave, a geoscience professor at the University of Calgary.</p>
+
+<p>
+<a href="https://www.loc.gov/preservation/digital/formats/fdd/fdd000464.shtml">Library of Congress</a>. Government.</p>
+
+<p>
+<a href="https://nssdc.gsfc.nasa.gov/nssdc/formats/IBM_32-Bit.html">NASA</a>. Astronautics.</p>
+
+<p>
+<a href="https://support.sas.com/content/dam/SAS/support/en/technical-papers/record-layout-of-a-sas-version-5-or-6-data-set-in-sas-transport-xport-format.pdf">SAS</a>. Statistics and business analytics. SAS wrapers for C.</p>
+
+<p>
+<a href="https://github.com/enthought/ibm2ieee">Enthought</a>. Python wrappers for C.</p>
+
+<h4>
+<tt>Hex_ieee</tt><a name="099df223-ed1e-405e-917f-0cccd1d54a26"></a>
+</h4>
+<p> <a href="https://blogs.mathworks.com/cleve/files/Hex_ieee.m"><tt>Hex_ieee</tt></a>. I have two twenty-line MATLAB functions, <tt>ieee2ibm</tt> and <tt>ibm2ieee</tt>, that convert IEEE-754 floating point to and from IBM hexadecimal format.</p>
+
+<p>Three statements in the middle of <tt>ieee2ibm</tt> are the key to the entire operation. The first statement is</p>
+
+<pre> [~,e] = log2(x)</pre>
+<p>With two output arguments, <tt>log2</tt> returns the mantissa and exponent of an IEEE-754 floating point number. The mantissa is not needed here.</p>
+
+<p>The second key statement</p>
+
+<pre> e = ceil(e/4)</pre>
+<p>makes <tt>e</tt> divisible by 4. This turns <tt>e</tt> into the appropriate hexadecimal exponent so that the third statement</p>
+
+<pre> f = x.*16.^(-e)</pre>
+<p>can produce the hexadecimal mantissa.</p>
+
+<h4>
+<tt>ieee2ibm</tt><a name="126c1d80-75f5-4879-841f-de925f083fc1"></a>
+</h4>
+<pre>function z = ieee2ibm(x)
+ Convert IEEE-754 to IBM System 360 hexadecimal.
+ z = ieee2ibm(x)
+ Input x, real column vector.
+ Output z, length(x)-by-16 char.
+ Example: ieee2ibm(-118.625) = 'C276A00000000000'.</pre>
+<pre> s = sign(x); % -1, 0, or 1
+ x = abs(x);
+ x(x < 16^(-65)) = 0; % Underflow
+ x(x >= 16^63) = (1-eps/2)*16^63; % Overflow</pre>
+<pre> [~,e] = log2(x); % base 2 exponent
+ e = ceil(e/4) % base 16 exponent
+ f = x.*16.^(-e); % base 16 mantissa</pre>
+<pre> E = uint64((e+64)*2^56); % Assemb1e output
+ F = uint64(f*2^56);
+ S = uint64((1-s)*2^62); % 1 or 0
+ z = dec2hex(S + E + F); % z = 'ZZFFFFFFFFFFFFFF'
+end</pre>
+<h4>
+<tt>ibm2ieee</tt><a name="88d3bc9c-b626-4578-872e-b95f02057e43"></a>
+</h4>
+<pre>function x = ibm2ieee(z)
+ Convert IBM System 360 hexadecimal to IEEE-754.
+ x = ibm2ieee(z)
+ Input z, n-by-16 char.
+ Output x, n-by-1 double.
+ Example: ibm2ieee('C276A00000000000') = -118.625.</pre>
+<pre> E = hex2dec(z(:,1:2)); % Disassemble input
+ F1 = hex2dec(z(:,3:8)); % < 16^6
+ F2 = hex2dec(z(:,9:end)); % < 16^8
+ s = sign(128-E); % -1 or 1</pre>
+<pre> e = E-(s>0)*64-(s<0)*192; % base 16 exponent
+ f = F1/16^6 + F2/16^14; % base 16 mantissa
+ x = s.*f.*16.^e;
+end</pre>
+<h4>Examples<a name="64f8c2ec-011c-40a2-a2f3-a2926ee929ac"></a>
+</h4>
+<p>Underflow. Anything <tt>< 16^(-65)</tt> is too small and is flushed to zero. There are no denormals.</p>
+
+<p>Overflow. Anything <tt>>= 16^63</tt> is too large. There is no <tt>inf</tt> or <tt>NaN</tt>.</p>
+
+<pre>* 1.0 4110000000000000
+* 0.1 401999999999999A
+* -pi C13243F6A8885A30
+* 5.3976e-79 0010000000000000
+* 7.2370e+75 7FFFFFFFFFFFFFF8</pre>
+<h4>Comparison<a name="41ed0fce-64bf-4471-b2c3-e22645d184f5"></a>
+</h4>
+<p>S/360 hexadecimal has 7 exponent bits, while IEEE-754 has 11. Consequently, hexadecimal has a much smaller range, 5.4e-79 to 7.2e+75 versus 2.2e-308 to 1.8e+308.</p>
+
+<p>The base-16 normalization implies that hexadecimal effectively has between 53 and 56 mantissa bits. Counting the hidden bit, IEEE-754 also has 53. So, the accuracy of the two is pretty much the same.</p>
+
+<h4>Software<a name="9e4ce83f-58b7-498d-b480-9f17c5c1f6e0"></a>
+</h4>
+<p>My functions <tt>ieee2ibm</tt> and <tt>ieee2ibm</tt> described above, modified to handle both single and double, plus <tt>hex_test</tt>, which does what its name implies, are available at <a href="https://blogs.mathworks.com/cleve/files/Hex_ieee.m"><tt>Hex_ieee</tt></a>.</p>
+
+<p>Homework: What happens?</p>
+
+<pre>ok = 0;
+for k = 1:10
+ x = single(k/10);
+ ok(k) = hex_test(x);
+end
+ok</pre>
+<!--
+ function grabCode_54dd3908d741477c9a1ad45b553487d5() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='54dd3908d741477c9a1ad45b553487d5 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 54dd3908d741477c9a1ad45b553487d5';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2024 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ -->
+<p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;">
+<br />
+<a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript>
+</span></a>
+<br />
+<br />
+ Published with MATLAB® R2024a<br />
+</p>
+
+</div>
+
+<!--
+54dd3908d741477c9a1ad45b553487d5 ##### SOURCE BEGIN #####
+%% IBM Hexadecimal Floating Point
+% Our technical support group recently received a request
+% for a tool that would convert IBM System/360 hexadecimal
+% floating point numbers to the IEEE-754 format.
+% I am probably the only one left at MathWorks that actually used
+% IBM mainframe computers.
+% I thought we had seen the last of hexadecimal arithmetic years ago.
+% But, it turns out that the hexadecimal floating point format
+% is alive and well.
+
+%% IBM System/360
+% The System/360 is a family of mainframe computers that IBM
+% introduced in 1965 and that dominated the computer industry
+% until PCs came along twenty years later. They range in size
+% from desk-sized to systems that fill a large room.
+%
+% Here is a photo of a mid-sized model.
+%
+% <<ibm-360-60.png>>
+%
+% _System/360, Model 60._
+% _Photo from Ken Shirrif's blog, IBM 360/System Summary_.
+%
+% The System/360 architecture is byte-oriented, so it can
+% handle business
+% data processing as well as scientific and engineering computation.
+% This leads to base-16, rather than base-2 or base-10,
+% floating point arithmetic.
+%
+% * Binary f*2^e 1/2<=f<1
+% * Decimal f*10^e 1/10<=f<1
+% * Hexadecimal f*16^e 1/16<=f<1
+
+%% Formats
+% Floating point formats played an important role in
+% technical computing in the early days.
+% This table from
+% <https://www.amazon.com/exec/obidos/ASIN/0131653326/acmorg-20
+% FMM> lists formats that
+% were in use in the 1970s, before IEEE-754 was introduced in 1985.
+%
+% <<fmm2.png>>
+%
+
+%% Data
+% The System/360 hexadecimal format is used in many industries for the
+% preservation of data files.
+%
+% <https://www.crewes.org/ResearchLinks/FreeSoftware CREWES>.
+% Teaching exploration seismology.
+% Comprehensive MATLAB toolbox for use with the textbook
+% "Numerical Methods of Exploration Seismology with algorithms in Matlab"
+% by Gary F. Margrave, a geoscience professor at the University of Calgary.
+%
+% <https://www.loc.gov/preservation/digital/formats/fdd/fdd000464.shtml
+% Library of Congress>. Government.
+%
+% <https://nssdc.gsfc.nasa.gov/nssdc/formats/IBM_32-Bit.html NASA>.
+% Astronautics.
+%
+% <https://support.sas.com/content/dam/SAS/support/en/technical-papers/record-layout-of-a-sas-version-5-or-6-data-set-in-sas-transport-xport-format.pdf
+% SAS>.
+% Statistics and business analytics. SAS wrapers for C.
+%
+% <https://github.com/enthought/ibm2ieee Enthought>. Python wrappers for C.
+%
+
+%% |Hex_ieee|
+% <https://blogs.mathworks.com/cleve/files/Hex_ieee.m |Hex_ieee|>.
+% I have two twenty-line MATLAB functions, |ieee2ibm| and |ibm2ieee|,
+% that convert IEEE-754 floating point to and from IBM hexadecimal format.
+%
+% Three statements in the middle of |ieee2ibm| are the key to
+% the entire operation. The first statement is
+%
+% [~,e] = log2(x)
+%
+% With two output arguments, |log2| returns the mantissa
+% and exponent of an IEEE-754 floating point number.
+% The mantissa is not needed here.
+%
+% The second key statement
+%
+% e = ceil(e/4)
+%
+% makes |e| divisible by 4. This turns |e| into the appropriate
+% hexadecimal exponent so that the third statement
+%
+% f = x.*16.^(-e)
+%
+% can produce the hexadecimal mantissa.
+%
+
+%% |ieee2ibm|
+% function z = ieee2ibm(x)
+% Convert IEEE-754 to IBM System 360 hexadecimal.
+% z = ieee2ibm(x)
+% Input x, real column vector.
+% Output z, length(x)-by-16 char.
+% Example: ieee2ibm(-118.625) = 'C276A00000000000'.
+%
+% s = sign(x); % -1, 0, or 1
+% x = abs(x);
+% x(x < 16^(-65)) = 0; % Underflow
+% x(x >= 16^63) = (1-eps/2)*16^63; % Overflow
+%
+% [~,e] = log2(x); % base 2 exponent
+% e = ceil(e/4) % base 16 exponent
+% f = x.*16.^(-e); % base 16 mantissa
+%
+% E = uint64((e+64)*2^56); % Assemb1e output
+% F = uint64(f*2^56);
+% S = uint64((1-s)*2^62); % 1 or 0
+% z = dec2hex(S + E + F); % z = 'ZZFFFFFFFFFFFFFF'
+% end
+
+%% |ibm2ieee|
+% function x = ibm2ieee(z)
+% Convert IBM System 360 hexadecimal to IEEE-754.
+% x = ibm2ieee(z)
+% Input z, n-by-16 char.
+% Output x, n-by-1 double.
+% Example: ibm2ieee('C276A00000000000') = -118.625.
+%
+% E = hex2dec(z(:,1:2)); % Disassemble input
+% F1 = hex2dec(z(:,3:8)); % < 16^6
+% F2 = hex2dec(z(:,9:end)); % < 16^8
+% s = sign(128-E); % -1 or 1
+%
+% e = E-(s>0)*64-(s<0)*192; % base 16 exponent
+% f = F1/16^6 + F2/16^14; % base 16 mantissa
+% x = s.*f.*16.^e;
+% end
+
+%% Examples
+% Underflow. Anything |< 16^(-65)| is too small and is flushed to zero.
+% There are no denormals.
+%
+% Overflow. Anything |>= 16^63| is too large.
+% There is no |inf| or |NaN|.
+%
+% * 1.0 4110000000000000
+% * 0.1 401999999999999A
+% * -pi C13243F6A8885A30
+% * 5.3976e-79 0010000000000000
+% * 7.2370e+75 7FFFFFFFFFFFFFF8
+
+%% Comparison
+% S/360 hexadecimal has 7 exponent bits, while IEEE-754 has 11.
+% Consequently, hexadecimal has a much smaller range, 5.4e-79 to 7.2e+75
+% versus 2.2e-308 to 1.8e+308.
+%
+% The base-16 normalization implies that hexadecimal effectively has
+% between 53 and 56 mantissa bits. Counting the hidden bit,
+% IEEE-754 also has 53. So, the accuracy of the two is pretty much the
+% same.
+
+%% Software
+% My functions |ieee2ibm| and |ieee2ibm| described above,
+% modified to handle both single and double,
+% plus |hex_test|, which does what its name implies, are available at
+% <https://blogs.mathworks.com/cleve/files/Hex_ieee.m |Hex_ieee|>.
+%
+% Homework: What happens?
+%
+% ok = 0;
+% for k = 1:10
+% x = single(k/10);
+% ok(k) = hex_test(x);
+% end
+% ok
+
+
+##### SOURCE END ##### 54dd3908d741477c9a1ad45b553487d5
+-->
+
+
+
+
+ A Sixty-Year Old Program for Predicting the Future
+
+ 2024-05-19T16:55:03-06:00
+ https://hpc.social/2024/a-sixty-year-old-program-for-predicting-the-future
+ <div class="content"><!--introduction-->
+<p>The graphics in <a href="https://blogs.mathworks.com/cleve/2024/05/04/r-squared-is-bigger-better/">my post about <tt>R^2</tt></a> were produced by an updated version of a sixty-year old program involving the U.S. census. Originally, the program was based on census data from 1900 to 1960 and sought to predict the population in 1970. The software back then was written in Fortran, the predominate technical programming language a half century ago. I have updated the MATLAB version of the program so that it now uses census data from 1900 to 2020.</p>
+
+<!--/introduction-->
+<h3>Contents</h3>
+<div>
+<ul>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#e46c5c76-356a-4c77-aea9-20aae3e00d62"><tt>censusapp2024</tt></a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#80c94327-eb2c-492a-8542-388485d68adc">Risky Business</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#97d3b2b7-4a14-4003-85b6-c7f854fc8d56">Splines</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#c8daccba-8dbe-4dbf-a0c6-6bb0b66a1e38">Exponentials</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#b1af50c9-b8ea-4211-884b-79f28e12d34f">Predictions</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#acb134fb-dc9a-43cb-840b-0e7934c63e24">Conclusion</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#d945ac16-2ef7-4c75-a529-d64d03f50776">Blogs</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#c7c11668-f0eb-404b-b951-52729c417b5c">FMM</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#906b81f5-b694-47e8-9dee-fb0586a19671">Software</a>
+</li>
+</ul>
+</div>
+
+<h4>
+<tt>censusapp2024</tt><a name="e46c5c76-356a-4c77-aea9-20aae3e00d62"></a>
+</h4>
+<p>The latest version of the census application is now available at <a href="https://blogs.mathworks.com/cleve/files/censusapp_2024.m">censusapp2024</a>. Here are the data and the opening screenshot.</p>
+
+<pre class="codeinput">[t,p]=UScensus;fprintf(<span class="string">'%12d%12.3f\n'</span>,[t,p]')
+</pre>
+<pre class="codeoutput"> 1900 75.995
+ 1910 91.972
+ 1920 105.711
+ 1930 123.203
+ 1940 131.669
+ 1950 150.697
+ 1960 179.323
+ 1970 203.212
+ 1980 226.505
+ 1990 249.633
+ 2000 281.422
+ 2010 308.746
+ 2020 331.449
+</pre>
+<p>
+<img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/screenshot.png" vspace="5" /> </p>
+
+<h4>Risky Business<a name="80c94327-eb2c-492a-8542-388485d68adc"></a>
+</h4>
+<p>Today, MATLAB makes it easier to vary parameters and visualize results, but the underlying mathematical principles are unchanged:</p>
+
+<div>
+<ul>
+<li>Using polynomials to predict the future by extrapolating data is a risky business.</li>
+</ul>
+</div>
+
+<p>One new observation is added to the data every 10 years, when the United States does the decennial census. Originally there were only 7 observations; today there are 13. The program now allows you to fit the data exactly by interpolation with a polynomial of degree 12 or fit it approximately by polynomials of degree less than 12.</p>
+
+<p>Here are the least-squares fits with linear, cubic, and degree seven polynomials and the interpolating polynomial. As the polynomial degree increases, so does <tt>R^2</tt>, until <tt>R^2</tt> reaches one with the exact fit.</p>
+
+<p>Do any of these fits look like they could be used to predict future population growth?</p>
+
+<p>
+<img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/polys.png" vspace="5" /> </p>
+
+<h4>Splines<a name="97d3b2b7-4a14-4003-85b6-c7f854fc8d56"></a>
+</h4>
+<p>In addition to polynomials, you can choose interpolation by three different <a href="https://blogs.mathworks.com/cleve/2019/04/29/makima-piecewise-cubic-interpolation/">piecewise Hermite cubics</a>.</p>
+
+<div>
+<ul>
+<li>
+<tt>spline</tt> Continuous second derivate, "not-a-knot" end condition.</li>
+<li>
+<tt>pchip</tt> Continuous first derivative, strictly shape-preserving.</li>
+<li>
+<tt>makima</tt> Continuous first derivative, relaxed shape-preserving.</li>
+</ul>
+</div>
+
+<p>Since these fits interpolate the data, all their <tt>R^2</tt> values are one. But before 1900 and after 2020 these functions are cubic polynomials that are not designed for extrapolation.</p>
+
+<p>
+<img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/splines.png" vspace="5" /> </p>
+
+<h4>Exponentials<a name="c8daccba-8dbe-4dbf-a0c6-6bb0b66a1e38"></a>
+</h4>
+<p>It is also possible to do nonlinear least squares fits by an exponential, a logistic sigmoid, and an exponential of an exponetial known as the Gompertz model.</p>
+
+<div>
+<ul>
+<li>
+<tt>exponential exp(b*t+c)</tt>
+</li>
+<li>
+<tt>logistic a./(1+exp(-b*(t-c)))</tt>
+</li>
+<li>
+<tt>gompertz a*exp(-b*exp(-c*t))</tt>
+</li>
+</ul>
+</div>
+
+<p>An article by Kathleen and Even Tjørve, from the Inland Norway University of Applied Sciences in Elverum, Norway, in the journal <a href="https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0178691">PLOS ONE</a> has this to say about Gompertz. "The Gompertz model has been in use as a growth model even longer than its better known relative, the logistic model. The model, referred to at the time as the Gompertz theoretical law of mortality, was first suggested and first applied by Mr. Benjamin Gompertz in 1825. He fitted it to the relationship between increasing death rate and age, what he referred to as 'the average exhaustions of a man’s power to avoid death” or the 'portion of his remaining power to oppose destruction.' "</p>
+
+<p>
+<img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/expos.png" vspace="5" /> </p>
+
+<h4>Predictions<a name="b1af50c9-b8ea-4211-884b-79f28e12d34f"></a>
+</h4>
+<p>Which fits are suitable for predicting future population size?</p>
+
+<p>Despite their large R^2 values, polynomials of any degree are not suitable because outside of the time interval they behave like polynomials and do not provide realistic predictions.</p>
+
+<p>Splines were never intended for extrapolation.</p>
+
+<p>That leaves the exponentials. The simple exponential model grows exponentially and is not suitable. The Gompertz fit does approach a finite asymptotic limit, but the value is an astronimical <tt>a</tt> = 2101, corresponding to 2.1 $\times 10^9$ inhabitants. Hopefully, that is out of the question.</p>
+
+<p>The logistic fit has an asymptotic limit of <tt>a</tt> = 655.7. We recently passed the value of <tt>t</tt> where <tt>p(t)</tt> reaches <tt>a/2</tt>, namely <tt>c</tt> = 2018. So, the logistic model predicts that the long-term size of the U.S. population will be about twice its current value. Is that realistic? Probably not.</p>
+
+<p>
+<img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/expos_future.png" vspace="5" /> </p>
+
+<h4>Conclusion<a name="acb134fb-dc9a-43cb-840b-0e7934c63e24"></a>
+</h4>
+<p>The British statistician George Box once said, "all models are wrong, some are useful." This is true of the models of the U. S. Census that I have discussed over the past sixty years.</p>
+
+<p>Here is <tt>censusapp2024</tt> after all its buttons have been pushed. The extrapolation date is set to 2040. White noise has been added to the data. The model is a fourth-degree polynomial with an <tt>R^2</tt> = 0.99. The <tt>R^2</tt> value and the error estimates produced by <tt>errs</tt> account for errors in the data, but not in the model.</p>
+
+<p>This particular model does a lousy job of predicting even twenty years in the future. Some of the other models are better, many are worse. Hopefully, their study is worthwhile.</p>
+
+<p>
+<img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/predict.png" vspace="5" /> </p>
+
+<h4>Blogs<a name="d945ac16-2ef7-4c75-a529-d64d03f50776"></a>
+</h4>
+<p>I have made blog posts about the census before, in <a href="https://blogs.mathworks.com/cleve/2020/11/06/anticipating-official-u-s-census-for-2020">2020</a> and in <a href="https://blogs.mathworks.com/cleve/2017/01/05/fitting-and-extrapolating-us-census-data">2017</a>.</p>
+
+<h4>FMM<a name="c7c11668-f0eb-404b-b951-52729c417b5c"></a>
+</h4>
+<p>Predicting population growth is featured in <i>Computer Methods for Mathematical Computations</i>, by George Forsythe, Mike Malcolm and myself, published by Prentice-Hall in 1977. That textbook is now available from an interesting smorgasbord of sources, including <a href="https://scholar.google.com/citations?view_op=view_citation&hl=en&user=rldfxOMAAAAJ&citation_for_view=rldfxOMAAAAJ:buQ7SEKw-1sC">Google Scholar</a>, <a href="https://www.amazon.com/exec/obidos/ASIN/0131653326/acmorg-20">Amazon</a>, <a href="https://www.etsy.com/listing/1676520741/vintage-textbook-computer-methods-for">dizhasneatstuff</a>, <a href="https://www.abebooks.com/servlet/BookDetailsPL?bi=22650690419">Abe Books</a>, <a href="https://archive.org/details/computermethodsf00fors/page/18/mode/2up">Internet Archive</a>, <a href="https://www.pdas.com/fmm.html">PDAS</a>, <a href="https://search.worldcat.org/title/1150302502">WorldCat (Chinese)</a>.</p>
+
+<h4>Software<a name="906b81f5-b694-47e8-9dee-fb0586a19671"></a>
+</h4>
+<p>
+<tt>censusapp2024</tt> is available at <a href="https://blogs.mathworks.com/cleve/files/censusapp_2024.m">censusapp2024</a>.</p>
+
+<!--
+ function grabCode_02c7b1cd1f114211a874bb3dcae61323() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='02c7b1cd1f114211a874bb3dcae61323 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 02c7b1cd1f114211a874bb3dcae61323';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2024 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ -->
+<p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;">
+<br />
+<a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript>
+</span></a>
+<br />
+<br />
+ Published with MATLAB® R2024a<br />
+</p>
+
+</div>
+
+<!--
+02c7b1cd1f114211a874bb3dcae61323 ##### SOURCE BEGIN #####
+%% A Sixty-Year Old Program for Predicting the Future
+% The graphics in
+% <https://blogs.mathworks.com/cleve/2024/05/04/r-squared-is-bigger-better/
+% my post about |R^2|> were produced by an updated version of
+% a sixty-year old program involving the U.S. census.
+% Originally, the program was based on census data from 1900 to 1960
+% and sought to predict the population in 1970.
+% The software back then was written in Fortran,
+% the predominate technical programming language a half century ago.
+% I have updated the MATLAB version of the program
+% so that it now uses census data from 1900 to 2020.
+
+%% |censusapp2024|
+% The latest version of the census application is now available at
+% <https://blogs.mathworks.com/cleve/files/censusapp_2024.m
+% censusapp2024>. Here are the data and the opening screenshot.
+
+ [t,p] = UScensus; fprintf('%12d%12.3f\n',[t,p]')
+
+%%
+% <<screenshot.png>>
+
+%% Risky Business
+% Today, MATLAB makes it easier to vary parameters and visualize
+% results, but the underlying mathematical principles are unchanged:
+%
+% * Using polynomials to predict
+% the future by extrapolating data is a risky business.
+%
+% One new observation is added to the data
+% every 10 years, when the United States does the decennial census.
+% Originally there were only 7 observations; today there are 13.
+% The program now allows you to fit the data exactly by interpolation with
+% a polynomial of degree 12 or fit it approximately by
+% polynomials of degree less than 12.
+%
+% Here are the least-squares fits with linear, cubic, and degree seven
+% polynomials and the interpolating polynomial.
+% As the polynomial degree increases, so does |R^2|, until |R^2| reaches
+% one with the exact fit.
+%
+% Do any of these fits look like they could be used to predict future
+% population growth?
+%
+% <<polys.png>>
+
+%% Splines
+% In addition to polynomials, you can choose
+% interpolation by three different
+% <https://blogs.mathworks.com/cleve/2019/04/29/makima-piecewise-cubic-interpolation/
+% piecewise Hermite cubics>.
+%
+% * |spline| Continuous second derivate, "not-a-knot" end condition.
+% * |pchip| Continuous first derivative, strictly shape-preserving.
+% * |makima| Continuous first derivative, relaxed shape-preserving.
+%
+% Since these fits interpolate the data, all their |R^2| values are one.
+% But before 1900 and after 2020 these functions are cubic polynomials
+% that are not designed for extrapolation.
+%
+% <<splines.png>>
+
+%% Exponentials
+% It is also possible to do nonlinear least squares fits by an exponential,
+% a logistic sigmoid, and an exponential of an exponetial known as the
+% Gompertz model.
+%
+% * |exponential exp(b*t+c)|
+% * |logistic a./(1+exp(-b*(t-c)))|
+% * |gompertz a*exp(-b*exp(-c*t))|
+%
+% An article by Kathleen and Even Tjørve, from the
+% Inland Norway University of Applied Sciences in Elverum, Norway,
+% in the journal
+% <https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0178691
+% PLOS ONE> has this to say about Gompertz.
+% "The Gompertz model has been in use as a growth model even longer
+% than its better known relative, the logistic model. The model,
+% referred to at the time as the Gompertz theoretical law of mortality, was
+% first suggested and first applied by Mr. Benjamin Gompertz in 1825.
+% He fitted it to the relationship between increasing death rate and age,
+% what he referred to as 'the average exhaustions of a man’s power to
+% avoid death” or the 'portion of his remaining power to oppose
+% destruction.' "
+%
+% <<expos.png>>
+
+%% Predictions
+% Which fits are suitable for predicting future population size?
+%
+% Despite their large R^2 values, polynomials of any degree
+% are not suitable because outside of the time interval they behave
+% like polynomials and do not provide realistic predictions.
+%
+% Splines were never intended for extrapolation.
+%
+% That leaves the exponentials. The simple exponential model grows
+% exponentially and is not suitable. The Gompertz fit does approach
+% a finite asymptotic limit, but the value is an astronimical |a| = 2101,
+% corresponding to 2.1 $\times 10^9$ inhabitants. Hopefully, that is
+% out of the question.
+%
+% The logistic fit has an asymptotic limit of |a| = 655.7.
+% We recently passed the value of |t| where |p(t)| reaches |a/2|,
+% namely |c| = 2018. So, the logistic model predicts that
+% the long-term size of the U.S. population will be about twice its
+% current value. Is that realistic? Probably not.
+%
+% <<expos_future.png>>
+%
+
+%% Conclusion
+% The British statistician George Box once said, "all models are wrong,
+% some are useful." This is true of the models of the
+% U. S. Census that I have discussed over the past sixty years.
+%
+% Here is |censusapp2024| after all its buttons have been pushed.
+% The extrapolation date is set to 2040.
+% White noise has been added to the data.
+% The model is a fourth-degree polynomial with an |R^2| = 0.99.
+% The |R^2| value and the error estimates produced by |errs|
+% account for errors in the data, but not in the model.
+%
+% This particular model does a lousy job of predicting even twenty
+% years in the future.
+% Some of the other models are better, many are worse.
+% Hopefully, their study is worthwhile.
+%
+% <<predict.png>>
+
+%% Blogs
+% I have made blog posts about the census before, in
+% <https://blogs.mathworks.com/cleve/2020/11/06/anticipating-official-u-s-census-for-2020
+% 2020> and in
+% <https://blogs.mathworks.com/cleve/2017/01/05/fitting-and-extrapolating-us-census-data
+% 2017>.
+
+%% FMM
+% Predicting population growth is featured in
+% _Computer Methods for Mathematical Computations_,
+% by George Forsythe, Mike Malcolm and myself,
+% published by Prentice-Hall in 1977.
+% That textbook is now available from an interesting smorgasbord of
+% sources, including
+% <https://scholar.google.com/citations?view_op=view_citation&hl=en&user=rldfxOMAAAAJ&citation_for_view=rldfxOMAAAAJ:buQ7SEKw-1sC
+% Google Scholar>,
+% <https://www.amazon.com/exec/obidos/ASIN/0131653326/acmorg-20 Amazon>,
+% <https://www.etsy.com/listing/1676520741/vintage-textbook-computer-methods-for
+% dizhasneatstuff>,
+% <https://www.abebooks.com/servlet/BookDetailsPL?bi=22650690419
+% Abe Books>,
+% <https://archive.org/details/computermethodsf00fors/page/18/mode/2up
+% Internet Archive>,
+% <https://www.pdas.com/fmm.html PDAS>,
+% <https://search.worldcat.org/title/1150302502 WorldCat (Chinese)>.
+
+%% Software
+% |censusapp2024| is available at
+% <https://blogs.mathworks.com/cleve/files/censusapp_2024.m
+% censusapp2024>.
+##### SOURCE END ##### 02c7b1cd1f114211a874bb3dcae61323
+-->
+
+
+
+
+ R-squared. Is Bigger Better?
+
+ 2024-05-04T14:33:38-06:00
+ https://hpc.social/2024/r-squared-is-bigger-better-
+ <div class="content"><!--introduction-->
+<p>The <i>coefficient of determination</i>, R-squared or <tt>R^2</tt>, is a popular statistic that describes how well a regression model fits data. It measures the proportion of variation in data that is predicted by a model. However, that is <i>all</i> that <tt>R^2</tt> measures. It is <i>not</i> appropriate for any other use. For example, it does not support extrapolation beyond the domain of the data. It does not suggest that one model is preferable to another.</p>
+
+<p>I recently watched high school students participate in the final round of a national mathematical modeling competition. The teams' presentations were excellent; they were well-prepared, mathematically sophisticated, and informative. Unfortunately, many of the presentations abused <tt>R^2</tt>. It was used to compare different fits, to justify extrapolation, and to recommend public policy.</p>
+
+<p>This was not the first time that I have seen abuses of <tt>R^2</tt>. As educators and authors of mathematical software, we must do more to expose its limitations. There are dozens of pages and videos on the web describing <tt>R^2</tt>, but few of them warn about possible misuse.</p>
+
+<p>
+<tt>R^2</tt> is easily computed. If <tt>y</tt> is a vector of observations, <tt>f</tt> is a fit to the data and <tt>ybar = mean(y)</tt>, then</p>
+
+<pre> R^2 = 1 - norm(y-f)^2/norm(y-ybar)^2</pre>
+<p>If the data are centered, then <tt>ybar = 0</tt> and <tt>R^2</tt> is between zero and one.</p>
+
+<!--/introduction-->
+<p>One of my favorite examples is the United States Census. Here is the population, in millions, every ten years since 1900.</p>
+
+<pre> t p
+ ____ _______
+ 1900 75.995
+ 1910 91.972
+ 1920 105.711
+ 1930 123.203
+ 1940 131.669
+ 1950 150.697
+ 1960 179.323
+ 1970 203.212
+ 1980 226.505
+ 1990 249.633
+ 2000 281.422
+ 2010 308.746
+ 2020 331.449</pre>
+<p>There are 13 observations. So, we can do a least-squares fit by a polynomial of any degree less than 12 and can interpolate by a polynomial of degree 12. Here are four such fits and the corresponding <tt>R^2</tt> values. As the degree increases, so does <tt>R^2</tt>. Interpolation fits the data exactly and earns a perfect core.</p>
+
+<p>Which fit would you choose to predict the population in 2030, or even to estimate the population between census years?</p>
+
+<pre class="codeinput">R2_census
+</pre>
+<img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/R2_blog_01.png" vspace="5" /> <p>Thanks to Peter Perkins and Tom Lane for help with this post.</p>
+
+<!--
+ function grabCode_c876d07b32bc454d8001573d08d2f7aa() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='c876d07b32bc454d8001573d08d2f7aa ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' c876d07b32bc454d8001573d08d2f7aa';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2024 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ -->
+<p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;">
+<br />
+<a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript>
+</span></a>
+<br />
+<br />
+ Published with MATLAB® R2024a<br />
+</p>
+
+</div>
+
+<!--
+c876d07b32bc454d8001573d08d2f7aa ##### SOURCE BEGIN #####
+%% R-squared. Is Bigger Better?
+% The _coefficient of determination_, R-squared or |R^2|, is a popular
+% statistic that describes how well a regression model fits data.
+% It measures the proportion of variation in data that is
+% predicted by a model. However, that is _all_ that |R^2|
+% measures. It is _not_ appropriate for any other use. For example,
+% it does not support extrapolation beyond the domain of the data.
+% It does not suggest that one model is preferable to
+% another.
+%
+% I recently watched high school students participate in the
+% final round of a national mathematical modeling competition.
+% The teams' presentations were excellent; they were
+% well-prepared, mathematically sophisticated, and informative.
+% Unfortunately, many of the presentations abused |R^2|. It was
+% used to compare different fits, to justify extrapolation,
+% and to recommend public policy.
+%
+% This was not the first time that I have seen abuses of |R^2|.
+% As educators and authors of mathematical software, we must
+% do more to expose its limitations. There are dozens of pages
+% and videos on the web describing |R^2|, but few of them warn
+% about possible misuse.
+%
+% |R^2| is easily computed.
+% If |y| is a vector of observations, |f| is a fit to
+% the data and |ybar = mean(y)|, then
+%
+% R^2 = 1 - norm(y-f)^2/norm(y-ybar)^2
+%
+% If the data are centered, then |ybar = 0| and |R^2| is between
+% zero and one.
+
+%%
+% One of my favorite examples is the United States Census.
+% Here is the population, in millions, every ten years since 1900.
+%
+% t p
+% ____ _______
+% 1900 75.995
+% 1910 91.972
+% 1920 105.711
+% 1930 123.203
+% 1940 131.669
+% 1950 150.697
+% 1960 179.323
+% 1970 203.212
+% 1980 226.505
+% 1990 249.633
+% 2000 281.422
+% 2010 308.746
+% 2020 331.449
+%
+% There are 13 observations. So, we can do a least-squares fit
+% by a polynomial of any degree less than 12 and can
+% interpolate by a polynomial of degree 12. Here are four such
+% fits and the corresponding |R^2| values. As the degree increases,
+% so does |R^2|. Interpolation fits the data exactly and earns
+% a perfect core.
+%
+% Which fit would you choose to predict the population in 2030,
+% or even to estimate the population between census years?
+
+R2_census
+
+%%
+% Thanks to Peter Perkins and Tom Lane for help with this post.
+
+##### SOURCE END ##### c876d07b32bc454d8001573d08d2f7aa
+-->
+
+
+
+
+ Closest Pair of Points Problem
+
+ 2024-03-28T20:00:00-06:00
+ https://hpc.social/2024/closest-pair-of-points-problem
+ <div class="content"><!--introduction--><p>The Closest Pair of Points problem is a standard topic in an algorithms course today, but when I taught such a course fifty years ago, the algorithm was not yet known.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#0f62a942-c8a3-4395-8f83-9509ed1dabd0">California Dreaming</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#825b1d10-1532-4f6e-8927-6d9e45dbdb49">Closest Pair of Points</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#92c53c07-0f81-494a-91a7-c364eb3132ea"><tt>Pairs</tt></a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#05e723c3-e7a0-4091-bb97-463ac017b7e0"><tt>DivCon</tt></a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#387c9a5e-eee6-47d0-be8a-6ea3d8d95f8f"><tt>Center</tt></a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#53330f5c-f9a0-4060-ba34-e5e98e1c9ed4">Complexity</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#5d10f4df-79d5-46b8-9375-01260abdba40">Timing</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#4de823af-8e67-4218-a471-d8def3204d38">Software</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#0dc6f3e8-7d3a-4381-8d34-13514fb2cad1">References</a></li></ul></div>
+<h4>California Dreaming<a name="0f62a942-c8a3-4395-8f83-9509ed1dabd0"></a></h4><p>Imagine you are driving a car on the Harbor Freeway in southern California with typical Los Angeles traffic conditions. Among the many things you might want to know is which pair of vehicles is nearest each other.</p>
+<p>This is an instance of the Closest Pair of Points problem:</p>
+<div><ul><li>Given the location of <tt>n</tt> points in the plane, which pair of points is closest to each other?</li></ul></div>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/traffic.png" vspace="5" /> </p>
+<h4>Closest Pair of Points<a name="825b1d10-1532-4f6e-8927-6d9e45dbdb49"></a></h4><p>It is convenient to represent the points by a vector of complex values. The distance between points <tt>z(k)</tt> and <tt>z(j)</tt> is then</p>
+<pre> d = abs(z(k) - z(j))</pre><p>Here are a few points in the unit square. The closest pair is highlighted.</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/pairs.png" vspace="5" /> </p>
+<h4><tt>Pairs</tt><a name="92c53c07-0f81-494a-91a7-c364eb3132ea"></a></h4><p>The first algorithm you might think of computes the distances between all possible pairs of points and finds the minimum. This is a brute force approach that requires only a few lines of code.</p>
+<pre>function d = Pairs(z)
+ % Pairs.
+ % d = Pairs(z) is the minimum distance between any two elements
+ % of the complex vector z.</pre><pre> n = length(z);
+ d = Inf;
+ for k = 1:n
+ for j = k+1:n
+ if abs(z(k) - z(j)) < d
+ d = abs(z(k) - z(j));
+ end
+ end
+ end
+end</pre><h4><tt>DivCon</tt><a name="05e723c3-e7a0-4091-bb97-463ac017b7e0"></a></h4><p>DivCon stands for Divide and Conquer. In outline, the steps are:</p>
+<div><ul><li>Divide the set of points into two halves.</li></ul></div>
+<div><ul><li>Recursively, find the closest pair in each half.</li></ul></div>
+<div><ul><li>Consider the case when the closest pair has one point in each half.</li></ul></div>
+<div><ul><li>Terminate the recursion with sets of two or three points.</li></ul></div>
+<pre>function d = DivCon(z,sorted)
+ % DivCon.
+ % d = DivCon(z) is the minimum distance between any two elements
+ % of the complex vector z.
+ %
+ % d = DivCon(z,true) is a recursive call with ascending real(z).</pre><pre> n = length(z);
+ if n <= 3
+ d = Pairs(z);
+ else
+ if nargin < 2 || ~sorted
+ [~,p] = sort(real(z));
+ z = z(p);
+ end
+ m = floor(n/2);</pre><pre> % Left half
+ dl = DivCon(z(1:m),true)</pre><pre> % Right half
+ dr = DivCon(z(m+1:end),true);</pre><pre> % Choose
+ d = min(dl,dr);</pre><pre> % Center strip
+ ds = Center(z,d);
+ d = min(ds,d);
+ end
+end</pre><h4><tt>Center</tt><a name="387c9a5e-eee6-47d0-be8a-6ea3d8d95f8f"></a></h4><p>The delicate case involves the strip of points near the center dividing line. The width of the strip is the closest distance found in the recursion. Any closer pair with one point in each half must be in this strip.</p>
+<pre>function d = Center(z,d)
+ % Center(z,d) is used by DivCon to examine the
+ % strip of half-width d about the center point.</pre><pre> n = length(z)
+ m = floor(n/2);
+ xh = real(z(m));
+ [~,p] = sort(imag(z));
+ z = z(p);
+ s = [];
+ for i = 1:n
+ if abs(real(z(i)) - xh) < d
+ s = [s; z(i)];
+ end
+ end</pre><pre> ns = length(s);
+ for k = 1:ns
+ for j = k+1:ns
+ if (imag(s(j)) - imag(s(k))) < d && abs(s(k) - s(j)) < d
+ d = abs(s(k) - s(j));
+ end
+ end
+ end
+end</pre><h4>Complexity<a name="53330f5c-f9a0-4060-ba34-e5e98e1c9ed4"></a></h4><p>Let <tt>n</tt> be the number of points. An asymptotic execution-time complexity analysis involves <tt>n</tt> approaching infinity.</p>
+<p>It is not hard to see that the complexity of the brute force algorithm implemented in <tt>Pairs</tt> is O(<tt>n</tt>^2).</p>
+<p>There are <a href="https://www.google.com/search?q=closest+pair+of+points+(divide+and+conquer)">dozens of pages on the web</a> devoted to showing that the complexity of the divide and conquer algorithm implemented in <tt>DivCon</tt> and <tt>Center</tt> is O(<tt>n</tt>*log(<tt>n</tt>)). The best page that I have seen is the <a href="https://www.youtube.com/watch?v=6u_hWxbOc7E">YouTube video by Ling Qi</a>. The key to the analysis is showing that the inner loop in <tt>Center</tt> is executed at most 7 times for any <tt>n</tt>.</p>
+<h4>Timing<a name="5d10f4df-79d5-46b8-9375-01260abdba40"></a></h4><p>We measured the execution time of <tt>Pairs(z)</tt> and <tt>DivCon(z)</tt> for <tt>n</tt> from 1,000 to 40,000 and computed the ratios of the two times. The complexity analysis predicts that this ratio is asymptotically</p>
+<pre> O(n/log(n))</pre><p>Here are the timing results and a least square fit by <tt>n</tt>/log(<tt>n</tt>).</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/fit.png" vspace="5" /> </p>
+<h4>Software<a name="4de823af-8e67-4218-a471-d8def3204d38"></a></h4><p>A self-extracting MATLAB archive is available at <a href="https://blogs.mathworks.com/cleve/files/TestDivCon_mzip.m">https://blogs.mathworks.com/cleve/files/TestDivCon_mzip.m</a></p>
+<h4>References<a name="0dc6f3e8-7d3a-4381-8d34-13514fb2cad1"></a></h4><p>Ling Qi, IDeer7, <i>Closest Pair of Points (Divide and Conquer) Explained</i>. <a href="https://www.youtube.com/watch?v=6u_hWxbOc7E">https://www.youtube.com/watch?v=6u_hWxbOc7E</a>.</p>
+<p>Cormen, Thomas H.; Leiserson, Charles E.; Rivest, Ronald L.; Stein, Clifford. <i>Introduction to Algorithms (4th ed.)</i>. MIT Press and McGraw-Hill. ISBN 0-262-04630-X. 1312 pp.</p>
+<!--
+ function grabCode_fc0430dede624952a83439140fe547ff() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='fc0430dede624952a83439140fe547ff ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' fc0430dede624952a83439140fe547ff';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2024 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+fc0430dede624952a83439140fe547ff ##### SOURCE BEGIN #####
+%% The Closest Pair of Points Problem
+% The Closest Pair of Points problem is a standard topic in an
+% algorithms course today, but when I taught such
+% a course fifty years ago, the algorithm was not yet known.
+
+%% California Dreaming
+% Imagine you are driving a car on the Harbor Freeway in southern
+% California with typical Los Angeles traffic conditions.
+% Among the many things you might want to know is which pair of
+% vehicles is nearest each other.
+%
+% This is an instance of the Closest Pair of Points problem:
+%
+% * Given the location of |n| points in the plane, which pair of points
+% is closest to each other?
+%
+% <<traffic.png>>
+%
+%% Closest Pair of Points
+% It is convenient to represent the points by a vector of complex values.
+% The distance between points |z(k)| and |z(j)| is then
+%
+% d = abs(z(k) - z(j))
+%
+% Here are a few points in the unit square. The closest pair is
+% highlighted.
+%
+% <<pairs.png>>
+%
+
+%% |Pairs|
+% The first algorithm you might think of computes the distance
+% between all possible pairs of points and finds the minimum. This is
+% a brute force approach that requires only a few lines of code.
+%
+% function d = Pairs(z)
+% % Pairs.
+% % d = Pairs(z) is the minimum distance between any two elements
+% % of the complex vector z.
+%
+% n = length(z);
+% d = Inf;
+% for k = 1:n
+% for j = k+1:n
+% if abs(z(k) - z(j)) < d
+% d = abs(z(k) - z(j));
+% end
+% end
+% end
+% end
+
+%% |DivCon|
+% DivCon stands for Divide and Conquer. In outline, the steps are:
+%
+% * Divide the set of points into two halves.
+%
+% * Recursively, find the closest pair in each half.
+%
+% * Consider the case when the closest pair has one point in each half.
+%
+% * Terminate the recursion with sets of two or three points.
+%
+% function d = DivCon(z,sorted)
+% % DivCon.
+% % d = DivCon(z) is the minimum distance between any two elements
+% % of the complex vector z.
+% %
+% % d = DivCon(z,true) is a recursive call with ascending real(z).
+%
+% n = length(z);
+% if n <= 3
+% d = Pairs(z);
+% else
+% if nargin < 2 || ~sorted
+% [~,p] = sort(real(z));
+% z = z(p);
+% end
+% m = floor(n/2);
+%
+% % Left half
+% dl = DivCon(z(1:m),true)
+%
+% % Right half
+% dr = DivCon(z(m+1:end),true);
+%
+% % Choose
+% d = min(dl,dr);
+%
+% % Center strip
+% ds = Center(z,d);
+% d = min(ds,d);
+% end
+% end
+
+%% |Center|
+% The delicate case involves the strip of points near the
+% center dividing line. The width of the strip is the closest
+% distance found in the recursion. Any closer pair with one point
+% in each half must be in this strip.
+%
+% function d = Center(z,d)
+% % Center(z,d) is used by DivCon to examine the
+% % strip of half-width d about the center point.
+%
+% n = length(z)
+% m = floor(n/2);
+% xh = real(z(m));
+% [~,p] = sort(imag(z));
+% z = z(p);
+% s = [];
+% for i = 1:n
+% if abs(real(z(i)) - xh) < d
+% s = [s; z(i)];
+% end
+% end
+%
+% ns = length(s);
+% for k = 1:ns
+% for j = k+1:ns
+% if (imag(s(j)) - imag(s(k))) < d && abs(s(k) - s(j)) < d
+% d = abs(s(k) - s(j));
+% end
+% end
+% end
+% end
+
+%% Complexity
+% Let |n| be the number of points. An asymptotic execution-time
+% complexity analysis involves |n| approaching infinity.
+%
+% It is not hard to see that the complexity of the brute force algorithm
+% implemented in |Pairs| is O(|n|^2).
+%
+% There are
+% <https://www.google.com/search?q=closest+pair+of+points+(divide+and+conquer)
+% dozens of pages on the web> devoted to showing that the complexity
+% of the divide and conquer algorithm implemented in |DivCon| and |Center|
+% is O(|n|*log(|n|)). The best page that I have seen is the
+% <https://www.youtube.com/watch?v=6u_hWxbOc7E
+% YouTube video by Ling Qi>.
+% The key to the analysis is showing that the inner
+% loop in |Center| is executed at most 7 times for any |n|.
+%
+%% Timing
+% We measured the execution time of |Pairs(z)| and |DivCon(z)| for
+% |n| from 1,000 to 40,000 and computed the ratios of the two times.
+% The complexity analysis predicts that this ratio is asymptotically
+%
+% O(n/log(n))
+%
+% Here are the timing results and a least square fit by |n|/log(|n|).
+%
+% <<fit.png>>
+
+%% Software
+% A self-extracting MATLAB archive is available at
+% <https://blogs.mathworks.com/cleve/files/TestDivCon_mzip.m>
+
+%% References
+%
+% Ling Qi, IDeer7, _Closest Pair of Points (Divide and Conquer) Explained_.
+% <https://www.youtube.com/watch?v=6u_hWxbOc7E>.
+%
+% Cormen, Thomas H.; Leiserson, Charles E.; Rivest, Ronald L.;
+% Stein, Clifford. _Introduction to Algorithms (4th ed.)_.
+% MIT Press and McGraw-Hill. ISBN 0-262-04630-X. 1312 pp.
+##### SOURCE END ##### fc0430dede624952a83439140fe547ff
+-->
+
+
+
+
+ Twenty Years of Parallel MATLAB
+
+ 2024-03-15T18:05:58-06:00
+ https://hpc.social/2024/twenty-years-of-parallel-matlab
+ <div class="content"><!--introduction--><p>I have just returned from the MathWorks company meeting celebrating our 40th Anniversary. In one of the presentations, Jos Martin described how Parallel MATLAB was introduced almost twenty years ago. Here are a few slides from Jos's talk.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#eb526631-dc7b-4d6f-b20d-0df539aebec4">Why There Wasn't Any Parallel MATLAB</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#46778056-77d3-4a5c-b5fe-b52d97931018">Twenty-seven Parallel MATLABs</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#3df2759d-d597-4b19-9c05-c9112532cadc">Distributed Computing Toolbox</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#7c5caf72-f3b8-485b-8b12-1c06813855e0">Supercomputing Conference</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#9266c227-5e9f-4e31-9d7d-a8d89fc7b2d1">Bill Gates</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#85862059-8ccf-4c67-b17b-018619edab9f">Now There is a Parallel MATLAB</a></li></ul></div>
+<h4>Why There Wasn't Any Parallel MATLAB<a name="eb526631-dc7b-4d6f-b20d-0df539aebec4"></a></h4><p>In <i>MATLAB News and Notes</i> for spring 1995, I wrote a one-page Cleve's Corner titled "Why there isn't any parallel MATLAB." There were three reasons.</p>
+<div><ul><li>Memory model. MATLAB would generate a matrix on a host machine, split it into roughly equally sized submatrices, and distribute each submatrix to a node. But it took far longer to distribute the data then it did to do the computation. Any matrix that would fit into memory on the host was too small to make effective use of the parallel computer itself.</li></ul></div>
+<div><ul><li>Granularity. The amount of work involved in a single matrix computation is too little to be effectively parallelized.</li></ul></div>
+<div><ul><li>Business situation. There are too few potential customers at this time (1995) to undertake fundamental changes in MATLAB's architecture.</li></ul></div>
+<p>This one-page note turned out to be one of my most widely cited publications.</p>
+<p>.</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/Picture3.png" vspace="5" /> </p>
+<p>.</p>
+<h4>Twenty-seven Parallel MATLABs<a name="46778056-77d3-4a5c-b5fe-b52d97931018"></a></h4><p><a href="https://citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&doi=0b90279927d97c5e4e2ae48a07f5a44f1abe7bac">A 2001 survey by Ron Choy</a> at MIT found 27 different projects that were developing some way to run MATLAB in parallel. All of them involved a MATLAB-based host program calling a fixed library of parallel functions, written in some other language, on the workers. None of the systems were capable of running arbitrary MATLAB programs in parallel. None of them were MathWorks products.</p>
+<h4>Distributed Computing Toolbox<a name="3df2759d-d597-4b19-9c05-c9112532cadc"></a></h4><p><a href="https://www.hpcwire.com/2004/11/09/mathworks-unveils-computing-toolbox-for-matlab-and-simulink/">MathWorks introduced</a> the MATLAB Distributed Computing Toolbox in November 2004. We improvised this demo setup at our first Supercomputing Conference, SC2004 in Pittsburg,</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/SC2004.png" vspace="5" /> </p>
+<p>.</p>
+<h4>Supercomputing Conference<a name="7c5caf72-f3b8-485b-8b12-1c06813855e0"></a></h4><p>A year later, SC2005 was in Seattle and our booth featured four worker machines on a wire shelving unit purchased at a local Home Depot.</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/SC2005.png" vspace="5" /> </p>
+<p>.</p>
+<h4>Bill Gates<a name="9266c227-5e9f-4e31-9d7d-a8d89fc7b2d1"></a></h4><p>Since Seattle was his home town, Bill Gates gave the keynote talk at SC2005. He announced that Microsoft was going into High Performance Computing and used the MathWorks Distributed Computing Toolbox in his demonstration.</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/Gates.png" vspace="5" /> </p>
+<p>.</p>
+<h4>Now There is a Parallel MATLAB<a name="85862059-8ccf-4c67-b17b-018619edab9f"></a></h4><p>So, a little more than ten years after the first Cleve's Corner about parallel computing, a second Cleve's Corner in <i>News and Notes</i> was able to reverse the situation.</p>
+<p>.</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/Picture2.png" vspace="5" /> </p>
+<!--
+ function grabCode_14a73fc939e74d6a9266b6fa2deda9a3() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='14a73fc939e74d6a9266b6fa2deda9a3 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 14a73fc939e74d6a9266b6fa2deda9a3';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2024 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+14a73fc939e74d6a9266b6fa2deda9a3 ##### SOURCE BEGIN #####
+%% Twenty Years of Parallel MATLAB
+% I have just returned from the MathWorks company meeting
+% celebrating our 40th Anniversary. In one of the presentations,
+% Jos Martin described how Parallel MATLAB was introduced
+% almost twenty years ago. Here are a few slides
+% from Jos's talk.
+
+%% Why There Wasn't Any Parallel MATLAB
+% In _MATLAB News and Notes_ for spring 1995, I wrote a one-page
+% Cleve's Corner titled "Why there isn't any parallel MATLAB."
+% There were three reasons.
+%
+% * Memory model. MATLAB would generate a matrix on a host machine,
+% split it into roughly equally sized submatrices, and distribute
+% each submatrix to a node. But it took far longer to distribute
+% the data then it did to do the computation. Any matrix that would
+% fit into memory on the host was too small to make effective use
+% of the parallel computer itself.
+%
+% * Granularity. The amount of work involved in a single matrix
+% computation is too little to be effectively parallelized.
+%
+% * Business situation. There are too few potential customers
+% at this time (1995) to undertake fundamental changes in
+% MATLAB's architecture.
+%
+% This one-page note turned out to be one of my most widely cited
+% publications.
+%
+% .
+%
+% <<Picture3.png>>
+%
+% .
+%
+
+%% Twenty-seven Parallel MATLABs
+% <https://citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&doi=0b90279927d97c5e4e2ae48a07f5a44f1abe7bac
+% A 2001 survey by Ron Choy> at MIT found 27 different projects
+% that were developing some way to run MATLAB in parallel.
+% All of them involved a MATLAB-based host program calling a fixed
+% library of parallel functions, written in some other language,
+% on the workers.
+% None of the systems were capable of running arbitrary MATLAB programs
+% in parallel. None of them were MathWorks products.
+%
+
+%%% Distributed Computing Toolbox
+% <https://www.hpcwire.com/2004/11/09/mathworks-unveils-computing-toolbox-for-matlab-and-simulink/
+% MathWorks introduced>
+% the MATLAB Distributed Computing Toolbox in November 2004.
+% We improvised this demo setup at our first Supercomputing
+% Conference, SC2004 in Pittsburg,
+%
+% <<SC2004.png>>
+%
+% .
+%
+
+
+%% Supercomputing Conference
+% A year later, SC2005 was in Seattle and our booth featured four worker
+% machines on a wire shelving unit purchased at a local Home Depot.
+%
+% <<SC2005.png>>
+%
+% .
+%
+
+%% Bill Gates
+% Since Seattle was his home town, Bill Gates gave the keynote talk at
+% SC2005. He announced that Microsoft was going into High Performance
+% Computing and used the MathWorks Distributed Computing Toolbox in
+% his demonstration.
+%
+% <<Gates.png>>
+%
+% .
+%
+
+
+%% Now There is a Parallel MATLAB
+% So, a little more than ten years after the first Cleve's Corner
+% about parallel computing, a second Cleve's Corner in _News and Notes_
+% was able to reverse the situation.
+%
+% .
+%
+% <<Picture2.png>>
+%
+
+
+##### SOURCE END ##### 14a73fc939e74d6a9266b6fa2deda9a3
+-->
+
+
+
+
+ Chaotic Swinging Sticks
+
+ 2024-02-20T16:24:41-07:00
+ https://hpc.social/2024/chaotic-swinging-sticks
+ <div class="content"><!--introduction-->
+<p>
+<a href="https://swingingsticks.com">The Swinging Sticks</a> is a kinetic sculpture that exhibits chaotic motion. The device became very popular after it upstaged Tony Stark in <a href="https://www.google.com/search?q=youtube+swinging+sticks+iron+man#fpstate=ive&vld=cid:6a6186e3,vid:sbbjhNLiL3c,st:0">Iron Man 2</a>. My daughter Carolyn gave me a desktop version of Swinging Sticks for Christmas. I immediately set out to simulate it.</p>
+
+<p>
+<img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/sculpture.png" vspace="5" /> </p>
+
+<!--/introduction-->
+<h3>Contents</h3>
+<div>
+<ul>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#a9143ab6-8f3f-482e-92ee-35cf3f9190de">Chaotic Motion</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#bf97f3ad-e2a5-4421-9892-a8466b18022a">Swinging Sticks</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#3862e132-f69e-4702-85b6-6aeeb1406839">Sculpture</a>
+</li>
+<li>
+<a href="https://feeds.feedburner.com/mathworks/moler#dd331fb2-a5f9-42c6-a538-5b2cb8c9b486">Code</a>
+</li>
+</ul>
+</div>
+
+<h4>Chaotic Motion<a name="a9143ab6-8f3f-482e-92ee-35cf3f9190de"></a>
+</h4>
+<p>Chaotic motion appears random but isn't. Once the motion begins, the initial conditions together with Newton's law of motion, F = ma, determine subsequent behavior. There are no random forces. It may be difficult to predict positions, but they are well-determined, nonetheless.</p>
+
+<p>A classic example of chaotic motion is the double pendulum. One mass at end of a massless string swings about a fixed pivot, and a second mass is attached by a massless string to the first. My simulator of the classis double pendulum is available in Cleve's Lab, <a href="https://blogs.mathworks.com/cleve/2016/10/31/introducing-cleves-laboratory">swinger</a>, and a movie is available here <a href="https://blogs.mathworks.com/cleve/files/swinger.mp4">pendulum movie</a>.</p>
+
+<h4>Swinging Sticks<a name="bf97f3ad-e2a5-4421-9892-a8466b18022a"></a>
+</h4>
+<p>The swinging sticks are similar to the double pendulum. The sticks are two rods with uniformly distributed mass, different lengths and off-center pivots. The best way to view the motion is to download <a href="https://blogs.mathworks.com/cleve/files/swinging_sticks.m">this code</a> and run it in your own MATLAB. Otherwise, here in a short slow-motion animated GIF.</p>
+
+<p>
+<img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/sticks_gif.gif" vspace="5" /> </p>
+
+<p>And, here is a longer <a href="https://blogs.mathworks.com/cleve/files/sticks.mp4">Swinging Sticks Video</a>.</p>
+
+<p>The motion of the shorter of the two rods is chaotic. Here are the orbits traced by the ends of the short rod.</p>
+
+<p>
+<img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/chaos.png" vspace="5" /> </p>
+
+<h4>Sculpture<a name="3862e132-f69e-4702-85b6-6aeeb1406839"></a>
+</h4>
+<p>Swinging Sticks sculptures are available in various sizes and colors. <a href="https://swingingsticks.com">The Swinging Sticks</a>.</p>
+
+<p>Our mathematical model is of a frictionless perpetual motion machine. The real sculptures have an ingenious electromagnetic controller in the base that is claimed to run for two years on four AA batteries. Mine has been running since Christmas. An excellent <a href="https://www.youtube.com/watch?v=PWg6TG2bkFU">YouTube video</a> by Wayne Schmidt describes the controller.</p>
+
+<h4>Code<a name="dd331fb2-a5f9-42c6-a538-5b2cb8c9b486"></a>
+</h4>
+<p>
+<a href="https://blogs.mathworks.com/cleve/files/swinging_sticks.m">https://blogs.mathworks.com/cleve/files/swinging_sticks.m</a>
+</p>
+
+<!--
+ function grabCode_3007bf720ec7402cb273ace1e6e2d61e() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='3007bf720ec7402cb273ace1e6e2d61e ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 3007bf720ec7402cb273ace1e6e2d61e';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2024 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ -->
+<p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;">
+<br />
+<a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript>
+</span></a>
+<br />
+<br />
+ Published with MATLAB® R2024a<br />
+</p>
+
+</div>
+
+<!--
+3007bf720ec7402cb273ace1e6e2d61e ##### SOURCE BEGIN #####
+%% Chaotic Swinging Sticks
+% <https://swingingsticks.com
+% The Swinging Sticks> is a kinetic sculpture that exhibits chaotic motion.
+% The device became very popular after it upstaged Tony Stark in
+% <https://www.google.com/search?q=youtube+swinging+sticks+iron+man#fpstate=ive&vld=cid:6a6186e3,vid:sbbjhNLiL3c,st:0
+% Iron Man 2>.
+% My daughter Carolyn gave me a desktop version of Swinging Sticks
+% for Christmas. I immediately set out to simulate it.
+%
+% <<sculpture.png>>
+
+
+%% Chaotic Motion
+% Chaotic motion appears random but isn't. Once the motion begins, the
+% initial conditions together with Newton's law of motion, F = ma,
+% determine subsequent behavior. There are no random forces. It may be
+% difficult to predict positions, but they are well-determined,
+% nonetheless.
+%
+% A classic example of chaotic motion is the double pendulum.
+% One mass at end of a massless string swings about a fixed pivot, and
+% a second mass is attached by a massless string to the first.
+% My simulator of the classis double pendulum is available in Cleve's Lab,
+% <https://blogs.mathworks.com/cleve/2016/10/31/introducing-cleves-laboratory
+% swinger>, and a movie is available here
+% <https://blogs.mathworks.com/cleve/files/swinger.mp4 pendulum movie>.
+
+%% Swinging Sticks
+% The swinging sticks are similar to the double pendulum.
+% The sticks are two rods with uniformly distributed mass,
+% different lengths and off-center pivots.
+% The best way to view the motion is to download
+% <https://blogs.mathworks.com/cleve/files/swinging_sticks.m
+% this code> and run it in your own MATLAB.
+% Otherwise, here in a short slow-motion animated GIF.
+%
+% <<sticks_gif.gif>>
+%
+% And, here is a longer
+% <https://blogs.mathworks.com/cleve/files/sticks.mp4
+% Swinging Sticks Video>.
+%
+% The motion of the shorter of the two rods is chaotic. Here are the
+% orbits traced by the ends of the short rod.
+%
+% <<chaos.png>>
+
+
+%% Sculpture
+% Swinging Sticks sculptures are available in various sizes and
+% colors. <https://swingingsticks.com The Swinging Sticks>.
+%
+% Our mathematical model is of a frictionless perpetual motion machine.
+% The real sculptures have an ingenious electromagnetic controller in the
+% base that is claimed to run for two years on four AA batteries.
+% Mine has been running since Christmas.
+% An excellent <https://www.youtube.com/watch?v=PWg6TG2bkFU YouTube video>
+% by Wayne Schmidt describes the controller.
+
+%% Code
+% <https://blogs.mathworks.com/cleve/files/swinging_sticks.m>
+##### SOURCE END ##### 3007bf720ec7402cb273ace1e6e2d61e
+-->
+
+
+
+
+ Nick Higham (1961-2024)
+
+ 2024-01-25T16:36:37-07:00
+ https://hpc.social/2024/nick-higham-1961-2024-
+ <div class="content"><!--introduction--><p>Nick Higham passed away last Saturday. Nick was a close friend of mine and a great friend of MATLAB. I will leave it to others to describe his research and teaching, his many honors, and his service to our community, especially SIAM. I have just a few, more personal, comments.</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/nick.png" vspace="5" /> </p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#30541246-5968-4618-8d07-532c62fe2e2a">NA Digest</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#10c6af44-05e5-4256-a91f-c92e2d648323">Books</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#b0e711ae-b3d7-419b-ae0e-150ac24e7133">MATLAB</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#bc2af9b1-f993-4890-87ca-98922e77688e"><tt>gallery</tt></a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#81a97ac0-cabd-445f-9a83-2791ffc04ac4"><tt>expm</tt></a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#6b361048-1e6f-40a5-8b30-1b8f7361e4b8">Goodbye</a></li></ul></div>
+<h4>NA Digest<a name="30541246-5968-4618-8d07-532c62fe2e2a"></a></h4><p>Monday's NA Digest led off with this from Nick's wife Francoise and his brother Des.</p>
+<pre>Subject: Nick Higham (1961--2024)</pre><pre>With great sadness we report that Nick Higham, Royal Society Research
+Professor and Richardson Professor of Applied Mathematics at the
+University of Manchester, passed away on January 20, 2024, at the age
+of 62 after an 18 month struggle with a form of blood cancer. An
+obituary describing Nick's research and leadership contributions will
+appear in SIAM News in due course.</pre><pre>Francoise Tisseur and Des Higham</pre><h4>Books<a name="10c6af44-05e5-4256-a91f-c92e2d648323"></a></h4><p>Nick was an excellent writer, and an excellent writer about writing.</p>
+<p>Here are the covers of his six books.</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/book_covers.png" vspace="5" /> </p>
+<p>SIAM published five of these. Two are surveys of Nick's research on the accuracy of numeric algorithms and the computation of matrix functions. Two more, one of them coauthored with Dennis Sherwood, are guides to mathematical exposition.</p>
+<p><i>MATLAB Guide</i>, by Des and Nick Higham, is one of my favorite books about MATLAB. It is a succinct introduction for newcomers and a valuable refresher for old-timers. The third edition, published in 2017, includes chapters on object-oriented computing, parallel computing, the Symbolic Math Toolbox and other recent additions. Be sure to check out the <a href="https://nhigham.com/matlab-guide/"><i>MATLAB Guide</i> web site</a>.</p>
+<p>The only non-SIAM book pictured above is <a href="https://nhigham.com/the-princeton-companion-to-applied-mathematics/"><i>The Princeton Companion to Applied Mathematics</i></a>. It is over 1,000 pages long and features nearly 200 sections written by an <a href="https://assets.press.princeton.edu/chapters/s1_10592.pdf">international team of experts</a>. Nick is the editor-in-chief and wrote many of the sections himself.</p>
+<h4>MATLAB<a name="b0e711ae-b3d7-419b-ae0e-150ac24e7133"></a></h4><p>Here is a <a href="https://nhigham.com">Word Cloud</a> from Nick's home page. It shows the frequency of the tags for his blog and confirms his interest in MATLAB.</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/word_cloud.png" vspace="5" /> </p>
+<h4><tt>gallery</tt><a name="bc2af9b1-f993-4890-87ca-98922e77688e"></a></h4><p>Anyone interested in numerical linear algebra should also be interested in the <tt>gallery</tt> function, which is based on Nick's work. Enter</p>
+<pre class="language-matlab">>> doc gallery
+</pre><p>Scroll down to <tt>matrixname</tt> and investigate over 70 different test matrices.</p>
+<p>If you find <tt>gallery</tt> irresistible, take a look at <a href="https://nhigham.com/2021/11/09/anymatrix/"><tt>anymatrix</tt></a>, an extensible matrix collection, by Nick and Mantas Mikaitis.</p>
+<h4><tt>expm</tt><a name="81a97ac0-cabd-445f-9a83-2791ffc04ac4"></a></h4><p>This is very personal for me. Thirty or forty years ago, Charlie Van Loan and I were regarded as authorities on computing the matrix exponential, $e^{A}$. The function <tt>expm</tt> has been in MATLAB since its very beginning. Around twenty years ago, we ceded the authority title to Nick and Awad Al-Mohy. <a href="https://eprints.maths.manchester.ac.uk/1300/1/alhi09a.pdf">Their code</a> for matrix exponential is now the basis for <tt>expm</tt>.</p>
+<h4>Goodbye<a name="6b361048-1e6f-40a5-8b30-1b8f7361e4b8"></a></h4><p>Our business has lost one of its superstars. I have lost a good friend, way too soon. Goodbye Nick.</p>
+<!--
+ function grabCode_062397ce6659461698190fb5b2757714() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='062397ce6659461698190fb5b2757714 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 062397ce6659461698190fb5b2757714';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2024 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+062397ce6659461698190fb5b2757714 ##### SOURCE BEGIN #####
+%% Nick Higham (1961-2024)
+% Nick Higham passed away last Saturday. Nick was a close friend of mine
+% and a great friend of MATLAB. I will leave it to others to describe his
+% research and teaching, his many honors, and his service to our community,
+% especially SIAM. I have just a few, more personal, comments.
+%
+% <<nick.png>>
+%
+
+%% NA Digest
+%
+% Monday's NA Digest led off with this from
+% Nick's wife Francoise and his brother Des.
+%
+% Subject: Nick Higham (1961REPLACE_WITH_DASH_DASH2024)
+%
+% With great sadness we report that Nick Higham, Royal Society Research
+% Professor and Richardson Professor of Applied Mathematics at the
+% University of Manchester, passed away on January 20, 2024, at the age
+% of 62 after an 18 month struggle with a form of blood cancer. An
+% obituary describing Nick's research and leadership contributions will
+% appear in SIAM News in due course.
+%
+% Francoise Tisseur and Des Higham
+%
+
+%% Books
+% Nick was an excellent writer, and an excellent writer about writing.
+%
+% Here are the covers of his six books.
+%
+% <<book_covers.png>>
+%
+% SIAM published five of these. Two are surveys of Nick's research
+% on the accuracy of numeric algorithms and
+% the computation of matrix functions.
+% Two more, one of them coauthored with Dennis Sherwood, are
+% guides to mathematical exposition.
+%
+% _MATLAB Guide_, by Des and Nick Higham, is one of my
+% favorite books about MATLAB.
+% It is a succinct introduction for newcomers
+% and a valuable refresher for old-timers.
+% The third edition, published in 2017, includes chapters on
+% object-oriented computing, parallel computing, the Symbolic Math
+% Toolbox and other recent additions. Be sure to check out the
+% <https://nhigham.com/matlab-guide/ _MATLAB Guide_ web site>.
+%
+% The only non-SIAM book pictured above is
+% <https://nhigham.com/the-princeton-companion-to-applied-mathematics/
+% _The Princeton Companion to Applied Mathematics_>. It is over 1,000 pages long and features
+% nearly 200 sections written by an
+% <https://assets.press.princeton.edu/chapters/s1_10592.pdf
+% international team of experts>.
+% Nick is the editor-in-chief and wrote many of the sections himself.
+
+%% MATLAB
+% Here is a <https://nhigham.com Word Cloud> from
+% Nick's home page. It shows the frequency of the tags for his blog
+% and confirms his interest in MATLAB.
+%
+% <<word_cloud.png>>
+%
+
+%% |gallery|
+% Anyone interested in numerical linear algebra should also be interested
+% in the |gallery| function, which is based on Nick's work. Enter
+%
+% >> doc gallery
+%
+% Scroll down to |matrixname| and investigate over 70 different test
+% matrices.
+%
+% If you find |gallery| irresistible, take a look at
+% <https://nhigham.com/2021/11/09/anymatrix/ |anymatrix|>,
+% an extensible matrix collection, by Nick and Mantas Mikaitis.
+
+%% |expm|
+% This is very personal for me.
+% Thirty or forty years ago, Charlie Van Loan and I were regarded as
+% authorities on computing the matrix exponential, $e^{A}$.
+% The function |expm| has been in MATLAB since its very beginning.
+% Around twenty years ago, we ceded the authority title to Nick and
+% Awad Al-Mohy.
+% <https://eprints.maths.manchester.ac.uk/1300/1/alhi09a.pdf
+% Their code> for matrix exponential is now the basis for |expm|.
+
+%% Goodbye
+% Our business has lost one of its superstars.
+% I have lost a good friend, way too soon.
+% Goodbye Nick.
+
+##### SOURCE END ##### 062397ce6659461698190fb5b2757714
+-->
+
+
+
+
+ Exponential Fitting, Separable Least Squares, and Quahogs
+
+ 2024-01-12T16:35:32-07:00
+ https://hpc.social/2024/exponential-fitting-separable-least-squares-and-quahogs
+ <div class="content"><!--introduction--><p>We have been investigating a recent bug report about <tt>fitnlm</tt>, the Statistics and Machine Learning Toolbox function for robust fitting of nonlinear models.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#e8d5954f-4051-48dd-9888-3729cc8d6313">Quahogs</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#1fd80451-cc63-4160-8fcc-b1a1448c7382">Acidification</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#faab8af3-c8dd-48bf-8621-b7fa14ade2fb">Separable Least Squares</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#8afd06c3-7aca-4df8-b636-b7d660a3b6ca">Centering Data</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#b8434e53-14a6-412e-97d9-39485ad02c07">Exponential Fitting</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#e6bd554c-66fa-4ebc-b3d4-2cd14229bed0">Results</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#dd10ff5a-44a4-4ad7-9ddb-7cb103a943eb">Software</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#7e09ac26-71d6-47be-aa47-13da26bc9755">Thanks</a></li></ul></div>
+<h4>Quahogs<a name="e8d5954f-4051-48dd-9888-3729cc8d6313"></a></h4><p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/quahogs.png" vspace="5" /> </p>
+<p>The bug report comes from Greg Pelletier, an independent research scientist and biogeochemical modeler in Olympia, Washington. Greg has been studying the vulnerability of sensitive marine organisms to increases in ocean acidification. One of the most important of these organisms is <a href="https://en.wikipedia.org/wiki/Hard_clam">Mercenaria mercenaria</a>, the hard clam.</p>
+<p>Especially here in New England, hard clams are known by their traditional Native American name, <i>quahog</i>. They have a well-deserved reputation for making excellent clam chowder.</p>
+<h4>Acidification<a name="1fd80451-cc63-4160-8fcc-b1a1448c7382"></a></h4><p>We are all aware of increasing levels of carbon dioxide in the earth's atmosphere. We may not be as aware of the effect this increase has on the health of the earth's oceans. According to <a href="https://www.noaa.gov/education/resource-collections/ocean-coasts/ocean-acidification">NOAA</a>, the ocean absorbs about 30% of the atmospheric carbon dioxide.</p>
+<p>A definitive and controversial 2009 paper by Justin Ries and colleagues, then at the Woods Hole Oceanographic Institution, is "Marine calcifiers exhibit mixed responses to CO2-induced ocean acidification", <a href="https://doi.org/10.1130/G30210A.1">https://doi.org/10.1130/G30210A.1</a>. The hard clam example in Greg's bug report comes from figure 1K in the Ries et al. paper.</p>
+<p>The independent variable in experiments is the ratio of alkalinity of sea water to the concentration of dissolved inorganic carbon. The dependent variable is the calcification rate, which compares how fast the organism builds its shells to how fast the shells are dissolving.</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/Ries_et_al.png" vspace="5" /> </p>
+<h4>Separable Least Squares<a name="faab8af3-c8dd-48bf-8621-b7fa14ade2fb"></a></h4><p>The model chosen by Ries at al. is</p>
+<p>$$ y \approx \beta_1 + \beta_2 e^{\lambda t} $$</p>
+<p>where $t$ is the ratio of alkalinity to dissolved carbon and $y$ is the calcification rate. The data have only four distinct values of $t$, with several observations of $y$ at each value.</p>
+<p>The parameters $\beta_1$, $\beta_2$ and $\lambda$ are determined by least squares curve fit. This is a <i>separable least squares</i> problem. For any given value of $\lambda$, the parameters $\beta_1$ and $\beta_2$ occur linearly and the least squares solution can be obtained by MATLAB's backslash.</p>
+<p>Gene Golub and Victor Pereyra described separable least squares in 1973 and proposed solving it by a <i>variable projection algorithm</i>. Since 1973 a number of people, including Pereyra, Linda Kaufman, Fred Krogh, John Bolstadt and David Gay, have contributed to the development of a series of Fortran programs named <tt>varpro</tt>. In 2011, Dianne O'Leary and Burt Rust created a MATLAB version of <tt>varpro</tt>. Their report, <a href="https://www.cs.umd.edu/~oleary/software/varpro/">https://www.cs.umd.edu/~oleary/software/varpro/</a>, is a good background source, as well as documentation for <tt>varpro.m</tt>.</p>
+<p>I have a section on separable least squares, and an example, <tt>expfitdemo</tt>, in NCM, <a href="https://www.mathworks.com/content/dam/mathworks/mathworks-dot-com/moler/leastsquares.pdf">Numerical Computing with MATLAB</a>. I have modified <tt>expfitdemo</tt> to work on Greg's quahogs problem.</p>
+<h4>Centering Data<a name="8afd06c3-7aca-4df8-b636-b7d660a3b6ca"></a></h4><p>It turns out that the problem Greg encountered can be traced to the fact that the data are not centered. The given values of $t$ are all positive. This causes <tt>fitnlm</tt> to print a warning message and attempt to rectify the situation by changing the degrees of freedom from 22 to 23, but this only makes the situation worse. (We should take another look at the portion of <tt>fitnlm</tt> that adjusts the degrees of freedom.)</p>
+<p>It is always a good idea in curve fitting to center the data with something like</p>
+<pre> t = t - mean(t)</pre><p>The values of $y$ are already pretty well centered. Rescaling $y$ with</p>
+<pre> y = 10000*y</pre><p>makes interpretation of results easier.</p>
+<h4>Exponential Fitting<a name="b8434e53-14a6-412e-97d9-39485ad02c07"></a></h4><p>With the data centered and scaled, we have three different ways of tackling Greg's problem. All three methods agree on the results they compute.</p>
+<div><ul><li><tt>fitnlm</tt>. Treats all parameters as if they were nonlinear. Computes statistical quantities such as R-squared and RMS Error.</li></ul></div>
+<div><ul><li><tt>varpro</tt>. Venerable software history. Only one nonlinear parameter for the quahogs problem. Delivers additional statistical quantities in <tt>Regression</tt> structure.</li></ul></div>
+<div><ul><li><tt>quahogsfit</tt>. Textbook separable least squares code. Modification for the quahogs problem of <tt>expfitdemo</tt> from NCM. Only one nonlinear parameter. No statistics.</li></ul></div>
+<h4>Results<a name="e6bd554c-66fa-4ebc-b3d4-2cd14229bed0"></a></h4><div><ul><li><tt>fitnlm</tt></li></ul></div>
+<pre>Nonlinear regression model:
+ y ~ param1 + param2*exp(param3*xval)</pre><pre>Estimated Coefficients:
+ Estimate SE tStat pValue
+ ________ _______ _______ __________</pre><pre> param1 0.69536 0.1657 4.1964 0.00037344
+ param2 -0.26482 0.19909 -1.3302 0.19709
+ param3 -22.218 8.1494 -2.7263 0.012327</pre><pre>Number of observations: 25, Error degrees of freedom: 22
+Root Mean Squared Error: 0.307
+R-Squared: 0.828, Adjusted R-Squared 0.813
+F-statistic vs. constant model: 53, p-value = 3.86e-09</pre><div><ul><li><tt>varpro</tt></li></ul></div>
+<pre>Linear Parameters:
+ 0.695367 -0.264837
+Nonlinear Parameters:
+ -22.217495</pre><pre>Norm of weighted residual = 1.438935
+Norm of data vector = 3.545820
+Expected error of observations = 0.306782
+Coefficient of determination = 0.828145</pre><pre>Regression.t_ratio
+ 4.1962
+ -1.3301
+ -2.7264</pre><pre>Regression.std_param
+ 0.1657
+ 0.1991
+ 8.1490</pre><div><ul><li><tt>quahogsfit</tt></li></ul></div>
+<pre>lambda =
+ -22.2180
+condX =
+ 4.3882
+beta =
+ 0.6954
+ -0.2648
+normres =
+ 1.4389</pre><p><tt>quahogsfit</tt> produces this plot, which can be compared with figure 1K from Ries et al, reproduced above.</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/quahogsfit.png" vspace="5" /> </p>
+<h4>Software<a name="dd10ff5a-44a4-4ad7-9ddb-7cb103a943eb"></a></h4><p>The codes for this post are available here <a href="https://blogs.mathworks.com/cleve/files/quahogs_driver.m">quahogs_driver.m</a> and here <a href="https://blogs.mathworks.com/cleve/files/varpro.m">varpro.m</a>.</p>
+<h4>Thanks<a name="7e09ac26-71d6-47be-aa47-13da26bc9755"></a></h4><p>Thanks to Greg Pelletier for the bug report and to Tom Lane for his statistical expertise.</p>
+<!--
+ function grabCode_0a292e90c48540ba9ef9da619b32e8e7() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='0a292e90c48540ba9ef9da619b32e8e7 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 0a292e90c48540ba9ef9da619b32e8e7';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2024 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+0a292e90c48540ba9ef9da619b32e8e7 ##### SOURCE BEGIN #####
+%% Exponential Fitting, Separable Least Squares, and Quahogs
+% We have been investigating a recent bug report about |fitnlm|,
+% the Statistics and Machine Learning Toolbox function
+% for robust fitting of nonlinear models.
+
+%% Quahogs
+% <<quahogs.png>>
+%
+% The bug report comes from Greg Pelletier, an independent research
+% scientist and biogeochemical modeler in Olympia, Washington.
+% Greg has been studying the
+% vulnerability of sensitive marine organisms to increases in ocean
+% acidification. One of the most important of these organisms is
+% <https://en.wikipedia.org/wiki/Hard_clam Mercenaria mercenaria>,
+% the hard clam.
+%
+% Especially here in New England, hard clams are known
+% by their traditional Native American name, _quahog_.
+% They have a well-deserved reputation for making excellent
+% clam chowder.
+
+%% Acidification
+% We are all aware of increasing levels of carbon dioxide in the earth's
+% atmosphere. We may not be as aware of the effect this increase has
+% on the health of the earth's oceans. According to
+% <https://www.noaa.gov/education/resource-collections/ocean-coasts/ocean-acidification
+% NOAA>, the ocean absorbs about 30% of the atmospheric carbon dioxide.
+%
+% A definitive and controversial 2009 paper
+% by Justin Ries and colleagues,
+% then at the Woods Hole Oceanographic Institution, is
+% "Marine calcifiers exhibit mixed responses to CO2-induced ocean
+% acidification", <https://doi.org/10.1130/G30210A.1>.
+% The hard clam example in Greg's bug report comes from
+% figure 1K in the Ries et al. paper.
+%
+% The independent variable in experiments is the
+% ratio of alkalinity of sea water
+% to the concentration of dissolved inorganic carbon.
+% The dependent variable is the calcification rate, which compares
+% how fast the organism builds its shells
+% to how fast the shells are dissolving.
+%
+% <<Ries_et_al.png>>
+%
+%% Separable Least Squares
+% The model chosen by Ries at al. is
+%
+% $$ y \approx \beta_1 + \beta_2 e^{\lambda t} $$
+%
+% where $t$ is the ratio of alkalinity to dissolved carbon and $y$ is the
+% calcification rate. The data have only four distinct values of $t$, with
+% several observations of $y$ at each value.
+%
+% The parameters $\beta_1$, $\beta_2$ and $\lambda$ are determined by
+% least squares curve fit. This is a _separable least squares_ problem.
+% For any given value of $\lambda$, the parameters $\beta_1$ and $\beta_2$
+% occur linearly and the least squares solution can be obtained by
+% MATLAB's backslash.
+%
+% Gene Golub and Victor Pereyra described separable least squares in 1973
+% and proposed solving it by a _variable projection algorithm_.
+% Since 1973 a number of people, including Pereyra, Linda Kaufman,
+% Fred Krogh, John Bolstadt and David Gay, have contributed to the
+% development of a series of Fortran programs named |varpro|.
+% In 2011, Dianne O'Leary and Burt Rust created a MATLAB version of
+% |varpro|. Their report,
+% <https://www.cs.umd.edu/~oleary/software/varpro></https://www.cs.umd.edu/~oleary/software/varpro>, is a good background
+% source, as well as documentation for |varpro.m|.
+%
+% I have a section on separable least squares, and an example,
+% |expfitdemo|, in NCM,
+% <https://www.mathworks.com/content/dam/mathworks/mathworks-dot-com/moler/leastsquares.pdf
+% Numerical Computing with MATLAB>. I have modified |expfitdemo| to
+% work on Greg's quahogs problem.
+
+%% Centering Data
+% It turns out that the problem Greg encountered can be traced to the
+% fact that the data are not centered. The given values of $t$ are all
+% positive. This causes |fitnlm| to print a warning message and attempt
+% to rectify the situation by changing the degrees of freedom
+% from 22 to 23, but this only makes the situation worse.
+% (We should take another look at the portion of |fitnlm| that adjusts
+% the degrees of freedom.)
+%
+% It is always a good idea in curve fitting to center the
+% data with something like
+%
+% t = t - mean(t)
+%
+% The values of $y$ are already pretty well centered.
+% Rescaling $y$ with
+%
+% y = 10000*y
+%
+% makes interpretation of results easier.
+
+%% Exponential Fitting
+% With the data centered and scaled, we have three different
+% ways of tackling Greg's problem. All three methods
+% agree on the results they compute.
+%
+% * |fitnlm|. Treats all parameters as if they were nonlinear.
+% Computes statistical quantities such as R-squared and
+% RMS Error.
+%
+% * |varpro|. Venerable software history.
+% Only one nonlinear parameter for the quahogs problem.
+% Delivers additional statistical quantities in |Regression| structure.
+%
+% * |quahogsfit|. Textbook separable least squares code.
+% Modification for the quahogs problem of |expfitdemo| from NCM.
+% Only one nonlinear parameter. No statistics.
+%
+
+%% Results
+% * |fitnlm|
+%
+% Nonlinear regression model:
+% y ~ param1 + param2*exp(param3*xval)
+%
+% Estimated Coefficients:
+% Estimate SE tStat pValue
+% ________ _______ _______ __________
+%
+% param1 0.69536 0.1657 4.1964 0.00037344
+% param2 -0.26482 0.19909 -1.3302 0.19709
+% param3 -22.218 8.1494 -2.7263 0.012327
+%
+%
+% Number of observations: 25, Error degrees of freedom: 22
+% Root Mean Squared Error: 0.307
+% R-Squared: 0.828, Adjusted R-Squared 0.813
+% F-statistic vs. constant model: 53, p-value = 3.86e-09
+%
+% * |varpro|
+%
+% Linear Parameters:
+% 0.695367 -0.264837
+% Nonlinear Parameters:
+% -22.217495
+%
+% Norm of weighted residual = 1.438935
+% Norm of data vector = 3.545820
+% Expected error of observations = 0.306782
+% Coefficient of determination = 0.828145
+%
+% Regression.t_ratio
+% 4.1962
+% -1.3301
+% -2.7264
+%
+% Regression.std_param
+% 0.1657
+% 0.1991
+% 8.1490
+%
+% * |quahogsfit|
+%
+% lambda =
+% -22.2180
+% condX =
+% 4.3882
+% beta =
+% 0.6954
+% -0.2648
+% normres =
+% 1.4389
+%
+% |quahogsfit| produces this plot, which can be compared with
+% figure 1K from Ries et al, reproduced above.
+%
+% <<quahogsfit.png>>
+%
+
+%% Software
+% The codes for this post are available here
+% <https://blogs.mathworks.com/cleve/files/quahogs_driver.m quahogs_driver.m>
+% and here
+% <https://blogs.mathworks.com/cleve/files/varpro.m varpro.m>.
+
+%% Thanks
+% Thanks to Greg Pelletier for the bug report and
+% to Tom Lane for his statistical expertise.
+
+##### SOURCE END ##### 0a292e90c48540ba9ef9da619b32e8e7
+-->
+
+
+
+
+ Season’s Greetings
+
+ 2023-12-20T14:13:20-07:00
+ https://hpc.social/2023/season-s-greetings
+ <div class="content"><h3>Season's Greeings</h3><p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/xmas.gif" vspace="5" /> </p>
+<!--
+ function grabCode_79511e45062b40d2899d215fa871042a() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='79511e45062b40d2899d215fa871042a ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 79511e45062b40d2899d215fa871042a';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2023 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+79511e45062b40d2899d215fa871042a ##### SOURCE BEGIN #####
+%% Season's Greeings
+%
+% <<xmas.gif>>
+%
+##### SOURCE END ##### 79511e45062b40d2899d215fa871042a
+-->
+
+
+
+
+ Blog Post Number 300, Vibrating Logo
+
+ 2023-12-13T18:23:26-07:00
+ https://hpc.social/2023/blog-post-number-300-vibrating-logo
+ <div class="content"><!--introduction--><p>This is post number 300 of <i>Cleve's Corner</i> blog. The first post was on June 6, 2012, which is 600 weeks ago. So, I have averaged one post every two weeks for over a decade. The posts were more frequent in the early days and are less frequent today.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#ccc2ebb6-1c1e-46a0-b19b-455cc4058635">Vibrating Logo</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#71788969-1610-4111-83ec-1f91f974b786">Code</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#407dbfb8-a326-471c-ac13-3f5c58b66121">vibrating_logo</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#ea75a53d-1aaa-4128-b51b-46fd84380580">vibrating_logo_frame</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#355fe3db-750d-4a82-b9d9-7de0df29ee65">first frame</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#4329c90d-ee62-412f-aa5d-018a818cca4d">init_fig</a></li></ul></div>
+<h4>Vibrating Logo<a name="ccc2ebb6-1c1e-46a0-b19b-455cc4058635"></a></h4><p>For my 300-th post, I want to take another look at our MathWorks logo. Here is a modified version of one of the animations that I entered in the recent <a href="https://www.mathworks.com/matlabcentral/communitycontests/contests/6/entries">MATLAB Flipbook Mini Hack</a>.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/vibrating_logo.gif" vspace="5" /> </p>
+<pre> Vibrating Logo</pre><p>The MathWorks company logo is the solution to a partial differential equation that describes how a disturbance travels through matter. I discussed the logo in a five-part blog post in 2014. Here are links to three of those posts.</p>
+<p><a href="https://blogs.mathworks.com/cleve/2014/10/13/mathworks-logo-part-one-why-is-it-l-shaped/">Why is it L-shaped?</a>.</p>
+<p><a href="https://blogs.mathworks.com/cleve/2014/11/17/mathworks-logo-part-four-method-of-particular-solutions-generates-the-logo/">The method of particular solutions</a>.</p>
+<p><a href="https://blogs.mathworks.com/cleve/2014/12/01/mathworks-logo-part-five-evolution-of-the-logo/">How the view has evolved.</a>.</p>
+<p>One of my most-liked blog posts is by ten-year old <a href="https://blogs.mathworks.com/cleve/2021/12/23/a-new-view-of-our-logo/">Eden Rajapakse</a>.</p>
+<h4>Code<a name="71788969-1610-4111-83ec-1f91f974b786"></a></h4><p>This code is available at <a href="https://blogs.mathworks.com/cleve/files/vibrating_logo.m">vibrating_logo</a>.</p>
+<h4>vibrating_logo<a name="407dbfb8-a326-471c-ac13-3f5c58b66121"></a></h4><pre class="codeinput"><span class="keyword">function</span> vibrating_logo
+</pre><pre class="codeinput"> <span class="comment">% MathWorks logo, vibrating L-shaped membrane.</span>
+ <span class="comment">% See Cleve's Corner, Dec. 13, 2023.</span>
+ <span class="comment">% https://blogs.mathworks.com/cleve/2023/12/13/blog-post-number-300-vibrating-logo.</span>
+
+ stop = init_fig;
+ fps = 6;
+ f = 0;
+ <span class="comment">% Loop until stop is toggled.</span>
+ <span class="keyword">while</span> true
+ f = f + 1;
+ <span class="keyword">if</span> stop.Value
+ <span class="keyword">return</span>
+ <span class="keyword">end</span>
+ vibrating_logo_frame(f)
+ pause(1/fps)
+ <span class="keyword">end</span>
+</pre><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/vibes_blog_01.png" vspace="5" /> <h4>vibrating_logo_frame<a name="ea75a53d-1aaa-4128-b51b-46fd84380580"></a></h4><pre class="codeinput"> <span class="keyword">function</span> vibrating_logo_frame(f)
+ <span class="comment">%</span>
+ <span class="comment">% One frame of animation.</span>
+ <span class="keyword">if</span> f == 1
+ first_frame
+ <span class="keyword">end</span>
+ fud = get(gcf,<span class="string">'UserData'</span>);
+ [mu,L,s] = deal(fud{:});
+ t = (f-1)/fps;
+ Z = cos(mu(1)*t)*L{1} + sin(mu(2)*t)*L{2} + sin(mu(3)*t)*L{3} + <span class="keyword">...</span>
+ sin(mu(4)*t)*L{4} + sin(mu(5)*t)*L{5} + sin(mu(6)*t)*L{6};
+ s.ZData = Z;
+ <span class="keyword">end</span>
+</pre><h4>first frame<a name="355fe3db-750d-4a82-b9d9-7de0df29ee65"></a></h4><pre class="codeinput"> <span class="keyword">function</span> first_frame
+ cla
+ axis <span class="string">off</span>
+
+ <span class="comment">% First six eigenvalues.</span>
+ mu = sqrt([9.6397238445, 15.19725192, 2*pi^2, <span class="keyword">...</span>
+ 29.5214811, 31.9126360, 41.4745099]);
+
+ <span class="comment">% First six eigenfunctions.</span>
+ L{1} = 30*membrane(1,25);
+ L{2} = 2*membrane(2,25);
+ L{3} = -2*membrane(3,25);
+ L{4} = 5*membrane(4,25);
+ L{5} = -3*membrane(5,25);
+ L{6} = 4*membrane(6,25);
+
+ <span class="comment">% Surf plot with custom lighting.</span>
+ axes(<span class="string">'CameraPosition'</span>, [-193.4013 -265.1546 220.4819],<span class="keyword">...</span>
+ <span class="string">'CameraTarget'</span>,[26 26 10], <span class="keyword">...</span>
+ <span class="string">'CameraUpVector'</span>,[0 0 1], <span class="keyword">...</span>
+ <span class="string">'CameraViewAngle'</span>,9.5, <span class="keyword">...</span>
+ <span class="string">'DataAspectRatio'</span>, [1 1 .9],<span class="keyword">...</span>
+ <span class="string">'Visible'</span>,<span class="string">'off'</span>, <span class="keyword">...</span>
+ <span class="string">'XLim'</span>,[1 51], <span class="keyword">...</span>
+ <span class="string">'YLim'</span>,[1 51], <span class="keyword">...</span>
+ <span class="string">'ZLim'</span>,[-13 40]);
+ s = surface(zeros(size(L{1})), <span class="keyword">...</span>
+ <span class="string">'EdgeColor'</span>,<span class="string">'none'</span>, <span class="keyword">...</span>
+ <span class="string">'FaceColor'</span>,[0.9 0.2 0.2], <span class="keyword">...</span>
+ <span class="string">'FaceLighting'</span>,<span class="string">'phong'</span>, <span class="keyword">...</span>
+ <span class="string">'AmbientStrength'</span>,0.3, <span class="keyword">...</span>
+ <span class="string">'DiffuseStrength'</span>,0.6, <span class="keyword">...</span>
+ <span class="string">'Clipping'</span>,<span class="string">'off'</span>,<span class="keyword">...</span>
+ <span class="string">'BackFaceLighting'</span>,<span class="string">'lit'</span>, <span class="keyword">...</span>
+ <span class="string">'SpecularStrength'</span>,1.0, <span class="keyword">...</span>
+ <span class="string">'SpecularColorReflectance'</span>,1, <span class="keyword">...</span>
+ <span class="string">'SpecularExponent'</span>,7);
+ light(<span class="string">'Position'</span>,[40 100 20], <span class="keyword">...</span>
+ <span class="string">'Style'</span>,<span class="string">'local'</span>, <span class="keyword">...</span>
+ <span class="string">'Color'</span>,[0 0.8 0.8]);
+ light(<span class="string">'Position'</span>,[.5 -1 .4], <span class="keyword">...</span>
+ <span class="string">'Color'</span>,[0.8 0.8 0]);
+ set(gcf,<span class="string">'UserData'</span>,{mu,L,s})
+ <span class="keyword">end</span>
+</pre><h4>init_fig<a name="4329c90d-ee62-412f-aa5d-018a818cca4d"></a></h4><pre class="codeinput"> <span class="keyword">function</span> stop = init_fig
+ <span class="comment">% Initialize figure.</span>
+ fig = gcf;
+ fig.Color = <span class="string">'k'</span>;
+ fig.MenuBar = <span class="string">'none'</span>;
+ fig.ToolBar = <span class="string">'none'</span>;
+ fig.NumberTitle = <span class="string">'off'</span>;
+ fig.Clipping = <span class="string">'off'</span>;
+ stop = uicontrol;
+ stop.Style = <span class="string">'togglebutton'</span>;
+ stop.String = <span class="string">'X'</span>;
+ stop.FontSize = 12;
+ stop.FontWeight = <span class="string">'bold'</span>;
+ stop.Units = <span class="string">'normalized'</span>;
+ stop.Position = [.92 .92 .06 .06];
+ cla
+ shg
+ <span class="keyword">end</span>
+</pre><pre class="codeinput"><span class="keyword">end</span>
+</pre><!--
+ function grabCode_cfdea481005c456d8c4a25238f900460() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='cfdea481005c456d8c4a25238f900460 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' cfdea481005c456d8c4a25238f900460';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2023 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+cfdea481005c456d8c4a25238f900460 ##### SOURCE BEGIN #####
+%% Blog Post Number 300, Vibrating Logo
+% This is post number 300 of _Cleve's Corner_ blog.
+% The first post was on June 6, 2012, which is 600 weeks ago.
+% So, I have averaged one post every two weeks for over a decade.
+% The posts were more frequent in the early days and are less frequent
+% today.
+
+%% Vibrating Logo
+% For my 300-th post, I want to take another look at our MathWorks logo.
+% Here is a modified version of one of the animations that I entered in
+% the recent
+% <https://www.mathworks.com/matlabcentral/communitycontests/contests/6/entries
+% MATLAB Flipbook Mini Hack>.
+%
+% <<vibrating_logo.gif>>
+%
+% Vibrating Logo
+%
+
+%%
+% The MathWorks company logo is the solution to a
+% partial differential equation that describes how a disturbance travels
+% through matter. I discussed the logo in a five-part blog post in 2014.
+% Here are links to three of those posts.
+%
+% <https://blogs.mathworks.com/cleve/2014/10/13/mathworks-logo-part-one-why-is-it-l-shaped/
+% Why is it L-shaped?>.
+%
+% <https://blogs.mathworks.com/cleve/2014/11/17/mathworks-logo-part-four-method-of-particular-solutions-generates-the-logo/
+% The method of particular solutions>.
+%
+% <https://blogs.mathworks.com/cleve/2014/12/01/mathworks-logo-part-five-evolution-of-the-logo/
+% How the view has evolved.>.
+%
+% One of my most-liked blog posts is by ten-year old
+% <https://blogs.mathworks.com/cleve/2021/12/23/a-new-view-of-our-logo/
+% Eden Rajapakse>.
+
+%% Code
+% This code is available at
+% <https://blogs.mathworks.com/cleve/files/vibrating_logo.m
+% vibrating_logo>.
+
+%% vibrating_logo
+
+function vibrating_logo
+ % MathWorks logo, vibrating L-shaped membrane.
+ % See Cleve's Corner, Dec. 13, 2023.
+ % https://blogs.mathworks.com/cleve/2023/12/13/blog-post-number-300-vibrating-logo.
+
+ stop = init_fig;
+ fps = 6;
+ f = 0;
+ % Loop until stop is toggled.
+ while true
+ f = f + 1;
+ if stop.Value
+ return
+ end
+ vibrating_logo_frame(f)
+ pause(1/fps)
+ end
+
+%% vibrating_logo_frame
+
+ function vibrating_logo_frame(f)
+ %
+ % One frame of animation.
+ if f == 1
+ first_frame
+ end
+ fud = get(gcf,'UserData');
+ [mu,L,s] = deal(fud{:});
+ t = (f-1)/fps;
+ Z = cos(mu(1)*t)*L{1} + sin(mu(2)*t)*L{2} + sin(mu(3)*t)*L{3} + ...
+ sin(mu(4)*t)*L{4} + sin(mu(5)*t)*L{5} + sin(mu(6)*t)*L{6};
+ s.ZData = Z;
+ end
+
+%% first frame
+
+ function first_frame
+ cla
+ axis off
+
+ % First six eigenvalues.
+ mu = sqrt([9.6397238445, 15.19725192, 2*pi^2, ...
+ 29.5214811, 31.9126360, 41.4745099]);
+
+ % First six eigenfunctions.
+ L{1} = 30*membrane(1,25);
+ L{2} = 2*membrane(2,25);
+ L{3} = -2*membrane(3,25);
+ L{4} = 5*membrane(4,25);
+ L{5} = -3*membrane(5,25);
+ L{6} = 4*membrane(6,25);
+
+ % Surf plot with custom lighting.
+ axes('CameraPosition', [-193.4013 -265.1546 220.4819],...
+ 'CameraTarget',[26 26 10], ...
+ 'CameraUpVector',[0 0 1], ...
+ 'CameraViewAngle',9.5, ...
+ 'DataAspectRatio', [1 1 .9],...
+ 'Visible','off', ...
+ 'XLim',[1 51], ...
+ 'YLim',[1 51], ...
+ 'ZLim',[-13 40]);
+ s = surface(zeros(size(L{1})), ...
+ 'EdgeColor','none', ...
+ 'FaceColor',[0.9 0.2 0.2], ...
+ 'FaceLighting','phong', ...
+ 'AmbientStrength',0.3, ...
+ 'DiffuseStrength',0.6, ...
+ 'Clipping','off',...
+ 'BackFaceLighting','lit', ...
+ 'SpecularStrength',1.0, ...
+ 'SpecularColorReflectance',1, ...
+ 'SpecularExponent',7);
+ light('Position',[40 100 20], ...
+ 'Style','local', ...
+ 'Color',[0 0.8 0.8]);
+ light('Position',[.5 -1 .4], ...
+ 'Color',[0.8 0.8 0]);
+ set(gcf,'UserData',{mu,L,s})
+ end
+
+%% init_fig
+
+ function stop = init_fig
+ % Initialize figure.
+ fig = gcf;
+ fig.Color = 'k';
+ fig.MenuBar = 'none';
+ fig.ToolBar = 'none';
+ fig.NumberTitle = 'off';
+ fig.Clipping = 'off';
+ stop = uicontrol;
+ stop.Style = 'togglebutton';
+ stop.String = 'X';
+ stop.FontSize = 12;
+ stop.FontWeight = 'bold';
+ stop.Units = 'normalized';
+ stop.Position = [.92 .92 .06 .06];
+ cla
+ shg
+ end
+end
+##### SOURCE END ##### cfdea481005c456d8c4a25238f900460
+-->
+
+
+
+
+ Bouncing Bucky Ball at Flipbook Mini Hack
+
+ 2023-11-16T23:01:49-07:00
+ https://hpc.social/2023/bouncing-bucky-ball-at-flipbook-mini-hack
+ <div class="content"><!--introduction--><p>The 2023 <a href="https://www.mathworks.com/matlabcentral/contests/2023-matlab-mini-hack.html">MATLAB Central Flipbook Mini Hack</a> contest runs from November 6 until December 3. Over 200 entries have been submitted in the first two weeks.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#b522fbe2-47f9-4136-a6f2-1892f2cf0495">New Rules</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#bfa6df5c-89fc-46be-b4f7-64f6a1fa7c33">Gallery</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#3d0c7d73-a1e6-40a1-94ca-11bc9e0705fd">Personal Favorites</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#56cf252d-30c5-4192-b1a9-ab40e17f29c7">Bouncing Bucky Ball</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#046a72f3-6f55-49b9-8420-0a1cd4c8e5d0">Software</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#8ea0a405-6fd5-4778-966c-4ff090808b5f">Thanks</a></li></ul></div>
+<h4>New Rules<a name="b522fbe2-47f9-4136-a6f2-1892f2cf0495"></a></h4><p>This year's mini hack features short animations. The contest software runs the program you submit to make an animated GIF file with exactly 48 frames and an inner-frame delay time of 1/24 second. So, your animation will run for two seconds, then continuously repeat. If you want periodic motion, you need to be back where you started by frame 48.</p>
+<p>In previous mini hacks, programs had to be Twitter length -- at most 255 characters long. Now, the new limit is 2,000 characters. Comments and formatting blanks are not counted. Remixes and reuse of other submissions is encouraged.</p>
+<p>Participants and other viewers vote on the submissions. There are prizes like Amazon gift cards and T-shirts. MathWorkers may participate, but not win prizes.</p>
+<h4>Gallery<a name="bfa6df5c-89fc-46be-b4f7-64f6a1fa7c33"></a></h4><p>Take a look at the <a href="https://www.mathworks.com/matlabcentral/communitycontests/contests/6/entries">Gallery</a>.</p>
+<h4>Personal Favorites<a name="3d0c7d73-a1e6-40a1-94ca-11bc9e0705fd"></a></h4><p>I find the results fascinating. There are so many different creative styles, artistic talents and programming techniques. Here are a few of my personal favorites.</p>
+<p><b>Jenny Bosten</b></p>
+<p><a href="https://blogs.mathworks.com/pick/2021/10/25/jenny-bostens-art-in-the-matlab-mini-hack">Jenny Bosten</a> is a familiar name on MATLAB Central. She is a Senior Lecturer in Psychology at the University of Sussex, where she is a "visual neuroscientist specialising in colour vision." Her code for <a href="https://www.mathworks.com/matlabcentral/communitycontests/contests/6/entries/13760">Time lapse of Lake view to the West</a> shows she is also a wizard of coordinate systems and color maps.</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/bosten.gif" vspace="5" /> </p>
+<p><b>隆光 中村</b></p>
+<p>I don't know anything about this person. All I see is this name, 隆光 中村, and this ingenious code for <a href="https://www.mathworks.com/matlabcentral/communitycontests/contests/6/entries/13092">Fireworks</a>.</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/fireworks.gif" vspace="5" /> </p>
+<p><b>Ned Gulley</b></p>
+<p>Ned is the long-time MathWorker who is the architect of MATLAB Central, and who, this time, is also a prolific participant. One of his more mathematical animations is <a href="https://www.mathworks.com/matlabcentral/communitycontests/contests/6/entries/13840">Orbiting Roots</a>.</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/gulley.gif" vspace="5" /> </p>
+<p><b>Eric Ludham</b>'</p>
+<p>Eric is head of the MathWorks development team for Graphics and Charting. Contributions like this <a href="https://www.mathworks.com/matlabcentral/communitycontests/contests/6/entries/13857">Blooming Rose</a> demonstrate his artistic design talent.</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/ludham.gif" vspace="5" /> </p>
+<h4>Bouncing Bucky Ball<a name="56cf252d-30c5-4192-b1a9-ab40e17f29c7"></a></h4><p>My own contributions are not nearly as attractive as these.</p>
+<p>The 2,000 character limit is a good idea. It forced me to look critically at some old code and rewrite it to be simpler and clearer.</p>
+<p>This program for a <a href="https://www.mathworks.com/matlabcentral/communitycontests/contests/6/entries/14102">Bouncing Bucky Ball</a> uses the <tt>hgtransform</tt> object to good effect. I also think it has a nice solution to the problem facing everybody of how to retain state from one frame to the next.</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/bouncing_bucky.gif" vspace="5" /> </p>
+<h4>Software<a name="046a72f3-6f55-49b9-8420-0a1cd4c8e5d0"></a></h4><p>Here is a link to a slightly more complicated version with one <tt>togglebutton</tt> that provides a random restart capability. <a href="https://blogs.mathworks.com/cleve/files/Bouncing_Bucky.m">Bouncing_Bucky.m</a></p>
+<h4>Thanks<a name="8ea0a405-6fd5-4778-966c-4ff090808b5f"></a></h4><p>Chen Lin, David Wey and Vinay Ramesh are running the Mini Hack this year,</p>
+<!--
+ function grabCode_65f76a589bbd4188bfa9698c4a4437a7() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='65f76a589bbd4188bfa9698c4a4437a7 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 65f76a589bbd4188bfa9698c4a4437a7';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2023 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+65f76a589bbd4188bfa9698c4a4437a7 ##### SOURCE BEGIN #####
+%% Bouncing Bucky Ball at Flipbook Mini Hack
+% The 2023
+% <https://www.mathworks.com/matlabcentral/contests/2023-matlab-mini-hack.html
+% MATLAB Central Flipbook Mini Hack> contest runs
+% from November 6 until December 3. Over 200 entries have been submitted
+% in the first two weeks.
+%
+
+%% New Rules
+% This year's mini hack features short animations.
+% The contest software runs the program you submit to make an animated
+% GIF file with exactly 48 frames and an inner-frame delay time
+% of 1/24 second. So, your animation will run for two seconds, then
+% continuously repeat. If you want periodic motion, you need
+% to be back where you started by frame 48.
+%
+% In previous mini hacks, programs had to be Twitter length REPLACE_WITH_DASH_DASH
+% at most 255 characters long.
+% Now, the new limit is 2,000 characters. Comments and formatting
+% blanks are not counted. Remixes and reuse of other submissions is
+% encouraged.
+%
+% Participants and other viewers vote on the submissions. There are
+% prizes like Amazon gift cards and T-shirts. MathWorkers may
+% participate, but not win prizes.
+
+%% Gallery
+% Take a look at the
+% <https://www.mathworks.com/matlabcentral/communitycontests/contests/6/entries
+% Gallery>.
+
+%% Personal Favorites
+% I find the results fascinating. There are so many different creative
+% styles, artistic talents and programming techniques.
+% Here are a few of my personal favorites.
+%
+% *Jenny Bosten*
+%
+% <https://blogs.mathworks.com/pick/2021/10/25/jenny-bostens-art-in-the-matlab-mini-hack
+% Jenny Bosten> is a familiar name on MATLAB Central.
+% She is a Senior Lecturer in Psychology at the University of Sussex,
+% where she is a "visual neuroscientist specialising in colour vision."
+% Her code for
+% <https://www.mathworks.com/matlabcentral/communitycontests/contests/6/entries/13760
+% Time lapse of Lake view to the West>
+% shows she is also a wizard of coordinate systems and color maps.
+%
+% <<bosten.gif>>
+%
+%
+% *隆光 中村*
+%
+% I don't know anything about this person. All I see is this
+% name, 隆光 中村, and this ingenious code for
+% <https://www.mathworks.com/matlabcentral/communitycontests/contests/6/entries/13092
+% Fireworks>.
+%
+% <<fireworks.gif>>
+%
+%
+% *Ned Gulley*
+%
+% Ned is the long-time MathWorker who is the architect of MATLAB Central,
+% and who, this time, is also a prolific participant. One of his more
+% mathematical animations is
+% <https://www.mathworks.com/matlabcentral/communitycontests/contests/6/entries/13840
+% Orbiting Roots>.
+%
+% <<gulley.gif>>
+%
+%
+% *Eric Ludham*'
+%
+% Eric is head of the MathWorks development team for Graphics and Charting.
+% Contributions like this
+% <https://www.mathworks.com/matlabcentral/communitycontests/contests/6/entries/13857
+% Blooming Rose> demonstrate his artistic design talent.
+%
+% <<ludham.gif>>
+%
+%
+%% Bouncing Bucky Ball
+% My own contributions are not nearly as attractive as these.
+%
+% The 2,000 character limit is a good idea. It forced me to look
+% critically at some old code and rewrite it to be simpler and clearer.
+%
+% This program for a
+% <https://www.mathworks.com/matlabcentral/communitycontests/contests/6/entries/14102
+% Bouncing Bucky Ball> uses the |hgtransform| object to good effect.
+% I also think it has a nice solution to the problem facing everybody of
+% how to retain state from one frame to the next.
+%
+% <<bouncing_bucky.gif>>
+%
+
+%% Software
+% Here is a link to a slightly more complicated version with one
+% |togglebutton| that provides a random restart capability.
+% <https://blogs.mathworks.com/cleve/files/Bouncing_Bucky.m
+% Bouncing_Bucky.m>
+
+%% Thanks
+% Chen Lin, David Wey and Vinay Ramesh are running the Mini Hack this year,
+
+##### SOURCE END ##### 65f76a589bbd4188bfa9698c4a4437a7
+-->
+
+
+
+
+ Exploring Matrices Exercises
+
+ 2023-09-25T17:57:28-06:00
+ https://hpc.social/2023/exploring-matrices-exercises
+ <div class="content"><!--introduction--><p>Try your hand at a few exercises involving <a href="https://blogs.mathworks.com/cleve/2023/09/11/exploring-matrices">Exploring Matrices</a>.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#39c51606-0f1d-4f63-a836-a5b7b53bd13b">Qube Simplified</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#7c52cde6-70d3-4ad5-b1a1-37c5ce6e87cc">Exploring Matrices Exercises</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#72d1baf3-32a5-43fd-9ee9-d78b0756d365">Matrix Multiplication</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#5866120b-8ad5-44c6-91d4-7599fdd930ad">Rotations and Scaling</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#9ee4efdc-6cce-4067-b642-b70c3c75d2c6">Computer Graphics</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#08826629-b0f9-4a97-a3e3-655f52742c85">Matrices and Cubes</a></li></ul></div>
+<h4>Qube Simplified<a name="39c51606-0f1d-4f63-a836-a5b7b53bd13b"></a></h4><p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/Qube_simplified.png" vspace="5" /> </p>
+<p>I have simplified the <tt>Qube</tt> app by removing these four buttons.</p>
+<div><ul><li><tt>solve</tt>. The <== key now controls the unscrambling operation.</li></ul></div>
+<div><ul><li><tt>scramble</tt>. The ==> key now does six random rotations.</li></ul></div>
+<div><ul><li><tt>order</tt>. I never found a satisfactory reference for the group theory of Rubik's cube.</li></ul></div>
+<div><ul><li><tt>score</tt>. I never found a use for the nuclear norm.</li></ul></div>
+<p>Code for <tt>Qube</tt> dated 9/24/2023 is included in the <a href="https://blogs.mathworks.com/cleve/files/Apps_mzip.m">Apps mzip archive</a>.</p>
+<h4>Exploring Matrices Exercises<a name="7c52cde6-70d3-4ad5-b1a1-37c5ce6e87cc"></a></h4><p>Here are a few exercises for <a href="https://blogs.mathworks.com/cleve/2023/09/11/exploring-matrices">Exploring Matrices</a>. The answers are available at <a href="https://blogs.mathworks.com/cleve/files/ExMatAnswers.pdf">ExMatAnswers</a>.</p>
+<h4>Matrix Multiplication<a name="72d1baf3-32a5-43fd-9ee9-d78b0756d365"></a></h4><p><b>1.</b> Compute by rows, and by columns.</p>
+<p>$$
+ \left(
+ \begin{array}{rrr}
+ 8 & 1 & 6 \\
+ 3 & 5 & 7 \\
+ 4 & 9 & 2
+ \end{array}
+ \right)
+ \left(
+ \begin{array}{r}
+ 1 \\
+ 1 \\
+ 1
+ \end{array}
+ \right)
+$$</p>
+<p><b>2.</b> Solve for $z$ using inner products of rows, and using linear combinations of columns.</p>
+<p>$$
+ \left(
+ \begin{array}{rrr}
+ 1 & 2 & 3 \\
+ 4 & 5 & 6 \\
+ 7 & 8 & 9
+ \end{array}
+ \right)
+ \left(
+ \begin{array}{r}
+ 1 \\
+ z \\
+ 1
+ \end{array}
+ \right)
+ \ = \
+ \left(
+ \begin{array}{r}
+ 0 \\
+ 0 \\
+ 0
+ \end{array}
+ \right)
+$$</p>
+<p><b>3.</b> What do the <tt>m</tt>, <tt>n</tt> and <tt>p</tt> buttons on the <tt>Multiply</tt> app do? What are the other buttons and what do they do?</p>
+<p><b>4.</b> If <i>A</i> is n-by-n and <i>x</i> is n-by-1, how many multiplications are required to compute <i>A x</i> ?</p>
+<p><b>5.</b> If <i>A</i> is m-by-n and <i>B</i> is n-by-p, how many multiplications are required to compute <i>A B</i> ?</p>
+<h4>Rotations and Scaling<a name="5866120b-8ad5-44c6-91d4-7599fdd930ad"></a></h4><p><b>1.</b> What is <i>R</i>(30º)?</p>
+<p>$$
+R(\theta) \ = \
+\left(
+ \begin{array}{rr}
+ \cos{\theta} & \sin{\theta} \\
+ -\sin{\theta} & \cos{\theta}
+ \end{array}
+ \right)
+$$</p>
+<p><b>2.</b> Explain <a href="https://xkcd.com/184">https://xkcd.com/184</a>.</p>
+<p><b>3.</b> What is the value of $\theta$ ?</p>
+<p>$$
+R(\theta) \ = \
+\left(
+ \begin{array}{rr}
+ 0.8 & 0.6 \\
+ -0.6 & 0.8
+ \end{array}
+ \right)
+$$</p>
+<p><b>4.</b> What is the value of $\theta$ ?</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/theta_exer.png" vspace="5" /> </p>
+<p><b>5.</b> Edit a copy of <tt>Rotate.m</tt> and replace the house with a hand. You can use <a href="https://mathworks-my.sharepoint.com/:u:/p/moler/EVREwZQo4ZBLkDggPTky6o4BNIfckvaLQoCDdX4ICjch9A?e=dGA2Y4">my hand</a> or your own hand; see exercise 3.4 in <a href="https://www.mathworks.com/content/dam/mathworks/mathworks-dot-com/moler/interp.pdf">Numerical Computing with MATLAB</a> .</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/hand_exer.png" vspace="5" /> </p>
+<h4>Computer Graphics<a name="9ee4efdc-6cce-4067-b642-b70c3c75d2c6"></a></h4><p><b>1.</b> Show how homogeneous coordinates and matrix-vector multiplication by <tt>Tx</tt>, <tt>Ty</tt> or <tt>Tz</tt> produce translation.</p>
+<p><b>2.</b> What is the range of the rotations used by the pitch, roll, and yaw buttons on the <tt>Grafix</tt> app?</p>
+<p><b>3.</b> What color in the beacon on top of the plane? How would you change the beacon's color?</p>
+<p><b>4,</b> What is the function of the resolution and offset sliders for the teapot?</p>
+<p><b>5,</b> How many times does the bucky ball bounce off the sides of the plot window?</p>
+<h4>Matrices and Cubes<a name="08826629-b0f9-4a97-a3e3-655f52742c85"></a></h4><p><b>1.</b> What is the color of central cubelet in the Color Cube?</p>
+<p><b>2.</b> What do the "<=" , "<==" , "=>" and "==>" buttons on <tt>Qube</tt> do?</p>
+<p><b>3.</b> What is "God's Number" for a 3-by-3-by-3 Rubik's Cube? What are <tt>Q20</tt> and <tt>Q26</tt>? See <a href="https://blogs.mathworks.com/cleve/2022/09/05/rubiks-cube-superflips-and-gods-number">Cleve's Corner 2022/09/05</a>.</p>
+<p><b>4.</b> Can you restore the following scrambled cubes with fewer moves than <tt><==</tt>, the unscramble key? Use the quarter-turn metric and reset the cube with <tt>start</tt> or by clicking on <tt>stack</tt> and <tt>Q0</tt>. You might also want to set <tt>speed</tt> to 30 or 45,</p>
+<div><ul><li><tt>LRUDFB</tt></li></ul></div>
+<div><ul><li><tt>LRL'R'</tt></li></ul></div>
+<div><ul><li><tt>FLLLRB</tt></li></ul></div>
+<div><ul><li><tt>Q26</tt></li></ul></div>
+<div><ul><li>Reset the random number generator by entering <tt>rng(r)</tt> for some small integer <tt>r</tt> in the command window and then generate six random rotations with the <tt>==></tt> key.</li></ul></div>
+<!--
+ function grabCode_661f86ea0d734810b8ca2514e6ba69c9() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='661f86ea0d734810b8ca2514e6ba69c9 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 661f86ea0d734810b8ca2514e6ba69c9';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2023 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+661f86ea0d734810b8ca2514e6ba69c9 ##### SOURCE BEGIN #####
+%% Exploring Matrices Exercises
+% Try your hand at a few exercises involving
+% <https://blogs.mathworks.com/cleve/2023/09/11/exploring-matrices
+% Exploring Matrices>.
+
+%% Qube Simplified
+%
+% <<Qube_simplified.png>>
+%
+% I have simplified the |Qube| app by removing these four buttons.
+%
+% * |solve|. The <== key now controls the unscrambling
+% operation.
+%
+% * |scramble|. The ==> key now does six random rotations.
+%
+% * |order|. I never found a satisfactory reference for
+% the group theory of Rubik's cube.
+%
+% * |score|. I never found a use for the nuclear norm.
+%
+% Code for |Qube| dated 9/24/2023 is included in the
+% <https://blogs.mathworks.com/cleve/files/Apps_mzip.m
+% Apps mzip archive>.
+
+%% Exploring Matrices Exercises
+%
+% Here are a few exercises for
+% <https://blogs.mathworks.com/cleve/2023/09/11/exploring-matrices
+% Exploring Matrices>.
+% The answers are available at
+% <https://blogs.mathworks.com/cleve/files/ExMatAnswers.pdf
+% ExMatAnswers>.
+
+%% Matrix Multiplication
+%
+% *1.*
+% Compute by rows, and by columns.
+%
+% $$
+% \left(
+% \begin{array}{rrr}
+% 8 & 1 & 6 \\
+% 3 & 5 & 7 \\
+% 4 & 9 & 2
+% \end{array}
+% \right)
+% \left(
+% \begin{array}{r}
+% 1 \\
+% 1 \\
+% 1
+% \end{array}
+% \right)
+% $$
+%
+%
+% *2.*
+% Solve for $z$ using inner products of rows, and
+% using linear combinations of columns.
+%
+% $$
+% \left(
+% \begin{array}{rrr}
+% 1 & 2 & 3 \\
+% 4 & 5 & 6 \\
+% 7 & 8 & 9
+% \end{array}
+% \right)
+% \left(
+% \begin{array}{r}
+% 1 \\
+% z \\
+% 1
+% \end{array}
+% \right)
+% \ = \
+% \left(
+% \begin{array}{r}
+% 0 \\
+% 0 \\
+% 0
+% \end{array}
+% \right)
+% $$
+%
+%
+% *3.*
+% What do the |m|, |n| and |p| buttons on the |Multiply| app do?
+% What are the other buttons and what do they do?
+%
+%
+% *4.*
+% If _A_ is n-by-n and _x_ is n-by-1,
+% how many multiplications are required to compute _A x_ ?
+%
+% *5.*
+% If _A_ is m-by-n and _B_ is n-by-p,
+% how many multiplications are required to compute _A B_ ?
+
+%% Rotations and Scaling
+%
+% *1.*
+% What is _R_(30º)?
+%
+% $$
+% R(\theta) \ = \
+% \left(
+% \begin{array}{rr}
+% \cos{\theta} & \sin{\theta} \\
+% -\sin{\theta} & \cos{\theta}
+% \end{array}
+% \right)
+% $$
+%
+% *2.*
+% Explain <https://xkcd.com/184>.
+%
+% *3.*
+% What is the value of $\theta$ ?
+%
+% $$
+% R(\theta) \ = \
+% \left(
+% \begin{array}{rr}
+% 0.8 & 0.6 \\
+% -0.6 & 0.8
+% \end{array}
+% \right)
+% $$
+%
+%
+% *4.*
+% What is the value of $\theta$ ?
+%
+% <<theta_exer.png>>
+%
+%
+% *5.*
+% Edit a copy of |Rotate.m| and replace the house with a hand. You can use
+% <https://mathworks-my.sharepoint.com/:u:/p/moler/EVREwZQo4ZBLkDggPTky6o4BNIfckvaLQoCDdX4ICjch9A?e=dGA2Y4 my hand>
+% or your own hand; see exercise 3.4 in
+% <https://www.mathworks.com/content/dam/mathworks/mathworks-dot-com/moler/interp.pdf
+% Numerical Computing with MATLAB> .
+%
+% <<hand_exer.png>>
+%
+
+%% Computer Graphics
+%
+% *1.*
+% Show how homogeneous coordinates and matrix-vector multiplication by
+% |Tx|, |Ty| or |Tz| produce translation.
+%
+%
+% *2.*
+% What is the range of the rotations used by the pitch, roll, and yaw
+% buttons on the |Grafix| app?
+%
+% *3.*
+% What color in the beacon on top of the plane?
+% How would you change the beacon's color?
+%
+%
+% *4,*
+% What is the function of the resolution and offset sliders for the teapot?
+%
+%
+% *5,*
+% How many times does the bucky ball bounce off the sides of the plot
+% window?
+%
+
+
+%% Matrices and Cubes
+%
+% *1.*
+% What is the color of central cubelet in the Color Cube?
+%
+%
+% *2.*
+% What do the "<=" , "<==" , "=>" and "==>" buttons on |Qube| do?
+%
+%
+% *3.*
+% What is "God's Number" for a 3-by-3-by-3 Rubik's Cube?
+% What are |Q20| and |Q26|?
+% See <https://blogs.mathworks.com/cleve/2022/09/05/rubiks-cube-superflips-and-gods-number
+% Cleve's Corner 2022/09/05>.
+%
+%
+% *4.*
+% Can you restore the following scrambled cubes with fewer moves than |<==|,
+% the unscramble key? Use the quarter-turn metric and
+% reset the cube with |start| or by clicking on |stack| and |Q0|.
+% You might also want to set |speed| to 30 or 45,
+%
+% * |LRUDFB|
+%
+% * |LRL'R'|
+%
+% * |FLLLRB|
+%
+% * |Q26|
+%
+% * Reset the random number generator by entering |rng(r)| for some
+% small integer |r| in the command window and then generate six
+% random rotations with the |==>| key.
+
+
+##### SOURCE END ##### 661f86ea0d734810b8ca2514e6ba69c9
+-->
+
+
+
+
+ Exploring Matrices
+
+ 2023-09-12T03:11:52-06:00
+ https://hpc.social/2023/exploring-matrices
+ <div class="content"><!--introduction--><p>I have spent much of my career working to bring abstract linear algebra and practical matrix computation closer together. This project is my latest effort.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#76e7f706-3666-4329-b846-6b0ab1b75468">Alibi</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#6c62b301-b35d-4699-a60a-6dc8bd2f86c3">Exploring Matrices</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#653e3c66-3977-46c8-aef6-8ae60d87baa9">YouTube Videos</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#ea1683fd-3523-4939-8c2e-c581324ac557">Matrix Multiplication</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#254c72ed-9b08-4442-b7a5-6d4f512351ef">Rotation and Scaling</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#cef8c368-00e7-4ccb-9f05-f2435e94a403">Computer Graphics</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#eec3c339-e1b1-466c-8361-62f63808b278">Matrices and Cubes</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#873c693b-1541-41b8-b6c6-583b05562cd0">Simulink</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#e6b8796b-c1b0-4132-9038-5e5cc92f9ec2">AI and Gorillas</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#96f4d47e-9920-4215-bf7d-2bf2a3286ab9">Software</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#29bbbdbc-5d65-4ac3-a74e-1aafe0388a95">Thanks</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#6116cfa9-4ed1-4e87-b2ed-099f26839a77">Dedication</a></li></ul></div>
+<h4>Alibi<a name="76e7f706-3666-4329-b846-6b0ab1b75468"></a></h4><p>Over sixty years ago, as a sophomore contemplating a major in mathematics, I took a course entitled Survey of Modern Algebra. We used a now-classic textbook by MacLane and Birkhoff that featured abstract theorems about groups, rings, fields, vector spaces and linear algebra. I remember the colorful terms <i>alias</i> and <i>alibi</i> had something to do with change of basis and change of position, but I have never seen those terms again.</p>
+<p>The next year, I took Numerical Analysis. We did some of the homework on a Burroughhs 205 Datatron and I wrote a machine language program to solve simultaneous linear equations. I was hooked.</p>
+<p>But at the time I did not realize that the two courses were about the same magnificent object -- the <i>matrix</i>.</p>
+<h4>Exploring Matrices<a name="6c62b301-b35d-4699-a60a-6dc8bd2f86c3"></a></h4><p>Exploring Matrices is a multi-media project that shows matrices in action. Short videos, blog posts, interactive MATLAB software and self-study exercises investigate applications of matrices. The material is intended for studebts in an undergraduate course in linear algebra or computational science. However, anyone using matrices should find topics that interest them.</p>
+<p>The first release of Exploring Matrices has six modules. All of the modules feature animated MATLAB displays and four of the modules include interactive MATLAB "apps". The modules are:</p>
+<div><ul><li>Matrix Multiplication</li><li>Rotation and Scaling</li><li>Computer Graphics</li><li>Matrices and Cubes</li><li>Simulink</li><li>AI and Gorillas %</li></ul></div>
+<h4>YouTube Videos<a name="653e3c66-3977-46c8-aef6-8ae60d87baa9"></a></h4><p>An introduction and six videos ranging in length from one to six minutes, are available on YouTube at</p>
+<p><a href="https://youtube.com/playlist?list=PLn8PRpmsu08oGNmtBfFOmgVC0TlXDaLDJ">https://youtube.com/playlist?list=PLn8PRpmsu08oGNmtBfFOmgVC0TlXDaLDJ</a>.</p>
+<p>The first four of these videos feature animations produced by our four MATLAB apps -- <tt>Multiply</tt>, <tt>Rotate</tt>, <tt>Grafix</tt>, and <tt>Qube</tt>. The other two videos describe two applications, simulation of control systems and neural networks for facial recognition (of gorillas).</p>
+<h4>Matrix Multiplication<a name="ea1683fd-3523-4939-8c2e-c581324ac557"></a></h4><p>Some viewers may just be learning the mechanics of matrix multiplication. Other viewers will have encountered it years ago. The traditional algorithm for computing the product of two matrices involves inner products between the rows of the first matrix and the columns of the second. A less familiar algorithm, which involves linear combinations of the columns of the first matrix, is often more efficient and informative. The two approaches produce the same final result from intermediate terms in different orders.</p>
+<p>Here is one frame from the animation of these two algorithms generated by our <tt>Multiply</tt> app. The highlighted element in the first matrix either moves across the rows or goes down the columns.</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/Multy.png" vspace="5" /> </p>
+<h4>Rotation and Scaling<a name="254c72ed-9b08-4442-b7a5-6d4f512351ef"></a></h4><p>Our first matrices are 2-by-2. We see how the matrix</p>
+<p>$$
+R \ = \
+\left(
+ \begin{array}{rr}
+ \cos{\theta} & \sin{\theta} \\
+ -\sin{\theta} & \cos{\theta}
+ \end{array}
+ \right)
+$$</p>
+<p>rotates points by the angle $\theta$, measured in degrees.</p>
+<p>We also see how the matrix</p>
+<p>$$
+S \ = \
+\left(
+ \begin{array}{rr}
+ \sigma & 0 \\
+ 0 & \sigma
+ \end{array}
+ \right)
+\ \ \ \ \ \ \ \
+$$</p>
+<p>makes objects larger and smaller.</p>
+<p>The two can be combined with matrix multiplication. For more operations in higher dimensions, matrix multiplication provides a unifying framework.</p>
+<p>Here is one frame from the animation of rotation and scaling generated by the <tt>Rotate</tt> app. The first panel displays a 2-by-2 rotation matrix, the second panel displays a 2-by-2 diagonal scaling matrix, and the third panel displays their product.</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/Rotate.png" vspace="5" /> </p>
+<h4>Computer Graphics<a name="cef8c368-00e7-4ccb-9f05-f2435e94a403"></a></h4><p>Operations with the 4-by-4 matrices that are at the heart of modern computer graphics employ a system known as "homogeneous coordinates". The leading 3-by-3 submatrix produces rotation and scaling in three dimensions. The fourth column produces translations.</p>
+<p>Here is one frame from an animation of rotation about the x-axis generated by the <tt>Grafix</tt> app. This is often called "pitch". Rotation about the y- and z-axes are "roll" and "yaw",</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/Graphics.png" vspace="5" /> </p>
+<h4>Matrices and Cubes<a name="eec3c339-e1b1-466c-8361-62f63808b278"></a></h4><p>Rubik's Cube, named for its inventor, Ernő Rubik, a Hungarian professor of architecture, is the greatest mathematical puzzle of all time. Our digital simulation of the puzzle, <tt>Qube</tt>, is powered by rotation matrices.</p>
+<p>The model consists of 27 identical copies of a single small <i>cubelet</i> whose sides are colored red, white, blue, yellow, orange and green. Initially, all cubelets have the same orientation. A <i>move</i> is the simultaneous rotation of the nine cubelets in one of the six faces, by 90° or 180°, clockwise or counterclockwise. This leads to $4.3 \times 10^{19}$ possible configurations for a scrambled cube.</p>
+<p>The object of the puzzle is to return a scrambled cube to the initial state. Most people are interested in solving the puzzle rapidly, but I am more interested in the number of moves required.</p>
+<p><tt>Qube</tt> offers animations of many mathematical properties of Rubik's cubes. Here is a frame from one of them.</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/Qube_frame.png" vspace="5" /> </p>
+<h4>Simulink<a name="873c693b-1541-41b8-b6c6-583b05562cd0"></a></h4><p>MATLAB's companion product, Simulink, is a block diagram programming environment used to design and simulate systems with multidomain models and to automatically generate the code required to operate embedded processors.</p>
+<p>Matrices are involved in dozens of different ways by Simulink, but most users rarely see operations at that detailed level. Our Simulink module shows a model of an automobile being driven on a test track and displays the pitch, roll and yaw recorded by the matrix connecting the coordinate system for the automobile to the coordinate system for the track.</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/Simulink.png" vspace="5" /> </p>
+<h4>AI and Gorillas<a name="e6b8796b-c1b0-4132-9038-5e5cc92f9ec2"></a></h4><p>This is a personal story about a project in the early stages of development.</p>
+<p>My wife and I first visited gorillas in the Volcano National Park of Rwanda twelve years ago. An American primatologist named Dian Fossey had studied the gorillas between 1966 and her murder by poachers in 1985. Her book <i>Gorillas in the Mist</i> was very popular and was the basis for a critically acclaimed 1988 Hollywood movie starring Sigourney Weaver.</p>
+<p>We have become good friends with the people in the <a href="https://www.gorilladoctors.org/">Gorilla Doctors</a> organization. These African and American veterinarians attend to the health of the roughly 1,000 gorillas in the park. Most of the gorillas have African names like "Inkundwa" and "Maisha". We envision a gorilla facial recognition system that is available on cell phones and tablets so that new guides and doctors can learn the names of their patients.</p>
+<p>Inception-v3 is a convolutional neural network (CNN) that is widely used for image processing. We have a version of the network pretrained on more than a million images from the ImageNet database. This publicly available system knows nothing about gorillas. We must do additional training using photos of our unique subjects.</p>
+<p>This is where matrices are applied. Training a CNN involves determining the values of thousands of weights and coefficients. The digital photos, regarded as vectors, and repeatedly multiplied by circulant matrices where each row is a shifted copy of the other rows. Importantly, a modern CNN also contains some nonlinear layers.</p>
+<p>Here is one photo from a small test collection. Indundwa appears to have his own selfie stick.</p>
+<p><img alt="" hspace="5" src="https://blogs.mathworks.com/cleve/files/Gorillas.png" vspace="5" /> </p>
+<h4>Software<a name="96f4d47e-9920-4215-bf7d-2bf2a3286ab9"></a></h4><p>A self-extracting MATLAB source archive of our four apps is available at</p>
+<p><a href="https://blogs.mathworks.com/cleve/files/Apps_mzip.m">https://blogs.mathworks.com/cleve/files/Apps_mzip.m</a></p>
+<h4>Thanks<a name="29bbbdbc-5d65-4ac3-a74e-1aafe0388a95"></a></h4><p>Thanks to Jackson Kustell, Josh Bethoney and Heather Gorr from MathWorks and Jan Ramer and Mike Cranfield from Gorilla Doctors.</p>
+<h4>Dedication<a name="6116cfa9-4ed1-4e87-b2ed-099f26839a77"></a></h4><p>We dedicate the Gorillas project to the memory of <a href="https://www.marylandzoo.org/news-and-updates/2023/08/mourning-the-loss-of-dr-mike-cranfield">Mike Cranfield, DMV</a>. Mike was Executive Director of the Mountain Gorillas Veterinary Project in Rwanda from 1999 until 2014. Before Rwanda, he held various positions at the Maryland Zoo in Baltimore.</p>
+<p>Three months ago, Mike sent us a disc drive containing over 14,000 photographs of gorillas he had taken in Rwanda. We are now sorting and organizing the photos to provide specialized training of the facial recognition neural net.</p>
+<p>A month ago, Mike was hospitalized from an apparent attack of West Nile Virus. He passed away on August 27. Ironically, after years of working safely in the mountain jungles of Central Africa, it is likely that he acquired the virus from a mosquito bite at his family's cabin in Canada.</p>
+<!--
+ function grabCode_77d29507140c40a1a497777d9fd035e6() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='77d29507140c40a1a497777d9fd035e6 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 77d29507140c40a1a497777d9fd035e6';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2023 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+77d29507140c40a1a497777d9fd035e6 ##### SOURCE BEGIN #####
+%% Exploring Matrices
+% I have spent much of my career working to bring abstract linear
+% algebra and practical matrix computation closer together. This project
+% is my latest effort.
+
+%% Alibi
+% Over sixty years ago, as a sophomore contemplating a major
+% in mathematics, I took a course entitled Survey of Modern Algebra.
+% We used a now-classic textbook by MacLane and Birkhoff that featured
+% abstract theorems about groups, rings, fields, vector spaces and
+% linear algebra.
+% I remember the colorful terms _alias_ and _alibi_ had something
+% to do with change of basis and change of position, but I have never
+% seen those terms again.
+%
+% The next year, I took Numerical Analysis. We did some of the homework
+% on a Burroughhs 205 Datatron and I wrote a machine language program to
+% solve simultaneous linear equations. I was hooked.
+%
+% But at the time I did not realize that the two courses were about the
+% same magnificent object REPLACE_WITH_DASH_DASH the _matrix_.
+%
+
+%% Exploring Matrices
+% Exploring Matrices is a multi-media project that shows matrices
+% in action. Short videos, blog posts,
+% interactive MATLAB software and self-study exercises investigate
+% applications of matrices. The material is intended for studebts in an
+% undergraduate course in linear algebra or computational science.
+% However, anyone using matrices should find topics that interest them.
+%
+% The first release of Exploring Matrices has six modules.
+% All of the modules feature animated MATLAB displays and
+% four of the modules include interactive MATLAB "apps".
+% The modules are:
+%
+% * Matrix Multiplication
+% * Rotation and Scaling
+% * Computer Graphics
+% * Matrices and Cubes
+% * Simulink
+% * AI and Gorillas
+% %
+
+%% YouTube Videos
+% An introduction and six videos ranging in length from one to
+% six minutes, are available on YouTube at
+%
+% <https://youtube.com/playlist?list=PLn8PRpmsu08oGNmtBfFOmgVC0TlXDaLDJ>.
+%
+% The first four of these videos feature animations produced by our four
+% MATLAB apps REPLACE_WITH_DASH_DASH |Multiply|, |Rotate|, |Grafix|, and |Qube|.
+% The other two videos describe two applications, simulation of control
+% systems and neural networks for facial recognition (of gorillas).
+
+%% Matrix Multiplication
+% Some viewers may just be learning the mechanics of matrix multiplication.
+% Other viewers will have encountered it years ago.
+% The traditional algorithm for computing the product of two
+% matrices involves inner products between the rows of the first matrix
+% and the columns of the second. A less familiar algorithm, which
+% involves linear combinations of the columns of the first matrix,
+% is often more efficient and informative. The two approaches produce
+% the same final result from intermediate terms in different orders.
+%
+% Here is one frame from the animation of these two algorithms generated
+% by our |Multiply| app. The highlighted element in the first matrix
+% either moves across the rows or goes down the columns.
+%
+% <<Multy.png>>
+
+%% Rotation and Scaling
+% Our first matrices are 2-by-2. We see how the matrix
+%
+% $$
+% R \ = \
+% \left(
+% \begin{array}{rr}
+% \cos{\theta} & \sin{\theta} \\
+% -\sin{\theta} & \cos{\theta}
+% \end{array}
+% \right)
+% $$
+%
+% rotates points by the angle $\theta$, measured in degrees.
+%
+% We also see how the matrix
+%
+% $$
+% S \ = \
+% \left(
+% \begin{array}{rr}
+% \sigma & 0 \\
+% 0 & \sigma
+% \end{array}
+% \right)
+% \ \ \ \ \ \ \ \
+% $$
+%
+% makes objects larger and smaller.
+%
+% The two can be combined with matrix multiplication.
+% For more operations in higher dimensions, matrix multiplication
+% provides a unifying framework.
+%
+% Here is one frame from the animation of rotation and scaling generated
+% by the |Rotate| app. The first panel displays a 2-by-2 rotation
+% matrix, the second panel displays a 2-by-2 diagonal scaling matrix,
+% and the third panel displays their product.
+%
+% <<Rotate.png>>
+%
+
+%% Computer Graphics
+% Operations with the 4-by-4 matrices that are at the heart of modern
+% computer graphics employ a system known as "homogeneous coordinates".
+% The leading 3-by-3 submatrix produces rotation and scaling in
+% three dimensions. The fourth column produces translations.
+%
+% Here is one frame from an animation of rotation about the x-axis
+% generated by the |Grafix| app.
+% This is often called "pitch". Rotation about the y- and z-axes
+% are "roll" and "yaw",
+%
+% <<Graphics.png>>
+%
+
+%% Matrices and Cubes
+% Rubik's Cube, named for its inventor, Ernő Rubik, a Hungarian professor
+% of architecture, is the greatest mathematical puzzle of all time. Our
+% digital simulation of the puzzle, |Qube|, is powered by rotation
+% matrices.
+%
+% The model consists of 27 identical copies of a single small _cubelet_
+% whose sides are colored red, white, blue, yellow, orange and green.
+% Initially, all cubelets have the same orientation.
+% A _move_ is the simultaneous rotation of the nine cubelets in one of
+% the six faces, by 90° or 180°, clockwise or counterclockwise. This
+% leads to $4.3 \times 10^{19}$ possible configurations for a scrambled
+% cube.
+%
+% The object of the puzzle is to return a scrambled cube to the initial
+% state. Most people are interested in solving the puzzle rapidly,
+% but I am more interested in the number of moves required.
+%
+% |Qube| offers animations of many mathematical properties
+% of Rubik's cubes. Here is a frame from one of them.
+%
+% <<Qube_frame.png>>
+
+%% Simulink
+% MATLAB's companion product, Simulink, is a block diagram programming
+% environment used to design and simulate systems with multidomain
+% models and to automatically generate the code required to operate
+% embedded processors.
+%
+% Matrices are involved in dozens of different ways by Simulink,
+% but most users rarely see operations at that detailed level.
+% Our Simulink module shows a model of an automobile being driven
+% on a test track and displays the pitch, roll and yaw recorded by
+% the matrix connecting the coordinate system for the automobile to
+% the coordinate system for the track.
+%
+% <<Simulink.png>>
+
+%% AI and Gorillas
+% This is a personal story about a project in the early stages of
+% development.
+%
+% My wife and I first visited gorillas
+% in the Volcano National Park of Rwanda twelve years ago.
+% An American primatologist named Dian Fossey had studied the gorillas
+% between 1966 and her murder by poachers in 1985.
+% Her book _Gorillas in the Mist_ was very popular and was the basis
+% for a critically acclaimed 1988 Hollywood movie starring
+% Sigourney Weaver.
+%
+% We have become good friends with the people in the
+% <https://www.gorilladoctors.org/ Gorilla Doctors> organization.
+% These African and American veterinarians attend to the health of the
+% roughly 1,000 gorillas in the park. Most of the gorillas have
+% African names like "Inkundwa" and "Maisha". We envision a
+% gorilla facial recognition system that is available on
+% cell phones and tablets so that new guides and doctors can learn
+% the names of their patients.
+%
+% Inception-v3 is a convolutional neural network (CNN) that is widely
+% used for image processing. We have a version of the network
+% pretrained on more than a million images from the ImageNet database.
+% This publicly available system knows nothing about gorillas.
+% We must do additional training using photos of our unique subjects.
+%
+% This is where matrices are applied. Training a CNN involves determining
+% the values of thousands of weights and coefficients. The digital photos,
+% regarded as vectors, and repeatedly multiplied by circulant matrices
+% where each row is a shifted copy of the other rows. Importantly,
+% a modern CNN also contains some nonlinear layers.
+%
+% Here is one photo from a small test collection. Indundwa appears
+% to have his own selfie stick.
+%
+% <<Gorillas.png>>
+
+%% Software
+% A self-extracting MATLAB source archive of our four apps is available at
+%
+% <https://blogs.mathworks.com/cleve/files/Apps_mzip.m>
+%
+
+%% Thanks
+% Thanks to Jackson Kustell, Josh Bethoney and Heather Gorr from MathWorks
+% and Jan Ramer and Mike Cranfield from Gorilla Doctors.
+
+%% Dedication
+% We dedicate the Gorillas project to the memory of
+% <https://www.marylandzoo.org/news-and-updates/2023/08/mourning-the-loss-of-dr-mike-cranfield
+% Mike Cranfield, DMV>. Mike was Executive Director of the Mountain Gorillas
+% Veterinary Project in Rwanda from 1999 until 2014. Before Rwanda,
+% he held various positions at the Maryland Zoo in Baltimore.
+%
+% Three months ago, Mike sent us a disc drive containing over 14,000
+% photographs of gorillas he had taken in Rwanda. We are now
+% sorting and organizing the photos to provide specialized training
+% of the facial recognition neural net.
+%
+% A month ago, Mike was hospitalized from an apparent attack of West Nile
+% Virus. He passed away on August 27. Ironically, after years of working
+% safely in the mountain jungles of Central Africa, it is likely that
+% he acquired the virus from a mosquito bite at his family's cabin
+% in Canada.
+##### SOURCE END ##### 77d29507140c40a1a497777d9fd035e6
+-->
+
+
+
+
+ MiniGallery, Sampler of MATLAB Test Matrices
+
+ 2023-06-28T16:34:09-06:00
+ https://hpc.social/2023/minigallery-sampler-of-matlab-test-matrices
+ <div class="content"><!--introduction--><p>MATLAB has dozens of test matrices. Here are a few.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#2fb5167b-7e82-4227-9f86-2870405cf53c">Mini_Gallery</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#eba25d52-863f-4050-9d5c-28d66c4a102b">Collections</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#66c32842-91ed-4ddf-9f2b-544fc3a88564">Blogs</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#a58fbf40-276b-4c6c-8576-97e02358a317">Software</a></li></ul></div>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/TinyGallery.png" vspace="5" /> </p>
+<h4>Mini_Gallery<a name="2fb5167b-7e82-4227-9f86-2870405cf53c"></a></h4><div><ul><li>Random. <tt>A = sprand(n,n,0.25)</tt>. Random sparse, density = 0.25.</li><li>Bucky. <tt>A = bucky</tt>. Sparse connectivity graph of the geodesic dome, the soccer ball, and the carbon-60 molecule.</li><li>Wilkinson. <tt>A = wilkinson(n)</tt>. Wn+. Nearly equal double eigenvalues.</li><li>Band. <tt>A = triu(tril(A,2),-2)</tt>. Elements near diagonal.</li><li>Triangular. <tt>A = triu(A)</tt>. Elements on and above diagonal.</li><li>Hessenberg. <tt>A = triu(A,-1)</tt>. Upper triangular plus one subdiagonal. See <tt>schur</tt>.</li><li>Permutation. <tt>A = sparse(randperm(n),1:n,1)</tt>. One +1 in each row and column.</li><li>Companion. <tt>c = charpoly(A); A = [-c(2:end); eye(n-1,n)]</tt>. Traditional companion matrix.</li><li>Fiedler. <tt>c = charpoly(A); A = fiedler(-c(2:end))</tt>. Fiedler companion matrix.</li><li>Hankel. <tt>A = flip(gallery('toeppd',n))</tt>. Constant antidiagonals.</li><li>Toeplitz. <tt>A = gallery('toeppd',n)</tt>. Constant diagonals.</li><li>Magic. <tt>A = magic(n)</tt>. Magic square.</li></ul></div>
+<h4>Collections<a name="eba25d52-863f-4050-9d5c-28d66c4a102b"></a></h4><div><ul><li><tt>gallery</tt>. Nick Higham and MathWorks, <a href="https://www.mathworks.com/help/matlab/ref/gallery.html">https://www.mathworks.com/help/matlab/ref/gallery.html</a></li><li>Anymatrix. Nick Higham and Mantas Mikaitis, <a href="https://nhigham.com/2021/11/09/anymatrix">https://nhigham.com/2021/11/09/anymatrix</a>></li><li>SuiteSparse. Tim Davis, Yifan Hu and Scott Kolodzie, <a href="http://sparse.tamu.edu">http://sparse.tamu.edu</a></li><li>MatrixMarket, NIST, <a href="https://math.nist.gov/MatrixMarket">https://math.nist.gov/MatrixMarket</a>.</li></ul></div>
+<h4>Blogs<a name="66c32842-91ed-4ddf-9f2b-544fc3a88564"></a></h4><div><ul><li><a href="https://blogs.mathworks.com/cleve/2012/11/05/magic-squares-part-2-algorithms/">https://blogs.mathworks.com/cleve/2012/11/05/magic-squares-part-2-algorithms/</a></li><li><a href="https://blogs.mathworks.com/cleve/2013/04/15/wilkinsons-matrices-2/">https://blogs.mathworks.com/cleve/2013/04/15/wilkinsons-matrices-2/</a>.</li><li><a href="https://blogs.mathworks.com/cleve/2013/12/23/fiedler-companion-matrix/">https://blogs.mathworks.com/cleve/2013/12/23/fiedler-companion-matrix/</a>.</li><li><a href="https://blogs.mathworks.com/cleve/2021/05/12/bringing-back-the-bucky-ball/">https://blogs.mathworks.com/cleve/2021/05/12/bringing-back-the-bucky-ball/</a>.</li></ul></div>
+<h4>Software<a name="a58fbf40-276b-4c6c-8576-97e02358a317"></a></h4><div><ul><li><a href="https://blogs.mathworks.com/cleve/files/Mini_Gallery.m">https://blogs.mathworks.com/cleve/files/Mini_Gallery.m</a></li></ul></div>
+<!--
+ function grabCode_3ac745ceafba4a469aec48ad4b98c1b4() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='3ac745ceafba4a469aec48ad4b98c1b4 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 3ac745ceafba4a469aec48ad4b98c1b4';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2023 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+3ac745ceafba4a469aec48ad4b98c1b4 ##### SOURCE BEGIN #####
+%% MiniGallery, Sampler of MATLAB Test Matrices
+% MATLAB has dozens of test matrices. Here are a few.
+
+%%
+%
+% <<TinyGallery.png>>
+%
+
+%% MiniGallery
+% * Random. |A = sprand(n,n,0.25)|. Random sparse, density = 0.25.
+% * Bucky. |A = bucky|. Sparse connectivity graph of the geodesic dome,
+% the soccer ball, and the carbon-60 molecule.
+% * Wilkinson. |A = wilkinson(n)|. Wn+. Nearly equal double eigenvalues.
+% * Band. |A = triu(tril(A,2),-2)|. Elements near diagonal.
+% * Triangular. |A = triu(A)|. Elements on and above diagonal.
+% * Hessenberg. |A = triu(A,-1)|. Upper triangular plus one subdiagonal.
+% See |schur|.
+% * Permutation. |A = sparse(randperm(n),1:n,1)|. One +1 in each row and
+% column.
+% * Companion. |c = charpoly(A); A = [-c(2:end); eye(n-1,n)]|.
+% Traditional companion matrix.
+% * Fiedler. |c = charpoly(A); A = fiedler(-c(2:end))|. Fiedler companion
+% matrix.
+% * Hankel. |A = flip(gallery('toeppd',n))|. Constant antidiagonals.
+% * Toeplitz. |A = gallery('toeppd',n)|. Constant diagonals.
+% * Magic. |A = magic(n)|. Magic square.
+
+%% Collections
+% * |gallery|. Nick Higham and MathWorks, <https://www.mathworks.com/help/matlab/ref/gallery.html>
+% * Anymatrix. Nick Higham and Mantas Mikaitis, https://nhigham.com/2021/11/09/anymatrix>
+% * SuiteSparse. Tim Davis, Yifan Hu and Scott Kolodzie, <http://sparse.tamu.edu>
+% * MatrixMarket, NIST, <https://math.nist.gov/MatrixMarket>.
+
+%% Blogs
+% * <https://blogs.mathworks.com/cleve/2012/11/05/magic-squares-part-2-algorithms></https://blogs.mathworks.com/cleve/2012/11/05/magic-squares-part-2-algorithms>
+% * <https://blogs.mathworks.com/cleve/2013/04/15/wilkinsons-matrices-2></https://blogs.mathworks.com/cleve/2013/04/15/wilkinsons-matrices-2>.
+% * <https://blogs.mathworks.com/cleve/2013/12/23/fiedler-companion-matrix></https://blogs.mathworks.com/cleve/2013/12/23/fiedler-companion-matrix>.
+% * <https://blogs.mathworks.com/cleve/2021/05/12/bringing-back-the-bucky-ball></https://blogs.mathworks.com/cleve/2021/05/12/bringing-back-the-bucky-ball>.
+
+%% Software
+% * <https://blogs.mathworks.com/cleve/files/MiniGallery.m>
+##### SOURCE END ##### 3ac745ceafba4a469aec48ad4b98c1b4
+-->
+
+
+
+
+ ARLS, Automatically Regularized Least Squares
+
+ 2023-06-17T00:57:05-06:00
+ https://hpc.social/2023/arls-automatically-regularized-least-squares
+ <div class="content"><!--introduction--><p>(I have a guest blogger today. Ron Jones worked with me in 1985 for his Ph. D. from the University of New Mexico. He retired recently after nearly 40 years at Sandia National Labs in Albuquerque and now has a chance to return to the problem he studied in his thesis. -- CBM)</p>
+<p>by Rondall Jones, <a href="mailto:rejones7@msn.com">rejones7@msn.com</a></p>
+<p>Our interest is in automatically solving difficult linear systems,</p>
+<pre> A*x = b</pre><p>Such systems often arise, for example, in "inverse problems" in which the analyst is trying to reverse the effects of natural smoothing processes such as heat dissipation, optical blurring, or indirect sensing. These problems exhibit "ill-conditioning", which means that the solution results are overly sensitive to insignificant changes to the observations, which are given in the right-hand-side vector, <tt>b</tt> .</p>
+<!--/introduction--><p>Here is a graphic showing this behavior using a common test matrix, a 31 x 31 Hilbert matrix, with the blue line being the ideal solution that one would hope a solver could compute. The jagged red line shows the result of a traditional solver on this problem.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/arls_0.bmp" vspace="5" /> </p>
+<p>In fact this graph is extremely mild: the magnitude of the oscillations often measure in the millions, not just a little larger than the true solution. Traditionally analysts have approached this issue in the linear algebraic system context by appending equations to <tt>A*x = b</tt> that request each solution value, <tt>x(i)</tt>, to be zero. Then, one weights these conditioning equations using a parameter usually called "lambda". We will call it <tt>p</tt> here. What we have to solve then is this expanded linear system:</p>
+<pre> [ A ; p*I] * x = [b; 0]</pre><p>If we decompose <tt>A</tt> into its Singular Value Decomposition</p>
+<pre> A = U * S * V'</pre><p>and multiply both sides by the transpose of the augmented LHS, the resulting solution to is</p>
+<pre> x = V * inv(S^2 + p^2*I) * S * U' * b</pre><p>instead of the usual</p>
+<pre> x = V * inv(S) * U' * b</pre><p>It is convenient in the following discussion to represent this as</p>
+<pre> x = V * PCV</pre><p>where</p>
+<pre> PCV = inv(S) * U' * b</pre><p>is what we call the <i>Picard Condition Vector</i>. Then <tt>x</tt> is computed in the usual SVD manner with the change that each singular value <tt>S(i)</tt> is replaced by</p>
+<pre> S(i) + p^2/S(i)</pre><p>This process is called <i>Tikhonov regularization</i>.</p>
+<p>Using Tikhonov regularization successfully requires <i>somehow</i> picking an appropriate value for <tt>p</tt>. Cleve Moler has for many years jokingly used the term "eyeball norm" to describe how to pick <tt>p</tt>. "Try various values of <tt>p</tt> and pick the resulting solution (or its graph) that 'looks good'".</p>
+<p>My early work in attempting to determine lambda automatically was based instead on determining when the PCV begins to seriously diverge. Beyond that point one can be fairly sure that noise in <tt>b</tt> is causing <tt>U'*b</tt> to decrease more slowly than <tt>inv(S)</tt> is increasing, so their product, which is the PCV, starts growing unacceptably. Such an algorithm can be made to work and versions of my work have been available in various forms over the years. But determining where the PCV starts growing unacceptably (which I refer to as the <i>usable rank</i>) is based on heuristics, moving averages, and such, as of which require choices of moving average lengths and other such parameters. This is not an optimal situation, so a I began trying to redesign algorithms that do not use any heuristics.</p>
+<p>How do we do that algorithmically? Per Christian Hansen gave a clue to this question when he said (my re-phrasing) that "the analyst should not expect a good solution for such a problem unless the PCV is 'declining'". We note that this adage is a context-specific application of a general requirement that when a function is represented by an orthogonal expansion the coefficients of the orthogonal basis functions should eventually decline toward zero. If this behavior does not happen, then typically either the model is incomplete or the data is contaminated. In our case the orthogonal basis is simply the columns of <tt>V</tt>, and <tt>b</tt> is the set of coefficients that would be expected to decline. A good working definition of "declining" has been hard to nail down. The algorithm in <tt>ARLS</tt> has implemented this concept using two specific essential steps:</p>
+<div><ul><li>First, we replace the PCV by a second-degree polynomial (e.g., a parabolic) least-squares fit to the PCV. This allows a lot of the typical "wild" variations in the PCV to be smoothed over and thereby tolerated without eliminating the problem's distinctive behavior.</li></ul></div>
+<div><ul><li>Second, we don't actually fit the curve to the PCV, but rather to the <b>logarithm</b> of the PCV. Without this change, small values of the PCV are seen by the curve fit process as just near-zero values, with no significant difference in the effect of a value of 0.0001 or a value of 0.0000000001. But in the (base 10) logarithm of the PCV these values nicely spread out from -4 to -10 (for example).</li></ul></div>
+<p>So, Phase 1 of ARLS searches a large range of values of p (remember, p is Tikhonov's "lambda") to find a value just barely large enough to make the slope of the parabolic fit entirely negative or zero. This gives us a tight lower bound for the "correct" value of p.</p>
+<p>Phase 2 of ARLS is much simpler. Since p is the minimum usable regularization parameter, the solution tends to be less smooth and less close to the ideal solution than optimum. So we simply increase p slightly to let the shape of the graph of x smooth out. Our current implementation increases p until the residual (that is, <tt>norm(A*x-b)</tt>) of the solution increases by a factor of 2. This is, unfortunately, a heuristic. But an appropriate value of it can be determined by “tuning” the algorithm on a wide range of test problems.</p>
+<p>We call this new algorithm Logarithmic Picard Condition Analysis. (If the problems you work on seem to need a bit more relaxation you can, of course, increase the number 2 a bit. It is 5 lines from the bottom of the file.) In the example shown in the graphic above, ARLS produces the blue line so closely that the ideal solution and ARLS computed solution are indistinguishable.</p>
+<p>In addition to ARLS(A,b) itself, we provide two constrained solvers built on ARLS which are called just like ARLS:</p>
+<div><ul><li>ARLSNN(A,b), which constrains the solution to be non-negative (like the classic NNLS, buth with regularization.</li></ul></div>
+<div><ul><li>ARLSRISE(A,b) which constrains the solution to be non-decreasing. To get a non-increasing, or “falling” solution, you can compute -ARLSRISE(A,-b).</li></ul></div>
+<p>Try ARLS. It's available from the MATLAB Central File Exchange, #130259, <a href="https://www.mathworks.com/matlabcentral/fileexchange/130259-arls-automatically-regularized-least-squares">at this link</a>.</p>
+<!--
+ function grabCode_95d95d5b92ad4c4ca262dfdb5ff7efe9() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='95d95d5b92ad4c4ca262dfdb5ff7efe9 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 95d95d5b92ad4c4ca262dfdb5ff7efe9';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2023 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+95d95d5b92ad4c4ca262dfdb5ff7efe9 ##### SOURCE BEGIN #####
+%% ARLS, Automatically Regularized Least Squares
+%
+% (I have a guest blogger today. Ron Jones worked with me in 1985 for
+% his Ph. D. from the University of New Mexico. He retired recently
+% after nearly 40 years at Sandia National Labs in Albuquerque and now
+% has a chance to return to the problem he studied in his thesis. REPLACE_WITH_DASH_DASH CBM)
+%
+% by Rondall Jones, rejones7@msn.com
+%
+% Our interest is in automatically solving difficult linear systems,
+%
+% A*x = b
+%
+% Such systems often arise, for example, in "inverse problems" in which
+% the analyst is trying to reverse the effects of natural smoothing
+% processes such as heat dissipation, optical blurring, or indirect sensing.
+% These problems exhibit "ill-conditioning", which means that the solution
+% results are overly sensitive to insignificant changes to the observations,
+% which are given in the right-hand-side vector, |b| .
+%%
+% Here is a graphic showing this behavior using a common test matrix, a
+% 31 x 31 Hilbert matrix, with the blue line being the ideal solution that
+% one would hope a solver could compute. The jagged red line shows the
+% result of a traditional solver on this problem.
+%
+% <<arls_0.bmp>>
+%
+% In fact this graph is extremely mild: the magnitude of the oscillations
+% often measure in the millions, not just a little larger than the true
+% solution. Traditionally analysts have approached this issue in the linear
+% algebraic system context by appending equations to |A*x = b| that request
+% each solution value, |x(i)|, to be zero. Then, one weights these
+% conditioning equations using a parameter usually called "lambda". We
+% will call it |p| here. What we have to solve then is this expanded linear
+% system:
+%
+% [ A ; p*I] * x = [b; 0]
+%
+% If we decompose |A| into its Singular Value Decomposition
+%
+% A = U * S * V'
+%
+% and multiply both sides by the transpose of the augmented LHS,
+% the resulting solution to is
+%
+% x = V * inv(S^2 + p^2*I) * S * U' * b
+%
+% instead of the usual
+%
+% x = V * inv(S) * U' * b
+%
+% It is convenient in the following discussion to represent this as
+%
+% x = V * PCV
+%
+% where
+%
+% PCV = inv(S) * U' * b
+%
+% is what we call the _Picard Condition Vector_. Then
+% |x| is computed in the usual SVD manner with the change that each
+% singular value |S(i)| is replaced by
+%
+% S(i) + p^2/S(i)
+%
+% This process is called _Tikhonov regularization_.
+%
+% Using Tikhonov regularization successfully requires _somehow_ picking
+% an appropriate value for |p|. Cleve Moler has for
+% many years jokingly used the term "eyeball norm" to describe how to pick
+% |p|. "Try various values of |p| and pick the resulting solution
+% (or its graph) that 'looks good'".
+
+%%
+% My early work in attempting to determine lambda automatically was
+% based instead on determining when the PCV begins to seriously diverge.
+% Beyond that point one can be fairly sure that noise in |b| is causing
+% |U'*b| to decrease more slowly than |inv(S)| is increasing, so their
+% product, which is the PCV, starts growing unacceptably.
+% Such an algorithm can be made
+% to work and versions of my work have been available in various forms
+% over the years. But determining where the PCV starts growing unacceptably
+% (which I refer to as the _usable rank_) is based on heuristics, moving
+% averages, and such, as of which require choices of moving average
+% lengths and other such parameters. This is not an optimal situation, so a
+% I began trying to redesign algorithms that do not use any heuristics.
+
+%%
+% How do we do that algorithmically? Per Christian Hansen gave a clue to
+% this question when he said (my re-phrasing) that "the analyst should not
+% expect a good solution for such a problem unless the PCV is 'declining'".
+% We note that this adage is a context-specific application of a general
+% requirement that when a function is represented by an orthogonal
+% expansion the coefficients of the orthogonal basis functions should
+% eventually decline toward zero. If this behavior does not happen, then
+% typically either the model is incomplete or the data is contaminated. In
+% our case the orthogonal basis is simply the columns of |V|, and |b| is
+% the set of coefficients that would be expected to decline. A good
+% working definition of "declining" has been hard to nail down. The
+% algorithm in |ARLS| has implemented this concept using two specific
+% essential steps:
+%
+% * First, we replace the PCV by a second-degree polynomial (e.g., a
+% parabolic) least-squares fit to the PCV. This allows a lot of the typical
+% "wild" variations in the PCV to be smoothed over and thereby tolerated
+% without eliminating the problem's distinctive behavior.
+%
+% * Second, we don't actually fit the curve to the PCV, but rather to the
+% *logarithm* of the PCV. Without this change, small values of the PCV
+% are seen by the curve fit process as just near-zero values, with no
+% significant difference in the effect of a value of 0.0001 or a value of
+% 0.0000000001. But in the (base 10) logarithm of the PCV these values
+% nicely spread out from -4 to -10 (for example).
+%
+% So, Phase 1 of ARLS searches a large range of values of p (remember, p
+% is Tikhonov's "lambda") to find a value just barely large enough to make
+% the slope of the parabolic fit entirely negative or zero. This gives us a
+% tight lower bound for the "correct" value of p.
+%
+% Phase 2 of ARLS is much simpler. Since p is the minimum usable
+% regularization parameter, the solution tends to be less smooth and less
+% close to the ideal solution than optimum. So we simply increase p
+% slightly to let the shape of the graph of x smooth out. Our current
+% implementation increases p until the residual (that is, |norm(A*x-b)|) of
+% the solution increases by a factor of 2. This is, unfortunately, a heuristic.
+% But an appropriate value of it can be determined by “tuning” the
+% algorithm on a wide range of test problems.
+%
+% We call this new algorithm Logarithmic Picard Condition Analysis.
+% (If the problems you work on seem to need a bit more relaxation you
+% can, of course, increase the number 2 a bit. It is 5 lines from the
+% bottom of the file.)
+% In the example shown in the graphic above, ARLS produces the blue line
+% so closely that the ideal solution and ARLS computed solution are
+% indistinguishable.
+%
+% In addition to ARLS(A,b) itself, we provide two constrained solvers
+% built on ARLS which are called just like ARLS:
+%
+% * ARLSNN(A,b), which constrains the solution to be non-negative
+% (like the classic NNLS, buth with regularization.
+%
+% * ARLSRISE(A,b) which constrains the solution to be non-decreasing.
+% To get a non-increasing, or “falling” solution, you can compute
+% -ARLSRISE(A,-b).
+%
+% Try ARLS. It's available from the MATLAB Central File Exchange,
+% #130259,
+% <https://www.mathworks.com/matlabcentral/fileexchange/130259-arls-automatically-regularized-least-squares
+% at this link>.
+##### SOURCE END ##### 95d95d5b92ad4c4ca262dfdb5ff7efe9
+-->
+
+
+
+
+ Happy Birthday, John Gilbert
+
+ 2023-06-07T14:48:32-06:00
+ https://hpc.social/2023/happy-birthday-john-gilbert
+ <div class="content"><!--introduction--><p>I have just returned from a one-day workshop at U. C. Santa Barbara honoring John Gilbert on his 70th birthday and his official retirement after 20 years on the UCSB faculty.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/johnrgilbert.jpg" vspace="5" /> </p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#483e8936-1d16-4486-a661-92c662f34d97">New Mexico</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#0be2f0ed-b459-4a36-af7a-57fefb22d647">Xerox PARC</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#e413f7b9-c197-454d-b046-d30190db4c17">Friendship</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#3b88cae7-503d-4399-99b3-4329200f4ed6">UCSB</a></li></ul></div>
+<h4>New Mexico<a name="483e8936-1d16-4486-a661-92c662f34d97"></a></h4><p>I have known John since he was a teenager.</p>
+<p>In the late 1960's, John's father, Ed Gilbert, together with fellow mathematicians Don Morrison and Sto Bell, left their jobs at Sandia National Labs in Albuquerque and established the Computer Science Department at the University of New Mexico. Ed was especially interested in undergraduate education and led the department to early adoption of Pascal and Unix in the curriculum.</p>
+<p>In 1972, my wife at the time, Nancy Martin, and I were seeking a university where we could both have faculty positions. UNM offered me a job in the Math Department and Nancy one in Computer Science. I stayed at UNM for 13 years, eventually succeeding Morrison as Chairman of Computer Science.</p>
+<p>When I first met the Gilbert family in '72, both John and his younger brother Erik were undergrad students at UNM. A year later, both brothers were admitted to grad school in Computer Science at Stanford. After getting their Ph.D.'s in CS at Stanford, Erik went on to cofound a software company that produced a dialect of Lisp and John joined the Computer Science Department at Cornell.</p>
+<h4>Xerox PARC<a name="0be2f0ed-b459-4a36-af7a-57fefb22d647"></a></h4><p>After several years at Cornell, John returned to California and the famous Xerox Palo Alto Research Center.</p>
+<p>Sometime around Christmas in 1988, Ian Duff, the British authority on sparse matrices, wanted to go skiing in the Sierras. Iain arranged with Gene Golub to give a talk at Stanford. I was living in Menlo Park at the time and went to the talk. So did John Gilbert and Rob Schreiber, from Hewlett Packard Research in Palo Alto.</p>
+<p>After the talk, everybody went for coffee at Tresidder, Stanford's student union. During the ensuing discussion, John, Rob and I decided it was time to have sparse matrices in MATLAB. The first new data structure in MATLAB and its description resulted. See the links at <a href="https://epubs.siam.org/doi/10.1137/0613024">SIAM</a> and <a href="https://www.mathworks.com/help/pdf_doc/otherdocs/simax.pdf">MathWorks</a>.</p>
+<h4>Friendship<a name="e413f7b9-c197-454d-b046-d30190db4c17"></a></h4><p>Our collaboration on sparse matrices has led to an enduring friendship. Every year, at SCxx, the High Performance Computing conference in November, the three of us and Jack Dongarra get together. Here we are with Sven Hammarling from NAG, at SC17 in Denver.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/sc17.jpg" vspace="5" /> </p>
+<h4>UCSB<a name="3b88cae7-503d-4399-99b3-4329200f4ed6"></a></h4><p>After a dozen years at PARC, John returned to academic life at the University of California near Santa Barbara. Last Saturday, Aydin Buluc and Daniel Lokshtanov, two of John's UCSB Ph. D. students, organized the JRG70 workshop. Here is a link to the Web page, including the list of talks presented. <a href="https://sites.google.com/lbl.gov/jrg70/home">link</a>. It was the first time since Tresidder that Iain, John, Rob and I have all been together.</p>
+<p>Here is a portrait of the JRG70 participants. As usual, John is being modest; he's in the back row, in a burgundy sweater.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/jrg70.jpg" vspace="5" /> </p>
+<!--
+ function grabCode_6a6c6e1bce6a40f28847707c01157cbb() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='6a6c6e1bce6a40f28847707c01157cbb ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 6a6c6e1bce6a40f28847707c01157cbb';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2023 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+6a6c6e1bce6a40f28847707c01157cbb ##### SOURCE BEGIN #####
+%% Happy Birthday, John Gilbert
+% I have just returned from a one-day workshop at U. C. Santa Barbara
+% honoring John Gilbert on his 70th birthday and his
+% official retirement after 20 years on the UCSB faculty.
+%
+% <<johnrgilbert.jpg>>
+%
+
+%% New Mexico
+% I have known John since he was a teenager.
+
+%%
+% In the late 1960's, John's father, Ed Gilbert, together with fellow
+% mathematicians Don Morrison and Sto Bell, left their jobs at
+% Sandia National Labs in Albuquerque and established the Computer
+% Science Department at the University of New Mexico. Ed was
+% especially interested in undergraduate education and led the
+% department to early adoption of Pascal and Unix in the curriculum.
+
+%%
+% In 1972, my wife at the time, Nancy Martin, and I were seeking a
+% university where we could both have faculty positions. UNM offered
+% me a job in the Math Department and Nancy one in Computer Science.
+% I stayed at UNM for 13 years, eventually succeeding Morrison as
+% Chairman of Computer Science.
+
+%%
+% When I first met the Gilbert family in '72, both John and his younger
+% brother Erik were undergrad students at UNM. A year later, both
+% brothers were admitted to grad school in Computer Science at Stanford.
+% After getting their Ph.D.'s in CS at Stanford, Erik went on to
+% cofound a software company that produced a dialect of Lisp and
+% John joined the Computer Science Department at Cornell.
+
+%% Xerox PARC
+% After several years at Cornell, John returned to California and
+% the famous Xerox Palo Alto Research Center.
+%
+% Sometime around Christmas in 1988, Ian Duff, the British authority on
+% sparse matrices, wanted to go skiing in the Sierras. Iain arranged with
+% Gene Golub to give a talk at Stanford. I was living in Menlo Park
+% at the time and went to the talk. So did John Gilbert and Rob Schreiber,
+% from Hewlett Packard Research in Palo Alto.
+%
+% After the talk, everybody went for coffee at Tresidder, Stanford's
+% student union. During the ensuing discussion, John, Rob and I decided
+% it was time to have sparse matrices in MATLAB. The first new data
+% structure in MATLAB and its description resulted. See the links at
+% <https://epubs.siam.org/doi/10.1137/0613024
+% SIAM> and
+% <https://www.mathworks.com/help/pdf_doc/otherdocs/simax.pdf
+% MathWorks>.
+
+%% Friendship
+% Our collaboration on sparse matrices has led to an enduring friendship.
+% Every year, at SCxx, the High Performance Computing conference in
+% November, the three of us and Jack Dongarra get together. Here we are
+% with Sven Hammarling from NAG, at SC17 in Denver.
+%
+% <<SC17.jpg>>
+%
+
+%% UCSB
+% After a dozen years at PARC, John returned to academic life at
+% the University of California near Santa Barbara.
+% Last Saturday, Aydin Buluc and Daniel Lokshtanov, two of John's
+% UCSB Ph. D. students, organized the JRG70 workshop. Here is a
+% link to the Web page, including the list of talks presented.
+% <https://sites.google.com/lbl.gov/jrg70/home link>.
+% It was the first time since Tresidder that Iain, John, Rob and I
+% have all been together.
+%
+% Here is a portrait of the JRG70 participants. As usual, John is
+% being modest; he's in the back row, in a burgundy sweater.
+%
+% <<jrg70.jpg>>
+
+
+
+##### SOURCE END ##### 6a6c6e1bce6a40f28847707c01157cbb
+-->
+
+
+
+
+ Special Notice
+
+ 2023-04-04T15:12:36-06:00
+ https://hpc.social/2023/special-notice
+ <div class="content"><h3>Special Notice</h3><p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/notice.png" vspace="5" /> </p>
+<p>If you have been following my posts about Wordle, be sure to see the puzzle in today's <i>New York Times</i>, Tuesday, April 4.</p>
+<!--
+ function grabCode_455754acb45549b2b4f3c459b7fef0d9() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='455754acb45549b2b4f3c459b7fef0d9 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 455754acb45549b2b4f3c459b7fef0d9';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2023 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+455754acb45549b2b4f3c459b7fef0d9 ##### SOURCE BEGIN #####
+%% Special Notice
+%
+% <<notice.png>>
+%
+% If you have been following my posts about Wordle, be sure to see
+% the puzzle in today's _New York Times_, Tuesday, April 4.
+
+##### SOURCE END ##### 455754acb45549b2b4f3c459b7fef0d9
+-->
+
+
+
+
+ My Chat with Ernie, a Chinese Chat Bot
+
+ 2023-04-01T05:00:26-06:00
+ https://hpc.social/2023/my-chat-with-ernie-a-chinese-chat-bot
+ <div class="content"><!--introduction--><p>I recently had an opportunity to chat with Ernie, the Large Language Model currently under development at the Chinese internet search giant, <a href="https://www.cnbc.com/2023/02/07/baidu-shares-leaps-as-it-reveals-plan-for-chatgpt-style-ernie-bot.html">Baidu</a>. As I expected, Ernie's responses are in Chinese. I don't speak Chinese, so I have asked Google Translate for the response in English.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#8bdaf182-51c2-4843-a2be-98df430c39cc">Embarrassingly Parallel</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#7aad9ef7-8d41-4907-be94-fd647ab6a762">Love MATLAB?</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#fc2f9078-105c-45bf-9ea6-df8e811b0de2">Cleve's Corner</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#6ac55893-0202-442a-8871-ffd685ea191a">Conclusion</a></li></ul></div>
+<h4>Embarrassingly Parallel<a name="8bdaf182-51c2-4843-a2be-98df430c39cc"></a></h4><p>One of my questions that Microsoft's ChatGPT answered incorrectly was</p>
+<pre> Who coined the term "embarrassingly parallel?"</pre><p>Ernie's response to the same question was</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/response3.jpg" vspace="5" /> </p>
+<p>Goggle translate:</p>
+<pre> Who coined the embarrassing word parallel?</pre><p>Well that's a <b>very</b> unfortunate misunderstanding. And, it's just repeating the question. That's an old trick; the mother of all chat bots, <a href="https://en.wikipedia.org/wiki/ELIZA">Eliza</a> , used it over sixty years ago.</p>
+<h4>Love MATLAB?<a name="7aad9ef7-8d41-4907-be94-fd647ab6a762"></a></h4><p>One of the questions I often ask when I meet someone for the first time is</p>
+<pre> Do you use MATLAB?</pre><p>Earnie's reply was</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/response1.jpg" vspace="5" /> </p>
+<p>Google translation is</p>
+<pre> I think I love you.</pre><p>Well, that's nice, but doesn't really answer my question.</p>
+<h4>Cleve's Corner<a name="fc2f9078-105c-45bf-9ea6-df8e811b0de2"></a></h4><p>Can a chat bot assist with writing this blog? I don't expect help with the MATLAB code, or with the graphics, or with any mathematics. How about the prose, if it isn't too technical.</p>
+<p>Here is the opening sentence of the <a href="https://blogs.mathworks.com/cleve/2023/02/04/matrices-in-action-grafix-2-0/">post I made a few weeks ago</a>.</p>
+<pre> The 4-by-4 matrices in the panels on the following screenshots
+ are at the heart of computer graphics.</pre><p>I asked Ernie how that would look in Chinese. Ernie responded with</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/response2.jpg" vspace="5" /> </p>
+<p>When Google translates that back to English, we get</p>
+<pre> The 4×4 matrix in the screenshot panel below is at the heart of
+ computer graphics.</pre><p>Ernie decided to make the sentence singular, which happens to shorten it. But I am afraid that isn't much help for this blog.</p>
+<h4>Conclusion<a name="6ac55893-0202-442a-8871-ffd685ea191a"></a></h4><p>I have already described <a href="https://blogs.mathworks.com/cleve/2023/02/21/my-chat-with-chatgpt/">my chat with ChatGPT</a>. This Chinese competitor is certainly not an improvement. For now, I will continue to produce this blog the old fashioned way, without any "help" from AI.</p>
+<!--
+ function grabCode_1ab0a9dd4230472ebcebbecc859ab36c() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='1ab0a9dd4230472ebcebbecc859ab36c ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 1ab0a9dd4230472ebcebbecc859ab36c';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2023 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+1ab0a9dd4230472ebcebbecc859ab36c ##### SOURCE BEGIN #####
+%% My Chat with Ernie, a Chinese Chat Bot
+% I recently had an opportunity to chat with Ernie, the Large Language
+% Model currently under development at the Chinese internet search giant,
+% <https://www.cnbc.com/2023/02/07/baidu-shares-leaps-as-it-reveals-plan-for-chatgpt-style-ernie-bot.html
+% Baidu>. As I expected, Ernie's responses are in Chinese.
+% I don't speak Chinese, so I have asked Google Translate for the response
+% in English.
+
+%% Embarrassingly Parallel
+% One of my questions that Microsoft's ChatGPT answered incorrectly
+% was
+%
+% Who coined the term "embarrassingly parallel?"
+%
+% Ernie's response to the same question was
+%
+% <<response3.jpg>>
+%
+% Goggle translate:
+%
+% Who coined the embarrassing word parallel?
+%
+% Well that's a *very* unfortunate misunderstanding.
+% And, it's just repeating the question.
+% That's an old trick; the mother of all chat bots,
+% <https://en.wikipedia.org/wiki/ELIZA
+% Eliza> , used it over sixty years ago.
+
+%% Love MATLAB?
+% One of the questions I often ask when I meet someone for the first
+% time is
+%
+% Do you use MATLAB?
+%
+% Earnie's reply was
+%
+% <<response1.jpg>>
+%
+% Google translation is
+%
+% I think I love you.
+%
+% Well, that's nice, but doesn't really answer my question.
+
+%% Cleve's Corner
+% Can a chat bot assist with writing this blog?
+% I don't expect help with the MATLAB code, or with the graphics, or with
+% any mathematics. How about the prose, if it isn't too technical.
+%
+% Here is the opening sentence of the
+% <https://blogs.mathworks.com/cleve/2023/02/04/matrices-in-action-grafix-2-0/
+% post I made a few weeks ago>.
+%
+% The 4-by-4 matrices in the panels on the following screenshots
+% are at the heart of computer graphics.
+%
+% I asked Ernie how that would look in Chinese.
+% Ernie responded with
+%
+% <<response2.jpg>>
+%
+% When Google translates that back to English, we get
+%
+% The 4×4 matrix in the screenshot panel below is at the heart of
+% computer graphics.
+%
+% Ernie decided to make the sentence singular, which happens to
+% shorten it. But I am afraid that isn't much help for this blog.
+
+%% Conclusion
+% I have already described
+% <https://blogs.mathworks.com/cleve/2023/02/21/my-chat-with-chatgpt/
+% my chat with ChatGPT>.
+% This Chinese competitor is certainly not an improvement.
+% For now, I will continue to produce this blog the old fashioned way,
+% without any "help" from AI.
+##### SOURCE END ##### 1ab0a9dd4230472ebcebbecc859ab36c
+-->
+
+
+
+
+ Three Wordle Assistants
+
+ 2023-03-28T03:00:55-06:00
+ https://hpc.social/2023/three-wordle-assistants
+ <div class="content"><!--introduction--><p>When I tackle a Wordle puzzle, I like to make all the key decisions myself. My three assistants set up puzzles and suggest words when I ask for help, but I guide the actual solution. My assistants also make it possible for me to play Wordle anywhere, anytime, even when my laptop is in airplane mode. I don't need the <i>New York Times</i> or access to the Web.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#dacb9b49-209b-4bd4-9600-ddcbf92f222e">Three Assistants</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#9a0fa3c8-2ea4-4e0d-8679-69e40f59921c">Vocabulary</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#fef3bbd2-49bf-47e0-b344-69a2b844ce95">Words</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#313da354-b5c6-4675-929e-3bbe89e7a74a">Wordle</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#bc74a1cc-f3c3-4b86-bd1b-7a19d18b8d36">NYT</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#a2a62471-6d35-4253-8c11-b0de6725afd4">Pared Down</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#3634c294-6419-4ca0-9339-7a1e50630492">Five Golds</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#fb298646-e9d7-4395-ba63-3e8d2607dc82">Thanks</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#3daf42e9-4815-4553-9b08-c2945d557011">Software</a></li></ul></div>
+<h4>Three Assistants<a name="dacb9b49-209b-4bd4-9600-ddcbf92f222e"></a></h4><p><tt>Wordler</tt>, <tt>Words</tt> and <tt>Wordie</tt> are the three assistants. <tt>Wordler</tt> replaces the <i>Times</i> by generating puzzles and evaluating responses. <tt>Words</tt> provides lists of possible responses. <tt>Wordie</tt> handles the Wordler Window and colors the letters gray, green or gold.</p>
+<h4>Vocabulary<a name="9a0fa3c8-2ea4-4e0d-8679-69e40f59921c"></a></h4><p><tt>Words</tt> has a <tt>vocabulary</tt> of 4665 five-letter English words. Any of them are acceptable responses. The vocabulary begins with</p>
+<pre> vocab = [ ...
+ "ABEAM" "ABETS" "ABHOR" "ABIDE" "ABLED" "ABLER" "ABODE" "ABORT" ...</pre><p>And, 584 lines later, ends with</p>
+<pre> "ZILCH" "ZINCS" "ZINGS" "ZIPPY" "ZOMBI" "ZONAL" "ZONED" "ZONES" ...
+ "ZOOMS" ];</pre><p>If you were to print the entire vocabulary with 40 lines per page, you would print over 100 pages of words.</p>
+<h4>Words<a name="fef3bbd2-49bf-47e0-b344-69a2b844ce95"></a></h4><p>It took me a long time to write the <tt>Words</tt> assistant, which is called whenever the Words button in the Wordle Window is clicked.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/ratio.gif" vspace="5" /> </p>
+<p><tt>Words</tt> is supported by a seventeen-program library of functions named <tt>Wordspq</tt> where <tt>p</tt> and <tt>q</tt> are nonnegative integers with <tt>p+q <= 5</tt>. <tt>Wordspq</tt> finds words with <tt>p</tt> green letters and <tt>q</tt> gold letters. The programs in the <tt>Words</tt> library all have the same structure involving five nested <tt>for</tt> loops.</p>
+<p>The last line of <tt>Words</tt> is</p>
+<pre> feval(['Words' p q],Gray,Green,GreenLoc,Gold,GoldLoc)</pre><p><tt>Gray</tt>, <tt>Green</tt> and <tt>Gold</tt> are lists of letters with specified colors and with locations <tt>GreenLoc</tt> and <tt>GoldLoc</tt>. Locating the green letters is easy because they must be in specific slots. Locating the gold letters is tricky because each of them can be in any of several different slots.</p>
+<p>For example, this situation in the NYT puzzle described below would result in a call to <tt>Words13</tt> with</p>
+<pre> Gray = 'AIHEC'
+ Green = 'T'
+ GreenLoc = 5
+ Gold = 'ROU'
+ GoldLoc = {[2,3],[3,4],[1,2,4]}</pre><p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/grout3.gif" vspace="5" /> </p>
+<h4>Wordle<a name="313da354-b5c6-4675-929e-3bbe89e7a74a"></a></h4><p><tt>Wordle</tt> starts a game by choosing a secret random target from the vocabulary, or from a smaller subset about half the size. At the same time, I choose my starting word, which is usually <tt>RATIO</tt>. My assistants respond with the Wordler Window and a simple keyboard.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/keybored.png" vspace="5" /> </p>
+<p>The gold <tt>O</tt> tells me the target contains an <tt>O</tt>, that it is not in position 5, and the target does not contain <tt>R</tt>, <tt>A</tt>, <tt>T</tt>, or <tt>I</tt>. I know there are hundreds of such words in the vocabulary. One of them is <tt>DEMOS</tt>, which I enter on the keyboard.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/demos.gif" vspace="5" /> </p>
+<p><tt>DEMOS</tt> happens to be a very lucky choice. The target has an <tt>E</tt> in the second slot, an <tt>S</tt> in the last slot, <tt>M</tt> and <tt>O</tt> in the remaining slots, and no <tt>D</tt>. When the answer does not occur to me in a minute or two, I click the <tt>Words</tt> button. The response is</p>
+<pre> MEOWS
+ cnt = 1</pre><p>So, there is only one word to choose, and it earns five greens.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/meows.gif" vspace="5" /> </p>
+<h4>NYT<a name="bc74a1cc-f3c3-4b86-bd1b-7a19d18b8d36"></a></h4><p>Let's do the <i>Times</i> puzzle from March 23. I start with my mathematical <tt>RATIO</tt>. I see that the answer contains <tt>R</tt>, <tt>T</tt> and <tt>O</tt> and does not contain <tt>A</tt> or <tt>I</tt>.</p>
+<p>I happen to remember that <tt>OTHER</tt> qualifies. It does not hit any new letters, but it places additional restrictions on the ones I already have and eliminates <tt>E</tt> and <tt>H</tt>.</p>
+<p><tt>Words</tt> now lists 37 words that I should choose from. I pick <tt>COURT</tt> because it contains <tt>U</tt>, the only remaining vowel.</p>
+<p><tt>Words</tt> informs me that there are only two possibilities left, <tt>TROUT</tt> and <tt>GROUT</tt>. I pick the one without a double consonant and it is the winner.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/grout_combo.gif" vspace="5" /> </p>
+<h4>Pared Down<a name="a2a62471-6d35-4253-8c11-b0de6725afd4"></a></h4><p>Here is an atypical, but instructive, example. For this puzzle I am pleased to see <tt>Wordler</tt> gives <tt>RATIO</tt> a green <tt>A</tt> in position 2 and a gold <tt>R</tt> somewhere in positions 3 through 5. I remember one of my favorite "technical" terms, <tt>PARSE</tt>.</p>
+<p>To use a baseball metaphor, <tt>PARSE</tt> hits a triple and almost gets an in-the-park home run. Now I need to ask <tt>Words</tt> for qualifying responses. There are exactly two, <tt>PARED</tt> and <tt>PARER</tt>. (Both come from the verb "to pare", which means to cut the outer skin off something.)</p>
+<p>One of the choices has a double consonant, so I choose the other one. When it doesn't fly, the only choice left earns the five-leaf clover.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/parer_combo.gif" vspace="5" /> </p>
+<h4>Five Golds<a name="3634c294-6419-4ca0-9339-7a1e50630492"></a></h4><p>How do I generate five golds? I need the starting guess to be a <i>permutation</i> of the final answer. A few moments thought suggests <tt>TAKES</tt> and <tt>SKATE</tt>. I am sure there are other possibilities. But this one is special because <tt>STEAK</tt> makes it triplets. <tt>TEAKS</tt> would make four permutations but does not meet the "hard mode" restrictions.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/skate_combo.gif" vspace="5" /> </p>
+<h4>Thanks<a name="fb298646-e9d7-4395-ba63-3e8d2607dc82"></a></h4><p>Over a year ago, MATLAB programs for solving Wordle puzzles were described by <a href="https://blogs.mathworks.com/loren/2022/01/18/building-a-wordle-solver/">Adam Filion</a> as a guest blogger on Loren's blog and by <a href="https://www.youtube.com/watch?v=bVTcQtEnOlk">Matt Tearle</a> with a YouTube video.</p>
+<h4>Software<a name="3daf42e9-4815-4553-9b08-c2945d557011"></a></h4><p>Working on my Wordle obsession has been very interesting. I have developed some useful tools and I see forgotten five-letter words everywhere. You can share the fun by downloading the code at <a href="https://blogs.mathworks.com/cleve/files/Wordler_mzip.m">this link</a> and running it yourself.</p>
+<!--
+ function grabCode_5b2bc84c600a4474a0eabbc4d9bb6ab8() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='5b2bc84c600a4474a0eabbc4d9bb6ab8 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 5b2bc84c600a4474a0eabbc4d9bb6ab8';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2023 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+5b2bc84c600a4474a0eabbc4d9bb6ab8 ##### SOURCE BEGIN #####
+%% Three Wordle Assistants
+% When I tackle a Wordle puzzle, I like to make all the key decisions
+% myself. My three assistants set up puzzles and suggest words
+% when I ask for help, but I guide the actual solution.
+% My assistants also make it possible for me to play Wordle anywhere,
+% anytime, even when my laptop is in airplane mode.
+% I don't need the _New York Times_ or access to the Web.
+
+%% Three Assistants
+% |Wordler|, |Words| and |Wordie| are the three assistants.
+% |Wordler| replaces the _Times_ by generating puzzles
+% and evaluating responses.
+% |Words| provides lists of possible responses.
+% |Wordie| handles the Wordler Window and colors the letters gray,
+% green or gold.
+
+%% Vocabulary
+% |Words| has a |vocabulary| of 4665 five-letter English words.
+% Any of them are acceptable responses.
+% The vocabulary begins with
+%
+% vocab = [ ...
+% "ABEAM" "ABETS" "ABHOR" "ABIDE" "ABLED" "ABLER" "ABODE" "ABORT" ...
+%
+% And, 584 lines later, ends with
+%
+% "ZILCH" "ZINCS" "ZINGS" "ZIPPY" "ZOMBI" "ZONAL" "ZONED" "ZONES" ...
+% "ZOOMS" ];
+%
+% If you were to print the entire vocabulary with 40 lines per page,
+% you would print over 100 pages of words.
+
+%% Words
+% It took me a long time to write the |Words| assistant, which is
+% called whenever the Words button in the Wordle Window is clicked.
+%
+% <<ratio.gif>>
+%
+% |Words| is supported by a seventeen-program library of functions
+% named |Wordspq| where |p| and |q| are nonnegative integers
+% with |p+q <= 5|.
+% |Wordspq| finds words with |p| green letters and |q| gold letters.
+% The programs in the |Words| library all have the same structure
+% involving five nested |for| loops.
+%
+% The last line of |Words| is
+%
+% feval(['Words' p q],Gray,Green,GreenLoc,Gold,GoldLoc)
+%
+% |Gray|, |Green| and |Gold| are lists of letters with specified
+% colors and with locations |GreenLoc| and |GoldLoc|. Locating the
+% green letters is easy because they must be in specific slots.
+% Locating the gold letters is tricky because each of them
+% can be in any of several different slots.
+%
+% For example, this situation in the NYT puzzle described below
+% would result in a call to |Words13| with
+%
+% Gray = 'AIHEC'
+% Green = 'T'
+% GreenLoc = 5
+% Gold = 'ROU'
+% GoldLoc = {[2,3],[3,4],[1,2,4]}
+%
+% <<grout3.gif>>
+
+%% Wordle
+% |Wordle| starts a game by choosing a secret random target
+% from the vocabulary, or from a smaller subset about half the size.
+% At the same time, I choose my starting word, which is usually
+% |RATIO|. My assistants respond with the Wordler Window
+% and a simple keyboard.
+%
+% <<keybored.png>>
+%
+
+%%
+% The gold |O| tells me the target contains an |O|, that it is not
+% in position 5, and the target does not contain |R|, |A|, |T|, or |I|.
+% I know there are hundreds of such words in the vocabulary.
+% One of them is |DEMOS|, which I enter on the keyboard.
+%
+% <<demos.gif>>
+%
+
+%%
+% |DEMOS| happens to be a very lucky choice. The target has an
+% |E| in the second slot, an |S| in the last slot, |M| and |O|
+% in the remaining slots, and no |D|.
+% When the answer does not occur to me in a minute or two,
+% I click the |Words| button. The response is
+%
+% MEOWS
+% cnt = 1
+%
+% So, there is only one word to choose, and it earns five greens.
+%
+% <<meows.gif>>
+%
+
+%% NYT
+% Let's do the _Times_ puzzle from March 23.
+% I start with my mathematical |RATIO|.
+% I see that the answer contains |R|, |T| and |O| and does
+% not contain |A| or |I|.
+%
+% I happen to remember that |OTHER| qualifies. It does not hit
+% any new letters, but it places additional restrictions on
+% the ones I already have and eliminates |E| and |H|.
+%
+% |Words| now lists 37 words that I should choose from. I pick |COURT|
+% because it contains |U|, the only remaining vowel.
+%
+% |Words| informs me that there are only two possibilities left,
+% |TROUT| and |GROUT|. I pick the one without a double consonant
+% and it is the winner.
+%
+% <<grout_combo.gif>>
+
+%% Pared Down
+% Here is an atypical, but instructive, example. For this puzzle
+% I am pleased to see |Wordler| gives |RATIO| a green |A| in position 2
+% and a gold |R| somewhere in positions 3 through 5. I remember one of
+% my favorite "technical" terms, |PARSE|.
+%
+% To use a baseball metaphor, |PARSE| hits a triple and almost
+% gets an in-the-park home run. Now I need to ask |Words|
+% for qualifying responses. There are exactly two, |PARED| and
+% |PARER|. (Both come from the verb "to pare", which means to cut
+% the outer skin off something.)
+%
+% One of the choices has a double consonant, so I choose the other
+% one. When it doesn't fly, the only choice left earns the
+% five-leaf clover.
+%
+% <<parer_combo.gif>>
+%
+
+%% Five Golds
+% How do I generate five golds? I need the starting guess to be
+% a _permutation_ of the final answer. A few moments thought
+% suggests |TAKES| and |SKATE|. I am sure there are other possibilities.
+% But this one is special because |STEAK| makes it triplets.
+% |TEAKS| would make four permutations but does not meet
+% the "hard mode" restrictions.
+%
+% <<skate_combo.gif>>
+%
+
+%% Thanks
+% Over a year ago, MATLAB programs for solving Wordle puzzles
+% were described by
+% <https://blogs.mathworks.com/loren/2022/01/18/building-a-wordle-solver/
+% Adam Filion> as a guest blogger on Loren's blog and by
+% <https://www.youtube.com/watch?v=bVTcQtEnOlk
+% Matt Tearle> with a YouTube video.
+
+%% Software
+% Working on my Wordle obsession has been very interesting.
+% I have developed some useful tools and I see forgotten five-letter
+% words everywhere. You can share the fun by downloading the code at
+% <https://blogs.mathworks.com/cleve/files/Wordler_mzip.m
+% this link> and running it yourself.
+##### SOURCE END ##### 5b2bc84c600a4474a0eabbc4d9bb6ab8
+-->
+
+
+
+
+ Wordle Sneak Previews
+
+ 2023-03-24T19:18:10-06:00
+ https://hpc.social/2023/wordle-sneak-previews
+ <div class="content"><!--introduction--><!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#55eb7850-c832-4b41-9b94-907594d82fcc">Early Birds</a></li></ul></div>
+<h4>Early Birds<a name="55eb7850-c832-4b41-9b94-907594d82fcc"></a></h4><p>There several sites on the Web that reveal the solution to the Wordle puzzle in the <i>New York Times</i> while it is still in play. Some of these sites are in India, where India Standard Time is 9-1/2 hours ahead of Eastern Daylight Time, so India sees the puzzle long before the USA does. These sites surround their puzzle clues with ads and are trying to get more visitors.</p>
+<p>For a while, whenever I get a chance, I intend try to update this animation with the latest reveals. I don't have any obvious ads, but I have to admit that my own motivation is similar to the other sites.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/word_gif37.gif" vspace="5" /> </p>
+<!--
+ function grabCode_432eb9e3bcc34e8da1135593bb49ee5f() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='432eb9e3bcc34e8da1135593bb49ee5f ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 432eb9e3bcc34e8da1135593bb49ee5f';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2023 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+432eb9e3bcc34e8da1135593bb49ee5f ##### SOURCE BEGIN #####
+%% Wordle Sneak Previews
+
+%% Early Birds
+% There several sites on the Web that reveal the solution to the
+% Wordle puzzle in the _New York Times_ while it is still in play.
+% Some of these sites are in India, where India Standard Time is
+% 9-1/2 hours ahead of Eastern Daylight Time, so India sees
+% the puzzle long before the USA does.
+% These sites surround their puzzle clues with ads
+% and are trying to get more visitors.
+%
+% For a while, whenever I get a chance, I intend try to update this
+% animation with the latest reveals. I don't have any obvious ads,
+% but I have to admit that my own motivation is similar to the other
+% sites.
+%
+% <<word_gif37.gif>>
+%
+##### SOURCE END ##### 432eb9e3bcc34e8da1135593bb49ee5f
+-->
+
+
+
+
+ WordBot and Words, My Wordle Assistants
+
+ 2023-03-11T19:07:02-07:00
+ https://hpc.social/2023/wordbot-and-words-my-wordle-assistants
+ <div class="content"><!--introduction--><p>I am late joining the Wordle craze. Over a year ago, MATLAB programs for solving Wordle puzzles were described by <a href="https://blogs.mathworks.com/loren/2022/01/18/building-a-wordle-solver/">Adam Filion</a> as a guest blogger on Loren's blog and by <a href="https://www.youtube.com/watch?v=bVTcQtEnOlk">Matt Tearle</a> with a YouTube video. But my programs for Wordle Assistants are different. <tt>WordBot</tt> doesn't try to solve any puzzles and <tt>Words</tt> just supplies lists of possible words. I enjoy providing the solution logic myself.</p>
+<p>Here are two examples, taken from recent Wordle puzzles in the <a href="https://www.nytimes.com/games/wordle/index.html"><i>New York Times</i></a>.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#07e1455b-4718-47a2-93c5-cce24028b05f">Wednesday</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#e5f6c4a9-b502-447f-9003-f6a351a4a093">Thursday</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#f246159e-8444-40a5-9280-1750f81c8c5d">Four Days in March</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#fa65c920-c034-4600-910d-ad06c3df4153">Software</a></li></ul></div>
+<h4>Wednesday<a name="07e1455b-4718-47a2-93c5-cce24028b05f"></a></h4><p><tt>WordBot</tt> has a list of 4676 possible words, but knows nothing about their probabilities, so I don't ask for any assistance with the opening guess.</p>
+<p>I like to use mathematical words whenever possible. I usually start with <tt>RATIO</tt>, which has three vowels and two popular consonants. <tt>RATIO</tt> was a good opening move for the puzzle in the <i>Times</i> on Wednesday. It received a green <tt>R</tt> and a gold <tt>A</tt>. I informed <tt>WordBot</tt> of our good fortune using 2, 1 and 0 to indicate green, gold and gray. My faithful assistant responded by reproducing the first graphic in the <i>Times</i>.</p>
+<pre class="codeinput"> WordBot <span class="string">ratio</span> <span class="string">21000</span>
+</pre><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/WordBot_blog_01.png" vspace="5" /> <p><tt>Words</tt> is my suite of programs that produce lists of acceptable words for various scenarios. In this situation with an <tt>R</tt> as the first letter, an <tt>A</tt> somewhere in the last three letters and <tt>T</tt>, <tt>I</tt> and <tt>O</tt> on the gray list, <tt>Words</tt> finds 25 words, starting with <tt>REACH</tt> and ending with <tt>RUMBA</tt>.</p>
+<p>The last of those 25 words got my attention. I decided to try <tt>RUMBA</tt> on my second move. I knew <tt>RUMBA</tt> was unlikely to succeed but would be spectacular if it did. Sure enough, Wordle didn't want to dance.</p>
+<pre class="codeinput"> WordBot <span class="string">rumba</span> <span class="string">20001</span>
+</pre><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/WordBot_blog_02.png" vspace="5" /> <p>Three more letters gray-listed and <tt>A</tt> limited to two slots reduces the number of possible words from 25 to 18. The first word on the list is still <tt>REACH</tt>.</p>
+<pre class="codeinput"> WordBot <span class="string">reach</span> <span class="string">22100</span>
+</pre><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/WordBot_blog_03.png" vspace="5" /> <p>There are now 11 possibilities.</p>
+<pre class="language-matlab">READS
+READY
+REALS
+REAPS
+REARS
+REGAL
+RELAX
+RELAY
+RENAL
+REPAY
+RERAN
+</pre><p>I need to relax.</p>
+<pre class="codeinput"> WordBot <span class="string">relax</span> <span class="string">22120</span>
+</pre><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/WordBot_blog_04.png" vspace="5" /> <p>I don't need another list of possibilities. I can quickly see the previous list has only two words that end in <tt>L</tt>. The choice between "fit for a monarch" and "pertaining to kidney function" is clear. I have solved Wednesday's puzzle in five moves, including the Hail Mary at move two.</p>
+<pre class="codeinput"> WordBot <span class="string">regal</span> <span class="string">22222</span>
+</pre><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/WordBot_blog_05.png" vspace="5" /> <pre class="codeinput"> close
+</pre><h4>Thursday<a name="e5f6c4a9-b502-447f-9003-f6a351a4a093"></a></h4><p>Thursday's puzzle in the <i>Times</i> offered different challenges. As always, I started with <tt>RATIO</tt>. This time I get only one gold letter.</p>
+<pre class="codeinput"> WordBot <span class="string">ratio</span> <span class="string">10000</span>
+</pre><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/WordBot_blog_06.png" vspace="5" /> <p>I need an <tt>R</tt> somewhere in the last four positions and can't use <tt>A</tt>, <tt>T</tt>, <tt>I</tt> or <tt>O</tt>. <tt>Words</tt> knows 229 qualified candidates. I choose another mathematical word.</p>
+<pre class="codeinput"> WordBot <span class="string">perms</span> <span class="string">01100</span>
+</pre><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/WordBot_blog_07.png" vspace="5" /> <p>I now must have an <tt>R</tt> and an <tt>E</tt> and can't have any of those seven grays. <tt>Words</tt> offers 72 possibilities. Have I been in an accident?</p>
+<pre class="codeinput"> WordBot <span class="string">wreck</span> <span class="string">21200</span>
+</pre><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/WordBot_blog_08.png" vspace="5" /> <p>Well, that's much better. Two greens, one gold, and nine grays. There is only one possibility. The solution must be <tt>WHERE</tt>.</p>
+<pre class="codeinput"> WordBot <span class="string">where</span> <span class="string">22222</span>
+</pre><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/WordBot_blog_09.png" vspace="5" /> <pre class="codeinput"> close
+</pre><h4>Four Days in March<a name="f246159e-8444-40a5-9280-1750f81c8c5d"></a></h4><p>Wednesday, Thursday, Friday and Saturday.</p>
+<p>If your browser isn't showing the animation, <a href="https://blogs.mathworks.com/cleve/files/word_gif.gif">look here</a>.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/word_gif.gif" vspace="5" /> </p>
+<h4>Software<a name="fa65c920-c034-4600-910d-ad06c3df4153"></a></h4><p><a href="https://blogs.mathworks.com/cleve/files/WordBot_2_mzip.m">This code</a> is immature. Be gentle and let me know how it works for you.</p>
+<!--
+ function grabCode_a44a8488723741b3acf8277d1f858a07() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='a44a8488723741b3acf8277d1f858a07 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' a44a8488723741b3acf8277d1f858a07';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2023 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+a44a8488723741b3acf8277d1f858a07 ##### SOURCE BEGIN #####
+%% WordBot and Words, My Wordle Assistants
+% I am late joining the Wordle craze.
+% Over a year ago, MATLAB programs for solving Wordle puzzles
+% were described by
+% <https://blogs.mathworks.com/loren/2022/01/18/building-a-wordle-solver/
+% Adam Filion> as a guest blogger on Loren's blog and by
+% <https://www.youtube.com/watch?v=bVTcQtEnOlk
+% Matt Tearle> with a YouTube video.
+% But my programs for Wordle Assistants are different.
+% |WordBot| doesn't try to solve any puzzles and
+% |Words| just supplies lists of possible words.
+% I enjoy providing the solution logic myself.
+%
+% Here are two examples, taken from recent Wordle puzzles in the
+% <https://www.nytimes.com/games/wordle/index.html
+% _New York Times_>.
+
+
+%% Wednesday
+% |WordBot| has a list of 4676 possible words,
+% but knows nothing about their probabilities, so I don't ask
+% for any assistance with the opening guess.
+%
+% I like to use mathematical words whenever possible.
+% I usually start with |RATIO|, which has three vowels and two
+% popular consonants. |RATIO| was a good opening move
+% for the puzzle in the _Times_ on Wednesday.
+% It received a green |R| and a gold |A|.
+% I informed |WordBot| of our good fortune using
+% 2, 1 and 0 to indicate green, gold and gray.
+% My faithful assistant responded by reproducing the first
+% graphic in the _Times_.
+
+ WordBot ratio 21000
+
+
+%%
+% |Words| is my suite of programs that produce lists of
+% acceptable words for various scenarios. In this situation
+% with an |R| as the first letter, an |A| somewhere in the last
+% three letters and |T|, |I| and |O| on the gray list, |Words|
+% finds 25 words, starting with |REACH| and ending with |RUMBA|.
+%
+% The last of those 25 words got my attention. I decided to try |RUMBA|
+% on my second move.
+% I knew |RUMBA| was unlikely to succeed but would be
+% spectacular if it did. Sure enough, Wordle didn't want to dance.
+
+ WordBot rumba 20001
+
+%%
+% Three more letters gray-listed and |A| limited to two slots reduces the
+% number of possible words from 25 to 18.
+% The first word on the list is still |REACH|.
+
+ WordBot reach 22100
+
+%%
+% There are now 11 possibilities.
+%
+% READS
+% READY
+% REALS
+% REAPS
+% REARS
+% REGAL
+% RELAX
+% RELAY
+% RENAL
+% REPAY
+% RERAN
+%
+% I need to relax.
+%
+ WordBot relax 22120
+
+%%
+% I don't need another list of possibilities.
+% I can quickly see the previous list has only two words that
+% end in |L|. The choice between "fit for a monarch" and
+% "pertaining to kidney function" is clear.
+% I have solved Wednesday's puzzle in five moves, including the Hail Mary
+% at move two.
+
+ WordBot regal 22222
+
+%%
+ close
+
+%% Thursday
+% Thursday's puzzle in the _Times_ offered different challenges.
+% As always, I started with |RATIO|. This time I get only one
+% gold letter.
+
+ WordBot ratio 10000
+
+%%
+% I need an |R| somewhere in the last four positions and can't
+% use |A|, |T|, |I| or |O|. |Words| knows 229 qualified candidates.
+% I choose another mathematical word.
+
+ WordBot perms 01100
+
+%%
+% I now must have an |R| and an |E| and can't have any of those seven
+% grays. |Words| offers 72 possibilities. Have I been in an accident?
+
+ WordBot wreck 21200
+
+%%
+% Well, that's much better. Two greens, one gold, and nine grays.
+% There is only one possibility. The solution must be |WHERE|.
+
+ WordBot where 22222
+
+%%
+ close
+
+%% Four Days in March
+% Wednesday, Thursday, Friday and Saturday.
+%
+% If your browser isn't showing the animation,
+% <https://blogs.mathworks.com/cleve/files/word_gif.gif
+% look here>.
+%
+% <<word_gif.gif>>
+%
+
+%% Software
+% <https://blogs.mathworks.com/cleve/files/WordBot_2_mzip.m
+% This code> is immature. Be gentle and let me know how it
+% works for you.
+
+##### SOURCE END ##### a44a8488723741b3acf8277d1f858a07
+-->
+
+
+
+
+ R2-D2, Rotations and Dilations in Two Dimensions
+
+ 2023-03-03T19:50:25-07:00
+ https://hpc.social/2023/r2-d2-rotations-and-dilations-in-two-dimensions
+ <div class="content"><!--introduction--><p><tt>R2_D2</tt> is is the name I've given a new MATLAB program that provides animations of 2-by-2 rotation and dilation matrices. I admit I chose "dilations" so the acronym would be memorable, but otherwise the code has little to do with the famous Star Wars droid.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#44861ff7-11fc-4399-ad23-d58213ec0d26">House</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#23ac6c7d-9deb-4368-af3a-b72341fd82e0">Hand</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#a87fd4bd-4298-4c71-a3c2-a9f90fa02fbe">Rotation</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#4b0e42eb-235d-4dc6-8a7e-5cfafe76b486">Dilation</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#3bd73ac8-4279-4bb6-b08e-9f866181f581">Both</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#384f6c01-d1f5-456f-a0d0-b31ba5b772b2"><tt>R2_D2</tt></a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#f6931ffe-5f30-439a-97cb-2e04cab0aeaf">Further Reading</a></li></ul></div>
+<h4>House<a name="44861ff7-11fc-4399-ad23-d58213ec0d26"></a></h4><p>This outline of a house is featured in <a href="https://www.mathworks.com/moler/exm/chapters.html"><i>Experiments with MATLAB</i></a>. The data are the 11 blue dots. The coordinates of each dot form a 2-by-1 vector; the 2-by-2 rotation and dilation matrices multiply each of these vectors separately. (The lines between the dots complete the picture and are not involved in any computation.)</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/house.gif" vspace="5" /> </p>
+<p>The house also appears in several editions of Gil Strang's textbooks. The cover of the third edition of Strang's <a href="https://www.amazon.com/Introduction-Linear-Algebra-Gilbert-Strang/dp/0961408898"><i>Introduction to Linear Algebra</i></a> features nine houses on a quilt made by Gil's friend Chris Curtis.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/quilt.png" vspace="5" /> </p>
+<h4>Hand<a name="23ac6c7d-9deb-4368-af3a-b72341fd82e0"></a></h4><p>This outline of a hand, which I made from measurements of my own hand, is also used in <a href="https://www.mathworks.com/moler/exm/chapters.html"><i>Experiments with MATLAB</i></a>. There are 37 points, so <tt>Hand</tt> is a 2-by-37 matrix.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/hand.gif" vspace="5" /> </p>
+<h4>Rotation<a name="a87fd4bd-4298-4c71-a3c2-a9f90fa02fbe"></a></h4><p>Multiplication by this matrix produces a two-dimensional rotation by an angle <tt>theta</tt>.</p>
+<p>$$ R = \left(
+ \begin{array}{rr}
+ \cos{\theta} & \sin{\theta} \\
+ - \sin{\theta} & \cos{\theta}
+ \end{array}
+ \right) $$</p>
+<p><tt>R</tt> is displayed in the first panel. If the house is not rotating in your browser, try this link: <a href="https://blogs.mathworks.com/cleve/files/house_rotate.gif">https://blogs.mathworks.com/cleve/files/house_rotate.gif</a></p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/house_rotate.gif" vspace="5" /> </p>
+<h4>Dilation<a name="4b0e42eb-235d-4dc6-8a7e-5cfafe76b486"></a></h4><p>Dilation is the process of making objects larger or smaller. Multiplication by this diagonal matrix produces a dilation by a factor <tt>sigma</tt>.</p>
+<p>$$ S = \left(
+ \begin{array}{rr}
+ \sigma & 0 \\
+ 0 & \sigma
+ \end{array}
+ \right) $$</p>
+<p><tt>S</tt> is displayed in the second panel. The animation is also available at: <a href="https://blogs.mathworks.com/cleve/files/hand_dilate.gif">https://blogs.mathworks.com/cleve/files/hand_dilate.gif</a></p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/hand_dilate.gif" vspace="5" /> </p>
+<h4>Both<a name="3bd73ac8-4279-4bb6-b08e-9f866181f581"></a></h4><p>Here rotation and dilation are combined. The product of the rotation and dilation matrices drives the action. If you are missing all the action, try: <a href="https://blogs.mathworks.com/cleve/files/hand_both.gif">https://blogs.mathworks.com/cleve/files/hand_both.gif</a></p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/hand_both.gif" vspace="5" /> </p>
+<h4><tt>R2_D2</tt><a name="384f6c01-d1f5-456f-a0d0-b31ba5b772b2"></a></h4><p>When you run <tt>R2_D2</tt> on your own computer, you can drive the rotations and dilations yourself. Mousing outside of the object creates rotation and mousing inside produces dilation.</p>
+<p>The <tt>R2_D2</tt> program is available from <a href="https://blogs.mathworks.com/cleve/files/R2_D2_4.m">https://blogs.mathworks.com/cleve/files/R2_D2_4.m</a>.</p>
+<h4>Further Reading<a name="f6931ffe-5f30-439a-97cb-2e04cab0aeaf"></a></h4><p>If you are not familiar with matrices, or just want a quick refresher, check out the <a href="https://www.mathworks.com/content/dam/mathworks/mathworks-dot-com/moler/exm/chapters/matrices.pdf">Matrices</a> chapter of <a href="https://www.mathworks.com/moler/exm/chapters.html"><i>Experiments with MATLAB</i></a>. Exercise 4.14 is particularly handy.</p>
+<!--
+ function grabCode_0fd9ed7550fd4ba3911f9d86fad47cd5() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='0fd9ed7550fd4ba3911f9d86fad47cd5 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 0fd9ed7550fd4ba3911f9d86fad47cd5';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2023 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+0fd9ed7550fd4ba3911f9d86fad47cd5 ##### SOURCE BEGIN #####
+%% R2-D2, Rotations and Dilations in Two Dimensions
+% |R2_D2| is is the name I've given a new MATLAB program that provides
+% animations of 2-by-2 rotation and dilation matrices.
+% I admit I chose "dilations"
+% so the acronym would be memorable, but otherwise
+% the code has little to do with the famous Star Wars droid.
+
+%% House
+% This outline of a house is featured in
+% <https://www.mathworks.com/moler/exm/chapters.html
+% _Experiments with MATLAB_>.
+% The data are the 11 blue dots. The coordinates of each dot form a 2-by-1
+% vector; the 2-by-2 rotation and dilation matrices multiply each of
+% these vectors separately. (The lines between the dots complete the
+% picture and are not involved in any computation.)
+%
+% <<house.gif>>
+%
+% The house also appears in several editions of Gil Strang's textbooks.
+% The cover of the third edition of Strang's
+% <https://www.amazon.com/Introduction-Linear-Algebra-Gilbert-Strang/dp/0961408898
+% _Introduction to Linear Algebra_> features nine houses on a quilt
+% made by Gil's friend Chris Curtis.
+%
+% <<quilt.png>>
+%
+
+
+%% Hand
+% This outline of a hand, which I made from measurements of my own hand,
+% is also used in
+% <https://www.mathworks.com/moler/exm/chapters.html
+% _Experiments with MATLAB_>.
+% There are 37 points, so |Hand| is a 2-by-37 matrix.
+%
+% <<hand.gif>>
+%
+
+%% Rotation
+% Multiplication by this matrix produces a two-dimensional
+% rotation by an angle |theta|.
+%
+% $$ R = \left(
+% \begin{array}{rr}
+% \cos{\theta} & \sin{\theta} \\
+% - \sin{\theta} & \cos{\theta}
+% \end{array}
+% \right) $$
+%
+% |R| is displayed in the first panel.
+% If the house is not rotating in your browser, try this link:
+% <https://blogs.mathworks.com/cleve/files/house_rotate.gif>
+%
+%
+% <<house_rotate.gif>>
+%
+
+%% Dilation
+% Dilation is the process of making objects larger or smaller.
+% Multiplication by this diagonal matrix
+% produces a dilation by a factor |sigma|.
+%
+% $$ S = \left(
+% \begin{array}{rr}
+% \sigma & 0 \\
+% 0 & \sigma
+% \end{array}
+% \right) $$
+%
+% |S| is displayed in the second panel.
+% The animation is also available at:
+% <https://blogs.mathworks.com/cleve/files/hand_dilate.gif>
+%
+%
+% <<hand_dilate.gif>>
+%
+
+%% Both
+% Here rotation and dilation are combined.
+% The product of the rotation and dilation matrices drives the action.
+% If you are missing all the action, try:
+% <https://blogs.mathworks.com/cleve/files/hand_both.gif>
+%
+% <<hand_both.gif>>
+%
+
+%% |R2_D2|
+% When you run |R2_D2| on your own computer, you can drive the
+% rotations and dilations yourself. Mousing outside of the object
+% creates rotation and mousing inside produces dilation.
+%
+% The |R2_D2| program is available from
+% <https://blogs.mathworks.com/cleve/files/R2_D2_4.m>.
+%
+%% Further Reading
+% If you are not familiar with matrices, or just want a quick
+% refresher, check out the
+% <https://www.mathworks.com/content/dam/mathworks/mathworks-dot-com/moler/exm/chapters/matrices.pdf
+% Matrices> chapter of
+% <https://www.mathworks.com/moler/exm/chapters.html
+% _Experiments with MATLAB_>.
+% Exercise 4.14 is particularly handy.
+##### SOURCE END ##### 0fd9ed7550fd4ba3911f9d86fad47cd5
+-->
+
+
+
+
+ My Chat With ChatGPT
+
+ 2023-02-22T02:06:53-07:00
+ https://hpc.social/2023/my-chat-with-chatgpt
+ <div class="content"><!--introduction--><p>While it is still fresh in my mind, I want to describe the conversation I had with <a href="https://openai.com/blog/chatgpt/">a publicly available version of ChatGPT</a>, the much-discussed large language model, LLM, for conversational artificial intelligence.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#5c070bbf-dca9-48a1-8be7-ac106737302f">Mixed Reception</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#6bc024ea-c1ab-40ea-b7de-687748c50bc9">Where Is Sydney?</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#bfe0d37b-cc5a-4998-9d8d-f16c425327f8">Me and AI</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#d44eee64-c400-46cb-ae9e-b18066fe1fb8">Me and ChatGPT</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#3fca7af1-1ac0-4481-8135-c47e5a3db750">AI Winters</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#ecb671af-be78-4da3-b321-d89f60308ce3">Truth</a></li></ul></div>
+<h4>Mixed Reception<a name="5c070bbf-dca9-48a1-8be7-ac106737302f"></a></h4><p>A newer version of ChatGPT than the one I used is available to selected journalists and computer industry observers. Their reaction has been, shall I say, mixed. At first, some of the reports were positive and even ecstatic. Most of these early reports were from people whose primary concern is the stock market, not AI technology. Many of the more recent and more careful reports have been negative and critical.</p>
+<h4>Where Is Sydney?<a name="6bc024ea-c1ab-40ea-b7de-687748c50bc9"></a></h4><p>I have given ChatGPT the nickname "Chad". Some early users of one of Chad's competitors asked deliberately provocative questions and encountered a cranky alter-ego named "Sydney". I didn't ask my Chad any unfair questions and didn't encounter any Sydney's.</p>
+<h4>Me and AI<a name="bfe0d37b-cc5a-4998-9d8d-f16c425327f8"></a></h4><p>I have been a long-time observer of -- although not a contributor to -- artificial intelligence research.</p>
+<div><ul><li>I took AI courses at Stanford from the inventor of the field, John McCarthy.</li></ul></div>
+<div><ul><li>Bill McKeeman and I entered McCarthy's chess program in a <i>San Francisco Chronicle's</i> by-mail chess contest. (The computer did not fair well.)</li></ul></div>
+<div><ul><li>I used Joe Weizenbaum's computer program Eliza, the very first Chat Bot.</li></ul></div>
+<div><ul><li>I was once married to someone with a PhD in AI.</li></ul></div>
+<div><ul><li>Symbolic Math, like MathWorks now does in our Toolbox, and which we used to do with Macsyma and Maple, was once considered AI.</li></ul></div>
+<div><ul><li>The wild animal trail cameras project that I did a few years ago with Heather Gorr and Jim Sanderson uses modern machine learning and AI.</li></ul></div>
+<h4>Me and ChatGPT<a name="d44eee64-c400-46cb-ae9e-b18066fe1fb8"></a></h4><p>I talked to -- I should say chatted with, or actually typed at -- Chad for most of an hour on a recent evening. Think of Stephen Hawking in a Web Browser. Chad's responses were always courteous and conversational. And the majority of Chad's responses were factually correct.</p>
+<p>However, a surprising number of Chad's answers were just plain wrong. Some examples:</p>
+<div><ul><li>I was neither born in, nor raised in, rural New Mexico.</li></ul></div>
+<div><ul><li>I did not get a PhD from the University of Michigan. Neither did my wife, Patsy.</li></ul></div>
+<div><ul><li>Patsy is not the mother of my daughter Kam, nor of my sister Betsy.</li></ul></div>
+<div><ul><li>Patsy is not an expert in computational fluid dynamics.</li></ul></div>
+<div><ul><li>Ken Kennedy did not coin the term "embarrassingly parallel."</li></ul></div>
+<div><ul><li>Pam McCorduck never worked for the Santa Fe Institute.</li></ul></div>
+<div><ul><li>I cannot find any reference to the guys Chad claimed improved Sympletic Spacewar.</li></ul></div>
+<p>All of Chad's incorrect responses could have been fact-checked by simple Google queries.</p>
+<h4>AI Winters<a name="3fca7af1-1ac0-4481-8135-c47e5a3db750"></a></h4><p>Everybody wants to combine the conversational style offered by large language models with the reliability and breadth provided by Google. Now THAT sounds like a really good idea.</p>
+<p>Artificial intelligence has a history of flush successes interspersed with fallow periods known as AI Winters. I am afraid that continued obsession with Chat Bots might lead to another AI Winter.</p>
+<h4>Truth<a name="ecb671af-be78-4da3-b321-d89f60308ce3"></a></h4><p>Steve Eddins revealed the Truth behind ChatGPT with this internal MathWorks Yammer post.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/ChatGPT_truth.jpg" vspace="5" /> </p>
+<!--
+ function grabCode_49d101acd4414820a4f6fe4b080b1113() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='49d101acd4414820a4f6fe4b080b1113 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 49d101acd4414820a4f6fe4b080b1113';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2023 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+49d101acd4414820a4f6fe4b080b1113 ##### SOURCE BEGIN #####
+%% My Chat with ChatGPT
+% While it is still fresh in my mind, I want to describe the conversation
+% I had with
+% <https://openai.com/blog/chatgpt/
+% a publicly available version of ChatGPT>, the much-discussed
+% large language model, LLM, for conversational artificial intelligence.
+
+%% Mixed Reception
+% A newer version of ChatGPT than the one I used is
+% available to selected journalists and computer industry observers.
+% Their reaction has been, shall I say, mixed.
+% At first, some of the reports were positive and even ecstatic.
+% Most of these early reports were from people whose primary concern
+% is the stock market, not AI technology. Many of the more recent and
+% more careful reports have been negative and critical.
+
+%% Where Is Sydney?
+% I have given ChatGPT the nickname "Chad".
+% Some early users of one of Chad's competitors asked
+% deliberately provocative questions and encountered a cranky alter-ego
+% named "Sydney". I didn't ask my Chad any unfair questions and
+% didn't encounter any Sydney's.
+
+%% Me and AI
+% I have been a long-time observer of REPLACE_WITH_DASH_DASH although not a contributor to REPLACE_WITH_DASH_DASH
+% artificial intelligence research.
+%
+% * I took AI courses at Stanford from the inventor of
+% the field, John McCarthy.
+%
+% * Bill McKeeman and I entered McCarthy's chess program in
+% a _San Francisco Chronicle's_ by-mail chess contest.
+% (The computer did not fair well.)
+%
+% * I used Joe Weizenbaum's computer program Eliza,
+% the very first Chat Bot.
+%
+% * I was once married to someone with a PhD in AI.
+%
+% * Symbolic Math, like MathWorks now does in our Toolbox, and which
+% we used to do with Macsyma and Maple, was once considered AI.
+%
+% * The wild animal trail cameras project that I did a few years ago with
+% Heather Gorr and Jim Sanderson uses modern machine learning and AI.
+
+%% Me and ChatGPT
+% I talked to REPLACE_WITH_DASH_DASH I should say chatted with, or actually typed at REPLACE_WITH_DASH_DASH
+% Chad for most of an hour on a recent evening.
+% Think of Stephen Hawking in a Web Browser.
+% Chad's responses were always courteous and conversational.
+% And the majority of Chad's responses were factually correct.
+%
+% However, a surprising number of Chad's answers were just plain wrong.
+% Some examples:
+%
+% * I was neither born in, nor raised in, rural New Mexico.
+%
+% * I did not get a PhD from the University of Michigan.
+% Neither did my wife, Patsy.
+%
+% * Patsy is not the mother of my daughter Kam,
+% nor of my sister Betsy.
+%
+% * Patsy is not an expert in
+% computational fluid dynamics.
+%
+% * Ken Kennedy did not coin the term "embarrassingly parallel."
+%
+% * Pam McCorduck never worked for the Santa Fe Institute.
+%
+% * I cannot find any reference to the guys Chad claimed
+% improved Sympletic Spacewar.
+%
+% All of Chad's incorrect responses could have been fact-checked
+% by simple Google queries.
+
+%% AI Winters
+% Everybody wants to combine the conversational style offered by
+% large language models with the reliability and breadth provided
+% by Google. Now THAT sounds like a really good idea.
+%
+% Artificial intelligence has a history of flush successes interspersed
+% with fallow periods known as AI Winters. I am afraid that
+% continued obsession with Chat Bots might lead to another AI Winter.
+
+%% Truth
+% Steve Eddins revealed the Truth behind ChatGPT with this internal
+% MathWorks Yammer post.
+%
+% <<ChatGPT_truth.jpg>>
+##### SOURCE END ##### 49d101acd4414820a4f6fe4b080b1113
+-->
+
+
+
+
+ Grafix Users Guide
+
+ 2023-02-10T18:36:06-07:00
+ https://hpc.social/2023/grafix-users-guide
+ <div class="content"><!--introduction--><p>This is a quick look at <tt>Grafix</tt>, our tool for exploring matrices via 3-D computer graphics.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Opening.png" vspace="5" /> </p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#21a702a7-c647-44ae-818a-6f571fa09592">Matrices</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#7cfcc1d4-26d2-4b2e-b4cb-a0ca04383ff8">Axis</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#6ce3a663-e301-4ddb-bc4d-58ae5e8f3b51">Rx</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#f007d1f0-d76b-4e3e-bea3-49bd18805a1f">Ry</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#200c71a6-5d9f-4c03-8a03-00476f103160">Rz</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#8dd6ed79-ba75-409b-a59d-68244c928c7a">Tx</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#a9651b74-3170-4b23-a015-890b537b778a">Ty</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#ce30422a-3bb7-4beb-90c6-3dfe5eb88351">Tz</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#20f8cb07-c525-4f1b-a1ae-f9b6320078eb">S</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#e8ae8340-3615-4ed7-90e7-b185a33f370a">Switches</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#097b4cbd-7971-430f-aa63-04db38192c6e">Pitch, Roll, Yaw</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#e558e05a-1bc3-41ed-a63b-ff056cf04620">Start, Reset, Viz</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#9d1fa1cc-0fe6-4d6f-9ca6-a50f0644fc62">Apps/taxi</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#0c8793f3-d9d5-45ef-90a8-7ec0c83356ca">Apps/takeoff</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#c20254e9-3887-4d66-9903-db87c5c7bb30">Prop</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#1adf580c-785f-4333-9494-0f5657c1ce53">Info</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#095cf406-3f28-4e05-ab8a-43d29a3310c1">Exercises</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#6df5e80a-e9fa-45c4-aff2-03edb1ccb334">Software</a></li></ul></div>
+<h4>Matrices<a name="21a702a7-c647-44ae-818a-6f571fa09592"></a></h4><p>The word <i>matrix</i> comes from the Latin word <i>mater</i>, which means <i>mother</i> or <i>origin</i>. Matrices provide the origins of much of modern applied mathematics and computational science.</p>
+<p><tt>Grafix</tt> is a study of the matrices that describe rotation, translation and scaling of objects moving in three-dimensional space. These matrices are the building blocks of today's computer graphics and are essential to all popular video games, to all CAD (Computer Added Design) packages, to CGI (Computer Graphics Imagery) in films. and to MATLAB's Handle Graphics.</p>
+<p>MATLAB is short for Matrix Laboratory. Matrices are also the foundation of MATLAB and of MathWorks.</p>
+<p>The <i>homogeneous coordinates</i> system used in modern computer graphics makes it possible to describe rotations, translations and many other operations with 4-by-4 matrices. These matrices operate on vectors with the position of an objec in the first three components and, for now, a one as the fourth component, e.g. <tt>[x,y,z,1]'</tt>,</p>
+<p>The matrices, which we collectively denote by <tt>M</tt>, are always shown in the panel in our displays. Here is an animation of one important example. Do you see the pattern in the evolving elements of this <tt>M</tt>? How are they related to each other? How long before they repeat?</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/mat_gif.gif" vspace="5" /> </p>
+<h4>Axis<a name="7cfcc1d4-26d2-4b2e-b4cb-a0ca04383ff8"></a></h4><p>Here is the coordinate system used by <tt>view(3)</tt>, MATLAB's default projection of our three-dimensional physical world onto the two-dimensional computer display. The positive <tt>x</tt>-axis goes up and to the right on the screen, the positive <tt>y</tt>-axis goes up and to the left, and the positive <tt>z</tt>-axis goes straight up.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/axis.png" vspace="5" /> </p>
+<h4>Rx<a name="6ce3a663-e301-4ddb-bc4d-58ae5e8f3b51"></a></h4><p>The three knobs at the lower right of the <tt>Grafix</tt> window allow you to vary the angles of <tt>Rx</tt>, <tt>Ry</tt> and <tt>Rz</tt>. Here are snapshots of the resulting motion. The <tt>Rx</tt> knob produces rotation about the <tt>x</tt>-axis, leaving <tt>x</tt> unchanged while rotating <tt>y</tt> and <tt>z</tt>.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Rx.png" vspace="5" /> </p>
+<h4>Ry<a name="f007d1f0-d76b-4e3e-bea3-49bd18805a1f"></a></h4><p><tt>Ry</tt>, rotation about the <tt>y</tt>-axis, leaves <tt>y</tt> unchanged while rotating <tt>x</tt> and <tt>z</tt>.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Ry.png" vspace="5" /> </p>
+<h4>Rz<a name="200c71a6-5d9f-4c03-8a03-00476f103160"></a></h4><p>And, <tt>Rz</tt>, rotation about the <tt>z</tt>-axis, leaves <tt>z</tt> unchanged while rotating <tt>x</tt> and <tt>y</tt>.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Rz.png" vspace="5" /> </p>
+<h4>Tx<a name="8dd6ed79-ba75-409b-a59d-68244c928c7a"></a></h4><p>The three sliders at the lower left of the <tt>Grafix</tt> window control matrices with values in the fourth column. Multiplying a vector by <tt>Tx</tt>, which has a nonzero element in the first row, produces a horizontal movement in the direction of the <tt>x</tt>-axis.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Tx.png" vspace="5" /> </p>
+<h4>Ty<a name="a9651b74-3170-4b23-a015-890b537b778a"></a></h4><p><tt>Ty</tt>, with a nonzero in the second row, is translation in the direction of the <tt>y</tt>-axis.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Ty.png" vspace="5" /> </p>
+<h4>Tz<a name="ce30422a-3bb7-4beb-90c6-3dfe5eb88351"></a></h4><p>And, <tt>Tz</tt> is translation in the <tt>z</tt> direction.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Tz.png" vspace="5" /> </p>
+<h4>S<a name="20f8cb07-c525-4f1b-a1ae-f9b6320078eb"></a></h4><p>The fourth slider controls <tt>S</tt>, a diagonal matrix with a single scaling factor for all three axes.</p>
+<p>The use of matrix multiplication allows translations and scaling to be combined with rotations and other operations in a uniform way. The arithmetic units on today's Graphics Processing Units, GPUs, are designed to do 4-by-4 matrix multiplications at speeds hundreds of times faster than general purpose Central Processing Units, CPUs.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/S.png" vspace="5" /> </p>
+<h4>Switches<a name="e8ae8340-3615-4ed7-90e7-b185a33f370a"></a></h4><p>The switch on the left provides other objects that we will introduce later. The switch on the right provides different <tt>views</tt> of three dimensions. The <tt>yz</tt> plane view is shown here.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/switches.png" vspace="5" /> </p>
+<h4>Pitch, Roll, Yaw<a name="097b4cbd-7971-430f-aa63-04db38192c6e"></a></h4><p><i>Pitch</i>, <i>roll</i> and <i>yaw</i> are often used to describe the motion of aircraft and spacecraft. These terms are closely related to the rotations <tt>Rx</tt>, <tt>Ry</tt> and <tt>Rz</tt>. The <tt>Pitch</tt> button animates the <tt>Rx</tt> knob. Here is a snapshot near one extreme of the resulting motion.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/pitch.png" vspace="5" /> </p>
+<h4>Start, Reset, Viz<a name="e558e05a-1bc3-41ed-a63b-ff056cf04620"></a></h4><p>The <tt>Start</tt> button restarts <tt>Grafix</tt>. The <tt>Reset</tt> button resets all knobs and sliders.</p>
+<p>The <tt>Viz</tt> button turns off the display of buttons, knobs, sliders, and switches. A small button, emphasized here with color, but usually barely visible, turns the display back on.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/viz.png" vspace="5" /> </p>
+<h4>Apps/taxi<a name="9d1fa1cc-0fe6-4d6f-9ca6-a50f0644fc62"></a></h4><p><tt>Grafix</tt> is programable, in a primitive sort of way. Apps are <tt>Grafix</tt> programs. <tt>Taxi</tt> is a small app. This is a snapshot.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/taxi.png" vspace="5" /> </p>
+<h4>Apps/takeoff<a name="0c8793f3-d9d5-45ef-90a8-7ec0c83356ca"></a></h4><p>When the <tt>takeoff</tt> app first appeared, I thought it was a bug in the code for <tt>Grafix</tt>.</p>
+<p>You can see the <tt>takeoff</tt> program by entering <tt>type takeoff</tt> at the MATLAB command prompt. You can also <tt>edit takeoff</tt>.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/takeoffapp.png" vspace="5" /> </p>
+<h4>Prop<a name="c20254e9-3887-4d66-9903-db87c5c7bb30"></a></h4><p>One of my favorite animations employs the rotations from the Matrices section to drive the propeller alone.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/prop_gif_small.gif" vspace="5" /> </p>
+<h4>Info<a name="1adf580c-785f-4333-9494-0f5657c1ce53"></a></h4><p>The <tt>info</tt> button is a link to this User's Guide.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Guide.png" vspace="5" /> </p>
+<h4>Exercises<a name="095cf406-3f28-4e05-ab8a-43d29a3310c1"></a></h4><div><ul><li>What color is the beacon on top of the plane?</li></ul></div>
+<div><ul><li>Demonstrate how matrix-vector multiplication, <tt>Mv</tt>, of a position vector, <tt>v = [x,y,z,1]'</tt>, by a 4-by-4 matrix <tt>M</tt>, achieves a rotation, translation or scaling.</li></ul></div>
+<div><ul><li>Describe the evolution of the matrix values in the Matrices and <tt>prop</tt> animations.</li></ul></div>
+<div><ul><li>What angles are involved in the snapshots shown for <tt>Rx</tt>, <tt>Ry</tt> and <tt>Rz</tt>?</li></ul></div>
+<div><ul><li>Why is the plane in the <tt>Pitch</tt> animation upside down?</li></ul></div>
+<div><ul><li>What angles and what matrices characterize the extremes of the <tt>Pitch</tt> animation?</li></ul></div>
+<div><ul><li>Write another app like <tt>taxi</tt> and <tt>takeoff</tt>.</li></ul></div>
+<h4>Software<a name="6df5e80a-e9fa-45c4-aff2-03edb1ccb334"></a></h4><p>The MATLAB code for <tt>Grafix</tt> <a href="https://blogs.mathworks.com/cleve/files/Grafix_mzip.m">is available here.</a></p>
+<!--
+ function grabCode_c11525de7f124cdcb5896c8c3f89d4a8() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='c11525de7f124cdcb5896c8c3f89d4a8 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' c11525de7f124cdcb5896c8c3f89d4a8';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2023 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+c11525de7f124cdcb5896c8c3f89d4a8 ##### SOURCE BEGIN #####
+%% Grafix User's Guide
+% This is a quick look at
+% |Grafix|, our tool for exploring matrices via 3-D computer graphics.
+%
+% <<Opening.png>>
+%
+
+%% Matrices
+% The word _matrix_ comes from the Latin word _mater_, which means
+% _mother_ or _origin_. Matrices provide the origins of much of
+% modern applied mathematics and computational science.
+%
+% |Grafix| is a study of the matrices that describe rotation, translation
+% and scaling of objects moving in three-dimensional space.
+% These matrices are the building blocks of today's computer graphics
+% and are essential to all popular video games,
+% to all CAD (Computer Added Design) packages,
+% to CGI (Computer Graphics Imagery) in films.
+% and to MATLAB's Handle Graphics.
+%
+% MATLAB is short for Matrix Laboratory.
+% Matrices are also the foundation of MATLAB and of MathWorks.
+%
+% The _homogeneous coordinates_ system used in modern computer graphics
+% makes it possible to describe rotations, translations
+% and many other operations with 4-by-4 matrices. These matrices
+% operate on vectors with the position of an objec
+% in the first three components and, for now, a one as the
+% fourth component, e.g. |[x,y,z,1]'|,
+%
+% The matrices, which we collectively denote by |M|, are always shown
+% in the panel in our displays. Here is an animation of one important
+% example. Do you see the pattern in the evolving elements of this |M|?
+% How are they related to each other? How long before they repeat?
+%
+% <<mat_gif.gif>>
+%
+
+%% Axis
+% Here is the coordinate system used by |view(3)|, MATLAB's default
+% projection of our three-dimensional physical world onto the
+% two-dimensional computer display.
+% The positive |x|-axis goes up and to the right on the screen,
+% the positive |y|-axis goes up and to the left, and the positive
+% |z|-axis goes straight up.
+%
+% <<axis.png>>
+
+%% Rx
+% The three knobs at the lower right of the |Grafix| window allow you
+% to vary the angles of |Rx|, |Ry| and |Rz|. Here are snapshots
+% of the resulting motion. The |Rx| knob produces rotation about the
+% |x|-axis, leaving |x| unchanged while rotating |y| and |z|.
+%
+% <<Rx.png>>
+%
+
+%% Ry
+% |Ry|, rotation about the |y|-axis, leaves |y| unchanged while
+% rotating |x| and |z|.
+%
+% <<Ry.png>>
+%
+
+%% Rz
+% And, |Rz|, rotation about the |z|-axis, leaves |z| unchanged while
+% rotating |x| and |y|.
+%
+% <<Rz.png>>
+%
+
+%% Tx
+% The three sliders at the lower left of the |Grafix| window
+% control matrices with values in the fourth column.
+% Multiplying a vector by |Tx|, which has a nonzero element in the first
+% row, produces a horizontal movement in the direction of the |x|-axis.
+%
+% <<Tx.png>>
+%
+
+%% Ty
+% |Ty|, with a nonzero in the second row, is translation in the
+% direction of the |y|-axis.
+%
+% <<Ty.png>>
+%
+
+%% Tz
+% And, |Tz| is translation in the |z| direction.
+%
+% <<Tz.png>>
+%
+
+%% S
+% The fourth slider controls |S|, a diagonal matrix with
+% a single scaling factor for all three axes.
+%
+% The use of matrix multiplication allows translations and scaling
+% to be combined with rotations and other operations in a uniform way.
+% The arithmetic units on today's
+% Graphics Processing Units, GPUs, are designed to do 4-by-4 matrix
+% multiplications at speeds hundreds of times faster than general
+% purpose Central Processing Units, CPUs.
+%
+% <<S.png>>
+%
+
+%% Switches
+% The switch on the left provides other objects that we will introduce
+% later. The switch on the right provides different |views|
+% of three dimensions. The |yz| plane view is shown here.
+%
+% <<switches.png>>
+%
+
+%% Pitch, Roll, Yaw
+% _Pitch_, _roll_ and _yaw_ are often used to describe
+% the motion of aircraft and spacecraft.
+% These terms are closely related to the rotations |Rx|, |Ry| and |Rz|.
+% The |Pitch| button animates the |Rx| knob. Here is a snapshot near
+% one extreme of the resulting motion.
+%
+% <<pitch.png>>
+%
+
+%% Start, Reset, Viz
+% The |Start| button restarts |Grafix|.
+% The |Reset| button resets all knobs and sliders.
+%
+% The |Viz| button turns off the display of buttons, knobs, sliders, and
+% switches. A small button, emphasized here with color, but usually
+% barely visible, turns the display back on.
+%
+% <<viz.png>>
+%
+
+%% Apps/taxi
+% |Grafix| is programable, in a primitive sort of way. Apps are |Grafix|
+% programs. |Taxi| is a small app. This is a snapshot.
+%
+% <<taxi.png>>
+%
+
+%% Apps/takeoff
+% When the |takeoff| app first appeared, I thought it was a bug in the
+% code for |Grafix|.
+%
+% You can see the |takeoff| program by entering |type takeoff|
+% at the MATLAB command prompt. You can also |edit takeoff|.
+%
+% <<takeoffapp.png>>
+%
+
+%% Prop
+% One of my favorite animations employs the rotations from the Matrices
+% section to drive the propeller alone.
+%
+% <<prop_gif_small.gif>>
+%
+
+%% Info
+% The |info| button is a link to this User's Guide.
+%
+% <<Guide.png>>
+%
+
+%% Exercises
+%
+% * What color is the beacon on top of the plane?
+%
+% * Demonstrate how matrix-vector multiplication, |Mv|, of a position
+% vector, |v = [x,y,z,1]'|, by a 4-by-4 matrix |M|, achieves a rotation,
+% translation or scaling.
+%
+% * Describe the evolution of the matrix values in the Matrices and
+% |prop| animations.
+%
+% * What angles are involved in the snapshots shown for
+% |Rx|, |Ry| and |Rz|?
+%
+% * Why is the plane in the |Pitch| animation upside down?
+%
+% * What angles and what matrices characterize the extremes of the |Pitch|
+% animation?
+%
+% * Write another app like |taxi| and |takeoff|.
+%
+
+%% Software
+%
+% The MATLAB code for |Grafix|
+% <https://blogs.mathworks.com/cleve/files/Grafix_mzip.m is available here.>
+##### SOURCE END ##### c11525de7f124cdcb5896c8c3f89d4a8
+-->
+
+
+
+
+ Matrices In Action, Grafix 2.0
+
+ 2023-02-04T13:00:33-07:00
+ https://hpc.social/2023/matrices-in-action-grafix-2-0
+ <div class="content"><!--introduction--><p>The 4-by-4 matrices in the panels on the following screenshots are at the heart of computer graphics. They describe objects moving in three-dimensional space and are essential to MATLAB's Handle Graphics, to CAD (Computer Added Design) packages, to CGI (Computer Graphics Imagery) in films, and to most popular video games.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#4c54a017-4a2d-4bd0-b5de-085c77696298">Grafix 2.0</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#19ccc0f8-ccd0-45a3-a624-c4f466eea2af">Rotations</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#4028a6e9-0449-4846-8e6e-c9a2c5ad64b6">Pitch, Roll, and Yaw</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#e6dc8b74-fe6e-4fb5-a343-2b8fbfe28558">Translations</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#9dbcd88d-756a-475c-bd7e-237261a3cdbe">Horizontal and Vertical</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#54cb3b88-904f-441b-9c61-91dca0a68c0d">Scalings</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#9bfb2311-6f44-4f2b-85aa-f09554da0cc6">Larger and Smaller</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#ef53d281-53a4-437e-80f0-93b331367abf">Suggestions</a></li></ul></div>
+<h4>Grafix 2.0<a name="4c54a017-4a2d-4bd0-b5de-085c77696298"></a></h4><p>Here is the opening screen from version 2.0 of <tt>Grafix</tt>, my tool for investigating the matrices involved in 3-D computer graphics. The MATLAB code for <tt>Grafix</tt> <a href="https://blogs.mathworks.com/cleve/files/Grafix_mzip.m">is availble here.</a></p>
+<p>I am interested in the matrix in the panel, which I call <tt>M</tt>. Many matrices like this one describe the dyamic transformations to be made on a set of target objects in a complex three-dimensional scene. This particular <tt>M</tt> is the product of a scaling and a rotation that results in the size and orientation of the plane shown.</p>
+<p>I also want to point out the coordinate axes being used. This is <tt>view(3)</tt>, MATLAB's default 3-D cordinate system. The positive $x$-axis goes up and to the right on the screen, the positive $y$-axis up and to the left, and the positive $z$-axis goes straight up.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/grafix.png" vspace="5" /> </p>
+<h4>Rotations<a name="19ccc0f8-ccd0-45a3-a624-c4f466eea2af"></a></h4><p>The <i>homogeneous coordinates</i> system used in modern computer graphics makes it possible to describe rotations, translations and many other operations with 4-by-4 matrices. These matrices operate on vectors with the position of an object in the first three components and, for now, a one as the fourth component, eg. [ $x$, $y$, $z$, 1 ]',</p>
+<p>Rotations are described by products of these matrices, each of which operates on only two of the first three components of the vector. The first matrix, $R_x$, leaves $x$ unchanged while it rotates $y$ and $z$. The second matrix, $R_y$, leaves $y$ unchanged while it rotates $x$ and $z$. And the third matrix, $R_z$, leaves $z$ unchanged while it rotates $x$ and $y$.</p>
+<p>$$ R_x(\theta) = \left[ \begin{array}{rrrr}
+ 1 & 0 & 0 & 0 \\
+ 0 & \cos{\theta} & -\sin{\theta} & 0 \\
+ 0 & \sin{\theta} & \cos{\theta} & 0 \\
+ 0 & 0 & 0 & 1
+ \end{array} \right] $$</p>
+<p>$$ R_y(\theta) = \left[ \begin{array}{rrrr}
+ \cos{\theta} & 0 & -\sin{\theta} & 0 \\
+ 0 & 1 & 0 & 0 \\
+ \sin{\theta} & 0 & \cos{\theta} & 0 \\
+ 0 & 0 & 0 & 1
+ \end{array} \right] $$</p>
+<p>$$ R_z(\theta) = \left[ \begin{array}{rrrr}
+ \cos{\theta} & -\sin{\theta} & 0 & 0 \\
+ \sin{\theta} & \cos{\theta} & 0 & 0 \\
+ 0 & 0 & 1 & 0 \\
+ 0 & 0 & 0 & 1
+ \end{array} \right] $$</p>
+<h4>Pitch, Roll, and Yaw<a name="4028a6e9-0449-4846-8e6e-c9a2c5ad64b6"></a></h4><p>The terms <i>pitch</i>, <i>roll</i> and <i>yaw</i> are often used to describe the motion of vehicles like aircraft, marine craft, and spacecraft. Pitch is $R_x$, rotation about the $x$-axis.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/pitchgif.gif" vspace="5" /> </p>
+<p>Roll is $R_y$, rotation about the $y$-axis.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/rollgif.gif" vspace="5" /> </p>
+<p>And yaw is $R_z$, rotation about the $z$-axis.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/yawgif.gif" vspace="5" /> </p>
+<h4>Translations<a name="e6dc8b74-fe6e-4fb5-a343-2b8fbfe28558"></a></h4><p>Translations are described by matrices with values in the fourth column. Multiplying a vector by one of these matrices produces a translation in the direction of the corresponding axis.</p>
+<p>$$ T_x(\delta) = \left[ \begin{array}{rrrr}
+ 1 & 0 & 0 & \delta \\
+ 0 & 1 & 0 & 0 \\
+ 0 & 0 & 1 & 0 \\
+ 0 & 0 & 0 & 1
+ \end{array} \right] $$</p>
+<p>$$ T_y(\delta) = \left[ \begin{array}{rrrr}
+ 1 & 0 & 0 & 0 \\
+ 0 & 1 & 0 & \delta \\
+ 0 & 0 & 1 & 0 \\
+ 0 & 0 & 0 & 1
+ \end{array} \right] $$</p>
+<p>$$ T_z(\delta) = \left[ \begin{array}{rrrr}
+ 1 & 0 & 0 & 0 \\
+ 0 & 1 & 0 & 0 \\
+ 0 & 0 & 1 & \delta \\
+ 0 & 0 & 0 & 1
+ \end{array} \right] $$</p>
+<p>While it is true that translations could be accomplished simply by adding the increment to the specified coordiate, the use of matrix multiplication allows translations to be combined in a uniform way with rotations and other operations. The arithmetic units on today's Graphics Processing Units, GPUs, are designed to do 4-by-4 matrix multiplications at speeds hundreds of times faster than general purpose Central Processing Units, CPUs.</p>
+<h4>Horizontal and Vertical<a name="9dbcd88d-756a-475c-bd7e-237261a3cdbe"></a></h4><p>Inspired by David Singmaster's notation for Rubik's cubes, L, R, B, F, U, and D, we can use the descriptive terms <i>left</i> and <i>right</i> for horizontal motion in the $x$ direction; <i>back</i> and <i>forth</i> for horizontal motion in the $y$ direction; and <i>up</i> and <i>down</i> for vertical motion in the $z$ direction.</p>
+<p>$T_x$, left and right.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Txgif.gif" vspace="5" /> </p>
+<p>$T_y$, back and forth.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Tygif.gif" vspace="5" /> </p>
+<p>$T_z$, up and down.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Tzgif.gif" vspace="5" /> </p>
+<h4>Scalings<a name="54cb3b88-904f-441b-9c61-91dca0a68c0d"></a></h4><p>This matrix applies a single scaling factor to all three axes.</p>
+<p>$$ S(\sigma) = \left[ \begin{array}{rrrr}
+ \sigma & 0 & 0 & 0 \\
+ 0 & \sigma & 0 & 0 \\
+ 0 & 0 & \sigma & 0 \\
+ 0 & 0 & 0 & 1
+ \end{array} \right] $$</p>
+<h4>Larger and Smaller<a name="9bfb2311-6f44-4f2b-85aa-f09554da0cc6"></a></h4><p>$S$</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Sgif.gif" vspace="5" /> </p>
+<h4>Suggestions<a name="ef53d281-53a4-437e-80f0-93b331367abf"></a></h4><p>Refresh your browser to syncronize the animations.</p>
+<p>Download your own self-archiving copies of</p>
+<div><ul><li><a href="https://blogs.mathworks.com/cleve/files/Grafix_mzip.m">Grafix</a></li><li><a href="https://blogs.mathworks.com/cleve/files/Qube_mzip-1.m">Qube</a></li></ul></div>
+<!--
+ function grabCode_b13c7ab1c73c4ad7909fa2d7cd9764f2() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='b13c7ab1c73c4ad7909fa2d7cd9764f2 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' b13c7ab1c73c4ad7909fa2d7cd9764f2';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2023 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+b13c7ab1c73c4ad7909fa2d7cd9764f2 ##### SOURCE BEGIN #####
+%% Matrices In Action, Grafix 2.0
+% The 4-by-4 matrices in the panels on the following screenshots
+% are at the heart of computer graphics.
+% They describe objects moving in three-dimensional
+% space and are essential to MATLAB's Handle Graphics,
+% to CAD (Computer Added Design) packages,
+% to CGI (Computer Graphics Imagery) in films,
+% and to most popular video games.
+%
+
+%% Grafix 2.0
+% Here is the opening screen from version 2.0 of |Grafix|,
+% my tool for investigating the matrices involved in 3-D computer graphics.
+% The MATLAB code for |Grafix|
+% <https://blogs.mathworks.com/cleve/files/Grafix_mzip.m is availble here.>
+
+%%
+% I am interested in the matrix in the panel, which I call |M|.
+% Many matrices like this one describe the dyamic transformations to be
+% made on a set of target objects in a complex three-dimensional scene.
+% This particular |M| is the product of a scaling and a rotation that
+% results in the size and orientation of the plane shown.
+%
+% I also want to point out the coordinate axes being used.
+% This is |view(3)|, MATLAB's default 3-D cordinate system. The positive
+% $x$-axis goes up and to the right on the screen, the positive $y$-axis
+% up and to the left, and the positive $z$-axis goes straight up.
+%
+% <<grafix.png>>
+%
+
+%% Rotations
+% The _homogeneous coordinates_ system used in modern computer graphics
+% makes it possible to describe rotations, translations
+% and many other operations with 4-by-4 matrices. These matrices
+% operate on vectors with the position of an object
+% in the first three components and, for now, a one as the
+% fourth component, eg. [ $x$, $y$, $z$, 1 ]',
+%
+% Rotations are described by products of these matrices,
+% each of which operates on only two of the first three components of
+% the vector. The first matrix, $R_x$, leaves $x$ unchanged while it
+% rotates $y$ and $z$. The second matrix, $R_y$, leaves $y$ unchanged
+% while it rotates $x$ and $z$. And the third matrix, $R_z$,
+% leaves $z$ unchanged while it rotates $x$ and $y$.
+%
+% $$ R_x(\theta) = \left[ \begin{array}{rrrr}
+% 1 & 0 & 0 & 0 \\
+% 0 & \cos{\theta} & -\sin{\theta} & 0 \\
+% 0 & \sin{\theta} & \cos{\theta} & 0 \\
+% 0 & 0 & 0 & 1
+% \end{array} \right] $$
+%
+%
+% $$ R_y(\theta) = \left[ \begin{array}{rrrr}
+% \cos{\theta} & 0 & -\sin{\theta} & 0 \\
+% 0 & 1 & 0 & 0 \\
+% \sin{\theta} & 0 & \cos{\theta} & 0 \\
+% 0 & 0 & 0 & 1
+% \end{array} \right] $$
+%
+%
+% $$ R_z(\theta) = \left[ \begin{array}{rrrr}
+% \cos{\theta} & -\sin{\theta} & 0 & 0 \\
+% \sin{\theta} & \cos{\theta} & 0 & 0 \\
+% 0 & 0 & 1 & 0 \\
+% 0 & 0 & 0 & 1
+% \end{array} \right] $$
+%
+
+%% Pitch, Roll, and Yaw
+% The terms _pitch_, _roll_ and _yaw_ are often used to describe
+% the motion of vehicles like aircraft, marine craft, and spacecraft.
+% Pitch is $R_x$, rotation about the $x$-axis.
+%
+% <<pitchgif.gif>>
+%
+
+%%
+% Roll is $R_y$, rotation about the $y$-axis.
+%
+% <<rollgif.gif>>
+%
+
+%%
+% And yaw is $R_z$, rotation about the $z$-axis.
+%
+% <<yawgif.gif>>
+%
+
+%% Translations
+% Translations are described by matrices with values in the fourth column.
+% Multiplying a vector by one of these matrices produces a translation
+% in the direction of the corresponding axis.
+%
+% $$ T_x(\delta) = \left[ \begin{array}{rrrr}
+% 1 & 0 & 0 & \delta \\
+% 0 & 1 & 0 & 0 \\
+% 0 & 0 & 1 & 0 \\
+% 0 & 0 & 0 & 1
+% \end{array} \right] $$
+%
+% $$ T_y(\delta) = \left[ \begin{array}{rrrr}
+% 1 & 0 & 0 & 0 \\
+% 0 & 1 & 0 & \delta \\
+% 0 & 0 & 1 & 0 \\
+% 0 & 0 & 0 & 1
+% \end{array} \right] $$
+%
+% $$ T_z(\delta) = \left[ \begin{array}{rrrr}
+% 1 & 0 & 0 & 0 \\
+% 0 & 1 & 0 & 0 \\
+% 0 & 0 & 1 & \delta \\
+% 0 & 0 & 0 & 1
+% \end{array} \right] $$
+%
+% While it is true that translations could be accomplished simply by
+% adding the increment to the specified coordiate, the use of matrix
+% multiplication allows translations to be combined in a uniform way
+% with rotations and other operations. The arithmetic units on today's
+% Graphics Processing Units, GPUs, are designed to do 4-by-4 matrix
+% multiplications at speeds hundreds of times faster than general
+% purpose Central Processing Units, CPUs.
+
+%% Horizontal and Vertical
+% Inspired by David Singmaster's notation for Rubik's cubes,
+% L, R, B, F, U, and D,
+% we can use the descriptive terms _left_ and _right_ for
+% horizontal motion in the $x$ direction; _back_ and _forth_
+% for horizontal motion in the $y$ direction; and _up_ and _down_
+% for vertical motion in the $z$ direction.
+%
+% $T_x$, left and right.
+%
+% <<Txgif.gif>>
+%
+%
+% $T_y$, back and forth.
+%
+% <<Tygif.gif>>
+%
+% $T_z$, up and down.
+%
+% <<Tzgif.gif>>
+%
+
+%% Scalings
+% This matrix applies a single scaling factor to all three axes.
+%
+% $$ S(\sigma) = \left[ \begin{array}{rrrr}
+% \sigma & 0 & 0 & 0 \\
+% 0 & \sigma & 0 & 0 \\
+% 0 & 0 & \sigma & 0 \\
+% 0 & 0 & 0 & 1
+% \end{array} \right] $$
+
+%% Larger and Smaller
+%
+% $S$
+%
+% <<Sgif.gif>>
+%
+
+%% Suggestions
+% Refresh your browser to syncronize the animations.
+%
+% Download your own self-archiving copies of
+%
+% * <https://blogs.mathworks.com/cleve/files/Grafix_mzip.m Grafix>
+% * <https://blogs.mathworks.com/cleve/files/Qube_mzip-1.m Qube>
+%
+##### SOURCE END ##### b13c7ab1c73c4ad7909fa2d7cd9764f2
+-->
+
+
+
+
+ Singular Matrix Pencils and the QZ Algorithm, Update
+
+ 2023-01-10T21:45:12-07:00
+ https://hpc.social/2023/singular-matrix-pencils-and-the-qz-algorithm-update
+ <div class="content"><!--introduction--><p>(The January 5 posting was premature and incomplete.)</p>
+<p>This year, 2023, is the 50-th anniversary of the QZ algorithm for the generalized matrix eigenvalue problem,</p>
+<pre> Ax = λBx</pre><p>The algorithm avoids inverting either <tt>A</tt> or <tt>B</tt>. And, importantly, the QZ algorithm can be used to detect and analyze exceptional instances of the problem known as <i>singular pencils</i>. These pencils do not occur in the standard eigenvalue problem where <tt>B</tt> is the identity matrix.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#59d30988-fe9f-4381-bf4b-70b9181f1d24">Singular pencils</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#aa953fcf-a488-43bb-8976-bef668d4b373">3-by-3 example</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#ebedf1c8-dc25-443b-9232-8e963a75eed3">Wilkinson example</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#2c8b301b-125b-4389-a5ea-fd8eccc8d4ba">References</a></li></ul></div>
+<h4>Singular pencils<a name="59d30988-fe9f-4381-bf4b-70b9181f1d24"></a></h4><p>A matrix pencil is <i>singular</i> if both <tt>A</tt> and <tt>B</tt> are singular and, moreover, <tt>A</tt> - λ <tt>B</tt> is singular for all λ. Equivalently,</p>
+<pre> det(A - λB) = 0 for all λ.</pre><p>Singular pencils are more insidious than might appear at first glance. In some sense, the spectrum is the entire complex plane.</p>
+<p>There are no singular pencils with the standard eigenvalue problem</p>
+<pre> Ax = λx</pre><p>where <tt>B</tt> is the identity matrix and certainly nonsingular.</p>
+<p>If <tt>A</tt> and <tt>B</tt> are both real symmetric or complex Hermitian, but neither is positive definite, the pencil may or may not be singular. Symmetric problems occur frequently and there are separate algorithms and perturbation and convergence theories.</p>
+<p>The QZ algorithm does not compute the eigenvalues λ until the very last step. It stably reduces <tt>A</tt> and <tt>B</tt> to triangular form with diagonals α and β. The eigenvalues are then the ratios</p>
+<pre> λ = α./β</pre><p>Isolated zeros in α or β yield zero or infinite eigenvalues with no special difficulties. Singular pencils occur if and only if zeros in α and β occur <i>with the same index</i> and (with exact arithmetic) lead to λ = 0/0 = NaN.</p>
+<p>With a singular pencil, some, perhaps all, of the diagonal values in α and β are highly sensitive to perturbation, and all of the eigenvalues computed from the ratios are suspect. Theoretically the ill-conditioned eigenvalues can be determined from the Kronecker Canonical Form, a generalization of the notorious Jordan Canonical Form. But, like the Jordan Form, the Kronecker Form cannot provide a stable numerical algorithm.</p>
+<h4>3-by-3 example<a name="aa953fcf-a488-43bb-8976-bef668d4b373"></a></h4><pre class="codeinput"> A = [9 8 7; 6 5 4; 3 2 1]
+
+ B = [1 3 2; 4 6 5; 7 9 8]
+</pre><pre class="codeoutput">
+A =
+
+ 9 8 7
+ 6 5 4
+ 3 2 1
+
+
+B =
+
+ 1 3 2
+ 4 6 5
+ 7 9 8
+
+</pre><p>Let's verify that this is a singular pencil. Use the Symbolic Math Toolbox to introduce a free variable.</p>
+<pre class="codeinput"> syms <span class="string">lambda</span>
+ AB = A - lambda*B
+</pre><pre class="codeoutput">
+AB =
+
+[ 9 - lambda, 8 - 3*lambda, 7 - 2*lambda]
+[6 - 4*lambda, 5 - 6*lambda, 4 - 5*lambda]
+[3 - 7*lambda, 2 - 9*lambda, 1 - 8*lambda]
+
+</pre><p>Without further computation, we can see that the second row is the average of the first and third rows for all <tt>lambda</tt> and consequently that the determinant must be identically zero.</p>
+<p>With exact arithmetic, each of these statements would produce the same eigenvalues. After the introduction of some roundoff error, two of the <tt>lambdas</tt> are indeterminant, but <tt>lambda = -1</tt> is present in all four results. Is <tt>lambda = -1</tt> a stable eigenvalue?</p>
+<pre class="codeinput"> lambda_AB = eig(A,B)
+ lambda_BA = 1./eig(B,A)
+ lambda_ATBT = eig(A',B')
+ lambda_BTAT = 1./eig(B',A')
+</pre><pre class="codeoutput">
+lambda_AB =
+
+ 1.8984
+ -1.0000
+ -0.0807
+
+
+lambda_BA =
+
+ -1.0000
+ 0.5837
+ -0.9274
+
+
+lambda_ATBT =
+
+ 0.0829
+ Inf
+ -1.0000
+
+
+lambda_BTAT =
+
+ -0.9661
+ 0
+ -1.0000
+
+</pre><p>The triangular matrices for <tt>lambda_AB</tt>.</p>
+<pre class="codeinput"> [QAZ,QBZ] = qz(A,B);
+ QAZ
+ QBZ
+</pre><pre class="codeoutput">
+QAZ =
+
+ 1.6131 10.2664 -11.0905
+ 0 -4.2969 5.9613
+ 0 0 -0.0000
+
+
+QBZ =
+
+ 0.7898 6.8901 -13.5242
+ 0 4.2969 -5.9613
+ 0 0 0.0000
+
+</pre><p>Careful examination of the diagonals reveals that <tt>alfa(2)/beta(2)</tt> is producing the <tt>-1</tt>, while <tt>alfa(3)/beta(3)</tt> is roundoff over roundoff.</p>
+<pre class="codeinput"> format <span class="string">long</span> <span class="string">e</span>
+ alfa = diag(QAZ)
+ beta = diag(QBZ)
+ format <span class="string">short</span>
+</pre><pre class="codeoutput">
+alfa =
+
+ 1.613087771308989e+00
+ -4.296911800112353e+00
+ -1.965207685813115e-15
+
+
+beta =
+
+ 7.898460671891234e-01
+ 4.296911800112357e+00
+ 1.359052275299816e-15
+
+</pre><h4>Wilkinson example<a name="ebedf1c8-dc25-443b-9232-8e963a75eed3"></a></h4><p>Jim Wilkinson published a survey paper about QZ and Kronecker products in 1979. One of his examples is</p>
+<pre class="codeinput"> A = [4 3 2 5; 6 4 2 7; -1 -1 -2 -2; 5 3 2 6]
+
+ B = [2 1 3 4; 3 3 3 5; 0 0 -3 -2; 3 1 3 5]
+</pre><pre class="codeoutput">
+A =
+
+ 4 3 2 5
+ 6 4 2 7
+ -1 -1 -2 -2
+ 5 3 2 6
+
+
+B =
+
+ 2 1 3 4
+ 3 3 3 5
+ 0 0 -3 -2
+ 3 1 3 5
+
+</pre><p>Use the Symbolic Math Toolbox to verify that this is a singular pencil.</p>
+<pre class="codeinput"> syms <span class="string">lambda</span>
+ AB = A - lambda*B
+</pre><pre class="codeoutput">
+AB =
+
+[4 - 2*lambda, 3 - lambda, 2 - 3*lambda, 5 - 4*lambda]
+[6 - 3*lambda, 4 - 3*lambda, 2 - 3*lambda, 7 - 5*lambda]
+[ -1, -1, 3*lambda - 2, 2*lambda - 2]
+[5 - 3*lambda, 3 - lambda, 2 - 3*lambda, 6 - 5*lambda]
+
+</pre><p>The determinant is identically zero for all <tt>lambda</tt>.</p>
+<pre class="codeinput"> d = det(AB)
+</pre><pre class="codeoutput">
+d =
+
+0
+
+</pre><p>With exact arithmetic, each of these statements would produce the same eigenvalues, but in practice each set is different. None of the eigenvalues is stable.</p>
+<pre class="codeinput"> lambda_AB = eig(A,B)
+ lambda_BA = 1./eig(B,A)
+ lambda_ATBT = eig(A',B')
+ lambda_BTAT = 1./eig(B',A')
+</pre><pre class="codeoutput">
+lambda_AB =
+
+ 1.2056
+ 0.7055
+ -1.0000
+ -Inf
+
+
+lambda_BA =
+
+ 1.5097
+ 0.6408
+ 0
+ -1.0000
+
+
+lambda_ATBT =
+
+ -0.2141 + 0.2033i
+ -0.2141 - 0.2033i
+ 0.7013 + 0.0000i
+ 1.4508 + 0.0000i
+
+
+lambda_BTAT =
+
+ 0.3168
+ 0.9823
+ 1.2325
+ 0
+
+</pre><p>The triangular matrices for <tt>lambda_AB</tt> are</p>
+<pre class="codeinput"> [QAZ,QBZ] = qz(A,B);
+ QAZ
+ QBZ
+</pre><pre class="codeoutput">
+QAZ =
+
+ 0.7437 4.1769 -12.7279 -5.5000
+ 0 0.0000 5.2328 2.1602
+ 0 0 0.7857 0.0123
+ 0 0 0 -0.2887
+
+
+QBZ =
+
+ 0.5005 6.6143 -8.4853 -2.5000
+ 0 0.0000 3.2668 2.0105
+ 0 0 1.1525 -0.7904
+ 0 0 0 0.2887
+
+</pre><p>Examine the diagonals more carefully. <tt>alfa(2)/beta(2)</tt> is the only roundoff over roundoff, but all four eigenvalues are unstable.</p>
+<pre class="codeinput"> format <span class="string">long</span> <span class="string">e</span>
+ alfa = diag(QAZ)
+ beta = diag(QBZ)
+ format <span class="string">short</span>
+</pre><pre class="codeoutput">
+alfa =
+
+ 7.437114999643711e-01
+ 1.216947725307920e-14
+ 7.857314232211017e-01
+ -2.886751345948121e-01
+
+
+beta =
+
+ 5.005405248737872e-01
+ 1.021080292327182e-13
+ 1.152509249099882e+00
+ 2.886751345948153e-01
+
+</pre><h4>References<a name="2c8b301b-125b-4389-a5ea-fd8eccc8d4ba"></a></h4><p>C. B. Moler and G. W. Stewart, "An Algorithm for Generalized Matrix Eigenvalue Problems", <i>SIAM J. Numerical Analysis</i>, Vol.10, No.2, April 1973. Also available at <a href="https://blogs.mathworks.com/cleve/files/cbm_gws.pdf">cbm_gws.pdf</a></p>
+<p>J. H. Wilkinson, "Kronecker's Canonical Form and the QZ Algorithm", <i>Linear Algebra and its Applications</i>, Vol. 28, 1979. Also available at <a href="https://blogmathworks.com/cleve/files/wilkinson.pdf">wilkinson.pdf</a></p>
+<!--
+ function grabCode_8891e70a294b4c03bb99ac1e6e01b5a5() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='8891e70a294b4c03bb99ac1e6e01b5a5 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 8891e70a294b4c03bb99ac1e6e01b5a5';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2023 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+8891e70a294b4c03bb99ac1e6e01b5a5 ##### SOURCE BEGIN #####
+%% Singular Matrix Pencils and the QZ Algorithm, Update
+% (The January 5 posting was premature and incomplete.)
+%
+% This year, 2023, is the 50-th anniversary of the QZ algorithm
+% for the generalized matrix eigenvalue problem,
+%
+% Ax = λBx
+%
+% The algorithm avoids inverting either |A| or |B|.
+% And, importantly, the QZ algorithm can be used to detect and analyze
+% exceptional instances of the problem known as _singular pencils_.
+% These pencils do not occur in the standard eigenvalue problem where
+% |B| is the identity matrix.
+
+%% Singular pencils
+% A matrix pencil is _singular_ if both |A| and |B| are singular and,
+% moreover, |A| - λ |B| is singular for all λ. Equivalently,
+%
+% det(A - λB) = 0 for all λ.
+%
+% Singular pencils are more insidious than might appear at first glance.
+% In some sense, the spectrum is the entire complex plane.
+%
+% There are no singular pencils with the standard eigenvalue problem
+%
+% Ax = λx
+%
+% where |B| is the identity matrix and certainly nonsingular.
+%
+% If |A| and |B| are both real symmetric or complex Hermitian, but neither
+% is positive definite, the pencil may or may not be singular.
+% Symmetric problems occur frequently and there are
+% separate algorithms and perturbation and convergence theories.
+%
+% The QZ algorithm does not compute the eigenvalues λ until the very last
+% step. It stably reduces |A| and |B| to triangular form
+% with diagonals α and β. The eigenvalues are then the ratios
+%
+% λ = α./β
+%
+% Isolated zeros in α or β yield zero or infinite eigenvalues with no
+% special difficulties. Singular pencils occur if and only if zeros in
+% α and β occur _with the same index_ and (with exact arithmetic) lead to
+% λ = 0/0 = NaN.
+%
+% With a singular pencil, some, perhaps all, of the diagonal values
+% in α and β are highly sensitive to perturbation, and all of the
+% eigenvalues computed from the ratios are suspect. Theoretically
+% the ill-conditioned eigenvalues can be determined from the Kronecker
+% Canonical Form, a generalization of the notorious Jordan Canonical
+% Form. But, like the Jordan Form, the Kronecker Form cannot provide
+% a stable numerical algorithm.
+
+%% 3-by-3 example
+
+ A = [9 8 7; 6 5 4; 3 2 1]
+
+ B = [1 3 2; 4 6 5; 7 9 8]
+
+%%
+% Let's verify that this is a singular pencil.
+% Use the Symbolic Math Toolbox to introduce a free variable.
+
+ syms lambda
+ AB = A - lambda*B
+
+%%
+% Without further computation,
+% we can see that the second row is the average of the first and third
+% rows for all |lambda| and consequently that the determinant must be
+% identically zero.
+
+%%
+% With exact arithmetic, each of these statements would produce the
+% same eigenvalues. After the introduction of some roundoff error,
+% two of the |lambdas| are indeterminant,
+% but |lambda = -1| is present in all four results.
+% Is |lambda = -1| a stable eigenvalue?
+
+ lambda_AB = eig(A,B)
+ lambda_BA = 1./eig(B,A)
+ lambda_ATBT = eig(A',B')
+ lambda_BTAT = 1./eig(B',A')
+
+%%
+% The triangular matrices for |lambda_AB|.
+
+ [QAZ,QBZ] = qz(A,B);
+ QAZ
+ QBZ
+
+%%
+% Careful examination of the diagonals reveals that |alfa(2)/beta(2)|
+% is producing the |-1|, while |alfa(3)/beta(3)| is roundoff over roundoff.
+
+ format long e
+ alfa = diag(QAZ)
+ beta = diag(QBZ)
+ format short
+
+
+%% Wilkinson example
+% Jim Wilkinson published a survey paper about QZ and Kronecker products
+% in 1979. One of his examples is
+
+ A = [4 3 2 5; 6 4 2 7; -1 -1 -2 -2; 5 3 2 6]
+
+ B = [2 1 3 4; 3 3 3 5; 0 0 -3 -2; 3 1 3 5]
+
+%%
+% Use the Symbolic Math Toolbox to verify that this is a singular pencil.
+
+ syms lambda
+ AB = A - lambda*B
+
+%%
+% The determinant is identically zero for all |lambda|.
+
+ d = det(AB)
+
+%%
+% With exact arithmetic, each of these statements would produce the
+% same eigenvalues, but in practice each set is different.
+% None of the eigenvalues is stable.
+
+ lambda_AB = eig(A,B)
+ lambda_BA = 1./eig(B,A)
+ lambda_ATBT = eig(A',B')
+ lambda_BTAT = 1./eig(B',A')
+
+%%
+% The triangular matrices for |lambda_AB| are
+
+ [QAZ,QBZ] = qz(A,B);
+ QAZ
+ QBZ
+
+%%
+% Examine the diagonals more carefully. |alfa(2)/beta(2)| is the only
+% roundoff over roundoff, but all four eigenvalues are unstable.
+
+ format long e
+ alfa = diag(QAZ)
+ beta = diag(QBZ)
+ format short
+
+%% References
+% C. B. Moler and G. W. Stewart,
+% "An Algorithm for Generalized Matrix Eigenvalue Problems",
+% _SIAM J. Numerical Analysis_, Vol.10, No.2, April 1973.
+% Also available at
+% <https://blogs.mathworks.com/cleve/files/cbm_gws.pdf cbm_gws.pdf>
+%
+% J. H. Wilkinson,
+% "Kronecker's Canonical Form and the QZ Algorithm",
+% _Linear Algebra and its Applications_, Vol. 28, 1979.
+% Also available at
+% <https://blogmathworks.com/cleve/files/wilkinson.pdf wilkinson.pdf>
+##### SOURCE END ##### 8891e70a294b4c03bb99ac1e6e01b5a5
+-->
+
+
+
+
+ Singular Matrix Pencils and the QZ Algorithm
+
+ 2023-01-05T16:37:04-07:00
+ https://hpc.social/2023/singular-matrix-pencils-and-the-qz-algorithm
+ <div class="content"><!--introduction--><p>This year, 2023, is the 50-th anniversary of the QZ algorithm for generalized matrix eignenvalue problems,</p>
+<pre class="language-matlab">Ax = λBx
+</pre><p>The algorithm computes these eigevalues without inverting either <tt>A</tt> or <tt>B</tt>. And, the QZ-algorithm can help detect and analyze exceptional situaions known as <i>singular pencils</i>.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#19d0dd38-a456-4a63-bf2f-18e02689531d">Matrix pencils</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#31c19b00-cfd8-493d-b712-08610ce3c5aa">Example</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#0f5d9fb9-0792-4d4c-a9ac-c5fd3e1e7691">Wilkinson example</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#cbe4eaf1-8a19-41e7-badd-1b8e69f74b61">References</a></li></ul></div>
+<h4>Matrix pencils<a name="19d0dd38-a456-4a63-bf2f-18e02689531d"></a></h4><p>If <tt>A</tt> and <tt>B</tt> are two square matrices, the <i>linear matrix pencil</i> is the matrix-valued function</p>
+<pre> A - λB</pre><p>A pencil is <i>regular</i> if there is at least one value of λ for which A - λB if not singular. The pencil is <i>singular</i> if both <tt>A</tt> and <tt>B</tt> are singular and, moreover, A - λB is singular for all λ. In other words,</p>
+<pre> det(A - λB) = 0 for all λ.</pre><p>Singular pencils are more insiduous than migt appear at first glance.</p>
+<h4>Example<a name="31c19b00-cfd8-493d-b712-08610ce3c5aa"></a></h4><pre class="codeinput"> A = [9 8 7; 6 5 4; 3 2 1]
+
+ B = [7 9 8; 4 6 5; 1 3 2]
+</pre><pre class="codeoutput">
+A =
+
+ 9 8 7
+ 6 5 4
+ 3 2 1
+
+
+B =
+
+ 7 9 8
+ 4 6 5
+ 1 3 2
+
+</pre><pre class="codeinput"> syms <span class="string">s</span>
+
+ AB = A - s*B
+
+ d = det(AB)
+</pre><pre class="codeoutput">
+AB =
+
+[9 - 7*s, 8 - 9*s, 7 - 8*s]
+[6 - 4*s, 5 - 6*s, 4 - 5*s]
+[ 3 - s, 2 - 3*s, 1 - 2*s]
+
+
+d =
+
+0
+
+</pre><pre class="codeinput"> eig1 = eig(A,B)
+
+ eig2 = 1./eig(B,A)
+
+ [QAZ,QBZ,Q,Z,V,W] = qz(A,B); QAZ, QBZ
+</pre><pre class="codeoutput">
+eig1 =
+
+ -0.4071
+ 1.0000
+ 0.2439
+
+
+eig2 =
+
+ -2.0000
+ 1.0000
+ 0.3536
+
+
+QAZ =
+
+ -1.0298 -13.0363 7.7455
+ 0 5.6991 -4.6389
+ 0 0 0.0000
+
+
+QBZ =
+
+ 2.4396 -11.4948 9.6394
+ 0 5.6991 -4.6389
+ 0 0 0.0000
+
+</pre><pre class="codeinput"> eig3 = eig(A',B')
+
+ eig4 = 1./eig(B',A')
+
+ [QATZ,QBTZ,Q,Z,V,W] = qz(A',B'); QATZ, QBTZ
+</pre><pre class="codeoutput">
+eig3 =
+
+ -0.2169
+ Inf
+ 1.0000
+
+
+eig4 =
+
+ -0.0738
+ 0
+ 1.0000
+
+
+QATZ =
+
+ -0.0000 -15.0218 6.8390
+ 0 2.6729 -2.2533
+ 0 0 0.5922
+
+
+QBTZ =
+
+ 0.0000 -15.2578 7.1280
+ 0 0 1.0203
+ 0 0 0.5922
+
+</pre><h4>Wilkinson example<a name="0f5d9fb9-0792-4d4c-a9ac-c5fd3e1e7691"></a></h4><pre class="codeinput"> clear
+
+ A = [4 3 2 5; 6 4 2 7; -1 -1 -2 -2; 5 3 2 6]
+
+ B = [2 1 3 4; 3 3 3 5; 0 0 -3 -2; 3 1 3 5]
+</pre><pre class="codeoutput">
+A =
+
+ 4 3 2 5
+ 6 4 2 7
+ -1 -1 -2 -2
+ 5 3 2 6
+
+
+B =
+
+ 2 1 3 4
+ 3 3 3 5
+ 0 0 -3 -2
+ 3 1 3 5
+
+</pre><pre class="codeinput"> syms <span class="string">s</span>
+
+ AB = A - s*B
+
+ d = det(AB)
+</pre><pre class="codeoutput">
+AB =
+
+[4 - 2*s, 3 - s, 2 - 3*s, 5 - 4*s]
+[6 - 3*s, 4 - 3*s, 2 - 3*s, 7 - 5*s]
+[ -1, -1, 3*s - 2, 2*s - 2]
+[5 - 3*s, 3 - s, 2 - 3*s, 6 - 5*s]
+
+
+d =
+
+0
+
+</pre><pre class="codeinput"> eig1 = eig(A,B)
+
+ eig2 = 1./eig(B,A)
+
+ [QAZ,QBZ,Q,Z,V,W] = qz(A,B); QAZ, QBZ
+</pre><pre class="codeoutput">
+eig1 =
+
+ 1.2056
+ 0.7055
+ -1.0000
+ -Inf
+
+
+eig2 =
+
+ 1.5097
+ 0.6408
+ 0
+ -1.0000
+
+
+QAZ =
+
+ 0.7437 4.1769 -12.7279 -5.5000
+ 0 0.0000 5.2328 2.1602
+ 0 0 0.7857 0.0123
+ 0 0 0 -0.2887
+
+
+QBZ =
+
+ 0.5005 6.6143 -8.4853 -2.5000
+ 0 0.0000 3.2668 2.0105
+ 0 0 1.1525 -0.7904
+ 0 0 0 0.2887
+
+</pre><pre class="codeinput"> eig3 = eig(A',B')
+
+ eig4 = 1./eig(B',A')
+
+ [QATZ,QBTZ,Q,Z,V,W] = qz(A',B'); QATZ, QBTZ
+</pre><pre class="codeoutput">
+eig3 =
+
+ -0.2141 + 0.2033i
+ -0.2141 - 0.2033i
+ 0.7013 + 0.0000i
+ 1.4508 + 0.0000i
+
+
+eig4 =
+
+ 0.3168
+ 0.9823
+ 1.2325
+ 0
+
+
+QATZ =
+
+ 0.1281 - 0.2434i 0.2665 + 0.0169i 0.2663 + 1.4905i 0.3721 + 3.5350i
+ 0.0000 + 0.0000i 0.0587 + 0.1116i 5.2603 - 1.6197i 12.7878 - 4.0110i
+ 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 4.1745 + 0.0000i
+ 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.7572 + 0.0000i
+
+
+QBTZ =
+
+ 0.9052 + 0.0000i 0.6130 - 0.6141i -0.2443 + 0.8738i 1.2233 + 2.5485i
+ 0.0000 + 0.0000i 0.4150 + 0.0000i 3.5658 - 1.2114i 8.0696 - 2.2671i
+ 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 6.6127 + 0.0000i
+ 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.5220 + 0.0000i
+
+</pre><h4>References<a name="cbe4eaf1-8a19-41e7-badd-1b8e69f74b61"></a></h4><p>C. B. Moler and G. W. Stewart, "An Algorithm for Generalized Matrix Eigenvalue Problems", SIAM J.NUMER.ANAL. Vol.10, No.2, April 1973. Also available at <a href="https://blogs.mathworks.com/cleve/files/cbm_gws.pdf">cbm_gws.pdf</a></p>
+<p>J. H. Wilkinson, Kronecker's Canonical Form and the QZ Algorithm", LINEAR ALGEBRA AND ITS APPPLICATIONS, Vol. 28, 1979. Also available at Also available at <a href="https://blogs.mathworks.com/cleve/files/wilkinson.pdf">wilkinson.pdf</a></p>
+<!--
+ function grabCode_a9bf4a4405b542598f6dba1c3d53fdbd() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='a9bf4a4405b542598f6dba1c3d53fdbd ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' a9bf4a4405b542598f6dba1c3d53fdbd';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2023 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2023a<br /></p>
+</div>
+<!--
+a9bf4a4405b542598f6dba1c3d53fdbd ##### SOURCE BEGIN #####
+%% Singular Matrix Pencils and the QZ Algorithm
+% This year, 2023, is the 50-th anniversary of the QZ algorithm
+% for generalized matrix eignenvalue problems,
+%
+% Ax = λBx
+%
+% The algorithm computes these eigevalues without inverting
+% either |A| or |B|. And, the QZ-algorithm can help detect and analyze
+% exceptional situaions known as _singular pencils_.
+
+%% Matrix pencils
+% If |A| and |B| are two square matrices, the _linear matrix pencil_
+% is the matrix-valued function
+%
+% A - λB
+%
+% A pencil is _regular_ if there is at least one value of λ for which
+% A - λB if not singular. The pencil is
+% _singular_ if both |A| and |B| are singular and, moreover, A - λB is
+% singular for all λ. In other words,
+%
+% det(A - λB) = 0 for all λ.
+
+%%
+% Singular pencils are more insiduous than migt appear at first glance.
+%% Example
+
+ A = [9 8 7; 6 5 4; 3 2 1]
+
+ B = [7 9 8; 4 6 5; 1 3 2]
+
+%%
+
+ syms s
+
+ AB = A - s*B
+
+ d = det(AB)
+
+%%
+
+ eig1 = eig(A,B)
+
+ eig2 = 1./eig(B,A)
+
+ [QAZ,QBZ,Q,Z,V,W] = qz(A,B); QAZ, QBZ
+
+
+%%
+
+ eig3 = eig(A',B')
+
+ eig4 = 1./eig(B',A')
+
+ [QATZ,QBTZ,Q,Z,V,W] = qz(A',B'); QATZ, QBTZ
+
+%% Wilkinson example
+
+ clear
+
+ A = [4 3 2 5; 6 4 2 7; -1 -1 -2 -2; 5 3 2 6]
+
+ B = [2 1 3 4; 3 3 3 5; 0 0 -3 -2; 3 1 3 5]
+
+
+%%
+
+ syms s
+
+ AB = A - s*B
+
+ d = det(AB)
+
+%%
+
+ eig1 = eig(A,B)
+
+ eig2 = 1./eig(B,A)
+
+ [QAZ,QBZ,Q,Z,V,W] = qz(A,B); QAZ, QBZ
+
+%%
+
+ eig3 = eig(A',B')
+
+ eig4 = 1./eig(B',A')
+
+ [QATZ,QBTZ,Q,Z,V,W] = qz(A',B'); QATZ, QBTZ
+
+%% References
+% C. B. Moler and G. W. Stewart,
+% "An Algorithm for Generalized Matrix Eigenvalue Problems",
+% SIAM J.NUMER.ANAL. Vol.10, No.2, April 1973. Also available at
+% <https://blogs.mathworks.com/cleve/files/cbm_gws.pdf cbm_gws.pdf>
+%
+% J. H. Wilkinson,
+% Kronecker's Canonical Form and the QZ Algorithm",
+% LINEAR ALGEBRA AND ITS APPPLICATIONS, Vol. 28, 1979. Also available at Also available at
+% <https://blogs.mathworks.com/cleve/files/wilkinson.pdf wilkinson.pdf>
+
+##### SOURCE END ##### a9bf4a4405b542598f6dba1c3d53fdbd
+-->
+
+
+
+
+ Color Cube Meets Rubik’s Cube
+
+ 2022-12-10T02:41:01-07:00
+ https://hpc.social/2022/color-cube-meets-rubik-s-cube
+ <div class="content"><!--introduction--><p>I have made a half dozen blog posts about <a href="https://blogs.mathworks.com/cleve/2022/09/05/rubiks-cube-superflips-and-gods-number/">Rubik's Cube</a> so far this year. And, during the MATLAB Central Mini Hack in October, I resurrected an old code about the <a href="https://blogs.mathworks.com/cleve/2022/10/21/an-interactive-version-of-colorcubes/">Color Cube</a>. Now, a combination of the two, Rubik/Color Qube, creates an elegant tool for investigating <i>Matrices in Action</i>.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#c4ab2cc4-7c62-45b6-b8d6-b58e96dd8c07">Opening</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#3426fb76-f361-4a32-b165-f771bba3fb03">Rubik and Color</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#28b692dc-0d85-4c30-905e-300857741d5c">Color Qube</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#f9469ecf-8b7e-41d3-8f47-ac23128f5f7d">Rotations</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#eb4d3e17-82e6-4b1e-b966-c75328d89269">n-by-n-by-n</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#715fe67d-21d9-46c4-a0b5-b2864db8776f">2-by-2-by-2</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#b23519d3-2aa0-46a3-9160-90f256981b7e">Software</a></li></ul></div>
+<h4>Opening<a name="c4ab2cc4-7c62-45b6-b8d6-b58e96dd8c07"></a></h4><p>Here is the opening screen shot of Rubik/Color Qube, one of the most elaborate MATLAB programs that I have ever written.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/screen_shot1.png" vspace="5" /> </p>
+<h4>Rubik and Color<a name="3426fb76-f361-4a32-b165-f771bba3fb03"></a></h4><p>There are two modes, <tt>rubik</tt> and <tt>color</tt>. In <tt>rubik</tt> mode, the large cube is formed from 27 identical copies of a single small <i>cubelet</i>. The six cubelet faces have six different colors. Red, white and blue are visible initially. Orange, yellow and green become visible as the faces are rotated.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/rubik.gif" vspace="5" /> </p>
+<p>In <tt>color</tt> mode, the large cube is formed from 27 <i>cubelets</i>, each with a different solid color. Three of the corner cubelets are the primary colors in the RGB color model -- red, green and blue. Three more corners are the complementary cyan, magenta and yellow. White and black complete the list of corners.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/color.gif" vspace="5" /> </p>
+<h4>Color Qube<a name="28b692dc-0d85-4c30-905e-300857741d5c"></a></h4><p>All of the familiar Rubik's moves are available in <tt>color</tt> mode. Here is a screen shot after a few rotations.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/screen_shot2.png" vspace="5" /> </p>
+<h4>Rotations<a name="f9469ecf-8b7e-41d3-8f47-ac23128f5f7d"></a></h4><p>Rotation matrices defined by this <tt>Rk</tt> function are the basic mathematical tool employed by <tt>Qube</tt>. The animation provides a detailed look at the action produced by the F key, counter-clockwise rotation of the Front face. This is the y-axis, case 2 in <tt>Rk</tt>. The detail is provided by taking <tt>d = 0:3:90</tt>, so there are 30 steps of 3 degrees.</p>
+<pre class="language-matlab"><span class="keyword">function</span> R = Rk(axis,d)
+ <span class="comment">% Rk(axis,d), Rotation by d degrees about the x-, y-, or z-axis.</span>
+ c = cosd(d);
+ s = sind(d);
+ <span class="keyword">switch</span> axis
+ <span class="keyword">case</span> 1, R = [ 1 0 0
+ 0 c s
+ 0 -s c ];
+ <span class="keyword">case</span> 2, R = [ c 0 s
+ 0 1 0
+ -s 0 c ];
+ <span class="keyword">case</span> 3, R = [ c s 0
+ -s c 0
+ 0 0 1 ];
+ <span class="keyword">end</span>
+ fmat = findobj(<span class="string">'tag'</span>,<span class="string">'fmat'</span>);
+ <span class="keyword">if</span> ~isempty(fmat)
+ fmat.String = mat3(R);
+ <span class="keyword">end</span>
+<span class="keyword">end</span>
+</pre><p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/dpm3.gif" vspace="5" /> </p>
+<h4>n-by-n-by-n<a name="eb4d3e17-82e6-4b1e-b966-c75328d89269"></a></h4><p><tt>Qube</tt> generalizes the classic 3-by-3-by-3 Rubik's Cube to n-by-n-by-n cubes for any n.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/n_by_n.gif" vspace="5" /> </p>
+<h4>2-by-2-by-2<a name="715fe67d-21d9-46c4-a0b5-b2864db8776f"></a></h4><p>The 2-by-2-by-2 cubes are good starting points for investigation of mathematical properties.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/2_by_2.png" vspace="5" /> </p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/2_by_2_color.png" vspace="5" /> </p>
+<h4>Software<a name="b23519d3-2aa0-46a3-9160-90f256981b7e"></a></h4><p><tt>Qube</tt> is available as a self-extracting MATLAB archive at this link, <a href="https://blogs.mathworks.com/cleve/files/Qube_mzip.m">Qube_mzip.m</a>.</p>
+<!--
+ function grabCode_ce9c453c88254608ad0e691ca4711df7() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='ce9c453c88254608ad0e691ca4711df7 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' ce9c453c88254608ad0e691ca4711df7';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2022 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2022b<br /></p>
+</div>
+<!--
+ce9c453c88254608ad0e691ca4711df7 ##### SOURCE BEGIN #####
+%% Color Cube Meets Rubik's Cube
+% I have made a half dozen blog posts about
+% <https://blogs.mathworks.com/cleve/2022/09/05/rubiks-cube-superflips-and-gods-number/
+% Rubik's Cube> so far this year. And, during the MATLAB Central Mini
+% Hack in October, I resurrected an old code about the
+% <https://blogs.mathworks.com/cleve/2022/10/21/an-interactive-version-of-colorcubes/
+% Color Cube>. Now, a combination of the two, Rubik/Color Qube,
+% creates an elegant
+% tool for investigating _Matrices in Action_.
+
+%% Opening
+% Here is the opening screen shot of Rubik/Color Qube, one of the most
+% elaborate MATLAB programs that I have ever written.
+%
+% <<screen_shot1.png>>
+%
+
+%% Rubik and Color
+% There are two modes, |rubik| and |color|.
+% In |rubik| mode, the large cube is formed from 27 identical copies
+% of a single small _cubelet_. The six cubelet faces have six different
+% colors. Red, white and blue are visible initially. Orange, yellow
+% and green become visible as the faces are rotated.
+%
+% <<rubik.gif>>
+%
+% In |color| mode, the large cube is formed from 27 _cubelets_,
+% each with a different solid color. Three of the corner cubelets are the
+% primary colors in the RGB color model REPLACE_WITH_DASH_DASH red, green and blue. Three
+% more corners are the complementary cyan, magenta and yellow.
+% White and black complete the list of corners.
+%
+% <<color.gif>>
+%
+
+%% Color Qube
+% All of the familiar Rubik's moves are available in |color| mode.
+% Here is a screen shot after a few rotations.
+%
+% <<screen_shot2.png>>
+%
+
+%% Rotations
+% Rotation matrices defined by this |Rk| function are the basic
+% mathematical tool employed by |Qube|. The animation provides a detailed
+% look at the action produced by the F key, counter-clockwise rotation of
+% the Front face. This is the y-axis, case 2 in |Rk|. The detail is
+% provided by taking |d = 0:3:90|, so there are 30 steps of 3 degrees.
+%
+% function R = Rk(axis,d)
+% % Rk(axis,d), Rotation by d degrees about the x-, y-, or z-axis.
+% c = cosd(d);
+% s = sind(d);
+% switch axis
+% case 1, R = [ 1 0 0
+% 0 c s
+% 0 -s c ];
+% case 2, R = [ c 0 s
+% 0 1 0
+% -s 0 c ];
+% case 3, R = [ c s 0
+% -s c 0
+% 0 0 1 ];
+% end
+% fmat = findobj('tag','fmat');
+% if ~isempty(fmat)
+% fmat.String = mat3(R);
+% end
+% end
+%
+%
+% <<dpm3.gif>>
+%
+
+%% n-by-n-by-n
+% |Qube| generalizes the classic 3-by-3-by-3 Rubik's Cube
+% to n-by-n-by-n cubes for any n.
+%
+% <<n_by_n.gif>>
+%
+
+%% 2-by-2-by-2
+% The 2-by-2-by-2 cubes are good starting points for investigation
+% of mathematical properties.
+%
+% <<2_by_2.png>>
+%
+% <<2_by_2_color.png>>
+%
+
+%% Software
+% |Qube| is available as a self-extracting MATLAB archive at this link,
+% <https://blogs.mathworks.com/cleve/files/Qube_mzip.m Qube_mzip.m>.
+##### SOURCE END ##### ce9c453c88254608ad0e691ca4711df7
+-->
+
+
+
+
+ Christian Reinsch, Roland Bulirsch, and the SVD
+
+ 2022-10-23T23:41:27-06:00
+ https://hpc.social/2022/christian-reinsch-roland-bulirsch-and-the-svd
+ <div class="content"><!--introduction--><p>Christian Reinsch and Roland Bulirsch both passed away recently, Reinsch on October 8 and Bulirsch on September 21. Reinsch was 88 years old and Bulirsch was 89. Both of them were retired professors of numerical analysis at the Technical University of Munich. Both of them were friends of mine. But in almost all other ways, they were very different people.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#0ac36cdd-70e0-4088-9e69-ed2d4f0ca1b2">Wilkinson and Reinsch</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#639c5ab8-be39-47d9-ad03-85ef8bfdb2d4">Wilkinson versus Reinsch</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#0f4a7aaa-052c-4af3-91d2-afa776ca9db7">Reinsch Personal Life</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#52c11caf-6fe1-4b50-9418-ced2ab57b498">SVD</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#b7a10e23-f5b3-4749-a571-a11b1c543e58">Stoer and Bulirsch</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#7d54ff86-6fef-4065-9b83-20dc7c627151">Bulirsch Personal Life</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#4d6e1726-75b6-4959-89de-d60322a4a857">Munich Visit</a></li></ul></div>
+<h4>Wilkinson and Reinsch<a name="0ac36cdd-70e0-4088-9e69-ed2d4f0ca1b2"></a></h4><p>The <i>Handbook for Automatic Computation, Volume II, Linear Algebra</i>, is a research monograph published in 1971 by Springer-Verlag. This <i>Handbook</i> was edited by J. H. Wilkinson and Christian Reinsch and includes dozens of Algol procedures by 19 different authors for solving systems of simultaneous equations and computing matrix eigenvalues and singular values.</p>
+<p>Wilkinson and colleagues at the National Physical Laboratory in Teddington, England wrote around half of the Algol procedures in the <i>Handbook</i>. Reinsch authored several procedures himself and reviewed and tested most, if not all, of the entire <i>Handbook</i>.</p>
+<p>Translations into Fortran of many of the Algol codes produced the EISPACK subroutine library that led to the first MATLAB. I think it is fair to say that without the work of Jim Wilkinson and Christian Reinsch on the <i>Handbook</i> there might never have been a MATLAB.</p>
+<h4>Wilkinson versus Reinsch<a name="639c5ab8-be39-47d9-ad03-85ef8bfdb2d4"></a></h4><p>I would have loved to listen in to discussions between Jim and Christian during the development of the <i>Handbook</i>. Here were two very talented, proud individuals working together at the detailed level required of scientific computer programing. It must have been exciting.</p>
+<p>One small example: what subscripts do you use for the <tt>n-1</tt> off-diagonal elements of the symmetric, tridiagonal matrix of order <tt>n</tt> produced in one procedure and passed to another? Is it <tt>e(1:n-1)</tt> or <tt>e(2:n)</tt>? (A "modern" <tt>e(0:n-2)</tt> is not a possibility.) The first statement of the Algol procedures for the QR algorithms is</p>
+<pre> for i := 2 step 1 until n do e[i-1] := e[i];</pre><p>Was there some kind of disconnect between Teddington and Munich?</p>
+<h4>Reinsch Personal Life<a name="0f4a7aaa-052c-4af3-91d2-afa776ca9db7"></a></h4><p>Christian Reinsch was born in Chemnitz, Germany, in 1934. He spent most of his career at the Technical University Munich, where he was a close associate of <a href="https://blogs.mathworks.com/cleve/2015/06/01/friedrich-bauer">Fritz Bauer</a>.</p>
+<p>Christian was an intensely private person. He never married and lived alone. He visited Argonne Laboratory in the 1970s, when we were working on EISPACK, and he attended a few Gatlinburg/Householder meetings. Other than that, he rarely travelled far from Munich.</p>
+<p>This photo, taken by his colleague Christoph Zenger, is the only photo of Reinsch that I have ever seen. And, as far as I know, it will be the first photo of him available on the Internet.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Reinsch_1.jpg" vspace="5" /> </p>
+<p>Photo credit: Christoph Zenger</p>
+<h4>SVD<a name="52c11caf-6fe1-4b50-9418-ced2ab57b498"></a></h4><p>Gene Golub is known as <a href="https://www.mathworks.com/company/newsletters/articles/professor-svd.html">Professor SVD</a> because he did more than anyone else to develop the algorithms for computing the decomposition and for popularizing its applications. A 1965 paper by Golub and Velvel Kahan provides the first practical method for computing the SVD. The Golub/Kahan approach is based on the eigenvalues of the <i>2n-by-2n</i> block matrix <tt>[0 A; A' 0]</tt> .</p>
+<p>Peter Businger was a grad student at Stanford in the 1960's who worked with Golub on several projects. A 1967 Stanford technical report by Golub and Businger includes an Algol procedure, written by Businger, for computing the SVD that is based on bidiagonalizing <tt>A</tt> itself. Both Golub/Kahan and Golub/Businger suggest Sturm sequences and Givens rotations for ultimately computing the singular values.</p>
+<p>At the same time, Christian Reinsch independently developed his own method for computing the SVD. His review work on the <i>Handbook</i> gave Reinsch access to the implicit tridiagonal QR techniques for matrix eigenvalues that Francis and Wilkinson were investigating. So, Reinsch adapted implicit QR with Wilkinson shifts to the singular value situation.</p>
+<p>Both Gene Golub and Christian Reinsch offered SVD contributions for the <i>Handbook</i> . It turns out that, with exact arithmetic and the same shifts, Golub/Businger and Reinsch would produce the same results. But Golub and Businger never used Wilkinson shifts and Golub did not join the QR club until later. Fortunately, Fritz Bauer, editor in chief of the <i>Handbook</i>, brokered a joint authorship arrangement and the Golub-Reinsch algorithm for computing the SVD resulted.</p>
+<p>Walter Gander has investigated the history of SVD algorithms. The slides for the talk he presented at a workshop in Lanzhou University are available <a href="https://people.inf.ethz.ch/gander/talks/Vortrag2022.pdf">at this link</a>.</p>
+<h4>Stoer and Bulirsch<a name="b7a10e23-f5b3-4749-a571-a11b1c543e58"></a></h4><p><i>Einfuhrung in die Numerische Mathematik</i>, <i>Introduction to Numerical Analysis</i>, is a classic textbook by Josef Stoer and Roland Bulirsch. The original German editions were published by Springer-Verlag in 1972 and 1976. The English translations were published in 1980 and 1993. A complete PDF of the second English edition is available <a href="https://zhilin.math.ncsu.edu/TEACHING/MA580/Stoer_Bulirsch.pdf">at this link</a>.</p>
+<p>I think of Stoer & Bulirsch as one of the best theoretical textbooks in numerical analysis. It is comparable to Isaacson & Keller. There are theorems and proofs. There are algorithms, but no software. There are a few, but not many, numerical examples. There are many excellent exercises.</p>
+<h4>Bulirsch Personal Life<a name="7d54ff86-6fef-4065-9b83-20dc7c627151"></a></h4><p>Roland Bulirsch was born in Liberec, in the former Czechoslovkia, in 1932. After visiting U. C. San Diego in the 1960's, he spent most of his career at the Technical University Munich. In contrast to Reinsch, Bulirsch was a very gregarious, public person. He adored his grand children and they adored him. The three-part <a href="https://bulirsch.eu/anlagen/Bulirsch_80_Jahre_1.pdf">photo collection</a> assembled for his 80th birthday has hundreds of snapshots and portraits.</p>
+<p>Roland was an avid body-builder. He had the broadest shoulders that I have ever seen -- and they were twice as broad as his waist. He had huge hands and huge biceps. One of my favorite stories about Roland explains the photo on his desk that was signed,</p>
+<pre> "Thanks for everything -- Arnie"</pre><p>It turns out that Roland and a body-builder from Austria named Arnold Swartzenegger trained together in Munich in the 1960's. Roland and some friends from the gym took up a collection to help the ambitious young Arnie emigrate to America.</p>
+<p>Here are a few photos from Roland's albums.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Roland_1.png" vspace="5" /> </p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Arnie_1.png" vspace="5" /> </p>
+<h4>Munich Visit<a name="4d6e1726-75b6-4959-89de-d60322a4a857"></a></h4><p>My last visit to T. U. Munich was in 2015. I gave my stump speech, <a href="https://www.youtube.com/watch?v=ekcLT8QgB60">The Evolution of MATLAB</a>, in a big, new lecture hall named after Friedrich Bauer. Christian Reinsch was in the audience (skip to time stamp 13:59 <a href="https://www.youtube.com/watch?v=ekcLT8QgB60f">in the video</a>). He was over 70 years old at the time and had just finished his daily 50-kilometer bicycle ride.</p>
+<p>After the talk, a few of us found our way to one of the famous Munich <i>Biergarten</i>. Christian came along but did not stay for dinner. He was not a beer drinker.</p>
+<p>Roland Bulirsch was able to join us for dinner, however, and we managed to polish off a few of those one-liter German beer steins before closing down the place.</p>
+<!--
+ function grabCode_f2dde2cc84e245d09b99f58b9781b0eb() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='f2dde2cc84e245d09b99f58b9781b0eb ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' f2dde2cc84e245d09b99f58b9781b0eb';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2022 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2022a<br /></p>
+</div>
+<!--
+f2dde2cc84e245d09b99f58b9781b0eb ##### SOURCE BEGIN #####
+%% Christian Reinsch, Roland Bulirsch, and the SVD
+% Christian Reinsch and Roland Bulirsch both passed away recently,
+% Reinsch on October 8 and Bulirsch on September 21.
+% Reinsch was 88 years old and Bulirsch was 89.
+% Both of them were retired professors of numerical analysis at the
+% Technical University of Munich.
+% Both of them were friends of mine.
+% But in almost all other ways, they were very different people.
+
+%% Wilkinson and Reinsch
+% The _Handbook for Automatic Computation, Volume II, Linear Algebra_, is a
+% research monograph published in 1971 by Springer-Verlag. This _Handbook_
+% was edited by J. H. Wilkinson and Christian Reinsch and includes dozens
+% of Algol procedures by 19 different authors for solving systems of
+% simultaneous equations and computing matrix eigenvalues and singular
+% values.
+
+%%
+% Wilkinson and colleagues at the National Physical Laboratory in
+% Teddington, England wrote around half of the Algol procedures in the
+% _Handbook_. Reinsch authored several procedures himself
+% and reviewed and tested most, if not all, of the entire _Handbook_.
+%
+% Translations into Fortran of many of the Algol codes produced the
+% EISPACK subroutine library that led to the first MATLAB.
+% I think it is fair to say that without the work of Jim Wilkinson and
+% Christian Reinsch on the _Handbook_ there might never have been a MATLAB.
+
+%% Wilkinson versus Reinsch
+% I would have loved to listen in to discussions between Jim and Christian
+% during the development of the _Handbook_. Here were two very talented,
+% proud individuals working together at the detailed level required of
+% scientific computer programing. It must have been exciting.
+%
+% One small example: what subscripts do you use for the |n-1| off-diagonal
+% elements of the symmetric, tridiagonal matrix of order |n| produced in
+% one procedure and passed to another?
+% Is it |e(1:n-1)| or |e(2:n)|? (A "modern" |e(0:n-2)| is
+% not a possibility.) The first statement of the Algol procedures
+% for the QR algorithms is
+%
+% for i := 2 step 1 until n do e[i-1] := e[i];
+%
+% Was there some kind of disconnect between Teddington and Munich?
+
+%% Reinsch Personal Life
+% Christian Reinsch was born in Chemnitz, Germany, in 1934.
+% He spent most of his career at the Technical University Munich, where
+% he was a close associate of
+% <https://blogs.mathworks.com/cleve/2015/06/01/friedrich-bauer
+% Fritz Bauer>.
+%
+% Christian was an intensely private person. He never married and lived
+% alone. He visited Argonne Laboratory in the 1970s, when we were working
+% on EISPACK, and he attended a few Gatlinburg/Householder meetings.
+% Other than that, he rarely travelled far from Munich.
+%
+% This photo, taken by his colleague Christoph Zenger,
+% is the only photo of Reinsch that I have ever seen. And, as far as I
+% know, it will be the first photo of him available on the Internet.
+%
+% <<Reinsch_1.jpg>>
+%
+% Photo credit: Christoph Zenger
+%
+
+%% SVD
+% Gene Golub is known as
+% <https://www.mathworks.com/company/newsletters/articles/professor-svd.html
+% Professor SVD> because he did more than anyone
+% else to develop the algorithms for computing the decomposition and
+% for popularizing its applications. A 1965 paper by Golub and
+% Velvel Kahan provides the first practical method for computing the
+% SVD. The Golub/Kahan approach is based on the eigenvalues of the
+% _2n-by-2n_ block matrix |[0 A; A' 0]| .
+%
+% Peter Businger was a grad student at Stanford in the 1960's who
+% worked with Golub on several projects. A 1967 Stanford technical
+% report by Golub and Businger includes an Algol procedure, written by
+% Businger, for computing the SVD that is based on bidiagonalizing |A|
+% itself. Both Golub/Kahan and Golub/Businger suggest Sturm sequences
+% and Givens rotations for ultimately computing the singular values.
+%
+% At the same time, Christian Reinsch independently developed his own
+% method for computing the SVD. His review work on the _Handbook_
+% gave Reinsch access to the implicit tridiagonal QR techniques for
+% matrix eigenvalues that Francis and Wilkinson were investigating. So,
+% Reinsch adapted implicit QR with Wilkinson shifts to the singular value
+% situation.
+%
+% Both Gene Golub and Christian Reinsch offered SVD
+% contributions for the _Handbook_ . It turns out that, with exact
+% arithmetic and the same shifts, Golub/Businger and Reinsch would
+% produce the same results. But Golub and Businger never used
+% Wilkinson shifts and Golub did not join the QR club until later.
+% Fortunately, Fritz Bauer, editor in chief of the _Handbook_, brokered
+% a joint authorship arrangement and the Golub-Reinsch algorithm
+% for computing the SVD resulted.
+%
+% Walter Gander has investigated the history of SVD algorithms.
+% The slides for the talk he presented at a workshop in
+% Lanzhou University are available
+% <https://people.inf.ethz.ch/gander/talks/Vortrag2022.pdf
+% at this link>.
+
+%% Stoer and Bulirsch
+% _Einfuhrung in die Numerische Mathematik_, _Introduction to Numerical
+% Analysis_, is a classic textbook by Josef Stoer and Roland Bulirsch.
+% The original German editions were published by Springer-Verlag in 1972
+% and 1976. The English translations were published in 1980 and 1993.
+% A complete PDF of the second English edition is available
+% <https://zhilin.math.ncsu.edu/TEACHING/MA580/Stoer_Bulirsch.pdf
+% at this link>.
+%
+% I think of Stoer & Bulirsch as one of the best theoretical
+% textbooks in numerical analysis. It is comparable to Isaacson & Keller.
+% There are theorems and proofs. There are algorithms, but no
+% software. There are a few, but not many, numerical examples.
+% There are many excellent exercises.
+
+%% Bulirsch Personal Life
+% Roland Bulirsch was born in Liberec, in the former Czechoslovkia,
+% in 1932. After visiting U. C. San Diego in the 1960's,
+% he spent most of his career at the Technical University Munich.
+% In contrast to Reinsch, Bulirsch was a very gregarious, public person.
+% He adored his grand children and they adored him. The three-part
+% <https://bulirsch.eu/anlagen/Bulirsch_80_Jahre_1.pdf photo collection>
+% assembled for his 80th birthday has hundreds of snapshots and portraits.
+%
+% Roland was an avid body-builder. He had the broadest shoulders that
+% I have ever seen REPLACE_WITH_DASH_DASH and they were twice as broad as his waist.
+% He had huge hands and huge biceps. One of my favorite stories about
+% Roland explains the photo on his desk that was signed,
+%
+% "Thanks for everything REPLACE_WITH_DASH_DASH Arnie"
+%
+% It turns out that Roland and a body-builder from Austria
+% named Arnold Swartzenegger trained together in Munich in the 1960's.
+% Roland and some friends from the gym took up a collection to help
+% the ambitious young Arnie emigrate to America.
+
+%%
+% Here are a few photos from Roland's albums.
+%
+% <<Roland_1.png>>
+%
+% <<Arnie_1.png>>
+%
+
+%% Munich Visit
+% My last visit to T. U. Munich was in 2015.
+% I gave my stump speech,
+% <https://www.youtube.com/watch?v=ekcLT8QgB60 The Evolution of MATLAB>,
+% in a big, new lecture hall named after Friedrich Bauer. Christian
+% Reinsch was in the audience (skip to time stamp 13:59
+% <https://www.youtube.com/watch?v=ekcLT8QgB60f in the video>).
+% He was over 70 years old at the time and had just finished his daily
+% 50-kilometer bicycle ride.
+%
+% After the talk, a few of us found our way to one of the famous Munich
+% _Biergarten_. Christian came along but did not stay for dinner.
+% He was not a beer drinker.
+%
+% Roland Bulirsch was able to join us for dinner, however, and we managed
+% to polish off a few of those one-liter German beer steins before
+% closing down the place.
+##### SOURCE END ##### f2dde2cc84e245d09b99f58b9781b0eb
+-->
+
+
+
+
+ An Interactive Version of colorcubes
+
+ 2022-10-21T20:58:02-06:00
+ https://hpc.social/2022/an-interactive-version-of-colorcubes
+ <div class="content"><!--introduction--><p>A 231-character static version of <a href="https://www.mathworks.com/matlabcentral/communitycontests/contests/5/entries/11543">colorcubes</a> in the current <a href="https://www.mathworks.com/matlabcentral/communitycontests/contests/5/entries">MiniHack</a> generated quite a bit of interest. So I am posting the full version, where you can change number of cubes and the view point, <a href="https://blogs.mathworks.com/cleve/files/colorcubes.m">at this link</a>.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#2842fcd2-e0df-4ec2-bc84-82fad5a13e51">Animation</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#530668b0-ea28-4376-a885-fa4d1a9c2037">Quiz</a></li></ul></div>
+<h4>Animation<a name="2842fcd2-e0df-4ec2-bc84-82fad5a13e51"></a></h4><p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/color_cubes.gif" vspace="5" /> </p>
+<h4>Quiz<a name="530668b0-ea28-4376-a885-fa4d1a9c2037"></a></h4><p>What is the color of the cubelet, or cubelets, in the center?</p>
+<!--
+ function grabCode_0796b1601674403b8501c6cc237cbce2() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='0796b1601674403b8501c6cc237cbce2 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 0796b1601674403b8501c6cc237cbce2';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2022 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2022a<br /></p>
+</div>
+<!--
+0796b1601674403b8501c6cc237cbce2 ##### SOURCE BEGIN #####
+%% An Interactive Version of colorcubes
+% A 231-character static version of
+% <https://www.mathworks.com/matlabcentral/communitycontests/contests/5/entries/11543
+% colorcubes> in the current
+% <https://www.mathworks.com/matlabcentral/communitycontests/contests/5/entries
+% MiniHack> generated quite a bit of interest.
+% So I am posting the full version, where you can change number of cubes
+% and the view point,
+% <https://blogs.mathworks.com/cleve/files/colorcubes.m
+% at this link>.
+
+%% Animation
+%
+% <<color_cubes.gif>>
+%
+
+%% Quiz
+% What is the color of the cubelet, or cubelets, in the center?
+##### SOURCE END ##### 0796b1601674403b8501c6cc237cbce2
+-->
+
+
+
+
+ modfun, A Short Program Produces Impressive Graphics
+
+ 2022-10-17T23:17:12-06:00
+ https://hpc.social/2022/modfun-a-short-program-produces-impressive-graphics
+ <div class="content"><!--introduction--><p>This nifty graphics gem started with a contribution by Paul Villain to the MATLAB 2022 Mini Hack, currently taking place on <a href="https://www.mathworks.com/matlabcentral/contests.html">MATLAB Central</a>.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#56a0ec8a-8f48-4d49-951d-ede8fd35a5a3"><tt>modfun</tt></a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#a4a42958-572e-4506-9fd6-fd5704698093">code</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#580b1824-d2ab-4ea9-883a-1aa69d0c8bb1">Animation</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#24d1d844-3760-4a2d-bd68-8671d9ff55b6">Gallery</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#b5cd86af-e8cd-4db6-9341-fa63d035cc3d">Quiz</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#336d3ee4-5965-44e5-bc73-926eb724f3f4">Software</a></li></ul></div>
+<h4><tt>modfun</tt><a name="56a0ec8a-8f48-4d49-951d-ede8fd35a5a3"></a></h4><p>Villain's contribution is <a href="https://www.mathworks.com/matlabcentral/communitycontests/contests/5/entries/9880">102 mod 500</a> . My rewrite is <a href="https://www.mathworks.com/matlabcentral/communitycontests/contests/5/entries/11093"><tt>modfun</tt></a>. Villain's <tt>102</tt> and <tt>500</tt> become the parameters <tt>m</tt> and <tt>n</tt>.</p>
+<pre> modfun(m,n) connects n points, z(j), equally spaced
+ around the complex unit circle, by n+1 straight lines.
+ The j-th line connects z(j+1) to z(mod(j*m,n)+1).</pre><h4>code<a name="a4a42958-572e-4506-9fd6-fd5704698093"></a></h4><p>The basic code uses complex arithmetic and is only eight lines long. When the graphics is done with <tt>line</tt> instead of <tt>plot</tt>, it is not necessary to use <tt>hold on</tt>.</p>
+<pre> function modfun(m,n)
+ init_fig
+ z = exp(2i*pi*(0:n)/n);
+ for j = 0:n
+ zj = [z(j+1),z(mod(j*m,n)+1)];
+ line(real(zj),imag(zj))
+ end
+ end</pre><p>The initialization makes <tt>line</tt> possible.</p>
+<pre> function init_fig
+ axis([-1 1 -1 1])
+ axis square
+ axis off
+ end</pre><h4>Animation<a name="580b1824-d2ab-4ea9-883a-1aa69d0c8bb1"></a></h4><p>This animation of <tt>modfun(105,200)</tt> has one frame for every five lines.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/modfun105.gif" vspace="5" /> </p>
+<h4>Gallery<a name="24d1d844-3760-4a2d-bd68-8671d9ff55b6"></a></h4><p>A sample.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/modfuns1.png" vspace="5" /> </p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/modfuns2.png" vspace="5" /> </p>
+<h4>Quiz<a name="b5cd86af-e8cd-4db6-9341-fa63d035cc3d"></a></h4><p>Match these calls to <tt>modfun</tt> to the plots in the Gallery.</p>
+<pre> modfun(88,179)
+ modfun(89,220)
+ modfun(99,200)
+ modfun(101,200)
+ modfun(111,200)
+ modfun(113,188)
+ modfun(126,188)
+ modfun(126,200)</pre><h4>Software<a name="336d3ee4-5965-44e5-bc73-926eb724f3f4"></a></h4><p>An interactive <tt>modfun</tt>.</p>
+<p><a href="https://blogs.mathworks.com/cleve/files/modfun.m">modfun.m</a>.</p>
+<!--
+ function grabCode_ce8d1e93d27746db8cedca87febedacd() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='ce8d1e93d27746db8cedca87febedacd ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' ce8d1e93d27746db8cedca87febedacd';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2022 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2022a<br /></p>
+</div>
+<!--
+ce8d1e93d27746db8cedca87febedacd ##### SOURCE BEGIN #####
+%% |modfun|, A Short Program Produces Impressive Graphics
+% This nifty graphics gem started with a contribution by Paul Villain
+% to the MATLAB 2022 Mini Hack, currently taking place on
+% <https://www.mathworks.com/matlabcentral/contests.html MATLAB Central>.
+
+%% |modfun|
+% Villain's contribution is
+% <https://www.mathworks.com/matlabcentral/communitycontests/contests/5/entries/9880
+% 102 mod 500> . My rewrite is
+% <https://www.mathworks.com/matlabcentral/communitycontests/contests/5/entries/11093
+% |modfun|>.
+% Villain's |102| and |500| become the parameters |m| and |n|.
+%
+% modfun(m,n) connects n points, z(j), equally spaced
+% around the complex unit circle, by n+1 straight lines.
+% The j-th line connects z(j+1) to z(mod(j*m,n)+1).
+%
+%% code
+% The basic code uses complex arithmetic and is only eight lines long.
+% When the graphics is done with |line| instead of |plot|,
+% it is not necessary to use |hold on|.
+%
+% function modfun(m,n)
+% init_fig
+% z = exp(2i*pi*(0:n)/n);
+% for j = 0:n
+% zj = [z(j+1),z(mod(j*m,n)+1)];
+% line(real(zj),imag(zj))
+% end
+% end
+%
+% The initialization makes |line| possible.
+%
+% function init_fig
+% axis([-1 1 -1 1])
+% axis square
+% axis off
+% end
+
+%% Animation
+% This animation of |modfun(105,200)| has one frame for every five lines.
+%
+% <<modfun105.gif>>
+%
+
+%% Gallery
+% A sample.
+%
+% <<modfuns1.png>>
+%
+% <<modfuns2.png>>
+
+%% Quiz
+% Match these calls to |modfun| to the plots in the Gallery.
+%
+% modfun(88,179)
+% modfun(89,220)
+% modfun(99,200)
+% modfun(101,200)
+% modfun(111,200)
+% modfun(113,188)
+% modfun(126,188)
+% modfun(126,200)
+
+%% Software
+% An interactive |modfun|.
+%
+% <https://blogs.mathworks.com/cleve/files/modfun.m modfun.m>.
+##### SOURCE END ##### ce8d1e93d27746db8cedca87febedacd
+-->
+
+
+
+
+ Trio, A Wooden Puzzle from the Czech Republic
+
+ 2022-09-25T17:00:41-06:00
+ https://hpc.social/2022/trio-a-wooden-puzzle-from-the-czech-republic
+ <div class="content"><!--introduction--><p>"Clever Toys" is a puzzle company in the Czech Republic. <a href="http://www.clevertoys.cz/index_eng.php?page=eng">Their Web site</a> describes five different hand-made, wooden puzzles that are related mathematically to the Rubik's Cube.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#52520048-f34a-4981-840a-9007a0387f6b">Puzzle</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#2dfd1830-7360-4517-9796-4632c066c884">Model</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#99075c53-97fe-4397-a096-3baedc01f129">Scramble</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#a45994ba-ec9b-49ab-b897-d0f79de81dcd">Animation</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#ff195cfa-9e7f-4693-9c9e-5109eebc19c4">Unscramble</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#87972e4e-c85c-4982-8459-add195223548">Solutions</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#2e58ba8b-073a-402d-8259-2f095e0e72d2">Software</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#0c756fc0-bf5b-4ccc-8d56-8eab84048dee">Thanks</a></li></ul></div>
+<h4>Puzzle<a name="52520048-f34a-4981-840a-9007a0387f6b"></a></h4><p>Here is the photo of the puzzle "Trio".</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/trio_puzzle.png" vspace="5" /> </p>
+<p>Here is an English translation of their description.</p>
+<p>
+<p style="margin-left: 3ex;">
+The task of this 2D puzzle is to assemble all the ovals according
+to their color into a basic assembly. By moving the balls in the
+grooves and turning the center wheel, you can gradually get each
+ball where you need it.
+</p>
+
+</p>
+<p>I am not sure that Clever Toys is still in business. They have not responded to my emails and I have not been able to purchase an actual Trio puzzle. Of course, that is all the motivation I need to make a MATLAB model.</p>
+<h4>Model<a name="2dfd1830-7360-4517-9796-4632c066c884"></a></h4><p>Here is the initial configuration. There are three fixed outer, partial, discs and one inner, full, disc. Each of the outer discs has a channel containing 10 marbles. When the inner disc is positioned properly, the marbles in a channel can be rotated. Rotating the inner disc itself moves some, but not all, of the marbles, thereby scrambling the colors.</p>
+<p>Like Rubik's Cube, the objective of the puzzle is to return to this initial "solved" state.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/trio_initial.gif" vspace="5" /> </p>
+<p>Mathematically, both Rubik's Cube and Trio are ultimately based upon rotation matrices. Rubik's Cube is a 3-D puzzle whose state is specified by the position and orientation of 27 cubelets; this gives Rubik's Cube about <tt>4.3*10^19</tt> possible positions. At each step, there are six faces and 12 possible rotations.</p>
+<p>Trio is a 2-D puzzle whose state is specified by the colors of the marbles. There are 10 marbles of each of three colors; this implies that Trio has <tt>30!/(10!)^3 = 5.6*10^12</tt> possible positions. At each step, there are eight possible rotations, four discs, clockwise or counter-clockwise.</p>
+<h4>Scramble<a name="99075c53-97fe-4397-a096-3baedc01f129"></a></h4><p>A "scramble" is an integer vector with elements between -4 and +4 that specify moves or rotations. Move 0 initializes the model. Move <tt>d</tt> with <tt>d</tt> equal to 1, 2, or 3 rotates all the marbles in the <tt>d</tt>-th channel counter-clockwise for one-tenth of a full rotation. Move <tt>d</tt> with <tt>d</tt> equal to -1, -2, or -3 is the corresponding clockwise rotation. Moves -4 and 4 turn the central disc clockwise or counter-clockwise for one-third of a full rotation. This rotates some, but not all, of the marbles and mixes the colors.</p>
+<p>Here is a scramble of length 29 that provides our example.</p>
+<p>D = [ 4 1 3 1 1 -2 3 1 4 4 2 4 4 -3 -3 -2 -3 -3 2 1 4 -1 3 -4 2]</p>
+<p>And here is the scrambled result.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/trio_scrambled.gif" vspace="5" /> </p>
+<h4>Animation<a name="a45994ba-ec9b-49ab-b897-d0f79de81dcd"></a></h4><p>This animated gif shows the scrambling process one move at a time. The animation does not repeat automatically, so to start it over again, refresh your browser. If it still doesn't move, find another browser.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/trio_scramble.gif" vspace="5" /> </p>
+<h4>Unscramble<a name="ff195cfa-9e7f-4693-9c9e-5109eebc19c4"></a></h4><p>Reverse the scramble by running it backwards, changing the sign of each move. This will return the scrambled position to the initial position. I call this "unscramble"; it solves the scrambled position by a "follow the breadcrumbs" algorithm.</p>
+<p>Both animations take a long time to run -- about 80 seconds with my browser.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/trio_unscramble.gif" vspace="5" /> </p>
+<h4>Solutions<a name="87972e4e-c85c-4982-8459-add195223548"></a></h4><p>I don't have any idea about how to actually solve a given position without using knowledge of how it was generated, and I don't have any idea about how to quantify the difficulty of finding a solution. This is in sharp contrast to Rubik's Cube where there are measures of difficulty and algorithms for finding optimum solutions.</p>
+<h4>Software<a name="2e58ba8b-073a-402d-8259-2f095e0e72d2"></a></h4><p>The program available at <a href="https://blogs.mathworks.com/cleve/files/trioo.m">this link</a> is interactive. Click or alt-click in any one of the four discs to make a move in that disc.</p>
+<h4>Thanks<a name="0c756fc0-bf5b-4ccc-8d56-8eab84048dee"></a></h4><p>Thanks to Steve Eddins and Tom Lane for help with this post.</p>
+<!--
+ function grabCode_233d0111a3a04a7896bd6aac6263df7c() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='233d0111a3a04a7896bd6aac6263df7c ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 233d0111a3a04a7896bd6aac6263df7c';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2022 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2022b<br /></p>
+</div>
+<!--
+233d0111a3a04a7896bd6aac6263df7c ##### SOURCE BEGIN #####
+%% Trio, A Wooden Puzzle from the Czech Republic
+% "Clever Toys" is a puzzle company in the Czech Republic.
+% <http://www.clevertoys.cz/index_eng.php?page=eng
+% Their Web site> describes five different hand-made, wooden puzzles
+% that are related mathematically to the Rubik's Cube.
+%% Puzzle
+% Here is the photo of the puzzle "Trio".
+%
+% <<trio_puzzle.png>>
+%
+
+%%
+% Here is an English translation of their description.
+%
+% <html>
+% <p style="margin-left:3ex;">
+% The task of this 2D puzzle is to assemble all the ovals according
+% to their color into a basic assembly. By moving the balls in the
+% grooves and turning the center wheel, you can gradually get each
+% ball where you need it.
+% </p>
+
+% </html>
+%
+% I am not sure that Clever Toys is still in business.
+% They have not responded to my emails and I have not been able
+% to purchase an actual Trio puzzle. Of course, that is all the
+% motivation I need to make a MATLAB model.
+
+%% Model
+% Here is the initial configuration. There are three fixed outer, partial,
+% discs and one inner, full, disc. Each of the outer discs has a channel
+% containing 10 marbles. When the inner disc is positioned properly,
+% the marbles in a channel can be rotated. Rotating the inner disc
+% itself moves some, but not all, of the marbles, thereby scrambling
+% the colors.
+%
+% Like Rubik's Cube, the objective of the puzzle is to return to this
+% initial "solved" state.
+%
+% <<trio_initial.gif>>
+%
+
+%%
+% Mathematically, both Rubik's Cube and Trio are ultimately based upon
+% rotation matrices. Rubik's Cube is a 3-D puzzle whose state is
+% specified by the position and orientation of 27 cubelets;
+% this gives Rubik's Cube about |4.3*10^19| possible positions.
+% At each step, there are six faces and 12 possible rotations.
+%
+% Trio is a 2-D puzzle whose state is specified by the colors of the
+% marbles. There are 10 marbles of each of three colors;
+% this implies that Trio has |30!/(10!)^3 = 5.6*10^12| possible
+% positions. At each step, there are eight possible rotations,
+% four discs, clockwise or counter-clockwise.
+
+%% Scramble
+% A "scramble" is an integer vector with elements between -4 and +4 that
+% specify moves or rotations. Move 0 initializes the model. Move |d| with
+% |d| equal to 1, 2, or 3 rotates all the marbles in the |d|-th channel
+% counter-clockwise for one-tenth of a full rotation. Move |d| with
+% |d| equal to -1, -2, or -3 is the corresponding clockwise rotation.
+% Moves -4 and 4 turn the central disc clockwise or counter-clockwise
+% for one-third of a full rotation. This rotates some, but not all, of
+% the marbles and mixes the colors.
+
+%%
+% Here is a scramble of length 29 that provides our example.
+%
+% D = [ 4 1 3 1 1 -2 3 1 4 4 2 4 4 -3 -3 -2 -3 -3 2 1 4 -1 3 -4 2]
+%
+% And here is the scrambled result.
+%
+% <<trio_scrambled.gif>>
+
+%% Animation
+% This animated gif shows the scrambling process one move at a time.
+% The animation does not repeat automatically, so to start it over again,
+% refresh your browser.
+% If it still doesn't move, find another browser.
+%
+% <<trio_scramble.gif>>
+%
+
+%% Unscramble
+% Reverse the scramble by running it backwards, changing the sign of
+% each move. This will return the scrambled position to the initial
+% position. I call this "unscramble"; it solves the scrambled position
+% by a "follow the breadcrumbs" algorithm.
+%
+% Both animations take a long time to run REPLACE_WITH_DASH_DASH about 80 seconds
+% with my browser.
+%
+% <<trio_unscramble.gif>>
+%
+
+%% Solutions
+% I don't have any idea about how to actually solve a given position
+% without using knowledge of how it was generated, and I don't have
+% any idea about how to quantify the difficulty of finding a solution.
+% This is in sharp contrast to Rubik's Cube where there are measures
+% of difficulty and algorithms for finding optimum solutions.
+
+%% Software
+% The program available at
+% <https://blogs.mathworks.com/cleve/files/trioo.m this link>
+% is interactive. Click or alt-click in any one of the four discs
+% to make a move in that disc.
+
+%% Thanks
+% Thanks to Steve Eddins and Tom Lane for help with this post.
+##### SOURCE END ##### 233d0111a3a04a7896bd6aac6263df7c
+-->
+
+
+
+
+ Rubik’s Cube Superflips and God’s Number
+
+ 2022-09-06T02:00:24-06:00
+ https://hpc.social/2022/rubik-s-cube-superflips-and-god-s-number
+ <div class="content"><!--introduction--><div><ul><li>How hard is it to solve a Rubik's Cube?</li><li>When can you say that your Rubik's Cube is completely scrambled?</li><li>Why might the answer depend on where you went to school?</li><li>What interesting mathematical questions are involved?</li></ul></div>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#3c346c42-143c-4ddf-aa1d-d75e75c29b38">Metrics</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#a32fd551-4332-475a-a222-185f9d2ae2d0">God's number</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#eece078d-6a7b-423f-9218-5476dc32fcc1">Superflip</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#e237f0a5-b64d-4df1-a432-d475f0d68ae5">Q20</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#707dbec1-844c-46fe-9ea1-722ae2c4685c">Q26</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#88069ce9-4903-4668-a121-0ba2741eabaa">Compare</a></li></ul></div>
+<h4>Metrics<a name="3c346c42-143c-4ddf-aa1d-d75e75c29b38"></a></h4><p>The difficulty of solving any configuration of a Rubik's Cube is the smallest number of moves required to return to the intial configuration where each face is showing a single color.</p>
+<p>But what, exactly, is a move? The so-called <i>quarter-turn metric</i> says a move is turning any face by 90 degrees. The <i>half-turn metric</i> says turning any face by either 90 or 180 degrees is a single move. For example, using Singmaster notation and the quarter-turn metric, the sequence "L L", which turns the left face twice in the same direction, is two moves. But in the half-move metric, the sequence becomes "L2" and counts as a single move.</p>
+<p>Tomas Rokicki, who describes himself as <a href="https://tomas.rokicki.com">a programmer from Palo Alto</a>, provides some history at <a href="https://cube20.org/qtm">cube20.org</a>.</p>
+<p>
+<p style="margin-left: 3ex;">
+In the early days of cube mathematics, two camps emerged on how to
+ measure the difficulty of a position. West coast and Stanford
+ mathematicians, free thinkers all, tended to prefer the half-turn
+ metric, where any twist of any face, whether 90 degrees, 180 degrees,
+ or 270 degrees counted as a single move. The east coast crowd,
+ including MIT, tended to prefer the rigor of the quarter-turn metric,
+ where a half-turn counted as two moves, since of course it could be
+ accomplished by two consecutive quarter turns.
+</p>
+
+</p>
+<p>When I began development of a Rubik's Cube simulator, <tt>Qube</tt>, I was unaware of this history and, even though I am a devout West-coaster, I just counted quarter-turns. Now a toggle switch in <tt>Qube</tt> allows use of either metric.</p>
+<h4>God's number<a name="a32fd551-4332-475a-a222-185f9d2ae2d0"></a></h4><p>Let <tt>Q</tt> denote a cube position,</p>
+<p>| <tt>Q</tt> | = minimum number of moves to solve <tt>Q</tt>,</p>
+<p><tt><b>Q</b></tt> = the set of all possible <tt>Q</tt>'s, and</p>
+<p><tt>G(<b>Q</b>)</tt> = maximum over <tt>Q</tt> in <b>Q</b> of | <tt>Q</tt> |.</p>
+<p><tt>G(<b>Q</b>)</tt> is known as "God's number". <b>Q</b> contains over <tt>4.3*10^19</tt> positions, so computing <tt>G(<b>Q</b>)</tt> is a formidable optimization problem. The definition of God's number does not require the optimal solution itself, only the number of moves.</p>
+<h4>Superflip<a name="eece078d-6a7b-423f-9218-5476dc32fcc1"></a></h4><p>The <i>superflip</i> of Rubik's cube is a configuration where the 8 corners, the 6 face centers, and the cube center show the initial colors, but the 12 edge cubelets have the colors reversed. In 1995, Michael Reid proved that solution of the superflip requires 20 half-turn metric moves. In 2010, Tomas Rokicki and colleagues, using hundreds of computers at Google, carried out a massive computation to prove that no other configuration took more than 20 moves, <a href="https://cube20.org/qtm">cube20.org</a>. This established that God's number for the half-turn metric is</p>
+<p><tt>G(<b>Q</b>)</tt> = 20</p>
+<h4>Q20<a name="e237f0a5-b64d-4df1-a432-d475f0d68ae5"></a></h4><p>I use <tt>Q20</tt> to denote the superflip. Our first animation generates the superflip with 20 moves. A few rotations at the beginning and at the end are shown in more detail so that we can see the rotation matrices involved. A higher resolution video clip is available at this link: <a href="https://blogs.mathworks.com/cleve/files/Q20.mp4">Q20.mp4</a></p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Q20.gif" vspace="5" /> </p>
+<p>The second animation shows a solution of <tt>Q20</tt> in 20 moves obtained by reversing and complementing the generating moves. Reid's proof shows that any other solution requires at least 20 moves. The high resolution clip is: <a href="https://blogs.mathworks.com/cleve/files/Q20solve.mp4">Q20solve.mp4</a></p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Q20solve.gif" vspace="5" /> </p>
+<p>There are several other configurations that require 20 moves. Any configuration with <tt>G(Q) = 20</tt> can be regarded as completely shuffled in the half-turn metric.</p>
+<h4>Q26<a name="707dbec1-844c-46fe-9ea1-722ae2c4685c"></a></h4><p>For the quarter-turn metric, if you combine superflip and a configuration known as <i>fourspot</i> you have <tt>Q26</tt> . Only 8 corners and two face enters are correct. The edges, four face centers, and the cube center are all reversed. When 180 degree turns are counted as two 90 degree turns, this configuration is generated by 26 moves and solved by reversing and complementing the 26 moves. The high resolution clip is: <a href="https://blogs.mathworks.com/cleve/files/Q26.mp4">Q26.mp4</a></p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Q26.gif" vspace="5" /> </p>
+<p>In 2014, a massive computation at the Ohio Supercomputer Center by Rokicki and Morley Davidson proved that only <tt>Q26</tt> (and its two rotations) required 26 quarter-turn moves All other configurations need fewer. <a href="https://cube20.org/qtm">cube20.org</a>. So, this established that God's number for the half-turn metric is</p>
+<p><tt>G(<b>Q</b>)</tt> = 26</p>
+<p>The high resolution clip is: <a href="https://blogs.mathworks.com/cleve/files/Q26solve.mp4">Q26solve.mp4</a></p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Q26solve.gif" vspace="5" /> </p>
+<h4>Compare<a name="88069ce9-4903-4668-a121-0ba2741eabaa"></a></h4><p>Let's compare <tt>Q20</tt> and <tt>Q26</tt> by alternating between the two.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/flipper03.gif" vspace="5" /> </p>
+<p>The type 3 corner pieces are the same in <tt>Q20</tt> and <tt>Q26</tt>, and are in the correct initial position.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/flipper33.gif" vspace="5" /> </p>
+<p>The type 2 edge pieces are also the same in <tt>Q20</tt> and <tt>Q26</tt>, but are reversed from their initial position.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/flipper22.gif" vspace="5" /> </p>
+<p>All the action is with cubelets of type 0 and type 1. In a real, physical Rubik's Cube, this is one solid piece that holds the Cube together.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/flipper01.gif" vspace="5" /> </p>
+<!--
+ function grabCode_552a77033bf74984addf11ae10f9bb2e() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='552a77033bf74984addf11ae10f9bb2e ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 552a77033bf74984addf11ae10f9bb2e';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2022 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2022b<br /></p>
+</div>
+<!--
+552a77033bf74984addf11ae10f9bb2e ##### SOURCE BEGIN #####
+%% Rubik's Cube Superflips and God's Number
+% * How hard is it to solve a Rubik's Cube?
+% * When can you say that your Rubik's Cube is completely scrambled?
+% * Why might the answer depend on where you went to school?
+% * What interesting mathematical questions are involved?
+
+%% Metrics
+% The difficulty of solving any configuration of a Rubik's Cube
+% is the smallest number of moves required to return to the intial
+% configuration where each face is showing a single color.
+%
+% But what, exactly, is a move? The so-called _quarter-turn metric_ says
+% a move is turning any face by 90 degrees. The _half-turn metric_ says
+% turning any face by either 90 or 180 degrees is a single move. For
+% example, using Singmaster notation and the quarter-turn metric, the
+% sequence "L L", which turns the left face twice in the same direction,
+% is two moves. But in the half-move metric, the sequence becomes "L2"
+% and counts as a single move.
+%
+% Tomas Rokicki, who describes himself as
+% <https://tomas.rokicki.com a programmer from Palo Alto>, provides
+% some history at <https://cube20.org/qtm cube20.org>.
+%
+% <html>
+% <p style="margin-left:3ex;">
+% In the early days of cube mathematics, two camps emerged on how to
+% measure the difficulty of a position. West coast and Stanford
+% mathematicians, free thinkers all, tended to prefer the half-turn
+% metric, where any twist of any face, whether 90 degrees, 180 degrees,
+% or 270 degrees counted as a single move. The east coast crowd,
+% including MIT, tended to prefer the rigor of the quarter-turn metric,
+% where a half-turn counted as two moves, since of course it could be
+% accomplished by two consecutive quarter turns.
+% </p>
+
+% </html>
+%
+% When I began development of a Rubik's Cube simulator, |Qube|,
+% I was unaware of this history and, even though I am a devout
+% West-coaster, I just counted quarter-turns. Now a toggle switch in
+% |Qube| allows use of either metric.
+
+%% God's number
+% Let |Q| denote a cube position,
+%
+% | |Q| | = minimum number of moves to solve |Q|,
+%
+% |*Q*| = the set of all possible |Q|'s, and
+%
+% |G(*Q*)| = maximum over |Q| in *Q* of | |Q| |.
+%
+% |G(*Q*)| is known as "God's number".
+% *Q* contains over |4.3*10^19| positions, so computing |G(*Q*)| is a
+% formidable optimization problem. The definition of God's number does
+% not require the optimal solution itself, only the number of moves.
+
+%% Superflip
+% The _superflip_ of Rubik's cube is a configuration where the 8 corners,
+% the 6 face centers, and the cube center show
+% the initial colors, but the 12 edge cubelets have the colors reversed.
+% In 1995, Michael Reid proved that solution of the superflip requires
+% 20 half-turn metric moves. In 2010, Tomas Rokicki and colleagues,
+% using hundreds of computers at Google, carried out a massive computation
+% to prove that no other configuration took more than 20 moves,
+% <https://cube20.org/qtm cube20.org>.
+% This established that God's number for the half-turn metric is
+%
+% |G(*Q*)| = 20
+%
+
+%% Q20
+% I use |Q20| to denote the superflip.
+% Our first animation generates the superflip with 20 moves.
+% A few rotations at the beginning and at the end are shown in more
+% detail so that we can see the rotation matrices involved.
+% A higher resolution video clip is available at this link:
+% <https://blogs.mathworks.com/cleve/files/Q20.mp4 Q20.mp4>
+%
+% <<Q20.gif>>
+%
+
+%%
+% The second animation shows a solution of |Q20| in 20 moves obtained
+% by reversing and complementing the generating moves.
+% Reid's proof shows that any other solution requires at least 20 moves.
+% The high resolution clip is:
+% <https://blogs.mathworks.com/cleve/files/Q20solve.mp4 Q20solve.mp4>
+%
+% <<Q20solve.gif>>
+%
+% There are several other configurations that require 20 moves.
+% Any configuration with |G(Q) = 20| can be regarded as completely
+% shuffled in the half-turn metric.
+
+%% Q26
+% For the quarter-turn metric,
+% if you combine superflip and a configuration known as _fourspot_
+% you have |Q26| .
+% Only 8 corners and two face enters are correct.
+% The edges, four face centers, and the cube center are all reversed.
+% When 180 degree turns are counted as two 90 degree turns,
+% this configuration is generated by 26 moves and solved by reversing
+% and complementing the 26 moves.
+% The high resolution clip is:
+% <https://blogs.mathworks.com/cleve/files/Q26.mp4 Q26.mp4>
+%
+% <<Q26.gif>>
+%
+% In 2014, a massive computation at the Ohio Supercomputer Center
+% by Rokicki and Morley Davidson proved that only |Q26| (and its two
+% rotations) required 26 quarter-turn moves All other configurations
+% need fewer.
+% <https://cube20.org/qtm cube20.org>.
+% So, this established that God's number for the half-turn metric is
+%
+% |G(*Q*)| = 26
+%
+% The high resolution clip is:
+% <https://blogs.mathworks.com/cleve/files/Q26solve.mp4 Q26solve.mp4>
+%
+% <<Q26solve.gif>>
+%
+
+%% Compare
+% Let's compare |Q20| and |Q26| by alternating between the two.
+%
+% <<flipper03.gif>>
+%
+
+%%
+% The type 3 corner pieces are the same in |Q20| and |Q26|,
+% and are in the correct initial position.
+%
+% <<flipper33.gif>>
+%
+
+%%
+% The type 2 edge pieces are also the same in |Q20| and |Q26|,
+% but are reversed from their initial position.
+%
+% <<flipper22.gif>>
+%
+
+%%
+% All the action is with cubelets of type 0 and type 1.
+% In a real, physical Rubik's Cube, this is one solid piece that holds
+% the Cube together.
+%
+% <<flipper01.gif>>
+%
+%
+##### SOURCE END ##### 552a77033bf74984addf11ae10f9bb2e
+-->
+
+
+
+
+ Polygons, Polyshapes and Puzzles
+
+ 2022-08-21T15:42:36-06:00
+ https://hpc.social/2022/polygons-polyshapes-and-puzzles
+ <div class="content"><!--introduction--><p>Until recently, I knew nothing about the <tt>polyshape</tt> object in MATLAB. Now I can use polyshape to simulate an extraordinary puzzle.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#b44ef23f-8ee4-4710-970e-758273aef673">Puzzles</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#af839423-9061-445a-abcc-33e483845857">Not a T</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#fbfbf351-698a-410b-9cba-7272f394fe65">A slice of cheese</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#55c27f57-400d-4f4c-8849-298407ab936f">My first solution</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#87aa86ac-b133-4c46-abed-79b9b9669023">Is this solution correct?</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#07004175-0ad2-4431-9504-3d9d8c33a86c">Spoiler alert !</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#bbdd0ff0-9265-4089-9325-4929faa2d325">My second solution</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#30e29a25-e0f0-449b-b09c-4ff8ee26a6b8">A round peg in a square hole</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#19fcdc7d-f204-47d7-9e55-221680530003">Theta</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#4933cc60-9813-49dd-8f8c-d822d7b9b2d2">Polyshapes</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#1dcd1993-0fec-49da-87a9-4b75d997227f">The solution</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#ed22add4-a328-41ed-9696-c5cebc945091">Software</a></li></ul></div>
+<h4>Puzzles<a name="b44ef23f-8ee4-4710-970e-758273aef673"></a></h4><p>The Web site <a href="https://www.artofplay.com">Art of Play</a>, from some folks in San Diego, has well over two-hundred puzzles. Recently, one of their most popular puzzles, <a href="https://www.artofplay.com/collections/packing-puzzles/products/mighty-cheese-travel-puzzle">Mighty Cheese</a>, caught my attention. The idea is to move the slices of plastic cheese around within the frame in order to create a hole large enough to hold the little plastic mouse. However, when I last checked, Mighty Cheese was sold out. Not wanting to be dissuaded by the unavailability of the puzzle itself, and not knowing the solution, I set out to build a simulator.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/July_22_2022_small.png" vspace="5" /> </p>
+<h4>Not a T<a name="af839423-9061-445a-abcc-33e483845857"></a></h4><p>I expected Mighty Cheese to be something like the <a href="https://www.mathworks.com/company/newsletters/articles/introducing-cleves-laboratory.html">T-puzzle</a> that I enjoyed several years ago. But, unlike the T, the geometry of cheese cannot be modelled by simple rectangular patches. I needed help. Steve Eddins answered my plea and told me about MATLAB's "polyshapes". That led to this blog post.</p>
+<h4>A slice of cheese<a name="fbfbf351-698a-410b-9cba-7272f394fe65"></a></h4><p>A "selfie" of a cheese slice provides an example of a <tt>polyshape</tt>. It has curved boundaries and a hole. The MATLAB documentation for <a href="https://www.mathworks.com/help/matlab/ref/polyshape.html"><tt>polyshape</tt></a> says this a <i>polygon</i>. In my mathematical world, <i>polygons</i> can't have curved boundaries or holes. But, I guess that I am being pedantic.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/polyshape.png" vspace="5" /> </p>
+<p>I began with this photo of the Mighty Cheese puzzle.</p>
+<pre class="language-matlab">puzzle = imread(<span class="string">'Cheese_puzzle.png'</span>);
+</pre><p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/puzzle.gif" vspace="5" /> </p>
+<p>Two lines of code and the <tt>L*a*b</tt> color model find the regions in <tt>photo</tt> that look like cheese.</p>
+<pre class="language-matlab">[L,a,b] = imsplit(rgb2lab(puzzle));
+mask = a > 30;
+spy(mask)
+</pre><p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/mask.gif" vspace="5" /> </p>
+<p>Steve provided a function that turns <tt>mask</tt> into a <tt>polyshape</tt> object.</p>
+<pre class="language-matlab">slice = my_polyshapes(mask);
+</pre><p>An overloaded <tt>plot</tt> function then generates the selfie from <tt>slice</tt>.</p>
+<pre class="language-matlab">sliceplot = plot(slice, <span class="keyword">...</span>
+ <span class="string">'facecolor'</span>,cheese_yellow, <span class="keyword">...</span>
+ <span class="string">'facealpha'</span>,1);
+</pre><h4>My first solution<a name="55c27f57-400d-4f4c-8849-298407ab936f"></a></h4><p>I didn't use AI or simulated annealing or any other modern technique to search for a solution. I just poked around while I was learning about polyshapes and programming my simulator. It was just me and a <i>real</i> mouse. No, not a <i>real real</i> mouse. You know the kind I mean.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Cheese.gif" vspace="5" /> </p>
+<h4>Is this solution correct?<a name="87aa86ac-b133-4c46-abed-79b9b9669023"></a></h4><p>I almost made a blog post claiming this is the solution the designers of Mighty Cheese must have had in mind. But I wasn't sure. My solution made use of the white space around the outside edges of the slices. How wide are those gaps? I didn't yet have a real physical puzzle to measure tolerances.</p>
+<h4>Spoiler alert !<a name="07004175-0ad2-4431-9504-3d9d8c33a86c"></a></h4><p>I am sure glad now that I didn't post that "solution". It wasn't correct, and it wasn't pretty.</p>
+<p>This puzzle is not as easy as it looks. In fact, the solution is very hard to find and is very elegant. If you want to try to solve it yourself, stop reading this post, bookmark this spot, and come back later.</p>
+<h4>My second solution<a name="bbdd0ff0-9265-4089-9325-4929faa2d325"></a></h4><p>As I should have known, this puzzle is no secret to the Internet It is available for about $10 at many places and YouTube offers several solutions. But I'm glad that I didn't see any of them until a few weeks ago.</p>
+<p>When I made more careful measurements on "Cheese_puzzle.png" and had a more accurate model to simulate, it became clear that my precious first solution just wouldn't fit.</p>
+<h4>A round peg in a square hole<a name="30e29a25-e0f0-449b-b09c-4ff8ee26a6b8"></a></h4><p>Nobody said that the mouse had to fit neatly into a circular hole with just the right diameter. Once you realize that you might be looking for a noncircular hole, you are on the way to finding the solution.</p>
+<h4>Theta<a name="19fcdc7d-f204-47d7-9e55-221680530003"></a></h4><p>The key to the puzzle's geometry is the purple axes in this picture. They cross at right angles at a point in the center hole at the tip of the protruding slice. The angle between the purple axes and the orange vertical/horizontal axes can be measured accurately on the photo and everything else follows. The angle is</p>
+<pre class="language-matlab">theta = atand((y(b)-y(a))/(b-a)) = 11.62 degrees
+</pre><p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Mighty_Cheese_theta.gif" vspace="5" /> </p>
+<h4>Polyshapes<a name="4933cc60-9813-49dd-8f8c-d822d7b9b2d2"></a></h4><p>The mask that I was using for my first solution got me started with polyshapes, but I eventually abandoned it. It is easy to make a polyshape directly from a list of points around the boundary, like this.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Mighty_Cheese_S3_dots.gif" vspace="5" /> </p>
+<h4>The solution<a name="1dcd1993-0fec-49da-87a9-4b75d997227f"></a></h4><p>The three holes in the original cheese slices do not appear to serve any purpose. So, I have moved them and given them an important role in this simulation. Combine the two triangular slices in the upper left into a single slice. Rotate each of the resulting four slices by an angle of 180-theta = 168.38 degrees about its center. The four right-angled corners from the central hole go to the corners of the puzzle while the outer corners form a central square just large enough to hold the mouse.</p>
+<p>That is really elegant.</p>
+<p>Where did this puzzle originate? What mathematics was involved in its design?</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/MCsolution.gif" vspace="5" /> </p>
+<h4>Software<a name="ed22add4-a328-41ed-9696-c5cebc945091"></a></h4><p>My code is here: <a href="https://blogs.mathworks.com/cleve/files/Mighty_Polyshape.m">Mighty_Polyshape.m</a>.</p>
+<!--
+ function grabCode_2f68df87f4004e7ea2832e4310206744() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='2f68df87f4004e7ea2832e4310206744 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 2f68df87f4004e7ea2832e4310206744';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2022 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2022a<br /></p>
+</div>
+<!--
+2f68df87f4004e7ea2832e4310206744 ##### SOURCE BEGIN #####
+%% Polygons, Polyshapes and Puzzles
+% Until recently, I knew nothing about the |polyshape| object in MATLAB.
+% Now I can use polyshape to simulate an extraordinary puzzle.
+
+%% Puzzles
+% The Web site <https://www.artofplay.com Art of Play>, from some folks in
+% San Diego, has well over two-hundred puzzles. Recently, one of
+% their most popular puzzles,
+% <https://www.artofplay.com/collections/packing-puzzles/products/mighty-cheese-travel-puzzle
+% Mighty Cheese>, caught my attention.
+% The idea is to move the slices of plastic cheese around within the
+% frame in order to create a hole large enough to hold the little
+% plastic mouse. However, when I last checked, Mighty Cheese was
+% sold out.
+% Not wanting to be dissuaded by the unavailability of the puzzle itself,
+% and not knowing the solution, I set out to build a simulator.
+%
+% <<July_22_2022_small.png>>
+%
+
+%% Not a T
+% I expected Mighty Cheese to be something like the
+% <https://www.mathworks.com/company/newsletters/articles/introducing-cleves-laboratory.html
+% T-puzzle> that I enjoyed several years ago.
+% But, unlike the T, the geometry of cheese cannot be modelled by simple
+% rectangular patches. I needed help. Steve Eddins answered my plea and
+% told me about MATLAB's "polyshapes". That led to this blog post.
+
+%% A slice of cheese
+% A "selfie" of a cheese slice provides an example of a |polyshape|.
+% It has curved boundaries and a hole. The MATLAB documentation for
+% <https://www.mathworks.com/help/matlab/ref/polyshape.html
+% |polyshape|> says this a _polygon_.
+% In my mathematical world, _polygons_ can't have curved boundaries
+% or holes. But, I guess that I am being pedantic.
+%
+% <<polyshape.png>>
+
+%%
+% I began with this photo of the Mighty Cheese puzzle.
+%
+% puzzle = imread('Cheese_puzzle.png');
+%
+% <<puzzle.gif>>
+%
+% Two lines of code and the |L*a*b| color model find the regions
+% in |photo| that look like cheese.
+%
+% [L,a,b] = imsplit(rgb2lab(puzzle));
+% mask = a > 30;
+% spy(mask)
+%
+% <<mask.gif>>
+%
+% Steve provided a function that turns |mask| into a |polyshape|
+% object.
+%
+% slice = my_polyshapes(mask);
+%
+% An overloaded |plot| function then generates the selfie from |slice|.
+%
+% sliceplot = plot(slice, ...
+% 'facecolor',cheese_yellow, ...
+% 'facealpha',1);
+
+%% My first solution
+% I didn't use AI or simulated annealing or any other modern technique
+% to search for a solution. I just poked around while I was learning
+% about polyshapes and programming my simulator. It was just me and
+% a _real_ mouse. No, not a _real real_ mouse. You know the kind I mean.
+%
+% <<Cheese.gif>>
+
+%% Is this solution correct?
+% I almost made a blog post claiming this is the solution the designers of
+% Mighty Cheese must have had in mind. But I wasn't sure.
+% My solution made use of the white space around the outside edges of the
+% slices. How wide are those gaps? I didn't yet have a real physical
+% puzzle to measure tolerances.
+
+%% Spoiler alert !
+% I am sure glad now that I didn't post that "solution".
+% It wasn't correct, and it wasn't pretty.
+%
+% This puzzle is not as easy as it looks.
+% In fact, the solution is very hard to find and is very elegant.
+% If you want to try to solve it yourself, stop reading this post,
+% bookmark this spot, and come back later.
+
+%% My second solution
+% As I should have known, this puzzle is no secret to the Internet
+% It is available for about $10 at many places and
+% YouTube offers several solutions. But I'm glad that I didn't see any
+% of them until a few weeks ago.
+%
+% When I made more careful measurements on "Cheese_puzzle.png"
+% and had a more accurate model to simulate,
+% it became clear that my precious first solution just wouldn't fit.
+
+%% A round peg in a square hole
+% Nobody said that the mouse had to fit neatly into a circular hole
+% with just the right diameter. Once you realize that you might be
+% looking for a noncircular hole, you are on the way to finding the
+% solution.
+
+%% Theta
+% The key to the puzzle's geometry is the purple axes in this picture.
+% They cross at right angles at a point in the center hole at the tip
+% of the protruding slice. The angle between the purple axes and the
+% orange vertical/horizontal axes can be measured accurately on the
+% photo and everything else follows. The angle is
+%
+% theta = atand((y(b)-y(a))/(b-a)) = 11.62 degrees
+%
+% <<Mighty_Cheese_theta.gif>>
+
+%% Polyshapes
+% The mask that I was using for my first solution got me started with
+% polyshapes, but I eventually abandoned it. It is easy to make a
+% polyshape directly from a list of points around the boundary, like this.
+%
+% <<Mighty_Cheese_S3_dots.gif>>
+
+%% The solution
+% The three holes in the original cheese slices do not appear
+% to serve any purpose. So, I have moved them and given them an
+% important role in this simulation.
+% Combine the two triangular slices in the upper left into a single slice.
+% Rotate each of the resulting four slices by an
+% angle of 180-theta = 168.38 degrees about its center. The four
+% right-angled corners from the central hole go to the corners of the
+% puzzle while the outer corners form a central square just large enough
+% to hold the mouse.
+%
+% That is really elegant.
+%
+% Where did this puzzle originate? What mathematics was involved in
+% its design?
+%
+% <<MCsolution.gif>>
+
+%% Software
+% My code is here:
+% <https://blogs.mathworks.com/cleve/files/Mighty_Polyshape.m
+% Mighty_Polyshape.m>.
+##### SOURCE END ##### 2f68df87f4004e7ea2832e4310206744
+-->
+
+
+
+
+ An Interesting, and Perhaps New, Matrix
+
+ 2022-07-21T04:38:23-06:00
+ https://hpc.social/2022/an-interesting-and-perhaps-new-matrix
+ <div class="content"><!--introduction--><p>I do not recall having seen this matrix before, but I will not be surprised to learn that somebody else already knows all about it, especially if that person's name is Nick.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#17afe407-67a2-462b-a10b-df348fccb837"><tt>Q</tt></a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#044996c2-78b8-4a23-a809-6ed8ab3e3607"><tt>D</tt></a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#eca1bb02-1ba1-4bbf-9ed0-39c244e018eb">O.E.I.S.</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#b7778074-8d3f-46ad-858b-13f27d2f99bd"><tt>R</tt></a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#1e78f08f-c39d-4810-93bb-b0428456710c">Condition</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#c60c371e-4378-4499-8242-376b1b37da8c">Extra Credit</a></li></ul></div>
+<h4><tt>Q</tt><a name="17afe407-67a2-462b-a10b-df348fccb837"></a></h4><p>I've been investigating the matrices generated by this elegant one-liner.</p>
+<pre class="codeinput"> Q = @(n) (-n:n).^2 + (-n:n)'.^2;
+</pre><p>The <tt>Q</tt> is for "quadratic".</p>
+<p>The middle column contains the squares of the integers from <tt>-n</tt> to <tt>n</tt>. So does the middle row. The apostrophe summons singleton expansion. The resulting matrix has order <tt>2*n+1</tt>. Here is <tt>Q(5)</tt>.</p>
+<pre class="codeinput"> Q5 = Q(5)
+</pre><pre class="codeoutput">
+Q5 =
+
+ 50 41 34 29 26 25 26 29 34 41 50
+ 41 32 25 20 17 16 17 20 25 32 41
+ 34 25 18 13 10 9 10 13 18 25 34
+ 29 20 13 8 5 4 5 8 13 20 29
+ 26 17 10 5 2 1 2 5 10 17 26
+ 25 16 9 4 1 0 1 4 9 16 25
+ 26 17 10 5 2 1 2 5 10 17 26
+ 29 20 13 8 5 4 5 8 13 20 29
+ 34 25 18 13 10 9 10 13 18 25 34
+ 41 32 25 20 17 16 17 20 25 32 41
+ 50 41 34 29 26 25 26 29 34 41 50
+
+</pre><p>I like the contour plot.</p>
+<pre class="codeinput"> contourf(Q(100))
+ axis <span class="string">square</span>
+ colorbar
+ title(<span class="string">'Q(100)'</span>)
+</pre><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/disc_blog_01.png" vspace="5" /> <h4><tt>D</tt><a name="044996c2-78b8-4a23-a809-6ed8ab3e3607"></a></h4><p>For another blog post under development, I need a logical mask that carves a circular region out of graphic. This disc does the job.</p>
+<pre class="codeinput"> D = @(n) Q(n) <= n^2;
+</pre><p>Here is my carver.</p>
+<pre class="codeinput"> spy(D(100))
+ title(<span class="string">'D(100)'</span>)
+</pre><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/disc_blog_02.png" vspace="5" /> <p>Did you notice the digits in the count of nonzeros in <tt>D(100)</tt>? It happens whenever <tt>n</tt> is a power of 10.</p>
+<pre class="codeinput"> fprintf(<span class="string">'%15s %12s\n'</span>,<span class="string">'n'</span>,<span class="string">'nnz(D(n))'</span>)
+ <span class="keyword">for</span> n = 10.^(0:4)
+ fprintf(<span class="string">'%15d %12d\n'</span>,n, nnz(D(n)))
+ <span class="keyword">end</span>
+</pre><pre class="codeoutput"> n nnz(D(n))
+ 1 5
+ 10 317
+ 100 31417
+ 1000 3141549
+ 10000 314159053
+</pre><h4>O.E.I.S.<a name="eca1bb02-1ba1-4bbf-9ed0-39c244e018eb"></a></h4><p>A classic problem, described in the <a href="https://oeis.org/A000328">Online Encyclopedia of Integer Sequences</a>, asks how many points with integer coordinates lie within a disc of increasing radius. Our nonzero count provides the answer.</p>
+<pre class="codeinput"> fprintf(<span class="string">'%15s %8s\n'</span>,<span class="string">'n'</span>,<span class="string">'a(n)'</span>)
+ <span class="keyword">for</span> n = [1:15 99:101 499:501 999:1001]
+ <span class="keyword">if</span> mod(n,100) == 99
+ fprintf(<span class="string">'%15s %8s\n'</span>,<span class="string">'-'</span>,<span class="string">'-'</span>)
+ <span class="keyword">end</span>
+ a(n) = nnz(D(n));
+ fprintf(<span class="string">'%15d %8d\n'</span>,n,a(n))
+ <span class="keyword">end</span>
+</pre><pre class="codeoutput"> n a(n)
+ 1 5
+ 2 13
+ 3 29
+ 4 49
+ 5 81
+ 6 113
+ 7 149
+ 8 197
+ 9 253
+ 10 317
+ 11 377
+ 12 441
+ 13 529
+ 14 613
+ 15 709
+ - -
+ 99 30757
+ 100 31417
+ 101 32017
+ - -
+ 499 782197
+ 500 785349
+ 501 788509
+ - -
+ 999 3135157
+ 1000 3141549
+ 1001 3147833
+</pre><h4><tt>R</tt><a name="b7778074-8d3f-46ad-858b-13f27d2f99bd"></a></h4><p>Taking the reciprocals of the matrix entries, and reducing the range of the anonymous index, produces a matrix that behaves a bit like the Hilbert matrix, <tt>hilb(n)</tt>.</p>
+<pre class="codeinput"> R = @(n) 1./((1:n).^2 + (1:n)'.^2);
+</pre><p>Here are the 5-by-5's.</p>
+<pre class="codeinput"> format <span class="string">rat</span>
+ R5 = R(5)
+ H5 = hilb(5)
+</pre><pre class="codeoutput">
+R5 =
+
+ 1/2 1/5 1/10 1/17 1/26
+ 1/5 1/8 1/13 1/20 1/29
+ 1/10 1/13 1/18 1/25 1/34
+ 1/17 1/20 1/25 1/32 1/41
+ 1/26 1/29 1/34 1/41 1/50
+
+
+H5 =
+
+ 1 1/2 1/3 1/4 1/5
+ 1/2 1/3 1/4 1/5 1/6
+ 1/3 1/4 1/5 1/6 1/7
+ 1/4 1/5 1/6 1/7 1/8
+ 1/5 1/6 1/7 1/8 1/9
+
+</pre><h4>Condition<a name="1e78f08f-c39d-4810-93bb-b0428456710c"></a></h4><p>Going away from the diagonal, the elements of <tt>R(n)</tt> decay more rapidly than those of <tt>hilb(n)</tt>, so <tt>R(n)</tt> is better conditioned than <tt>hilb(n)</tt>.</p>
+<pre class="codeinput"> format <span class="string">short</span> <span class="string">e</span>
+ fprintf(<span class="string">'%15s %12s %12s\n'</span>,<span class="string">'n'</span>,<span class="string">'cond R'</span>,<span class="string">'cond H'</span>)
+ <span class="keyword">for</span> n = 1:12
+ fprintf(<span class="string">'%15d %12.2e %12.2e\n'</span>,n,cond(R(n)),cond(hilb(n)))
+ <span class="keyword">end</span>
+</pre><pre class="codeoutput"> n cond R cond H
+ 1 1.00e+00 1.00e+00
+ 2 1.53e+01 1.93e+01
+ 3 2.04e+02 5.24e+02
+ 4 2.59e+03 1.55e+04
+ 5 3.21e+04 4.77e+05
+ 6 3.89e+05 1.50e+07
+ 7 4.67e+06 4.75e+08
+ 8 5.54e+07 1.53e+10
+ 9 6.53e+08 4.93e+11
+ 10 7.65e+09 1.60e+13
+ 11 8.92e+10 5.22e+14
+ 12 1.04e+12 1.62e+16
+</pre><h4>Extra Credit<a name="c60c371e-4378-4499-8242-376b1b37da8c"></a></h4><p>What is the rank of <tt>Q(n)</tt>? Why? See <a href="https://epubs.siam.org/doi/epdf/10.1137/20M1358694">a paper in SIAM Review</a> by Strang and Moler.</p>
+<p>Why is the table of values for <tt>nnz(D(10^k))</tt> so short? How might you extend this table?</p>
+<p>Investigate <tt>R(n)</tt>. Is it positive definite? What are its eigenvalues? What is its inverse? What is the sign pattern of the elements of its inverse? For what values of <tt>n</tt> can you compute the inverse reliably using floating point arithmetic? How does all this compare with <tt>hilb(n)</tt> and <tt>invhilb(n)</tt> ?</p>
+<p>Comments in the Comments, or in email to me, are welcome.</p>
+<!--
+ function grabCode_4c513405f3644e5fbcae1bf70683cb1d() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='4c513405f3644e5fbcae1bf70683cb1d ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' 4c513405f3644e5fbcae1bf70683cb1d';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2022 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2022a<br /></p>
+</div>
+<!--
+4c513405f3644e5fbcae1bf70683cb1d ##### SOURCE BEGIN #####
+%% An Interesting, and Perhaps New, Matrix
+% I do not recall having seen this matrix before, but
+% I will not be surprised to learn that somebody else already knows
+% all about it, especially if that person's name is Nick.
+
+%% |Q|
+%
+% I've been investigating the matrices generated by this elegant one-liner.
+
+ Q = @(n) (-n:n).^2 + (-n:n)'.^2;
+
+%%
+% The |Q| is for "quadratic".
+%
+% The middle column contains the squares of the integers from |-n| to |n|.
+% So does the middle row. The apostrophe summons singleton expansion.
+% The resulting matrix has order |2*n+1|.
+% Here is |Q(5)|.
+
+ Q5 = Q(5)
+
+%%
+% I like the contour plot.
+
+ contourf(Q(100))
+ axis square
+ colorbar
+ title('Q(100)')
+
+%% |D|
+% For another blog post under development, I need a logical mask that
+% carves a circular region out of graphic. This disc does the job.
+
+ D = @(n) Q(n) <= n^2;
+
+%%
+% Here is my carver.
+
+ spy(D(100))
+ title('D(100)')
+
+%%
+% Did you notice the digits in the count of
+% nonzeros in |D(100)|?
+% It happens whenever |n| is a power of 10.
+
+ fprintf('%15s %12s\n','n','nnz(D(n))')
+ for n = 10.^(0:4)
+ fprintf('%15d %12d\n',n, nnz(D(n)))
+ end
+
+%% O.E.I.S.
+% A classic problem, described in the <https://oeis.org/A000328
+% Online Encyclopedia of Integer Sequences>, asks how many points with
+% integer coordinates lie within a disc of increasing radius.
+% Our nonzero count provides the answer.
+
+ fprintf('%15s %8s\n','n','a(n)')
+ for n = [1:15 99:101 499:501 999:1001]
+ if mod(n,100) == 99
+ fprintf('%15s %8s\n','-','-')
+ end
+ a(n) = nnz(D(n));
+ fprintf('%15d %8d\n',n,a(n))
+ end
+
+%% |R|
+% Taking the reciprocals of the matrix entries, and reducing the range of
+% the anonymous index, produces a matrix that behaves a bit like
+% the Hilbert matrix, |hilb(n)|.
+
+ R = @(n) 1./((1:n).^2 + (1:n)'.^2);
+
+%%
+% Here are the 5-by-5's.
+
+ format rat
+ R5 = R(5)
+ H5 = hilb(5)
+
+%% Condition
+% Going away from the diagonal,
+% the elements of |R(n)| decay more rapidly than those of |hilb(n)|,
+% so |R(n)| is better conditioned than |hilb(n)|.
+
+ format short e
+ fprintf('%15s %12s %12s\n','n','cond R','cond H')
+ for n = 1:12
+ fprintf('%15d %12.2e %12.2e\n',n,cond(R(n)),cond(hilb(n)))
+ end
+
+%% Extra Credit
+% What is the rank of |Q(n)|? Why? See
+% <https://epubs.siam.org/doi/epdf/10.1137/20M1358694
+% a paper in SIAM Review> by Strang and Moler.
+%
+% Why is the table of values for |nnz(D(10^k))| so short?
+% How might you extend this table?
+%
+% Investigate |R(n)|. Is it positive definite? What are its
+% eigenvalues? What is its inverse? What is the sign pattern of
+% the elements of its inverse? For what values of |n| can you
+% compute the inverse reliably using floating point arithmetic?
+% How does all this compare with |hilb(n)| and |invhilb(n)| ?
+%
+% Comments in the Comments, or in email to me, are welcome.
+
+##### SOURCE END ##### 4c513405f3644e5fbcae1bf70683cb1d
+-->
+
+
+
+
+ The Soma Cube, Again
+
+ 2022-06-10T09:07:52-06:00
+ https://hpc.social/2022/the-soma-cube-again
+ <div class="content"><!--introduction--><p>The Soma Cube brings back memories.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#d24e61ac-9d35-47eb-bca6-357702418141">Piet Hein</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#1d20680b-94e4-464d-84a6-7481a2c30e00">Bill McKeeman</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#3432acb9-d2ca-49a7-ac3a-b8327c5e7f9a">The original <tt>soma</tt> demo</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#412ef701-867b-45f9-9d16-b38a8bd051b1">A new <tt>Soma</tt> demo</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#0c997775-0706-4f98-855c-23e311f68cb0">Software</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#3b67595f-6619-4959-8d78-0417f13c73a3">Update</a></li></ul></div>
+<h4>Piet Hein<a name="d24e61ac-9d35-47eb-bca6-357702418141"></a></h4><p>Piet Hein (1905-1996) was an extraordinary Danish inventor, mathematician, poet and philosopher. He invented the <a href="https://en.wikipedia.org/wiki/Soma_cube">Soma Cube puzzle</a> in 1933. I wrote a blog post about Hein and some of his creations several years ago, <a href="https://blogs.mathworks.com/cleve/2016/03/28/piet-hein-super-ellipses-and-soma-cubes">Soma Cube 2016</a>.</p>
+<p>The Soma Cube puzzle has seven pieces. One of them is a V-shaped piece made from three cubelets. The other six pieces are L, T, Z, R, S, and Y with four cubelets each. That's a total of 27 cubelets, just enough to make a 3-by-3-by-3 cube. Sound familiar?</p>
+<h4>Bill McKeeman<a name="1d20680b-94e4-464d-84a6-7481a2c30e00"></a></h4><p>Bill McKeeman and I were buddies in grad school. He was a professor at U. C. Santa Cruz for a while, and then at the ill-fated Wang Institute of Graduate Studies in Tyngsborough, Mass. He worked for DEC in New Hampshire for a long time, taught compilers at Dartmouth, and even consulted for the MathWorks. As an exercise to learn MATLAB, he wrote the modern version of our <tt>why</tt> command.</p>
+<h4>The original <tt>soma</tt> demo<a name="3432acb9-d2ca-49a7-ac3a-b8327c5e7f9a"></a></h4><p>Bill and I became obsessed with the Soma cube after Martin Gardiner described the puzzle in his <i>Scientific American</i> column. You may not have noticed it before, but one of Bill's programs, <tt>soma</tt>, is in the MATLAB <tt>demos</tt> directory. Bill generated all of the 240 distinctly different puzzle solutions and stored them in a 240-by-27 matrix, <tt>demos/somasols</tt>. His program lets you page through the solutions.</p>
+<h4>A new <tt>Soma</tt> demo<a name="412ef701-867b-45f9-9d16-b38a8bd051b1"></a></h4><p>My new <tt>Soma</tt> code uses technology from <tt>Qube</tt>, the digital Rubik's Cube simulator, to plot the 240 solutions. Here are the seven Soma pieces, surrounding an animation stepping through every tenth solution.</p>
+<p>Do you recognize the colors?</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/Soma24.gif" vspace="5" /> </p>
+<h4>Software<a name="0c997775-0706-4f98-855c-23e311f68cb0"></a></h4><p><tt>Soma</tt> is available from <a href="https://blogs.mathworks.com/cleve/files/Soma.m">this link</a>. You already have <tt>somasols</tt>, but another copy is available from <a href="https://blogs.mathworks.com/cleve/files/somasols.m">this link</a>.</p>
+<h4>Update<a name="3b67595f-6619-4959-8d78-0417f13c73a3"></a></h4><p>I have combined my new display code and McKeeman's old program that finds all the solutions. The self-extracting archive is available at <a href="https://blogs.mathworks.com/cleve/files/Soma_osf.m"><https://blogs.mathworks.com/cleve/files/Soma_osf.m</a>></p>
+<!--
+ function grabCode_ba03413b3d6846149e5b9f9e92eb3300() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='ba03413b3d6846149e5b9f9e92eb3300 ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' ba03413b3d6846149e5b9f9e92eb3300';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2022 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2022b<br /></p>
+</div>
+<!--
+ba03413b3d6846149e5b9f9e92eb3300 ##### SOURCE BEGIN #####
+%% The Soma Cube, Again
+% The Soma Cube brings back memories.
+
+%% Piet Hein
+% Piet Hein (1905-1996) was an extraordinary Danish inventor,
+% mathematician, poet and philosopher. He invented the
+% <https://en.wikipedia.org/wiki/Soma_cube
+% Soma Cube puzzle> in 1933.
+% I wrote a blog post about Hein and some of his creations several years ago,
+% <https://blogs.mathworks.com/cleve/2016/03/28/piet-hein-super-ellipses-and-soma-cubes
+% Soma Cube 2016>.
+%%
+% The Soma Cube puzzle has seven pieces. One of them is a V-shaped piece
+% made from three cubelets. The other six pieces are L, T, Z, R, S, and Y
+% with four cubelets each. That's a total of 27 cubelets, just enough
+% to make a 3-by-3-by-3 cube. Sound familiar?
+
+%% Bill McKeeman
+% Bill McKeeman and I were buddies in grad school. He was a professor at
+% U. C. Santa Cruz for a while, and then at the ill-fated Wang Institute
+% of Graduate Studies in Tyngsborough, Mass. He worked for
+% DEC in New Hampshire for a long time, taught compilers at Dartmouth,
+% and even consulted for the MathWorks. As an exercise to learn MATLAB,
+% he wrote the modern version of our |why| command.
+
+%% The original |soma| demo
+% Bill and I became obsessed with the Soma cube after Martin Gardiner
+% described the puzzle in his _Scientific American_ column.
+% You may not have noticed it before, but one of Bill's programs,
+% |soma|, is in the MATLAB |demos| directory.
+% Bill generated all of the 240 distinctly different puzzle solutions
+% and stored them in a 240-by-27 matrix, |demos/somasols|.
+% His program lets you page through the solutions.
+
+%% A new |Soma| demo
+% My new |Soma| code uses technology from |Qube|,
+% the digital Rubik's Cube simulator, to plot the 240 solutions.
+% Here are the seven Soma pieces, surrounding an animation stepping
+% through every tenth solution.
+%
+% Do you recognize the colors?
+%
+% <<Soma24.gif>>
+%
+
+%% Software
+% |Soma| is available from
+% <https://blogs.mathworks.com/cleve/files/Soma.m
+% this link>.
+% You already have |somasols|, but another copy is available from
+% <https://blogs.mathworks.com/cleve/files/somasols.m
+% this link>.
+
+%% Update
+% I have combined my new display code and McKeeman's old program that
+% finds all the solutions. The self-extracting archive is available at
+% <https://blogs.mathworks.com/cleve/files/Soma_osf.m
+% https://blogs.mathworks.com/cleve/files/Soma_osf.m>
+
+##### SOURCE END ##### ba03413b3d6846149e5b9f9e92eb3300
+-->
+
+
+
+
+ Rotation Matrices
+
+ 2022-05-18T23:50:24-06:00
+ https://hpc.social/2022/rotation-matrices
+ <div class="content"><!--introduction--><p>The matrices in the following animations are at the heart of computer graphics. They describe objects moving in three-dimensional space and are essential to MATLAB's Handle Graphics, to Computer Added Design packages, to Computer Graphics Imagery in films, and to most popular video games. Many modern computers contain GPUs, <i>Graphic Processing Units</i>, which are optimized to compute the product of these matrices.</p>
+<!--/introduction--><h3>Contents</h3><div><ul><li><a href="https://feeds.feedburner.com/mathworks/moler#3a6da3e1-6503-4ec5-aab8-a13b4a419218">Rotations</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#c80c5877-8380-4b82-a0b8-3fb8fd146dcf"><tt>theta</tt></a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#2f2feaa8-2ff1-436c-ba43-62fbf44a95f4">Compass</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#75ba0607-fc08-40cf-b038-e2e9ddf4d2ba">Roll, Pitch, Yaw</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#819e8a6b-9508-4efb-a12a-1b7d57015db2">Propeller</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#ca750655-1342-4eda-bf54-d721058acc24">Cubelet</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#48892ff7-e295-4784-9282-e149dbd41697">Scramble</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#6f09e9ca-8a4e-4df4-a894-3ce2a082d8dc">Unscramble</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#19f99287-c2df-4589-a762-4410ffa64eb9">Exercises</a></li><li><a href="https://feeds.feedburner.com/mathworks/moler#fa106610-d1c0-4b93-9ea4-c3ee6136fb40">Software</a></li></ul></div>
+<h4>Rotations<a name="3a6da3e1-6503-4ec5-aab8-a13b4a419218"></a></h4><p>The <i>homogeneous coordinates</i> system used in today's computer graphics software and hardware makes it possible to describe rotations, translations and many other operations with 3-by-3 and 4-by-4 matrices. These matrices operate on vectors with the position of an object, <i>x</i>, <i>y</i> and <i>z</i> , in the first three components.</p>
+<p>Rotations about the coordinate axes are described by three matrices. Rotations about the <i>x</i> -axis are produced by $R_x$, which rotates <i>y</i> and <i>z</i>, while leaving <i>x</i> unchanged.</p>
+<p>$$ R_x(\theta) = \left( \begin{array}{rrr}
+ 1 & 0 & 0 \\
+ 0 & \cos{\theta} & -\sin{\theta} \\
+ 0 & \sin{\theta} & \cos{\theta}
+ \end{array} \right) $$</p>
+<p>Rotations about the <i>y</i> -axis are generated by</p>
+<p>$$ R_y(\theta) = \left( \begin{array}{rrr}
+ \cos{\theta} & 0 & -\sin{\theta} \\
+ 0 & 1 & 0 \\
+ \sin{\theta} & 0 & \cos{\theta}
+ \end{array} \right) $$</p>
+<p>And, rotations about <i>z</i> are provided by</p>
+<p>$$ R_z(\theta) = \left( \begin{array}{rrr}
+ \cos{\theta} & -\sin{\theta} & 0 \\
+ \sin{\theta} & \cos{\theta} & 0 \\
+ 0 & 0 & 1 \\
+ \end{array} \right) $$</p>
+<h4><tt>theta</tt><a name="c80c5877-8380-4b82-a0b8-3fb8fd146dcf"></a></h4><p>Rotation angles are specified in degrees. Our MATLAB programs use the degree-based trig functions <tt>cosd</tt> and <tt>sind</tt>. Here are graphs of $\cos\theta$ and $-\sin\theta$ , evaluated with the angle $\theta$ going from <tt>0</tt> to <tt>360</tt> degrees in <tt>10</tt>-degree steps.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/cos_sin.gif" vspace="5" /> </p>
+<h4>Compass<a name="2f2feaa8-2ff1-436c-ba43-62fbf44a95f4"></a></h4><p>Here is another look at the same data, <tt>cosd(theta)</tt> and <tt>-sind(theta)</tt> for <tt>theta = 0:10:360</tt>. The columns of the rotation matrix are the coordinates of the rotating dots. The blue dot starts at (0,1) and the orange dot starts at (1,0).</p>
+<p>If you drop the zeros from the values of <tt>theta</tt>, you are left with the integers from 1 to 36. This is the numbering in the international standard describing the compass direction of runways at airports. The initial position of our blue dot corresponds to runway 36 and the orange dot starts as runway 9.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/compass.gif" vspace="5" /> </p>
+<h4>Roll, Pitch, Yaw<a name="75ba0607-fc08-40cf-b038-e2e9ddf4d2ba"></a></h4><p><b>Note: Refresh your browser to synchronize these animations.</b></p>
+<p>For aircraft and space vehicles, rotation around the <tt>x</tt>-axis from nose to tail is known as <i>roll</i>.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/roll.gif" vspace="5" /> </p>
+<p>Rotation about the <tt>y</tt>-axis parallel to the wings is <i>pitch</i>.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/pitch.gif" vspace="5" /> </p>
+<p>And, rotation about the vertical <tt>z</tt>-axis is <i>yaw</i>.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/yaw.gif" vspace="5" /> </p>
+<h4>Propeller<a name="819e8a6b-9508-4efb-a12a-1b7d57015db2"></a></h4><p>Our model of the Piper PA-24 Comanche has 97 <i>patches</i>. One of them is the propeller. This animation of a rotating propeller is very similar to our earlier animation of the compass.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/propeller.gif" vspace="5" /> </p>
+<h4>Cubelet<a name="ca750655-1342-4eda-bf54-d721058acc24"></a></h4><p><tt>Qube</tt>, our digital Rubik's Cube simulator, uses 27 copies of a single <i>cubelet</i>. This animation of a rotating cubelet shows a quarter turn clockwise about <tt>x</tt>, followed by a quarter turn clockwise about <tt>y</tt> and then a quarter turn counterclockwise about <tt>z</tt>. If these three rotations are repeated four times, the cubelet returns to its initial orientation. In the process, we see the traditional Rubik's colors of all six faces -- white, green and orange opposite yellow, blue and red.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/cubelet.gif" vspace="5" /> </p>
+<h4>Scramble<a name="48892ff7-e295-4784-9282-e149dbd41697"></a></h4><p><b>Note: Refresh your browser to synchronize these animations.</b></p>
+<p>Rubick's Cube is all about rotations. Rotating the cubelets in any face of the puzzle, while leaving the rest of the puzzle fixed, is called a "move". Like any cube, Rubik's cube has six faces. Each move rotates one of the six faces in either a clockwise or counterclockwise direction. So, after <tt>n</tt> moves, the puzzle is in one of <tt>12^n</tt> possible states. The challenge is to return the cube to its original orientation.</p>
+<p>Here are six random rotations produced by <tt>scramble(6)</tt>. Because <tt>12^6</tt> is <tt>2,985,984</tt>, this is just one of almost three million six-move scrambles.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/scramble.gif" vspace="5" /> </p>
+<h4>Unscramble<a name="6f09e9ca-8a4e-4df4-a894-3ce2a082d8dc"></a></h4><p>One possible way to restore any starting condition is to retrace the moves that produced it. This is the "follow the breadcrumbs" algorithm. So, I call this <tt>unscramble</tt>, rather than <tt>solve</tt>.</p>
+<p><img alt="" hspace="5" src="http://blogs.mathworks.com/cleve/files/unscramble.gif" vspace="5" /> </p>
+<h4>Exercises<a name="19f99287-c2df-4589-a762-4410ffa64eb9"></a></h4><div><ul><li>1: Which rotation matrices and what values of <tt>theta</tt> are used in the animations?</li></ul></div>
+<div><ul><li>2 (not easy): When is <tt>unscamble</tt> a solution with the minimum number of moves?</li></ul></div>
+<h4>Software<a name="fa106610-d1c0-4b93-9ea4-c3ee6136fb40"></a></h4><p>The source code for <tt>Qube</tt> is available from this link: <a href="https://blogs.mathworks.com/cleve/files/Qube_May18_osf.m">Qube_May18_osf.m</a>. The <tt>osf</tt>, <i>one single file</i>, format is a self-extracting archive that expands into a directory of individual functions.</p>
+<!--
+ function grabCode_fac94086e84b4ca1b5df2dbc8d19f63c() {
+ // Remember the title so we can use it in the new page
+ title = document.title;
+
+ // Break up these strings so that their presence
+ // in the Javascript doesn't mess up the search for
+ // the MATLAB code.
+ t1='fac94086e84b4ca1b5df2dbc8d19f63c ' + '##### ' + 'SOURCE BEGIN' + ' #####';
+ t2='##### ' + 'SOURCE END' + ' #####' + ' fac94086e84b4ca1b5df2dbc8d19f63c';
+
+ b=document.getElementsByTagName('body')[0];
+ i1=b.innerHTML.indexOf(t1)+t1.length;
+ i2=b.innerHTML.indexOf(t2);
+
+ code_string = b.innerHTML.substring(i1, i2);
+ code_string = code_string.replace(/REPLACE_WITH_DASH_DASH/g,'--');
+
+ // Use /x3C/g instead of the less-than character to avoid errors
+ // in the XML parser.
+ // Use '\x26#60;' instead of '<' so that the XML parser
+ // doesn't go ahead and substitute the less-than character.
+ code_string = code_string.replace(/\x3C/g, '\x26#60;');
+
+ copyright = 'Copyright 2022 The MathWorks, Inc.';
+
+ w = window.open();
+ d = w.document;
+ d.write('<pre>\n');
+ d.write(code_string);
+
+ // Add copyright line at the bottom if specified.
+ if (copyright.length > 0) {
+ d.writeln('');
+ d.writeln('%%');
+ if (copyright.length > 0) {
+ d.writeln('% _' + copyright + '_');
+ }
+ }
+
+ d.write('</pre>\n');
+
+ d.title = title + ' (MATLAB code)';
+ d.close();
+ }
+ --><p style="text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;"><br /><a href=""><span style="font-size: x-small; font-style: italic;">Get
+ the MATLAB code <noscript>(requires JavaScript)</noscript></span></a><br /><br />
+ Published with MATLAB® R2022a<br /></p>
+</div>
+<!--
+fac94086e84b4ca1b5df2dbc8d19f63c ##### SOURCE BEGIN #####
+%% Rotation Matrices
+% The matrices in the following animations
+% are at the heart of computer graphics.
+% They describe objects moving in three-dimensional
+% space and are essential to MATLAB's Handle Graphics,
+% to Computer Added Design packages,
+% to Computer Graphics Imagery in films,
+% and to most popular video games.
+% Many modern computers
+% contain GPUs, _Graphic Processing Units_, which are
+% optimized to compute the product of these matrices.
+
+%% Rotations
+% The _homogeneous coordinates_ system used in today's
+% computer graphics software and hardware
+% makes it possible to describe rotations, translations
+% and many other operations with 3-by-3 and 4-by-4 matrices.
+% These matrices operate on vectors with the position of an object,
+% _x_, _y_ and _z_ , in the first three components.
+%
+% Rotations about the coordinate axes are described by three matrices.
+% Rotations about the _x_ -axis are produced by $R_x$, which
+% rotates _y_ and _z_, while leaving _x_ unchanged.
+%
+% $$ R_x(\theta) = \left( \begin{array}{rrr}
+% 1 & 0 & 0 \\
+% 0 & \cos{\theta} & -\sin{\theta} \\
+% 0 & \sin{\theta} & \cos{\theta}
+% \end{array} \right) $$
+%
+% Rotations about the _y_ -axis are generated by
+%
+% $$ R_y(\theta) = \left( \begin{array}{rrr}
+% \cos{\theta} & 0 & -\sin{\theta} \\
+% 0 & 1 & 0 \\
+% \sin{\theta} & 0 & \cos{\theta}
+% \end{array} \right) $$
+%
+% And, rotations about _z_ are provided by
+%
+% $$ R_z(\theta) = \left( \begin{array}{rrr}
+% \cos{\theta} & -\sin{\theta} & 0 \\
+% \sin{\theta} & \cos{\theta} & 0 \\
+% 0 & 0 & 1 \\
+% \end{array} \right) $$
+%
+
+%% |theta|
+% Rotation angles are specified in degrees. Our MATLAB programs
+% use the degree-based trig functions |cosd| and |sind|.
+% Here are graphs of $\cos\theta$ and $-\sin\theta$ , evaluated with
+% the angle $\theta$ going from |0| to |360| degrees
+% in |10|-degree steps.
+%
+% <<cos_sin.gif>>
+%
+
+%% Compass
+% Here is another look at the same data, |cosd(theta)| and
+% |-sind(theta)| for |theta = 0:10:360|.
+% The columns of the rotation matrix are the coordinates of
+% the rotating dots. The blue dot starts at (0,1) and the
+% orange dot starts at (1,0).
+%
+% If you drop the zeros from the values of |theta|, you are
+% left with the integers from 1 to 36. This is the numbering in the
+% international standard describing the compass direction of runways
+% at airports. The initial position of our blue dot corresponds to
+% runway 36 and the orange dot starts as runway 9.
+%
+% <<compass.gif>>
+%
+
+%% Roll, Pitch, Yaw
+% *Note: Refresh your browser to synchronize these animations.*
+%
+% For aircraft and space vehicles, rotation around
+% the |x|-axis from nose to tail is known as _roll_.
+%
+% <<roll.gif>>
+%
+% Rotation about the |y|-axis parallel to the wings is _pitch_.
+%
+% <<pitch.gif>>
+%
+% And, rotation about the vertical |z|-axis is _yaw_.
+%
+% <<yaw.gif>>
+%
+
+%% Propeller
+% Our model of the Piper PA-24 Comanche has 97 _patches_.
+% One of them is the propeller.
+% This animation of a rotating propeller is very similar to our
+% earlier animation of the compass.
+%
+% <<propeller.gif>>
+%
+
+%% Cubelet
+% |Qube|, our digital Rubik's Cube simulator, uses 27 copies
+% of a single _cubelet_. This animation of a rotating cubelet
+% shows a quarter turn clockwise about |x|, followed by a quarter
+% turn clockwise about |y| and then a quarter turn counterclockwise
+% about |z|. If these three rotations are repeated four times,
+% the cubelet returns to its initial orientation.
+% In the process, we see the traditional Rubik's colors of all
+% six faces REPLACE_WITH_DASH_DASH white, green and orange opposite yellow, blue and red.
+%
+% <<cubelet.gif>>
+
+%% Scramble
+% *Note: Refresh your browser to synchronize these animations.*
+%
+% Rubick's Cube is all about rotations. Rotating the cubelets in any
+% face of the puzzle, while leaving the rest of the puzzle fixed,
+% is called a "move". Like any cube, Rubik's cube has six faces.
+% Each move rotates one of the six faces in either a clockwise or
+% counterclockwise direction. So, after |n| moves, the puzzle is in one
+% of |12^n| possible states. The challenge is to return the cube
+% to its original orientation.
+%
+% Here are six random rotations produced by |scramble(6)|.
+% Because |12^6| is |2,985,984|,
+% this is just one of almost three million six-move scrambles.
+%
+% <<scramble.gif>>
+%
+
+%% Unscramble
+% One possible way to restore any starting condition is to retrace the
+% moves that produced it. This is the "follow the breadcrumbs" algorithm.
+% So, I call this |unscramble|, rather than |solve|.
+%
+% <<unscramble.gif>>
+%
+
+%% Exercises
+% * 1: Which rotation matrices and what values of |theta| are used
+% in the animations?
+%
+% * 2 (not easy): When is |unscamble| a solution with the
+% minimum number of moves?
+
+%% Software
+% The source code for |Qube| is available from this link:
+% <https://blogs.mathworks.com/cleve/files/Qube_May18_osf.m
+% Qube_May18_osf.m>.
+% The |osf|, _one single file_, format is a self-extracting archive
+% that expands into a directory of individual functions.
+
+
+##### SOURCE END ##### fac94086e84b4ca1b5df2dbc8d19f63c
+-->
+
+
+
+
+
diff --git a/feed.json b/feed.json
new file mode 100644
index 0000000..c28b1c4
--- /dev/null
+++ b/feed.json
@@ -0,0 +1,704 @@
+{
+ "version": "https://jsonfeed.org/version/1",
+ "title": "hpc.social - Aggregated Commercial Blog",
+ "home_page_url": "https://hpc.social/commercial-blog/",
+ "feed_url": "https://hpc.social/commercial-blog/feed.json",
+ "description": "Vendor and commercial posts in the hpc.social community",
+ "icon": "https://hpc.social/commercial-blog/assets/images/apple-touch-icon.png",
+ "favicon": "https://hpc.social/commercial-blog/assets/images/favicon.png",
+ "expired": false,
+
+ "author": {
+ "name": "hpc.social",
+ "url": null,
+ "avatar": null
+ },
+
+"items": [
+
+ {
+ "id": "https://hpc.social/commercial-blog/2024/m%C3%B6bius-mertens-and-redheffer/",
+ "title": "Möbius, Mertens and Redheffer",
+ "summary": null,
+ "content_text": "Recently, I have made a series of blog posts about Redheffer matrices and the Mertens conjecture. After each of the posts, readers and colleagues offered suggestions to speed up the calculations. Here is a summary of what I have learned.ContentsMöbius FunctionMertens FunctionRedheffer MatricesOEISTen MillionMertens ConjectureConjecture is FalseMatricesSparsityComputing Mertens#1#2#3#4#5PerformanceMöbius Function The function named after the mid-nineteenth century German mathematician August Möbius is fundamental to the study of prime numbers. The Möbius function maps the positive integers onto -1,0 and +1. mu(n) = 0 if n has a repeated prime factor, = (-1)^(number prime factors) if the factors of n are not repeatedHere is my code for the Möbius function. It relies on factor(n) which uses a sieve to find the prime factors of n. function mu = mobius(n) % mu = mobius(n) returns mu(1:n). mu = -eye(1,n); for k = 2:n f = factor(k); d = diff([1 f]); if any(d == 0) mu(k) = 0; else mu(k) = (-1)^length(f); end end endHere is a graph of mu(n) for n = 1:40. For example, mu(29:31) are all -1 because 29 and 31 are both prime and 30 has an odd number of prime factors, 2, 3 and 5. mu = moebius(40); plot(1:40,mu,'.-','linewidth',1.5,'markersize',16) axis([-242-1.51.5]) title('Möbius function') Mertens Function The Mertens function is named after the late-nineteenth century Polish mathematician Franz Mertens. The function, which we denote by M(n), is simply the partial sums of the Möbius function. The MATLAB code is very short. function M = mertens(n) % M = mertens(n) returns Mertens(1:n). mu = moebius(n); M = cumsum([1 mu(2:n)]); endHere is a graph of M(n) for n = 1:40. M = mertens(40); plot(1:40,M,'.-','linewidth',1.5,'markersize',16) axis([-242-4.51.5]) title('Mertens function') Redheffer Matrices The twentieth-century American mathematician Ray Redheffer, who was a professor at UCLA for 55 years, had a wide range of interests. He was the author of several popular textbooks, the inventor of the electronic game Nim and, with Ray and Charles Eames, the creator of a four-meter long poster Men of Modern Mathematics.The n-by-n Redheffer's matrix R(n) is a matrix of zeros and ones. For j > 1, the element R(k,j) equals one if j is a divisor of k. And importantly, for j = 1, the first column R(:,1) is all ones. function R = redheffer(n) k = 1:n; j = k'; R = (mod(k,j) == 0); R(:,1) = 1; endNick Higham put Redheffer's matrix in the MATLAB Gallery several years ago. Here is a spy plot of the 200-by-200. R = gallery('redheff',200); spy(R) title('Redheffer') OEISIn the Online Encyclopedia of Integer Sequences, the Mertens function is OEIS/A002321. One of the many cool features of the OEIS is \"listen\", which generates music driven by the sequences. Take a look -- and a listen -- to my 63 second movie about A002321.https://blogs.mathworks.com/cleve/files/mertens_plot.mp4Ten MillionHere are plots of M(1:n) with n ranging from 100 to 10 million. Each plot after the first also shows the range of the previous plot. I will discuss the red lines in the next section load mertens M tiledlayout(2,3) for n = 10.^(2:7) nexttile mertens_plot(M(1:n)) end Mertens ConjectureThe red lines above are plots of ±sqrt(n). They clearly bound M(n) for n up to 10 million. The Mertens Conjecture is that this holds for all n. |M(n)| < sqrt(n) for all n > 0The conjecture appears in a 1885 letter from Thomas Stieltjes to Charles Hermite and in a 1897 paper by Mertens.Wikipedia says It is a striking example of a mathematical conjecture proven false despite a large amount of computational evidence in its favor.Conjecture is FalseIn 1985, 100 years after the Stieltjes letter, Andrew Odlyzko and Herman te Riele proved that the conjecture is false. Their proof is indirect. They prove the existence of infinitely many n for which |M(n)|/sqrt(n) > 1.06But they do not know the value of any particular n. They informally estimate that such an n would be greater than 10^30 and probably much larger.MatricesLet's get back to the world of matrices. It is not obvious, but is true, that the determinants of Redheffer matrices are equal to the Mertens function. det(R(n)) = M(n)So, if I could have proved that |det(R(n))| < sqrt(n) for all n > 0I would have had a proof of the Riemann Hypothesis.It might appear that I am out of the clutches of number theory and safely back to matrix computation. But that illusion does not last for long.SparsityThe 0(n^3) memory required by the Redheffer matrix from the gallery runs out of steam quickly. We need to take advantage of sparsity. This function generates the sparse representation of a Redheffer matrix directly. function R = spredheffer(n) j = (1:n)'; k = ones(n,1); m = n; for i = 2:n t = [1 i:i:n]; p = length(t); j(m+(1:p)) = t; k(m+(1:p)) = i; m = m+p; end R = sparse(k,j,1,n,n); endComputing MertensHere are five methods for computing the Mertens function.#1The first simply takes the determinant of the Redheffer matrix in the gallery. M = det(gallery('redheff',n))#2The sparse Gaussian elimination function lu with one input and four sparse outputs is designed for solving sparse linear systems. Written primarily by Tim Davis and included in his UMFPACK package, the function uses an unsymmetric pattern multifrontal pivoting strategy to reduce fill-in while maintaining numerical stability. The determinant of the input matrix is the product of the four determinants of the output matrices. Two them are triangular and two are permutations, so it is easy, and quick, to compute their determinants. R = spredheffer(n); [L,U,P,Q] = lu(R) M = det(L)*det(U)*det(P)*det(Q);#3Pat Quillen realized that by interchanging the first and last columns, there would be little fill-in. We need only one determinant. R = spredheffer(n); R(:,[1 n]) = R(:,[n 1]); M = -det(R);#4A thoughtful reader of the blog submitted a suggestion based on the Schur complement. Suppose E is a block matrix, E = [A B C D]Schur's formula for the determinant of E is det(E) = det(D)*det(A - B*(D\\C))Apply this to R(n) with A the (1,1) entry, which is 1, and D the lower (n-1)-by-(n-1) submatrix, which is upper triangular with ones on the diagonal and determinant equal 1. This leads to method #4 which uses backslash with a sparse, unit, upper triangular matrix. There is a Redheffer matrix, but no determinant. S = spredheffer(n); e = ones(n-1,1); M = 1 - e'*(S(2:n,2:n)\\e);#5Once we have generated R(n) and computed M(n), how do we get R(n+1) and M(n+1)? After several iterations of this approach, I found myself without any matrices and only the original definitions of Möbius and Mertens. mu = mobius(n); M = cumsum([1 mu(2:n)]);PerformanceLet's summarize the five methods. The first four generate a single, isolated value of M(n). Method #5 generates M(n) for all n from 1 to any specified maximum. matrix function dets M #1 full gallery 1 1 #2 sparse lu 4 1 #3 sparse swap 1 1 #4 sparse \\ 0 1 #5 none factor 0 manyTime in seconds to compute M(n) on my Lenovo T14 laptop running Windows. n 2e4 2e5 2e6 2e7 #1 28.652 - - - #2 0.344 21.77 - - #3 0.086 1.29 16.4 #4 0.055 0.65 6.7 70.1 #5 0.075 0.80 10.7 204.5Get the MATLAB code (requires JavaScript) Published with MATLAB® R2024a",
+ "content_html": "
Recently, I have made a series of blog posts about Redheffer matrices and the Mertens conjecture. After each of the posts, readers and colleagues offered suggestions to speed up the calculations. Here is a summary of what I have learned.
The function named after the mid-nineteenth century German mathematician August Möbius is fundamental to the study of prime numbers. The Möbius function maps the positive integers onto -1,0 and +1.
mu(n) = 0 if n has a repeated prime factor, = (-1)^(number prime factors) if the factors of n are not repeated
Here is my code for the Möbius function. It relies on factor(n) which uses a sieve to find the prime factors of n.
function mu = mobius(n) % mu = mobius(n) returns mu(1:n). mu = -eye(1,n); for k = 2:n f = factor(k); d = diff([1 f]); if any(d == 0) mu(k) = 0; else mu(k) = (-1)^length(f); end end end
Here is a graph of mu(n) for n = 1:40. For example, mu(29:31) are all -1 because 29 and 31 are both prime and 30 has an odd number of prime factors, 2, 3 and 5.
mu = moebius(40); plot(1:40,mu,'.-','linewidth',1.5,'markersize',16) axis([-242-1.51.5]) title('Möbius function')
Mertens Function
The Mertens function is named after the late-nineteenth century Polish mathematician Franz Mertens. The function, which we denote by M(n), is simply the partial sums of the Möbius function. The MATLAB code is very short.
function M = mertens(n) % M = mertens(n) returns Mertens(1:n). mu = moebius(n); M = cumsum([1 mu(2:n)]); end
Here is a graph of M(n) for n = 1:40.
M = mertens(40); plot(1:40,M,'.-','linewidth',1.5,'markersize',16) axis([-242-4.51.5]) title('Mertens function')
Redheffer Matrices
The twentieth-century American mathematician Ray Redheffer, who was a professor at UCLA for 55 years, had a wide range of interests. He was the author of several popular textbooks, the inventor of the electronic game Nim and, with Ray and Charles Eames, the creator of a four-meter long poster Men of Modern Mathematics.
The n-by-n Redheffer's matrix R(n) is a matrix of zeros and ones. For j > 1, the element R(k,j) equals one if j is a divisor of k. And importantly, for j = 1, the first column R(:,1) is all ones.
function R = redheffer(n) k = 1:n; j = k'; R = (mod(k,j) == 0); R(:,1) = 1; end
Nick Higham put Redheffer's matrix in the MATLAB Gallery several years ago. Here is a spy plot of the 200-by-200.
R = gallery('redheff',200); spy(R) title('Redheffer')
OEIS
In the Online Encyclopedia of Integer Sequences, the Mertens function is OEIS/A002321. One of the many cool features of the OEIS is \"listen\", which generates music driven by the sequences. Take a look -- and a listen -- to my 63 second movie about A002321.
Here are plots of M(1:n) with n ranging from 100 to 10 million. Each plot after the first also shows the range of the previous plot. I will discuss the red lines in the next section
load mertens M tiledlayout(2,3) for n = 10.^(2:7) nexttile mertens_plot(M(1:n)) end
Mertens Conjecture
The red lines above are plots of ±sqrt(n). They clearly bound M(n) for n up to 10 million. The Mertens Conjecture is that this holds for all n.
|M(n)| < sqrt(n) for all n > 0
The conjecture appears in a 1885 letter from Thomas Stieltjes to Charles Hermite and in a 1897 paper by Mertens.
It is a striking example of a mathematical conjecture proven false despite a large amount of computational evidence in its favor.
Conjecture is False
In 1985, 100 years after the Stieltjes letter, Andrew Odlyzko and Herman te Riele proved that the conjecture is false. Their proof is indirect. They prove the existence of infinitely many n for which
|M(n)|/sqrt(n) > 1.06
But they do not know the value of any particular n. They informally estimate that such an n would be greater than 10^30 and probably much larger.
Matrices
Let's get back to the world of matrices. It is not obvious, but is true, that the determinants of Redheffer matrices are equal to the Mertens function.
det(R(n)) = M(n)
So, if I could have proved that
|det(R(n))| < sqrt(n) for all n > 0
I would have had a proof of the Riemann Hypothesis.
It might appear that I am out of the clutches of number theory and safely back to matrix computation. But that illusion does not last for long.
Sparsity
The 0(n^3) memory required by the Redheffer matrix from the gallery runs out of steam quickly. We need to take advantage of sparsity. This function generates the sparse representation of a Redheffer matrix directly.
function R = spredheffer(n) j = (1:n)'; k = ones(n,1); m = n; for i = 2:n t = [1 i:i:n]; p = length(t); j(m+(1:p)) = t; k(m+(1:p)) = i; m = m+p; end R = sparse(k,j,1,n,n); end
Computing Mertens
Here are five methods for computing the Mertens function.
#1
The first simply takes the determinant of the Redheffer matrix in the gallery.
M = det(gallery('redheff',n))
#2
The sparse Gaussian elimination function lu with one input and four sparse outputs is designed for solving sparse linear systems. Written primarily by Tim Davis and included in his UMFPACK package, the function uses an unsymmetric pattern multifrontal pivoting strategy to reduce fill-in while maintaining numerical stability. The determinant of the input matrix is the product of the four determinants of the output matrices. Two them are triangular and two are permutations, so it is easy, and quick, to compute their determinants.
R = spredheffer(n); [L,U,P,Q] = lu(R) M = det(L)*det(U)*det(P)*det(Q);
#3
Pat Quillen realized that by interchanging the first and last columns, there would be little fill-in. We need only one determinant.
R = spredheffer(n); R(:,[1 n]) = R(:,[n 1]); M = -det(R);
#4
A thoughtful reader of the blog submitted a suggestion based on the Schur complement. Suppose E is a block matrix,
E = [A B C D]
Schur's formula for the determinant of E is
det(E) = det(D)*det(A - B*(D\\C))
Apply this to R(n) with A the (1,1) entry, which is 1, and D the lower (n-1)-by-(n-1) submatrix, which is upper triangular with ones on the diagonal and determinant equal 1. This leads to method #4 which uses backslash with a sparse, unit, upper triangular matrix. There is a Redheffer matrix, but no determinant.
S = spredheffer(n); e = ones(n-1,1); M = 1 - e'*(S(2:n,2:n)\\e);
#5
Once we have generated R(n) and computed M(n), how do we get R(n+1) and M(n+1)? After several iterations of this approach, I found myself without any matrices and only the original definitions of Möbius and Mertens.
mu = mobius(n); M = cumsum([1 mu(2:n)]);
Performance
Let's summarize the five methods. The first four generate a single, isolated value of M(n). Method #5 generates M(n) for all n from 1 to any specified maximum.
matrix function dets M
#1 full gallery 1 1 #2 sparse lu 4 1 #3 sparse swap 1 1 #4 sparse \\ 0 1 #5 none factor 0 many
Time in seconds to compute M(n) on my Lenovo T14 laptop running Windows.
",
+ "url": "https://hpc.social/commercial-blog/2024/m%C3%B6bius-mertens-and-redheffer/",
+
+
+
+
+
+ "date_published": "2024-10-23T00:53:53-06:00",
+ "date_modified": "2024-10-23T00:53:53-06:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2024/experience-with-chatbots-generating-matlab/",
+ "title": "Experience With Chatbots Generating MATLAB",
+ "summary": null,
+ "content_text": "A friend is investigating the use of generative AI in his classes. I asked two different popular chatbots to write MATLAB programs for a mathematically nontrivial problem. Both chatbots understood my query and both wrote plausible MATLAB programs, but one of the programs was not correct. My recommendation for coursework: carefully read and test programs produced by generative AI and repair any incorrect ones.ContentsRedheffer, Mertens and AhaltProgram number oneProgram number twoProgram number threeHappy EndingRedheffer, Mertens and AhaltFrequent readers of this blog know about my recent obsession with Redheffer matrices and the Mertens conjecture. So, when my friend Stan Ahalt visited from North Carolina State a few days ago, and wanted to discuss the use of generative AI in the new Data Science curriculum, I suggested asking chatbots to write MATLAB programs that check the Mertens conjecture.We logged onto the web sites for two different AI companies. Our query was the same at both sites.Please write a MATLAB program to test the Mertens conjecture.I was pleasantly surprised when both systems knew about MATLAB and understood the query. One of the systems replied:Certainly! I'll create a MATLAB program to test the Mertensconjecture. First, let me briefly explain what the Mertensconjecture is, and then I'll provide the code.The Mertens conjecture states that the Mertens function M(n)is bounded by √n for all positive integers n. Mathematically,it can be expressed as:|M(n)| ≤ √n for all n > 1Where M(n) is the Mertens function, defined as the sum ofthe Möbius function μ(k) for all positive integers k up to n:M(n) = Σ μ(k) for k = 1 to nHere's a MATLAB program to test this conjecture.Program number oneThe program from one of the web sites begins:function M = test_Mertens(n) % Function to test the Mertens conjecture for a given n % Returns true if the conjecture holds for all values up to n, false otherwiseThis is followed by code to sum the Möbius function and verify that abs(M) < sqrt(n). The crucial mobius is a straight-forward implementation of the definition. The code relies on MATLAB intrinsics, factor and unique.function mu = mobius(k) % Function to calculate the Möbius function of k % Factorize k p = factor(k); % Check for square factors if length(p) ~= length(unique(p)) mu = 0; else mu = (-1)^length(p); endendI was very pleased. The entire program is only 40 lines long, eminently readable, and correct.Program number twoThe program from the other web site is more sophisticated. It knows enough about MATLAB to use its cumulative summation.M = cumsum(mu);Here is the crucial mobius function. At first glance, it looks OK. Is it?function mu = mobius(n) % Calculate Möbius function values up to n mu = ones(1, n); for i = 2:sqrt(n) if mu(i) == 1 for j = i^2:i:n if mod(j, i^2) == 0 mu(j) = 0; else mu(j) = -mu(j); end end end endendAs you have guessed, program number two is not correct. Even its own plot reveals that something is amiss.Program number threeLet's return to the second Web site and make a more specific query.Please write a MATLAB program that uses Redheffermatrices to test the Mertens conjecture.The resulting program generates a Redheffer matrix withR = zeros(n,n);for i = 1:n for j = 1:n if mod(i, j) == 0 R(i, j) = 1; end endendIt computes the determinant to obtain the Mertens value, M(n). It is able to confirm the conjecture for all the n in the given range.What's wrong now? Look at the plot. The computed M(n) is always equal to one. Why? Happy EndingProgram number three can be repaired by adding one line to the code that generates R. What is that line? Respond in the comments.Look at the good side. Instead of just using AI to do homework, we can challenge students to check the results carefully and repair any incorrect programs.Get the MATLAB code (requires JavaScript) Published with MATLAB® R2024a",
+ "content_html": "
A friend is investigating the use of generative AI in his classes. I asked two different popular chatbots to write MATLAB programs for a mathematically nontrivial problem. Both chatbots understood my query and both wrote plausible MATLAB programs, but one of the programs was not correct. My recommendation for coursework: carefully read and test programs produced by generative AI and repair any incorrect ones.
Frequent readers of this blog know about my recent obsession with Redheffer matrices and the Mertens conjecture. So, when my friend Stan Ahalt visited from North Carolina State a few days ago, and wanted to discuss the use of generative AI in the new Data Science curriculum, I suggested asking chatbots to write MATLAB programs that check the Mertens conjecture.
We logged onto the web sites for two different AI companies. Our query was the same at both sites.
Please write a MATLAB program to test the Mertens conjecture.
I was pleasantly surprised when both systems knew about MATLAB and understood the query. One of the systems replied:
Certainly! I'll create a MATLAB program to test the Mertensconjecture. First, let me briefly explain what the Mertensconjecture is, and then I'll provide the code.The Mertens conjecture states that the Mertens function M(n)is bounded by √n for all positive integers n. Mathematically,it can be expressed as:
|M(n)| ≤ √n for all n > 1
Where M(n) is the Mertens function, defined as the sum ofthe Möbius function μ(k) for all positive integers k up to n:
M(n) = Σ μ(k) for k = 1 to n
Here's a MATLAB program to test this conjecture.
Program number one
The program from one of the web sites begins:
function M = test_Mertens(n) % Function to test the Mertens conjecture for a given n % Returns true if the conjecture holds for all values up to n, false otherwise
This is followed by code to sum the Möbius function and verify that abs(M) < sqrt(n). The crucial mobius is a straight-forward implementation of the definition. The code relies on MATLAB intrinsics, factor and unique.
function mu = mobius(k) % Function to calculate the Möbius function of k % Factorize k p = factor(k); % Check for square factors if length(p) ~= length(unique(p)) mu = 0; else mu = (-1)^length(p); endend
I was very pleased. The entire program is only 40 lines long, eminently readable, and correct.
Program number two
The program from the other web site is more sophisticated. It knows enough about MATLAB to use its cumulative summation.
M = cumsum(mu);
Here is the crucial mobius function. At first glance, it looks OK. Is it?
function mu = mobius(n) % Calculate Möbius function values up to n mu = ones(1, n); for i = 2:sqrt(n) if mu(i) == 1 for j = i^2:i:n if mod(j, i^2) == 0 mu(j) = 0; else mu(j) = -mu(j); end end end endend
As you have guessed, program number two is not correct. Even its own plot reveals that something is amiss.
Program number three
Let's return to the second Web site and make a more specific query.
Please write a MATLAB program that uses Redheffermatrices to test the Mertens conjecture.
The resulting program generates a Redheffer matrix with
R = zeros(n,n);for i = 1:n for j = 1:n if mod(i, j) == 0 R(i, j) = 1; end endend
It computes the determinant to obtain the Mertens value, M(n). It is able to confirm the conjecture for all the n in the given range.
What's wrong now? Look at the plot. The computed M(n) is always equal to one. Why?
Happy Ending
Program number three can be repaired by adding one line to the code that generates R. What is that line? Respond in the comments.
Look at the good side. Instead of just using AI to do homework, we can challenge students to check the results carefully and repair any incorrect programs.
",
+ "url": "https://hpc.social/commercial-blog/2024/experience-with-chatbots-generating-matlab/",
+
+
+
+
+
+ "date_published": "2024-10-07T14:31:38-06:00",
+ "date_modified": "2024-10-07T14:31:38-06:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2024/redheffer-and-mertens-accelerated/",
+ "title": "Redheffer and Mertens, Accelerated",
+ "summary": null,
+ "content_text": "Shortly after I published the second post about the Mertens conjecture, a reader's comment suggested a new approach to computing Redheffer determinants and the Mertens function. It is now possible to compute a half-million values of the Mertens function in about five hours.ContentsBlock matricesredmertInside redmertmertens_plotPostscriptBlock matricesThe comment references the Wikipedia article on block matrices. You could also consider the matrix as a 2x2 block matrix and use the formula for the determinant of a block matrix [1]. A = redheffer(n); M = full(A(1,1) - A(1, 2:end) * (A(2:end,2:end) \\ A(2:end, 1))); Since the (n-1)x(n-1) block is upper triangular, the solve becomes a back-substitution.redmertMy new program is named redmert, an abbreviation of Redheffer-Mertens. It uses the fact that redheffer(n) is obtained from redheffer(n-1) by appending the last column.Let R(n) denote the upper or right-triangular part of redheffer(n). R(n) = triu(redheffer(n))R(n) is sparse, upper triangular and has ones on the diagonal. The indices of the nonzeros in the last column of R(n) are the factors of n. For example, here is R(8).R8 = full(triu(redheffer(8)))R8 = 1 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1The idea behind redmert is to compute a sequence of Redheffer matrices, R, and associated values of the Mertens function, M. [M,R] = redmert(p,R)The input is a scalar integer p, the desired sequence length, and a sparse matrix R, the upper triangle of a Redheffer matrix of some order, n. The output is an integer vector of values M(n+1:n+p) and the upper triangle of the Redheffer matrix of order n+p. This output R can then be used as the input R in another call to redmert.The sequence is started with an empty R.For example,[M,R] = redmert(8,[]);The output is mertens(n), n = 1:8, and R8 from the example above.MR8 = full(R)M = 1 0 -1 -1 -2 -1 -2 -2R8 = 1 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1Inside redmertThe entire code for redmert is twelve lines long. It manipulates sparse matrices and uses sparse backslash to solve a triangular system. Nothing else is required.Lines 7 and 8 generate the last column of R and lines 9 and 10 implement the new idea about block matrices.dbtype redmert1 function [M,R] = redmert(p,Rin)2 M = zeros(p,1);3 R = sparse(triu(Rin));4 n = size(R,1);5 for q = 1:p6 n = n+1;7 k = (mod(n,1:n) == 0);8 R(k,n) = 1;9 e = ones(n-1,1);10 M(q) = R(1,1) - e'*(R(2:n,2:n)\\e);11 end12 endmertens_plotIt takes about five hours for redmert to compute half a million values on my laptop. n = 0.5e6; p = 0.5e4; R = sparse([]); M = []; for k = p:p:n disp(k) [Mout,R] = redmert(p,R); M = [M; Mout]; mertens_plot(M) endmertens_plot PostscriptI started this project by being surprised to find myself computing determinants. Now I am back to my long-time position disparaging determinants. They have been replaced by a good friend, backslash.Get the MATLAB code (requires JavaScript) Published with MATLAB® R2024a",
+ "content_html": "
Shortly after I published the second post about the Mertens conjecture, a reader's comment suggested a new approach to computing Redheffer determinants and the Mertens function. It is now possible to compute a half-million values of the Mertens function in about five hours.
You could also consider the matrix as a 2x2 block matrix and use the formula for the determinant of a block matrix [1]. A = redheffer(n); M = full(A(1,1) - A(1, 2:end) * (A(2:end,2:end) \\ A(2:end, 1))); Since the (n-1)x(n-1) block is upper triangular, the solve becomes a back-substitution.
redmert
My new program is named redmert, an abbreviation of Redheffer-Mertens. It uses the fact that redheffer(n) is obtained from redheffer(n-1) by appending the last column.
Let R(n) denote the upper or right-triangular part of redheffer(n).
R(n) = triu(redheffer(n))
R(n) is sparse, upper triangular and has ones on the diagonal. The indices of the nonzeros in the last column of R(n) are the factors of n. For example, here is R(8).
The idea behind redmert is to compute a sequence of Redheffer matrices, R, and associated values of the Mertens function, M.
[M,R] = redmert(p,R)
The input is a scalar integer p, the desired sequence length, and a sparse matrix R, the upper triangle of a Redheffer matrix of some order, n. The output is an integer vector of values M(n+1:n+p) and the upper triangle of the Redheffer matrix of order n+p. This output R can then be used as the input R in another call to redmert.
The sequence is started with an empty R.
For example,
[M,R] = redmert(8,[]);
The output is mertens(n), n = 1:8, and R8 from the example above.
The entire code for redmert is twelve lines long. It manipulates sparse matrices and uses sparse backslash to solve a triangular system. Nothing else is required.
Lines 7 and 8 generate the last column of R and lines 9 and 10 implement the new idea about block matrices.
dbtype redmert
1 function [M,R] = redmert(p,Rin)2 M = zeros(p,1);3 R = sparse(triu(Rin));4 n = size(R,1);5 for q = 1:p6 n = n+1;7 k = (mod(n,1:n) == 0);8 R(k,n) = 1;9 e = ones(n-1,1);10 M(q) = R(1,1) - e'*(R(2:n,2:n)\\e);11 end12 end
mertens_plot
It takes about five hours for redmert to compute half a million values on my laptop.
n = 0.5e6; p = 0.5e4; R = sparse([]); M = []; for k = p:p:n disp(k) [Mout,R] = redmert(p,R); M = [M; Mout]; mertens_plot(M) end
mertens_plot
Postscript
I started this project by being surprised to find myself computing determinants. Now I am back to my long-time position disparaging determinants. They have been replaced by a good friend, backslash.
",
+ "url": "https://hpc.social/commercial-blog/2024/redheffer-and-mertens-accelerated/",
+
+
+
+
+
+ "date_published": "2024-09-30T14:28:40-06:00",
+ "date_modified": "2024-09-30T14:28:40-06:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2024/redheffer-and-mertens-continued/",
+ "title": "Redheffer and Mertens, Continued",
+ "summary": null,
+ "content_text": "Shortly after I posted Redheffer, Mertens and One-Million Dollars a few days ago, Mathworks' Pat Quillen made an important observation about computing the Mertens function.ContentsmertensMertens functionMertens computationMertens conjecturemertensThe elements in the first column of the Redheffer matrix, A = redheffer(n), are all equal to one. That dense column does not make MATLAB happy about computing det(A) . However, the last column of A has only a few nonzero elements and so Pat suggested interchanging the first and last columns before computing the determinant. This makes a world of difference. (Thanks, Pat.)typemertensfunction M = mertens(n) if n > 1 A = redheffer(n); A(:,[1 n]) = A(:,[n 1]); M = -round(det(A)); else M = 1; endendThe time required to compute det(A) varies with the sparsity of the last column, but it is only a little more than the time to compute redheffer(n) in the first place.mertens2_time Mertens functionPat's change makes it possible to take n up to a quarter of a million, and beyond. Here is a new plot of the Mertens function M(n) and the sqrt(n) bounds of the Mertens conjecture.mertens_plot There are a quarter of a million points in the data for this plot. Fortunately, the .PNG file used for the blog only needs to sample the data.Mertens computationThe job that I ran on my laptop to compute one-quarter of a million values of M(n) is still running. It currently is past 0.35 million and takes less than two seconds for each value. I may keep the job running over the weekend, just to see how far it gets.The task is embarrassingly parallel. If I had a pool with a million processors, I could have each processor compute one value. I would then just have to collect the results, but that doesn't involve any arithmetic.Mertens conjectureYou can see from the plot why late 19th- and early 20th-century mathematicians believed that the Mertens conjecture, |M(n)| < sqrt(n) for all n,might be true. It is hard to imagine that the plot of M(n) ever escapes sqrt(n).We now know that M(n) eventually does escape, but only barely and only briefly. We also know that all the computation we can do with determinants of Redheffer's matrix will never prove or disprove the conjecture or win that million-dollar prize.Get the MATLAB code (requires JavaScript) Published with MATLAB® R2024a",
+ "content_html": "
Shortly after I posted Redheffer, Mertens and One-Million Dollars a few days ago, Mathworks' Pat Quillen made an important observation about computing the Mertens function.
The elements in the first column of the Redheffer matrix, A = redheffer(n), are all equal to one. That dense column does not make MATLAB happy about computing det(A) . However, the last column of A has only a few nonzero elements and so Pat suggested interchanging the first and last columns before computing the determinant. This makes a world of difference. (Thanks, Pat.)
typemertens
function M = mertens(n) if n > 1 A = redheffer(n); A(:,[1 n]) = A(:,[n 1]); M = -round(det(A)); else M = 1; endend
The time required to compute det(A) varies with the sparsity of the last column, but it is only a little more than the time to compute redheffer(n) in the first place.
mertens2_time
Mertens function
Pat's change makes it possible to take n up to a quarter of a million, and beyond. Here is a new plot of the Mertens function M(n) and the sqrt(n) bounds of the Mertens conjecture.
mertens_plot
There are a quarter of a million points in the data for this plot. Fortunately, the .PNG file used for the blog only needs to sample the data.
Mertens computation
The job that I ran on my laptop to compute one-quarter of a million values of M(n) is still running. It currently is past 0.35 million and takes less than two seconds for each value. I may keep the job running over the weekend, just to see how far it gets.
The task is embarrassingly parallel. If I had a pool with a million processors, I could have each processor compute one value. I would then just have to collect the results, but that doesn't involve any arithmetic.
Mertens conjecture
You can see from the plot why late 19th- and early 20th-century mathematicians believed that the Mertens conjecture,
|M(n)| < sqrt(n) for all n,
might be true. It is hard to imagine that the plot of M(n) ever escapes sqrt(n).
We now know that M(n) eventually does escape, but only barely and only briefly. We also know that all the computation we can do with determinants of Redheffer's matrix will never prove or disprove the conjecture or win that million-dollar prize.
",
+ "url": "https://hpc.social/commercial-blog/2024/redheffer-and-mertens-continued/",
+
+
+
+
+
+ "date_published": "2024-09-27T12:28:39-06:00",
+ "date_modified": "2024-09-27T12:28:39-06:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2024/redheffer-mertens-and-one-million-dollars/",
+ "title": "Redheffer, Mertens and One-Million Dollars",
+ "summary": null,
+ "content_text": "I didn't know anything about these topics until a couple of weeks ago. Now I can't stop thinking about them.Redheffer's matrix has been in the MATLAB Gallery for a long time, but I have ignored it .Redheffer's matrix can be used to compute Mertens function and investigate the Mertens conjecture.A proof of the Mertens conjecture would also provide a proof of the Riemann hypothesis.For nearly a century, all the available computational evidence indicated that the Mertens conjecture was likely to be true.The Riemann hypothesis is the most important unsolved problem in mathematics and wins a Clay prize worth one-million dollars.MATLAB's sparse matrix functions turn out to be useful in an investigation of Redheffer's matrix and the Mertens conjecture.However, it has been known since 1985 that the Mertens conjecture is false.ContentsRedheffer's MatrixMöbius FunctionMertens FunctionMertens ConjectureMertens Meets RedhefferRedheffer SparsityredhefferSparse LUmertensMertens Conjecture Is FalsePostscriptsReferencesRedheffer's MatrixRaymond Redheffer (1921-2005) was an American mathematician, a professor at UCLA for 55 years, the author of several popular textbooks, the inventor of the electronic game Nim and, with Ray and Charles Eames, the creator of a four-meter long poster Men of Modern Mathematics.Redheffer's matrix is a matrix of zeros and ones. A(k,j) equals one if j is a divisor of k. In addition, the first column is all ones. function A = redheffer(n) k = 1:n; j = k'; A = (mod(k,j) == 0); A(:,1) = 1; endOr A = gallery('redheff',n)Here is the 10-by-10. A = redheffer(10); disp(full(A)) 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1And here is a spy plot of the 200-by-200. A = redheffer(200); spy(A) title('redheffer(200)') Möbius FunctionThe Möbius function was introduced in 1832 by German mathematician August Möbius and is ubiquitous in the study of prime numbers. For positive integers n, μ(n) is0 if n has a squared prime factor,+1 if n is square-free and has an even number of prime factors,-1 if n is square-free and has an odd number of prime factors.Mertens FunctionFranz Mertens (1840-1927) was a Polish mathematician who spent most of his career in Austria at the University of Vienna. Here is a link to a biography of Mertens at the University of St. Andrews MacTutor project.The Mertens function is sum of values of the Möbius function. For a positive integer n, the Mertens function is M(n) = sum(μ(1:n))So M(n) is the difference between the number of square-free integers with an even number of prime factors and those with an odd number.This graphic shows M(n) for n = 1:100000. mertens_plot_2 Mertens ConjectureThe Mertens function M(n) fluctuates wildly and grows slowly with increasing n. The graphic shows that M(n) is easily bounded by of sqrt(n) and -sqrt(n), at least for n less than 100k. The Mertens conjecture is that this continues for larger n. -sqrt(n) < M(n) < sqrt(n) for all nThe conjecture was included in a letter from Stieltjes to Hermite in 1895 and in a paper by Mertens in 1897. The result is important since a proof of the Mertens conjecture would imply the truth of the Riemann hypothesis.Mertens Meets RedhefferI became interested in all this when I learned that the determinant of the MATLAB Gallery matrix which I have ignored for years is related to the Riemann hypothesis and the million-dollar prize. M(n) = det(gallery('redheff',n))I know very little about the distribution of prime numbers and computing values of the Möbius function. On the other hand, I know a lot about numerical linear algebra and computing determinants.In general, I am dead set against computing determinants. They are often used to check for singularity or to somehow compute eigenvalues. But here the determinant is an integer counter of modest size.Redheffer SparsityComputing M(n) directly with det(redheffer(n)) requires O(n^2) space and O(n^3) time and is not practical for large n.However, A = redheffer(n) is modestly sparse. Here is the fraction of nonzeros. s = nnz(A)/n^2 disp(sparsity) n s _____ ________ 10000 0.001037 20000 0.000553 30000 0.000382 40000 0.000294 50000 0.000239 60000 0.000203 70000 0.000176 80000 0.000156 90000 0.000139 1e+05 0.000127Taking advantage of this sparsity and the MATLAB tools for sparse matrix computation provide linear space complexity and perhaps O(n^2) time complexity.redhefferHere is MATLAB code to generate a sparse redheffer(n) without creating any full intermediate matrices.type redheffer function A = redheffer(n) j(1:n) = (1:n)'; k(1:n) = 1; m = n; for i = 2:n t = [1 i:i:n]'; p = length(t); j(m+(1:p)) = t; k(m+(1:p)) = i; m = m+p; end A = sparse(k,j,1,n,n); endAs expected, we see that the execution time for redheffer(n) is a linear function of n. (The space required also grows linearly.) redheffer_time Sparse LUThe MATLAB Gaussian elimination function lu with one sparse input and four sparse outputs is designed for solving sparse linear systems. [L,U,P,Q] = lu(A)Written primarily by Tim Davis and included in his UMFPACK package, the function uses an unsymmetric pattern multifrontal pivoting strategy to find permutations P and Q so that L is lower triangular, U is upper triangular and P*A*Q = L*UConsequently, the determinant of A is the product of four easily computed determinants. det(A) = det(L)*det(U)*det(P)*det(Q)The pivoting strategy aims to reduce fill-in while maintaining numerical stability.For example, here are L and U for the Redheffer matrix in the spy plot near the top of this blog post. close A = redheffer(200); [L,U,P,Q] = lu(A); spy(L|U) title('L|U') And here are the four determinants. dets = [det(L),det(U),det(P),det(Q)]; disp(dets) 1 -8 -1 -1Finally, M(200) is M_200 = det(L)*det(U)*det(P)*det(Q) M_200 = -8mertensMertens function can be computed with four lines of code. type mertens function M = mertens(n) der = @(x) full(round(prod(diag(x)))); A = redheffer(n); [L,U,P,Q] = lu(A); M = der(L)*der(U)*det(P)*det(Q); endExecution time for mertens is dominated by the time in sparse lu. The time required to compute the four determinants is an order of magnitude smaller than the other two.Experimentally, we see that the time complexity of sparse lu is O(n^2), but we have no proof. mertens_time Mertens Conjecture Is FalseThe Mertens conjecture stood for nearly 100 years before it was proved false in 1985 by Andrew Odlyzko and Herman te Riele. The authors present indirect proofs that lim sup (n -> inf) M(n)/sqrt(n) > 1.06 lim inf (n -> inf) M(n)/sqrt(n) < -1.009Odlyzko and te Riele do not actually produce any value of n for which M(n) > sqrt(x). They suspect that any Mertens conjecture counterexample requires n > $10^{30}$, which is far beyond any computation possible today.Odlyzko and te Riele also describe several complete tabulations of M(n) for n as large as $7.8 \\cdot 10^{9}$ . These computations do not use Redheffer determinants.PostscriptsTo tell the truth, I did not really expect to find any Mertens or Riemann counterexamples. I did, however, enjoy computing determinants for the first time and discovering an unexpected use for sparse LU.Thanks a lot to Tim Davis for his help with this post.ReferencesA. M. Odlyzko and H. J. J. te Riele, \"Disproof of the Mertens conjecture\", Journal für die reine und angewandte Mathematik, Vol. 357 (1985), Pages138-160. https://eudml.org/doc/152712.Timothy A. Davis, \"A Column Pre-Ordering Strategy for the Unsymmetric-Pattern Multifrontal Method\", ACM Transactions on Mathematical Software, Vol. 30, No. 2, June 2004, Pages 165–195. https://dl.acm.org/doi/abs/10.1145/992200.992205.Get the MATLAB code (requires JavaScript) Published with MATLAB® R2024a",
+ "content_html": "
I didn't know anything about these topics until a couple of weeks ago. Now I can't stop thinking about them.
Redheffer's matrix has been in the MATLAB Gallery for a long time, but I have ignored it .
Redheffer's matrix can be used to compute Mertens function and investigate the Mertens conjecture.
A proof of the Mertens conjecture would also provide a proof of the Riemann hypothesis.
For nearly a century, all the available computational evidence indicated that the Mertens conjecture was likely to be true.
The Riemann hypothesis is the most important unsolved problem in mathematics and wins a Clay prize worth one-million dollars.
MATLAB's sparse matrix functions turn out to be useful in an investigation of Redheffer's matrix and the Mertens conjecture.
However, it has been known since 1985 that the Mertens conjecture is false.
Raymond Redheffer (1921-2005) was an American mathematician, a professor at UCLA for 55 years, the author of several popular textbooks, the inventor of the electronic game Nim and, with Ray and Charles Eames, the creator of a four-meter long poster Men of Modern Mathematics.
Redheffer's matrix is a matrix of zeros and ones. A(k,j) equals one if j is a divisor of k. In addition, the first column is all ones.
function A = redheffer(n) k = 1:n; j = k'; A = (mod(k,j) == 0); A(:,1) = 1; end
A = redheffer(200); spy(A) title('redheffer(200)')
Möbius Function
The Möbius function was introduced in 1832 by German mathematician August Möbius and is ubiquitous in the study of prime numbers. For positive integers n, μ(n) is
0 if n has a squared prime factor,
+1 if n is square-free and has an even number of prime factors,
-1 if n is square-free and has an odd number of prime factors.
Mertens Function
Franz Mertens (1840-1927) was a Polish mathematician who spent most of his career in Austria at the University of Vienna. Here is a link to a biography of Mertens at the University of St. Andrews MacTutor project.
The Mertens function is sum of values of the Möbius function. For a positive integer n, the Mertens function is
M(n) = sum(μ(1:n))
So M(n) is the difference between the number of square-free integers with an even number of prime factors and those with an odd number.
This graphic shows M(n) for n = 1:100000.
mertens_plot_2
Mertens Conjecture
The Mertens function M(n) fluctuates wildly and grows slowly with increasing n. The graphic shows that M(n) is easily bounded by of sqrt(n) and -sqrt(n), at least for n less than 100k. The Mertens conjecture is that this continues for larger n.
-sqrt(n) < M(n) < sqrt(n) for all n
The conjecture was included in a letter from Stieltjes to Hermite in 1895 and in a paper by Mertens in 1897. The result is important since a proof of the Mertens conjecture would imply the truth of the Riemann hypothesis.
Mertens Meets Redheffer
I became interested in all this when I learned that the determinant of the MATLAB Gallery matrix which I have ignored for years is related to the Riemann hypothesis and the million-dollar prize.
M(n) = det(gallery('redheff',n))
I know very little about the distribution of prime numbers and computing values of the Möbius function. On the other hand, I know a lot about numerical linear algebra and computing determinants.
In general, I am dead set against computing determinants. They are often used to check for singularity or to somehow compute eigenvalues. But here the determinant is an integer counter of modest size.
Redheffer Sparsity
Computing M(n) directly with det(redheffer(n)) requires O(n^2) space and O(n^3) time and is not practical for large n.
However, A = redheffer(n) is modestly sparse. Here is the fraction of nonzeros.
Taking advantage of this sparsity and the MATLAB tools for sparse matrix computation provide linear space complexity and perhaps O(n^2) time complexity.
redheffer
Here is MATLAB code to generate a sparse redheffer(n) without creating any full intermediate matrices.
type redheffer
function A = redheffer(n) j(1:n) = (1:n)'; k(1:n) = 1; m = n; for i = 2:n t = [1 i:i:n]'; p = length(t); j(m+(1:p)) = t; k(m+(1:p)) = i; m = m+p; end A = sparse(k,j,1,n,n); end
As expected, we see that the execution time for redheffer(n) is a linear function of n. (The space required also grows linearly.)
redheffer_time
Sparse LU
The MATLAB Gaussian elimination function lu with one sparse input and four sparse outputs is designed for solving sparse linear systems.
[L,U,P,Q] = lu(A)
Written primarily by Tim Davis and included in his UMFPACK package, the function uses an unsymmetric pattern multifrontal pivoting strategy to find permutations P and Q so that L is lower triangular, U is upper triangular and
P*A*Q = L*U
Consequently, the determinant of A is the product of four easily computed determinants.
det(A) = det(L)*det(U)*det(P)*det(Q)
The pivoting strategy aims to reduce fill-in while maintaining numerical stability.
For example, here are L and U for the Redheffer matrix in the spy plot near the top of this blog post.
close A = redheffer(200); [L,U,P,Q] = lu(A); spy(L|U) title('L|U')
And here are the four determinants.
dets = [det(L),det(U),det(P),det(Q)]; disp(dets)
1 -8 -1 -1
Finally, M(200) is
M_200 = det(L)*det(U)*det(P)*det(Q)
M_200 = -8
mertens
Mertens function can be computed with four lines of code.
type mertens
function M = mertens(n) der = @(x) full(round(prod(diag(x)))); A = redheffer(n); [L,U,P,Q] = lu(A); M = der(L)*der(U)*det(P)*det(Q); end
Execution time for mertens is dominated by the time in sparse lu. The time required to compute the four determinants is an order of magnitude smaller than the other two.
Experimentally, we see that the time complexity of sparse lu is O(n^2), but we have no proof.
mertens_time
Mertens Conjecture Is False
The Mertens conjecture stood for nearly 100 years before it was proved false in 1985 by Andrew Odlyzko and Herman te Riele. The authors present indirect proofs that
lim sup (n -> inf) M(n)/sqrt(n) > 1.06
lim inf (n -> inf) M(n)/sqrt(n) < -1.009
Odlyzko and te Riele do not actually produce any value of n for which M(n) > sqrt(x). They suspect that any Mertens conjecture counterexample requires n > $10^{30}$, which is far beyond any computation possible today.
Odlyzko and te Riele also describe several complete tabulations of M(n) for n as large as $7.8 \\cdot 10^{9}$ . These computations do not use Redheffer determinants.
Postscripts
To tell the truth, I did not really expect to find any Mertens or Riemann counterexamples. I did, however, enjoy computing determinants for the first time and discovering an unexpected use for sparse LU.
Thanks a lot to Tim Davis for his help with this post.
References
A. M. Odlyzko and H. J. J. te Riele, \"Disproof of the Mertens conjecture\", Journal für die reine und angewandte Mathematik, Vol. 357 (1985), Pages138-160. https://eudml.org/doc/152712.
Timothy A. Davis, \"A Column Pre-Ordering Strategy for the Unsymmetric-Pattern Multifrontal Method\", ACM Transactions on Mathematical Software, Vol. 30, No. 2, June 2004, Pages 165–195. https://dl.acm.org/doi/abs/10.1145/992200.992205.
",
+ "url": "https://hpc.social/commercial-blog/2024/redheffer-mertens-and-one-million-dollars/",
+
+
+
+
+
+ "date_published": "2024-09-23T17:12:35-06:00",
+ "date_modified": "2024-09-23T17:12:35-06:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2024/na-digest-and-na-net/",
+ "title": "NA_Digest and NA_Net",
+ "summary": null,
+ "content_text": "The NA-Digest is an electronic newsletter for the numerical analysis and scientific software community. The NA-Digest is one of world's first examples of social networking. The Digest is one of the forces that makes our community a living, viable community.The Digest is part of NA-Net, which also includes Netlib, a collection of mathematical software, papers, and databases.For its first forty years, the NA-Digest has had only four editors. Now, we are adding two more. As we do that, I would like to take a personal look back at the history of the NA-Digest.ContentsGene and MarkJack and EricTammy and DannyDavid and AlexArchiveMembersImportant PostingsThanksReferencesGene and MarkLike many other developments in the numerical analysis world, the Digest began with Gene Golub. In the early 1980's, Golub was chair of Stanford's Computer Science Department. Email was a new thing and Gene maintained a list of email addresses for his many friends around the world. Email addresses came in many different formats; today's system of domain names was not yet in wide spread use.In 1984, Mark Kent, one of Gene's grad students, with help from Ray Tuminaro, Mark Crispin and Dan Kolkowitz, wrote software that used Gene's list in an email forwarding service. Mail sent tona.name@su-scorewould be forwarded to the person with that last name. And email sent tona@su-scorewould be forwarded to everyone on the list.Gene and Mark Kent began to gather contributions together and send the collection out periodically. By February 1987, this had evolved into a moderated weekly newsletter. Gene dubbed these email services the NA-Net.Nick Trefethen has this memory. Early in the days of email, domain names were all over the place. I think there was a period when Gene was using xxx.na for the names of numerical analysts. Then somebody decided addresses should end with the country, giving us .uk and .fr and .ch and all that. For a period, we found that a lot of our numerical analysis emails were being directed to Namibia!In 1987, Gene asked me to moderate NA-Digest temporarily while he went on a sabbatical. That temporary position ultimately lasted 18 years, until 2005.Jack and EricJack Dongarra began his career at Argonne National Laboratory. Jack's colleague, Eric Grosse, began his career at Bell Labs. In 1984, Jack and Eric created Netlib, a software repository and distribution service, and merged it with NA-Net. In 1989, Jack and the NA-Net system moved from Argonne to Oak Ridge National Lab and the University of Tennessee.Keith Moore, at the University of Tennessee, rewrote the NA-Net software and maintained the servers for many years.Gerald Ragghianti, the Technical Services Leader at Tennessee's Innovative Computer Lab, currently maintains the NA-Net software and servers.Tammy and DannyIn 2005, I asked Tammy Kolda, who was then at Sandia Labs in Livermore, to be the NA-Digest editor. Tammy's Wikipedia page reveals that her given name is \"Tamara\", but everybody calls her \"Tammy\". She left Sandia is 2021 and now has her own consulting company, MathSci.ai.In 2010, Tammy recommended that Danny Dunlavy, from Sandia Labs in Albuquerque, take over as editor. He has been the editor for 14 years. Danny's day job at Sandia's Center for Computing Research involves a wide range of fields including computer architecture, cognitive modeling and discrete mathematics. David and Alex Starting next week, NA-Digest and NA-Net will move lock, stock, and barrel to Cornell University. The new editors are David Bindell and Alex Townsend. Cornell's IT organization will be taking over the logistics.David, Alex and Anil Damle are also the hosts for Householder XXII, June 8-13, 2025.ArchiveEvery issue of NA-Digest since February 1987 is available at https://www.netlib.org/na-digest-html.MembersWhen I succeeded Gene as editor in 1987, there were about 800 names on the NA-Net mailing list. Today, in 2024, there are a little over 10,000. Discontinuities in the size of the list result when unused and illegitimate names are removed. Important PostingsI have made three personally important announcements in the Digest over the years.October 29, 1989In 1989 I was working at Ardent Computer, a startup in Silicon Valley. I announced in NA-Digest that MathWorks was looking for a numerical analyst. (Note the MathWorks telephone number near the end of this announcement.) From: Cleve Moler <na.moler@na-net.stanford.edu> Date: Sun Oct 29 10:39:38 PST 1989 Subject: Positions at The MathWorks The MathWorks is the company which develops and markets MATLAB. The company currently employs about 30 people and expects to add three or four more soon. The company headquarters is in East Natick, Massachusetts, which is about a half hour drive west of Boston. The background and interests expected for the various positions available range from numerical linear algebra and matrix computation to systems programming and graphics. Educational level and experience expected range from inexperienced beginner willing to learn to seasoned Ph.D. with a personal library of M-files. For more information, send email to na.moler@na-net.stanford.edu or phone me at 408-732-0400. Or, contact the MathWorks' president, John Little, with email to jnl@mathworks.com, phone 508-653-1415, or write to: The MathWorks 21 Eliot Street South Natick, MA 01760November 26, 1989Shortly after that announcement, Ardent imploded and I said that I was taking the job myself. From: Cleve Moler <moler@mathworks.com> Date: Sun Nov 26 09:16:32 PST 1989 Subject: Change of Address for Moler A couple of weeks ago, I made an announcement here that The MathWorks, the MATLAB company, was looking to fill several positions, including one for a numerical analyst. Now, I've decided to take that slot myself. I'm one of the founders of MathWorks, and have always been a consultant to the company, but now I'll be a full time employee. For a while at least, I'll be working out of my home in California, even though MathWorks headquarters is in Massachusetts. (There are already a couple of other MathWorks developers in the Bay Area.) . . . My electronic address is \"moler@mathworks.com\". If your mailer can't find the route via uunet to mathworks.com, you can still use \"na.moler@na-net.stanford.edu\".November 16, 2007In November 2007 I was attending the Super Computing conference in Reno. I had rented a car and intended to drive to the Bay Area after the conference. But my wife called me and said, \"Hey Cleve, have you heard that Gene is in the hospital?\" I left SC immediately and drove to Palo Alto. Two days later we sent out a special issue of the Digest: From: Cleve Moler <Cleve.Moler@mathworks.com> Date: Fri, 16 Nov 2007 17:55:42 -0500 Subject: Gene Golub, 1932 - 2007 Gene Golub, founder of the NA Digest, passed away today, Friday, November 16, at the Stanford University Hospital. He was 75 years old. Gene returned home to Stanford recently from a trip to Hong Kong. He was planning to leave again Tuesday on another trip, this one to Zurich where the ETH was to honor him with a special degree. Instead, Sunday night he went to the emergency room because he was \"feeling lousy\". On Tuesday, he was found to have AML, acute myelogenous leukemia, a form of cancer that affects the white blood cells. This is a potentially curable disease and he was expecting to begin chemotherapy today. But serious complications developed suddenly over night. I was able to see Gene for an hour last night and he was in reasonably good spirits. Mike Saunders was trying to get Gene's laptop to use dial-up over the hospital's phone system because Gene said he was a couple of days behind on his email. I was planning to get a wireless card for his machine today. None of us had any idea how suddenly the situation would worsen. The Stanford ICME students have created a memorial blog at http://genehgolub.blogspot.com . Our community has lost its foremost member. He was a valued colleague and friend. Goodbye, Gene. -- Cleve MolerThanksGene Golub and Mark Kent for creating NA-Digest and NA-Net.Tammy Kolda and Danny Dunlavy for editing the Digest for two decades.Jack Dongarra, Eric Grosse, Keith Moore and Geri Ragghianti for creating Netlib and for hosting the system for four decades.David Bindel and Alex Townsend for joining this team.ReferencesJack Dongarra, Gene Golub, Eric Grosse, Cleve Moler and Keith Moore. \"Netlib and NA-Net: Building a Scientific Computing Community\", IEEE Annals of the History of Computing, (Volume: 30, Issue: 2, April-June 2008). A PDF is available here.Mark Kent, The Numerical Analysis Net (NA-NET), Technical Report 85, ETH Zurich, Institut fuer Informatik, 1988.Get the MATLAB code (requires JavaScript) Published with MATLAB® R2024a",
+ "content_html": "
The NA-Digest is an electronic newsletter for the numerical analysis and scientific software community. The NA-Digest is one of world's first examples of social networking. The Digest is one of the forces that makes our community a living, viable community.
The Digest is part of NA-Net, which also includes Netlib, a collection of mathematical software, papers, and databases.
For its first forty years, the NA-Digest has had only four editors. Now, we are adding two more. As we do that, I would like to take a personal look back at the history of the NA-Digest.
Like many other developments in the numerical analysis world, the Digest began with Gene Golub. In the early 1980's, Golub was chair of Stanford's Computer Science Department. Email was a new thing and Gene maintained a list of email addresses for his many friends around the world. Email addresses came in many different formats; today's system of domain names was not yet in wide spread use.
In 1984, Mark Kent, one of Gene's grad students, with help from Ray Tuminaro, Mark Crispin and Dan Kolkowitz, wrote software that used Gene's list in an email forwarding service. Mail sent to
na.name@su-score
would be forwarded to the person with that last name. And email sent to
na@su-score
would be forwarded to everyone on the list.
Gene and Mark Kent began to gather contributions together and send the collection out periodically. By February 1987, this had evolved into a moderated weekly newsletter. Gene dubbed these email services the NA-Net.
Nick Trefethen has this memory.
Early in the days of email, domain names were all over the place. I think there was a period when Gene was using xxx.na for the names of numerical analysts. Then somebody decided addresses should end with the country, giving us .uk and .fr and .ch and all that. For a period, we found that a lot of our numerical analysis emails were being directed to Namibia!
In 1987, Gene asked me to moderate NA-Digest temporarily while he went on a sabbatical. That temporary position ultimately lasted 18 years, until 2005.
Jack and Eric
Jack Dongarra began his career at Argonne National Laboratory. Jack's colleague, Eric Grosse, began his career at Bell Labs. In 1984, Jack and Eric created Netlib, a software repository and distribution service, and merged it with NA-Net. In 1989, Jack and the NA-Net system moved from Argonne to Oak Ridge National Lab and the University of Tennessee.
Keith Moore, at the University of Tennessee, rewrote the NA-Net software and maintained the servers for many years.
Gerald Ragghianti, the Technical Services Leader at Tennessee's Innovative Computer Lab, currently maintains the NA-Net software and servers.
Tammy and Danny
In 2005, I asked Tammy Kolda, who was then at Sandia Labs in Livermore, to be the NA-Digest editor. Tammy's Wikipedia page reveals that her given name is \"Tamara\", but everybody calls her \"Tammy\". She left Sandia is 2021 and now has her own consulting company, MathSci.ai.
In 2010, Tammy recommended that Danny Dunlavy, from Sandia Labs in Albuquerque, take over as editor. He has been the editor for 14 years. Danny's day job at Sandia's Center for Computing Research involves a wide range of fields including computer architecture, cognitive modeling and discrete mathematics.
When I succeeded Gene as editor in 1987, there were about 800 names on the NA-Net mailing list. Today, in 2024, there are a little over 10,000. Discontinuities in the size of the list result when unused and illegitimate names are removed.
Important Postings
I have made three personally important announcements in the Digest over the years.
October 29, 1989
In 1989 I was working at Ardent Computer, a startup in Silicon Valley. I announced in NA-Digest that MathWorks was looking for a numerical analyst. (Note the MathWorks telephone number near the end of this announcement.)
From: Cleve Moler <na.moler@na-net.stanford.edu> Date: Sun Oct 29 10:39:38 PST 1989 Subject: Positions at The MathWorks
The MathWorks is the company which develops and markets MATLAB. The company currently employs about 30 people and expects to add three or four more soon. The company headquarters is in East Natick, Massachusetts, which is about a half hour drive west of Boston.
The background and interests expected for the various positions available range from numerical linear algebra and matrix computation to systems programming and graphics. Educational level and experience expected range from inexperienced beginner willing to learn to seasoned Ph.D. with a personal library of M-files.
For more information, send email to na.moler@na-net.stanford.edu or phone me at 408-732-0400. Or, contact the MathWorks' president, John Little, with email to jnl@mathworks.com, phone 508-653-1415, or write to:
The MathWorks 21 Eliot Street South Natick, MA 01760
November 26, 1989
Shortly after that announcement, Ardent imploded and I said that I was taking the job myself.
From: Cleve Moler <moler@mathworks.com> Date: Sun Nov 26 09:16:32 PST 1989 Subject: Change of Address for Moler
A couple of weeks ago, I made an announcement here that The MathWorks, the MATLAB company, was looking to fill several positions, including one for a numerical analyst. Now, I've decided to take that slot myself. I'm one of the founders of MathWorks, and have always been a consultant to the company, but now I'll be a full time employee. For a while at least, I'll be working out of my home in California, even though MathWorks headquarters is in Massachusetts. (There are already a couple of other MathWorks developers in the Bay Area.) . . . My electronic address is \"moler@mathworks.com\". If your mailer can't find the route via uunet to mathworks.com, you can still use \"na.moler@na-net.stanford.edu\".
November 16, 2007
In November 2007 I was attending the Super Computing conference in Reno. I had rented a car and intended to drive to the Bay Area after the conference. But my wife called me and said, \"Hey Cleve, have you heard that Gene is in the hospital?\" I left SC immediately and drove to Palo Alto. Two days later we sent out a special issue of the Digest:
Gene Golub, founder of the NA Digest, passed away today, Friday, November 16, at the Stanford University Hospital. He was 75 years old.
Gene returned home to Stanford recently from a trip to Hong Kong. He was planning to leave again Tuesday on another trip, this one to Zurich where the ETH was to honor him with a special degree. Instead, Sunday night he went to the emergency room because he was \"feeling lousy\". On Tuesday, he was found to have AML, acute myelogenous leukemia, a form of cancer that affects the white blood cells. This is a potentially curable disease and he was expecting to begin chemotherapy today. But serious complications developed suddenly over night.
I was able to see Gene for an hour last night and he was in reasonably good spirits. Mike Saunders was trying to get Gene's laptop to use dial-up over the hospital's phone system because Gene said he was a couple of days behind on his email. I was planning to get a wireless card for his machine today. None of us had any idea how suddenly the situation would worsen.
The Stanford ICME students have created a memorial blog at http://genehgolub.blogspot.com .
Our community has lost its foremost member. He was a valued colleague and friend. Goodbye, Gene.
-- Cleve Moler
Thanks
Gene Golub and Mark Kent for creating NA-Digest and NA-Net.
Tammy Kolda and Danny Dunlavy for editing the Digest for two decades.
Jack Dongarra, Eric Grosse, Keith Moore and Geri Ragghianti for creating Netlib and for hosting the system for four decades.
David Bindel and Alex Townsend for joining this team.
",
+ "url": "https://hpc.social/commercial-blog/2024/na-digest-and-na-net/",
+
+
+
+
+
+ "date_published": "2024-08-31T21:44:36-06:00",
+ "date_modified": "2024-08-31T21:44:36-06:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2024/a-treacherous-svd/",
+ "title": "A Treacherous SVD",
+ "summary": null,
+ "content_text": "A few days ago, a bug report from our office in Cambridge caught my attention. Computing the singular values and singular vectors of a particular matrix would sometimes cause MATLAB to crash.ContentsTwo ComputersMath LibrariesG3366394RankZero rowsFuzzFlipNow what?Two ComputersI use two different two computers regularly. The machine in my home office is a Lenovo ThinkPad® model T14, loaded with two external monitors, several external disc drives, a sound bar and a dedicated internet connection. My traveling machine is a Lenovo ThinkPad X1 Nano with no external hardware.The report of a crash in the SVD became even more interesting when I found that it happens on my office computer, but not on the portable. A quick check revealed that the CPUs on the two machines come from different manufacturers. The office computer uses an AMD® Ryzen Pro 5 while the traveling machine uses an Intel® Core i7.Math LibrariesThe crash occurs several software layers deep in CGESVD, the LAPACK driver for single precision complex SVD. Various chip manufacturers provide math libraries that have been optimized for their CPUs. However, by default, MATLAB uses the reportedly faster Intel Math Kernel Library, MKL. It is possible to switch to other math libraries.We have experts at MathWorks who know far more about the details of these libraries than I do. They will soon sort this all out. In the meantime, here is what I have learned about the offending matrix.G3366394We refer to the matrix in the crash report by its case number in our bug tracking system. The matrix is of modest size but is otherwise unusual for several reasons. It is rectangular with fewer rows than columns, it is in single precision, and it is complex. clear load g3366394 X whos Name Size Bytes Class Attributes X 219x384 672768 single complexThe following code calling SVD with three outputs will crash MATLAB on my T14, but not on my X1. trysvd = false if trysvd [U,S,V] = svd(X); R = U*S*V' - X; relres = norm(R)/norm(X) end trysvd = logical 0RankComputing the singular values without the vectors can be done on either machine. The following code uses double precision and then plots the singular values on a logarithmic scale with a line at single precision roundoff level. S = svd(X); semilogy(S,'.-') ep = eps('single'); line([0 230],[ep ep]) axis([0 230 1e-15 10]) legend({'singular values','eps(''single'')'}) We see that the matrix is far from full rank. About half of its singular values are negligible. This is confirmed by xrank = rank(X) xrank = 110Zero rowsThe cause of the low rank is easy to find. This surf plot reveals that almost half of the rows are flat zero. Let's remove the zero rows. c = sum(abs(X),2)==0; nnzc = nnz(c) X(c>0,:) = []; nnzc = 109 The remaining matrix is full rank and it is safe to compute its singular vectors. [U,S,V] = svd(X); R = U*S*V' - X; resnorm = norm(R) resnorm = 2.8191e-06FuzzRemoving the zero rows was the first work-around that I tried. There are many others. You can replace the zeros with any nonzero \"fuzz\". fuzz = 1.e-20; [U,S,V] = svd(X + fuzz*randn(size(X))); resnorm = norm(U*S*V'-X) resnorm = 2.8222e-06FlipYou can reorder the matrix so that the zero rows are not at the beginning. [U,S,V] = svd(flipud(X)); U = flipud(U); resnorm = norm(U*S*V'-X) resnorm = 2.3809e-06Now what?How to avoid the crash is not the most important question. What causes the crash with the original matrix? We will find out and get it fixed.Get the MATLAB code (requires JavaScript) Published with MATLAB® R2024a",
+ "content_html": "
A few days ago, a bug report from our office in Cambridge caught my attention. Computing the singular values and singular vectors of a particular matrix would sometimes cause MATLAB to crash.
I use two different two computers regularly. The machine in my home office is a Lenovo ThinkPad® model T14, loaded with two external monitors, several external disc drives, a sound bar and a dedicated internet connection. My traveling machine is a Lenovo ThinkPad X1 Nano with no external hardware.
The report of a crash in the SVD became even more interesting when I found that it happens on my office computer, but not on the portable. A quick check revealed that the CPUs on the two machines come from different manufacturers. The office computer uses an AMD® Ryzen Pro 5 while the traveling machine uses an Intel® Core i7.
Math Libraries
The crash occurs several software layers deep in CGESVD, the LAPACK driver for single precision complex SVD. Various chip manufacturers provide math libraries that have been optimized for their CPUs. However, by default, MATLAB uses the reportedly faster Intel Math Kernel Library, MKL. It is possible to switch to other math libraries.
We have experts at MathWorks who know far more about the details of these libraries than I do. They will soon sort this all out. In the meantime, here is what I have learned about the offending matrix.
G3366394
We refer to the matrix in the crash report by its case number in our bug tracking system. The matrix is of modest size but is otherwise unusual for several reasons. It is rectangular with fewer rows than columns, it is in single precision, and it is complex.
clear load g3366394 X whos
Name Size Bytes Class Attributes X 219x384 672768 single complex
The following code calling SVD with three outputs will crash MATLAB on my T14, but not on my X1.
trysvd = false if trysvd [U,S,V] = svd(X); R = U*S*V' - X; relres = norm(R)/norm(X) end
trysvd = logical 0
Rank
Computing the singular values without the vectors can be done on either machine. The following code uses double precision and then plots the singular values on a logarithmic scale with a line at single precision roundoff level.
S = svd(X); semilogy(S,'.-') ep = eps('single'); line([0 230],[ep ep]) axis([0 230 1e-15 10]) legend({'singular values','eps(''single'')'})
We see that the matrix is far from full rank. About half of its singular values are negligible. This is confirmed by
xrank = rank(X)
xrank = 110
Zero rows
The cause of the low rank is easy to find. This surf plot reveals that almost half of the rows are flat zero.
Let's remove the zero rows.
c = sum(abs(X),2)==0; nnzc = nnz(c) X(c>0,:) = [];
nnzc = 109
The remaining matrix is full rank and it is safe to compute its singular vectors.
",
+ "url": "https://hpc.social/commercial-blog/2024/a-treacherous-svd/",
+
+
+
+
+
+ "date_published": "2024-07-15T15:39:04-06:00",
+ "date_modified": "2024-07-15T15:39:04-06:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2024/supersum-in-defense-of-floating-point-arithmetic/",
+ "title": "SuperSum, In Defense of Floating Point Arithmetic",
+ "summary": null,
+ "content_text": "Floating point arithmetic doesn't get the respect it deserves. Many people consider it mysterious, fuzzy, unpredictable. These misgivings often occur in discussion of vector sums. Our provocatively named SuperSum is intended to calm these fears.ContentsLedgersChecksumsOrderSpeedThree SumsToy ExampleSecond TestConclusionLedgersA ledger is a list of transactions in an account. Auditing the ledger involves comparing the total of the items with the change in the account balance.If v is a vector of transaction amounts, then we need to computesum(v)If this sum is equal to the change in the balance, then it is reasonable to assume that the ledger is correct. If not, the ledger must be examined line-by-line.ChecksumsHave you ever used a checksum for a file transfer? One checksum is computed before the file is sent. After the file has been sent over a questionable channel, a second checksum is computed on the receiving end. If the two checksums agree, the transmission was probably okay. If not, the file must be sent again.OrderFloating point addition is not associative. This means(a + b) + cis not necessarily the same asa+(b+c).So the order of doing a computation is important.Computers are deterministic devices. If the same computation is done in the same order more than once, the results must be the same. If you get different sums from different runs on a fixed computer, then it must be because the order has been changed.SpeedIn recent years, we have made the built-in function sum(x) faster by parallelizing it. The input vector is broken into several pieces, the sum of each piece is computed separately and simultaneously, then the partial sums are combined to give the final result. If the number and size of the pieces varies from run to run, the order varies and consequently the computed sums may vary.Three SumsHere are three replacements for nansum(x), the version of sum(x) that skips over NaNs and infs.simplesumAvoid the effect of blocking in the built-in sum(x).function s = simplesum(x) % simplesum. s = simplesum(x), for vector(x). % Force sequential order for sum(x). % Skips NaNs and infs. s = 0; for k = 1:length(x) if isfinite(x(k)) s = s + x(k); end endendKahanSumThis is the Kahan summation algorithm. The sum is accumulated in two words, the more significant s and the correction c. If you were able to form s + c exactly, it would be more accurate than s alone.function s = KahanSum(x) % KahanSum. s = KahanSum(x), for vector(x). % More accurate, but slower, than sum(x). % Skips NaNs and infs. % https://en.wikipedia.org/wiki/Kahan_summation_algorithm. s = 0; % sum c = 0; % correction for k = 1:length(x) if isfinite(x(k)) y = x(k) - c; t = s + y; c = (t - s) - y; s = t; end endendSuperSumI gave it a pretentious name to grab attention. Use extended precision, with enough digits to hold any MATLAB double.function s = SuperSum(x) % SuperSum. s = SuperSum(x), for vector(x). % Symbolic Math Toolbox extended precision. % Skips NaNs and infs. % % 632 decimal digits holds every IEEE-754 double. % 632 = ceil(log10(realmax) - log10(eps*realmin)); % din = digits(632); % Remember current setting s = double(sum(sym(x(isfinite(x)),'D'))); digits(din) % RestoreendToy ExampleA test case here at MathWorks, known by a French-Canadian name that translates to \"toy example\", has a vector e2 of length 4243 and values that range from -3.3e7 to 6.8e9.When running tests involving floating point numbers it is a good idea to set the output format to hex so we can see every last bit.format hexload jeuTest e2x = e2;[nansum(x) simplesum(x) KahanSum(x) SuperSum(x)]ans = 423785e8206150e2 423785e8206150e0 423785e8206150e1 423785e8206150e1For jeuTest, Kahan summation gets the same result as SuperSum, while nansum and simplesum differ in the last bit or two.Second TestThe vector length is only three, but the third term completely cancels the first, and the second term rises from obscurity. In this situation, KahanSum is no more accurate than sum.format hexx = [1 1e-14 -1]'[nansum(x) simplesum(x) KahanSum(x) SuperSum(x)]x = 3ff0000000000000 3d06849b86a12b9b bff0000000000000ans = 3d06800000000000 3d06800000000000 3d06800000000000 3d06849b86a12b9bConclusionI will leave careful timing for another day. Let's just say that in situations like jeuTest, KahanSum is probably all you need. It is usually more accurate than sum, and not much slower.However, for complete reliability, use SuperSum. There is no substitute for the right answer.Get the MATLAB code (requires JavaScript) Published with MATLAB® R2024a",
+ "content_html": "
Floating point arithmetic doesn't get the respect it deserves. Many people consider it mysterious, fuzzy, unpredictable. These misgivings often occur in discussion of vector sums. Our provocatively named SuperSum is intended to calm these fears.
A ledger is a list of transactions in an account. Auditing the ledger involves comparing the total of the items with the change in the account balance.
If v is a vector of transaction amounts, then we need to compute
sum(v)
If this sum is equal to the change in the balance, then it is reasonable to assume that the ledger is correct. If not, the ledger must be examined line-by-line.
Checksums
Have you ever used a checksum for a file transfer? One checksum is computed before the file is sent. After the file has been sent over a questionable channel, a second checksum is computed on the receiving end. If the two checksums agree, the transmission was probably okay. If not, the file must be sent again.
Order
Floating point addition is not associative. This means
(a + b) + c
is not necessarily the same as
a+(b+c).
So the order of doing a computation is important.
Computers are deterministic devices. If the same computation is done in the same order more than once, the results must be the same. If you get different sums from different runs on a fixed computer, then it must be because the order has been changed.
Speed
In recent years, we have made the built-in function sum(x) faster by parallelizing it. The input vector is broken into several pieces, the sum of each piece is computed separately and simultaneously, then the partial sums are combined to give the final result. If the number and size of the pieces varies from run to run, the order varies and consequently the computed sums may vary.
Three Sums
Here are three replacements for nansum(x), the version of sum(x) that skips over NaNs and infs.
simplesum
Avoid the effect of blocking in the built-in sum(x).
function s = simplesum(x) % simplesum. s = simplesum(x), for vector(x). % Force sequential order for sum(x). % Skips NaNs and infs.
s = 0; for k = 1:length(x) if isfinite(x(k)) s = s + x(k); end endend
KahanSum
This is the Kahan summation algorithm. The sum is accumulated in two words, the more significant s and the correction c. If you were able to form s + c exactly, it would be more accurate than s alone.
function s = KahanSum(x) % KahanSum. s = KahanSum(x), for vector(x). % More accurate, but slower, than sum(x). % Skips NaNs and infs. % https://en.wikipedia.org/wiki/Kahan_summation_algorithm.
s = 0; % sum c = 0; % correction for k = 1:length(x) if isfinite(x(k)) y = x(k) - c; t = s + y; c = (t - s) - y; s = t; end endend
SuperSum
I gave it a pretentious name to grab attention. Use extended precision, with enough digits to hold any MATLAB double.
function s = SuperSum(x) % SuperSum. s = SuperSum(x), for vector(x). % Symbolic Math Toolbox extended precision. % Skips NaNs and infs. % % 632 decimal digits holds every IEEE-754 double. % 632 = ceil(log10(realmax) - log10(eps*realmin)); % din = digits(632); % Remember current setting s = double(sum(sym(x(isfinite(x)),'D'))); digits(din) % Restoreend
Toy Example
A test case here at MathWorks, known by a French-Canadian name that translates to \"toy example\", has a vector e2 of length 4243 and values that range from -3.3e7 to 6.8e9.
When running tests involving floating point numbers it is a good idea to set the output format to hex so we can see every last bit.
format hexload jeuTest e2x = e2;
[nansum(x) simplesum(x) KahanSum(x) SuperSum(x)]
ans = 423785e8206150e2 423785e8206150e0 423785e8206150e1 423785e8206150e1
For jeuTest, Kahan summation gets the same result as SuperSum, while nansum and simplesum differ in the last bit or two.
Second Test
The vector length is only three, but the third term completely cancels the first, and the second term rises from obscurity. In this situation, KahanSum is no more accurate than sum.
format hexx = [1 1e-14 -1]'
[nansum(x) simplesum(x) KahanSum(x) SuperSum(x)]
x = 3ff0000000000000 3d06849b86a12b9b bff0000000000000
ans = 3d06800000000000 3d06800000000000 3d06800000000000 3d06849b86a12b9b
Conclusion
I will leave careful timing for another day. Let's just say that in situations like jeuTest, KahanSum is probably all you need. It is usually more accurate than sum, and not much slower.
However, for complete reliability, use SuperSum. There is no substitute for the right answer.
",
+ "url": "https://hpc.social/commercial-blog/2024/supersum-in-defense-of-floating-point-arithmetic/",
+
+
+
+
+
+ "date_published": "2024-06-27T17:54:38-06:00",
+ "date_modified": "2024-06-27T17:54:38-06:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2024/ibm-hexadecimal-floating-point/",
+ "title": "IBM Hexadecimal Floating Point",
+ "summary": null,
+ "content_text": "Our technical support group recently received a request for a tool that would convert IBM System/360 hexadecimal floating point numbers to the IEEE-754 format. I am probably the only one left at MathWorks that actually used IBM mainframe computers. I thought we had seen the last of hexadecimal arithmetic years ago. But, it turns out that the hexadecimal floating point format is alive and well.ContentsIBM System/360FormatsDataHex_ieeeieee2ibmibm2ieeeExamplesComparisonSoftwareIBM System/360The System/360 is a family of mainframe computers that IBM introduced in 1965 and that dominated the computer industry until PCs came along twenty years later. They range in size from desk-sized to systems that fill a large room.Here is a photo of a mid-sized model. System/360, Model 60. Photo from Ken Shirrif's blog, IBM 360/System Summary.The System/360 architecture is byte-oriented, so it can handle business data processing as well as scientific and engineering computation. This leads to base-16, rather than base-2 or base-10, floating point arithmetic.* Binary f*2^e 1/2<=f<1* Decimal f*10^e 1/10<=f<1* Hexadecimal f*16^e 1/16<=f<1FormatsFloating point formats played an important role in technical computing in the early days. This table from FMM lists formats that were in use in the 1970s, before IEEE-754 was introduced in 1985. DataThe System/360 hexadecimal format is used in many industries for the preservation of data files.CREWES. Teaching exploration seismology. Comprehensive MATLAB toolbox for use with the textbook \"Numerical Methods of Exploration Seismology with algorithms in Matlab\" by Gary F. Margrave, a geoscience professor at the University of Calgary.Library of Congress. Government.NASA. Astronautics.SAS. Statistics and business analytics. SAS wrapers for C.Enthought. Python wrappers for C.Hex_ieee Hex_ieee. I have two twenty-line MATLAB functions, ieee2ibm and ibm2ieee, that convert IEEE-754 floating point to and from IBM hexadecimal format.Three statements in the middle of ieee2ibm are the key to the entire operation. The first statement is [~,e] = log2(x)With two output arguments, log2 returns the mantissa and exponent of an IEEE-754 floating point number. The mantissa is not needed here.The second key statement e = ceil(e/4)makes e divisible by 4. This turns e into the appropriate hexadecimal exponent so that the third statement f = x.*16.^(-e)can produce the hexadecimal mantissa.ieee2ibmfunction z = ieee2ibm(x) Convert IEEE-754 to IBM System 360 hexadecimal. z = ieee2ibm(x) Input x, real column vector. Output z, length(x)-by-16 char. Example: ieee2ibm(-118.625) = 'C276A00000000000'. s = sign(x); % -1, 0, or 1 x = abs(x); x(x < 16^(-65)) = 0; % Underflow x(x >= 16^63) = (1-eps/2)*16^63; % Overflow [~,e] = log2(x); % base 2 exponent e = ceil(e/4) % base 16 exponent f = x.*16.^(-e); % base 16 mantissa E = uint64((e+64)*2^56); % Assemb1e output F = uint64(f*2^56); S = uint64((1-s)*2^62); % 1 or 0 z = dec2hex(S + E + F); % z = 'ZZFFFFFFFFFFFFFF'endibm2ieeefunction x = ibm2ieee(z) Convert IBM System 360 hexadecimal to IEEE-754. x = ibm2ieee(z) Input z, n-by-16 char. Output x, n-by-1 double. Example: ibm2ieee('C276A00000000000') = -118.625. E = hex2dec(z(:,1:2)); % Disassemble input F1 = hex2dec(z(:,3:8)); % < 16^6 F2 = hex2dec(z(:,9:end)); % < 16^8 s = sign(128-E); % -1 or 1 e = E-(s>0)*64-(s<0)*192; % base 16 exponent f = F1/16^6 + F2/16^14; % base 16 mantissa x = s.*f.*16.^e;endExamplesUnderflow. Anything < 16^(-65) is too small and is flushed to zero. There are no denormals.Overflow. Anything >= 16^63 is too large. There is no inf or NaN.* 1.0 4110000000000000* 0.1 401999999999999A* -pi C13243F6A8885A30* 5.3976e-79 0010000000000000* 7.2370e+75 7FFFFFFFFFFFFFF8ComparisonS/360 hexadecimal has 7 exponent bits, while IEEE-754 has 11. Consequently, hexadecimal has a much smaller range, 5.4e-79 to 7.2e+75 versus 2.2e-308 to 1.8e+308.The base-16 normalization implies that hexadecimal effectively has between 53 and 56 mantissa bits. Counting the hidden bit, IEEE-754 also has 53. So, the accuracy of the two is pretty much the same.SoftwareMy functions ieee2ibm and ieee2ibm described above, modified to handle both single and double, plus hex_test, which does what its name implies, are available at Hex_ieee.Homework: What happens?ok = 0;for k = 1:10 x = single(k/10); ok(k) = hex_test(x);endokGet the MATLAB code (requires JavaScript) Published with MATLAB® R2024a",
+ "content_html": "
Our technical support group recently received a request for a tool that would convert IBM System/360 hexadecimal floating point numbers to the IEEE-754 format. I am probably the only one left at MathWorks that actually used IBM mainframe computers. I thought we had seen the last of hexadecimal arithmetic years ago. But, it turns out that the hexadecimal floating point format is alive and well.
The System/360 is a family of mainframe computers that IBM introduced in 1965 and that dominated the computer industry until PCs came along twenty years later. They range in size from desk-sized to systems that fill a large room.
Here is a photo of a mid-sized model.
System/360, Model 60.Photo from Ken Shirrif's blog, IBM 360/System Summary.
The System/360 architecture is byte-oriented, so it can handle business data processing as well as scientific and engineering computation. This leads to base-16, rather than base-2 or base-10, floating point arithmetic.
Floating point formats played an important role in technical computing in the early days. This table from FMM lists formats that were in use in the 1970s, before IEEE-754 was introduced in 1985.
Data
The System/360 hexadecimal format is used in many industries for the preservation of data files.
CREWES. Teaching exploration seismology. Comprehensive MATLAB toolbox for use with the textbook \"Numerical Methods of Exploration Seismology with algorithms in Matlab\" by Gary F. Margrave, a geoscience professor at the University of Calgary.
Hex_ieee. I have two twenty-line MATLAB functions, ieee2ibm and ibm2ieee, that convert IEEE-754 floating point to and from IBM hexadecimal format.
Three statements in the middle of ieee2ibm are the key to the entire operation. The first statement is
[~,e] = log2(x)
With two output arguments, log2 returns the mantissa and exponent of an IEEE-754 floating point number. The mantissa is not needed here.
The second key statement
e = ceil(e/4)
makes e divisible by 4. This turns e into the appropriate hexadecimal exponent so that the third statement
f = x.*16.^(-e)
can produce the hexadecimal mantissa.
ieee2ibm
function z = ieee2ibm(x) Convert IEEE-754 to IBM System 360 hexadecimal. z = ieee2ibm(x) Input x, real column vector. Output z, length(x)-by-16 char. Example: ieee2ibm(-118.625) = 'C276A00000000000'.
s = sign(x); % -1, 0, or 1 x = abs(x); x(x < 16^(-65)) = 0; % Underflow x(x >= 16^63) = (1-eps/2)*16^63; % Overflow
[~,e] = log2(x); % base 2 exponent e = ceil(e/4) % base 16 exponent f = x.*16.^(-e); % base 16 mantissa
E = uint64((e+64)*2^56); % Assemb1e output F = uint64(f*2^56); S = uint64((1-s)*2^62); % 1 or 0 z = dec2hex(S + E + F); % z = 'ZZFFFFFFFFFFFFFF'end
ibm2ieee
function x = ibm2ieee(z) Convert IBM System 360 hexadecimal to IEEE-754. x = ibm2ieee(z) Input z, n-by-16 char. Output x, n-by-1 double. Example: ibm2ieee('C276A00000000000') = -118.625.
E = hex2dec(z(:,1:2)); % Disassemble input F1 = hex2dec(z(:,3:8)); % < 16^6 F2 = hex2dec(z(:,9:end)); % < 16^8 s = sign(128-E); % -1 or 1
e = E-(s>0)*64-(s<0)*192; % base 16 exponent f = F1/16^6 + F2/16^14; % base 16 mantissa x = s.*f.*16.^e;end
Examples
Underflow. Anything < 16^(-65) is too small and is flushed to zero. There are no denormals.
Overflow. Anything >= 16^63 is too large. There is no inf or NaN.
S/360 hexadecimal has 7 exponent bits, while IEEE-754 has 11. Consequently, hexadecimal has a much smaller range, 5.4e-79 to 7.2e+75 versus 2.2e-308 to 1.8e+308.
The base-16 normalization implies that hexadecimal effectively has between 53 and 56 mantissa bits. Counting the hidden bit, IEEE-754 also has 53. So, the accuracy of the two is pretty much the same.
Software
My functions ieee2ibm and ieee2ibm described above, modified to handle both single and double, plus hex_test, which does what its name implies, are available at Hex_ieee.
Homework: What happens?
ok = 0;for k = 1:10 x = single(k/10); ok(k) = hex_test(x);endok
",
+ "url": "https://hpc.social/commercial-blog/2024/ibm-hexadecimal-floating-point/",
+
+
+
+
+
+ "date_published": "2024-05-25T15:51:21-06:00",
+ "date_modified": "2024-05-25T15:51:21-06:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2024/a-sixty-year-old-program-for-predicting-the-future/",
+ "title": "A Sixty-Year Old Program for Predicting the Future",
+ "summary": null,
+ "content_text": "The graphics in my post about R^2 were produced by an updated version of a sixty-year old program involving the U.S. census. Originally, the program was based on census data from 1900 to 1960 and sought to predict the population in 1970. The software back then was written in Fortran, the predominate technical programming language a half century ago. I have updated the MATLAB version of the program so that it now uses census data from 1900 to 2020.Contentscensusapp2024Risky BusinessSplinesExponentialsPredictionsConclusionBlogsFMMSoftwarecensusapp2024The latest version of the census application is now available at censusapp2024. Here are the data and the opening screenshot.[t,p]=UScensus;fprintf('%12d%12.3f\\n',[t,p]') 1900 75.995 1910 91.972 1920 105.711 1930 123.203 1940 131.669 1950 150.697 1960 179.323 1970 203.212 1980 226.505 1990 249.633 2000 281.422 2010 308.746 2020 331.449 Risky BusinessToday, MATLAB makes it easier to vary parameters and visualize results, but the underlying mathematical principles are unchanged:Using polynomials to predict the future by extrapolating data is a risky business.One new observation is added to the data every 10 years, when the United States does the decennial census. Originally there were only 7 observations; today there are 13. The program now allows you to fit the data exactly by interpolation with a polynomial of degree 12 or fit it approximately by polynomials of degree less than 12.Here are the least-squares fits with linear, cubic, and degree seven polynomials and the interpolating polynomial. As the polynomial degree increases, so does R^2, until R^2 reaches one with the exact fit.Do any of these fits look like they could be used to predict future population growth? SplinesIn addition to polynomials, you can choose interpolation by three different piecewise Hermite cubics.spline Continuous second derivate, \"not-a-knot\" end condition.pchip Continuous first derivative, strictly shape-preserving.makima Continuous first derivative, relaxed shape-preserving.Since these fits interpolate the data, all their R^2 values are one. But before 1900 and after 2020 these functions are cubic polynomials that are not designed for extrapolation. ExponentialsIt is also possible to do nonlinear least squares fits by an exponential, a logistic sigmoid, and an exponential of an exponetial known as the Gompertz model.exponential exp(b*t+c)logistic a./(1+exp(-b*(t-c)))gompertz a*exp(-b*exp(-c*t))An article by Kathleen and Even Tjørve, from the Inland Norway University of Applied Sciences in Elverum, Norway, in the journal PLOS ONE has this to say about Gompertz. \"The Gompertz model has been in use as a growth model even longer than its better known relative, the logistic model. The model, referred to at the time as the Gompertz theoretical law of mortality, was first suggested and first applied by Mr. Benjamin Gompertz in 1825. He fitted it to the relationship between increasing death rate and age, what he referred to as 'the average exhaustions of a man’s power to avoid death” or the 'portion of his remaining power to oppose destruction.' \" PredictionsWhich fits are suitable for predicting future population size?Despite their large R^2 values, polynomials of any degree are not suitable because outside of the time interval they behave like polynomials and do not provide realistic predictions.Splines were never intended for extrapolation.That leaves the exponentials. The simple exponential model grows exponentially and is not suitable. The Gompertz fit does approach a finite asymptotic limit, but the value is an astronimical a = 2101, corresponding to 2.1 $\\times 10^9$ inhabitants. Hopefully, that is out of the question.The logistic fit has an asymptotic limit of a = 655.7. We recently passed the value of t where p(t) reaches a/2, namely c = 2018. So, the logistic model predicts that the long-term size of the U.S. population will be about twice its current value. Is that realistic? Probably not. ConclusionThe British statistician George Box once said, \"all models are wrong, some are useful.\" This is true of the models of the U. S. Census that I have discussed over the past sixty years.Here is censusapp2024 after all its buttons have been pushed. The extrapolation date is set to 2040. White noise has been added to the data. The model is a fourth-degree polynomial with an R^2 = 0.99. The R^2 value and the error estimates produced by errs account for errors in the data, but not in the model.This particular model does a lousy job of predicting even twenty years in the future. Some of the other models are better, many are worse. Hopefully, their study is worthwhile. BlogsI have made blog posts about the census before, in 2020 and in 2017.FMMPredicting population growth is featured in Computer Methods for Mathematical Computations, by George Forsythe, Mike Malcolm and myself, published by Prentice-Hall in 1977. That textbook is now available from an interesting smorgasbord of sources, including Google Scholar, Amazon, dizhasneatstuff, Abe Books, Internet Archive, PDAS, WorldCat (Chinese).Softwarecensusapp2024 is available at censusapp2024.Get the MATLAB code (requires JavaScript) Published with MATLAB® R2024a",
+ "content_html": "
The graphics in my post about R^2 were produced by an updated version of a sixty-year old program involving the U.S. census. Originally, the program was based on census data from 1900 to 1960 and sought to predict the population in 1970. The software back then was written in Fortran, the predominate technical programming language a half century ago. I have updated the MATLAB version of the program so that it now uses census data from 1900 to 2020.
Today, MATLAB makes it easier to vary parameters and visualize results, but the underlying mathematical principles are unchanged:
Using polynomials to predict the future by extrapolating data is a risky business.
One new observation is added to the data every 10 years, when the United States does the decennial census. Originally there were only 7 observations; today there are 13. The program now allows you to fit the data exactly by interpolation with a polynomial of degree 12 or fit it approximately by polynomials of degree less than 12.
Here are the least-squares fits with linear, cubic, and degree seven polynomials and the interpolating polynomial. As the polynomial degree increases, so does R^2, until R^2 reaches one with the exact fit.
Do any of these fits look like they could be used to predict future population growth?
Splines
In addition to polynomials, you can choose interpolation by three different piecewise Hermite cubics.
spline Continuous second derivate, \"not-a-knot\" end condition.
pchip Continuous first derivative, strictly shape-preserving.
makima Continuous first derivative, relaxed shape-preserving.
Since these fits interpolate the data, all their R^2 values are one. But before 1900 and after 2020 these functions are cubic polynomials that are not designed for extrapolation.
Exponentials
It is also possible to do nonlinear least squares fits by an exponential, a logistic sigmoid, and an exponential of an exponetial known as the Gompertz model.
exponential exp(b*t+c)
logistic a./(1+exp(-b*(t-c)))
gompertz a*exp(-b*exp(-c*t))
An article by Kathleen and Even Tjørve, from the Inland Norway University of Applied Sciences in Elverum, Norway, in the journal PLOS ONE has this to say about Gompertz. \"The Gompertz model has been in use as a growth model even longer than its better known relative, the logistic model. The model, referred to at the time as the Gompertz theoretical law of mortality, was first suggested and first applied by Mr. Benjamin Gompertz in 1825. He fitted it to the relationship between increasing death rate and age, what he referred to as 'the average exhaustions of a man’s power to avoid death” or the 'portion of his remaining power to oppose destruction.' \"
Predictions
Which fits are suitable for predicting future population size?
Despite their large R^2 values, polynomials of any degree are not suitable because outside of the time interval they behave like polynomials and do not provide realistic predictions.
Splines were never intended for extrapolation.
That leaves the exponentials. The simple exponential model grows exponentially and is not suitable. The Gompertz fit does approach a finite asymptotic limit, but the value is an astronimical a = 2101, corresponding to 2.1 $\\times 10^9$ inhabitants. Hopefully, that is out of the question.
The logistic fit has an asymptotic limit of a = 655.7. We recently passed the value of t where p(t) reaches a/2, namely c = 2018. So, the logistic model predicts that the long-term size of the U.S. population will be about twice its current value. Is that realistic? Probably not.
Conclusion
The British statistician George Box once said, \"all models are wrong, some are useful.\" This is true of the models of the U. S. Census that I have discussed over the past sixty years.
Here is censusapp2024 after all its buttons have been pushed. The extrapolation date is set to 2040. White noise has been added to the data. The model is a fourth-degree polynomial with an R^2 = 0.99. The R^2 value and the error estimates produced by errs account for errors in the data, but not in the model.
This particular model does a lousy job of predicting even twenty years in the future. Some of the other models are better, many are worse. Hopefully, their study is worthwhile.
Blogs
I have made blog posts about the census before, in 2020 and in 2017.
FMM
Predicting population growth is featured in Computer Methods for Mathematical Computations, by George Forsythe, Mike Malcolm and myself, published by Prentice-Hall in 1977. That textbook is now available from an interesting smorgasbord of sources, including Google Scholar, Amazon, dizhasneatstuff, Abe Books, Internet Archive, PDAS, WorldCat (Chinese).
",
+ "url": "https://hpc.social/commercial-blog/2024/a-sixty-year-old-program-for-predicting-the-future/",
+
+
+
+
+
+ "date_published": "2024-05-19T16:55:03-06:00",
+ "date_modified": "2024-05-19T16:55:03-06:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2024/r-squared-is-bigger-better/",
+ "title": "R-squared. Is Bigger Better?",
+ "summary": null,
+ "content_text": "The coefficient of determination, R-squared or R^2, is a popular statistic that describes how well a regression model fits data. It measures the proportion of variation in data that is predicted by a model. However, that is all that R^2 measures. It is not appropriate for any other use. For example, it does not support extrapolation beyond the domain of the data. It does not suggest that one model is preferable to another.I recently watched high school students participate in the final round of a national mathematical modeling competition. The teams' presentations were excellent; they were well-prepared, mathematically sophisticated, and informative. Unfortunately, many of the presentations abused R^2. It was used to compare different fits, to justify extrapolation, and to recommend public policy.This was not the first time that I have seen abuses of R^2. As educators and authors of mathematical software, we must do more to expose its limitations. There are dozens of pages and videos on the web describing R^2, but few of them warn about possible misuse.R^2 is easily computed. If y is a vector of observations, f is a fit to the data and ybar = mean(y), then R^2 = 1 - norm(y-f)^2/norm(y-ybar)^2If the data are centered, then ybar = 0 and R^2 is between zero and one.One of my favorite examples is the United States Census. Here is the population, in millions, every ten years since 1900. t p ____ _______ 1900 75.995 1910 91.972 1920 105.711 1930 123.203 1940 131.669 1950 150.697 1960 179.323 1970 203.212 1980 226.505 1990 249.633 2000 281.422 2010 308.746 2020 331.449There are 13 observations. So, we can do a least-squares fit by a polynomial of any degree less than 12 and can interpolate by a polynomial of degree 12. Here are four such fits and the corresponding R^2 values. As the degree increases, so does R^2. Interpolation fits the data exactly and earns a perfect core.Which fit would you choose to predict the population in 2030, or even to estimate the population between census years?R2_census Thanks to Peter Perkins and Tom Lane for help with this post.Get the MATLAB code (requires JavaScript) Published with MATLAB® R2024a",
+ "content_html": "
The coefficient of determination, R-squared or R^2, is a popular statistic that describes how well a regression model fits data. It measures the proportion of variation in data that is predicted by a model. However, that is all that R^2 measures. It is not appropriate for any other use. For example, it does not support extrapolation beyond the domain of the data. It does not suggest that one model is preferable to another.
I recently watched high school students participate in the final round of a national mathematical modeling competition. The teams' presentations were excellent; they were well-prepared, mathematically sophisticated, and informative. Unfortunately, many of the presentations abused R^2. It was used to compare different fits, to justify extrapolation, and to recommend public policy.
This was not the first time that I have seen abuses of R^2. As educators and authors of mathematical software, we must do more to expose its limitations. There are dozens of pages and videos on the web describing R^2, but few of them warn about possible misuse.
R^2 is easily computed. If y is a vector of observations, f is a fit to the data and ybar = mean(y), then
R^2 = 1 - norm(y-f)^2/norm(y-ybar)^2
If the data are centered, then ybar = 0 and R^2 is between zero and one.
One of my favorite examples is the United States Census. Here is the population, in millions, every ten years since 1900.
There are 13 observations. So, we can do a least-squares fit by a polynomial of any degree less than 12 and can interpolate by a polynomial of degree 12. Here are four such fits and the corresponding R^2 values. As the degree increases, so does R^2. Interpolation fits the data exactly and earns a perfect core.
Which fit would you choose to predict the population in 2030, or even to estimate the population between census years?
R2_census
Thanks to Peter Perkins and Tom Lane for help with this post.
",
+ "url": "https://hpc.social/commercial-blog/2024/r-squared-is-bigger-better/",
+
+
+
+
+
+ "date_published": "2024-05-04T14:33:38-06:00",
+ "date_modified": "2024-05-04T14:33:38-06:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2024/closest-pair-of-points-problem/",
+ "title": "Closest Pair of Points Problem",
+ "summary": null,
+ "content_text": "The Closest Pair of Points problem is a standard topic in an algorithms course today, but when I taught such a course fifty years ago, the algorithm was not yet known.ContentsCalifornia DreamingClosest Pair of PointsPairsDivConCenterComplexityTimingSoftwareReferencesCalifornia DreamingImagine you are driving a car on the Harbor Freeway in southern California with typical Los Angeles traffic conditions. Among the many things you might want to know is which pair of vehicles is nearest each other.This is an instance of the Closest Pair of Points problem:Given the location of n points in the plane, which pair of points is closest to each other? Closest Pair of PointsIt is convenient to represent the points by a vector of complex values. The distance between points z(k) and z(j) is then d = abs(z(k) - z(j))Here are a few points in the unit square. The closest pair is highlighted. PairsThe first algorithm you might think of computes the distances between all possible pairs of points and finds the minimum. This is a brute force approach that requires only a few lines of code.function d = Pairs(z) % Pairs. % d = Pairs(z) is the minimum distance between any two elements % of the complex vector z. n = length(z); d = Inf; for k = 1:n for j = k+1:n if abs(z(k) - z(j)) < d d = abs(z(k) - z(j)); end end endendDivConDivCon stands for Divide and Conquer. In outline, the steps are:Divide the set of points into two halves.Recursively, find the closest pair in each half.Consider the case when the closest pair has one point in each half.Terminate the recursion with sets of two or three points.function d = DivCon(z,sorted) % DivCon. % d = DivCon(z) is the minimum distance between any two elements % of the complex vector z. % % d = DivCon(z,true) is a recursive call with ascending real(z). n = length(z); if n <= 3 d = Pairs(z); else if nargin < 2 || ~sorted [~,p] = sort(real(z)); z = z(p); end m = floor(n/2); % Left half dl = DivCon(z(1:m),true) % Right half dr = DivCon(z(m+1:end),true); % Choose d = min(dl,dr); % Center strip ds = Center(z,d); d = min(ds,d); endendCenterThe delicate case involves the strip of points near the center dividing line. The width of the strip is the closest distance found in the recursion. Any closer pair with one point in each half must be in this strip.function d = Center(z,d) % Center(z,d) is used by DivCon to examine the % strip of half-width d about the center point. n = length(z) m = floor(n/2); xh = real(z(m)); [~,p] = sort(imag(z)); z = z(p); s = []; for i = 1:n if abs(real(z(i)) - xh) < d s = [s; z(i)]; end end ns = length(s); for k = 1:ns for j = k+1:ns if (imag(s(j)) - imag(s(k))) < d && abs(s(k) - s(j)) < d d = abs(s(k) - s(j)); end end endendComplexityLet n be the number of points. An asymptotic execution-time complexity analysis involves n approaching infinity.It is not hard to see that the complexity of the brute force algorithm implemented in Pairs is O(n^2).There are dozens of pages on the web devoted to showing that the complexity of the divide and conquer algorithm implemented in DivCon and Center is O(n*log(n)). The best page that I have seen is the YouTube video by Ling Qi. The key to the analysis is showing that the inner loop in Center is executed at most 7 times for any n.TimingWe measured the execution time of Pairs(z) and DivCon(z) for n from 1,000 to 40,000 and computed the ratios of the two times. The complexity analysis predicts that this ratio is asymptotically O(n/log(n))Here are the timing results and a least square fit by n/log(n). SoftwareA self-extracting MATLAB archive is available at https://blogs.mathworks.com/cleve/files/TestDivCon_mzip.mReferencesLing Qi, IDeer7, Closest Pair of Points (Divide and Conquer) Explained. https://www.youtube.com/watch?v=6u_hWxbOc7E.Cormen, Thomas H.; Leiserson, Charles E.; Rivest, Ronald L.; Stein, Clifford. Introduction to Algorithms (4th ed.). MIT Press and McGraw-Hill. ISBN 0-262-04630-X. 1312 pp.Get the MATLAB code (requires JavaScript) Published with MATLAB® R2023a",
+ "content_html": "
The Closest Pair of Points problem is a standard topic in an algorithms course today, but when I taught such a course fifty years ago, the algorithm was not yet known.
Imagine you are driving a car on the Harbor Freeway in southern California with typical Los Angeles traffic conditions. Among the many things you might want to know is which pair of vehicles is nearest each other.
This is an instance of the Closest Pair of Points problem:
Given the location of n points in the plane, which pair of points is closest to each other?
Closest Pair of Points
It is convenient to represent the points by a vector of complex values. The distance between points z(k) and z(j) is then
d = abs(z(k) - z(j))
Here are a few points in the unit square. The closest pair is highlighted.
Pairs
The first algorithm you might think of computes the distances between all possible pairs of points and finds the minimum. This is a brute force approach that requires only a few lines of code.
function d = Pairs(z) % Pairs. % d = Pairs(z) is the minimum distance between any two elements % of the complex vector z.
n = length(z); d = Inf; for k = 1:n for j = k+1:n if abs(z(k) - z(j)) < d d = abs(z(k) - z(j)); end end endend
DivCon
DivCon stands for Divide and Conquer. In outline, the steps are:
Divide the set of points into two halves.
Recursively, find the closest pair in each half.
Consider the case when the closest pair has one point in each half.
Terminate the recursion with sets of two or three points.
function d = DivCon(z,sorted) % DivCon. % d = DivCon(z) is the minimum distance between any two elements % of the complex vector z. % % d = DivCon(z,true) is a recursive call with ascending real(z).
n = length(z); if n <= 3 d = Pairs(z); else if nargin < 2 || ~sorted [~,p] = sort(real(z)); z = z(p); end m = floor(n/2);
% Left half dl = DivCon(z(1:m),true)
% Right half dr = DivCon(z(m+1:end),true);
% Choose d = min(dl,dr);
% Center strip ds = Center(z,d); d = min(ds,d); endend
Center
The delicate case involves the strip of points near the center dividing line. The width of the strip is the closest distance found in the recursion. Any closer pair with one point in each half must be in this strip.
function d = Center(z,d) % Center(z,d) is used by DivCon to examine the % strip of half-width d about the center point.
n = length(z) m = floor(n/2); xh = real(z(m)); [~,p] = sort(imag(z)); z = z(p); s = []; for i = 1:n if abs(real(z(i)) - xh) < d s = [s; z(i)]; end end
ns = length(s); for k = 1:ns for j = k+1:ns if (imag(s(j)) - imag(s(k))) < d && abs(s(k) - s(j)) < d d = abs(s(k) - s(j)); end end endend
Complexity
Let n be the number of points. An asymptotic execution-time complexity analysis involves n approaching infinity.
It is not hard to see that the complexity of the brute force algorithm implemented in Pairs is O(n^2).
There are dozens of pages on the web devoted to showing that the complexity of the divide and conquer algorithm implemented in DivCon and Center is O(n*log(n)). The best page that I have seen is the YouTube video by Ling Qi. The key to the analysis is showing that the inner loop in Center is executed at most 7 times for any n.
Timing
We measured the execution time of Pairs(z) and DivCon(z) for n from 1,000 to 40,000 and computed the ratios of the two times. The complexity analysis predicts that this ratio is asymptotically
O(n/log(n))
Here are the timing results and a least square fit by n/log(n).
Cormen, Thomas H.; Leiserson, Charles E.; Rivest, Ronald L.; Stein, Clifford. Introduction to Algorithms (4th ed.). MIT Press and McGraw-Hill. ISBN 0-262-04630-X. 1312 pp.
",
+ "url": "https://hpc.social/commercial-blog/2024/closest-pair-of-points-problem/",
+
+
+
+
+
+ "date_published": "2024-03-28T20:00:00-06:00",
+ "date_modified": "2024-03-28T20:00:00-06:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2024/twenty-years-of-parallel-matlab/",
+ "title": "Twenty Years of Parallel MATLAB",
+ "summary": null,
+ "content_text": "I have just returned from the MathWorks company meeting celebrating our 40th Anniversary. In one of the presentations, Jos Martin described how Parallel MATLAB was introduced almost twenty years ago. Here are a few slides from Jos's talk.ContentsWhy There Wasn't Any Parallel MATLABTwenty-seven Parallel MATLABsDistributed Computing ToolboxSupercomputing ConferenceBill GatesNow There is a Parallel MATLABWhy There Wasn't Any Parallel MATLABIn MATLAB News and Notes for spring 1995, I wrote a one-page Cleve's Corner titled \"Why there isn't any parallel MATLAB.\" There were three reasons.Memory model. MATLAB would generate a matrix on a host machine, split it into roughly equally sized submatrices, and distribute each submatrix to a node. But it took far longer to distribute the data then it did to do the computation. Any matrix that would fit into memory on the host was too small to make effective use of the parallel computer itself.Granularity. The amount of work involved in a single matrix computation is too little to be effectively parallelized.Business situation. There are too few potential customers at this time (1995) to undertake fundamental changes in MATLAB's architecture.This one-page note turned out to be one of my most widely cited publications.. .Twenty-seven Parallel MATLABsA 2001 survey by Ron Choy at MIT found 27 different projects that were developing some way to run MATLAB in parallel. All of them involved a MATLAB-based host program calling a fixed library of parallel functions, written in some other language, on the workers. None of the systems were capable of running arbitrary MATLAB programs in parallel. None of them were MathWorks products.Distributed Computing ToolboxMathWorks introduced the MATLAB Distributed Computing Toolbox in November 2004. We improvised this demo setup at our first Supercomputing Conference, SC2004 in Pittsburg, .Supercomputing ConferenceA year later, SC2005 was in Seattle and our booth featured four worker machines on a wire shelving unit purchased at a local Home Depot. .Bill GatesSince Seattle was his home town, Bill Gates gave the keynote talk at SC2005. He announced that Microsoft was going into High Performance Computing and used the MathWorks Distributed Computing Toolbox in his demonstration. .Now There is a Parallel MATLABSo, a little more than ten years after the first Cleve's Corner about parallel computing, a second Cleve's Corner in News and Notes was able to reverse the situation.. Get the MATLAB code (requires JavaScript) Published with MATLAB® R2023a",
+ "content_html": "
I have just returned from the MathWorks company meeting celebrating our 40th Anniversary. In one of the presentations, Jos Martin described how Parallel MATLAB was introduced almost twenty years ago. Here are a few slides from Jos's talk.
In MATLAB News and Notes for spring 1995, I wrote a one-page Cleve's Corner titled \"Why there isn't any parallel MATLAB.\" There were three reasons.
Memory model. MATLAB would generate a matrix on a host machine, split it into roughly equally sized submatrices, and distribute each submatrix to a node. But it took far longer to distribute the data then it did to do the computation. Any matrix that would fit into memory on the host was too small to make effective use of the parallel computer itself.
Granularity. The amount of work involved in a single matrix computation is too little to be effectively parallelized.
Business situation. There are too few potential customers at this time (1995) to undertake fundamental changes in MATLAB's architecture.
This one-page note turned out to be one of my most widely cited publications.
.
.
Twenty-seven Parallel MATLABs
A 2001 survey by Ron Choy at MIT found 27 different projects that were developing some way to run MATLAB in parallel. All of them involved a MATLAB-based host program calling a fixed library of parallel functions, written in some other language, on the workers. None of the systems were capable of running arbitrary MATLAB programs in parallel. None of them were MathWorks products.
Distributed Computing Toolbox
MathWorks introduced the MATLAB Distributed Computing Toolbox in November 2004. We improvised this demo setup at our first Supercomputing Conference, SC2004 in Pittsburg,
.
Supercomputing Conference
A year later, SC2005 was in Seattle and our booth featured four worker machines on a wire shelving unit purchased at a local Home Depot.
.
Bill Gates
Since Seattle was his home town, Bill Gates gave the keynote talk at SC2005. He announced that Microsoft was going into High Performance Computing and used the MathWorks Distributed Computing Toolbox in his demonstration.
.
Now There is a Parallel MATLAB
So, a little more than ten years after the first Cleve's Corner about parallel computing, a second Cleve's Corner in News and Notes was able to reverse the situation.
",
+ "url": "https://hpc.social/commercial-blog/2024/twenty-years-of-parallel-matlab/",
+
+
+
+
+
+ "date_published": "2024-03-15T18:05:58-06:00",
+ "date_modified": "2024-03-15T18:05:58-06:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2024/chaotic-swinging-sticks/",
+ "title": "Chaotic Swinging Sticks",
+ "summary": null,
+ "content_text": "The Swinging Sticks is a kinetic sculpture that exhibits chaotic motion. The device became very popular after it upstaged Tony Stark in Iron Man 2. My daughter Carolyn gave me a desktop version of Swinging Sticks for Christmas. I immediately set out to simulate it. ContentsChaotic MotionSwinging SticksSculptureCodeChaotic MotionChaotic motion appears random but isn't. Once the motion begins, the initial conditions together with Newton's law of motion, F = ma, determine subsequent behavior. There are no random forces. It may be difficult to predict positions, but they are well-determined, nonetheless.A classic example of chaotic motion is the double pendulum. One mass at end of a massless string swings about a fixed pivot, and a second mass is attached by a massless string to the first. My simulator of the classis double pendulum is available in Cleve's Lab, swinger, and a movie is available here pendulum movie.Swinging SticksThe swinging sticks are similar to the double pendulum. The sticks are two rods with uniformly distributed mass, different lengths and off-center pivots. The best way to view the motion is to download this code and run it in your own MATLAB. Otherwise, here in a short slow-motion animated GIF. And, here is a longer Swinging Sticks Video.The motion of the shorter of the two rods is chaotic. Here are the orbits traced by the ends of the short rod. SculptureSwinging Sticks sculptures are available in various sizes and colors. The Swinging Sticks.Our mathematical model is of a frictionless perpetual motion machine. The real sculptures have an ingenious electromagnetic controller in the base that is claimed to run for two years on four AA batteries. Mine has been running since Christmas. An excellent YouTube video by Wayne Schmidt describes the controller.Codehttps://blogs.mathworks.com/cleve/files/swinging_sticks.mGet the MATLAB code (requires JavaScript) Published with MATLAB® R2024a",
+ "content_html": "
The Swinging Sticks is a kinetic sculpture that exhibits chaotic motion. The device became very popular after it upstaged Tony Stark in Iron Man 2. My daughter Carolyn gave me a desktop version of Swinging Sticks for Christmas. I immediately set out to simulate it.
Chaotic motion appears random but isn't. Once the motion begins, the initial conditions together with Newton's law of motion, F = ma, determine subsequent behavior. There are no random forces. It may be difficult to predict positions, but they are well-determined, nonetheless.
A classic example of chaotic motion is the double pendulum. One mass at end of a massless string swings about a fixed pivot, and a second mass is attached by a massless string to the first. My simulator of the classis double pendulum is available in Cleve's Lab, swinger, and a movie is available here pendulum movie.
Swinging Sticks
The swinging sticks are similar to the double pendulum. The sticks are two rods with uniformly distributed mass, different lengths and off-center pivots. The best way to view the motion is to download this code and run it in your own MATLAB. Otherwise, here in a short slow-motion animated GIF.
The motion of the shorter of the two rods is chaotic. Here are the orbits traced by the ends of the short rod.
Sculpture
Swinging Sticks sculptures are available in various sizes and colors. The Swinging Sticks.
Our mathematical model is of a frictionless perpetual motion machine. The real sculptures have an ingenious electromagnetic controller in the base that is claimed to run for two years on four AA batteries. Mine has been running since Christmas. An excellent YouTube video by Wayne Schmidt describes the controller.
",
+ "url": "https://hpc.social/commercial-blog/2024/chaotic-swinging-sticks/",
+
+
+
+
+
+ "date_published": "2024-02-20T16:24:41-07:00",
+ "date_modified": "2024-02-20T16:24:41-07:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2024/nick-higham-1961-2024/",
+ "title": "Nick Higham (1961-2024)",
+ "summary": null,
+ "content_text": "Nick Higham passed away last Saturday. Nick was a close friend of mine and a great friend of MATLAB. I will leave it to others to describe his research and teaching, his many honors, and his service to our community, especially SIAM. I have just a few, more personal, comments. ContentsNA DigestBooksMATLABgalleryexpmGoodbyeNA DigestMonday's NA Digest led off with this from Nick's wife Francoise and his brother Des.Subject: Nick Higham (1961--2024)With great sadness we report that Nick Higham, Royal Society ResearchProfessor and Richardson Professor of Applied Mathematics at theUniversity of Manchester, passed away on January 20, 2024, at the ageof 62 after an 18 month struggle with a form of blood cancer. Anobituary describing Nick's research and leadership contributions willappear in SIAM News in due course.Francoise Tisseur and Des HighamBooksNick was an excellent writer, and an excellent writer about writing.Here are the covers of his six books. SIAM published five of these. Two are surveys of Nick's research on the accuracy of numeric algorithms and the computation of matrix functions. Two more, one of them coauthored with Dennis Sherwood, are guides to mathematical exposition.MATLAB Guide, by Des and Nick Higham, is one of my favorite books about MATLAB. It is a succinct introduction for newcomers and a valuable refresher for old-timers. The third edition, published in 2017, includes chapters on object-oriented computing, parallel computing, the Symbolic Math Toolbox and other recent additions. Be sure to check out the MATLAB Guide web site.The only non-SIAM book pictured above is The Princeton Companion to Applied Mathematics. It is over 1,000 pages long and features nearly 200 sections written by an international team of experts. Nick is the editor-in-chief and wrote many of the sections himself.MATLABHere is a Word Cloud from Nick's home page. It shows the frequency of the tags for his blog and confirms his interest in MATLAB. galleryAnyone interested in numerical linear algebra should also be interested in the gallery function, which is based on Nick's work. Enter>> doc galleryScroll down to matrixname and investigate over 70 different test matrices.If you find gallery irresistible, take a look at anymatrix, an extensible matrix collection, by Nick and Mantas Mikaitis.expmThis is very personal for me. Thirty or forty years ago, Charlie Van Loan and I were regarded as authorities on computing the matrix exponential, $e^{A}$. The function expm has been in MATLAB since its very beginning. Around twenty years ago, we ceded the authority title to Nick and Awad Al-Mohy. Their code for matrix exponential is now the basis for expm.GoodbyeOur business has lost one of its superstars. I have lost a good friend, way too soon. Goodbye Nick.Get the MATLAB code (requires JavaScript) Published with MATLAB® R2023a",
+ "content_html": "
Nick Higham passed away last Saturday. Nick was a close friend of mine and a great friend of MATLAB. I will leave it to others to describe his research and teaching, his many honors, and his service to our community, especially SIAM. I have just a few, more personal, comments.
Monday's NA Digest led off with this from Nick's wife Francoise and his brother Des.
Subject: Nick Higham (1961--2024)
With great sadness we report that Nick Higham, Royal Society ResearchProfessor and Richardson Professor of Applied Mathematics at theUniversity of Manchester, passed away on January 20, 2024, at the ageof 62 after an 18 month struggle with a form of blood cancer. Anobituary describing Nick's research and leadership contributions willappear in SIAM News in due course.
Francoise Tisseur and Des Higham
Books
Nick was an excellent writer, and an excellent writer about writing.
Here are the covers of his six books.
SIAM published five of these. Two are surveys of Nick's research on the accuracy of numeric algorithms and the computation of matrix functions. Two more, one of them coauthored with Dennis Sherwood, are guides to mathematical exposition.
MATLAB Guide, by Des and Nick Higham, is one of my favorite books about MATLAB. It is a succinct introduction for newcomers and a valuable refresher for old-timers. The third edition, published in 2017, includes chapters on object-oriented computing, parallel computing, the Symbolic Math Toolbox and other recent additions. Be sure to check out the MATLAB Guide web site.
Here is a Word Cloud from Nick's home page. It shows the frequency of the tags for his blog and confirms his interest in MATLAB.
gallery
Anyone interested in numerical linear algebra should also be interested in the gallery function, which is based on Nick's work. Enter
>> doc gallery
Scroll down to matrixname and investigate over 70 different test matrices.
If you find gallery irresistible, take a look at anymatrix, an extensible matrix collection, by Nick and Mantas Mikaitis.
expm
This is very personal for me. Thirty or forty years ago, Charlie Van Loan and I were regarded as authorities on computing the matrix exponential, $e^{A}$. The function expm has been in MATLAB since its very beginning. Around twenty years ago, we ceded the authority title to Nick and Awad Al-Mohy. Their code for matrix exponential is now the basis for expm.
Goodbye
Our business has lost one of its superstars. I have lost a good friend, way too soon. Goodbye Nick.
",
+ "url": "https://hpc.social/commercial-blog/2024/nick-higham-1961-2024/",
+
+
+
+
+
+ "date_published": "2024-01-25T16:36:37-07:00",
+ "date_modified": "2024-01-25T16:36:37-07:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2024/exponential-fitting-separable-least-squares-and-quahogs/",
+ "title": "Exponential Fitting, Separable Least Squares, and Quahogs",
+ "summary": null,
+ "content_text": "We have been investigating a recent bug report about fitnlm, the Statistics and Machine Learning Toolbox function for robust fitting of nonlinear models.ContentsQuahogsAcidificationSeparable Least SquaresCentering DataExponential FittingResultsSoftwareThanksQuahogs The bug report comes from Greg Pelletier, an independent research scientist and biogeochemical modeler in Olympia, Washington. Greg has been studying the vulnerability of sensitive marine organisms to increases in ocean acidification. One of the most important of these organisms is Mercenaria mercenaria, the hard clam.Especially here in New England, hard clams are known by their traditional Native American name, quahog. They have a well-deserved reputation for making excellent clam chowder.AcidificationWe are all aware of increasing levels of carbon dioxide in the earth's atmosphere. We may not be as aware of the effect this increase has on the health of the earth's oceans. According to NOAA, the ocean absorbs about 30% of the atmospheric carbon dioxide.A definitive and controversial 2009 paper by Justin Ries and colleagues, then at the Woods Hole Oceanographic Institution, is \"Marine calcifiers exhibit mixed responses to CO2-induced ocean acidification\", https://doi.org/10.1130/G30210A.1. The hard clam example in Greg's bug report comes from figure 1K in the Ries et al. paper.The independent variable in experiments is the ratio of alkalinity of sea water to the concentration of dissolved inorganic carbon. The dependent variable is the calcification rate, which compares how fast the organism builds its shells to how fast the shells are dissolving. Separable Least SquaresThe model chosen by Ries at al. is$$ y \\approx \\beta_1 + \\beta_2 e^{\\lambda t} $$where $t$ is the ratio of alkalinity to dissolved carbon and $y$ is the calcification rate. The data have only four distinct values of $t$, with several observations of $y$ at each value.The parameters $\\beta_1$, $\\beta_2$ and $\\lambda$ are determined by least squares curve fit. This is a separable least squares problem. For any given value of $\\lambda$, the parameters $\\beta_1$ and $\\beta_2$ occur linearly and the least squares solution can be obtained by MATLAB's backslash.Gene Golub and Victor Pereyra described separable least squares in 1973 and proposed solving it by a variable projection algorithm. Since 1973 a number of people, including Pereyra, Linda Kaufman, Fred Krogh, John Bolstadt and David Gay, have contributed to the development of a series of Fortran programs named varpro. In 2011, Dianne O'Leary and Burt Rust created a MATLAB version of varpro. Their report, https://www.cs.umd.edu/~oleary/software/varpro/, is a good background source, as well as documentation for varpro.m.I have a section on separable least squares, and an example, expfitdemo, in NCM, Numerical Computing with MATLAB. I have modified expfitdemo to work on Greg's quahogs problem.Centering DataIt turns out that the problem Greg encountered can be traced to the fact that the data are not centered. The given values of $t$ are all positive. This causes fitnlm to print a warning message and attempt to rectify the situation by changing the degrees of freedom from 22 to 23, but this only makes the situation worse. (We should take another look at the portion of fitnlm that adjusts the degrees of freedom.)It is always a good idea in curve fitting to center the data with something like t = t - mean(t)The values of $y$ are already pretty well centered. Rescaling $y$ with y = 10000*ymakes interpretation of results easier.Exponential FittingWith the data centered and scaled, we have three different ways of tackling Greg's problem. All three methods agree on the results they compute.fitnlm. Treats all parameters as if they were nonlinear. Computes statistical quantities such as R-squared and RMS Error.varpro. Venerable software history. Only one nonlinear parameter for the quahogs problem. Delivers additional statistical quantities in Regression structure.quahogsfit. Textbook separable least squares code. Modification for the quahogs problem of expfitdemo from NCM. Only one nonlinear parameter. No statistics.ResultsfitnlmNonlinear regression model: y ~ param1 + param2*exp(param3*xval)Estimated Coefficients: Estimate SE tStat pValue ________ _______ _______ __________ param1 0.69536 0.1657 4.1964 0.00037344 param2 -0.26482 0.19909 -1.3302 0.19709 param3 -22.218 8.1494 -2.7263 0.012327Number of observations: 25, Error degrees of freedom: 22Root Mean Squared Error: 0.307R-Squared: 0.828, Adjusted R-Squared 0.813F-statistic vs. constant model: 53, p-value = 3.86e-09varproLinear Parameters: 0.695367 -0.264837Nonlinear Parameters: -22.217495Norm of weighted residual = 1.438935Norm of data vector = 3.545820Expected error of observations = 0.306782Coefficient of determination = 0.828145Regression.t_ratio 4.1962 -1.3301 -2.7264Regression.std_param 0.1657 0.1991 8.1490quahogsfitlambda = -22.2180condX = 4.3882beta = 0.6954 -0.2648normres = 1.4389quahogsfit produces this plot, which can be compared with figure 1K from Ries et al, reproduced above. SoftwareThe codes for this post are available here quahogs_driver.m and here varpro.m.ThanksThanks to Greg Pelletier for the bug report and to Tom Lane for his statistical expertise.Get the MATLAB code (requires JavaScript) Published with MATLAB® R2023a",
+ "content_html": "
We have been investigating a recent bug report about fitnlm, the Statistics and Machine Learning Toolbox function for robust fitting of nonlinear models.
The bug report comes from Greg Pelletier, an independent research scientist and biogeochemical modeler in Olympia, Washington. Greg has been studying the vulnerability of sensitive marine organisms to increases in ocean acidification. One of the most important of these organisms is Mercenaria mercenaria, the hard clam.
Especially here in New England, hard clams are known by their traditional Native American name, quahog. They have a well-deserved reputation for making excellent clam chowder.
Acidification
We are all aware of increasing levels of carbon dioxide in the earth's atmosphere. We may not be as aware of the effect this increase has on the health of the earth's oceans. According to NOAA, the ocean absorbs about 30% of the atmospheric carbon dioxide.
A definitive and controversial 2009 paper by Justin Ries and colleagues, then at the Woods Hole Oceanographic Institution, is \"Marine calcifiers exhibit mixed responses to CO2-induced ocean acidification\", https://doi.org/10.1130/G30210A.1. The hard clam example in Greg's bug report comes from figure 1K in the Ries et al. paper.
The independent variable in experiments is the ratio of alkalinity of sea water to the concentration of dissolved inorganic carbon. The dependent variable is the calcification rate, which compares how fast the organism builds its shells to how fast the shells are dissolving.
Separable Least Squares
The model chosen by Ries at al. is
$$ y \\approx \\beta_1 + \\beta_2 e^{\\lambda t} $$
where $t$ is the ratio of alkalinity to dissolved carbon and $y$ is the calcification rate. The data have only four distinct values of $t$, with several observations of $y$ at each value.
The parameters $\\beta_1$, $\\beta_2$ and $\\lambda$ are determined by least squares curve fit. This is a separable least squares problem. For any given value of $\\lambda$, the parameters $\\beta_1$ and $\\beta_2$ occur linearly and the least squares solution can be obtained by MATLAB's backslash.
Gene Golub and Victor Pereyra described separable least squares in 1973 and proposed solving it by a variable projection algorithm. Since 1973 a number of people, including Pereyra, Linda Kaufman, Fred Krogh, John Bolstadt and David Gay, have contributed to the development of a series of Fortran programs named varpro. In 2011, Dianne O'Leary and Burt Rust created a MATLAB version of varpro. Their report, https://www.cs.umd.edu/~oleary/software/varpro/, is a good background source, as well as documentation for varpro.m.
I have a section on separable least squares, and an example, expfitdemo, in NCM, Numerical Computing with MATLAB. I have modified expfitdemo to work on Greg's quahogs problem.
Centering Data
It turns out that the problem Greg encountered can be traced to the fact that the data are not centered. The given values of $t$ are all positive. This causes fitnlm to print a warning message and attempt to rectify the situation by changing the degrees of freedom from 22 to 23, but this only makes the situation worse. (We should take another look at the portion of fitnlm that adjusts the degrees of freedom.)
It is always a good idea in curve fitting to center the data with something like
t = t - mean(t)
The values of $y$ are already pretty well centered. Rescaling $y$ with
y = 10000*y
makes interpretation of results easier.
Exponential Fitting
With the data centered and scaled, we have three different ways of tackling Greg's problem. All three methods agree on the results they compute.
fitnlm. Treats all parameters as if they were nonlinear. Computes statistical quantities such as R-squared and RMS Error.
varpro. Venerable software history. Only one nonlinear parameter for the quahogs problem. Delivers additional statistical quantities in Regression structure.
quahogsfit. Textbook separable least squares code. Modification for the quahogs problem of expfitdemo from NCM. Only one nonlinear parameter. No statistics.
Results
fitnlm
Nonlinear regression model: y ~ param1 + param2*exp(param3*xval)
Estimated Coefficients: Estimate SE tStat pValue ________ _______ _______ __________
Number of observations: 25, Error degrees of freedom: 22Root Mean Squared Error: 0.307R-Squared: 0.828, Adjusted R-Squared 0.813F-statistic vs. constant model: 53, p-value = 3.86e-09
varpro
Linear Parameters: 0.695367 -0.264837Nonlinear Parameters: -22.217495
Norm of weighted residual = 1.438935Norm of data vector = 3.545820Expected error of observations = 0.306782Coefficient of determination = 0.828145
",
+ "url": "https://hpc.social/commercial-blog/2023/season-s-greetings/",
+
+
+
+
+
+ "date_published": "2023-12-20T14:13:20-07:00",
+ "date_modified": "2023-12-20T14:13:20-07:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2023/blog-post-number-300-vibrating-logo/",
+ "title": "Blog Post Number 300, Vibrating Logo",
+ "summary": null,
+ "content_text": "This is post number 300 of Cleve's Corner blog. The first post was on June 6, 2012, which is 600 weeks ago. So, I have averaged one post every two weeks for over a decade. The posts were more frequent in the early days and are less frequent today.ContentsVibrating LogoCodevibrating_logovibrating_logo_framefirst frameinit_figVibrating LogoFor my 300-th post, I want to take another look at our MathWorks logo. Here is a modified version of one of the animations that I entered in the recent MATLAB Flipbook Mini Hack. Vibrating LogoThe MathWorks company logo is the solution to a partial differential equation that describes how a disturbance travels through matter. I discussed the logo in a five-part blog post in 2014. Here are links to three of those posts.Why is it L-shaped?.The method of particular solutions.How the view has evolved..One of my most-liked blog posts is by ten-year old Eden Rajapakse.CodeThis code is available at vibrating_logo.vibrating_logofunction vibrating_logo % MathWorks logo, vibrating L-shaped membrane. % See Cleve's Corner, Dec. 13, 2023. % https://blogs.mathworks.com/cleve/2023/12/13/blog-post-number-300-vibrating-logo. stop = init_fig; fps = 6; f = 0; % Loop until stop is toggled. while true f = f + 1; if stop.Value return end vibrating_logo_frame(f) pause(1/fps) end vibrating_logo_frame function vibrating_logo_frame(f) % % One frame of animation. if f == 1 first_frame end fud = get(gcf,'UserData'); [mu,L,s] = deal(fud{:}); t = (f-1)/fps; Z = cos(mu(1)*t)*L{1} + sin(mu(2)*t)*L{2} + sin(mu(3)*t)*L{3} + ... sin(mu(4)*t)*L{4} + sin(mu(5)*t)*L{5} + sin(mu(6)*t)*L{6}; s.ZData = Z; endfirst frame function first_frame cla axis off % First six eigenvalues. mu = sqrt([9.6397238445, 15.19725192, 2*pi^2, ... 29.5214811, 31.9126360, 41.4745099]); % First six eigenfunctions. L{1} = 30*membrane(1,25); L{2} = 2*membrane(2,25); L{3} = -2*membrane(3,25); L{4} = 5*membrane(4,25); L{5} = -3*membrane(5,25); L{6} = 4*membrane(6,25); % Surf plot with custom lighting. axes('CameraPosition', [-193.4013 -265.1546 220.4819],... 'CameraTarget',[26 26 10], ... 'CameraUpVector',[0 0 1], ... 'CameraViewAngle',9.5, ... 'DataAspectRatio', [1 1 .9],... 'Visible','off', ... 'XLim',[1 51], ... 'YLim',[1 51], ... 'ZLim',[-13 40]); s = surface(zeros(size(L{1})), ... 'EdgeColor','none', ... 'FaceColor',[0.9 0.2 0.2], ... 'FaceLighting','phong', ... 'AmbientStrength',0.3, ... 'DiffuseStrength',0.6, ... 'Clipping','off',... 'BackFaceLighting','lit', ... 'SpecularStrength',1.0, ... 'SpecularColorReflectance',1, ... 'SpecularExponent',7); light('Position',[40 100 20], ... 'Style','local', ... 'Color',[0 0.8 0.8]); light('Position',[.5 -1 .4], ... 'Color',[0.8 0.8 0]); set(gcf,'UserData',{mu,L,s}) endinit_fig function stop = init_fig % Initialize figure. fig = gcf; fig.Color = 'k'; fig.MenuBar = 'none'; fig.ToolBar = 'none'; fig.NumberTitle = 'off'; fig.Clipping = 'off'; stop = uicontrol; stop.Style = 'togglebutton'; stop.String = 'X'; stop.FontSize = 12; stop.FontWeight = 'bold'; stop.Units = 'normalized'; stop.Position = [.92 .92 .06 .06]; cla shg endendGet the MATLAB code (requires JavaScript) Published with MATLAB® R2023a",
+ "content_html": "
This is post number 300 of Cleve's Corner blog. The first post was on June 6, 2012, which is 600 weeks ago. So, I have averaged one post every two weeks for over a decade. The posts were more frequent in the early days and are less frequent today.
For my 300-th post, I want to take another look at our MathWorks logo. Here is a modified version of one of the animations that I entered in the recent MATLAB Flipbook Mini Hack.
Vibrating Logo
The MathWorks company logo is the solution to a partial differential equation that describes how a disturbance travels through matter. I discussed the logo in a five-part blog post in 2014. Here are links to three of those posts.
% MathWorks logo, vibrating L-shaped membrane.% See Cleve's Corner, Dec. 13, 2023.% https://blogs.mathworks.com/cleve/2023/12/13/blog-post-number-300-vibrating-logo. stop = init_fig; fps = 6; f = 0; % Loop until stop is toggled.while true f = f + 1; if stop.Value returnend vibrating_logo_frame(f) pause(1/fps) end
vibrating_logo_frame
function vibrating_logo_frame(f) %% One frame of animation.if f == 1 first_frame end fud = get(gcf,'UserData'); [mu,L,s] = deal(fud{:}); t = (f-1)/fps; Z = cos(mu(1)*t)*L{1} + sin(mu(2)*t)*L{2} + sin(mu(3)*t)*L{3} + ... sin(mu(4)*t)*L{4} + sin(mu(5)*t)*L{5} + sin(mu(6)*t)*L{6}; s.ZData = Z; end
",
+ "url": "https://hpc.social/commercial-blog/2023/blog-post-number-300-vibrating-logo/",
+
+
+
+
+
+ "date_published": "2023-12-13T18:23:26-07:00",
+ "date_modified": "2023-12-13T18:23:26-07:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2023/bouncing-bucky-ball-at-flipbook-mini-hack/",
+ "title": "Bouncing Bucky Ball at Flipbook Mini Hack",
+ "summary": null,
+ "content_text": "The 2023 MATLAB Central Flipbook Mini Hack contest runs from November 6 until December 3. Over 200 entries have been submitted in the first two weeks.ContentsNew RulesGalleryPersonal FavoritesBouncing Bucky BallSoftwareThanksNew RulesThis year's mini hack features short animations. The contest software runs the program you submit to make an animated GIF file with exactly 48 frames and an inner-frame delay time of 1/24 second. So, your animation will run for two seconds, then continuously repeat. If you want periodic motion, you need to be back where you started by frame 48.In previous mini hacks, programs had to be Twitter length -- at most 255 characters long. Now, the new limit is 2,000 characters. Comments and formatting blanks are not counted. Remixes and reuse of other submissions is encouraged.Participants and other viewers vote on the submissions. There are prizes like Amazon gift cards and T-shirts. MathWorkers may participate, but not win prizes.GalleryTake a look at the Gallery.Personal FavoritesI find the results fascinating. There are so many different creative styles, artistic talents and programming techniques. Here are a few of my personal favorites.Jenny BostenJenny Bosten is a familiar name on MATLAB Central. She is a Senior Lecturer in Psychology at the University of Sussex, where she is a \"visual neuroscientist specialising in colour vision.\" Her code for Time lapse of Lake view to the West shows she is also a wizard of coordinate systems and color maps. 隆光 中村I don't know anything about this person. All I see is this name, 隆光 中村, and this ingenious code for Fireworks. Ned GulleyNed is the long-time MathWorker who is the architect of MATLAB Central, and who, this time, is also a prolific participant. One of his more mathematical animations is Orbiting Roots. Eric Ludham'Eric is head of the MathWorks development team for Graphics and Charting. Contributions like this Blooming Rose demonstrate his artistic design talent. Bouncing Bucky BallMy own contributions are not nearly as attractive as these.The 2,000 character limit is a good idea. It forced me to look critically at some old code and rewrite it to be simpler and clearer.This program for a Bouncing Bucky Ball uses the hgtransform object to good effect. I also think it has a nice solution to the problem facing everybody of how to retain state from one frame to the next. SoftwareHere is a link to a slightly more complicated version with one togglebutton that provides a random restart capability. Bouncing_Bucky.mThanksChen Lin, David Wey and Vinay Ramesh are running the Mini Hack this year,Get the MATLAB code (requires JavaScript) Published with MATLAB® R2023a",
+ "content_html": "
The 2023 MATLAB Central Flipbook Mini Hack contest runs from November 6 until December 3. Over 200 entries have been submitted in the first two weeks.
This year's mini hack features short animations. The contest software runs the program you submit to make an animated GIF file with exactly 48 frames and an inner-frame delay time of 1/24 second. So, your animation will run for two seconds, then continuously repeat. If you want periodic motion, you need to be back where you started by frame 48.
In previous mini hacks, programs had to be Twitter length -- at most 255 characters long. Now, the new limit is 2,000 characters. Comments and formatting blanks are not counted. Remixes and reuse of other submissions is encouraged.
Participants and other viewers vote on the submissions. There are prizes like Amazon gift cards and T-shirts. MathWorkers may participate, but not win prizes.
I find the results fascinating. There are so many different creative styles, artistic talents and programming techniques. Here are a few of my personal favorites.
Jenny Bosten
Jenny Bosten is a familiar name on MATLAB Central. She is a Senior Lecturer in Psychology at the University of Sussex, where she is a \"visual neuroscientist specialising in colour vision.\" Her code for Time lapse of Lake view to the West shows she is also a wizard of coordinate systems and color maps.
隆光 中村
I don't know anything about this person. All I see is this name, 隆光 中村, and this ingenious code for Fireworks.
Ned Gulley
Ned is the long-time MathWorker who is the architect of MATLAB Central, and who, this time, is also a prolific participant. One of his more mathematical animations is Orbiting Roots.
Eric Ludham'
Eric is head of the MathWorks development team for Graphics and Charting. Contributions like this Blooming Rose demonstrate his artistic design talent.
Bouncing Bucky Ball
My own contributions are not nearly as attractive as these.
The 2,000 character limit is a good idea. It forced me to look critically at some old code and rewrite it to be simpler and clearer.
This program for a Bouncing Bucky Ball uses the hgtransform object to good effect. I also think it has a nice solution to the problem facing everybody of how to retain state from one frame to the next.
Software
Here is a link to a slightly more complicated version with one togglebutton that provides a random restart capability. Bouncing_Bucky.m
Thanks
Chen Lin, David Wey and Vinay Ramesh are running the Mini Hack this year,
",
+ "url": "https://hpc.social/commercial-blog/2023/bouncing-bucky-ball-at-flipbook-mini-hack/",
+
+
+
+
+
+ "date_published": "2023-11-16T23:01:49-07:00",
+ "date_modified": "2023-11-16T23:01:49-07:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2023/exploring-matrices-exercises/",
+ "title": "Exploring Matrices Exercises",
+ "summary": null,
+ "content_text": "Try your hand at a few exercises involving Exploring Matrices.ContentsQube SimplifiedExploring Matrices ExercisesMatrix MultiplicationRotations and ScalingComputer GraphicsMatrices and CubesQube Simplified I have simplified the Qube app by removing these four buttons.solve. The <== key now controls the unscrambling operation.scramble. The ==> key now does six random rotations.order. I never found a satisfactory reference for the group theory of Rubik's cube.score. I never found a use for the nuclear norm.Code for Qube dated 9/24/2023 is included in the Apps mzip archive.Exploring Matrices ExercisesHere are a few exercises for Exploring Matrices. The answers are available at ExMatAnswers.Matrix Multiplication1. Compute by rows, and by columns.$$ \\left( \\begin{array}{rrr} 8 & 1 & 6 \\\\ 3 & 5 & 7 \\\\ 4 & 9 & 2 \\end{array} \\right) \\left( \\begin{array}{r} 1 \\\\ 1 \\\\ 1 \\end{array} \\right)$$2. Solve for $z$ using inner products of rows, and using linear combinations of columns.$$ \\left( \\begin{array}{rrr} 1 & 2 & 3 \\\\ 4 & 5 & 6 \\\\ 7 & 8 & 9 \\end{array} \\right) \\left( \\begin{array}{r} 1 \\\\ z \\\\ 1 \\end{array} \\right) \\ = \\ \\left( \\begin{array}{r} 0 \\\\ 0 \\\\ 0 \\end{array} \\right)$$3. What do the m, n and p buttons on the Multiply app do? What are the other buttons and what do they do?4. If A is n-by-n and x is n-by-1, how many multiplications are required to compute A x ?5. If A is m-by-n and B is n-by-p, how many multiplications are required to compute A B ?Rotations and Scaling1. What is R(30º)?$$R(\\theta) \\ = \\\\left( \\begin{array}{rr} \\cos{\\theta} & \\sin{\\theta} \\\\ -\\sin{\\theta} & \\cos{\\theta} \\end{array} \\right)$$2. Explain https://xkcd.com/184.3. What is the value of $\\theta$ ?$$R(\\theta) \\ = \\\\left( \\begin{array}{rr} 0.8 & 0.6 \\\\ -0.6 & 0.8 \\end{array} \\right)$$4. What is the value of $\\theta$ ? 5. Edit a copy of Rotate.m and replace the house with a hand. You can use my hand or your own hand; see exercise 3.4 in Numerical Computing with MATLAB . Computer Graphics1. Show how homogeneous coordinates and matrix-vector multiplication by Tx, Ty or Tz produce translation.2. What is the range of the rotations used by the pitch, roll, and yaw buttons on the Grafix app?3. What color in the beacon on top of the plane? How would you change the beacon's color?4, What is the function of the resolution and offset sliders for the teapot?5, How many times does the bucky ball bounce off the sides of the plot window?Matrices and Cubes1. What is the color of central cubelet in the Color Cube?2. What do the \"<=\" , \"<==\" , \"=>\" and \"==>\" buttons on Qube do?3. What is \"God's Number\" for a 3-by-3-by-3 Rubik's Cube? What are Q20 and Q26? See Cleve's Corner 2022/09/05.4. Can you restore the following scrambled cubes with fewer moves than <==, the unscramble key? Use the quarter-turn metric and reset the cube with start or by clicking on stack and Q0. You might also want to set speed to 30 or 45,LRUDFBLRL'R'FLLLRBQ26Reset the random number generator by entering rng(r) for some small integer r in the command window and then generate six random rotations with the ==> key.Get the MATLAB code (requires JavaScript) Published with MATLAB® R2023a",
+ "content_html": "
5. Edit a copy of Rotate.m and replace the house with a hand. You can use my hand or your own hand; see exercise 3.4 in Numerical Computing with MATLAB .
Computer Graphics
1. Show how homogeneous coordinates and matrix-vector multiplication by Tx, Ty or Tz produce translation.
2. What is the range of the rotations used by the pitch, roll, and yaw buttons on the Grafix app?
3. What color in the beacon on top of the plane? How would you change the beacon's color?
4, What is the function of the resolution and offset sliders for the teapot?
5, How many times does the bucky ball bounce off the sides of the plot window?
Matrices and Cubes
1. What is the color of central cubelet in the Color Cube?
2. What do the \"<=\" , \"<==\" , \"=>\" and \"==>\" buttons on Qube do?
3. What is \"God's Number\" for a 3-by-3-by-3 Rubik's Cube? What are Q20 and Q26? See Cleve's Corner 2022/09/05.
4. Can you restore the following scrambled cubes with fewer moves than <==, the unscramble key? Use the quarter-turn metric and reset the cube with start or by clicking on stack and Q0. You might also want to set speed to 30 or 45,
LRUDFB
LRL'R'
FLLLRB
Q26
Reset the random number generator by entering rng(r) for some small integer r in the command window and then generate six random rotations with the ==> key.
",
+ "url": "https://hpc.social/commercial-blog/2023/exploring-matrices-exercises/",
+
+
+
+
+
+ "date_published": "2023-09-25T17:57:28-06:00",
+ "date_modified": "2023-09-25T17:57:28-06:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2023/exploring-matrices/",
+ "title": "Exploring Matrices",
+ "summary": null,
+ "content_text": "I have spent much of my career working to bring abstract linear algebra and practical matrix computation closer together. This project is my latest effort.ContentsAlibiExploring MatricesYouTube VideosMatrix MultiplicationRotation and ScalingComputer GraphicsMatrices and CubesSimulinkAI and GorillasSoftwareThanksDedicationAlibiOver sixty years ago, as a sophomore contemplating a major in mathematics, I took a course entitled Survey of Modern Algebra. We used a now-classic textbook by MacLane and Birkhoff that featured abstract theorems about groups, rings, fields, vector spaces and linear algebra. I remember the colorful terms alias and alibi had something to do with change of basis and change of position, but I have never seen those terms again.The next year, I took Numerical Analysis. We did some of the homework on a Burroughhs 205 Datatron and I wrote a machine language program to solve simultaneous linear equations. I was hooked.But at the time I did not realize that the two courses were about the same magnificent object -- the matrix.Exploring MatricesExploring Matrices is a multi-media project that shows matrices in action. Short videos, blog posts, interactive MATLAB software and self-study exercises investigate applications of matrices. The material is intended for studebts in an undergraduate course in linear algebra or computational science. However, anyone using matrices should find topics that interest them.The first release of Exploring Matrices has six modules. All of the modules feature animated MATLAB displays and four of the modules include interactive MATLAB \"apps\". The modules are:Matrix MultiplicationRotation and ScalingComputer GraphicsMatrices and CubesSimulinkAI and Gorillas %YouTube VideosAn introduction and six videos ranging in length from one to six minutes, are available on YouTube athttps://youtube.com/playlist?list=PLn8PRpmsu08oGNmtBfFOmgVC0TlXDaLDJ.The first four of these videos feature animations produced by our four MATLAB apps -- Multiply, Rotate, Grafix, and Qube. The other two videos describe two applications, simulation of control systems and neural networks for facial recognition (of gorillas).Matrix MultiplicationSome viewers may just be learning the mechanics of matrix multiplication. Other viewers will have encountered it years ago. The traditional algorithm for computing the product of two matrices involves inner products between the rows of the first matrix and the columns of the second. A less familiar algorithm, which involves linear combinations of the columns of the first matrix, is often more efficient and informative. The two approaches produce the same final result from intermediate terms in different orders.Here is one frame from the animation of these two algorithms generated by our Multiply app. The highlighted element in the first matrix either moves across the rows or goes down the columns. Rotation and ScalingOur first matrices are 2-by-2. We see how the matrix$$R \\ = \\\\left( \\begin{array}{rr} \\cos{\\theta} & \\sin{\\theta} \\\\ -\\sin{\\theta} & \\cos{\\theta} \\end{array} \\right)$$rotates points by the angle $\\theta$, measured in degrees.We also see how the matrix$$S \\ = \\\\left( \\begin{array}{rr} \\sigma & 0 \\\\ 0 & \\sigma \\end{array} \\right)\\ \\ \\ \\ \\ \\ \\ \\$$makes objects larger and smaller.The two can be combined with matrix multiplication. For more operations in higher dimensions, matrix multiplication provides a unifying framework.Here is one frame from the animation of rotation and scaling generated by the Rotate app. The first panel displays a 2-by-2 rotation matrix, the second panel displays a 2-by-2 diagonal scaling matrix, and the third panel displays their product. Computer GraphicsOperations with the 4-by-4 matrices that are at the heart of modern computer graphics employ a system known as \"homogeneous coordinates\". The leading 3-by-3 submatrix produces rotation and scaling in three dimensions. The fourth column produces translations.Here is one frame from an animation of rotation about the x-axis generated by the Grafix app. This is often called \"pitch\". Rotation about the y- and z-axes are \"roll\" and \"yaw\", Matrices and CubesRubik's Cube, named for its inventor, Ernő Rubik, a Hungarian professor of architecture, is the greatest mathematical puzzle of all time. Our digital simulation of the puzzle, Qube, is powered by rotation matrices.The model consists of 27 identical copies of a single small cubelet whose sides are colored red, white, blue, yellow, orange and green. Initially, all cubelets have the same orientation. A move is the simultaneous rotation of the nine cubelets in one of the six faces, by 90° or 180°, clockwise or counterclockwise. This leads to $4.3 \\times 10^{19}$ possible configurations for a scrambled cube.The object of the puzzle is to return a scrambled cube to the initial state. Most people are interested in solving the puzzle rapidly, but I am more interested in the number of moves required.Qube offers animations of many mathematical properties of Rubik's cubes. Here is a frame from one of them. SimulinkMATLAB's companion product, Simulink, is a block diagram programming environment used to design and simulate systems with multidomain models and to automatically generate the code required to operate embedded processors.Matrices are involved in dozens of different ways by Simulink, but most users rarely see operations at that detailed level. Our Simulink module shows a model of an automobile being driven on a test track and displays the pitch, roll and yaw recorded by the matrix connecting the coordinate system for the automobile to the coordinate system for the track. AI and GorillasThis is a personal story about a project in the early stages of development.My wife and I first visited gorillas in the Volcano National Park of Rwanda twelve years ago. An American primatologist named Dian Fossey had studied the gorillas between 1966 and her murder by poachers in 1985. Her book Gorillas in the Mist was very popular and was the basis for a critically acclaimed 1988 Hollywood movie starring Sigourney Weaver.We have become good friends with the people in the Gorilla Doctors organization. These African and American veterinarians attend to the health of the roughly 1,000 gorillas in the park. Most of the gorillas have African names like \"Inkundwa\" and \"Maisha\". We envision a gorilla facial recognition system that is available on cell phones and tablets so that new guides and doctors can learn the names of their patients.Inception-v3 is a convolutional neural network (CNN) that is widely used for image processing. We have a version of the network pretrained on more than a million images from the ImageNet database. This publicly available system knows nothing about gorillas. We must do additional training using photos of our unique subjects.This is where matrices are applied. Training a CNN involves determining the values of thousands of weights and coefficients. The digital photos, regarded as vectors, and repeatedly multiplied by circulant matrices where each row is a shifted copy of the other rows. Importantly, a modern CNN also contains some nonlinear layers.Here is one photo from a small test collection. Indundwa appears to have his own selfie stick. SoftwareA self-extracting MATLAB source archive of our four apps is available athttps://blogs.mathworks.com/cleve/files/Apps_mzip.mThanksThanks to Jackson Kustell, Josh Bethoney and Heather Gorr from MathWorks and Jan Ramer and Mike Cranfield from Gorilla Doctors.DedicationWe dedicate the Gorillas project to the memory of Mike Cranfield, DMV. Mike was Executive Director of the Mountain Gorillas Veterinary Project in Rwanda from 1999 until 2014. Before Rwanda, he held various positions at the Maryland Zoo in Baltimore.Three months ago, Mike sent us a disc drive containing over 14,000 photographs of gorillas he had taken in Rwanda. We are now sorting and organizing the photos to provide specialized training of the facial recognition neural net.A month ago, Mike was hospitalized from an apparent attack of West Nile Virus. He passed away on August 27. Ironically, after years of working safely in the mountain jungles of Central Africa, it is likely that he acquired the virus from a mosquito bite at his family's cabin in Canada.Get the MATLAB code (requires JavaScript) Published with MATLAB® R2023a",
+ "content_html": "
I have spent much of my career working to bring abstract linear algebra and practical matrix computation closer together. This project is my latest effort.
Over sixty years ago, as a sophomore contemplating a major in mathematics, I took a course entitled Survey of Modern Algebra. We used a now-classic textbook by MacLane and Birkhoff that featured abstract theorems about groups, rings, fields, vector spaces and linear algebra. I remember the colorful terms alias and alibi had something to do with change of basis and change of position, but I have never seen those terms again.
The next year, I took Numerical Analysis. We did some of the homework on a Burroughhs 205 Datatron and I wrote a machine language program to solve simultaneous linear equations. I was hooked.
But at the time I did not realize that the two courses were about the same magnificent object -- the matrix.
Exploring Matrices
Exploring Matrices is a multi-media project that shows matrices in action. Short videos, blog posts, interactive MATLAB software and self-study exercises investigate applications of matrices. The material is intended for studebts in an undergraduate course in linear algebra or computational science. However, anyone using matrices should find topics that interest them.
The first release of Exploring Matrices has six modules. All of the modules feature animated MATLAB displays and four of the modules include interactive MATLAB \"apps\". The modules are:
Matrix Multiplication
Rotation and Scaling
Computer Graphics
Matrices and Cubes
Simulink
AI and Gorillas %
YouTube Videos
An introduction and six videos ranging in length from one to six minutes, are available on YouTube at
The first four of these videos feature animations produced by our four MATLAB apps -- Multiply, Rotate, Grafix, and Qube. The other two videos describe two applications, simulation of control systems and neural networks for facial recognition (of gorillas).
Matrix Multiplication
Some viewers may just be learning the mechanics of matrix multiplication. Other viewers will have encountered it years ago. The traditional algorithm for computing the product of two matrices involves inner products between the rows of the first matrix and the columns of the second. A less familiar algorithm, which involves linear combinations of the columns of the first matrix, is often more efficient and informative. The two approaches produce the same final result from intermediate terms in different orders.
Here is one frame from the animation of these two algorithms generated by our Multiply app. The highlighted element in the first matrix either moves across the rows or goes down the columns.
Rotation and Scaling
Our first matrices are 2-by-2. We see how the matrix
The two can be combined with matrix multiplication. For more operations in higher dimensions, matrix multiplication provides a unifying framework.
Here is one frame from the animation of rotation and scaling generated by the Rotate app. The first panel displays a 2-by-2 rotation matrix, the second panel displays a 2-by-2 diagonal scaling matrix, and the third panel displays their product.
Computer Graphics
Operations with the 4-by-4 matrices that are at the heart of modern computer graphics employ a system known as \"homogeneous coordinates\". The leading 3-by-3 submatrix produces rotation and scaling in three dimensions. The fourth column produces translations.
Here is one frame from an animation of rotation about the x-axis generated by the Grafix app. This is often called \"pitch\". Rotation about the y- and z-axes are \"roll\" and \"yaw\",
Matrices and Cubes
Rubik's Cube, named for its inventor, Ernő Rubik, a Hungarian professor of architecture, is the greatest mathematical puzzle of all time. Our digital simulation of the puzzle, Qube, is powered by rotation matrices.
The model consists of 27 identical copies of a single small cubelet whose sides are colored red, white, blue, yellow, orange and green. Initially, all cubelets have the same orientation. A move is the simultaneous rotation of the nine cubelets in one of the six faces, by 90° or 180°, clockwise or counterclockwise. This leads to $4.3 \\times 10^{19}$ possible configurations for a scrambled cube.
The object of the puzzle is to return a scrambled cube to the initial state. Most people are interested in solving the puzzle rapidly, but I am more interested in the number of moves required.
Qube offers animations of many mathematical properties of Rubik's cubes. Here is a frame from one of them.
Simulink
MATLAB's companion product, Simulink, is a block diagram programming environment used to design and simulate systems with multidomain models and to automatically generate the code required to operate embedded processors.
Matrices are involved in dozens of different ways by Simulink, but most users rarely see operations at that detailed level. Our Simulink module shows a model of an automobile being driven on a test track and displays the pitch, roll and yaw recorded by the matrix connecting the coordinate system for the automobile to the coordinate system for the track.
AI and Gorillas
This is a personal story about a project in the early stages of development.
My wife and I first visited gorillas in the Volcano National Park of Rwanda twelve years ago. An American primatologist named Dian Fossey had studied the gorillas between 1966 and her murder by poachers in 1985. Her book Gorillas in the Mist was very popular and was the basis for a critically acclaimed 1988 Hollywood movie starring Sigourney Weaver.
We have become good friends with the people in the Gorilla Doctors organization. These African and American veterinarians attend to the health of the roughly 1,000 gorillas in the park. Most of the gorillas have African names like \"Inkundwa\" and \"Maisha\". We envision a gorilla facial recognition system that is available on cell phones and tablets so that new guides and doctors can learn the names of their patients.
Inception-v3 is a convolutional neural network (CNN) that is widely used for image processing. We have a version of the network pretrained on more than a million images from the ImageNet database. This publicly available system knows nothing about gorillas. We must do additional training using photos of our unique subjects.
This is where matrices are applied. Training a CNN involves determining the values of thousands of weights and coefficients. The digital photos, regarded as vectors, and repeatedly multiplied by circulant matrices where each row is a shifted copy of the other rows. Importantly, a modern CNN also contains some nonlinear layers.
Here is one photo from a small test collection. Indundwa appears to have his own selfie stick.
Software
A self-extracting MATLAB source archive of our four apps is available at
Thanks to Jackson Kustell, Josh Bethoney and Heather Gorr from MathWorks and Jan Ramer and Mike Cranfield from Gorilla Doctors.
Dedication
We dedicate the Gorillas project to the memory of Mike Cranfield, DMV. Mike was Executive Director of the Mountain Gorillas Veterinary Project in Rwanda from 1999 until 2014. Before Rwanda, he held various positions at the Maryland Zoo in Baltimore.
Three months ago, Mike sent us a disc drive containing over 14,000 photographs of gorillas he had taken in Rwanda. We are now sorting and organizing the photos to provide specialized training of the facial recognition neural net.
A month ago, Mike was hospitalized from an apparent attack of West Nile Virus. He passed away on August 27. Ironically, after years of working safely in the mountain jungles of Central Africa, it is likely that he acquired the virus from a mosquito bite at his family's cabin in Canada.
",
+ "url": "https://hpc.social/commercial-blog/2023/exploring-matrices/",
+
+
+
+
+
+ "date_published": "2023-09-12T03:11:52-06:00",
+ "date_modified": "2023-09-12T03:11:52-06:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2023/minigallery-sampler-of-matlab-test-matrices/",
+ "title": "MiniGallery, Sampler of MATLAB Test Matrices",
+ "summary": null,
+ "content_text": "MATLAB has dozens of test matrices. Here are a few.ContentsMini_GalleryCollectionsBlogsSoftware Mini_GalleryRandom. A = sprand(n,n,0.25). Random sparse, density = 0.25.Bucky. A = bucky. Sparse connectivity graph of the geodesic dome, the soccer ball, and the carbon-60 molecule.Wilkinson. A = wilkinson(n). Wn+. Nearly equal double eigenvalues.Band. A = triu(tril(A,2),-2). Elements near diagonal.Triangular. A = triu(A). Elements on and above diagonal.Hessenberg. A = triu(A,-1). Upper triangular plus one subdiagonal. See schur.Permutation. A = sparse(randperm(n),1:n,1). One +1 in each row and column.Companion. c = charpoly(A); A = [-c(2:end); eye(n-1,n)]. Traditional companion matrix.Fiedler. c = charpoly(A); A = fiedler(-c(2:end)). Fiedler companion matrix.Hankel. A = flip(gallery('toeppd',n)). Constant antidiagonals.Toeplitz. A = gallery('toeppd',n). Constant diagonals.Magic. A = magic(n). Magic square.Collectionsgallery. Nick Higham and MathWorks, https://www.mathworks.com/help/matlab/ref/gallery.htmlAnymatrix. Nick Higham and Mantas Mikaitis, https://nhigham.com/2021/11/09/anymatrix>SuiteSparse. Tim Davis, Yifan Hu and Scott Kolodzie, http://sparse.tamu.eduMatrixMarket, NIST, https://math.nist.gov/MatrixMarket.Blogshttps://blogs.mathworks.com/cleve/2012/11/05/magic-squares-part-2-algorithms/https://blogs.mathworks.com/cleve/2013/04/15/wilkinsons-matrices-2/.https://blogs.mathworks.com/cleve/2013/12/23/fiedler-companion-matrix/.https://blogs.mathworks.com/cleve/2021/05/12/bringing-back-the-bucky-ball/.Softwarehttps://blogs.mathworks.com/cleve/files/Mini_Gallery.mGet the MATLAB code (requires JavaScript) Published with MATLAB® R2023a",
+ "content_html": "
MATLAB has dozens of test matrices. Here are a few.
",
+ "url": "https://hpc.social/commercial-blog/2023/minigallery-sampler-of-matlab-test-matrices/",
+
+
+
+
+
+ "date_published": "2023-06-28T16:34:09-06:00",
+ "date_modified": "2023-06-28T16:34:09-06:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2023/arls-automatically-regularized-least-squares/",
+ "title": "ARLS, Automatically Regularized Least Squares",
+ "summary": null,
+ "content_text": "(I have a guest blogger today. Ron Jones worked with me in 1985 for his Ph. D. from the University of New Mexico. He retired recently after nearly 40 years at Sandia National Labs in Albuquerque and now has a chance to return to the problem he studied in his thesis. -- CBM)by Rondall Jones, rejones7@msn.comOur interest is in automatically solving difficult linear systems, A*x = bSuch systems often arise, for example, in \"inverse problems\" in which the analyst is trying to reverse the effects of natural smoothing processes such as heat dissipation, optical blurring, or indirect sensing. These problems exhibit \"ill-conditioning\", which means that the solution results are overly sensitive to insignificant changes to the observations, which are given in the right-hand-side vector, b .Here is a graphic showing this behavior using a common test matrix, a 31 x 31 Hilbert matrix, with the blue line being the ideal solution that one would hope a solver could compute. The jagged red line shows the result of a traditional solver on this problem. In fact this graph is extremely mild: the magnitude of the oscillations often measure in the millions, not just a little larger than the true solution. Traditionally analysts have approached this issue in the linear algebraic system context by appending equations to A*x = b that request each solution value, x(i), to be zero. Then, one weights these conditioning equations using a parameter usually called \"lambda\". We will call it p here. What we have to solve then is this expanded linear system: [ A ; p*I] * x = [b; 0]If we decompose A into its Singular Value Decomposition A = U * S * V'and multiply both sides by the transpose of the augmented LHS, the resulting solution to is x = V * inv(S^2 + p^2*I) * S * U' * binstead of the usual x = V * inv(S) * U' * bIt is convenient in the following discussion to represent this as x = V * PCVwhere PCV = inv(S) * U' * bis what we call the Picard Condition Vector. Then x is computed in the usual SVD manner with the change that each singular value S(i) is replaced by S(i) + p^2/S(i)This process is called Tikhonov regularization.Using Tikhonov regularization successfully requires somehow picking an appropriate value for p. Cleve Moler has for many years jokingly used the term \"eyeball norm\" to describe how to pick p. \"Try various values of p and pick the resulting solution (or its graph) that 'looks good'\".My early work in attempting to determine lambda automatically was based instead on determining when the PCV begins to seriously diverge. Beyond that point one can be fairly sure that noise in b is causing U'*b to decrease more slowly than inv(S) is increasing, so their product, which is the PCV, starts growing unacceptably. Such an algorithm can be made to work and versions of my work have been available in various forms over the years. But determining where the PCV starts growing unacceptably (which I refer to as the usable rank) is based on heuristics, moving averages, and such, as of which require choices of moving average lengths and other such parameters. This is not an optimal situation, so a I began trying to redesign algorithms that do not use any heuristics.How do we do that algorithmically? Per Christian Hansen gave a clue to this question when he said (my re-phrasing) that \"the analyst should not expect a good solution for such a problem unless the PCV is 'declining'\". We note that this adage is a context-specific application of a general requirement that when a function is represented by an orthogonal expansion the coefficients of the orthogonal basis functions should eventually decline toward zero. If this behavior does not happen, then typically either the model is incomplete or the data is contaminated. In our case the orthogonal basis is simply the columns of V, and b is the set of coefficients that would be expected to decline. A good working definition of \"declining\" has been hard to nail down. The algorithm in ARLS has implemented this concept using two specific essential steps:First, we replace the PCV by a second-degree polynomial (e.g., a parabolic) least-squares fit to the PCV. This allows a lot of the typical \"wild\" variations in the PCV to be smoothed over and thereby tolerated without eliminating the problem's distinctive behavior.Second, we don't actually fit the curve to the PCV, but rather to the logarithm of the PCV. Without this change, small values of the PCV are seen by the curve fit process as just near-zero values, with no significant difference in the effect of a value of 0.0001 or a value of 0.0000000001. But in the (base 10) logarithm of the PCV these values nicely spread out from -4 to -10 (for example).So, Phase 1 of ARLS searches a large range of values of p (remember, p is Tikhonov's \"lambda\") to find a value just barely large enough to make the slope of the parabolic fit entirely negative or zero. This gives us a tight lower bound for the \"correct\" value of p.Phase 2 of ARLS is much simpler. Since p is the minimum usable regularization parameter, the solution tends to be less smooth and less close to the ideal solution than optimum. So we simply increase p slightly to let the shape of the graph of x smooth out. Our current implementation increases p until the residual (that is, norm(A*x-b)) of the solution increases by a factor of 2. This is, unfortunately, a heuristic. But an appropriate value of it can be determined by “tuning” the algorithm on a wide range of test problems.We call this new algorithm Logarithmic Picard Condition Analysis. (If the problems you work on seem to need a bit more relaxation you can, of course, increase the number 2 a bit. It is 5 lines from the bottom of the file.) In the example shown in the graphic above, ARLS produces the blue line so closely that the ideal solution and ARLS computed solution are indistinguishable.In addition to ARLS(A,b) itself, we provide two constrained solvers built on ARLS which are called just like ARLS:ARLSNN(A,b), which constrains the solution to be non-negative (like the classic NNLS, buth with regularization.ARLSRISE(A,b) which constrains the solution to be non-decreasing. To get a non-increasing, or “falling” solution, you can compute -ARLSRISE(A,-b).Try ARLS. It's available from the MATLAB Central File Exchange, #130259, at this link.Get the MATLAB code (requires JavaScript) Published with MATLAB® R2023a",
+ "content_html": "
(I have a guest blogger today. Ron Jones worked with me in 1985 for his Ph. D. from the University of New Mexico. He retired recently after nearly 40 years at Sandia National Labs in Albuquerque and now has a chance to return to the problem he studied in his thesis. -- CBM)
Our interest is in automatically solving difficult linear systems,
A*x = b
Such systems often arise, for example, in \"inverse problems\" in which the analyst is trying to reverse the effects of natural smoothing processes such as heat dissipation, optical blurring, or indirect sensing. These problems exhibit \"ill-conditioning\", which means that the solution results are overly sensitive to insignificant changes to the observations, which are given in the right-hand-side vector, b .
Here is a graphic showing this behavior using a common test matrix, a 31 x 31 Hilbert matrix, with the blue line being the ideal solution that one would hope a solver could compute. The jagged red line shows the result of a traditional solver on this problem.
In fact this graph is extremely mild: the magnitude of the oscillations often measure in the millions, not just a little larger than the true solution. Traditionally analysts have approached this issue in the linear algebraic system context by appending equations to A*x = b that request each solution value, x(i), to be zero. Then, one weights these conditioning equations using a parameter usually called \"lambda\". We will call it p here. What we have to solve then is this expanded linear system:
[ A ; p*I] * x = [b; 0]
If we decompose A into its Singular Value Decomposition
A = U * S * V'
and multiply both sides by the transpose of the augmented LHS, the resulting solution to is
x = V * inv(S^2 + p^2*I) * S * U' * b
instead of the usual
x = V * inv(S) * U' * b
It is convenient in the following discussion to represent this as
x = V * PCV
where
PCV = inv(S) * U' * b
is what we call the Picard Condition Vector. Then x is computed in the usual SVD manner with the change that each singular value S(i) is replaced by
S(i) + p^2/S(i)
This process is called Tikhonov regularization.
Using Tikhonov regularization successfully requires somehow picking an appropriate value for p. Cleve Moler has for many years jokingly used the term \"eyeball norm\" to describe how to pick p. \"Try various values of p and pick the resulting solution (or its graph) that 'looks good'\".
My early work in attempting to determine lambda automatically was based instead on determining when the PCV begins to seriously diverge. Beyond that point one can be fairly sure that noise in b is causing U'*b to decrease more slowly than inv(S) is increasing, so their product, which is the PCV, starts growing unacceptably. Such an algorithm can be made to work and versions of my work have been available in various forms over the years. But determining where the PCV starts growing unacceptably (which I refer to as the usable rank) is based on heuristics, moving averages, and such, as of which require choices of moving average lengths and other such parameters. This is not an optimal situation, so a I began trying to redesign algorithms that do not use any heuristics.
How do we do that algorithmically? Per Christian Hansen gave a clue to this question when he said (my re-phrasing) that \"the analyst should not expect a good solution for such a problem unless the PCV is 'declining'\". We note that this adage is a context-specific application of a general requirement that when a function is represented by an orthogonal expansion the coefficients of the orthogonal basis functions should eventually decline toward zero. If this behavior does not happen, then typically either the model is incomplete or the data is contaminated. In our case the orthogonal basis is simply the columns of V, and b is the set of coefficients that would be expected to decline. A good working definition of \"declining\" has been hard to nail down. The algorithm in ARLS has implemented this concept using two specific essential steps:
First, we replace the PCV by a second-degree polynomial (e.g., a parabolic) least-squares fit to the PCV. This allows a lot of the typical \"wild\" variations in the PCV to be smoothed over and thereby tolerated without eliminating the problem's distinctive behavior.
Second, we don't actually fit the curve to the PCV, but rather to the logarithm of the PCV. Without this change, small values of the PCV are seen by the curve fit process as just near-zero values, with no significant difference in the effect of a value of 0.0001 or a value of 0.0000000001. But in the (base 10) logarithm of the PCV these values nicely spread out from -4 to -10 (for example).
So, Phase 1 of ARLS searches a large range of values of p (remember, p is Tikhonov's \"lambda\") to find a value just barely large enough to make the slope of the parabolic fit entirely negative or zero. This gives us a tight lower bound for the \"correct\" value of p.
Phase 2 of ARLS is much simpler. Since p is the minimum usable regularization parameter, the solution tends to be less smooth and less close to the ideal solution than optimum. So we simply increase p slightly to let the shape of the graph of x smooth out. Our current implementation increases p until the residual (that is, norm(A*x-b)) of the solution increases by a factor of 2. This is, unfortunately, a heuristic. But an appropriate value of it can be determined by “tuning” the algorithm on a wide range of test problems.
We call this new algorithm Logarithmic Picard Condition Analysis. (If the problems you work on seem to need a bit more relaxation you can, of course, increase the number 2 a bit. It is 5 lines from the bottom of the file.) In the example shown in the graphic above, ARLS produces the blue line so closely that the ideal solution and ARLS computed solution are indistinguishable.
In addition to ARLS(A,b) itself, we provide two constrained solvers built on ARLS which are called just like ARLS:
ARLSNN(A,b), which constrains the solution to be non-negative (like the classic NNLS, buth with regularization.
ARLSRISE(A,b) which constrains the solution to be non-decreasing. To get a non-increasing, or “falling” solution, you can compute -ARLSRISE(A,-b).
Try ARLS. It's available from the MATLAB Central File Exchange, #130259, at this link.
",
+ "url": "https://hpc.social/commercial-blog/2023/arls-automatically-regularized-least-squares/",
+
+
+
+
+
+ "date_published": "2023-06-17T00:57:05-06:00",
+ "date_modified": "2023-06-17T00:57:05-06:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2023/happy-birthday-john-gilbert/",
+ "title": "Happy Birthday, John Gilbert",
+ "summary": null,
+ "content_text": "I have just returned from a one-day workshop at U. C. Santa Barbara honoring John Gilbert on his 70th birthday and his official retirement after 20 years on the UCSB faculty. ContentsNew MexicoXerox PARCFriendshipUCSBNew MexicoI have known John since he was a teenager.In the late 1960's, John's father, Ed Gilbert, together with fellow mathematicians Don Morrison and Sto Bell, left their jobs at Sandia National Labs in Albuquerque and established the Computer Science Department at the University of New Mexico. Ed was especially interested in undergraduate education and led the department to early adoption of Pascal and Unix in the curriculum.In 1972, my wife at the time, Nancy Martin, and I were seeking a university where we could both have faculty positions. UNM offered me a job in the Math Department and Nancy one in Computer Science. I stayed at UNM for 13 years, eventually succeeding Morrison as Chairman of Computer Science.When I first met the Gilbert family in '72, both John and his younger brother Erik were undergrad students at UNM. A year later, both brothers were admitted to grad school in Computer Science at Stanford. After getting their Ph.D.'s in CS at Stanford, Erik went on to cofound a software company that produced a dialect of Lisp and John joined the Computer Science Department at Cornell.Xerox PARCAfter several years at Cornell, John returned to California and the famous Xerox Palo Alto Research Center.Sometime around Christmas in 1988, Ian Duff, the British authority on sparse matrices, wanted to go skiing in the Sierras. Iain arranged with Gene Golub to give a talk at Stanford. I was living in Menlo Park at the time and went to the talk. So did John Gilbert and Rob Schreiber, from Hewlett Packard Research in Palo Alto.After the talk, everybody went for coffee at Tresidder, Stanford's student union. During the ensuing discussion, John, Rob and I decided it was time to have sparse matrices in MATLAB. The first new data structure in MATLAB and its description resulted. See the links at SIAM and MathWorks.FriendshipOur collaboration on sparse matrices has led to an enduring friendship. Every year, at SCxx, the High Performance Computing conference in November, the three of us and Jack Dongarra get together. Here we are with Sven Hammarling from NAG, at SC17 in Denver. UCSBAfter a dozen years at PARC, John returned to academic life at the University of California near Santa Barbara. Last Saturday, Aydin Buluc and Daniel Lokshtanov, two of John's UCSB Ph. D. students, organized the JRG70 workshop. Here is a link to the Web page, including the list of talks presented. link. It was the first time since Tresidder that Iain, John, Rob and I have all been together.Here is a portrait of the JRG70 participants. As usual, John is being modest; he's in the back row, in a burgundy sweater. Get the MATLAB code (requires JavaScript) Published with MATLAB® R2023a",
+ "content_html": "
I have just returned from a one-day workshop at U. C. Santa Barbara honoring John Gilbert on his 70th birthday and his official retirement after 20 years on the UCSB faculty.
In the late 1960's, John's father, Ed Gilbert, together with fellow mathematicians Don Morrison and Sto Bell, left their jobs at Sandia National Labs in Albuquerque and established the Computer Science Department at the University of New Mexico. Ed was especially interested in undergraduate education and led the department to early adoption of Pascal and Unix in the curriculum.
In 1972, my wife at the time, Nancy Martin, and I were seeking a university where we could both have faculty positions. UNM offered me a job in the Math Department and Nancy one in Computer Science. I stayed at UNM for 13 years, eventually succeeding Morrison as Chairman of Computer Science.
When I first met the Gilbert family in '72, both John and his younger brother Erik were undergrad students at UNM. A year later, both brothers were admitted to grad school in Computer Science at Stanford. After getting their Ph.D.'s in CS at Stanford, Erik went on to cofound a software company that produced a dialect of Lisp and John joined the Computer Science Department at Cornell.
Xerox PARC
After several years at Cornell, John returned to California and the famous Xerox Palo Alto Research Center.
Sometime around Christmas in 1988, Ian Duff, the British authority on sparse matrices, wanted to go skiing in the Sierras. Iain arranged with Gene Golub to give a talk at Stanford. I was living in Menlo Park at the time and went to the talk. So did John Gilbert and Rob Schreiber, from Hewlett Packard Research in Palo Alto.
After the talk, everybody went for coffee at Tresidder, Stanford's student union. During the ensuing discussion, John, Rob and I decided it was time to have sparse matrices in MATLAB. The first new data structure in MATLAB and its description resulted. See the links at SIAM and MathWorks.
Friendship
Our collaboration on sparse matrices has led to an enduring friendship. Every year, at SCxx, the High Performance Computing conference in November, the three of us and Jack Dongarra get together. Here we are with Sven Hammarling from NAG, at SC17 in Denver.
UCSB
After a dozen years at PARC, John returned to academic life at the University of California near Santa Barbara. Last Saturday, Aydin Buluc and Daniel Lokshtanov, two of John's UCSB Ph. D. students, organized the JRG70 workshop. Here is a link to the Web page, including the list of talks presented. link. It was the first time since Tresidder that Iain, John, Rob and I have all been together.
Here is a portrait of the JRG70 participants. As usual, John is being modest; he's in the back row, in a burgundy sweater.
",
+ "url": "https://hpc.social/commercial-blog/2023/happy-birthday-john-gilbert/",
+
+
+
+
+
+ "date_published": "2023-06-07T14:48:32-06:00",
+ "date_modified": "2023-06-07T14:48:32-06:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2023/special-notice/",
+ "title": "Special Notice",
+ "summary": null,
+ "content_text": "Special Notice If you have been following my posts about Wordle, be sure to see the puzzle in today's New York Times, Tuesday, April 4.Get the MATLAB code (requires JavaScript) Published with MATLAB® R2023a",
+ "content_html": "
Special Notice
If you have been following my posts about Wordle, be sure to see the puzzle in today's New York Times, Tuesday, April 4.
",
+ "url": "https://hpc.social/commercial-blog/2023/special-notice/",
+
+
+
+
+
+ "date_published": "2023-04-04T15:12:36-06:00",
+ "date_modified": "2023-04-04T15:12:36-06:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2023/my-chat-with-ernie-a-chinese-chat-bot/",
+ "title": "My Chat with Ernie, a Chinese Chat Bot",
+ "summary": null,
+ "content_text": "I recently had an opportunity to chat with Ernie, the Large Language Model currently under development at the Chinese internet search giant, Baidu. As I expected, Ernie's responses are in Chinese. I don't speak Chinese, so I have asked Google Translate for the response in English.ContentsEmbarrassingly ParallelLove MATLAB?Cleve's CornerConclusionEmbarrassingly ParallelOne of my questions that Microsoft's ChatGPT answered incorrectly was Who coined the term \"embarrassingly parallel?\"Ernie's response to the same question was Goggle translate: Who coined the embarrassing word parallel?Well that's a very unfortunate misunderstanding. And, it's just repeating the question. That's an old trick; the mother of all chat bots, Eliza , used it over sixty years ago.Love MATLAB?One of the questions I often ask when I meet someone for the first time is Do you use MATLAB?Earnie's reply was Google translation is I think I love you.Well, that's nice, but doesn't really answer my question.Cleve's CornerCan a chat bot assist with writing this blog? I don't expect help with the MATLAB code, or with the graphics, or with any mathematics. How about the prose, if it isn't too technical.Here is the opening sentence of the post I made a few weeks ago. The 4-by-4 matrices in the panels on the following screenshots are at the heart of computer graphics.I asked Ernie how that would look in Chinese. Ernie responded with When Google translates that back to English, we get The 4×4 matrix in the screenshot panel below is at the heart of computer graphics.Ernie decided to make the sentence singular, which happens to shorten it. But I am afraid that isn't much help for this blog.ConclusionI have already described my chat with ChatGPT. This Chinese competitor is certainly not an improvement. For now, I will continue to produce this blog the old fashioned way, without any \"help\" from AI.Get the MATLAB code (requires JavaScript) Published with MATLAB® R2023a",
+ "content_html": "
I recently had an opportunity to chat with Ernie, the Large Language Model currently under development at the Chinese internet search giant, Baidu. As I expected, Ernie's responses are in Chinese. I don't speak Chinese, so I have asked Google Translate for the response in English.
One of my questions that Microsoft's ChatGPT answered incorrectly was
Who coined the term \"embarrassingly parallel?\"
Ernie's response to the same question was
Goggle translate:
Who coined the embarrassing word parallel?
Well that's a very unfortunate misunderstanding. And, it's just repeating the question. That's an old trick; the mother of all chat bots, Eliza , used it over sixty years ago.
Love MATLAB?
One of the questions I often ask when I meet someone for the first time is
Do you use MATLAB?
Earnie's reply was
Google translation is
I think I love you.
Well, that's nice, but doesn't really answer my question.
Cleve's Corner
Can a chat bot assist with writing this blog? I don't expect help with the MATLAB code, or with the graphics, or with any mathematics. How about the prose, if it isn't too technical.
The 4-by-4 matrices in the panels on the following screenshots are at the heart of computer graphics.
I asked Ernie how that would look in Chinese. Ernie responded with
When Google translates that back to English, we get
The 4×4 matrix in the screenshot panel below is at the heart of computer graphics.
Ernie decided to make the sentence singular, which happens to shorten it. But I am afraid that isn't much help for this blog.
Conclusion
I have already described my chat with ChatGPT. This Chinese competitor is certainly not an improvement. For now, I will continue to produce this blog the old fashioned way, without any \"help\" from AI.
",
+ "url": "https://hpc.social/commercial-blog/2023/my-chat-with-ernie-a-chinese-chat-bot/",
+
+
+
+
+
+ "date_published": "2023-04-01T05:00:26-06:00",
+ "date_modified": "2023-04-01T05:00:26-06:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2023/three-wordle-assistants/",
+ "title": "Three Wordle Assistants",
+ "summary": null,
+ "content_text": "When I tackle a Wordle puzzle, I like to make all the key decisions myself. My three assistants set up puzzles and suggest words when I ask for help, but I guide the actual solution. My assistants also make it possible for me to play Wordle anywhere, anytime, even when my laptop is in airplane mode. I don't need the New York Times or access to the Web.ContentsThree AssistantsVocabularyWordsWordleNYTPared DownFive GoldsThanksSoftwareThree AssistantsWordler, Words and Wordie are the three assistants. Wordler replaces the Times by generating puzzles and evaluating responses. Words provides lists of possible responses. Wordie handles the Wordler Window and colors the letters gray, green or gold.VocabularyWords has a vocabulary of 4665 five-letter English words. Any of them are acceptable responses. The vocabulary begins with vocab = [ ... \"ABEAM\" \"ABETS\" \"ABHOR\" \"ABIDE\" \"ABLED\" \"ABLER\" \"ABODE\" \"ABORT\" ...And, 584 lines later, ends with \"ZILCH\" \"ZINCS\" \"ZINGS\" \"ZIPPY\" \"ZOMBI\" \"ZONAL\" \"ZONED\" \"ZONES\" ... \"ZOOMS\" ];If you were to print the entire vocabulary with 40 lines per page, you would print over 100 pages of words.WordsIt took me a long time to write the Words assistant, which is called whenever the Words button in the Wordle Window is clicked. Words is supported by a seventeen-program library of functions named Wordspq where p and q are nonnegative integers with p+q <= 5. Wordspq finds words with p green letters and q gold letters. The programs in the Words library all have the same structure involving five nested for loops.The last line of Words is feval(['Words' p q],Gray,Green,GreenLoc,Gold,GoldLoc)Gray, Green and Gold are lists of letters with specified colors and with locations GreenLoc and GoldLoc. Locating the green letters is easy because they must be in specific slots. Locating the gold letters is tricky because each of them can be in any of several different slots.For example, this situation in the NYT puzzle described below would result in a call to Words13 with Gray = 'AIHEC' Green = 'T' GreenLoc = 5 Gold = 'ROU' GoldLoc = {[2,3],[3,4],[1,2,4]} WordleWordle starts a game by choosing a secret random target from the vocabulary, or from a smaller subset about half the size. At the same time, I choose my starting word, which is usually RATIO. My assistants respond with the Wordler Window and a simple keyboard. The gold O tells me the target contains an O, that it is not in position 5, and the target does not contain R, A, T, or I. I know there are hundreds of such words in the vocabulary. One of them is DEMOS, which I enter on the keyboard. DEMOS happens to be a very lucky choice. The target has an E in the second slot, an S in the last slot, M and O in the remaining slots, and no D. When the answer does not occur to me in a minute or two, I click the Words button. The response is MEOWS cnt = 1So, there is only one word to choose, and it earns five greens. NYTLet's do the Times puzzle from March 23. I start with my mathematical RATIO. I see that the answer contains R, T and O and does not contain A or I.I happen to remember that OTHER qualifies. It does not hit any new letters, but it places additional restrictions on the ones I already have and eliminates E and H.Words now lists 37 words that I should choose from. I pick COURT because it contains U, the only remaining vowel.Words informs me that there are only two possibilities left, TROUT and GROUT. I pick the one without a double consonant and it is the winner. Pared DownHere is an atypical, but instructive, example. For this puzzle I am pleased to see Wordler gives RATIO a green A in position 2 and a gold R somewhere in positions 3 through 5. I remember one of my favorite \"technical\" terms, PARSE.To use a baseball metaphor, PARSE hits a triple and almost gets an in-the-park home run. Now I need to ask Words for qualifying responses. There are exactly two, PARED and PARER. (Both come from the verb \"to pare\", which means to cut the outer skin off something.)One of the choices has a double consonant, so I choose the other one. When it doesn't fly, the only choice left earns the five-leaf clover. Five GoldsHow do I generate five golds? I need the starting guess to be a permutation of the final answer. A few moments thought suggests TAKES and SKATE. I am sure there are other possibilities. But this one is special because STEAK makes it triplets. TEAKS would make four permutations but does not meet the \"hard mode\" restrictions. ThanksOver a year ago, MATLAB programs for solving Wordle puzzles were described by Adam Filion as a guest blogger on Loren's blog and by Matt Tearle with a YouTube video.SoftwareWorking on my Wordle obsession has been very interesting. I have developed some useful tools and I see forgotten five-letter words everywhere. You can share the fun by downloading the code at this link and running it yourself.Get the MATLAB code (requires JavaScript) Published with MATLAB® R2023a",
+ "content_html": "
When I tackle a Wordle puzzle, I like to make all the key decisions myself. My three assistants set up puzzles and suggest words when I ask for help, but I guide the actual solution. My assistants also make it possible for me to play Wordle anywhere, anytime, even when my laptop is in airplane mode. I don't need the New York Times or access to the Web.
Wordler, Words and Wordie are the three assistants. Wordler replaces the Times by generating puzzles and evaluating responses. Words provides lists of possible responses. Wordie handles the Wordler Window and colors the letters gray, green or gold.
Vocabulary
Words has a vocabulary of 4665 five-letter English words. Any of them are acceptable responses. The vocabulary begins with
If you were to print the entire vocabulary with 40 lines per page, you would print over 100 pages of words.
Words
It took me a long time to write the Words assistant, which is called whenever the Words button in the Wordle Window is clicked.
Words is supported by a seventeen-program library of functions named Wordspq where p and q are nonnegative integers with p+q <= 5. Wordspq finds words with p green letters and q gold letters. The programs in the Words library all have the same structure involving five nested for loops.
The last line of Words is
feval(['Words' p q],Gray,Green,GreenLoc,Gold,GoldLoc)
Gray, Green and Gold are lists of letters with specified colors and with locations GreenLoc and GoldLoc. Locating the green letters is easy because they must be in specific slots. Locating the gold letters is tricky because each of them can be in any of several different slots.
For example, this situation in the NYT puzzle described below would result in a call to Words13 with
Wordle starts a game by choosing a secret random target from the vocabulary, or from a smaller subset about half the size. At the same time, I choose my starting word, which is usually RATIO. My assistants respond with the Wordler Window and a simple keyboard.
The gold O tells me the target contains an O, that it is not in position 5, and the target does not contain R, A, T, or I. I know there are hundreds of such words in the vocabulary. One of them is DEMOS, which I enter on the keyboard.
DEMOS happens to be a very lucky choice. The target has an E in the second slot, an S in the last slot, M and O in the remaining slots, and no D. When the answer does not occur to me in a minute or two, I click the Words button. The response is
MEOWS cnt = 1
So, there is only one word to choose, and it earns five greens.
NYT
Let's do the Times puzzle from March 23. I start with my mathematical RATIO. I see that the answer contains R, T and O and does not contain A or I.
I happen to remember that OTHER qualifies. It does not hit any new letters, but it places additional restrictions on the ones I already have and eliminates E and H.
Words now lists 37 words that I should choose from. I pick COURT because it contains U, the only remaining vowel.
Words informs me that there are only two possibilities left, TROUT and GROUT. I pick the one without a double consonant and it is the winner.
Pared Down
Here is an atypical, but instructive, example. For this puzzle I am pleased to see Wordler gives RATIO a green A in position 2 and a gold R somewhere in positions 3 through 5. I remember one of my favorite \"technical\" terms, PARSE.
To use a baseball metaphor, PARSE hits a triple and almost gets an in-the-park home run. Now I need to ask Words for qualifying responses. There are exactly two, PARED and PARER. (Both come from the verb \"to pare\", which means to cut the outer skin off something.)
One of the choices has a double consonant, so I choose the other one. When it doesn't fly, the only choice left earns the five-leaf clover.
Five Golds
How do I generate five golds? I need the starting guess to be a permutation of the final answer. A few moments thought suggests TAKES and SKATE. I am sure there are other possibilities. But this one is special because STEAK makes it triplets. TEAKS would make four permutations but does not meet the \"hard mode\" restrictions.
Thanks
Over a year ago, MATLAB programs for solving Wordle puzzles were described by Adam Filion as a guest blogger on Loren's blog and by Matt Tearle with a YouTube video.
Software
Working on my Wordle obsession has been very interesting. I have developed some useful tools and I see forgotten five-letter words everywhere. You can share the fun by downloading the code at this link and running it yourself.
",
+ "url": "https://hpc.social/commercial-blog/2023/three-wordle-assistants/",
+
+
+
+
+
+ "date_published": "2023-03-28T03:00:55-06:00",
+ "date_modified": "2023-03-28T03:00:55-06:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2023/wordle-sneak-previews/",
+ "title": "Wordle Sneak Previews",
+ "summary": null,
+ "content_text": "ContentsEarly BirdsEarly BirdsThere several sites on the Web that reveal the solution to the Wordle puzzle in the New York Times while it is still in play. Some of these sites are in India, where India Standard Time is 9-1/2 hours ahead of Eastern Daylight Time, so India sees the puzzle long before the USA does. These sites surround their puzzle clues with ads and are trying to get more visitors.For a while, whenever I get a chance, I intend try to update this animation with the latest reveals. I don't have any obvious ads, but I have to admit that my own motivation is similar to the other sites. Get the MATLAB code (requires JavaScript) Published with MATLAB® R2023a",
+ "content_html": "
There several sites on the Web that reveal the solution to the Wordle puzzle in the New York Times while it is still in play. Some of these sites are in India, where India Standard Time is 9-1/2 hours ahead of Eastern Daylight Time, so India sees the puzzle long before the USA does. These sites surround their puzzle clues with ads and are trying to get more visitors.
For a while, whenever I get a chance, I intend try to update this animation with the latest reveals. I don't have any obvious ads, but I have to admit that my own motivation is similar to the other sites.
",
+ "url": "https://hpc.social/commercial-blog/2023/wordle-sneak-previews/",
+
+
+
+
+
+ "date_published": "2023-03-24T19:18:10-06:00",
+ "date_modified": "2023-03-24T19:18:10-06:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2023/wordbot-and-words-my-wordle-assistants/",
+ "title": "WordBot and Words, My Wordle Assistants",
+ "summary": null,
+ "content_text": "I am late joining the Wordle craze. Over a year ago, MATLAB programs for solving Wordle puzzles were described by Adam Filion as a guest blogger on Loren's blog and by Matt Tearle with a YouTube video. But my programs for Wordle Assistants are different. WordBot doesn't try to solve any puzzles and Words just supplies lists of possible words. I enjoy providing the solution logic myself.Here are two examples, taken from recent Wordle puzzles in the New York Times.ContentsWednesdayThursdayFour Days in MarchSoftwareWednesdayWordBot has a list of 4676 possible words, but knows nothing about their probabilities, so I don't ask for any assistance with the opening guess.I like to use mathematical words whenever possible. I usually start with RATIO, which has three vowels and two popular consonants. RATIO was a good opening move for the puzzle in the Times on Wednesday. It received a green R and a gold A. I informed WordBot of our good fortune using 2, 1 and 0 to indicate green, gold and gray. My faithful assistant responded by reproducing the first graphic in the Times. WordBot ratio 21000 Words is my suite of programs that produce lists of acceptable words for various scenarios. In this situation with an R as the first letter, an A somewhere in the last three letters and T, I and O on the gray list, Words finds 25 words, starting with REACH and ending with RUMBA.The last of those 25 words got my attention. I decided to try RUMBA on my second move. I knew RUMBA was unlikely to succeed but would be spectacular if it did. Sure enough, Wordle didn't want to dance. WordBot rumba 20001 Three more letters gray-listed and A limited to two slots reduces the number of possible words from 25 to 18. The first word on the list is still REACH. WordBot reach 22100 There are now 11 possibilities.READSREADYREALSREAPSREARSREGALRELAXRELAYRENALREPAYRERANI need to relax. WordBot relax 22120 I don't need another list of possibilities. I can quickly see the previous list has only two words that end in L. The choice between \"fit for a monarch\" and \"pertaining to kidney function\" is clear. I have solved Wednesday's puzzle in five moves, including the Hail Mary at move two. WordBot regal 22222 closeThursdayThursday's puzzle in the Times offered different challenges. As always, I started with RATIO. This time I get only one gold letter. WordBot ratio 10000 I need an R somewhere in the last four positions and can't use A, T, I or O. Words knows 229 qualified candidates. I choose another mathematical word. WordBot perms 01100 I now must have an R and an E and can't have any of those seven grays. Words offers 72 possibilities. Have I been in an accident? WordBot wreck 21200 Well, that's much better. Two greens, one gold, and nine grays. There is only one possibility. The solution must be WHERE. WordBot where 22222 closeFour Days in MarchWednesday, Thursday, Friday and Saturday.If your browser isn't showing the animation, look here. SoftwareThis code is immature. Be gentle and let me know how it works for you.Get the MATLAB code (requires JavaScript) Published with MATLAB® R2023a",
+ "content_html": "
I am late joining the Wordle craze. Over a year ago, MATLAB programs for solving Wordle puzzles were described by Adam Filion as a guest blogger on Loren's blog and by Matt Tearle with a YouTube video. But my programs for Wordle Assistants are different. WordBot doesn't try to solve any puzzles and Words just supplies lists of possible words. I enjoy providing the solution logic myself.
Here are two examples, taken from recent Wordle puzzles in the New York Times.
WordBot has a list of 4676 possible words, but knows nothing about their probabilities, so I don't ask for any assistance with the opening guess.
I like to use mathematical words whenever possible. I usually start with RATIO, which has three vowels and two popular consonants. RATIO was a good opening move for the puzzle in the Times on Wednesday. It received a green R and a gold A. I informed WordBot of our good fortune using 2, 1 and 0 to indicate green, gold and gray. My faithful assistant responded by reproducing the first graphic in the Times.
WordBot ratio21000
Words is my suite of programs that produce lists of acceptable words for various scenarios. In this situation with an R as the first letter, an A somewhere in the last three letters and T, I and O on the gray list, Words finds 25 words, starting with REACH and ending with RUMBA.
The last of those 25 words got my attention. I decided to try RUMBA on my second move. I knew RUMBA was unlikely to succeed but would be spectacular if it did. Sure enough, Wordle didn't want to dance.
WordBot rumba20001
Three more letters gray-listed and A limited to two slots reduces the number of possible words from 25 to 18. The first word on the list is still REACH.
I don't need another list of possibilities. I can quickly see the previous list has only two words that end in L. The choice between \"fit for a monarch\" and \"pertaining to kidney function\" is clear. I have solved Wednesday's puzzle in five moves, including the Hail Mary at move two.
WordBot regal22222
close
Thursday
Thursday's puzzle in the Times offered different challenges. As always, I started with RATIO. This time I get only one gold letter.
WordBot ratio10000
I need an R somewhere in the last four positions and can't use A, T, I or O. Words knows 229 qualified candidates. I choose another mathematical word.
WordBot perms01100
I now must have an R and an E and can't have any of those seven grays. Words offers 72 possibilities. Have I been in an accident?
WordBot wreck21200
Well, that's much better. Two greens, one gold, and nine grays. There is only one possibility. The solution must be WHERE.
WordBot where22222
close
Four Days in March
Wednesday, Thursday, Friday and Saturday.
If your browser isn't showing the animation, look here.
Software
This code is immature. Be gentle and let me know how it works for you.
",
+ "url": "https://hpc.social/commercial-blog/2023/wordbot-and-words-my-wordle-assistants/",
+
+
+
+
+
+ "date_published": "2023-03-11T19:07:02-07:00",
+ "date_modified": "2023-03-11T19:07:02-07:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2023/r2-d2-rotations-and-dilations-in-two-dimensions/",
+ "title": "R2-D2, Rotations and Dilations in Two Dimensions",
+ "summary": null,
+ "content_text": "R2_D2 is is the name I've given a new MATLAB program that provides animations of 2-by-2 rotation and dilation matrices. I admit I chose \"dilations\" so the acronym would be memorable, but otherwise the code has little to do with the famous Star Wars droid.ContentsHouseHandRotationDilationBothR2_D2Further ReadingHouseThis outline of a house is featured in Experiments with MATLAB. The data are the 11 blue dots. The coordinates of each dot form a 2-by-1 vector; the 2-by-2 rotation and dilation matrices multiply each of these vectors separately. (The lines between the dots complete the picture and are not involved in any computation.) The house also appears in several editions of Gil Strang's textbooks. The cover of the third edition of Strang's Introduction to Linear Algebra features nine houses on a quilt made by Gil's friend Chris Curtis. HandThis outline of a hand, which I made from measurements of my own hand, is also used in Experiments with MATLAB. There are 37 points, so Hand is a 2-by-37 matrix. RotationMultiplication by this matrix produces a two-dimensional rotation by an angle theta.$$ R = \\left( \\begin{array}{rr} \\cos{\\theta} & \\sin{\\theta} \\\\ - \\sin{\\theta} & \\cos{\\theta} \\end{array} \\right) $$R is displayed in the first panel. If the house is not rotating in your browser, try this link: https://blogs.mathworks.com/cleve/files/house_rotate.gif DilationDilation is the process of making objects larger or smaller. Multiplication by this diagonal matrix produces a dilation by a factor sigma.$$ S = \\left( \\begin{array}{rr} \\sigma & 0 \\\\ 0 & \\sigma \\end{array} \\right) $$S is displayed in the second panel. The animation is also available at: https://blogs.mathworks.com/cleve/files/hand_dilate.gif BothHere rotation and dilation are combined. The product of the rotation and dilation matrices drives the action. If you are missing all the action, try: https://blogs.mathworks.com/cleve/files/hand_both.gif R2_D2When you run R2_D2 on your own computer, you can drive the rotations and dilations yourself. Mousing outside of the object creates rotation and mousing inside produces dilation.The R2_D2 program is available from https://blogs.mathworks.com/cleve/files/R2_D2_4.m.Further ReadingIf you are not familiar with matrices, or just want a quick refresher, check out the Matrices chapter of Experiments with MATLAB. Exercise 4.14 is particularly handy.Get the MATLAB code (requires JavaScript) Published with MATLAB® R2023a",
+ "content_html": "
R2_D2 is is the name I've given a new MATLAB program that provides animations of 2-by-2 rotation and dilation matrices. I admit I chose \"dilations\" so the acronym would be memorable, but otherwise the code has little to do with the famous Star Wars droid.
This outline of a house is featured in Experiments with MATLAB. The data are the 11 blue dots. The coordinates of each dot form a 2-by-1 vector; the 2-by-2 rotation and dilation matrices multiply each of these vectors separately. (The lines between the dots complete the picture and are not involved in any computation.)
The house also appears in several editions of Gil Strang's textbooks. The cover of the third edition of Strang's Introduction to Linear Algebra features nine houses on a quilt made by Gil's friend Chris Curtis.
Hand
This outline of a hand, which I made from measurements of my own hand, is also used in Experiments with MATLAB. There are 37 points, so Hand is a 2-by-37 matrix.
Rotation
Multiplication by this matrix produces a two-dimensional rotation by an angle theta.
When you run R2_D2 on your own computer, you can drive the rotations and dilations yourself. Mousing outside of the object creates rotation and mousing inside produces dilation.
If you are not familiar with matrices, or just want a quick refresher, check out the Matrices chapter of Experiments with MATLAB. Exercise 4.14 is particularly handy.
",
+ "url": "https://hpc.social/commercial-blog/2023/r2-d2-rotations-and-dilations-in-two-dimensions/",
+
+
+
+
+
+ "date_published": "2023-03-03T19:50:25-07:00",
+ "date_modified": "2023-03-03T19:50:25-07:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2023/my-chat-with-chatgpt/",
+ "title": "My Chat With ChatGPT",
+ "summary": null,
+ "content_text": "While it is still fresh in my mind, I want to describe the conversation I had with a publicly available version of ChatGPT, the much-discussed large language model, LLM, for conversational artificial intelligence.ContentsMixed ReceptionWhere Is Sydney?Me and AIMe and ChatGPTAI WintersTruthMixed ReceptionA newer version of ChatGPT than the one I used is available to selected journalists and computer industry observers. Their reaction has been, shall I say, mixed. At first, some of the reports were positive and even ecstatic. Most of these early reports were from people whose primary concern is the stock market, not AI technology. Many of the more recent and more careful reports have been negative and critical.Where Is Sydney?I have given ChatGPT the nickname \"Chad\". Some early users of one of Chad's competitors asked deliberately provocative questions and encountered a cranky alter-ego named \"Sydney\". I didn't ask my Chad any unfair questions and didn't encounter any Sydney's.Me and AII have been a long-time observer of -- although not a contributor to -- artificial intelligence research.I took AI courses at Stanford from the inventor of the field, John McCarthy.Bill McKeeman and I entered McCarthy's chess program in a San Francisco Chronicle's by-mail chess contest. (The computer did not fair well.)I used Joe Weizenbaum's computer program Eliza, the very first Chat Bot.I was once married to someone with a PhD in AI.Symbolic Math, like MathWorks now does in our Toolbox, and which we used to do with Macsyma and Maple, was once considered AI.The wild animal trail cameras project that I did a few years ago with Heather Gorr and Jim Sanderson uses modern machine learning and AI.Me and ChatGPTI talked to -- I should say chatted with, or actually typed at -- Chad for most of an hour on a recent evening. Think of Stephen Hawking in a Web Browser. Chad's responses were always courteous and conversational. And the majority of Chad's responses were factually correct.However, a surprising number of Chad's answers were just plain wrong. Some examples:I was neither born in, nor raised in, rural New Mexico.I did not get a PhD from the University of Michigan. Neither did my wife, Patsy.Patsy is not the mother of my daughter Kam, nor of my sister Betsy.Patsy is not an expert in computational fluid dynamics.Ken Kennedy did not coin the term \"embarrassingly parallel.\"Pam McCorduck never worked for the Santa Fe Institute.I cannot find any reference to the guys Chad claimed improved Sympletic Spacewar.All of Chad's incorrect responses could have been fact-checked by simple Google queries.AI WintersEverybody wants to combine the conversational style offered by large language models with the reliability and breadth provided by Google. Now THAT sounds like a really good idea.Artificial intelligence has a history of flush successes interspersed with fallow periods known as AI Winters. I am afraid that continued obsession with Chat Bots might lead to another AI Winter.TruthSteve Eddins revealed the Truth behind ChatGPT with this internal MathWorks Yammer post. Get the MATLAB code (requires JavaScript) Published with MATLAB® R2023a",
+ "content_html": "
While it is still fresh in my mind, I want to describe the conversation I had with a publicly available version of ChatGPT, the much-discussed large language model, LLM, for conversational artificial intelligence.
A newer version of ChatGPT than the one I used is available to selected journalists and computer industry observers. Their reaction has been, shall I say, mixed. At first, some of the reports were positive and even ecstatic. Most of these early reports were from people whose primary concern is the stock market, not AI technology. Many of the more recent and more careful reports have been negative and critical.
Where Is Sydney?
I have given ChatGPT the nickname \"Chad\". Some early users of one of Chad's competitors asked deliberately provocative questions and encountered a cranky alter-ego named \"Sydney\". I didn't ask my Chad any unfair questions and didn't encounter any Sydney's.
Me and AI
I have been a long-time observer of -- although not a contributor to -- artificial intelligence research.
I took AI courses at Stanford from the inventor of the field, John McCarthy.
Bill McKeeman and I entered McCarthy's chess program in a San Francisco Chronicle's by-mail chess contest. (The computer did not fair well.)
I used Joe Weizenbaum's computer program Eliza, the very first Chat Bot.
I was once married to someone with a PhD in AI.
Symbolic Math, like MathWorks now does in our Toolbox, and which we used to do with Macsyma and Maple, was once considered AI.
The wild animal trail cameras project that I did a few years ago with Heather Gorr and Jim Sanderson uses modern machine learning and AI.
Me and ChatGPT
I talked to -- I should say chatted with, or actually typed at -- Chad for most of an hour on a recent evening. Think of Stephen Hawking in a Web Browser. Chad's responses were always courteous and conversational. And the majority of Chad's responses were factually correct.
However, a surprising number of Chad's answers were just plain wrong. Some examples:
I was neither born in, nor raised in, rural New Mexico.
I did not get a PhD from the University of Michigan. Neither did my wife, Patsy.
Patsy is not the mother of my daughter Kam, nor of my sister Betsy.
Patsy is not an expert in computational fluid dynamics.
Ken Kennedy did not coin the term \"embarrassingly parallel.\"
Pam McCorduck never worked for the Santa Fe Institute.
I cannot find any reference to the guys Chad claimed improved Sympletic Spacewar.
All of Chad's incorrect responses could have been fact-checked by simple Google queries.
AI Winters
Everybody wants to combine the conversational style offered by large language models with the reliability and breadth provided by Google. Now THAT sounds like a really good idea.
Artificial intelligence has a history of flush successes interspersed with fallow periods known as AI Winters. I am afraid that continued obsession with Chat Bots might lead to another AI Winter.
Truth
Steve Eddins revealed the Truth behind ChatGPT with this internal MathWorks Yammer post.
",
+ "url": "https://hpc.social/commercial-blog/2023/my-chat-with-chatgpt/",
+
+
+
+
+
+ "date_published": "2023-02-22T02:06:53-07:00",
+ "date_modified": "2023-02-22T02:06:53-07:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2023/grafix-users-guide/",
+ "title": "Grafix Users Guide",
+ "summary": null,
+ "content_text": "This is a quick look at Grafix, our tool for exploring matrices via 3-D computer graphics. ContentsMatricesAxisRxRyRzTxTyTzSSwitchesPitch, Roll, YawStart, Reset, VizApps/taxiApps/takeoffPropInfoExercisesSoftwareMatricesThe word matrix comes from the Latin word mater, which means mother or origin. Matrices provide the origins of much of modern applied mathematics and computational science.Grafix is a study of the matrices that describe rotation, translation and scaling of objects moving in three-dimensional space. These matrices are the building blocks of today's computer graphics and are essential to all popular video games, to all CAD (Computer Added Design) packages, to CGI (Computer Graphics Imagery) in films. and to MATLAB's Handle Graphics.MATLAB is short for Matrix Laboratory. Matrices are also the foundation of MATLAB and of MathWorks.The homogeneous coordinates system used in modern computer graphics makes it possible to describe rotations, translations and many other operations with 4-by-4 matrices. These matrices operate on vectors with the position of an objec in the first three components and, for now, a one as the fourth component, e.g. [x,y,z,1]',The matrices, which we collectively denote by M, are always shown in the panel in our displays. Here is an animation of one important example. Do you see the pattern in the evolving elements of this M? How are they related to each other? How long before they repeat? AxisHere is the coordinate system used by view(3), MATLAB's default projection of our three-dimensional physical world onto the two-dimensional computer display. The positive x-axis goes up and to the right on the screen, the positive y-axis goes up and to the left, and the positive z-axis goes straight up. RxThe three knobs at the lower right of the Grafix window allow you to vary the angles of Rx, Ry and Rz. Here are snapshots of the resulting motion. The Rx knob produces rotation about the x-axis, leaving x unchanged while rotating y and z. RyRy, rotation about the y-axis, leaves y unchanged while rotating x and z. RzAnd, Rz, rotation about the z-axis, leaves z unchanged while rotating x and y. TxThe three sliders at the lower left of the Grafix window control matrices with values in the fourth column. Multiplying a vector by Tx, which has a nonzero element in the first row, produces a horizontal movement in the direction of the x-axis. TyTy, with a nonzero in the second row, is translation in the direction of the y-axis. TzAnd, Tz is translation in the z direction. SThe fourth slider controls S, a diagonal matrix with a single scaling factor for all three axes.The use of matrix multiplication allows translations and scaling to be combined with rotations and other operations in a uniform way. The arithmetic units on today's Graphics Processing Units, GPUs, are designed to do 4-by-4 matrix multiplications at speeds hundreds of times faster than general purpose Central Processing Units, CPUs. SwitchesThe switch on the left provides other objects that we will introduce later. The switch on the right provides different views of three dimensions. The yz plane view is shown here. Pitch, Roll, YawPitch, roll and yaw are often used to describe the motion of aircraft and spacecraft. These terms are closely related to the rotations Rx, Ry and Rz. The Pitch button animates the Rx knob. Here is a snapshot near one extreme of the resulting motion. Start, Reset, VizThe Start button restarts Grafix. The Reset button resets all knobs and sliders.The Viz button turns off the display of buttons, knobs, sliders, and switches. A small button, emphasized here with color, but usually barely visible, turns the display back on. Apps/taxiGrafix is programable, in a primitive sort of way. Apps are Grafix programs. Taxi is a small app. This is a snapshot. Apps/takeoffWhen the takeoff app first appeared, I thought it was a bug in the code for Grafix.You can see the takeoff program by entering type takeoff at the MATLAB command prompt. You can also edit takeoff. PropOne of my favorite animations employs the rotations from the Matrices section to drive the propeller alone. InfoThe info button is a link to this User's Guide. ExercisesWhat color is the beacon on top of the plane?Demonstrate how matrix-vector multiplication, Mv, of a position vector, v = [x,y,z,1]', by a 4-by-4 matrix M, achieves a rotation, translation or scaling.Describe the evolution of the matrix values in the Matrices and prop animations.What angles are involved in the snapshots shown for Rx, Ry and Rz?Why is the plane in the Pitch animation upside down?What angles and what matrices characterize the extremes of the Pitch animation?Write another app like taxi and takeoff.SoftwareThe MATLAB code for Grafix is available here.Get the MATLAB code (requires JavaScript) Published with MATLAB® R2023a",
+ "content_html": "
This is a quick look at Grafix, our tool for exploring matrices via 3-D computer graphics.
The word matrix comes from the Latin word mater, which means mother or origin. Matrices provide the origins of much of modern applied mathematics and computational science.
Grafix is a study of the matrices that describe rotation, translation and scaling of objects moving in three-dimensional space. These matrices are the building blocks of today's computer graphics and are essential to all popular video games, to all CAD (Computer Added Design) packages, to CGI (Computer Graphics Imagery) in films. and to MATLAB's Handle Graphics.
MATLAB is short for Matrix Laboratory. Matrices are also the foundation of MATLAB and of MathWorks.
The homogeneous coordinates system used in modern computer graphics makes it possible to describe rotations, translations and many other operations with 4-by-4 matrices. These matrices operate on vectors with the position of an objec in the first three components and, for now, a one as the fourth component, e.g. [x,y,z,1]',
The matrices, which we collectively denote by M, are always shown in the panel in our displays. Here is an animation of one important example. Do you see the pattern in the evolving elements of this M? How are they related to each other? How long before they repeat?
Axis
Here is the coordinate system used by view(3), MATLAB's default projection of our three-dimensional physical world onto the two-dimensional computer display. The positive x-axis goes up and to the right on the screen, the positive y-axis goes up and to the left, and the positive z-axis goes straight up.
Rx
The three knobs at the lower right of the Grafix window allow you to vary the angles of Rx, Ry and Rz. Here are snapshots of the resulting motion. The Rx knob produces rotation about the x-axis, leaving x unchanged while rotating y and z.
Ry
Ry, rotation about the y-axis, leaves y unchanged while rotating x and z.
Rz
And, Rz, rotation about the z-axis, leaves z unchanged while rotating x and y.
Tx
The three sliders at the lower left of the Grafix window control matrices with values in the fourth column. Multiplying a vector by Tx, which has a nonzero element in the first row, produces a horizontal movement in the direction of the x-axis.
Ty
Ty, with a nonzero in the second row, is translation in the direction of the y-axis.
Tz
And, Tz is translation in the z direction.
S
The fourth slider controls S, a diagonal matrix with a single scaling factor for all three axes.
The use of matrix multiplication allows translations and scaling to be combined with rotations and other operations in a uniform way. The arithmetic units on today's Graphics Processing Units, GPUs, are designed to do 4-by-4 matrix multiplications at speeds hundreds of times faster than general purpose Central Processing Units, CPUs.
Switches
The switch on the left provides other objects that we will introduce later. The switch on the right provides different views of three dimensions. The yz plane view is shown here.
Pitch, Roll, Yaw
Pitch, roll and yaw are often used to describe the motion of aircraft and spacecraft. These terms are closely related to the rotations Rx, Ry and Rz. The Pitch button animates the Rx knob. Here is a snapshot near one extreme of the resulting motion.
Start, Reset, Viz
The Start button restarts Grafix. The Reset button resets all knobs and sliders.
The Viz button turns off the display of buttons, knobs, sliders, and switches. A small button, emphasized here with color, but usually barely visible, turns the display back on.
Apps/taxi
Grafix is programable, in a primitive sort of way. Apps are Grafix programs. Taxi is a small app. This is a snapshot.
Apps/takeoff
When the takeoff app first appeared, I thought it was a bug in the code for Grafix.
You can see the takeoff program by entering type takeoff at the MATLAB command prompt. You can also edit takeoff.
Prop
One of my favorite animations employs the rotations from the Matrices section to drive the propeller alone.
Info
The info button is a link to this User's Guide.
Exercises
What color is the beacon on top of the plane?
Demonstrate how matrix-vector multiplication, Mv, of a position vector, v = [x,y,z,1]', by a 4-by-4 matrix M, achieves a rotation, translation or scaling.
Describe the evolution of the matrix values in the Matrices and prop animations.
What angles are involved in the snapshots shown for Rx, Ry and Rz?
Why is the plane in the Pitch animation upside down?
What angles and what matrices characterize the extremes of the Pitch animation?
",
+ "url": "https://hpc.social/commercial-blog/2023/grafix-users-guide/",
+
+
+
+
+
+ "date_published": "2023-02-10T18:36:06-07:00",
+ "date_modified": "2023-02-10T18:36:06-07:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2023/matrices-in-action-grafix-2-0/",
+ "title": "Matrices In Action, Grafix 2.0",
+ "summary": null,
+ "content_text": "The 4-by-4 matrices in the panels on the following screenshots are at the heart of computer graphics. They describe objects moving in three-dimensional space and are essential to MATLAB's Handle Graphics, to CAD (Computer Added Design) packages, to CGI (Computer Graphics Imagery) in films, and to most popular video games.ContentsGrafix 2.0RotationsPitch, Roll, and YawTranslationsHorizontal and VerticalScalingsLarger and SmallerSuggestionsGrafix 2.0Here is the opening screen from version 2.0 of Grafix, my tool for investigating the matrices involved in 3-D computer graphics. The MATLAB code for Grafix is availble here.I am interested in the matrix in the panel, which I call M. Many matrices like this one describe the dyamic transformations to be made on a set of target objects in a complex three-dimensional scene. This particular M is the product of a scaling and a rotation that results in the size and orientation of the plane shown.I also want to point out the coordinate axes being used. This is view(3), MATLAB's default 3-D cordinate system. The positive $x$-axis goes up and to the right on the screen, the positive $y$-axis up and to the left, and the positive $z$-axis goes straight up. RotationsThe homogeneous coordinates system used in modern computer graphics makes it possible to describe rotations, translations and many other operations with 4-by-4 matrices. These matrices operate on vectors with the position of an object in the first three components and, for now, a one as the fourth component, eg. [ $x$, $y$, $z$, 1 ]',Rotations are described by products of these matrices, each of which operates on only two of the first three components of the vector. The first matrix, $R_x$, leaves $x$ unchanged while it rotates $y$ and $z$. The second matrix, $R_y$, leaves $y$ unchanged while it rotates $x$ and $z$. And the third matrix, $R_z$, leaves $z$ unchanged while it rotates $x$ and $y$.$$ R_x(\\theta) = \\left[ \\begin{array}{rrrr} 1 & 0 & 0 & 0 \\\\ 0 & \\cos{\\theta} & -\\sin{\\theta} & 0 \\\\ 0 & \\sin{\\theta} & \\cos{\\theta} & 0 \\\\ 0 & 0 & 0 & 1 \\end{array} \\right] $$$$ R_y(\\theta) = \\left[ \\begin{array}{rrrr} \\cos{\\theta} & 0 & -\\sin{\\theta} & 0 \\\\ 0 & 1 & 0 & 0 \\\\ \\sin{\\theta} & 0 & \\cos{\\theta} & 0 \\\\ 0 & 0 & 0 & 1 \\end{array} \\right] $$$$ R_z(\\theta) = \\left[ \\begin{array}{rrrr} \\cos{\\theta} & -\\sin{\\theta} & 0 & 0 \\\\ \\sin{\\theta} & \\cos{\\theta} & 0 & 0 \\\\ 0 & 0 & 1 & 0 \\\\ 0 & 0 & 0 & 1 \\end{array} \\right] $$Pitch, Roll, and YawThe terms pitch, roll and yaw are often used to describe the motion of vehicles like aircraft, marine craft, and spacecraft. Pitch is $R_x$, rotation about the $x$-axis. Roll is $R_y$, rotation about the $y$-axis. And yaw is $R_z$, rotation about the $z$-axis. TranslationsTranslations are described by matrices with values in the fourth column. Multiplying a vector by one of these matrices produces a translation in the direction of the corresponding axis.$$ T_x(\\delta) = \\left[ \\begin{array}{rrrr} 1 & 0 & 0 & \\delta \\\\ 0 & 1 & 0 & 0 \\\\ 0 & 0 & 1 & 0 \\\\ 0 & 0 & 0 & 1 \\end{array} \\right] $$$$ T_y(\\delta) = \\left[ \\begin{array}{rrrr} 1 & 0 & 0 & 0 \\\\ 0 & 1 & 0 & \\delta \\\\ 0 & 0 & 1 & 0 \\\\ 0 & 0 & 0 & 1 \\end{array} \\right] $$$$ T_z(\\delta) = \\left[ \\begin{array}{rrrr} 1 & 0 & 0 & 0 \\\\ 0 & 1 & 0 & 0 \\\\ 0 & 0 & 1 & \\delta \\\\ 0 & 0 & 0 & 1 \\end{array} \\right] $$While it is true that translations could be accomplished simply by adding the increment to the specified coordiate, the use of matrix multiplication allows translations to be combined in a uniform way with rotations and other operations. The arithmetic units on today's Graphics Processing Units, GPUs, are designed to do 4-by-4 matrix multiplications at speeds hundreds of times faster than general purpose Central Processing Units, CPUs.Horizontal and VerticalInspired by David Singmaster's notation for Rubik's cubes, L, R, B, F, U, and D, we can use the descriptive terms left and right for horizontal motion in the $x$ direction; back and forth for horizontal motion in the $y$ direction; and up and down for vertical motion in the $z$ direction.$T_x$, left and right. $T_y$, back and forth. $T_z$, up and down. ScalingsThis matrix applies a single scaling factor to all three axes.$$ S(\\sigma) = \\left[ \\begin{array}{rrrr} \\sigma & 0 & 0 & 0 \\\\ 0 & \\sigma & 0 & 0 \\\\ 0 & 0 & \\sigma & 0 \\\\ 0 & 0 & 0 & 1 \\end{array} \\right] $$Larger and Smaller$S$ SuggestionsRefresh your browser to syncronize the animations.Download your own self-archiving copies ofGrafixQubeGet the MATLAB code (requires JavaScript) Published with MATLAB® R2023a",
+ "content_html": "
The 4-by-4 matrices in the panels on the following screenshots are at the heart of computer graphics. They describe objects moving in three-dimensional space and are essential to MATLAB's Handle Graphics, to CAD (Computer Added Design) packages, to CGI (Computer Graphics Imagery) in films, and to most popular video games.
Here is the opening screen from version 2.0 of Grafix, my tool for investigating the matrices involved in 3-D computer graphics. The MATLAB code for Grafixis availble here.
I am interested in the matrix in the panel, which I call M. Many matrices like this one describe the dyamic transformations to be made on a set of target objects in a complex three-dimensional scene. This particular M is the product of a scaling and a rotation that results in the size and orientation of the plane shown.
I also want to point out the coordinate axes being used. This is view(3), MATLAB's default 3-D cordinate system. The positive $x$-axis goes up and to the right on the screen, the positive $y$-axis up and to the left, and the positive $z$-axis goes straight up.
Rotations
The homogeneous coordinates system used in modern computer graphics makes it possible to describe rotations, translations and many other operations with 4-by-4 matrices. These matrices operate on vectors with the position of an object in the first three components and, for now, a one as the fourth component, eg. [ $x$, $y$, $z$, 1 ]',
Rotations are described by products of these matrices, each of which operates on only two of the first three components of the vector. The first matrix, $R_x$, leaves $x$ unchanged while it rotates $y$ and $z$. The second matrix, $R_y$, leaves $y$ unchanged while it rotates $x$ and $z$. And the third matrix, $R_z$, leaves $z$ unchanged while it rotates $x$ and $y$.
The terms pitch, roll and yaw are often used to describe the motion of vehicles like aircraft, marine craft, and spacecraft. Pitch is $R_x$, rotation about the $x$-axis.
Roll is $R_y$, rotation about the $y$-axis.
And yaw is $R_z$, rotation about the $z$-axis.
Translations
Translations are described by matrices with values in the fourth column. Multiplying a vector by one of these matrices produces a translation in the direction of the corresponding axis.
While it is true that translations could be accomplished simply by adding the increment to the specified coordiate, the use of matrix multiplication allows translations to be combined in a uniform way with rotations and other operations. The arithmetic units on today's Graphics Processing Units, GPUs, are designed to do 4-by-4 matrix multiplications at speeds hundreds of times faster than general purpose Central Processing Units, CPUs.
Horizontal and Vertical
Inspired by David Singmaster's notation for Rubik's cubes, L, R, B, F, U, and D, we can use the descriptive terms left and right for horizontal motion in the $x$ direction; back and forth for horizontal motion in the $y$ direction; and up and down for vertical motion in the $z$ direction.
$T_x$, left and right.
$T_y$, back and forth.
$T_z$, up and down.
Scalings
This matrix applies a single scaling factor to all three axes.
",
+ "url": "https://hpc.social/commercial-blog/2023/matrices-in-action-grafix-2-0/",
+
+
+
+
+
+ "date_published": "2023-02-04T13:00:33-07:00",
+ "date_modified": "2023-02-04T13:00:33-07:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2023/singular-matrix-pencils-and-the-qz-algorithm-update/",
+ "title": "Singular Matrix Pencils and the QZ Algorithm, Update",
+ "summary": null,
+ "content_text": "(The January 5 posting was premature and incomplete.)This year, 2023, is the 50-th anniversary of the QZ algorithm for the generalized matrix eigenvalue problem, Ax = λBxThe algorithm avoids inverting either A or B. And, importantly, the QZ algorithm can be used to detect and analyze exceptional instances of the problem known as singular pencils. These pencils do not occur in the standard eigenvalue problem where B is the identity matrix.ContentsSingular pencils3-by-3 exampleWilkinson exampleReferencesSingular pencilsA matrix pencil is singular if both A and B are singular and, moreover, A - λ B is singular for all λ. Equivalently, det(A - λB) = 0 for all λ.Singular pencils are more insidious than might appear at first glance. In some sense, the spectrum is the entire complex plane.There are no singular pencils with the standard eigenvalue problem Ax = λxwhere B is the identity matrix and certainly nonsingular.If A and B are both real symmetric or complex Hermitian, but neither is positive definite, the pencil may or may not be singular. Symmetric problems occur frequently and there are separate algorithms and perturbation and convergence theories.The QZ algorithm does not compute the eigenvalues λ until the very last step. It stably reduces A and B to triangular form with diagonals α and β. The eigenvalues are then the ratios λ = α./βIsolated zeros in α or β yield zero or infinite eigenvalues with no special difficulties. Singular pencils occur if and only if zeros in α and β occur with the same index and (with exact arithmetic) lead to λ = 0/0 = NaN.With a singular pencil, some, perhaps all, of the diagonal values in α and β are highly sensitive to perturbation, and all of the eigenvalues computed from the ratios are suspect. Theoretically the ill-conditioned eigenvalues can be determined from the Kronecker Canonical Form, a generalization of the notorious Jordan Canonical Form. But, like the Jordan Form, the Kronecker Form cannot provide a stable numerical algorithm.3-by-3 example A = [9 8 7; 6 5 4; 3 2 1] B = [1 3 2; 4 6 5; 7 9 8]A = 9 8 7 6 5 4 3 2 1B = 1 3 2 4 6 5 7 9 8Let's verify that this is a singular pencil. Use the Symbolic Math Toolbox to introduce a free variable. syms lambda AB = A - lambda*B AB = [ 9 - lambda, 8 - 3*lambda, 7 - 2*lambda][6 - 4*lambda, 5 - 6*lambda, 4 - 5*lambda][3 - 7*lambda, 2 - 9*lambda, 1 - 8*lambda] Without further computation, we can see that the second row is the average of the first and third rows for all lambda and consequently that the determinant must be identically zero.With exact arithmetic, each of these statements would produce the same eigenvalues. After the introduction of some roundoff error, two of the lambdas are indeterminant, but lambda = -1 is present in all four results. Is lambda = -1 a stable eigenvalue? lambda_AB = eig(A,B) lambda_BA = 1./eig(B,A) lambda_ATBT = eig(A',B') lambda_BTAT = 1./eig(B',A')lambda_AB = 1.8984 -1.0000 -0.0807lambda_BA = -1.0000 0.5837 -0.9274lambda_ATBT = 0.0829 Inf -1.0000lambda_BTAT = -0.9661 0 -1.0000The triangular matrices for lambda_AB. [QAZ,QBZ] = qz(A,B); QAZ QBZQAZ = 1.6131 10.2664 -11.0905 0 -4.2969 5.9613 0 0 -0.0000QBZ = 0.7898 6.8901 -13.5242 0 4.2969 -5.9613 0 0 0.0000Careful examination of the diagonals reveals that alfa(2)/beta(2) is producing the -1, while alfa(3)/beta(3) is roundoff over roundoff. format long e alfa = diag(QAZ) beta = diag(QBZ) format shortalfa = 1.613087771308989e+00 -4.296911800112353e+00 -1.965207685813115e-15beta = 7.898460671891234e-01 4.296911800112357e+00 1.359052275299816e-15Wilkinson exampleJim Wilkinson published a survey paper about QZ and Kronecker products in 1979. One of his examples is A = [4 3 2 5; 6 4 2 7; -1 -1 -2 -2; 5 3 2 6] B = [2 1 3 4; 3 3 3 5; 0 0 -3 -2; 3 1 3 5]A = 4 3 2 5 6 4 2 7 -1 -1 -2 -2 5 3 2 6B = 2 1 3 4 3 3 3 5 0 0 -3 -2 3 1 3 5Use the Symbolic Math Toolbox to verify that this is a singular pencil. syms lambda AB = A - lambda*B AB = [4 - 2*lambda, 3 - lambda, 2 - 3*lambda, 5 - 4*lambda][6 - 3*lambda, 4 - 3*lambda, 2 - 3*lambda, 7 - 5*lambda][ -1, -1, 3*lambda - 2, 2*lambda - 2][5 - 3*lambda, 3 - lambda, 2 - 3*lambda, 6 - 5*lambda] The determinant is identically zero for all lambda. d = det(AB) d = 0 With exact arithmetic, each of these statements would produce the same eigenvalues, but in practice each set is different. None of the eigenvalues is stable. lambda_AB = eig(A,B) lambda_BA = 1./eig(B,A) lambda_ATBT = eig(A',B') lambda_BTAT = 1./eig(B',A')lambda_AB = 1.2056 0.7055 -1.0000 -Inflambda_BA = 1.5097 0.6408 0 -1.0000lambda_ATBT = -0.2141 + 0.2033i -0.2141 - 0.2033i 0.7013 + 0.0000i 1.4508 + 0.0000ilambda_BTAT = 0.3168 0.9823 1.2325 0The triangular matrices for lambda_AB are [QAZ,QBZ] = qz(A,B); QAZ QBZQAZ = 0.7437 4.1769 -12.7279 -5.5000 0 0.0000 5.2328 2.1602 0 0 0.7857 0.0123 0 0 0 -0.2887QBZ = 0.5005 6.6143 -8.4853 -2.5000 0 0.0000 3.2668 2.0105 0 0 1.1525 -0.7904 0 0 0 0.2887Examine the diagonals more carefully. alfa(2)/beta(2) is the only roundoff over roundoff, but all four eigenvalues are unstable. format long e alfa = diag(QAZ) beta = diag(QBZ) format shortalfa = 7.437114999643711e-01 1.216947725307920e-14 7.857314232211017e-01 -2.886751345948121e-01beta = 5.005405248737872e-01 1.021080292327182e-13 1.152509249099882e+00 2.886751345948153e-01ReferencesC. B. Moler and G. W. Stewart, \"An Algorithm for Generalized Matrix Eigenvalue Problems\", SIAM J. Numerical Analysis, Vol.10, No.2, April 1973. Also available at cbm_gws.pdfJ. H. Wilkinson, \"Kronecker's Canonical Form and the QZ Algorithm\", Linear Algebra and its Applications, Vol. 28, 1979. Also available at wilkinson.pdfGet the MATLAB code (requires JavaScript) Published with MATLAB® R2023a",
+ "content_html": "
(The January 5 posting was premature and incomplete.)
This year, 2023, is the 50-th anniversary of the QZ algorithm for the generalized matrix eigenvalue problem,
Ax = λBx
The algorithm avoids inverting either A or B. And, importantly, the QZ algorithm can be used to detect and analyze exceptional instances of the problem known as singular pencils. These pencils do not occur in the standard eigenvalue problem where B is the identity matrix.
A matrix pencil is singular if both A and B are singular and, moreover, A - λ B is singular for all λ. Equivalently,
det(A - λB) = 0 for all λ.
Singular pencils are more insidious than might appear at first glance. In some sense, the spectrum is the entire complex plane.
There are no singular pencils with the standard eigenvalue problem
Ax = λx
where B is the identity matrix and certainly nonsingular.
If A and B are both real symmetric or complex Hermitian, but neither is positive definite, the pencil may or may not be singular. Symmetric problems occur frequently and there are separate algorithms and perturbation and convergence theories.
The QZ algorithm does not compute the eigenvalues λ until the very last step. It stably reduces A and B to triangular form with diagonals α and β. The eigenvalues are then the ratios
λ = α./β
Isolated zeros in α or β yield zero or infinite eigenvalues with no special difficulties. Singular pencils occur if and only if zeros in α and β occur with the same index and (with exact arithmetic) lead to λ = 0/0 = NaN.
With a singular pencil, some, perhaps all, of the diagonal values in α and β are highly sensitive to perturbation, and all of the eigenvalues computed from the ratios are suspect. Theoretically the ill-conditioned eigenvalues can be determined from the Kronecker Canonical Form, a generalization of the notorious Jordan Canonical Form. But, like the Jordan Form, the Kronecker Form cannot provide a stable numerical algorithm.
Without further computation, we can see that the second row is the average of the first and third rows for all lambda and consequently that the determinant must be identically zero.
With exact arithmetic, each of these statements would produce the same eigenvalues. After the introduction of some roundoff error, two of the lambdas are indeterminant, but lambda = -1 is present in all four results. Is lambda = -1 a stable eigenvalue?
The determinant is identically zero for all lambda.
d = det(AB)
d = 0
With exact arithmetic, each of these statements would produce the same eigenvalues, but in practice each set is different. None of the eigenvalues is stable.
C. B. Moler and G. W. Stewart, \"An Algorithm for Generalized Matrix Eigenvalue Problems\", SIAM J. Numerical Analysis, Vol.10, No.2, April 1973. Also available at cbm_gws.pdf
J. H. Wilkinson, \"Kronecker's Canonical Form and the QZ Algorithm\", Linear Algebra and its Applications, Vol. 28, 1979. Also available at wilkinson.pdf
",
+ "url": "https://hpc.social/commercial-blog/2023/singular-matrix-pencils-and-the-qz-algorithm-update/",
+
+
+
+
+
+ "date_published": "2023-01-10T21:45:12-07:00",
+ "date_modified": "2023-01-10T21:45:12-07:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2023/singular-matrix-pencils-and-the-qz-algorithm/",
+ "title": "Singular Matrix Pencils and the QZ Algorithm",
+ "summary": null,
+ "content_text": "This year, 2023, is the 50-th anniversary of the QZ algorithm for generalized matrix eignenvalue problems,Ax = λBxThe algorithm computes these eigevalues without inverting either A or B. And, the QZ-algorithm can help detect and analyze exceptional situaions known as singular pencils.ContentsMatrix pencilsExampleWilkinson exampleReferencesMatrix pencilsIf A and B are two square matrices, the linear matrix pencil is the matrix-valued function A - λBA pencil is regular if there is at least one value of λ for which A - λB if not singular. The pencil is singular if both A and B are singular and, moreover, A - λB is singular for all λ. In other words, det(A - λB) = 0 for all λ.Singular pencils are more insiduous than migt appear at first glance.Example A = [9 8 7; 6 5 4; 3 2 1] B = [7 9 8; 4 6 5; 1 3 2]A = 9 8 7 6 5 4 3 2 1B = 7 9 8 4 6 5 1 3 2 syms s AB = A - s*B d = det(AB) AB = [9 - 7*s, 8 - 9*s, 7 - 8*s][6 - 4*s, 5 - 6*s, 4 - 5*s][ 3 - s, 2 - 3*s, 1 - 2*s] d = 0 eig1 = eig(A,B) eig2 = 1./eig(B,A) [QAZ,QBZ,Q,Z,V,W] = qz(A,B); QAZ, QBZeig1 = -0.4071 1.0000 0.2439eig2 = -2.0000 1.0000 0.3536QAZ = -1.0298 -13.0363 7.7455 0 5.6991 -4.6389 0 0 0.0000QBZ = 2.4396 -11.4948 9.6394 0 5.6991 -4.6389 0 0 0.0000 eig3 = eig(A',B') eig4 = 1./eig(B',A') [QATZ,QBTZ,Q,Z,V,W] = qz(A',B'); QATZ, QBTZeig3 = -0.2169 Inf 1.0000eig4 = -0.0738 0 1.0000QATZ = -0.0000 -15.0218 6.8390 0 2.6729 -2.2533 0 0 0.5922QBTZ = 0.0000 -15.2578 7.1280 0 0 1.0203 0 0 0.5922Wilkinson example clear A = [4 3 2 5; 6 4 2 7; -1 -1 -2 -2; 5 3 2 6] B = [2 1 3 4; 3 3 3 5; 0 0 -3 -2; 3 1 3 5]A = 4 3 2 5 6 4 2 7 -1 -1 -2 -2 5 3 2 6B = 2 1 3 4 3 3 3 5 0 0 -3 -2 3 1 3 5 syms s AB = A - s*B d = det(AB) AB = [4 - 2*s, 3 - s, 2 - 3*s, 5 - 4*s][6 - 3*s, 4 - 3*s, 2 - 3*s, 7 - 5*s][ -1, -1, 3*s - 2, 2*s - 2][5 - 3*s, 3 - s, 2 - 3*s, 6 - 5*s] d = 0 eig1 = eig(A,B) eig2 = 1./eig(B,A) [QAZ,QBZ,Q,Z,V,W] = qz(A,B); QAZ, QBZeig1 = 1.2056 0.7055 -1.0000 -Infeig2 = 1.5097 0.6408 0 -1.0000QAZ = 0.7437 4.1769 -12.7279 -5.5000 0 0.0000 5.2328 2.1602 0 0 0.7857 0.0123 0 0 0 -0.2887QBZ = 0.5005 6.6143 -8.4853 -2.5000 0 0.0000 3.2668 2.0105 0 0 1.1525 -0.7904 0 0 0 0.2887 eig3 = eig(A',B') eig4 = 1./eig(B',A') [QATZ,QBTZ,Q,Z,V,W] = qz(A',B'); QATZ, QBTZeig3 = -0.2141 + 0.2033i -0.2141 - 0.2033i 0.7013 + 0.0000i 1.4508 + 0.0000ieig4 = 0.3168 0.9823 1.2325 0QATZ = 0.1281 - 0.2434i 0.2665 + 0.0169i 0.2663 + 1.4905i 0.3721 + 3.5350i 0.0000 + 0.0000i 0.0587 + 0.1116i 5.2603 - 1.6197i 12.7878 - 4.0110i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 4.1745 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.7572 + 0.0000iQBTZ = 0.9052 + 0.0000i 0.6130 - 0.6141i -0.2443 + 0.8738i 1.2233 + 2.5485i 0.0000 + 0.0000i 0.4150 + 0.0000i 3.5658 - 1.2114i 8.0696 - 2.2671i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 6.6127 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.5220 + 0.0000iReferencesC. B. Moler and G. W. Stewart, \"An Algorithm for Generalized Matrix Eigenvalue Problems\", SIAM J.NUMER.ANAL. Vol.10, No.2, April 1973. Also available at cbm_gws.pdfJ. H. Wilkinson, Kronecker's Canonical Form and the QZ Algorithm\", LINEAR ALGEBRA AND ITS APPPLICATIONS, Vol. 28, 1979. Also available at Also available at wilkinson.pdfGet the MATLAB code (requires JavaScript) Published with MATLAB® R2023a",
+ "content_html": "
This year, 2023, is the 50-th anniversary of the QZ algorithm for generalized matrix eignenvalue problems,
Ax = λBx
The algorithm computes these eigevalues without inverting either A or B. And, the QZ-algorithm can help detect and analyze exceptional situaions known as singular pencils.
If A and B are two square matrices, the linear matrix pencil is the matrix-valued function
A - λB
A pencil is regular if there is at least one value of λ for which A - λB if not singular. The pencil is singular if both A and B are singular and, moreover, A - λB is singular for all λ. In other words,
det(A - λB) = 0 for all λ.
Singular pencils are more insiduous than migt appear at first glance.
C. B. Moler and G. W. Stewart, \"An Algorithm for Generalized Matrix Eigenvalue Problems\", SIAM J.NUMER.ANAL. Vol.10, No.2, April 1973. Also available at cbm_gws.pdf
J. H. Wilkinson, Kronecker's Canonical Form and the QZ Algorithm\", LINEAR ALGEBRA AND ITS APPPLICATIONS, Vol. 28, 1979. Also available at Also available at wilkinson.pdf
",
+ "url": "https://hpc.social/commercial-blog/2023/singular-matrix-pencils-and-the-qz-algorithm/",
+
+
+
+
+
+ "date_published": "2023-01-05T16:37:04-07:00",
+ "date_modified": "2023-01-05T16:37:04-07:00",
+
+ "author": "MathWorks Blogs"
+
+ },
+
+ {
+ "id": "https://hpc.social/commercial-blog/2022/color-cube-meets-rubik-s-cube/",
+ "title": "Color Cube Meets Rubik’s Cube",
+ "summary": null,
+ "content_text": "I have made a half dozen blog posts about Rubik's Cube so far this year. And, during the MATLAB Central Mini Hack in October, I resurrected an old code about the Color Cube. Now, a combination of the two, Rubik/Color Qube, creates an elegant tool for investigating Matrices in Action.ContentsOpeningRubik and ColorColor QubeRotationsn-by-n-by-n2-by-2-by-2SoftwareOpeningHere is the opening screen shot of Rubik/Color Qube, one of the most elaborate MATLAB programs that I have ever written. Rubik and ColorThere are two modes, rubik and color. In rubik mode, the large cube is formed from 27 identical copies of a single small cubelet. The six cubelet faces have six different colors. Red, white and blue are visible initially. Orange, yellow and green become visible as the faces are rotated. In color mode, the large cube is formed from 27 cubelets, each with a different solid color. Three of the corner cubelets are the primary colors in the RGB color model -- red, green and blue. Three more corners are the complementary cyan, magenta and yellow. White and black complete the list of corners. Color QubeAll of the familiar Rubik's moves are available in color mode. Here is a screen shot after a few rotations. RotationsRotation matrices defined by this Rk function are the basic mathematical tool employed by Qube. The animation provides a detailed look at the action produced by the F key, counter-clockwise rotation of the Front face. This is the y-axis, case 2 in Rk. The detail is provided by taking d = 0:3:90, so there are 30 steps of 3 degrees.function R = Rk(axis,d) % Rk(axis,d), Rotation by d degrees about the x-, y-, or z-axis. c = cosd(d); s = sind(d); switch axis case 1, R = [ 1 0 0 0 c s 0 -s c ]; case 2, R = [ c 0 s 0 1 0 -s 0 c ]; case 3, R = [ c s 0 -s c 0 0 0 1 ]; end fmat = findobj('tag','fmat'); if ~isempty(fmat) fmat.String = mat3(R); endend n-by-n-by-nQube generalizes the classic 3-by-3-by-3 Rubik's Cube to n-by-n-by-n cubes for any n. 2-by-2-by-2The 2-by-2-by-2 cubes are good starting points for investigation of mathematical properties. SoftwareQube is available as a self-extracting MATLAB archive at this link, Qube_mzip.m.Get the MATLAB code (requires JavaScript) Published with MATLAB® R2022b",
+ "content_html": "
I have made a half dozen blog posts about Rubik's Cube so far this year. And, during the MATLAB Central Mini Hack in October, I resurrected an old code about the Color Cube. Now, a combination of the two, Rubik/Color Qube, creates an elegant tool for investigating Matrices in Action.
Here is the opening screen shot of Rubik/Color Qube, one of the most elaborate MATLAB programs that I have ever written.
Rubik and Color
There are two modes, rubik and color. In rubik mode, the large cube is formed from 27 identical copies of a single small cubelet. The six cubelet faces have six different colors. Red, white and blue are visible initially. Orange, yellow and green become visible as the faces are rotated.
In color mode, the large cube is formed from 27 cubelets, each with a different solid color. Three of the corner cubelets are the primary colors in the RGB color model -- red, green and blue. Three more corners are the complementary cyan, magenta and yellow. White and black complete the list of corners.
Color Qube
All of the familiar Rubik's moves are available in color mode. Here is a screen shot after a few rotations.
Rotations
Rotation matrices defined by this Rk function are the basic mathematical tool employed by Qube. The animation provides a detailed look at the action produced by the F key, counter-clockwise rotation of the Front face. This is the y-axis, case 2 in Rk. The detail is provided by taking d = 0:3:90, so there are 30 steps of 3 degrees.
function R = Rk(axis,d) % Rk(axis,d), Rotation by d degrees about the x-, y-, or z-axis. c = cosd(d); s = sind(d); switch axis case 1, R = [ 1 0 0 0 c s 0 -s c ]; case 2, R = [ c 0 s 0 1 0 -s 0 c ]; case 3, R = [ c s 0 -s c 0 0 0 1 ]; end fmat = findobj('tag','fmat'); if ~isempty(fmat) fmat.String = mat3(R); endend
n-by-n-by-n
Qube generalizes the classic 3-by-3-by-3 Rubik's Cube to n-by-n-by-n cubes for any n.
2-by-2-by-2
The 2-by-2-by-2 cubes are good starting points for investigation of mathematical properties.
Software
Qube is available as a self-extracting MATLAB archive at this link, Qube_mzip.m.
Recently, I have made a series of blog posts about Redheffer matrices and the Mertens conjecture. After each of the posts, readers and colleagues offered suggestions to speed up the calculations. Here is a summary of what I have learned.
The function named after the mid-nineteenth century German mathematician August Möbius is fundamental to the study of prime numbers. The Möbius function maps the positive integers onto -1,0 and +1.
+
+
mu(n) = 0 if n has a repeated prime factor,
+ = (-1)^(number prime factors) if the factors of n are not repeated
+
Here is my code for the Möbius function. It relies on factor(n) which uses a sieve to find the prime factors of n.
+
+
function mu = mobius(n)
+ % mu = mobius(n) returns mu(1:n).
+ mu = -eye(1,n);
+ for k = 2:n
+ f = factor(k);
+ d = diff([1 f]);
+ if any(d == 0)
+ mu(k) = 0;
+ else
+ mu(k) = (-1)^length(f);
+ end
+ end
+ end
+
Here is a graph of mu(n) for n = 1:40. For example, mu(29:31) are all -1 because 29 and 31 are both prime and 30 has an odd number of prime factors, 2, 3 and 5.
The Mertens function is named after the late-nineteenth century Polish mathematician Franz Mertens. The function, which we denote by M(n), is simply the partial sums of the Möbius function. The MATLAB code is very short.
+
+
function M = mertens(n)
+ % M = mertens(n) returns Mertens(1:n).
+ mu = moebius(n);
+ M = cumsum([1 mu(2:n)]);
+ end
The twentieth-century American mathematician Ray Redheffer, who was a professor at UCLA for 55 years, had a wide range of interests. He was the author of several popular textbooks, the inventor of the electronic game Nim and, with Ray and Charles Eames, the creator of a four-meter long poster Men of Modern Mathematics.
+
+
The n-by-n Redheffer's matrix R(n) is a matrix of zeros and ones. For j > 1, the element R(k,j) equals one if j is a divisor of k. And importantly, for j = 1, the first column R(:,1) is all ones.
+
+
function R = redheffer(n)
+ k = 1:n;
+ j = k';
+ R = (mod(k,j) == 0);
+ R(:,1) = 1;
+ end
+
Nick Higham put Redheffer's matrix in the MATLAB Gallery several years ago. Here is a spy plot of the 200-by-200.
+
+
+ R = gallery('redheff',200);
+ spy(R)
+ title('Redheffer')
+
+
OEIS
+
+
In the Online Encyclopedia of Integer Sequences, the Mertens function is OEIS/A002321. One of the many cool features of the OEIS is "listen", which generates music driven by the sequences. Take a look -- and a listen -- to my 63 second movie about A002321.
Here are plots of M(1:n) with n ranging from 100 to 10 million. Each plot after the first also shows the range of the previous plot. I will discuss the red lines in the next section
+
+
+ load mertens M
+ tiledlayout(2,3)
+ for n = 10.^(2:7)
+ nexttile
+ mertens_plot(M(1:n))
+ end
+
+
Mertens Conjecture
+
+
The red lines above are plots of ±sqrt(n). They clearly bound M(n) for n up to 10 million. The Mertens Conjecture is that this holds for all n.
+
+
|M(n)| < sqrt(n) for all n > 0
+
The conjecture appears in a 1885 letter from Thomas Stieltjes to Charles Hermite and in a 1897 paper by Mertens.
It is a striking example of a mathematical conjecture proven false
+ despite a large amount of computational evidence in its favor.
+
Conjecture is False
+
+
In 1985, 100 years after the Stieltjes letter, Andrew Odlyzko and Herman te Riele proved that the conjecture is false. Their proof is indirect. They prove the existence of infinitely many n for which
+
+
|M(n)|/sqrt(n) > 1.06
+
But they do not know the value of any particular n. They informally estimate that such an n would be greater than 10^30 and probably much larger.
+
+
Matrices
+
+
Let's get back to the world of matrices. It is not obvious, but is true, that the determinants of Redheffer matrices are equal to the Mertens function.
+
+
det(R(n)) = M(n)
+
So, if I could have proved that
+
+
|det(R(n))| < sqrt(n) for all n > 0
+
I would have had a proof of the Riemann Hypothesis.
+
+
It might appear that I am out of the clutches of number theory and safely back to matrix computation. But that illusion does not last for long.
+
+
Sparsity
+
+
The 0(n^3) memory required by the Redheffer matrix from the gallery runs out of steam quickly. We need to take advantage of sparsity. This function generates the sparse representation of a Redheffer matrix directly.
+
+
function R = spredheffer(n)
+ j = (1:n)';
+ k = ones(n,1);
+ m = n;
+ for i = 2:n
+ t = [1 i:i:n];
+ p = length(t);
+ j(m+(1:p)) = t;
+ k(m+(1:p)) = i;
+ m = m+p;
+ end
+ R = sparse(k,j,1,n,n);
+ end
+
Computing Mertens
+
+
Here are five methods for computing the Mertens function.
+
+
#1
+
+
The first simply takes the determinant of the Redheffer matrix in the gallery.
+
+
M = det(gallery('redheff',n))
+
#2
+
+
The sparse Gaussian elimination function lu with one input and four sparse outputs is designed for solving sparse linear systems. Written primarily by Tim Davis and included in his UMFPACK package, the function uses an unsymmetric pattern multifrontal pivoting strategy to reduce fill-in while maintaining numerical stability. The determinant of the input matrix is the product of the four determinants of the output matrices. Two them are triangular and two are permutations, so it is easy, and quick, to compute their determinants.
+
+
R = spredheffer(n);
+ [L,U,P,Q] = lu(R)
+ M = det(L)*det(U)*det(P)*det(Q);
+
#3
+
+
Pat Quillen realized that by interchanging the first and last columns, there would be little fill-in. We need only one determinant.
+
+
R = spredheffer(n);
+ R(:,[1 n]) = R(:,[n 1]);
+ M = -det(R);
+
#4
+
+
A thoughtful reader of the blog submitted a suggestion based on the Schur complement. Suppose E is a block matrix,
+
+
E = [A B
+ C D]
+
Schur's formula for the determinant of E is
+
+
det(E) = det(D)*det(A - B*(D\C))
+
Apply this to R(n) with A the (1,1) entry, which is 1, and D the lower (n-1)-by-(n-1) submatrix, which is upper triangular with ones on the diagonal and determinant equal 1. This leads to method #4 which uses backslash with a sparse, unit, upper triangular matrix. There is a Redheffer matrix, but no determinant.
+
+
S = spredheffer(n);
+ e = ones(n-1,1);
+ M = 1 - e'*(S(2:n,2:n)\e);
+
#5
+
+
Once we have generated R(n) and computed M(n), how do we get R(n+1) and M(n+1)? After several iterations of this approach, I found myself without any matrices and only the original definitions of Möbius and Mertens.
+
+
mu = mobius(n);
+ M = cumsum([1 mu(2:n)]);
+
Performance
+
+
Let's summarize the five methods. The first four generate a single, isolated value of M(n). Method #5 generates M(n) for all n from 1 to any specified maximum.
+
+
matrix function dets M
+
#1 full gallery 1 1
+ #2 sparse lu 4 1
+ #3 sparse swap 1 1
+ #4 sparse \ 0 1
+ #5 none factor 0 many
+
Time in seconds to compute M(n) on my Lenovo T14 laptop running Windows.
+
+]]>MathWorks BlogsExperience With Chatbots Generating MATLAB2024-10-07T14:31:38-06:002024-10-07T14:31:38-06:00https://hpc.social/commercial-blog/2024/experience-with-chatbots-generating-matlab
+
A friend is investigating the use of generative AI in his classes. I asked two different popular chatbots to write MATLAB programs for a mathematically nontrivial problem. Both chatbots understood my query and both wrote plausible MATLAB programs, but one of the programs was not correct. My recommendation for coursework: carefully read and test programs produced by generative AI and repair any incorrect ones.
Frequent readers of this blog know about my recent obsession with Redheffer matrices and the Mertens conjecture. So, when my friend Stan Ahalt visited from North Carolina State a few days ago, and wanted to discuss the use of generative AI in the new Data Science curriculum, I suggested asking chatbots to write MATLAB programs that check the Mertens conjecture.
+
+
We logged onto the web sites for two different AI companies. Our query was the same at both sites.
+
+
Please write a MATLAB program to test the Mertens conjecture.
+
I was pleasantly surprised when both systems knew about MATLAB and understood the query. One of the systems replied:
+
+
Certainly! I'll create a MATLAB program to test the Mertens
+conjecture. First, let me briefly explain what the Mertens
+conjecture is, and then I'll provide the code.
+The Mertens conjecture states that the Mertens function M(n)
+is bounded by √n for all positive integers n. Mathematically,
+it can be expressed as:
+
|M(n)| ≤ √n for all n > 1
+
Where M(n) is the Mertens function, defined as the sum of
+the Möbius function μ(k) for all positive integers k up to n:
+
M(n) = Σ μ(k) for k = 1 to n
+
Here's a MATLAB program to test this conjecture.
+
Program number one
+
+
The program from one of the web sites begins:
+
+
function M = test_Mertens(n)
+ % Function to test the Mertens conjecture for a given n
+ % Returns true if the conjecture holds for all values up to n, false otherwise
+
This is followed by code to sum the Möbius function and verify that abs(M) < sqrt(n). The crucial mobius is a straight-forward implementation of the definition. The code relies on MATLAB intrinsics, factor and unique.
+
+
function mu = mobius(k)
+ % Function to calculate the Möbius function of k
+ % Factorize k
+ p = factor(k);
+ % Check for square factors
+ if length(p) ~= length(unique(p))
+ mu = 0;
+ else
+ mu = (-1)^length(p);
+ end
+end
+
I was very pleased. The entire program is only 40 lines long, eminently readable, and correct.
+
+
Program number two
+
+
The program from the other web site is more sophisticated. It knows enough about MATLAB to use its cumulative summation.
+
+
M = cumsum(mu);
+
Here is the crucial mobius function. At first glance, it looks OK. Is it?
+
+
function mu = mobius(n)
+ % Calculate Möbius function values up to n
+ mu = ones(1, n);
+ for i = 2:sqrt(n)
+ if mu(i) == 1
+ for j = i^2:i:n
+ if mod(j, i^2) == 0
+ mu(j) = 0;
+ else
+ mu(j) = -mu(j);
+ end
+ end
+ end
+ end
+end
+
As you have guessed, program number two is not correct. Even its own plot reveals that something is amiss.
+
+
Program number three
+
+
Let's return to the second Web site and make a more specific query.
+
+
Please write a MATLAB program that uses Redheffer
+matrices to test the Mertens conjecture.
+
The resulting program generates a Redheffer matrix with
+
+
R = zeros(n,n);
+for i = 1:n
+ for j = 1:n
+ if mod(i, j) == 0
+ R(i, j) = 1;
+ end
+ end
+end
+
It computes the determinant to obtain the Mertens value, M(n). It is able to confirm the conjecture for all the n in the given range.
+
+
What's wrong now? Look at the plot. The computed M(n) is always equal to one. Why?
+
+
+
+
+
Happy Ending
+
+
Program number three can be repaired by adding one line to the code that generates R. What is that line? Respond in the comments.
+
+
Look at the good side. Instead of just using AI to do homework, we can challenge students to check the results carefully and repair any incorrect programs.
+
+]]>MathWorks BlogsRedheffer and Mertens, Accelerated2024-09-30T14:28:40-06:002024-09-30T14:28:40-06:00https://hpc.social/commercial-blog/2024/redheffer-and-mertens-accelerated
+
Shortly after I published the second post about the Mertens conjecture, a reader's comment suggested a new approach to computing Redheffer determinants and the Mertens function. It is now possible to compute a half-million values of the Mertens function in about five hours.
You could also consider the matrix as a 2x2 block matrix and
+ use the formula for the determinant of a block matrix [1].
+ A = redheffer(n);
+ M = full(A(1,1) - A(1, 2:end) * (A(2:end,2:end) \ A(2:end, 1)));
+ Since the (n-1)x(n-1) block is upper triangular, the solve becomes
+ a back-substitution.
+
+redmert
+
+
My new program is named redmert, an abbreviation of Redheffer-Mertens. It uses the fact that redheffer(n) is obtained from redheffer(n-1) by appending the last column.
+
+
Let R(n) denote the upper or right-triangular part of redheffer(n).
+
+
R(n) = triu(redheffer(n))
+
+R(n) is sparse, upper triangular and has ones on the diagonal. The indices of the nonzeros in the last column of R(n) are the factors of n. For example, here is R(8).
The idea behind redmert is to compute a sequence of Redheffer matrices, R, and associated values of the Mertens function, M.
+
+
[M,R] = redmert(p,R)
+
The input is a scalar integer p, the desired sequence length, and a sparse matrix R, the upper triangle of a Redheffer matrix of some order, n. The output is an integer vector of values M(n+1:n+p) and the upper triangle of the Redheffer matrix of order n+p. This output R can then be used as the input R in another call to redmert.
+
+
The sequence is started with an empty R.
+
+
For example,
+
+
+[M,R] = redmert(8,[]);
+
+
The output is mertens(n), n = 1:8, and R8 from the example above.
The entire code for redmert is twelve lines long. It manipulates sparse matrices and uses sparse backslash to solve a triangular system. Nothing else is required.
+
+
Lines 7 and 8 generate the last column of R and lines 9 and 10 implement the new idea about block matrices.
+
+
+dbtype redmert
+
+
+1 function [M,R] = redmert(p,Rin)
+2 M = zeros(p,1);
+3 R = sparse(triu(Rin));
+4 n = size(R,1);
+5 for q = 1:p
+6 n = n+1;
+7 k = (mod(n,1:n) == 0);
+8 R(k,n) = 1;
+9 e = ones(n-1,1);
+10 M(q) = R(1,1) - e'*(R(2:n,2:n)\e);
+11 end
+12 end
+
+
mertens_plot
+
+
It takes about five hours for redmert to compute half a million values on my laptop.
+
+
n = 0.5e6;
+ p = 0.5e4;
+ R = sparse([]);
+ M = [];
+ for k = p:p:n
+ disp(k)
+ [Mout,R] = redmert(p,R);
+ M = [M; Mout];
+ mertens_plot(M)
+ end
+
+mertens_plot
+
+
Postscript
+
+
I started this project by being surprised to find myself computing determinants. Now I am back to my long-time position disparaging determinants. They have been replaced by a good friend, backslash.
+
+]]>MathWorks BlogsRedheffer and Mertens, Continued2024-09-27T12:28:39-06:002024-09-27T12:28:39-06:00https://hpc.social/commercial-blog/2024/redheffer-and-mertens-continued
+
Shortly after I posted Redheffer, Mertens and One-Million Dollars a few days ago, Mathworks' Pat Quillen made an important observation about computing the Mertens function.
The elements in the first column of the Redheffer matrix, A = redheffer(n), are all equal to one. That dense column does not make MATLAB happy about computing det(A) . However, the last column of A has only a few nonzero elements and so Pat suggested interchanging the first and last columns before computing the determinant. This makes a world of difference. (Thanks, Pat.)
+
+
typemertens
+
+
+function M = mertens(n)
+ if n > 1
+ A = redheffer(n);
+ A(:,[1 n]) = A(:,[n 1]);
+ M = -round(det(A));
+ else
+ M = 1;
+ end
+end
+
+
The time required to compute det(A) varies with the sparsity of the last column, but it is only a little more than the time to compute redheffer(n) in the first place.
+
+
mertens2_time
+
+
Mertens function
+
+
Pat's change makes it possible to take n up to a quarter of a million, and beyond. Here is a new plot of the Mertens function M(n) and the sqrt(n) bounds of the Mertens conjecture.
+
+
mertens_plot
+
+
There are a quarter of a million points in the data for this plot. Fortunately, the .PNG file used for the blog only needs to sample the data.
+
+
Mertens computation
+
+
The job that I ran on my laptop to compute one-quarter of a million values of M(n) is still running. It currently is past 0.35 million and takes less than two seconds for each value. I may keep the job running over the weekend, just to see how far it gets.
+
+
The task is embarrassingly parallel. If I had a pool with a million processors, I could have each processor compute one value. I would then just have to collect the results, but that doesn't involve any arithmetic.
+
+
Mertens conjecture
+
+
You can see from the plot why late 19th- and early 20th-century mathematicians believed that the Mertens conjecture,
+
+
|M(n)| < sqrt(n) for all n,
+
might be true. It is hard to imagine that the plot of M(n) ever escapes sqrt(n).
+
+
We now know that M(n) eventually does escape, but only barely and only briefly. We also know that all the computation we can do with determinants of Redheffer's matrix will never prove or disprove the conjecture or win that million-dollar prize.
+Raymond Redheffer (1921-2005) was an American mathematician, a professor at UCLA for 55 years, the author of several popular textbooks, the inventor of the electronic game Nim and, with Ray and Charles Eames, the creator of a four-meter long poster Men of Modern Mathematics.
+
+
Redheffer's matrix is a matrix of zeros and ones. A(k,j) equals one if j is a divisor of k. In addition, the first column is all ones.
+
+
function A = redheffer(n)
+ k = 1:n;
+ j = k';
+ A = (mod(k,j) == 0);
+ A(:,1) = 1;
+ end
+ A = redheffer(200);
+ spy(A)
+ title('redheffer(200)')
+
+
Möbius Function
+
+
The Möbius function was introduced in 1832 by German mathematician August Möbius and is ubiquitous in the study of prime numbers. For positive integers n, μ(n) is
+
+
+
+
+0 if n has a squared prime factor,
+
++1 if n is square-free and has an even number of prime factors,
+
+-1 if n is square-free and has an odd number of prime factors.
+
+
+
+
Mertens Function
+
+
+Franz Mertens (1840-1927) was a Polish mathematician who spent most of his career in Austria at the University of Vienna. Here is a link to a biography of Mertens at the University of St. Andrews MacTutor project.
+
+
The Mertens function is sum of values of the Möbius function. For a positive integer n, the Mertens function is
+
+
M(n) = sum(μ(1:n))
+
So M(n) is the difference between the number of square-free integers with an even number of prime factors and those with an odd number.
+
+
This graphic shows M(n) for n = 1:100000.
+
+
+ mertens_plot_2
+
+
Mertens Conjecture
+
+
The Mertens function M(n) fluctuates wildly and grows slowly with increasing n. The graphic shows that M(n) is easily bounded by of sqrt(n) and -sqrt(n), at least for n less than 100k. The Mertens conjecture is that this continues for larger n.
+
+
-sqrt(n) < M(n) < sqrt(n) for all n
+
The conjecture was included in a letter from Stieltjes to Hermite in 1895 and in a paper by Mertens in 1897. The result is important since a proof of the Mertens conjecture would imply the truth of the Riemann hypothesis.
+
+
Mertens Meets Redheffer
+
+
I became interested in all this when I learned that the determinant of the MATLAB Gallery matrix which I have ignored for years is related to the Riemann hypothesis and the million-dollar prize.
+
+
M(n) = det(gallery('redheff',n))
+
I know very little about the distribution of prime numbers and computing values of the Möbius function. On the other hand, I know a lot about numerical linear algebra and computing determinants.
+
+
In general, I am dead set against computing determinants. They are often used to check for singularity or to somehow compute eigenvalues. But here the determinant is an integer counter of modest size.
+
+
Redheffer Sparsity
+
+
Computing M(n) directly with det(redheffer(n)) requires O(n^2) space and O(n^3) time and is not practical for large n.
+
+
However, A = redheffer(n) is modestly sparse. Here is the fraction of nonzeros.
Taking advantage of this sparsity and the MATLAB tools for sparse matrix computation provide linear space complexity and perhaps O(n^2) time complexity.
+
+
+redheffer
+
+
Here is MATLAB code to generate a sparse redheffer(n) without creating any full intermediate matrices.
+
+
type redheffer
+
+
+ function A = redheffer(n)
+ j(1:n) = (1:n)';
+ k(1:n) = 1;
+ m = n;
+ for i = 2:n
+ t = [1 i:i:n]';
+ p = length(t);
+ j(m+(1:p)) = t;
+ k(m+(1:p)) = i;
+ m = m+p;
+ end
+ A = sparse(k,j,1,n,n);
+ end
+
+
As expected, we see that the execution time for redheffer(n) is a linear function of n. (The space required also grows linearly.)
+
+
+ redheffer_time
+
+
Sparse LU
+
+
The MATLAB Gaussian elimination function lu with one sparse input and four sparse outputs is designed for solving sparse linear systems.
+
+
[L,U,P,Q] = lu(A)
+
Written primarily by Tim Davis and included in his UMFPACK package, the function uses an unsymmetric pattern multifrontal pivoting strategy to find permutations P and Q so that L is lower triangular, U is upper triangular and
+
+
P*A*Q = L*U
+
Consequently, the determinant of A is the product of four easily computed determinants.
+
+
det(A) = det(L)*det(U)*det(P)*det(Q)
+
The pivoting strategy aims to reduce fill-in while maintaining numerical stability.
+
+
For example, here are L and U for the Redheffer matrix in the spy plot near the top of this blog post.
+
+
+ close
+ A = redheffer(200);
+ [L,U,P,Q] = lu(A);
+ spy(L|U)
+ title('L|U')
+
+
And here are the four determinants.
+
+
+ dets = [det(L),det(U),det(P),det(Q)];
+ disp(dets)
+
+
+ 1 -8 -1 -1
+
+
Finally, M(200) is
+
+
+ M_200 = det(L)*det(U)*det(P)*det(Q)
+
+
+ M_200 =
+ -8
+
+
+mertens
+
+
Mertens function can be computed with four lines of code.
+
+
+ type mertens
+
+
+ function M = mertens(n)
+ der = @(x) full(round(prod(diag(x))));
+ A = redheffer(n);
+ [L,U,P,Q] = lu(A);
+ M = der(L)*der(U)*det(P)*det(Q);
+ end
+
+
Execution time for mertens is dominated by the time in sparse lu. The time required to compute the four determinants is an order of magnitude smaller than the other two.
+
+
Experimentally, we see that the time complexity of sparse lu is O(n^2), but we have no proof.
+
+
+ mertens_time
+
+
Mertens Conjecture Is False
+
+
The Mertens conjecture stood for nearly 100 years before it was proved false in 1985 by Andrew Odlyzko and Herman te Riele. The authors present indirect proofs that
+
+
lim sup (n -> inf) M(n)/sqrt(n) > 1.06
+
lim inf (n -> inf) M(n)/sqrt(n) < -1.009
+
Odlyzko and te Riele do not actually produce any value of n for which M(n) > sqrt(x). They suspect that any Mertens conjecture counterexample requires n > $10^{30}$, which is far beyond any computation possible today.
+
+
Odlyzko and te Riele also describe several complete tabulations of M(n) for n as large as $7.8 \cdot 10^{9}$ . These computations do not use Redheffer determinants.
+
+
Postscripts
+
+
To tell the truth, I did not really expect to find any Mertens or Riemann counterexamples. I did, however, enjoy computing determinants for the first time and discovering an unexpected use for sparse LU.
+
+
Thanks a lot to Tim Davis for his help with this post.
+
+
References
+
+
A. M. Odlyzko and H. J. J. te Riele, "Disproof of the Mertens conjecture", Journal für die reine und angewandte Mathematik, Vol. 357 (1985), Pages138-160. https://eudml.org/doc/152712.
+
+
Timothy A. Davis, "A Column Pre-Ordering Strategy for the Unsymmetric-Pattern Multifrontal Method", ACM Transactions on Mathematical Software, Vol. 30, No. 2, June 2004, Pages 165–195. https://dl.acm.org/doi/abs/10.1145/992200.992205.
+
+]]>MathWorks BlogsNA_Digest and NA_Net2024-08-31T21:44:36-06:002024-08-31T21:44:36-06:00https://hpc.social/commercial-blog/2024/na-digest-and-na-net
+
The NA-Digest is an electronic newsletter for the numerical analysis and scientific software community. The NA-Digest is one of world's first examples of social networking. The Digest is one of the forces that makes our community a living, viable community.
+
+
The Digest is part of NA-Net, which also includes Netlib, a collection of mathematical software, papers, and databases.
+
+
For its first forty years, the NA-Digest has had only four editors. Now, we are adding two more. As we do that, I would like to take a personal look back at the history of the NA-Digest.
Like many other developments in the numerical analysis world, the Digest began with Gene Golub. In the early 1980's, Golub was chair of Stanford's Computer Science Department. Email was a new thing and Gene maintained a list of email addresses for his many friends around the world. Email addresses came in many different formats; today's system of domain names was not yet in wide spread use.
+
+
In 1984, Mark Kent, one of Gene's grad students, with help from Ray Tuminaro, Mark Crispin and Dan Kolkowitz, wrote software that used Gene's list in an email forwarding service. Mail sent to
+
+
+na.name@su-score
+
+
+
would be forwarded to the person with that last name. And email sent to
+
+
+na@su-score
+
+
+
would be forwarded to everyone on the list.
+
+
Gene and Mark Kent began to gather contributions together and send the collection out periodically. By February 1987, this had evolved into a moderated weekly newsletter. Gene dubbed these email services the NA-Net.
+
+
Nick Trefethen has this memory.
+
+
Early in the days of email, domain names were all over the place.
+ I think there was a period when Gene was using xxx.na for the
+ names of numerical analysts. Then somebody decided addresses should
+ end with the country, giving us .uk and .fr and .ch and all
+ that. For a period, we found that a lot of our numerical
+ analysis emails were being directed to Namibia!
+
In 1987, Gene asked me to moderate NA-Digest temporarily while he went on a sabbatical. That temporary position ultimately lasted 18 years, until 2005.
+
+
Jack and Eric
+
+
+Jack Dongarra began his career at Argonne National Laboratory. Jack's colleague, Eric Grosse, began his career at Bell Labs. In 1984, Jack and Eric created Netlib, a software repository and distribution service, and merged it with NA-Net. In 1989, Jack and the NA-Net system moved from Argonne to Oak Ridge National Lab and the University of Tennessee.
+
+
Keith Moore, at the University of Tennessee, rewrote the NA-Net software and maintained the servers for many years.
+
+
Gerald Ragghianti, the Technical Services Leader at Tennessee's Innovative Computer Lab, currently maintains the NA-Net software and servers.
+
+
Tammy and Danny
+
+
In 2005, I asked Tammy Kolda, who was then at Sandia Labs in Livermore, to be the NA-Digest editor. Tammy's Wikipedia page reveals that her given name is "Tamara", but everybody calls her "Tammy". She left Sandia is 2021 and now has her own consulting company, MathSci.ai.
+
+
In 2010, Tammy recommended that Danny Dunlavy, from Sandia Labs in Albuquerque, take over as editor. He has been the editor for 14 years. Danny's day job at Sandia's Center for Computing Research involves a wide range of fields including computer architecture, cognitive modeling and discrete mathematics.
When I succeeded Gene as editor in 1987, there were about 800 names on the NA-Net mailing list. Today, in 2024, there are a little over 10,000. Discontinuities in the size of the list result when unused and illegitimate names are removed.
+
+
+
+
+
Important Postings
+
+
I have made three personally important announcements in the Digest over the years.
+
+
+October 29, 1989
+
+
+
In 1989 I was working at Ardent Computer, a startup in Silicon Valley. I announced in NA-Digest that MathWorks was looking for a numerical analyst. (Note the MathWorks telephone number near the end of this announcement.)
+
+
From: Cleve Moler <na.moler@na-net.stanford.edu>
+ Date: Sun Oct 29 10:39:38 PST 1989
+ Subject: Positions at The MathWorks
+
The MathWorks is the company which develops and markets MATLAB.
+ The company currently employs about 30 people and expects to
+ add three or four more soon. The company headquarters is in
+ East Natick, Massachusetts, which is about a half hour drive
+ west of Boston.
+
The background and interests expected for the various positions
+ available range from numerical linear algebra and matrix computation
+ to systems programming and graphics. Educational level and
+ experience expected range from inexperienced beginner willing
+ to learn to seasoned Ph.D. with a personal library of M-files.
+
For more information, send email to na.moler@na-net.stanford.edu
+ or phone me at 408-732-0400. Or, contact the MathWorks' president,
+ John Little, with email to jnl@mathworks.com, phone 508-653-1415,
+ or write to:
+
The MathWorks
+ 21 Eliot Street
+ South Natick, MA 01760
+
+November 26, 1989
+
+
+
Shortly after that announcement, Ardent imploded and I said that I was taking the job myself.
+
+
From: Cleve Moler <moler@mathworks.com>
+ Date: Sun Nov 26 09:16:32 PST 1989
+ Subject: Change of Address for Moler
+
A couple of weeks ago, I made an announcement here that
+ The MathWorks, the MATLAB company, was looking to fill several
+ positions, including one for a numerical analyst. Now, I've
+ decided to take that slot myself. I'm one of the founders of
+ MathWorks, and have always been a consultant to the company, but
+ now I'll be a full time employee. For a while at least, I'll
+ be working out of my home in California, even though MathWorks
+ headquarters is in Massachusetts. (There are already a couple
+ of other MathWorks developers in the Bay Area.)
+ . . .
+ My electronic address is "moler@mathworks.com". If your mailer
+ can't find the route via uunet to mathworks.com, you can still
+ use "na.moler@na-net.stanford.edu".
+
+November 16, 2007
+
+
+
In November 2007 I was attending the Super Computing conference in Reno. I had rented a car and intended to drive to the Bay Area after the conference. But my wife called me and said, "Hey Cleve, have you heard that Gene is in the hospital?" I left SC immediately and drove to Palo Alto. Two days later we sent out a special issue of the Digest:
Gene Golub, founder of the NA Digest, passed away today, Friday, November 16,
+ at the Stanford University Hospital. He was 75 years old.
+
Gene returned home to Stanford recently from a trip to Hong Kong. He was
+ planning to leave again Tuesday on another trip, this one to Zurich where the
+ ETH was to honor him with a special degree. Instead, Sunday night he went to
+ the emergency room because he was "feeling lousy". On Tuesday, he was found
+ to have AML, acute myelogenous leukemia, a form of cancer that affects the
+ white blood cells. This is a potentially curable disease and he was expecting
+ to begin chemotherapy today. But serious complications developed suddenly
+ over night.
+
I was able to see Gene for an hour last night and he was in reasonably good
+ spirits. Mike Saunders was trying to get Gene's laptop to use dial-up over
+ the hospital's phone system because Gene said he was a couple of days behind
+ on his email. I was planning to get a wireless card for his machine today.
+ None of us had any idea how suddenly the situation would worsen.
+
The Stanford ICME students have created a memorial blog at
+ http://genehgolub.blogspot.com .
+
Our community has lost its foremost member. He was a valued colleague and
+ friend. Goodbye, Gene.
+
-- Cleve Moler
+
Thanks
+
+
+
+
Gene Golub and Mark Kent for creating NA-Digest and NA-Net.
+
Tammy Kolda and Danny Dunlavy for editing the Digest for two decades.
+
Jack Dongarra, Eric Grosse, Keith Moore and Geri Ragghianti for creating Netlib and for hosting the system for four decades.
+
David Bindel and Alex Townsend for joining this team.
A few days ago, a bug report from our office in Cambridge caught my attention. Computing the singular values and singular vectors of a particular matrix would sometimes cause MATLAB to crash.
I use two different two computers regularly. The machine in my home office is a Lenovo ThinkPad® model T14, loaded with two external monitors, several external disc drives, a sound bar and a dedicated internet connection. My traveling machine is a Lenovo ThinkPad X1 Nano with no external hardware.
+
+
The report of a crash in the SVD became even more interesting when I found that it happens on my office computer, but not on the portable. A quick check revealed that the CPUs on the two machines come from different manufacturers. The office computer uses an AMD® Ryzen Pro 5 while the traveling machine uses an Intel® Core i7.
+
+
Math Libraries
+
+
The crash occurs several software layers deep in CGESVD, the LAPACK driver for single precision complex SVD. Various chip manufacturers provide math libraries that have been optimized for their CPUs. However, by default, MATLAB uses the reportedly faster Intel Math Kernel Library, MKL. It is possible to switch to other math libraries.
+
+
We have experts at MathWorks who know far more about the details of these libraries than I do. They will soon sort this all out. In the meantime, here is what I have learned about the offending matrix.
+
+
G3366394
+
+
We refer to the matrix in the crash report by its case number in our bug tracking system. The matrix is of modest size but is otherwise unusual for several reasons. It is rectangular with fewer rows than columns, it is in single precision, and it is complex.
+
+
clear
+ load g3366394 X
+ whos
+
Name Size Bytes Class Attributes
+ X 219x384 672768 single complex
+
The following code calling SVD with three outputs will crash MATLAB on my T14, but not on my X1.
+
+
trysvd = false
+ if trysvd
+ [U,S,V] = svd(X);
+ R = U*S*V' - X;
+ relres = norm(R)/norm(X)
+ end
+
trysvd =
+ logical
+ 0
+
Rank
+
+
Computing the singular values without the vectors can be done on either machine. The following code uses double precision and then plots the singular values on a logarithmic scale with a line at single precision roundoff level.
+
+]]>MathWorks BlogsSuperSum, In Defense of Floating Point Arithmetic2024-06-27T17:54:38-06:002024-06-27T17:54:38-06:00https://hpc.social/commercial-blog/2024/supersum-in-defense-of-floating-point-arithmetic
+
Floating point arithmetic doesn't get the respect it deserves. Many people consider it mysterious, fuzzy, unpredictable. These misgivings often occur in discussion of vector sums. Our provocatively named SuperSum is intended to calm these fears.
A ledger is a list of transactions in an account. Auditing the ledger involves comparing the total of the items with the change in the account balance.
+
+
If v is a vector of transaction amounts, then we need to compute
+
+
sum(v)
+
If this sum is equal to the change in the balance, then it is reasonable to assume that the ledger is correct. If not, the ledger must be examined line-by-line.
+
+
Checksums
+
+
Have you ever used a checksum for a file transfer? One checksum is computed before the file is sent. After the file has been sent over a questionable channel, a second checksum is computed on the receiving end. If the two checksums agree, the transmission was probably okay. If not, the file must be sent again.
+
+
Order
+
+
Floating point addition is not associative. This means
+
+
(a + b) + c
+
is not necessarily the same as
+
+
a+(b+c).
+
+
So the order of doing a computation is important.
+
+
Computers are deterministic devices. If the same computation is done in the same order more than once, the results must be the same. If you get different sums from different runs on a fixed computer, then it must be because the order has been changed.
+
+
Speed
+
+
In recent years, we have made the built-in function sum(x) faster by parallelizing it. The input vector is broken into several pieces, the sum of each piece is computed separately and simultaneously, then the partial sums are combined to give the final result. If the number and size of the pieces varies from run to run, the order varies and consequently the computed sums may vary.
+
+
Three Sums
+
+
Here are three replacements for nansum(x), the version of sum(x) that skips over NaNs and infs.
+
+
+simplesum
+
+
+
Avoid the effect of blocking in the built-in sum(x).
+
+
function s = simplesum(x)
+ % simplesum. s = simplesum(x), for vector(x).
+ % Force sequential order for sum(x).
+ % Skips NaNs and infs.
+
s = 0;
+ for k = 1:length(x)
+ if isfinite(x(k))
+ s = s + x(k);
+ end
+ end
+end
+
+KahanSum
+
+
+
This is the Kahan summation algorithm. The sum is accumulated in two words, the more significant s and the correction c. If you were able to form s + c exactly, it would be more accurate than s alone.
+
+
function s = KahanSum(x)
+ % KahanSum. s = KahanSum(x), for vector(x).
+ % More accurate, but slower, than sum(x).
+ % Skips NaNs and infs.
+ % https://en.wikipedia.org/wiki/Kahan_summation_algorithm.
+
s = 0; % sum
+ c = 0; % correction
+ for k = 1:length(x)
+ if isfinite(x(k))
+ y = x(k) - c;
+ t = s + y;
+ c = (t - s) - y;
+ s = t;
+ end
+ end
+end
+
+SuperSum
+
+
+
I gave it a pretentious name to grab attention. Use extended precision, with enough digits to hold any MATLAB double.
+
+
function s = SuperSum(x)
+ % SuperSum. s = SuperSum(x), for vector(x).
+ % Symbolic Math Toolbox extended precision.
+ % Skips NaNs and infs.
+ %
+ % 632 decimal digits holds every IEEE-754 double.
+ % 632 = ceil(log10(realmax) - log10(eps*realmin));
+ %
+ din = digits(632); % Remember current setting
+ s = double(sum(sym(x(isfinite(x)),'D')));
+ digits(din) % Restore
+end
+
Toy Example
+
+
A test case here at MathWorks, known by a French-Canadian name that translates to "toy example", has a vector e2 of length 4243 and values that range from -3.3e7 to 6.8e9.
+
+
When running tests involving floating point numbers it is a good idea to set the output format to hex so we can see every last bit.
ans =
+ 423785e8206150e2
+ 423785e8206150e0
+ 423785e8206150e1
+ 423785e8206150e1
+
For jeuTest, Kahan summation gets the same result as SuperSum, while nansum and simplesum differ in the last bit or two.
+
+
Second Test
+
+
The vector length is only three, but the third term completely cancels the first, and the second term rises from obscurity. In this situation, KahanSum is no more accurate than sum.
x =
+ 3ff0000000000000
+ 3d06849b86a12b9b
+ bff0000000000000
+
ans =
+ 3d06800000000000
+ 3d06800000000000
+ 3d06800000000000
+ 3d06849b86a12b9b
+
Conclusion
+
+
I will leave careful timing for another day. Let's just say that in situations like jeuTest, KahanSum is probably all you need. It is usually more accurate than sum, and not much slower.
+
+
However, for complete reliability, use SuperSum. There is no substitute for the right answer.
Our technical support group recently received a request for a tool that would convert IBM System/360 hexadecimal floating point numbers to the IEEE-754 format. I am probably the only one left at MathWorks that actually used IBM mainframe computers. I thought we had seen the last of hexadecimal arithmetic years ago. But, it turns out that the hexadecimal floating point format is alive and well.
The System/360 is a family of mainframe computers that IBM introduced in 1965 and that dominated the computer industry until PCs came along twenty years later. They range in size from desk-sized to systems that fill a large room.
+
+
Here is a photo of a mid-sized model.
+
+
+
+
+
+System/360, Model 60.Photo from Ken Shirrif's blog, IBM 360/System Summary.
+
+
The System/360 architecture is byte-oriented, so it can handle business data processing as well as scientific and engineering computation. This leads to base-16, rather than base-2 or base-10, floating point arithmetic.
Floating point formats played an important role in technical computing in the early days. This table from FMM lists formats that were in use in the 1970s, before IEEE-754 was introduced in 1985.
+
+
+
+
+
Data
+
+
The System/360 hexadecimal format is used in many industries for the preservation of data files.
+
+
+CREWES. Teaching exploration seismology. Comprehensive MATLAB toolbox for use with the textbook "Numerical Methods of Exploration Seismology with algorithms in Matlab" by Gary F. Margrave, a geoscience professor at the University of Calgary.
Hex_ieee. I have two twenty-line MATLAB functions, ieee2ibm and ibm2ieee, that convert IEEE-754 floating point to and from IBM hexadecimal format.
+
+
Three statements in the middle of ieee2ibm are the key to the entire operation. The first statement is
+
+
[~,e] = log2(x)
+
With two output arguments, log2 returns the mantissa and exponent of an IEEE-754 floating point number. The mantissa is not needed here.
+
+
The second key statement
+
+
e = ceil(e/4)
+
makes e divisible by 4. This turns e into the appropriate hexadecimal exponent so that the third statement
+
+
f = x.*16.^(-e)
+
can produce the hexadecimal mantissa.
+
+
+ieee2ibm
+
+
function z = ieee2ibm(x)
+ Convert IEEE-754 to IBM System 360 hexadecimal.
+ z = ieee2ibm(x)
+ Input x, real column vector.
+ Output z, length(x)-by-16 char.
+ Example: ieee2ibm(-118.625) = 'C276A00000000000'.
+
s = sign(x); % -1, 0, or 1
+ x = abs(x);
+ x(x < 16^(-65)) = 0; % Underflow
+ x(x >= 16^63) = (1-eps/2)*16^63; % Overflow
+
[~,e] = log2(x); % base 2 exponent
+ e = ceil(e/4) % base 16 exponent
+ f = x.*16.^(-e); % base 16 mantissa
+
E = uint64((e+64)*2^56); % Assemb1e output
+ F = uint64(f*2^56);
+ S = uint64((1-s)*2^62); % 1 or 0
+ z = dec2hex(S + E + F); % z = 'ZZFFFFFFFFFFFFFF'
+end
+
+ibm2ieee
+
+
function x = ibm2ieee(z)
+ Convert IBM System 360 hexadecimal to IEEE-754.
+ x = ibm2ieee(z)
+ Input z, n-by-16 char.
+ Output x, n-by-1 double.
+ Example: ibm2ieee('C276A00000000000') = -118.625.
+
E = hex2dec(z(:,1:2)); % Disassemble input
+ F1 = hex2dec(z(:,3:8)); % < 16^6
+ F2 = hex2dec(z(:,9:end)); % < 16^8
+ s = sign(128-E); % -1 or 1
+
e = E-(s>0)*64-(s<0)*192; % base 16 exponent
+ f = F1/16^6 + F2/16^14; % base 16 mantissa
+ x = s.*f.*16.^e;
+end
+
Examples
+
+
Underflow. Anything < 16^(-65) is too small and is flushed to zero. There are no denormals.
+
+
Overflow. Anything >= 16^63 is too large. There is no inf or NaN.
S/360 hexadecimal has 7 exponent bits, while IEEE-754 has 11. Consequently, hexadecimal has a much smaller range, 5.4e-79 to 7.2e+75 versus 2.2e-308 to 1.8e+308.
+
+
The base-16 normalization implies that hexadecimal effectively has between 53 and 56 mantissa bits. Counting the hidden bit, IEEE-754 also has 53. So, the accuracy of the two is pretty much the same.
+
+
Software
+
+
My functions ieee2ibm and ieee2ibm described above, modified to handle both single and double, plus hex_test, which does what its name implies, are available at Hex_ieee.
+
+
Homework: What happens?
+
+
ok = 0;
+for k = 1:10
+ x = single(k/10);
+ ok(k) = hex_test(x);
+end
+ok
+
+]]>MathWorks BlogsA Sixty-Year Old Program for Predicting the Future2024-05-19T16:55:03-06:002024-05-19T16:55:03-06:00https://hpc.social/commercial-blog/2024/a-sixty-year-old-program-for-predicting-the-future
+
The graphics in my post about R^2 were produced by an updated version of a sixty-year old program involving the U.S. census. Originally, the program was based on census data from 1900 to 1960 and sought to predict the population in 1970. The software back then was written in Fortran, the predominate technical programming language a half century ago. I have updated the MATLAB version of the program so that it now uses census data from 1900 to 2020.
Today, MATLAB makes it easier to vary parameters and visualize results, but the underlying mathematical principles are unchanged:
+
+
+
+
Using polynomials to predict the future by extrapolating data is a risky business.
+
+
+
+
One new observation is added to the data every 10 years, when the United States does the decennial census. Originally there were only 7 observations; today there are 13. The program now allows you to fit the data exactly by interpolation with a polynomial of degree 12 or fit it approximately by polynomials of degree less than 12.
+
+
Here are the least-squares fits with linear, cubic, and degree seven polynomials and the interpolating polynomial. As the polynomial degree increases, so does R^2, until R^2 reaches one with the exact fit.
+
+
Do any of these fits look like they could be used to predict future population growth?
+
+
+
+
+
Splines
+
+
In addition to polynomials, you can choose interpolation by three different piecewise Hermite cubics.
+
+
+
+
+spline Continuous second derivate, "not-a-knot" end condition.
+
+pchip Continuous first derivative, strictly shape-preserving.
+
+makima Continuous first derivative, relaxed shape-preserving.
+
+
+
+
Since these fits interpolate the data, all their R^2 values are one. But before 1900 and after 2020 these functions are cubic polynomials that are not designed for extrapolation.
+
+
+
+
+
Exponentials
+
+
It is also possible to do nonlinear least squares fits by an exponential, a logistic sigmoid, and an exponential of an exponetial known as the Gompertz model.
+
+
+
+
+exponential exp(b*t+c)
+
+
+logistic a./(1+exp(-b*(t-c)))
+
+
+gompertz a*exp(-b*exp(-c*t))
+
+
+
+
+
An article by Kathleen and Even Tjørve, from the Inland Norway University of Applied Sciences in Elverum, Norway, in the journal PLOS ONE has this to say about Gompertz. "The Gompertz model has been in use as a growth model even longer than its better known relative, the logistic model. The model, referred to at the time as the Gompertz theoretical law of mortality, was first suggested and first applied by Mr. Benjamin Gompertz in 1825. He fitted it to the relationship between increasing death rate and age, what he referred to as 'the average exhaustions of a man’s power to avoid death” or the 'portion of his remaining power to oppose destruction.' "
+
+
+
+
+
Predictions
+
+
Which fits are suitable for predicting future population size?
+
+
Despite their large R^2 values, polynomials of any degree are not suitable because outside of the time interval they behave like polynomials and do not provide realistic predictions.
+
+
Splines were never intended for extrapolation.
+
+
That leaves the exponentials. The simple exponential model grows exponentially and is not suitable. The Gompertz fit does approach a finite asymptotic limit, but the value is an astronimical a = 2101, corresponding to 2.1 $\times 10^9$ inhabitants. Hopefully, that is out of the question.
+
+
The logistic fit has an asymptotic limit of a = 655.7. We recently passed the value of t where p(t) reaches a/2, namely c = 2018. So, the logistic model predicts that the long-term size of the U.S. population will be about twice its current value. Is that realistic? Probably not.
+
+
+
+
+
Conclusion
+
+
The British statistician George Box once said, "all models are wrong, some are useful." This is true of the models of the U. S. Census that I have discussed over the past sixty years.
+
+
Here is censusapp2024 after all its buttons have been pushed. The extrapolation date is set to 2040. White noise has been added to the data. The model is a fourth-degree polynomial with an R^2 = 0.99. The R^2 value and the error estimates produced by errs account for errors in the data, but not in the model.
+
+
This particular model does a lousy job of predicting even twenty years in the future. Some of the other models are better, many are worse. Hopefully, their study is worthwhile.
+
+
+
+
+
Blogs
+
+
I have made blog posts about the census before, in 2020 and in 2017.
+
+
FMM
+
+
Predicting population growth is featured in Computer Methods for Mathematical Computations, by George Forsythe, Mike Malcolm and myself, published by Prentice-Hall in 1977. That textbook is now available from an interesting smorgasbord of sources, including Google Scholar, Amazon, dizhasneatstuff, Abe Books, Internet Archive, PDAS, WorldCat (Chinese).
+
+
+
+
+
diff --git a/pages/404.md b/pages/404.md
deleted file mode 100755
index 98cc312..0000000
--- a/pages/404.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-layout: page
-title: "404: Page not found"
-permalink: /404.html
----
-
-Whoops! We couldn't find that link! [Go home]({{ site.baseurl }}) or just admire this cute animation.
diff --git a/pages/about.md b/pages/about.md
deleted file mode 100755
index 20df5e8..0000000
--- a/pages/about.md
+++ /dev/null
@@ -1,19 +0,0 @@
----
-layout: page
-title: "About the hpc.social Community Blog"
-permalink: /about/
----
-
-This belongs in the hpc.social family of blogs. In particular, this is an aggregated feed of commercial posts that meet the following criteria:
-
-> The commercial blog space is for vendor and company voices that don't fit in the personal or community spaces. We advocate for learning resources, tutorials, and related content, and encourage contributors to not use this as an advertising space.
-
-The hpc.social blogs aims to share ideas, news, and stories from diverse people, centers and groups across the High Performance Computing (HPC) community.
-Whether you are an advanced practitioner, a developer that touches HPC, or a novice, your voice is welcome here. This community blog reflects exactly that - a syndicated feed of our community voices. It's one places that you can subscribe to via a variety of channels (below) and also follow instructions to contribute a commercial feed.
-
-
-
-
-
-As a word of caution, we curate authors at the point of adding the blog, but do not regularly curate individual posts that are added nightly via automation. The opinions expressed here are owned by the authors and do not reflect the opinion of the hpc.social community at large. Offensive or inappropriate posts should be reported to [info@hpc.social](mailto:info@hpc.social) if you wish to report anonymously. You can also submit a pull request to remove the offending feed if you are comfortable doing so publicly.
-
diff --git a/pages/archive.md b/pages/archive.md
deleted file mode 100644
index 8477f28..0000000
--- a/pages/archive.md
+++ /dev/null
@@ -1,21 +0,0 @@
----
-layout: page
-title: Archive
-description: A collection of posts, organized by year
-permalink: /archive/
----
-
-{% include scrolltop.html %}
-
- {% for post in site.posts %}
- {% assign currentDate = post.date | date: "%Y" %}
- {% if currentDate != myDate %}
- {% unless forloop.first %}{% endunless %}
-