Літак підірвати


10

Роздуття є потужним інструментом в алгебраїчній геометрії. Це дозволяє вилучити особливості з алгебраїчних множин , зберігаючи решту їх структури.

Якщо ви не знайомі ні з чим, не хвилюйтеся, фактичні обчислення не важко зрозуміти (див. Нижче).

Далі ми розглянемо вибух точки(0,0)алгебраїчної кривої в 2D. Алгебраїчна крива в 2D задається нульовим локусом многочлена у двох змінних (наприклад,p(x,y)=x2+y21 для одиничного кола, або p(x,y)=yx2для параболи). Роздуття цієї кривої (в(0,0)) задається двома многочленами r,sяк визначено нижче. І те й іншеr і s описати p з (можливою) особливістю при (0,0) вилучено.

Виклик

Дано деякий многочлен p, знайти r і s як визначено нижче.

Визначення

Перш за все зауважте, що все, що я тут кажу, спрощене і не відповідає повністю фактичним визначенням.

Дано многочлен p у двох змінних x,yроздуття задається двома многочленамиr,s знову кожна з двох змінних.

Отримати r ми спочатку визначимося R(x,v):=p(x,vx). ТодіR(x,v) ймовірно, кратний x, тобто R(x,v)=xnr(x,v) для деяких n де x не ділиться r(x,v). Тодіr(x,v) в основному те, що залишається після поділу.

Інший многочлен визначається точно так само, але ми перемикаємо змінні: Спочатку запишіть S(u,y):=p(uy,y). Тодіs визначається таким, що S(u,y)=yms(u,y) для деяких m де y не ділиться s(u,y).

Для того, щоб було зрозуміліше, розгляньте наступне

Приклад

Розглянемо криву, задану нульовим локусом p(x,y)=y2(1+x)x2. (Він має особливість у(0,0)тому що в цій точці немає чітко визначеної дотичної. )

Тоді знаходимо

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

Тоді r(x,v)=v21x є першим многочленом.

Аналогічно

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

Тоді s(u,y)=1(1+uy)u2=1u2+u3y.

rс

Формат вводу / виводу

(Те саме, що тут .) Поліноми представлені у вигляді (m+1) x (n+1)матриць / списків списків цілих коефіцієнтів, у прикладі нижче умови коефіцієнтів наведено у їхньому положенні:

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

Так еліпс 0 = x^2 + 2y^2 -1буде представлений як

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

При бажанні ви можете також поміняти xі y. У кожному напрямку вам дозволяється мати кінцеві нулі (тобто коефіцієнти вищих ступенів, що дорівнюють нулю). Якщо це зручніше, ви також можете мати ступінчасті масиви (замість прямокутних), такі, що всі підмасиви не містять проміжних нулів.

  • Формат виводу такий же, як і формат введення.

Приклади

Ще потрібно додати ( джерело для більше )

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 с

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 с

Приклади без малюнків

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
Цей заголовок, безумовно, не те, що я вважав, що це ...
негативний сім

Рекомендована 0+x+x^2+x^3+x^4
тестова скринька

@Cowsquack додав його!
недолік

Відповіді:


5

Python 3 + numpy, 165 134 байт

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

Спробуйте в Інтернеті!

Функція приймає один numpyдвовимірний масив pяк вхідний і повертає набір (r,s)з двох numpy2D-масивів.

Розбивка розчину полягає в наступному. Для того, щоб обчислити многочленr, ми переписуємо кожен термін xjyi з p в xj+i(yx)i, і стає xj+iui в p(x,ux). Таким чином ми можемо переставити вхід(m+1)×(n+1) матриця P в а (m+1)×(m+n1) матриця D відповідна p(x,ux) шляхом встановлення D[i,j+i]=P[i,j]. Тоді ми усуваємо абсолютно нульові стовпці на початку та в кінціD виконати зменшення і отримати вихідну матрицю R для r.

Для обчислення s, ми просто поміняємо місцями x і y, повторіть той же процес, а потім поміняйте їх назад. Це відповідає обчислювальній техніціR для PT а потім переносить результат.

У наведеному нижче коді безгольфічний опис наведений вище процес обчислення.

Безумовні (основні)

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

Спробуйте в Інтернеті!

Подальше вдосконалення рішення обчислює матрицю R в одному пропуску на основі R[i,j+ic]=P[i,j], де c=minP[i,j]0i+j.

Безлічі (покращені)

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

Спробуйте в Інтернеті!


3

APL (Dyalog Unicode) , 38 37 байт

1 байт збережено завдяки ngn , використовуючи +/∘⍴замість манекена літералу0

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

Спробуйте в Інтернеті!

(поїзд з ⎕io(індекс походження) встановлений як 0)

доданий правильний аргумент

, з'єднаний з

  • ⊂∘ укладений

  • перенесений правильний аргумент

s обчислюється з першого, з другогоr

¨ на кожному

+/∘⍴{ ... } виконайте наступну функцію з лівим аргументом

  • +/ сума

      • форма правильного аргументу, тобто отримати рядки + стовпці

і правильним аргументом буде кожна із доданих матриць.

⍺↑⍵і візьміть з лівого аргументу багато рядків з правого аргументу , якщо рядків не вистачає (що це буде тому, що рядки + стовпці> рядки), він зафіксований достатньою кількістю 0s

Обчислення підстановки або на замість або здійснюється обертанням стовпців на їх індекс, а оскільки укладене значеннями 0s, стовпці фактично попередньо бажаної кількості 0s.vxuyyx

обертати стовпці на

  • ⍉⍵ перенесені

  • кількість рядків, разом, ≢⍉⍵отримує кількість стовпців у

  • діапазон 0 .. кол-1

  • -заперечуючи, щоб повертати в іншому напрямку та за замовчуванням для , щоб у кінцевому рахунку отримати 0 ¯1 ¯2 ... - (кол-1), це автоматично векторизується через кожен стовпець так, щоб 0-й стовпець повертався на 0, 1-й на 1, ...

q← призначити цю змінну q

Тепер, щоб поділити многочлен на найбільшу потужність або , провідні рядки all-0 потрібно видалити.xy

∨/ зменшити на LCM для кожного рядка, якщо рядок є всі-0, це дає 0, інакше він дає додатне число

×отримайте його знак, 00і додатне число → 1

індекси тритій, тобто індекси 1s

вибираючи перший елемент, ⊃⍸просто отримує індекс першого 1

q↓⍨випадає з багатьох рядків q, знову ⎕io←0допомагає повернути правильне значення для випадання провідних рядків all-0

(функція виходу)

s вже досягнуто, щоб отримати друге значення, потрібно перенести черезr⊢∘⍉\


Інші підходи перелічені нижче.

⍝(⊢∘⍉\+/∘⍴{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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.