jsoftware / jsource

J engine source mirror
Other
650 stars 90 forks source link

cross-product/quaternion-product primitive #96

Open HenryHRich opened 2 years ago

rdm commented 1 year ago

I see a variety of possible representations here, so I'll try to provide some concrete examples.

There's no two character * glyphs which remain open for this. But perhaps we could use X: here.


There's several ways of representing quaternions. Consider

   0 2 3 5 X: 0 7 11 13
_112 _16 9 1

Here we would distinguish quaternion product from cross product using the length of the arguments

   2 3 5 X: 7 11 13
_16 9 1

However, we could instead use a hybrid Cayley-Dickson construction for quaternions (which would not change the cross product representation), perhaps:

   0j2 3j5 X: 0j7 11j13
_112j_16 9j1

Also, though, assuming the first representation we probably want

   1 2 3 4 X: 1
1 2 3 4

Because we probably want relatively easy access to quaternion inverse. For example:

    1 2 3 4 X:inv 1
0.0333333 _0.0666667 _0.1 _0.133333

I think we would want a left inverse here, because that's how *inv works.

I don't think there's an equivalent concept for cross product, so that probably gets a nonce or domain error...

This should be equivalent, so that this operation works cleanly with higher ranked arrays:

   1 2 3 4 X: ,1
1 2 3 4

It might also make sense for this hypothetical X: verb to support complex multiplication with 2-wide arguments. This would give us another way of representing gaussian integers and would give us a way of representing extended/rational complex numbers.

moon-chilled commented 1 year ago

I like the idea of a cross-product primitive. Your proposal feels a bit inconsistent to me, though. For '1 2 3 4 X: ,1' to work the way you suggest, it seems like X: has rank 1, and implicitly pads all arguments of length <4 with zeroes; putting (say) the real part first, and the padding to the right. But if '2 3 5 X: 7 11 13' is cross-product, then it would seem the padding goes to the left (or else the real part goes to the right). Either way, these can not be unified, and so there is simply a special case made for 1-cells of lengths 3 and 1, which I do not like so much.

It might also make sense for this hypothetical X: verb to support complex multiplication with 2-wide arguments. This would give us another way of representing gaussian integers and would give us a way of representing extended/rational complex numbers

That is consistent with putting the real part to the left, and padding to the right, which makes your quaternion inverse work, but requires manual padding for cross-product.


One alternative is a quaternion data type, a la nars2000.

By the by, I propose to use X. rather than X:; it is a bit less noisy and easier to type, and I would like to use X: for big floats.

rdm commented 1 year ago

I was thinking that the arguments would be made to conform using x ,:&, y (or something analogous, at rank 1).

rdm commented 1 year ago

Oh, also... I had talked with Henry about the possibility of adding a quaternion type to J.

In his opinion, the cost (in terms of overhead in the context of J's multiple-dispatch type system) was higher than the value provided by quaternions.

moon-chilled commented 1 year ago

Where is the performance cost? If the case of a quaternion is handled only in branches which currently throw an error, then performance should be exactly the same if you don't use quaternions.

(I do think the advantages of quaternions are fairly marginal.)

rdm commented 1 year ago

I had originally wrote "performance cost" and then changed that to simply "cost". I think he was largely concerned with the implementation cost.

One issue here is the argument type conversion table at https://www.jsoftware.com/help/dictionary/dictg.htm -- if we put quaternions in the logical position there (outside right and bottom) that gets complicated, especially if we're going to add extended floats in roughly the same place (presumably also with extended complex).

Another issue was the number of routines needed for type dispatching (I think here he was assuming a treatment similar to float rather than similar to rational, though we didn't take the conversation far enough to discuss that issue).

A key issue though was lack of mathematical motivation. Complex type is needed to support exponentials of arbitrary real numbers. Quaternions have no such motivation. This drops the conceptual value of quaternions as a supported type.

Anyways, ... perhaps we should consider this question: if quaternion multiplication gives us the almost all of the utility of quaternion support, why should we pay the implementation cost of type support for quaternions?