Построить сопутствующую матрицу


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^nравен 1. Для любого другого значения разделите все остальные коэффициенты на x^n's. Кроме того, 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

1
Какой полином минимальной степени мы должны учитывать?
Алекс А.

Ответы:


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])

Принимает вектор коэффициентов в порядке возрастания.

Ungolfed:

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

Попробуйте онлайн

Сохранено 20 байтов благодаря Glen O!


2

R 71 59 байт

Принимает ввод в порядке возрастания.

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

Ungolfed:

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

@ThomasKwa Спасибо! Тем не менее, это неверный синтаксис в Matlab. n=numel(input(''))будет действительным, но мне нужно использовать cпозже
Луис Мендо

Сожалею; это работало в Октаве, где я проверял это.
Lirtosiast

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 (!), поэтому на самом деле полезно создавать только нулевые матрицы.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.