Java 四元数比较?

Java 四元数比较?,java,math,comparison,comparable,quaternions,Java,Math,Comparison,Comparable,Quaternions,四元数比较可能吗?我正在编写一个四元数的Java类,我想实现使用Collections.sort(List)工具的接口。我不是数学专家,我真的不懂我读到的关于四元数的东西。那么,有人能告诉我我可以覆盖四元数的比较方法吗 我的班级去极化: public class Quaternion implements Serializable, Comparable<Quaternion> { private double s; // scalar part private d

四元数比较可能吗?我正在编写一个四元数的Java类,我想实现使用
Collections.sort(List)
工具的接口。我不是数学专家,我真的不懂我读到的关于四元数的东西。那么,有人能告诉我我可以覆盖四元数的
比较方法吗

我的班级去极化:

public class Quaternion implements Serializable, Comparable<Quaternion> {

    private double s; // scalar part
    private double i, j, k; // vectorel part


    public Quaternion() {
        super();
    }

    public Quaternion(double s, double i, double j, double k) {
        super();
        this.s = s;
        this.i = i;
        this.j = j;
        this.k = k;
    }
公共类四元数实现可序列化、可比较{
私有双s;//标量部分
私有双i,j,k;//向量部分
公共四元数(){
超级();
}
公共四元数(双s,双i,双j,双k){
超级();
这个.s=s;
这个。i=i;
这个。j=j;
这个。k=k;
}

您可以通过比较其字段来实现compareTo。但是,您需要确定您想要的顺序是什么。好吧,对于复数,没有标准的前后顺序定义,更不用说四元数了。

没有理由不能比较两个四元数。假设您想要比较magnitudes,计算并比较。您的四元数类应该有一个范数(幅值)方法,允许比较如下:

int compareTo(Quaternion o){
  return (int)(this.norm() - o.norm());
}
更好的版本是:

int compareTo(Quaternion o){
  // return (int)(this.norm() - o.norm());
  double tNorm = this.norm;
  double oNorm = o.norm;
  int retVal = 0;

  if (tNorm < oNorm){
    retVal = -1;
  } else if (tNorm > oNorm){
    retVal = 1;
  }

  return retVal;
}
int比较(四元数o){
//返回(int)(this.norm()-o.norm());
双tNorm=this.norm;
双oNorm=o.norm;
int-retVal=0;
if(tNormoNorm){
retVal=1;
}
返回返回;
}

将四元数视为四个浮点数的元组(有序列表)。定义相等非常简单,但如何定义总顺序?换句话说,如何定义两个四位数序列之间的大于关系

事实上,即使在复数和四元数之间也没有共同的大于关系。四元数可以被视为一对复数。只有在一维空间中才有可能进行简单的比较。复数是二维的,四元数是四元数。

你当然可以比较它们;无论比较是否有意义因为四元数可以用四个实数来表示,所以你只需要做一些类似(伪代码)的事情


由于这些值是实数,您可以使用基于epsilon的比较,您需要将微小的正负差异转换为正负整数。但您明白了。四元数是一种四维向量。 您想如何订购?最合理的方法是使用标准

public int compareTo(Object o) {
  if (o instanceOf Quaternion) {
    // Compute the difference between the square of the norm
    double result = s*s + i*i + j*j + k*k - o.s*o.s - o.i*o.i - o.j*o.j - o.k*o.k;
    if (result > 0) { return 1; }
    if (result < 0) { return -1; }
    return 0;
  }
}
double norm = Math.sqrt(s*s + i*i + j*j + k*k);
public int compareTo(对象o){
if(四元数的o实例){
//计算范数平方之间的差
双结果=s*s+i*i+j*j+k*k-o.s*o.s-o.i*o.i-o.j*o.j-o.k*o.k;
如果(结果>0){返回1;}
如果(结果<0){return-1;}
返回0;
}
}

请注意,使用范数将使长度相等但指向不同方向的四元数相等,有些算法无法区分它们。排序算法可能会丢弃“重复项”。只是一个友好的警告。

你可以,但我认为你不应该

该参数与复数的参数相同。给定两个四元数,它们要么相等,要么不相等,无法确定哪一个大于另一个。四元数形成一个除法代数,它没有顺序(与实数域不同)。唯一的(合理的)我认为,比较两个四元数的方法是使用范数

public int compareTo(Object o) {
  if (o instanceOf Quaternion) {
    // Compute the difference between the square of the norm
    double result = s*s + i*i + j*j + k*k - o.s*o.s - o.i*o.i - o.j*o.j - o.k*o.k;
    if (result > 0) { return 1; }
    if (result < 0) { return -1; }
    return 0;
  }
}
double norm = Math.sqrt(s*s + i*i + j*j + k*k);
在这种情况下,您可以定义四元数a大于四元数b,如果a的范数大于b的范数。但这绝对不是一个标准定义。我会小心地使四元数或复数具有可比性。但是,这取决于您的用例。请考虑到没有对这些数字进行标准排序的方法

有关比较复数的一些好链接,请参见本文。四元数的参数基本相同


比较四元数的另一种方法是使用a。

四元数或复数没有数学标准排序

不过,您可能希望实现
Compariable
接口,以便方便地进行排序,并将它们存储在
TreeSet
TreeMap
集合中

为了明确排序是任意的,我将使用四元数组件的字典组合。这也确保了排序与
等于
一致,并且算法按预期工作


对于更自然的排序,例如考虑范数的排序,您始终可以显式定义比较器。

这是一个数学问题,而不是编程问题。请咨询数学专家,如果您在实现该解决方案时遇到问题,请在此寻求实现帮助。我建议不要在中使用
-
e> 比较到
(由于潜在溢出)。使用
是的,我已经实现了norm方法,这似乎是最有意义的比较。感谢您不应该比较四元数的原因是:它们不能排序。您可以定义如何比较两个四元数,但也有一些缺点。使用norm时最严重的缺点是(正如Klas提到的)两个不相等的四元数可以有相等的范数。这也违反了,即只有当两个对象相等时才返回0。@马丁:在数学中不比较四元数的真正原因是不能有(aa+c0和b>0=>ab>0)因为这意味着-1<0和-1>0。这些公理需要对排序做任何有意义的事情。当涉及到在树中存储四元数时,字典顺序是非常好的。我同意howe