Aereo esploso


10

Il Blow-up è un potente strumento nella geometria algebrica. Permette la rimozione delle singolarità dai set algebrici preservando il resto della loro struttura.

Se non hai familiarità con nessuno di questi non ti preoccupare, il calcolo effettivo non è difficile da capire (vedi sotto).

Di seguito stiamo considerando l' esplosione del punto di una curva algebrica in 2D. Una curva algebrica in 2D è data dal locus zero di un polinomio in due variabili (ad es. per il cerchio unitario o per una parabola). Lo scoppio di quella curva (in ) è dato da due polinomi come definito di seguito. Sia che descrivono con la (possibile) singolarità a rimossa.(0,0)p(x,y)=x2+y21p(x,y)=yx2 ( 0 , 0 ) r , s r s p ( 0 , 0 )(0,0)r,srsp(0,0)

Sfida

Dato un polinomio , trovare e come definito di seguito.prs

Definizione

Prima di tutto nota che tutto ciò che dico qui è semplificato e non corrisponde completamente alle definizioni effettive.

Dato un polinomio in due variabili l' esplosione è data da due polinomi nuovo ciascuno in due variabili.px,yr , sr,s

Per ottenere definiamo prima . Quindi è probabilmente un multiplo di , ovvero per alcuni cui non divide . Quindi è fondamentalmente ciò che rimane dopo la divisione.rR(x,v):=p(x,vx)R(x,v)xR(x,v)=xnr(x,v)nxr(x,v)r(x,v)

L'altro polinomio è definito esattamente lo stesso, ma cambiamo le variabili: prima scrivi . Quindi viene definito in modo tale che per alcuni cui non divide .S(u,y):=p(uy,y)sS(u,y)=yms(u,y)mys(u,y)

Per rendere più chiaro considerare quanto segue

Esempio

Considera la curva data dal locus zero di . (Ha una singolarità in perché non esiste una tangente ben definita in quel punto.)p(x,y)=y2(1+x)x2(0,0)

Quindi troviamo

R(x,v)=p(x,vx)=v2x2(1+x)x2=x2(v21x)

Quindi è il primo polinomio.r(x,v)=v21x

allo stesso modo

S(u,y)=p(uy,y)=y2(1+uy)u2y2=y2(1(1+uy)u2)

Quindi .s(u,y)=1(1+uy)u2=1u2+u3y

rS

Formato di input / output

(Come qui .) I polinomi sono rappresentati come (m+1) x (n+1)matrici / elenchi di elenchi di coefficienti interi, nell'esempio seguente i termini dei coefficienti sono riportati nella loro posizione:

[   1 * 1,   1 * x,   1 * x^2,   1 * x^3,  ... , 1 * x^n ]
[   y * 1,   y * x,   y * x^2,   y * x^4,  ... , y * x^n ]
[   ...  ,   ...   ,   ...   ,    ...   ,  ... ,   ...   ]
[ y^m * 1, y^m * x, y^m * x^2, y^m * x^3 , ..., y^m * x^n]

Quindi un'ellisse 0 = x^2 + 2y^2 -1sarebbe rappresentata come

[[-1, 0, 1],
 [ 0, 0, 0],
 [ 2, 0, 0]]

Se preferisci puoi anche scambiare xe y. In ogni direzione ti è permesso avere zeri finali (cioè coefficienti di gradi più alti che sono solo zero). Se è più conveniente, puoi anche avere array sfalsati (anziché rettangolari) in modo tale che tutti i sotto-array secondari non contengano zero finali.

  • Il formato di output è lo stesso del formato di input.

Esempi

Altro da aggiungere ( fonte di più )

Trifolium
p(x,y) = (x^2 + y^2)^2 - (x^3 - 3xy^2)
r(x,v) = v^4  x + 2  v^2  x + x + 3  v^2 - 1
s(u,y) = u^4  y + 2  u^2  y + y - u^3 + 3  u

p r S

Descartes Folium
p(x,y) = y^3 - 3xy + x^3
r(x,v) = v^3  x + x - 3v
s(u,y) = u^3  y + y - 3u

p r S

Esempi senza immagini

Trifolium:
p:
[[0,0,0,-1,1],
 [0,0,0, 0,0],
 [0,3,2, 0,0],
 [0,0,0, 0,0],
 [1,0,0, 0,0]]
r: (using the "down" dimension for v instead of y)
[[-1,1],
 [ 0,0],
 [ 3,2],
 [ 0,0],
 [ 0,1]]
s: (using the "right" dimension for u instead of x)
[[0,3,0,-1,0],
 [1,0,2, 0,1]]

Descartes Folium:
p:
[[0, 0,0,1],
 [0,-3,0,0],
 [0, 0,0,0],
 [1, 0,0,0]]
r:
[[ 0,1],
 [-3,0],
 [ 0,0],
 [ 0,1]]
s:
[[0,-3,0,0],
 [1, 0,0,1]]

Lemniscate:
p: 
[[0,0,-1,0,1],
 [0,0, 0,0,0],
 [1,0, 0,0,0]]
r:
[[-1,0,1],
 [ 0,0,0],
 [ 1,0,0]]
s:
[[1,0,-1,0,0],
 [0,0, 0,0,0],
 [0,0, 0,0,1]]

Powers:
p:
[[0,1,1,1,1]]

r:
[[1,1,1,1]]

s:
[[0,1,0,0,0],
 [0,0,1,0,0],
 [0,0,0,1,0],
 [0,0,0,0,1]]

7
Questo titolo sicuramente non è quello che pensavo fosse ...
negativo sette

Testcase suggerito:0+x+x^2+x^3+x^4
user41805

@Cowsquack Aggiunto!
Flawr,

Risposte:


5

Python 3 + numpy, 165 134 byte

lambda p:(r(p),r(p.T).T)
from numpy import*
def r(p):w,l=where(p);s=w+l;n=min(s);o=zeros((len(p),max(s)-n+1));o[w,s-n]=p[w,l];return o

Provalo online!

La funzione accetta un numpyarray 2D pcome input e restituisce una tupla (r,s)di due numpyarray 2D.

La suddivisione della soluzione è la seguente. Per calcolare il polinomio , riscriviamo ogni termine di in , e diventa in . Quindi possiamo riorganizzare la matrice di input in a matrix corrispondente a impostando . Quindi eliminiamo le colonne tutto zero all'inizio e alla fine di per eseguire una riduzione e ottenere la matrice di output per .rxjyipxj+i(yx)ixj+iuip(x,ux)(m+1)×(n+1)P(m+1)×(m+n1)Dp(x,ux)D[i,j+i]=P[i,j]DRr

Per calcolare , semplicemente scambiamo ed , ripetere lo stesso processo, e quindi scambiare indietro. Ciò corrisponde al calcolo di per e quindi traspone il risultato.sxyRPT

Il seguente codice non golfato mostra il processo di calcolo sopra riportato.

Ungolfed (Basic)

import numpy as np

def r(p):
    num_rows, num_cols = p.shape
    deg_mat = np.zeros((num_rows, num_rows + num_cols - 1))
    for i, row in enumerate(p):
        deg_mat[i, i:i+num_cols] = row
    non_zero_col_idx, = np.where(deg_mat.any(axis=0))
    return deg_mat[:,non_zero_col_idx.min():non_zero_col_idx.max()+1]

def rs(p):
    return r(p), r(p.T).T

Provalo online!

Un ulteriore miglioramento della soluzione calcola la matrice in un singolo passaggio in base a , dove .RR[i,j+ic]=P[i,j]c=minP[i,j]0i+j

Ungolfed (migliorato)

import numpy as np

def r(p):
    y_deg, x_deg = np.where(p)  # Retrieve degrees of y and x for non-zero elements in p
    total_deg = y_deg + x_deg
    min_total_deg = total_deg.min()
    max_total_deg = total_deg.max()
    out = np.zeros((p.shape[0], max_total_deg - min_total_deg + 1))
    out[y_deg, y_deg + x_deg - min_total_deg] = p[y_deg, x_deg]
    return out

def rs(p):
    return r(p), r(p.T).T

Provalo online!


3

APL (Dyalog Unicode) , 38 37 byte

1 byte salvato grazie a ngn usando +/∘⍴al posto del valore fittizio letterale0

⊢∘⍉\+/∘⍴{q↓⍨⊃⍸×∨/q←(-⍳≢⍉⍵)⊖⍺↑⍵}¨⊂,⊂∘⍉

Provalo online!

(un treno con ⎕io(origine indice) impostato come 0)

argomento corretto allegato

, concatenato con

  • ⊂∘ chiuso

  • trasposto giusto argomento

s viene calcolato dal primo, dal secondor

¨ su ciascun

+/∘⍴{ ... } eseguire la seguente funzione con argomento sinistro

  • +/ somma

      • la forma dell'argomento giusto, ovvero ottenere righe + colonne

e l'argomento giusto sarà ciascuna delle matrici allegate.

⍺↑⍵e prendi argomento a sinistra molte righe dall'argomento a destra , se è carente nelle righe (che sarà perché righe + colonne> righe), è riempito con abbastanza 0s

Il calcolo della sostituzione di o al posto di o viene effettuato ruotando le colonne del loro indice e, poiché è riempito con 0s, le colonne di sono effettivamente anteposte alla quantità desiderata di 0s.vxuyyx

ruota le colonne di

  • ⍉⍵ trasposta

  • contare le righe, tutte insieme, ≢⍉⍵ottiene il numero di colonne

  • intervallo 0 .. count-1

  • -negato, per ruotare nell'altra direzione e il valore predefinito per , in ultima analisi, per produrre 0 ¯1 ¯2 ... - (count-1), questo vettorializza automaticamente attraverso ogni colonna in modo tale che la 0a colonna sia ruotata di 0, il 1 a 1, ...

q← assegnare questo alla variabile q

Ora per dividere il polinomio per la più grande potenza di o , le prime righe di tutto 0 devono essere rimosse.xy

∨/ riduci di LCM attraverso ogni riga, se la riga è tutta-0, questo produce 0, altrimenti fornisce un numero positivo

×ottieni il segno, 00e il numero positivo → 1

indici di verità, cioè indici di 1s

scegli il primo elemento, ⊃⍸ottiene semplicemente l'indice del primo 1

q↓⍨elimina da molte righe q, di nuovo ⎕io←0aiuta a restituire il valore corretto per eliminare le righe all-0 iniziali

(funzione di uscita)

s è già stato raggiunto, per ottenere il secondo valore deve essere trasposto tramiter⊢∘⍉\


Altri approcci sono elencati di seguito.

⍝(⊢∘⍉\+/∘⍴{q↓⍨⊃⍸×∨/q←(-⍳≢⍉⍵)⊖⍺↑⍵}¨⊂,⊂∘⍉)¨a
⍝(⊢∘⍉\∘⌽⍴{q↓⍨⊃⍸×∨/q←(-⍳⍺)⊖⍵↑⍨+/⍴⍵}¨⊂∘⍉,⊂)¨a
⍝(⊢∘⍉\⌽∘⍴{q↓⍨⊃⍸×∨/q←(-⍳⍺)⊖⍵↑⍨+/⍴⍵}¨⊂,⊂∘⍉)¨a
⍝(⊢∘⍉\0{q↓⍨⊃⍸×∨/q←(-⍳≢⍉⍵)⊖⍵↑⍨+/⍴⍵}¨⊂,⊂∘⍉)¨a
⍝(⊢∘⍉\+/∘⍴({⍵↓⍨⊃⍸×∨/⍵}(-∘⍳1⊃⊢∘⍴)⊖↑)¨⊂,⊂∘⍉)¨a
⍝(⊂∘⍉∘⊃@0⍴{q↓⍨⊃⍸×∨/q←(-⍳⍺)⊖⍵↑⍨+/⍴⍵}¨⊂∘⍉,⊂)¨a
⍝{⊢∘⍉\{q↓⍨⊃⍸×∨/q←(-⍳≢⍉⍵)⊖⍵↑⍨+/⍴⍵}¨⍵(⍉⍵)}¨a
⍝(⊢∘⍉\(({⍵↓⍨⊃⍸×∨/⍵}(-∘⍳1⊃⍴)⊖⊢↑⍨1⊥⍴)¨⊂,⊂∘⍉))¨a
⍝(0 1{⍉⍣⍺⊢q↓⍨⊃⍸×∨/q←(-⍳≢⍉⍵)⊖⍵↑⍨+/⍴⍵}¨⊂,⊂∘⍉)¨a
⍝{⊢∘⍉\{q[;⍸×∨\∨q←↑(,\0⍴⍨≢⍵),¨↓⍵]}¨⍵(⍉⍵)}¨a
⍝{⊢∘⍉\{q↓⍨1⍳⍨×∨/q←(-⍳≢⍉⍵)⊖⍵↑⍨+/⍴⍵}¨⍵(⍉⍵)}¨a
⍝(⊢∘⍉\(((⊢↓⍨1⍳⍨0≠∨/)(-∘⍳1⊃⍴)⊖⊢↑⍨1⊥⍴)¨⊂,⊂∘⍉))¨a
⍝{⊢∘⍉\{q[⍸×∨\∨/q←(-⍳≢⍉⍵)⊖⍵↑⍨+/⍴⍵;]}¨⍵(⍉⍵)}¨a
⍝{⊢∘⍉\{q↓⍨+/0=∨\∨/q←(-⍳≢⍉⍵)⊖⍵↑⍨+/⍴⍵}¨⍵(⍉⍵)}¨a
⍝{⊢∘⍉\{q↓⍨⌊/+⌿∧⍀0=q←(-⍳≢⍉⍵)⊖⍵↑⍨+/⍴⍵}¨⍵(⍉⍵)}¨a
⍝(⌽∘⍉¨1↓({⊖⍉q[⍸×∨\∨/q←(-⍳≢⍉⍵)⊖⍵↑⍨+/⍴⍵;]}\3/⊂))¨a
⍝{⊢∘⍉\{↑(↓q)/⍨∨∨/q←(-⍳≢⍉⍵)⊖⍵↑⍨+/⍴⍵}¨⍵(⍉⍵)}¨a
f←⊢∘⍉\⋄{f{q[⍸×∨\∨/q←(-⍳≢⍉⍵)⊖⍵↑⍨+/⍴⍵;]}¨f⍵⍵}¨a
⍝{1↓⌽∘⍉¨{⊖⍉q[⍸×∨\∨/q←(-⍳≢⍉⍵)⊖⍵↑⍨+/⍴⍵;]}\3/⊂⍵}¨a
⍝{f←{q[⍸×∨\∨/q←(-⍳≢⍉⍵)⊖⍵↑⍨+/⍴⍵;]}⋄(f⍵)(⍉f⍉⍵)}¨a
⍝{⊢∘⍉\{↑(↓q)/⍨∨\0≠∨/q←(-⍳≢⍉⍵)⊖⍵↑⍨+/⍴⍵}¨⍵(⍉⍵)}¨a
⍝{⊢∘⍉\{(0~⍨∊⍵)@(↓⍉(⊢-⌊/)@1+⍀⍉↑⍸0≠⍵)⊢0⍴⍨,⍨⌈/⍴⍵}¨⍵(⍉⍵)}¨a
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.