矩阵三角法


13

介绍

两种最常见的三角函数,sinecosine(或sincos的简称),可以扩展为矩阵值函数。计算矩阵值类似物的一种方法如下:

考虑以下两个重要的三角恒等式:

触发身份

使用这些标识,我们可以为sin和导出以下方程式cos

触发功能

矩阵指数存在于所有方阵和由下式给出:

矩阵指数

其中A 0是单位矩阵IA具有相同的维度。使用矩阵指数,可以将这两个三角函数(以及所有其他三角函数)评估为矩阵的函数。

挑战

给定一个正方形矩阵,的输出的值sin(A)cos(A)

规则

  • 输入和输出可以采用任何方便且合理的格式(2D数组,您的语言的矩阵格式等)。
  • 您可以编写一个程序,两个独立程序,一个功能或两个功能。如果选择编写两个函数,则可能会在它们之间共享代码(例如,导入和帮助函数)。
  • 输入矩阵的值将始终为整数。
  • 由于浮点不精确,您的解决方案可能会出现准确性问题。如果您的语言具有神奇的无限精度值,那么您的解决方案应该可以完美地工作(忽略它需要无限的时间和/或内存的事实)。但是,由于不存在那些不可思议的无限精度值,因此可以接受由有限精度引起的不准确性。制定该规则是为了避免由于要求输出达到特定精度而导致的复杂情况。
  • 不允许为矩阵参数计算三角函数的内建函数(包括双曲三角函数)。允许使用其他矩阵内建函数(例如乘法,乘幂,对角化,分解和矩阵指数)。

测试用例

格式: A -> sin(A), cos(A)

[[0]] -> [[0]], [[1]]
[[0, 2], [3, 5]] -> [[-0.761177343863758, 0.160587281888277], [0.240880922832416, -0.359709139143065]], [[0.600283445979886, 0.119962280223493], [0.179943420335240, 0.900189146538619]]
[[1, 0, 1], [0, 0, 0], [0, 1, 0]] -> [[0.841470984807897, -0.158529015192103, 0.841470984807897], [0, 0, 0], [0, 1, 0]], [[0.540302305868140, -0.459697694131860, -0.459697694131860], [0, 1, 0], [0, 0, 1]]
[[1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1]] -> [[0.841470984807897, 0, 0, 0, 0], [0, 0.841470984807897, 0, 0, 0], [0, 0, 0.841470984807897, 0, 0], [0, 0, 0, 0.841470984807897, 0], [0, 0, 0, 0, 0.841470984807897]], [[0.540302305868140, 0, 0, 0, 0], [0, 0.540302305868140, 0, 0, 0], [0, 0, 0.540302305868140, 0, 0], [0, 0, 0, 0.540302305868140, 0], [0, 0, 0, 0, 0.540302305868140]]
[[-3, 2, -6], [3, 0, 4], [4, -2, 7]] -> [[-0.374786510963954, 0.135652884035570, -1.35191037980742], [1.14843105375406, 0.773644542790111, 1.21625749577185], [1.21625749577185, -0.135652884035570, 2.19338136461532]], [[4.13614256031450, -1.91289828483056, 5.50873853927692], [-2.63939111203107, 1.49675144828342, -3.59584025444636], [-3.59584025444636, 1.91289828483056, -4.96843623340878]]

进一步阅读

Math.SE上的这个极好的问题包括三角函数的矩阵值类似物的一些替代推导。


我有sin([[1, 0, 1], [0, 0, 0], [0, 1, 0]]) = {{0.841, -0.158, 0.841}, {0, 0, 0}, {0, 1, 0}}Mathematica,可以查一下吗?
kennytm '16

1
@kennytm这就是测试用例显示的内容。
Mego

1
@Mego显然,所有现有答案都应删除。
feersum '16

3
@Mego认为所有基于浮点的内建函数都使用一种精确的算法(或者如果将浮点运算替换为“实数”运算则是一种精确的算法)是完全不合理的。
feersum '16

1
@feersum我在最近的编辑中已经解决了:(ignoring the fact that it would require infinite time and/or memory)
Mego

Answers:


6

朱莉娅,33 19字节

A->reim(expm(A*im))

该函数接受浮点数的二维数组,并返回分别对应于余弦和正弦的此类数组的元组。请注意,这与测试用例中给出的顺序相反,在测试用例中先列出了正弦。

对于实值矩阵A,我们有

正弦

余弦

也就是说,A的正弦和余弦对应于矩阵指数e iA的虚部和实部。参见矩阵函数(Higham,2008年)。

在线尝试!(包括所有测试用例)

由于丹尼斯节省了14个字节!


6

Mathematica,27个字节

{Im@#,Re@#}&@MatrixExp[I#]&

基于@ Rainer P.的解决方案。

以方阵A为参数,并输出包含的列表{sin(A), cos(A)}

所述输入与格式化N得到的数值代替长精确公式的和Column显示的结果sin(A)cos(A)作为单独的矩阵代替的嵌套列表。

例

分别计算值需要38个字节

{(#2-#)I,+##}/2&@@MatrixExp/@{I#,-I#}&

6

果冻23 22 字节

³æ*÷!
®Ḥ‘©r0Ç€s2_@/µÐL

在线尝试!

背景

该方法直接计算正弦余弦的泰勒级数,即

式

它会增加两个系列的初始项的数量,直到结果不再更改为止,因此其精度仅受浮点类型的精度限制。

怎么运行的

®Ḥ‘©r0Ç€s2_@/µÐL  Main link, Argument: A (matrix)

             µÐL  Loop; apply the chain until the results are no longer unique.
                  Return the last unique result.
®                   Yield the value of the register (initially zero).
 Ḥ                  Unhalve/double it.
  ‘©                Increment and copy the result (n) to the register.
    r0              Range; yield [n, ..., 0].
      ǀ            Apply the helper link to each k in the range.
        s2          Split the results into chunks of length 2. Since n is always
                    odd, this yields [[Ç(n), Ç(n-1)], ..., [Ç(1), Ç(0)]].
          _@/       Reduce the columns of the result by swapped subtraction,
                    yielding [Ç(1) - Ç(3) + ... Ç(n), Ç(0) - Ç(2) + ... Ç(n - 1)].


³æ*÷!             Helper link. Argument: k (integer)

³                 Yield the first command-line argument (A).
 æ*               Elevate A to the k-th power.
    !             Yield the factorial of k.
   ÷              Divide the left result by the right one.

3

C ++,305个字节

#include<cmath>
#include<iostream>
#include<vector>
int x,i=0, j;void p(std::vector<double> v){int x=sqrt(v.size());for(i=0;i<x;i++){for(j=0;j<x;j++) std::cout << v[x] << " ";std::cout << "\n";}}int main(){std::vector<double> s, c;while(std::cin >> x){s.push_back(sin(x));c.push_back(cos(x));}p(s);p(c);}

输入是数字列表,这些数字是stdin上的理想平方。输出是在stdout上漂亮打印的二维数组


2

Matlab,138121 52 50字节

由于允许矩阵求幂,(我首先没有注意到的是,d'oh)我不再需要定义我的辅助函数,并且可以简单地解决整个问题:

A=input('')*i;a=expm(A);b=expm(-A);[(b-a)*i,a+b]/2

输入应为矩阵,例如[1,2;4,5][[1,2];[3,4]]

意外的事情(事后看来并不意外)是余弦和正弦矩阵仍然满足

I = sin(A)^2+cos(A)^2

A^0一样eye(size(A))吗?
FryAmTheEggman's

哦,你是对的,谢谢!
瑕疵的

2
为什么不使用expm
路易斯·门多

2
根据身份:我应该希望他们满足该身份,考虑到标量形式已用于将函数扩展到矩阵!
芒果

1
好了,整个事情变得微不足道了。
瑕疵的



0

贤者,44字节

lambda A:map(exp(I*A).apply_map,(imag,real))

在线尝试

此匿名函数返回分别对应于sin(A)和的2个矩阵的列表cos(A)exp(I*A)计算I*AA的所有元素乘以虚数单位的)的矩阵指数,并matrix.apply_map(f)返回一个f已应用于其所有元素的矩阵。通过将imag和应用real(用于获取标量值的虚部和实部的函数)到矩阵,由于欧拉的著名身份(在质询文本中进行了引用),我们获得了sin(A)和的值cos(A)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.