Calcola Matrix-Vector


14

Dato un array intero di almeno due elementi, emette il Matrix-Vector (definito di seguito) dell'array.

Per calcolare Matrix-Vector , prima ruota attraverso l' narray input-size per creare una matrice di size n x n, con il primo elemento dell'array che segue la diagonale principale. Questo costituisce la porzione di matrice. Per il vettore, capovolgi verticalmente l'array di input. Quindi eseguire la moltiplicazione della matrice normale. Il vettore di output è il risultato.

Per esempio,

a = [1, 2, 3]

Innanzitutto, ruota l'array due volte a destra, per ottenere [3, 1, 2]e [2, 3, 1], quindi, impilarli per formare una 3x3matrice

[[1, 2, 3]
 [3, 1, 2]
 [2, 3, 1]]

Quindi, capovolgi l'array in verticale per formare il vettore

[[1, 2, 3]    [[1]
 [3, 1, 2]  x  [2]
 [2, 3, 1]]    [3]]

Eseguire la solita moltiplicazione di matrice

[[1, 2, 3]    [[1]    [[1+4+9]    [[14]
 [3, 1, 2]  x  [2]  =  [3+2+6]  =  [11]
 [2, 3, 1]]    [3]]    [2+6+3]]    [11]]

E l'output è [14, 11, 11]o [[14], [11], [11]](la tua scelta se è appiattito o meno).

Esempio n. 2

a = [2, 5, 8, 3]

[[2, 5, 8, 3]    [[2]    [[4+25+64+9]     [[102]
 [3, 2, 5, 8]  x  [5]  =  [6+10+40+24]  =  [80]
 [8, 3, 2, 5]     [8]     [16+15+16+15]    [62]
 [5, 8, 3, 2]]    [3]]    [10+40+24+6]]    [80]]

[102, 80, 62, 80]

Regole

  • Si può presumere che l'input e l'output si adattino al tipo intero nativo della tua lingua.
  • L'input e l'output possono essere forniti in qualsiasi formato conveniente .
  • È accettabile un programma completo o una funzione. Se una funzione, è possibile restituire l'output anziché stamparlo.
  • Se possibile, includi un collegamento a un ambiente di test online in modo che altre persone possano provare il tuo codice!
  • Sono vietate le scappatoie standard .
  • Si tratta di quindi si applicano tutte le normali regole del golf e vince il codice più breve (in byte).

Risposte:


8

Gelatina , 5 byte

ṙJṚæ.

Provalo online!

Spiegazione

In primo luogo:

dove sono i vettori di riga ed è un vettore di colonna .vkx

Ciò dimostra che la moltiplicazione di matrici è solo un punto prodotto tra righe e colonne.

Poi, è in realtà ruotato verso destra, ed è ruotato verso destra, etc.v1v0vkvk-1

Da un altro punto, viene ruotato verso sinistra, ed è ruotato verso sinistra, etc.v1vnvnv1

Come funziona

ṙJṚæ.   input: z (a list of length n)
ṙJ      [rot(z,1), rot(z,2), ..., rot(z,n)] (to the left)
  Ṛ     [rot(z,n), ..., rot(z,2), rot(z,1)]
   æ.   [rot(z,n).z , ..., rot(z,2).z , rot(z,1).z] (dot product)




3

Gelatina , 9 byte

LḶN⁸ṙæ×W€

Provalo online!

Una funzione che restituisce un array verticale. Come programma completo, sembra che ritorni un array orizzontale. Per restituire un array orizzontale, LḶN⁸ṙ×⁸S€invece, dovresti farlo .



2

Haskell , 49 byte

f v=sum.zipWith(*)v.fst<$>zip(iterate tail$v++v)v

Provalo online!

Per un input v=[1,2]

  • iterate tail$v++v restituisce l'elenco [[1,2,1,2],[2,1,2],[1,2],[2],[],...]
  • fst<$>zip l vè uguale take(length v)le cede[[1,2,1,2],[2,1,2]]
  • sum.zipWith(*)v viene mappato su ciascun elemento e per produrre il prodotto della riga matrice vettoriale.

Molto più intelligente della mia risposta! Mi piace fst<$>zip l vmolto
jferard,

2

R , 66 62 byte

sapply(length(n<-scan()):1,function(i)c(n[-(1:i)],n[1:i])%*%n)

Provalo online!


l'utilizzo Map(function(i)c(n[-(1:i)],n[1:i])%*%n,length(n<-scan()):1)è più corto di 3 byte; restituisce solo un elenco di matrici.
Giuseppe,

e un ciclo for for(i in seq(n<-scan()))F=c(c(n[-(1:i)],n[1:i])%*%n,F);F[1:i]è di 61 byte senza restituire uno strano formato di output.
Giuseppe,





1

J , 14 byte

+/ .*~#\.1&|.]

Provalo online!

Spiegazione

+/ .*~#\.1&|.]  Input: array M
      #\.       Length of each suffix, forms the range [len(M), ..., 2, 1]
             ]  Identity, get M
         1&|.   For each 'x' in the suffix lengths, rotate left M  by 'x'
+/ .*~          Dot product with M

Questo è abbastanza carino Una domanda. Quando non 1&|.non è vero bonding 1per |., la creazione di una monade? ma poi usi quella monade con un argomento sia destro che sinistro, con quello sinistro che determina quante volte viene applicato. Cosa sta succedendo qui?
Giona,

@Jonah È un modulo speciale per &. Se usato come u n&f v, sta eseguendo (n&f)^:u v. Vedi il fondo del legame per vedere più analisi di esso.
miglia

ah, TIL. è qualcosa che usi spesso?
Giona,

@Jonah In molti casi è utile per giocare a golf. In questo caso, avrebbe potuto essere fatto in un numero uguale di byte usando il grado #\.|."{], ma ho pubblicato il più breve che mi è venuto in mente prima di provare le alternative.
miglia

1

APL, 17 byte

(↑¯1⌽(⍳≢)⌽¨⊂)+.×⍪

Spiegazione:

(↑¯1⌽(⍳≢)⌽¨⊂)+.×⍪

 ↑                      matrix format of
  ¯1⌽                   right rotate by 1 of
     (⍳≢)               the 1..[length N]
         ⌽¨             rotations of
           ⊂            the enclosed input
             +.×        inner product with
                ⍪       1-column matrix of input


1

Haskell , 56 55 52 byte

f l=[sum$zipWith(*)l$drop i$l++l|i<-[0..length l-1]]

Provalo online!

Salvato un byte grazie a @Laikoni

Tre byte salvati: l++lanzichécycle l


È possibile salvare un byte con zipWith(*)l$drop i$cycle l.
Laikoni,

1

Buccia , 11 byte

mΣ§‡*´ṀKoṫ¢

Provalo online!

Spiegazione

mΣ§‡*´ṀKoṫ¢  Implicit input, e.g. [1,2,3]
          ¢  Cycle: [1,2,3,1,2,3,...
        oṫ   Tails: [[1,2,3,1,2,3...],[2,3,1,2,3...],[3,1,2,3...]...
     ´ṀK     Replace each element of input with input: [[1,2,3],[1,2,3],[1,2,3]]
   ‡*        Vectorized multiplication (truncated with respect to shortest list)
  §          applied to the last two results: [[1,4,9],[2,6,3],[3,2,6]]
mΣ           Sum of each row: [14,11,11]

1

Ottava - 67 48 byte

Grazie a Luis Mendo per aver ridotto questo codice di 19 byte!

Nota: questo codice può essere eseguito solo in Octave. MATLAB non supporta espressioni all'interno di funzioni che possono creare variabili mentre allo stesso tempo valuta le espressioni che le creano.

n=numel(a=input(''));a(mod((x=0:n-1)-x',n)+1)*a'

Il codice originale in MATLAB può essere trovato qui, ma può essere eseguito in qualsiasi versione di MATLAB. Questo codice è di 67 byte:

a=input('');n=numel(a)-1;a(mod(bsxfun(@minus,0:n,(0:n)'),n+1)+1)*a'

Spiegazione

  1. a=input('');- Riceve un vettore (riga) dall'utente tramite input standard. Devi inserire il vettore in forma di ottava (es [1,2,3].).
  2. n=numel(...); - Ottiene il numero totale di elementi nel vettore di input.
  3. x=0:n-1- Crea un vettore di riga che aumenta da 0fino a n-1con incrementi di 1.
  4. (x=0:n-1)-x'- Esegue la trasmissione in modo da disporre di una n x nmatrice in modo che ogni riga isia composta da elementi da 0 fino a n-1ogni elemento nella riga isottratto da i.
  5. mod(..., n)+1- Assicura che tutti i valori negativi vengano inseriti in nmodo che ogni riga icontenga il vettore da 0 an-1 spostati in spostato a sinistra circolare dii elementi. Aggiungiamo 1 come MATLAB / Octave inizia a indicizzare i vettori o le matrici con 1.
  6. a(...) - Crea un n x n matrice in cui utilizzando (4), accediamo agli indici corretti del vettore di input dettati da ciascun valore da (4) ottenendo così la matrice di cui abbiamo bisogno.
  7. (...)*a' - Esegue la moltiplicazione della matrice vettoriale trasponendo / capovolgendo a per diventare un vettore colonna prima di eseguire la moltiplicazione.

Esecuzioni di esempio

>> n=numel(a=input(''));a(mod((x=0:n-1)-x',n)+1)*a'
[1,2,3]

ans =

         14.00
         11.00
         11.00

>> n=numel(a=input(''));a(mod((x=0:n-1)-x',n)+1)*a'
[2,5,8,3]

ans =

        102.00
         80.00
         62.00
         80.00

Provalo online!


È possibile utilizzare l'espansione implicita anziché bsxfun. Definire nsenza -1salvare anche pochi byte. E se ti limiti ad Octave puoi assegnare ae 0:nalle variabili al volo e salvarne ancora . Inoltre, vieni qui più spesso !! MrGreen
Luis Mendo,

@LuisMendo ah yes. Dico che Octave ha già supportato l'espansione implicita. Anche salvare la variabile all'interno della inputfunzione è un grande trucco. Non pensavo potesse supportarlo. L'ho visto solo in C o C ++ per esperienza personale. Grazie!
rayryeng - Ripristina Monica il

1
@LuisMendo Presto inserirò le modifiche suggerite come modifica. Sono stato occupato, ma non ne ho fatto una priorità poiché questa voce non vincerà mai nel conteggio dei byte.
rayryeng - Ripristina Monica il

@LuisMendo Changed. Grazie mille :) Ho capito il codice mentre stavo cambiando la mia spiegazione sopra.
rayryeng - Ripristina Monica il

Sono contento di poterti aiutare :-)
Luis Mendo il

0

Javascript 79 byte

Accetta un array di input e genera un array del vettore matrice

a=>(b=[...a],a.map(x=>([...b].reduce((m,n,i)=>m+=n*a[i],0,b.push(b.shift())))))

Spiegazione

a=>(
    b=[...a],                    // copy the input into b
    a.map(x=>(                   // transform a into a new array
        [...b].reduce(           // copy b into a new array and reduce
            (m,n,i)=>m+=n*a[i],  // memo += the element in the array * the ith
                                 // element in a
            0,                   // start memo at 0
            b.push(b.shift())    // shift the first element in b to the end
                                 // not used by reduce, but performing this op
                                 // here saves a few bytes
        )
    ))
)

0

Clojure, 80 byte

#(map(fn[_ c](apply +(map * c %)))%(iterate(fn[c](into[(last c)](butlast c)))%))

iterateproduce una sequenza infinita, ma invece di usarlo (take (count %) (iterate ...))per fermarlo, lo uso %come argomento extra map.


0

Perl 5 , 65 + 1 (-a) = 66 byte

@o=@F;for(@o){$r=0;$r+=$_*$F[$i++%@F]for@o;say$r;unshift@F,pop@F}

Provalo online!

Prende il vettore di input come numeri separati da spazio. Emette numeri separati di avanzamento riga che rappresentano il vettore del risultato.



0

Lisp comune, 78 byte

(lambda(x)(loop as i on(append x x)as y in x collect(reduce'+(mapcar'* i x))))

Provalo online!

Raddoppiate l'array (in questo caso un elenco Lisp) e ripetete le liste secondarie con i(usando x, attraverso y, per interrompere l'iterazione). Quindi calcola il prossimo elemento del risultato sommando il risultato della moltiplicazione di ciascun elemento di xcon ogni elemento di i(di nuovo arrestandosi quando viene terminata la lista più breve).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.