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
error to call the adjugate the adjoint.
I would not be surprised if there plenty of elementary linear algebra
texts out there who describe adj(A) as the adjoint of A.
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
>
Do you have a reference for this convention? I had never seen the word
"adjugate" before.
--
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
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
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
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
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 :
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
+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 - 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
+1
>
> Jason - wasn't there some spirited discussion a while ago about using
> Python properties? I couldn't find it in a search.
>
> Rob
>
+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
It's standard notation in linear algebra (i.e., A^H=conjugate transpose
of A) [1].
Thanks,
Jason
[1] See http://mathworld.wolfram.com/ConjugateTranspose.html
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
2. "adjugate" is newer and (IMO) less standard terminology -- in
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
traditional in Sage.
The usage of "adjoint" is ubiquitous in relation to quadratic forms
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
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
a dodecadic!)
John
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
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
-------
+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
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
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
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
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?