构造伴随矩阵


15

您有许多个孤独的多项式,因此请让他们成为一些同伴(不会威胁您的攻击)!

对于度的多项式n,有一个n by n伴随的立方 矩阵。您需要创建一个函数,该函数以升序(a + bx +cx^2 + …)或降序(ax^n + bx^(n-1) + cx^(n-2)+…)的顺序接受多项式的系数列表(但不能同时接受)并输出伴随矩阵。

对于一个多项式c0 + c1x + c2x^2 + ... + cn-1x^(n-1) + x^n,其伴随矩阵为

     (0, 0, 0, ..., -c0  ),
     (1, 0, 0, ..., -c1  ),
     (0, 1, 0, ..., -c2  ),
     (...................),
     (0, 0, ..., 1, -cn-1)

请注意,的系数为x^n1。对于其他任何值,请将所有其余系数除以x^n。此外,1从对角线偏移。

如果您使用的语言已经包含执行此操作的功能或模块,则不能使用它-您必须编写自己的语言。

例如,如果您有4x^2 – 7x + 12,则升序系数为(12, -7, 4)和降序(4, -7, 12)。函数或程序应按[(0, -3.0), (1, 1.75)]任一顺序输出。指定您的代码接受的顺序。最小多项式应为二次。系数限于实数。

以下是示例–您的输出不必与漂亮的格式匹配,但应按()顺序输出矩阵的行(中的)。

升序:

input:
    [3., 7., -5., 4., 1.]
output:
    [(0, 0, 0, -3.),
     (1, 0, 0, -7.),
     (0, 1, 0,  5.),
     (0, 0, 1, -4.)]

input:
    [-4., -7., 13.]
output:
    [(0, 0.30769231),
     (1, 0.53846154)]

input:
    [23., 1., 92., 8., -45., 88., 88.]
output:
    [(0, 0, 0, 0, 0, -0.26136364),
     (1, 0, 0, 0, 0, -0.01136364),
     (0, 1, 0, 0, 0, -1.04545455),
     (0, 0, 1, 0, 0, -0.09090909),
     (0, 0, 0, 1, 0,  0.51136364),
     (0, 0, 0, 0, 1, -1.        )]

降序:

input:
    [1., 4., -5., 7., 3.]
output:
    [(0, 0, 0, -3.),
     (1, 0, 0, -7.),
     (0, 1, 0,  5.),
     (0, 0, 1, -4.)]

input:
    [13., -7., -4.]
output:
    [(0, 0.30769231),
     (1, 0.53846154)]

input:
    [88., 88., -45., 8., 92.,1., 23.]
output:
    [(0, 0, 0, 0, 0, -0.26136364),
     (1, 0, 0, 0, 0, -0.01136364),
     (0, 1, 0, 0, 0, -1.04545455),
     (0, 0, 1, 0, 0, -0.09090909),
     (0, 0, 0, 1, 0,  0.51136364),
     (0, 0, 0, 0, 1, -1.        )]

丹尼斯以20字节获胜!


2
系数是实数(不复杂),对吗?
路易斯·门多

1
程序有效还是仅功能正常?(请记住,将竞赛限制在功能范围内会禁止没有功能的有趣语言。)
lirtosiast 2015年

1
我们必须考虑的最小次多项式是多少?
Alex A.

Answers:


3

CJam,23个 20字节

{)W*f/_,,_ff=1f>\.+}

此函数从堆栈中弹出输入(升序),然后将输出压入。

CJam解释器中在线尝试。

怎么运行的

)   e# Pop the last element from the input array.
W*  e# Multiply it by -1.
f/  e# Divide the remaining array elements by this product.
_,  e# Push a copy of the array and compute its length (L).
,_  e# Push [0 ... L-1] twice.
ff= e# For each I in [0 ... L-1]:
    e#   For each J in [0 ... L-1]:
    e#     Push (I==J).
    e# This pushes the L x L identity matrix.
1f> e# Discard the first element of each row, i.e., the first column.
\   e# Swap the result with the modified input.
.+  e# Vectorized append; append the input as a new column.

3

CJam,32 31 28字节

0q~)f/f-_,(_,\0a*1+fm<~]W%z

在线尝试

这将使用CJam列表格式以升序输入。输入样例:

[-4.0 -7.0 13.0]

说明:

0     Push a 0 for later sign inversion.
q~    Get and interpret input.
)     Pop off last value.
f/    Divide all other values by it.
f-    Invert sign of values.
_,    Get count of values, which corresponds to n.
(     Decrement by 1.
_,    Create list of offsets [0 1 ... n-1] for later.
\     Swap n-1 back to top.
0a*   Create list of n-1 zeros.
1+    Append a 1. This is the second-but-last column [0 0 ... 0 1].
fm<   Apply rotation with all offsets [0 1 ... n-1] to column.
~     Unwrap the list of 0/1 columns.
]     Wrap all columns
W%    Invert their order from last-to-first to first-to last.
z     Transpose to get final matrix.
`     Convert to string for output.

3

APL,40 30字节

{(-n↑⍵÷⊃⊖⍵),⍨⍉1↓⍉∘.=⍨⍳n←1-⍨≢⍵}

接受升序输入。

说明:

{
                        n←1-⍨≢⍵    ⍝ Define n = length(input)-1
                   ∘.=⍨⍳           ⍝ Create an n×n identity matrix
               ⍉1↓⍉                ⍝ Drop the leftmost column
            ,⍨                     ⍝ Append on the right:
  (-n↑⍵                            ⍝ n negated coefficients,
       ÷⊃⊖⍵)                       ⍝ divided by the n+1st
}

在线尝试


3

朱莉娅,43个字节

c->rot180([-c[2:(n=end)]/c[] eye(n-1,n-2)])

这使用降序输入。它构造了旋转180度的矩阵,以便能够更有效地使用“眼睛”,然后将矩阵旋转到正确的方向。


2

朱莉娅,64 44字节

c->(k=c[n=end];[eye(n-=1)[:,2:n] -c[1:n]/k])

以升序接受系数的向量。

取消高尔夫:

function f(c::Array)
    # Simultaneously define k = the last element of c and
    # n = the length of c
    k = c[n = end]

    # Decrement n, create an n×n identity matrix, and exclude the
    # first column. Horizontally append the negated coefficients.
    [eye(n-=1)[:,2:n] -c[1:n]/k]
end

在线尝试

感谢Glen O,节省了20个字节!


2

R,71 59字节

以升序输入。

function(x)cbind(diag(n<-length(x)-1)[,2:n],-x[1:n]/x[n+1])

取消高尔夫:

f <- function(x) {
    # Get the length of the input
    n <- length(x)-1

    # Create an identity matrix and exclude the first column
    i <- diag(n)[, 2:n]

    # Horizontally append the negated coefficients divided
    # by the last one
    cbind(i, -x[1:n]/x[n+1])
}

1

Matlab,66个字节

function y=f(c)
n=numel(c);y=[[0*(3:n);eye(n-2)] -c(1:n-1)'/c(n)];

它使用升序输入,格式为[3., 7., -5., 4., 1.][3. 7. -5. 4. 1.]

在线试用(八度)。

示例(在Matlab中):

>> f([23., 1., 92., 8., -45., 88., 88.])
ans =
                   0                   0                   0                   0                   0  -0.261363636363636
   1.000000000000000                   0                   0                   0                   0  -0.011363636363636
                   0   1.000000000000000                   0                   0                   0  -1.045454545454545
                   0                   0   1.000000000000000                   0                   0  -0.090909090909091
                   0                   0                   0   1.000000000000000                   0   0.511363636363636
                   0                   0                   0                   0   1.000000000000000  -1.000000000000000

如果程序有效(而不是函数),请使用stdin和stdout:

Matlab,59个字节

c=input('');n=numel(c);[[0*(3:n);eye(n-2)] -c(1:n-1)'/c(n)]

我认为您可以做到n=numel(c=input(''));
lirtosiast 2015年

@ThomasKwa谢谢!但是,这在Matlab中不是有效的语法。n=numel(input(''))会有效,但我需要c稍后再使用
Luis Mendo 2015年

抱歉; 它在我测试过的Octave中工作。
lirtosiast 2015年

1

八度,45 44字节

假设c一个列向量x的结尾处具有最高幂的系数。

@(c)[eye(n=rows(c)-1)(:,2:n),-c(1:n)/c(end)]

旧版本:

@(c)[eye(n=numel(c)-1)(:,2:n),-c(1:n)/c(end)]

高五,朱莉娅!


1

Python 2,141字节

我自己的尝试:

def C(p):
 c,r=p.pop(0),range;d=[-i/c for i in p];n=len(d);m=[[0]*n for i in r(n)]
 for i in r(n-1):m[i][i+1]=1
 m[-1]=d[::-1];return zip(*m)

以降序方式获取系数列表,然后首先构建伴随矩阵的转置-以刺伤和健谈着称。返回使用zip产生该转置的转置以获得实际矩阵。

>>> C([1., 4., -5., 7., 3.])
[(0, 0, 0, -3.0), (1, 0, 0, -7.0), (0, 1, 0, 5.0), (0, 0, 1, -4.0)]

1

JavaScript(ES6)85

升序。

在任何符合EcmaScript 6的浏览器中测试运行以下代码段。

f=c=>alert(c.map((v,i)=>c.map((x,j)=>++j-i?j-c.length?0:-v/m:1),m=c.pop()).join(`
`))

// test
// redefine alert to write into the snippet body
alert=x=>O.innerHTML+=x+'\n'

function test() {
  v=I.value.match(/\d+/g)
  I.value=v+''
  alert(v)
  f(v)
}  

test()
<input value='23.,1.,92.,8.,-45.,88.,88.' id=I><button onclick="test()">-></button>
<pre id=O></pre>


0

TI-BASIC,50个字节

Ans→X
List▶matr(ΔList(Ans-cumSum(Ans)),[A]
dim(Ans
augment(augment(0randM(Ans-2,1),identity(Ans-2))ᵀ,[A]∟X(Ans)⁻¹

以升序输入。请注意,这对于度数小于2的多项式不起作用,因为TI-BASIC不支持空矩阵或列表。在OP做出裁决之前,我可以花几个字节来解决这个问题。

首先,我们将列表存储到其中∟X以供以后使用最后一个元素。然后,我们计算ΔList(Ans-cumSum(Ans)),它是最后一个元素被切掉的求反列表,并将其转换为列向量。由于List▶matr(未进行修改Ans,我们可以使用下一行获取列表的维度,我们使用三次。TI-BASIC没有垂直串联,因此我们需要进行转置和水平串联。在最后一行中,[A]/∟X(Ans这是行不通的,因为矩阵可以与标量相乘但不能相除。

旁白:为了生成零的行向量,我们利用了很少有用的randM(命令。randM(创建一个随机矩阵,但它的条目始终是-9到9(!)之间的随机整数,因此,它仅对创建零矩阵有用。


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.