在方程式中得出未知矩阵

发布于 2025-02-11 08:19:14 字数 232 浏览 4 评论 0原文

我正在逆向工程,从事一些计算机图形数学的软件系统。我在一个奇怪的情况下结束了以下数学的出现:

m * x * m^-1 * a = b

,其中m是3x3常量可逆矩阵,m^-1是m的倒数,x是一个3x3矩阵i可以控制,A是3x1列向量i也可以控制。 b是可测量的。

我怎么能找到m是?我很确定,我可以通过将所有矩阵组件将代数扩展到几个巨大的方程式中来找到答案 - 但是肯定会感觉到都应该有一个更简单的机制。

I'm working on reverse-engineering a software system doing some computer graphics math. I've wound up in a weird situation where the following math is coming up:

M * X * M^-1 * A = B

Where M is a 3x3 constant invertible matrix, M^-1 is the inverse of M, X is a 3x3 matrix I can control, A is a 3x1 column vector I can also control. B is measurable.

How can I find what M is? I'm pretty sure that I could find the answer by expanding out all matrix components algebraically into a few massive equations - but it sure feels like there should be a more straightforward mechanism.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

゛清羽墨安 2025-02-18 08:19:14

这看起来像 eigendecomposition

“

其中矩阵 a 被分解为对角线矩阵λ,而特征向量的向量 q

而您可以确认确实 X 在您的情况下是对角线矩阵,那么您知道 m c 的特征向量。您可以从 c 获得 c = a -1 b

就发现而言即使对于3×3矩阵,特征向量也是一个真正的困难问题。通常,您会做 shur noreferrer“> shur demomposition 并恢复eigevectors。

我确实找到了3×3问题的在线资源,我将其移植到其他项目中的c#中。 在这里


/// <summary>
/// Calculates the three eigenvalues analytically.
/// </summary>
/// <remarks>
/// Code taken from:
/// https://www.mpi-hd.mpg.de/personalhomes/globes/3x3/index.html
/// </remarks>
/// <returns>A vector containing the three eigenvalues.</returns>
public Vector3 GetEigenValues()
{
    //      Determine coefficients of characteristic polynomial. We write
    //      | A   D   F  |
    // A =  | D*  B   E  |
    //      | F*  E*  C  |

    var de = data.m_12 * data.m_23;
    var dd = data.m_12 * data.m_12;
    var ee = data.m_23 * data.m_23;
    var ff = data.m_13 * data.m_13;
    var m = data.m_11 + data.m_22 + data.m_33;
    var c1 = (data.m_11 * data.m_22 + data.m_11 * data.m_33 + data.m_22 * data.m_33) - (dd + ee + ff);
    var c0 = data.m_33 * dd + data.m_11 * ee + data.m_22 * ff - data.m_11 * data.m_22 * data.m_33 - 2.0 * data.m_13 * de;

    var p = m * m - 3.0 * c1;
    var q = m * (p - (3.0 / 2.0) * c1) - (27.0 / 2.0) * c0;
    var sqrt_p = (float) Math.Sqrt(Math.Abs(p));

    var sqrt_z = (float) Math.Sqrt(Math.Abs(27.0 * (0.25 * c1 * c1 * (p - c1) + c0 * (q + 27.0 / 4.0 * c0))));
    var phi = (1 / 3f) * (float) Math.Atan2(sqrt_z, q);

    var c = sqrt_p * (float) Math.Cos(phi);
    var s = sqrt_p * (float)( Math.Abs(Math.Sin(phi))/ Math.Sqrt(3));

    var w = (1 / 3f) * (m - c);

    // sort the eigenvalues
    if (c >= s)
    {
        return new Vector3(
            w - s,
            w + s,
            w + c);
    }
    else if (c >= -s)
    {
        return new Vector3(
            w - s,
            w + c,
            w + s);
    }
    else
    {
        return new Vector3(
            w + c,
            w - s,
            w + s);
    }
}

public Matrix3 GetEigenVectors() => GetEigenVectors(GetEigenValues());
public Matrix3 GetEigenVectors(Vector3 eigenValues)
{
    Vector3 ev1 = GetEigenVector(eigenValues.X).Unit();
    Vector3 ev2 = GetEigenVector(eigenValues.Y).Unit();
    Vector3 ev3 = GetEigenVector(eigenValues.Z).Unit();

    return FromColumns(ev1, ev2, ev3);
}
Vector3 GetEigenVector(float w)
{
    return new Vector3(
          data.m_12 * (data.m_23 - data.m_33 + w) - data.m_13 * (data.m_22 - data.m_23 - w)
        + data.m_22 * (data.m_33 - w) - data.m_23 * data.m_23 - w * (data.m_33 - w),
        -data.m_11 * (data.m_23 - data.m_33 + w) + data.m_12 * (data.m_13 - data.m_33 + w)
        - data.m_13 * data.m_13 + data.m_13 * data.m_23 + w * (data.m_23 - data.m_33 + w),
          data.m_11 * (data.m_22 - data.m_23 - w) - data.m_12 * data.m_12 + data.m_12 * (data.m_13 + data.m_23)
        + data.m_13 * (w - data.m_22) - w * (data.m_22 - data.m_23 - w));
}

对于您的情况,您将进行m = c.geteigenVectors();


最终说明是您可以按一个因素来扩展 m ,并且不会改变方程式由于您正在使用 m m -1 同时乘以。因此,您只需要找到一个无限矩阵 m 的一个就可以使该方程式起作用。

This looks like the Eigendecomposition of a matrix.

fig1

where the matrix A is decomposed into a diagonal matrix Λ and a vector of eigenvectors Q.

In your case you have

C = (M X M-1)

If you can confirm that indeed X in your case is a diagonal matrix, then you know M to be the eigenvectors of C. You can get C from C = A-1 B

As far as finding the eigenvectors, even for 3×3 matrices, is a genuinely hard problem. Typically you do a Shur Decomposition and recover the eigevectors.

I did find an online resource for the 3×3 problem, which I ported into C# for an other project. Original source here.


/// <summary>
/// Calculates the three eigenvalues analytically.
/// </summary>
/// <remarks>
/// Code taken from:
/// https://www.mpi-hd.mpg.de/personalhomes/globes/3x3/index.html
/// </remarks>
/// <returns>A vector containing the three eigenvalues.</returns>
public Vector3 GetEigenValues()
{
    //      Determine coefficients of characteristic polynomial. We write
    //      | A   D   F  |
    // A =  | D*  B   E  |
    //      | F*  E*  C  |

    var de = data.m_12 * data.m_23;
    var dd = data.m_12 * data.m_12;
    var ee = data.m_23 * data.m_23;
    var ff = data.m_13 * data.m_13;
    var m = data.m_11 + data.m_22 + data.m_33;
    var c1 = (data.m_11 * data.m_22 + data.m_11 * data.m_33 + data.m_22 * data.m_33) - (dd + ee + ff);
    var c0 = data.m_33 * dd + data.m_11 * ee + data.m_22 * ff - data.m_11 * data.m_22 * data.m_33 - 2.0 * data.m_13 * de;

    var p = m * m - 3.0 * c1;
    var q = m * (p - (3.0 / 2.0) * c1) - (27.0 / 2.0) * c0;
    var sqrt_p = (float) Math.Sqrt(Math.Abs(p));

    var sqrt_z = (float) Math.Sqrt(Math.Abs(27.0 * (0.25 * c1 * c1 * (p - c1) + c0 * (q + 27.0 / 4.0 * c0))));
    var phi = (1 / 3f) * (float) Math.Atan2(sqrt_z, q);

    var c = sqrt_p * (float) Math.Cos(phi);
    var s = sqrt_p * (float)( Math.Abs(Math.Sin(phi))/ Math.Sqrt(3));

    var w = (1 / 3f) * (m - c);

    // sort the eigenvalues
    if (c >= s)
    {
        return new Vector3(
            w - s,
            w + s,
            w + c);
    }
    else if (c >= -s)
    {
        return new Vector3(
            w - s,
            w + c,
            w + s);
    }
    else
    {
        return new Vector3(
            w + c,
            w - s,
            w + s);
    }
}

public Matrix3 GetEigenVectors() => GetEigenVectors(GetEigenValues());
public Matrix3 GetEigenVectors(Vector3 eigenValues)
{
    Vector3 ev1 = GetEigenVector(eigenValues.X).Unit();
    Vector3 ev2 = GetEigenVector(eigenValues.Y).Unit();
    Vector3 ev3 = GetEigenVector(eigenValues.Z).Unit();

    return FromColumns(ev1, ev2, ev3);
}
Vector3 GetEigenVector(float w)
{
    return new Vector3(
          data.m_12 * (data.m_23 - data.m_33 + w) - data.m_13 * (data.m_22 - data.m_23 - w)
        + data.m_22 * (data.m_33 - w) - data.m_23 * data.m_23 - w * (data.m_33 - w),
        -data.m_11 * (data.m_23 - data.m_33 + w) + data.m_12 * (data.m_13 - data.m_33 + w)
        - data.m_13 * data.m_13 + data.m_13 * data.m_23 + w * (data.m_23 - data.m_33 + w),
          data.m_11 * (data.m_22 - data.m_23 - w) - data.m_12 * data.m_12 + data.m_12 * (data.m_13 + data.m_23)
        + data.m_13 * (w - data.m_22) - w * (data.m_22 - data.m_23 - w));
}

For your case you would do M=C.GetEigenVectors();


A final note here is that you can scale M up or down by a factor, and it wont change the equation since you are multiplying with M and M-1 at the same time. So you just need to find just one of the infinite matrices M that would make this equation work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文