813 views

### Rob Beezer

Dec 1, 2010, 11:47:50 PM12/1/10
to sage-devel
What does the "adjoint of a matrix" mean to you?

I was brought up to understand it to mean the transpose of the matrix
of signed minors, a matrix close to being the inverse of the
original. Poking around (Wikipedia, Planet Math, Math World) would
imply this is known as the "classical adjoint." Hmmm, I'm not that
old. Anyway, it is also known now as the "adjugate matrix."

It seems that the term "adjoint" is now more commonly used for the
conjugate-transpose of a matrix (and for vectors) and that's what I
find in most any relatively new textbook on matrix algebra.

Presently, in Sage, "adjoint" gives the "classical" interpretation. I
would much prefer to define and implement the adjoint of a matrix to
be the conjugate transpose. So two questions:

1. Thoughts on what "adjoint" should be?

2. If adjoint were to be redefined to a more modern interpretation,
its current use could be aliased to "adjugate" and deprecated, but
that won't make it available for reuse until the deprecation period
runs its course. Any precedent, or techniques, for radically
redefining a method name?

Rob

### John Cremona

Dec 2, 2010, 4:16:31 AM12/2/10
My opinion:

What you call the classical adjoint is really the adjugate. That is
abbreviated to adj, and since there is also an adjoint, it is a common

I would not be surprised if there plenty of elementary linear algebra

For a complex square matrix the genuine adjoint is denoted A^* and is
the conjugate transpose. That is a special case of the adjoint of a
linear operator on an inner product space (in the case of C^n with the
standard inner product).

However: the first ever occurrence of what I just said is really the
adjugate is in Gauss's Disquisitiones Mathematicae in Art. 267 (page
293 of the modern Springer translation), where he calls it the
adjoint! But this is in a very special case: symmetric 3x3 integer
matrices, representing ternary quadratic forms, and Gauss does not use
our standard matrix notation. So he is defining the adjoint of
ternary quadratic forms rather than matrices.

I support your proposal but it would have to be very well documented.
We already have the problem, for those wanting to use Sage to teach
linear algebra, that it uses the Magma convention where matrices act
on the right on row vectors instead of the more common convention in
textbooks of a left action on column vectors. This is potentially
another situation like that...

John

> --
> To post to this group, send an email to sage-...@googlegroups.com
> To unsubscribe from this group, send an email to sage-devel+...@googlegroups.com
> For more options, visit this group at http://groups.google.com/group/sage-devel
> URL: http://www.sagemath.org
>

### kcrisman

Dec 2, 2010, 9:43:37 AM12/2/10
to sage-devel
> For a complex square matrix the genuine  adjoint is denoted A^* and is
> the conjugate transpose.  That is a special case of the adjoint of a
> linear operator on an inner product space (in the case of C^n with the
> standard inner product).

That's what I thought, too. We should definitely change this.

An extremely non-random sample of linear algebra texts in my office
suggests this is the usual use in undergraduate texts.

> I support your proposal but it would have to be very well documented.
> We already have the problem, for those wanting to use Sage to teach
> linear algebra, that it uses the Magma convention where matrices act
> on the right on row vectors instead of the more common convention in
> textbooks of a left action on column vectors.  This is potentially
> another situation like that...

Having not used Sage to teach linear algebra, I haven't run into
that... yet. But probably the current situation with the adjoint is
the reverse situation (i.e., current behavior is not the usual
convention for teaching).

With respect to 2., maybe a search of all sagenb worksheets for uses
of adjoint would be helpful in ascertaining things... or it could be a
backwards-incompatible change in time for 5.0. Whenever that
happens. But I don't think there is a good way to come up with an
interim solution, short of adding a keyword nonclassical=True, which
seems extremely onerous!

- kcrisman

### Gonzalo Tornaria

Dec 2, 2010, 8:51:38 PM12/2/10
On Thu, Dec 2, 2010 at 7:16 AM, John Cremona <john.c...@gmail.com> wrote:
> What you call the classical adjoint is really the adjugate.  That is
> abbreviated to adj, and since there is also an adjoint, it is a common

Do you have a reference for this convention? I had never seen the word

--

Something interesting:

if T : V --> V is an operator, it naturally induces a graded operator
T* in the exterior algebra of V. If V is of finite dimension n, there
are two pieces of the exterior algebra which are isomorphic to V,
namely

1. Lambda_1(V) = the dual space of V
2. Lambda_{n-1}(V) = the space of (n-1)-multivectors of V

Then the restriction of T* to Lambda_1(V) is the adjoint (or dual)
operator, but the dual space is not canonically isomorphic to V. Given
a duality (inner product) then you get the adjoint operator acting in
V. The matrix depends on the choice of basis.

On the other hand, Lambda_{n-1}(V) is naturally isomorphic to V (the
isomorphism is given by the determinant), and
so the restriction of T* to Lambda_{n-1}(V) naturally induces an
operator on V, which is precisely what I would call "adj T". Since
this is natural, an adjoint operation for matrices can be defined in
terms of this.

In summary, both notions of adjointness are quite related. The simple
one is just duality, and makes more sense for operators in inner
product spaces. The seemingly not-so-simple one is natural, makes
sense for operators or matrices, is usually expressed in terms of
matrices, and appears often in relation to quadratic forms.

> However:  the first ever occurrence of what I just said is really the
> adjugate is in Gauss's Disquisitiones Mathematicae in Art. 267 (page
> 293 of the modern Springer translation), where he calls it the
> adjoint!  But this is in a very special case: symmetric 3x3 integer
> matrices, representing ternary quadratic forms, and Gauss does not use
> our standard matrix notation.  So he is defining the adjoint of
> ternary quadratic forms rather than matrices.

+1 to Gauss :-)

[he reduces ternary quadratic forms by alternating a binary reduction
step on the form itself and a binary reduction step on the adjoint, so
he may have invented adjoints for this purpose]

Gonzalo

### kcrisman

Dec 2, 2010, 9:59:07 PM12/2/10
to sage-devel

On Dec 2, 8:51 pm, Gonzalo Tornaria <torna...@math.utexas.edu> wrote:
> On Thu, Dec 2, 2010 at 7:16 AM, John Cremona <john.crem...@gmail.com> wrote:
> > What you call the classical adjoint is really the adjugate.  That is
> > abbreviated to adj, and since there is also an adjoint, it is a common
>
> Do you have a reference for this convention? I had never seen the word
>

At least in an older edition of Lay's Linear Algebra book (fairly
widely used) uses this, and points out there is a "real" adjoint which
is not covered in his text.

- kcrisman

### Gonzalo Tornaria

Dec 2, 2010, 11:21:31 PM12/2/10
On Fri, Dec 3, 2010 at 12:59 AM, kcrisman <kcri...@gmail.com> wrote:
>> Do you have a reference for this convention? I had never seen the word
>
> At least in an older edition of Lay's Linear Algebra book (fairly
> widely used) uses this, and points out there is a "real" adjoint which
> is not covered in his text.

With a bit of help of books.google.com I can see "adjugate" is used in
this book (adjoint matrix is not used, though); however it doesn't
seem to contain any reference to where this word came from. Do you
know?

On the other hand, searching for

"The adjoint of a square matrix" bourbaki

in books.google.com, yields the following passage:

"""
The adjoint of a square matrix X of order n over A is the matrix X =
(det (A'")) of minors of A" of order n — 1.
"""

(bourbaki, elements, book 2, chapter III, section 11, exercise 9 --
the term also shows at the index of terminology)

Best,
Gonzalo

### Rob Beezer

Dec 3, 2010, 1:19:45 AM12/3/10
to sage-devel
Planet Math page (below) says H. Eves (Elementary Matrix Theory, Dover
publications, 1980) uses "tranjugate." Maybe that is the solution
here. ;-)

Thanks, Gonzalo, John and KDC - I continue to learn a lot from the
collective knowledge here.

I do not know the source of any of these terms, but here are a couple
of books I've been using a lot lately, plus three accessible internet
sites (which all seem to link to each other).

Trefethen & Bau, Numerical Linear Algebra
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This nice text uses "adjoint" regularly for the conjugate transpose

Watkins, Fundamentals of Matrix Computations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2010 revision just calls it "conjugate transpose"

Planet Math
~~~~~~~~~~~

"The conjugate transpose of A is also called the adjoint matrix of A"

http://planetmath.org/encyclopedia/Tranjugate.html

from the usual usage of ``adjoint'' which denotes the conjugate
transpose operation."

MathWorld
~~~~~~~~~

former says:
"The word adjoint has a number of related meanings. In linear algebra,
it refers to the conjugate transpose and is most commonly denoted
A^(H). The analogous concept applied to an operator instead of a
matrix, sometimes also known as the Hermitian conjugate"

While the latter says:
matrix, Hermitian adjoint, or Hermitian transpose"

http://mathworld.wolfram.com/ConjugateTranspose.html

Wikipedia
~~~~~~~~~

matrix is a matrix that plays a role similar to the inverse of a
matrix; it can however be defined for any square matrix without the
need to perform any divisions. The adjugate has sometimes been called
a matrix normally refers to its corresponding adjoint operator, which
is its conjugate transpose.'

"Other names for the conjugate transpose of a matrix are Hermitian
conjugate, or transjugate."

http://en.wikipedia.org/wiki/Conjugate_transpose

### Dima Pasechnik

Dec 3, 2010, 1:55:18 AM12/3/10
to sage-devel
Right, "adjoint" should mean "conjugate transpose", and not "classical
But for "conjugate transpose" one can just introduce operator ^*, as
usually
the conjugate transpose of \$A\$ is denoted by \$A^*\$.

Dunno how much Sage code this would break, though...

Dmitrii

### Rob Beezer

Dec 3, 2010, 2:05:08 AM12/3/10
to sage-devel
On Dec 2, 10:55 pm, Dima Pasechnik <dimp...@gmail.com> wrote:
> But for "conjugate transpose" one can just introduce operator ^*, as
> usually
> the conjugate transpose of \$A\$ is denoted by \$A^*\$.

Accepted notation is another can of worms. Conjugate-transpose can be
an exponent that is a star, dagger or the letter H. And sometimes a *
just means complex conjugation.

Lets not go there. ;-)

Rob

### John Cremona

Dec 3, 2010, 4:14:35 AM12/3/10
Wow, that question got people interested!

Checking a few books myself I was struck by how many advanced texts
avoid using the term at all (for the adjugate or classical adjoint).

P M Cohn's Algebra 1 defines adjugate (p.196).

Maclana and Birkhoff (p.194) call it the "classical adjoint".

Aposotol's Calculus (which is very good on linear algebra!) has a
footnote "In much of the matrix literature the transpose of the
cofactor matrix is called the adjugate of A. Some of the older
literature calls it the adjoint of A. However, current nomenclature
reserves the name adjoint for an entirely different object..."

John

### Jason Grout

Dec 3, 2010, 11:38:59 PM12/3/10

In numpy, the conjugate transpose is A.H, the transpose is A.T, and the
inverse is A.I. I'd love if we adopted those shortcuts (as properties
that return new matrices, not functions).

Jason

### Clement Pernet

Dec 8, 2010, 9:16:24 AM12/8/10
Interesting discussion, I never realized that we are using two interpretations for this same word
depending on the context!

My 2 cents:
In my favorite linear algebra book:
F. R. Gantmacher, The theory of matrices. (1959)

The adjoint of a matrix is defined 2 times with the two meanings!!! (at least in the french
translation of the book, originally in Russian).

Clément

Jason Grout a écrit :

### mhampton

Dec 8, 2010, 2:36:41 PM12/8/10
to sage-devel
+1. I think it usually makes sense to stick with numpy conventions
(which are in turn mostly designed to follow matlab).

-Marshall

### Dima Pasechnik

Dec 8, 2010, 11:47:09 PM12/8/10
to sage-devel

On Dec 9, 3:36 am, mhampton <hampto...@gmail.com> wrote:
> +1.  I think it usually makes sense to stick with numpy conventions
> (which are in turn mostly designed to follow matlab).

Matlab... Oy gevalt. Will you suggest renaming binomial() as
nchoosek() ? :-)

Dima

### Jason Grout

Dec 9, 2010, 2:25:22 AM12/9/10
On 12/8/10 10:47 PM, Dima Pasechnik wrote:
>
>
> On Dec 9, 3:36 am, mhampton<hampto...@gmail.com> wrote:
>> +1. I think it usually makes sense to stick with numpy conventions
>> (which are in turn mostly designed to follow matlab).
>
> Matlab... Oy gevalt. Will you suggest renaming binomial() as
> nchoosek() ? :-)

I could see eventually having a matlab compatibility module so that
someone could do:

from matlab_commands import *

and then be able to use nchoosek()

Jason

### Rob Beezer

Dec 9, 2010, 7:03:36 PM12/9/10
to sage-devel
Thanks, everybody, for the illuminating discussion.

Is there any objection to deprecating the current .adjoint() function
(which returns a matrix of cofactors) and renaming it as the
"adjugate"? With all the usual procedures and warnings for the
deprecation. That would begin the process to free up "adjoint" for
something else (ideally the conjugate-transpose).

Jason - wasn't there some spirited discussion a while ago about using
Python properties? I couldn't find it in a search.

Rob

### kcrisman

Dec 9, 2010, 8:32:13 PM12/9/10
to sage-devel

On Dec 9, 7:03 pm, Rob Beezer <goo...@beezer.cotse.net> wrote:
> Thanks, everybody, for the illuminating discussion.
>
> Is there any objection to deprecating the current .adjoint() function
> (which returns a matrix of cofactors) and renaming it as the
> "adjugate"?  With all the usual procedures and warnings for the
> deprecation.  That would begin the process to free up "adjoint" for
> something else (ideally the conjugate-transpose).

We definitely should have adjoint be conjugate transpose as soon as
possible. In this case, I would even argue that the current behavior
is close enough to "wrong" that it would be acceptable to discuss a
shorter deprecation period, though in reality Sage 5.0 isn't coming
soon, so that will still be plenty of time...

> Jason - wasn't there some spirited discussion a while ago about using
> Python properties?  I couldn't find it in a search.

students to remember the parentheses; having to remember when to use
it or not, yikes...

### Jason Grout

Dec 9, 2010, 11:26:41 PM12/9/10
On 12/9/10 6:03 PM, Rob Beezer wrote:
> Thanks, everybody, for the illuminating discussion.
>
> Is there any objection to deprecating the current .adjoint() function
> (which returns a matrix of cofactors) and renaming it as the
> "adjugate"? With all the usual procedures and warnings for the
> deprecation. That would begin the process to free up "adjoint" for
> something else (ideally the conjugate-transpose).
>

+1

> Jason - wasn't there some spirited discussion a while ago about using
> Python properties? I couldn't find it in a search.

Well, I don't know how "spirited" it was, but I'm still in favor of
using properties occasionally. I believe you can get Sphinx to
recognize documentation for properties, which would take care of one of
the objections.

Jason

### Jason Grout

Dec 9, 2010, 11:31:45 PM12/9/10
On 12/9/10 7:32 PM, kcrisman wrote:

>> Jason - wasn't there some spirited discussion a while ago about using
>> Python properties? I couldn't find it in a search.
>
> Oh, please don't bring that back. It's already enough work getting
> students to remember the parentheses; having to remember when to use
> it or not, yikes...

Here's why I'd really like properties for at least the transpose:

3*(A.T()*B.T())*(2*(A.T()-I))

compared to

3*(A.T*B.T)*(2*(A.T-I))

I think the second one is much easier to read because you don't have to
parse which parentheses are for grouping and which parentheses are for
function calls.

Jason

### John Cremona

Dec 10, 2010, 4:03:47 AM12/10/10
On Fri, Dec 10, 2010 at 12:03 AM, Rob Beezer <goo...@beezer.cotse.net> wrote:
> Thanks, everybody, for the illuminating discussion.
>
> Is there any objection to deprecating the current .adjoint() function
> (which returns a matrix of cofactors) and renaming it as the
> "adjugate"?  With all the usual procedures and warnings for the
> deprecation.  That would begin the process to free up "adjoint" for
> something else (ideally the conjugate-transpose).

+1

>
> Jason - wasn't there some spirited discussion a while ago about using
> Python properties?  I couldn't find it in a search.
>
> Rob
>

### daveloeffler

Dec 10, 2010, 5:45:26 AM12/10/10
to sage-devel

On Dec 10, 9:03 am, John Cremona <john.crem...@gmail.com> wrote:
> On Fri, Dec 10, 2010 at 12:03 AM, Rob Beezer <goo...@beezer.cotse.net> wrote:
> > Thanks, everybody, for the illuminating discussion.
>
> > Is there any objection to deprecating the current .adjoint() function
> > (which returns a matrix of cofactors) and renaming it as the
> > "adjugate"?  With all the usual procedures and warnings for the
> > deprecation.  That would begin the process to free up "adjoint" for
> > something else (ideally the conjugate-transpose).
>
> +1

+1 from me as well.

### William Stein

Dec 10, 2010, 1:09:50 PM12/10/10

+1

In addition to whatever gets done, it would be a good idea to add a
method called "conjugate_transpose()".

sage: A = random_matrix(CDF,2); A
[ 0.612527807778 + 0.44135771466*I 0.654609238114 + 0.769997550005*I]
[0.877761009274 - 0.771264650112*I 0.874089814928 + 0.123225733001*I]
sage: A.conjugate_transpose()
[ 0.612527807778 - 0.44135771466*I 0.877761009274 + 0.771264650112*I]
[0.654609238114 - 0.769997550005*I 0.874089814928 - 0.123225733001*I]

It's totally crystal clear what it means. Adjoint is a little weird,
because to me it means "adjoint with respect to an inner product".
Since vector spaces in Sage can have arbitrary inner products, one
could at least imagine having

sage: A.adjoint() # default inner product

sage: phi.adjoint() # where phi is linear transformation of vector spaces

sage: A.adjoint(inner_product) # where inner_product is an
as-yet-to-be-defined object

---

> 3*(A.T*B.T)*(2*(A.T-I))

I can't see the harm in adding properties in a very, very small number
of special cases. Just please don't go crazy and have dozens of
them, since they are hard to document and can be confusing to read.

> In numpy, the conjugate transpose is A.H, the transpose is A.T, and the
> inverse is A.I. I'd love if we adopted those shortcuts (as properties

A.H seems arbitrary? Why "H"? Consistency with numpy is a good
argument for supporting this though.

-- William

William Stein
Professor of Mathematics
University of Washington
http://wstein.org

### Jason Grout

Dec 10, 2010, 1:39:18 PM12/10/10
On 12/10/10 12:09 PM, William Stein wrote:
>> In numpy, the conjugate transpose is A.H, the transpose is A.T, and the
>> > inverse is A.I. I'd love if we adopted those shortcuts (as properties
> A.H seems arbitrary? Why "H"? Consistency with numpy is a good
> argument for supporting this though.

It's standard notation in linear algebra (i.e., A^H=conjugate transpose
of A) [1].

Thanks,

Jason

### Rob Beezer

Dec 10, 2010, 1:46:27 PM12/10/10
to sage-devel
On Dec 10, 10:09 am, William Stein <wst...@gmail.com> wrote:
> In addition to whatever gets done, it would be a good idea to add a
> method called "conjugate_transpose()".

+1

I was thinking of this as a seque until adjoint broke free, and based
on this discussion I think having adjoint be more general and high-
powered makes good sense.

Rob

### Rob Beezer

Dec 10, 2010, 7:55:50 PM12/10/10
to sage-devel
Thanks again for the input and excellent background and suggestions.

I've made a small meta-ticket to track progress on this. I'll get
started soon on the first two parts and attach the actual ticket
numbers to the meta-ticket as they get created.

http://trac.sagemath.org/sage_trac/ticket/10465

Feel free to continue the discussion here, or on Trac, as appropriate.

Rob

### Rob Beezer

Dec 10, 2010, 7:58:39 PM12/10/10
to sage-devel
On Dec 10, 10:09 am, William Stein <wst...@gmail.com> wrote:
> A.H seems arbitrary?  Why "H"?

I saw this regularly when reading up on the confusion. When A^H==A
the matrix is Hermitian, so I would *speculate* that this is the
origin of the choice.

Rob

### Felix Lawrence

Dec 12, 2010, 11:55:58 PM12/12/10
to sage-devel
On Dec 10, 10:09 am, William Stein <wst...@gmail.com> wrote:

> > A.H seems arbitrary?  Why "H"?

I learnt linear algebra with A^H notation, with H denoting the
Hermitian transpose. Wikipedia lists the various names for the
conjugate transpose as "conjugate transpose, Hermitian transpose,

FWIW, my initial decision to use numpy matrices rather than Sage
matrices in my numerical code was partially based on numpy having such
a clean notation for .I, .T and .H.

Felix

### Gonzalo Tornaria

Dec 20, 2010, 8:33:18 PM12/20/10
On Thu, Dec 9, 2010 at 10:03 PM, Rob Beezer <goo...@beezer.cotse.net> wrote:
> Is there any objection to deprecating the current .adjoint() function
> (which returns a matrix of cofactors) and renaming it as the
> "adjugate"?  With all the usual procedures and warnings for the
> deprecation.  That would begin the process to free up "adjoint" for
> something else (ideally the conjugate-transpose).

I've been unable to reply on this before, and today after receiving a
comment on ticket #10501 I commented right there, which was possibly a
bit unpolite given the lapse of time and that I didn't post that
commentto this thread (if so I apologize).

Anyway, here's a copy of my post, in case it's helpful:

I already stated some objections, but I'll repeat:

On deprecating "adjoint" meaning "matrix of cofactors"
1. it's standard terminology and has meant this in sage for long
particular it has no obvious translations

On using "adjoint" meaning "conjugate transpose"
3. "conjugate transpose" is easy to say, and it's really what is meant
4. the "adjoint operator" for a matrix seems ill-defined, because a
matrix is not an operator but only a representation of an operator in
some basis.

Moreover, if there are two colliding usages of the name "adjoint", I
would find it more reasonable to keep the usage that is already

afaict (and, as John Cremona pointed out, is where the term originates
with Gauss on ternary quadratic forms).

I also pointed out a reference to Bourbaki which I already posted
above. I still haven't found a reference for "adjugate" which
satisfies me (I mean, where does it originate?) or a good reference
for how to use "adjoint of a matrix" as meaning "conjugate transpose"
in reference to adjoint operators without eventually causing some pain
when using it in the real world where not all bases are orthogonal
(not even all vector spaces have inner product).

OTOH, I do certainly appreciate that transpose and conjugate transpose
is used quite a lot, and thus I think it really deserves all the
shortcuts proposed (T, H, star, etc).

Gonzalo

### Rob Beezer

Dec 21, 2010, 12:17:17 AM12/21/10
to sage-devel
So, maybe some background I should have included somewhere along the
way. I'm adding significant amounts of Sage code to my open source
linear algebra textbook and am working hard to make the linear algebra
code more welcoming to beginners (and thanks to those who have been
helping).

The confusion (obvious above) is one thing I wanted to tackle. The
patch at

http://trac.sagemath.org/sage_trac/ticket/10501

the crypto code (inverting an integer matrix) and two or three changes
to code within quadratic forms routines. But it does introduce new
which is implemented with PARI's matadjoint method.

I have no good source for the term adjugate (but don't have my books
handy lately) and don't like the word much myself. Having taught a
"matrix analysis" course twice now, it seems that adjoint is what gets
used regularly for the conjugate-transpose, so that is my motivation.
I'll admit the distinction between matrices and operators is less
interesting to me.

I didn't think properties were going to fly, but they are close to
ready at #8094. I could probably live with a conjugate_transpose
method (#10471) and the new H property as a less cumbersome version.
Then I would document Sage's use of the adjoint carefully in the
textbook (and maybe in some docstrings) rather than waiting for it to
come out of a deprecation waiting period. My one reservation is that
beginners get very confused about why, for example, A.tranpose() is
correct, yet A.transpose is not. Having A.H work seems to just add to
that misunderstanding. (I'm not against properties, I just would not
use them with beginners.)

Strong opinions welcome, otherwise Gonzalo and I will come to some
agreement and move on.

Rob

### John Cremona

Dec 21, 2010, 6:28:17 AM12/21/10
Etymology does not help much. To say that two things are "adjugate"
means that they are "yoked or joined together" from the Latin word for
a yoke (such as you would use if your ox cart was being pulled by two
oxen and they needed to pull together). And to say that they are
"adjoint" means the same thing, from the word to join.

It is a good point that the word adjoint is properly associated to a
linear operator rather than a matrix. On C^n with standard Hermitian
inner product and the standard basis to represent operators, this
leads to the conjugate transpose. But if you use a random basis (not
an orthonormal one) then even in this situation the adjoint operator
is not represented by the conjugate transpose matrix).

[This caught me out eons ago when I was computing Hecke operators on
spaces of modular forms. [Actually I still am...] I knew they were
self-adjoint (for the experts out there, these were Hecke operators
for Gamma_0(N)) but the matrices were real but not symmetric, even
though their eigenvalues were all real, as they do not, of course,
depend on the basis used.]

The wonderful website "Earliest Known Uses of Some of the Words of
Mathematics" (see http://jeff560.tripod.com/a.html for the A page)
does not mention adjugate unfortunately, but does have this entry:

ADJOINT MATRIX. The OED quotes from M. Bôcher's Introduction to Higher
Algebra of 1907: "By the adjoint A of a matrix a is understood another
matrix of the same order in which the element in the ith row and jth
column is the cofactor of the element in the jth row and ith column of
a." (p. 77)

That site also has an entry for "adjoint linear form", Cayley 1856,
which I just spent some time looking up, but it does not seem relevant
(despite coming just before the definitions of resultant and
discriminant). If you like long words which never quite caught on,
Cayley is the mathematician for you. (I am looking forward to the
next time I have a polynomial of degree 12 since I now know to call it

John

### kcrisman

Dec 21, 2010, 8:54:58 AM12/21/10
to sage-devel

> The wonderful website "Earliest Known Uses of Some of the Words of
> Mathematics"  (seehttp://jeff560.tripod.com/a.htmlfor the A page)
> does not mention adjugate unfortunately, but does have this entry:
>

Resolving this could be good Math Overflow bait.

Rob is right, at the very least there should be as easy a way as
possible to get the conjugate transpose. If they are nicely
documented, with lots of examples, properties could work for this, but
a method() should also be available, as is pointed out.

- kcrisman

### Dima Pasechnik

Dec 22, 2010, 1:34:48 AM12/22/10
Adjugate features in Muir's "A treatise on the theory of determinants", 1933.

### Rob Beezer

Dec 30, 2010, 1:09:23 AM12/30/10
to sage-devel
Whatever we use here for matrices, I'd like to do the same thing for
vectors over CDF (see related post from a few minutes ago).
"conjugate_transpose" is a bit odd for vectors, since Sage carries no
notion of vectors being rows or columns. And it wouldn't make sense
to me to use .adjoint() on a vector if we didn't use it on matrices.

Proposal: How do folks feel about using .star() for matrices and
vectors as a shorthand/alias for .conjugate_transpose()
and .conjugate() (respectively)?

Pros:

1) A star is a very common notation for this. It is not universal,
but I think the variants (H, a dagger) are more common in other fields
(like physics).

2) Short.

3) No ambiguity about its past.

4) It does not appear to be used elsewhere as a method or function
name (and only a few places as a keyword).

Cons:

1) Highly non-obvious.

2) Others?

Rob

### Jason Grout

Dec 30, 2010, 1:31:14 AM12/30/10
On 12/29/10 11:09 PM, Rob Beezer wrote:
> Whatever we use here for matrices, I'd like to do the same thing for
> vectors over CDF (see related post from a few minutes ago).
> "conjugate_transpose" is a bit odd for vectors, since Sage carries no
> notion of vectors being rows or columns. And it wouldn't make sense
> to me to use .adjoint() on a vector if we didn't use it on matrices.

Notice that there is an underlying ideology that vectors are rows:

sage: u=vector([1,2,3])
sage: matrix(u)
[1 2 3]
sage: u.transpose()
[1]
[2]
[3]

So if a vector had a conjugate method, the conjugate transpose would
make sense and would be a matrix.

> Proposal: How do folks feel about using .star() for matrices and
> vectors as a shorthand/alias for .conjugate_transpose()
> and .conjugate() (respectively)?
>
> Pros:
>
> 1) A star is a very common notation for this. It is not universal,
> but I think the variants (H, a dagger) are more common in other fields
> (like physics).
>
> 2) Short.
>
> 3) No ambiguity about its past.
>
> 4) It does not appear to be used elsewhere as a method or function
> name (and only a few places as a keyword).
>
> Cons:
>
> 1) Highly non-obvious.
>
> 2) Others?

I'm not sure how I feel about .star() yet. I do think the .H property
should be implemented, which would be consistent with numpy.

Jason

### Rob Beezer

Dec 30, 2010, 3:22:22 AM12/30/10
to sage-devel
On Dec 29, 10:31 pm, Jason Grout <jason-s...@creativetrax.com> wrote:
> Notice that there is an underlying ideology that vectors are rows:

Yes, I have noticed that. Ties go to rows:

sage: matrix( [vector(QQ, [1,2,3]), vector(QQ,[4,5,6])] )
[1 2 3]
[4 5 6]

But the above is the first example where I have been tempted to
suggest some optional keyword to cause columns to win the tie. In
other words, I am writing instructions for beginning students on how
to use Sage for linear algebra and I've been surprised at how little
trouble I have had maintaining a column-oriented development alongside
Sage's row-oriented preferences. Excepting the above - I want to
build matrices out of sets of vectors where the vectors become columns
(as optional behavior).

> sage: u=vector([1,2,3])
> sage: matrix(u)
> [1 2 3]
> sage: u.transpose()
> [1]
> [2]
> [3]

If I were BDFL I'd ban the above. ;-) It converts vectors to
matrices without warning. Implicitly says vectors are row vectors,
while for a 3x3 matrix A, the expressions u*A and A*u both compute
just fine and so there is no such preference here. Can't have your
cake and eat it too. If I were to "conjugate-transpose" a vector, I'd
want it to remain a vector, not get upgraded to an n x 1 matrix. Or
go entirely to a strict dichotomy between row vectors and column
vectors. I'd default to implementing the proposed .star() as
returning a vector.

> I'm not sure how I feel about .star() yet.  I do think the .H property
> should be implemented, which would be consistent with numpy.

+10 to having .H

-5 to having to explain to students why you don't write it as .H()

Not as belligerent as I sound,
Rob ;-)

### Dan Drake

Dec 30, 2010, 4:01:11 AM12/30/10
On Thu, 30 Dec 2010 at 12:22AM -0800, Rob Beezer wrote:
> Excepting the above - I want to build matrices out of sets of vectors
> where the vectors become columns (as optional behavior).

Big thumbs up to being able to easily make matrices whose columns are
specified vectors.

This past semester, I taught a basic linear algebra course (the first
I've done that's *only* linear algebra, no differential equations, etc).
I didn't use Sage, but if -- uh, I mean, *when* -- I do so in the
future, building matrices using vectors as columns will be key.

There are a number of "basic moves" in linear algebra that you do all
the time when describing algorithms, doing proofs, and so on. The better
Sage supports those basic moves, the easier it will be to experiment
with basic linear algebra stuff.

Dan

--
--- Dan Drake
----- http://mathsci.kaist.ac.kr/~drake
-------

signature.asc

### Jason Grout

Dec 30, 2010, 1:46:40 PM12/30/10
On 12/30/10 1:22 AM, Rob Beezer wrote:
> On Dec 29, 10:31 pm, Jason Grout<jason-s...@creativetrax.com> wrote:
>> Notice that there is an underlying ideology that vectors are rows:
>
> Yes, I have noticed that. Ties go to rows:
>
> sage: matrix( [vector(QQ, [1,2,3]), vector(QQ,[4,5,6])] )
> [1 2 3]
> [4 5 6]
>
> But the above is the first example where I have been tempted to
> suggest some optional keyword to cause columns to win the tie. In
> other words, I am writing instructions for beginning students on how
> to use Sage for linear algebra and I've been surprised at how little
> trouble I have had maintaining a column-oriented development alongside
> Sage's row-oriented preferences. Excepting the above - I want to
> build matrices out of sets of vectors where the vectors become columns
> (as optional behavior).
>

+1. I usually use a transpose after constructing a matrix so that the
vectors in the constructor give the columns.

I was thinking of another matrix constructor that is a very thin wrapper
around matrix(). Something like:

def column_matrix(*args, **kwds):
return matrix(*args, **kwds).transpose()

Jason

### Rob Beezer

Dec 30, 2010, 7:13:21 PM12/30/10
to sage-devel
On Dec 30, 10:46 am, Jason Grout <jason-s...@creativetrax.com> wrote:
> I was thinking of another matrix constructor that is a very thin wrapper
> around matrix().  Something like:
>
> def column_matrix(*args, **kwds):
>      return matrix(*args, **kwds).transpose()

I like it. See http://trac.sagemath.org/sage_trac/ticket/10535

And if you provide just a single dimension, along with a flat list of
entries, the dimension gets interpreted as the number of *columns*.
Bonus.

sage: column_matrix(ZZ, 8, range(24))
[ 0 3 6 9 12 15 18 21]
[ 1 4 7 10 13 16 19 22]
[ 2 5 8 11 14 17 20 23]

Rob

### Rob Beezer

Dec 30, 2010, 7:17:39 PM12/30/10
to sage-devel
On Dec 30, 1:01 am, Dan Drake <dr...@kaist.edu> wrote:
> There are a number of "basic moves" in linear algebra that you do all
> the time when describing algorithms, doing proofs, and so on. The better
> Sage supports those basic moves, the easier it will be to experiment
> with basic linear algebra stuff.

That's a nice way to put it. I'm trying to make available as many of
the natural "basic moves" as possible. Mostly I've been concentrating
on vectors (as vectors, not as matrices with a single row or column),
but I'm about to move on into matrices. So, send me your wish list of
missing basic moves. Anybody.

Rob

### Jason Grout

Dec 30, 2010, 11:02:03 PM12/30/10
On 12/30/10 5:13 PM, Rob Beezer wrote:
> On Dec 30, 10:46 am, Jason Grout<jason-s...@creativetrax.com> wrote:
>> I was thinking of another matrix constructor that is a very thin wrapper
>> around matrix(). Something like:
>>
>> def column_matrix(*args, **kwds):
>> return matrix(*args, **kwds).transpose()
>
> I like it. See http://trac.sagemath.org/sage_trac/ticket/10535

Nice. Here's another. If v is a vector, it would be nice to have:

v.row() -- return a 1-row matrix, same as matrix(v) (i.e., a row vector)

v.column() -- return a 1-column matrix, same as v.transpose() (i.e., a
column vector)

That would take care of your ideological problem with v.transpose(), I
think.

Thanks,

Jason

### Rob Beezer

Dec 31, 2010, 8:16:35 PM12/31/10
to sage-devel
On Dec 30, 8:02 pm, Jason Grout <jason-s...@creativetrax.com> wrote:
> Nice.  Here's another.  If v is a vector, it would be nice to have:
>
> v.row() -- return a 1-row matrix, same as matrix(v) (i.e., a row vector)
>
> v.column() -- return a 1-column matrix, same as v.transpose() (i.e., a
> column vector)

I like this, too.

> That would take care of your ideological problem with v.transpose(), I
> think.

Yes, I'll sleep better tonight. ;-)

Rob

### Rob Beezer

Jan 18, 2011, 4:04:27 PM1/18/11
to sage-devel
I am working nearly full-time on a big project to add detailed
explanations to my introductory linear algebra textbook about how to
use Sage to study linear algebra. At every turn, this work suggests
additions or modifications to the Sage library. At a minimum, I think
the final product will be a very good demonstration of how useful and
comprehensive Sage can be in teaching undergraduate mathematics
courses. You can view the suggested patches, and a work-in-progress
version of the textbook at:
http://wiki.sagemath.org/devel/LatexToWorksheet

There are several goals to these modifications of the Sage code:

(a) Simply conversions between vectors and matrices. For example, a
patch allows for augmenting a matrix with a vector, rather than the
previous behavior which required three steps: converting the vector to
a 1-row matrix, then transposing it to a 1-column matrix, and then
augmenting with the column matrix. (Dan Drake's "basic moves.")

(b) Allied with (a), make it as easy to take a column-oriented view of
linear algebra as a row-oriented view. This has been much easier than
I suspected it would be, while still allowing for Sage's preference
for rows to dominate.

naturally occur over the complex numbers. Adding a "Hermitian inner
product" (name suggested by Dima P.) should not be controversial, I
hope. From there, Sage needs a convenient way to take a conjugate
transpose of a matrix or a vector (yes, the transpose is irrelevant
for a Sage vector), then checks for Hermitian and unitary matrices,
etc.

(d) Fix various bugs and improve documentation.

Despite trying to start early, I am now at a junction where I am
postponing major decisions relative to (c). I could be beating a dead
horse, but here's the situation relative to the conjugate-transpose.
A common construction is (v^*)(A^*)Av, where v is a column vector,
A is a matrix, and the * represents the conjugate-transpose.
Alternatives for expressing this in Sage:

v = vector(....)
A = matrix(....)

(1) v.conjugate()*A.conjugate_tranpose()*A*v
Basically status quo. v.conjugate() does not exist yet, but would be

(2) v.H*A.H*A*v
New "H" property at Trac #8094 for matrices, would need to add it for
vectors. I feel the lack of parentheses will be confusing to
beginners.

Requires a change in the meaning of "adjoint" as discussed in this
thread. One objection lodged on Trac #10501.

(4) v.star()*A.star()*A*v
A new suggestion made above. Yes, using a word for a symbol is
probably a bad precedent. But it is compact and mirrors a common
notational use without deprecating anything.

on this.

Thanks,
Rob

### kcrisman

Jan 18, 2011, 4:17:47 PM1/18/11
to sage-devel

> (1) v.conjugate()*A.conjugate_tranpose()*A*v
> Basically status quo.  v.conjugate() does not exist yet, but would be

Might as well do this.

> (2) v.H*A.H*A*v
> New "H" property at Trac #8094 for matrices, would need to add it for
> vectors.  I feel the lack of parentheses will be confusing to
> beginners.

Again, useful to add, but I agree on the beginners.

> Requires a change in the meaning of "adjoint" as discussed in this
> thread.  One objection lodged on Trac #10501.

Right.

> (4) v.star()*A.star()*A*v
> A new suggestion made above.  Yes, using a word for a symbol is
> probably a bad precedent.  But it is compact and mirrors a common
> notational use without deprecating anything.

Anyway, I think the key is to try something. If #3 causes problems,
one advantage of having a book with attached worksheets using #1 (say)
is that there is much less to remember for the new person! So no one
would even know there had been this controversy. You can even put in
still using conjugate_transpose or something. Esp. with an open-
source book, updating in another edition won't be a big problem if
this resolves itself later :)

- kcrisman

### Dima Pasechnik

Jan 18, 2011, 8:12:26 PM1/18/11
to sage-devel
Transpose of a vector is a duality between the underlying vectorspace
and its dual.
IMHO for teaching purposes it's important to see the distinction
between row and column vectors.
(Ideally, I think, one would have a "student mode" of Sage, where if
A*v is valid for a square matrix A and a vector v, then v*A is not.)

### Jason Grout

Jan 18, 2011, 8:34:21 PM1/18/11

With a patch going in soon or already in, you can "specify" an
orientation for a vector by using .row() or .column() (really this just
returns a single column or single row matrix).

A*v.column() would work, but v.column()*A would not work. Likewise,
v.row()*A would work, but A*v.row() would not work.

It's not exactly what you want because vectors aren't exactly just
single-row matrices or single-column matrices in Sage (i.e., they can
have different methods, etc.). I can imagine in the future having a
flag in the vector class which specifies an orientation, defaulting to
None (for the current behavior). Then v.row() could return a new vector
exactly like v, except with the flag set to "row", for example.

Right now, v.transpose() does what kind of what you want. v.transpose()
returns a single-column matrix, so indeed v.transpose()*A does not work,
but A*v.transpose() does.

Jason

### Rob Beezer

Jan 19, 2011, 11:38:28 AM1/19/11
to sage-devel
On Jan 18, 5:12 pm, Dima Pasechnik <dimp...@gmail.com> wrote:
> Transpose of a vector is a duality between the underlying vectorspace
> and its dual.
> IMHO for teaching purposes it's important to see the distinction
> between row and column vectors.
> (Ideally, I think, one would have a "student mode" of Sage, where if
> A*v is valid for a square matrix A and a vector v, then v*A is not.)

Hi Dima,

Two years ago, tangential to another discussion, I suggested something
very similar to what Jason described - tagging vectors as rows or
columns, or None. It didn't get a great response.

I have now come around to the opinion that vectors are just vectors,
ie ordered lists of scalars (or coordinates relative to an ordered
basis, if you want a more general view). You do not need to consider
a vector as a column vector to define a matrix-vector product A*v, you
just use the entries of v to form a linear combination of the columns
of A, which can again be just a vector (not necessarily a column
vector). And so on. The new vector methods .row() and .column() make
the conversion of a vector to a matrix explicit, so for example you
could do something like an outer product as v.column()*w.row(). You
only need to decide on an orientation once you try to print the thing.

A professor of mine in graduate school, JJ Uhl, would love to claim
that you never needed to write a transpose, since he felt you could
always deduce it from the context. I'm sure there are
counterexamples, but he had a point.

A "student mode" is tempting and has been discussed in other contexts
(calculus?). I think a strength of Sage is that a student can start
with it as an undergraduate and continue to use it the remainder of
their professional careers. So for my money, I'd rather make
available the functions and methods that alleviate any confusion a
beginner might face, so that as their needs and confidence grow they
can slide into more subtle uses, rather than having to transistion
from one mode to another.

Rob

### kcrisman

Jan 19, 2011, 1:21:02 PM1/19/11
to sage-devel

> A "student mode" is tempting and has been discussed in other contexts
> (calculus?).  I think a strength of Sage is that a student can start
> with it as an undergraduate and continue to use it the remainder of
> their professional careers.  So for my money, I'd rather make
> available the functions and methods that alleviate any confusion a
> beginner might face, so that as their needs and confidence grow they
> can slide into more subtle uses, rather than having to transistion
> from one mode to another.

+1

I used to be an advocate of a 'student mode' of sorts, at least
privately (it may have been before I was as involved with Sage), but
think Rob makes well the case for not having this.

That's not the same as not providing individual contexts - for
instance, it might be nice to have some way to declare a variable is
always real at the top of a page, and then have plot(x^(1/3)) do what
one naively thinks it would do if one hadn't seen a CAS before... and
we definitely need to advertise the 'magic' turning of methods into
functions more, if only to track down bugs in it.

- kcrisman

### Stephan Ehlen

Feb 8, 2013, 6:09:32 AM2/8/13
Hey, this discussion is amazing...

I'm currently teaching linear algebra and I introduced sage to the students.
I was confused by the fact that .adjoint() returns what we called "complementary matrix" or "adjugate"
in class and I was close to submitting a bug report or at least start a discussion here.
But then (as an educated user of google groups etc ;-)) I did a search first and found this topic.

I will first try to ask my question here before starting a new topic with a reference to this one.
(Since the topic is very old, I'm not sure if someone will answer...)

I kind of scanned through it and learned something.
But it is not clear to me why in the end the .adjoint() was left to mean the matrix of cofactors,
even though this can be confusing. Was it the backwards compatibility?
The meta-ticket http://trac.sagemath.org/sage_trac/ticket/10465 does not show any progress on that issue
(except that conjugate_transpose() was introduced).

I would have preferred to deprecate .adjoint() (and maybe implement the more advanced one that was suggested)
but maybe you had good reasons not to do so. Or did just nobody do the work after the long discussion?

Stephan

On Thursday, 2 December 2010 05:47:50 UTC+1, Rob Beezer wrote:
What does the "adjoint of a matrix" mean to you?

I was brought up to understand it to mean the transpose of the matrix
of signed minors, a matrix close to being the inverse of the
original.  Poking around (Wikipedia, Planet Math, Math World) would
imply this is known as the "classical adjoint."  Hmmm, I'm not that
old.  Anyway, it is also known now as the "adjugate matrix."

It seems that the term "adjoint" is now more commonly used for the
conjugate-transpose of a matrix (and for vectors) and that's what I
find in most any relatively new textbook on matrix algebra.

Presently, in Sage, "adjoint" gives the "classical" interpretation.  I
would much prefer to define and implement the adjoint of a matrix to
be the conjugate transpose.  So two questions:

1.  Thoughts on what "adjoint" should be?

2.  If adjoint were to be redefined to a more modern interpretation,
its current use could be aliased to "adjugate" and deprecated, but
that won't make it available for reuse until the deprecation period
runs its course.  Any precedent, or techniques, for radically
redefining a method name?

Rob

### kcrisman

Feb 8, 2013, 9:51:02 AM2/8/13

On Friday, February 8, 2013 6:09:32 AM UTC-5, Stephan Ehlen wrote:
Hey, this discussion is amazing...

I'm currently teaching linear algebra and I introduced sage to the students.
I was confused by the fact that .adjoint() returns what we called "complementary matrix" or "adjugate"
in class and I was close to submitting a bug report or at least start a discussion here.
But then (as an educated user of google groups etc ;-)) I did a search first and found this topic.

I will first try to ask my question here before starting a new topic with a reference to this one.
(Since the topic is very old, I'm not sure if someone will answer...)

I kind of scanned through it and learned something.
But it is not clear to me why in the end the .adjoint() was left to mean the matrix of cofactors,
even though this can be confusing. Was it the backwards compatibility?
The meta-ticket http://trac.sagemath.org/sage_trac/ticket/10465 does not show any progress on that issue
(except that conjugate_transpose() was introduced).

I would have preferred to deprecate .adjoint() (and maybe implement the more advanced one that was suggested)
but maybe you had good reasons not to do so. Or did just nobody do the work after the long discussion?

Probably a bit of that and a bit of still lacking consensus.  If you do some work on #10501 - see http://trac.sagemath.org/sage_trac/ticket/10501#comment:7 - I'm sure we'll be eager to finally resolve this :-)

- kcrisman

### Jason Grout

Feb 8, 2013, 9:55:41 AM2/8/13
On 2/8/13 5:09 AM, Stephan Ehlen wrote:
> Hey, this discussion is amazing...
>
> I'm currently teaching linear algebra and I introduced sage to the students.
> I was confused by the fact that .adjoint() returns what we called
> in class and I was close to submitting a bug report or at least start a
> discussion here.
> But then (as an educated user of google groups etc ;-)) I did a search
> first and found this topic.
>
> I will first try to ask my question here before starting a new topic
> with a reference to this one.
> (Since the topic is very old, I'm not sure if someone will answer...)
>
> I kind of scanned through it and learned something.
> But it is not clear to me why in the end the .adjoint() was left to mean
> the matrix of cofactors,
> even though this can be confusing. Was it the backwards compatibility?
> The meta-ticket http://trac.sagemath.org/sage_trac/ticket/10465 does not
> show any progress on that issue
> (except that conjugate_transpose() was introduced).
>
> I would have preferred to deprecate .adjoint() (and maybe implement the
> more advanced one that was suggested)
> but maybe you had good reasons not to do so. Or did just nobody do the
> work after the long discussion?

My guess is that it was as Karl-Dieter says. I certainly wouldn't be
opposed to introducing .adjugate(), and I would probably be +0 on
deprecating .adjoint() (meaning indifferent, leaning towards deprecation).

For the conjugate transpose, you could use the more explicit
A.conjugate_transpose() method, or you could use the "hermitian
transpose" shortcut: A.H

Thanks,

Jason