Konstruieren Sie eine Begleitmatrix


15

Sie haben eine Reihe von Polynomen, die einsam sind, also machen Sie sie zu Gefährten (die nicht drohen zu erstechen)!

Für ein Polynom vom Grad ngibt es eine n by nBegleiter Würfelmatrix für sie. Sie müssen eine Funktion erstellen, die eine Liste von Koeffizienten für ein Polynom in aufsteigender ( ) oder absteigender ( ) Reihenfolge (aber nicht in beiden) akzeptiert, und die Begleitmatrix ausgeben. a + bx +cx^2 + …ax^n + bx^(n-1) + cx^(n-2)+…

für ein Polynom c0 + c1x + c2x^2 + ... + cn-1x^(n-1) + x^nist seine Begleitmatrix

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

Beachten Sie, dass der Koeffizient für x^n1 ist. Teilen Sie für jeden anderen Wert alle übrigen Koeffizienten durch x^n's. Zusätzlich sind die Einsen von der Diagonalen versetzt.

Wenn die von Ihnen verwendete Sprache bereits eine Funktion oder ein Modul enthält, die bzw. das dies tut, können Sie sie nicht verwenden - Sie müssen Ihre eigene schreiben.

Wenn Sie dies getan haben 4x^2 – 7x + 12, sind die Koeffizienten in aufsteigender Reihenfolge (12, -7, 4)und absteigender Reihenfolge (4, -7, 12). Die Funktion oder das Programm sollte [(0, -3.0), (1, 1.75)]für jede Bestellung ausgegeben werden. Geben Sie an, welche Bestellung Ihr Code akzeptiert. Das minimale Polynom sollte quadratisch sein. Koeffizienten sind auf reelle Zahlen beschränkt.

Unten sind Beispiele aufgeführt - Ihre Ausgabe muss nicht mit der hübschen Formatierung übereinstimmen, sondern sollte die Zeilen (in der ()) der Matrix in der angegebenen Reihenfolge ausgeben .

Aufsteigende Reihenfolge:

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

Absteigende Reihenfolge:

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

Dennis gewinnt mit 20 Bytes!


2
Koeffizienten sind real (nicht komplex), richtig?
Luis Mendo

1
Sind Programme gültig oder funktioniert es nur? (Denken Sie daran, dass die Beschränkung des Wettbewerbs auf Funktionen interessante Sprachen ohne Funktionen nicht
zulässt

1
Was ist das minimale Gradpolynom, das wir berücksichtigen müssen?
Alex A.

Antworten:


3

CJam, 23 20 Bytes

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

Dies ist eine Funktion, die die Eingabe (aufsteigende Reihenfolge) vom Stapel abruft und die Ausgabe zurückschiebt.

Probieren Sie es online im CJam-Interpreter aus .

Wie es funktioniert

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

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

Probieren Sie es online aus

Dies nimmt die Eingabe in aufsteigender Reihenfolge vor, wobei das CJam-Listenformat verwendet wird. Beispieleingabe:

[-4.0 -7.0 13.0]

Erläuterung:

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 Bytes

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

Akzeptiert die Eingabe in aufsteigender Reihenfolge.

Erläuterung:

{
                        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
}

Probieren Sie es online aus


3

Julia, 43 Bytes

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

Dies verwendet absteigende Reihenfolge für die Eingabe. Es konstruiert die um 180 Grad gedrehte Matrix, um eine effizientere Nutzung des "Auges" zu ermöglichen, und dreht dann die Matrix in die richtige Ausrichtung.


2

Julia, 64 44 Bytes

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

Akzeptiert einen Vektor der Koeffizienten in aufsteigender Reihenfolge.

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

Probieren Sie es online aus

Dank Glen O 20 Bytes gespart!


2

R 71 59 Bytes

Nimmt die Eingabe in aufsteigender Reihenfolge vor.

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 Bytes

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

Die Eingabe erfolgt in aufsteigender Reihenfolge, mit Format [3., 7., -5., 4., 1.]oder [3. 7. -5. 4. 1.].

Versuchen Sie es online (in Oktave).

Beispiel (in 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

Wenn ein Programm gültig ist (anstelle einer Funktion), mit stdin und stdout:

Matlab, 59 Bytes

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

Ich denke, Sie können tunn=numel(c=input(''));
Lirtosiast

@ ThomasKwa Vielen Dank! Dies ist jedoch in Matlab keine gültige Syntax. n=numel(input(''))wäre gültig, aber ich muss cspäter wieder verwenden
Luis Mendo

Es tut uns leid; es hat in Octave funktioniert, wo ich es getestet habe.
Lirtosiast

1

Oktave, 45 44 Bytes

Angenommen cist ein Spaltenvektor mit dem Koeffizienten der höchsten Potenz von xam Ende.

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

Alte Version:

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

High Five, Julia!


1

Python 2, 141 Bytes

Mein eigener Versuch:

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)

Erstellt eine Liste der Koeffizienten in absteigender Reihenfolge und erstellt zuerst die Transponierung der Begleitmatrix - bekannt für das Stechen und Sprechen. Die Rückgabe erzeugt mit zip die Transponierung dieser Transponierung, um die eigentliche Matrix zu erhalten.

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

Aufsteigende Reihenfolge

Testen Sie das folgende Snippet in einem beliebigen EcmaScript 6-kompatiblen Browser.

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 Bytes

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

Nimmt die Eingabe in aufsteigender Reihenfolge vor. Beachten Sie, dass dies für Polynome vom Grad <2 nicht funktioniert, da TI-BASIC keine leeren Matrizen oder Listen unterstützt. In Erwartung einer Entscheidung von OP kann ich dies auf Kosten einiger Bytes beheben.

Zuerst speichern wir die Liste in ∟X, um später das letzte Element zu verwenden. Dann berechnen wir ΔList(Ans-cumSum(Ans)), das ist nur die negierte Liste mit dem zuletzt abgeschnittenen Element, und konvertieren sie in einen Spaltenvektor. Da List▶matr(nicht geändert wird Ans, können wir die nächste Zeile verwenden, um die Dimension der Liste zu ermitteln, die wir dreimal verwenden. TI-BASIC hat keine vertikale Verkettung, daher müssen Transponierungen vorgenommen und horizontal verkettet werden. In der letzten Zeile [A]/∟X(Answürde das nicht funktionieren, da Matrizen mit Skalaren multipliziert, aber nicht geteilt werden können.

Nebenbei: Um den Zeilenvektor aus Nullen zu generieren, nutzen wir den selten nützlichen randM(Befehl. randM(Erstellt eine zufällige Matrix, deren Einträge jedoch immer zufällige Ganzzahlen zwischen -9 und 9 (!) sind. Es ist also wirklich nur sinnvoll, Nullmatrizen zu erstellen.


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.