Самолет взорвать


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,

рs

Формат ввода / вывода

(То же, что и здесь .) Полиномы представлены в виде (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

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

п р s

Примеры без картинок

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 добавил это!
19

Ответы:


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

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

Функция принимает один numpy2D-массив в 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 а затем переносит результат.

В следующем негольфовом коде показан вышеуказанный процесс вычисления.

Ungolfed (Основной)

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,

Ungolfed (Улучшено)

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 байт сохранен благодаря СПП , используя +/∘⍴вместо манекена литерала0

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

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

(поезд с ⎕io(начало координат) установлен в 0)

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

, соединенный с

  • ⊂∘ закрытый

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

s вычисляется из первого, из второгоr

¨ на каждой

+/∘⍴{ ... } выполнить следующую функцию с левым аргументом

  • +/ сумма

      • форма правильного аргумента, т.е. получить строки + столбцы

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

⍺↑⍵и взять левый аргумент из множества строк из правого аргумента , если в строках не хватает (что будет, потому что строки + столбцы> строки), он дополняется достаточным количеством 0

Вычисление замены или вместо или выполняется путем поворота столбцов на их индекс, и, поскольку они заполнены нулями, к столбцам эффективно добавляется желаемое количество нулей.vxuyyx

вращать столбцы

  • ⍉⍵ транспонировать

  • количество строк, все вместе, ≢⍉⍵получает количество столбцов в

  • диапазон 0 .. количество -1

  • -Отрицательно, чтобы повернуть в другом направлении и по умолчанию для , чтобы в конечном итоге привести к 0 ¯1 ¯2 ... - (count-1), это автоматически векторизируется по каждому столбцу так, что 0-й столбец поворачивается на 0, 1 на 1, ...

q← назначить это переменной q

Теперь, чтобы разделить многочлен на наибольшую степень или , необходимо удалить ведущие строки из всех нулей .xy

∨/ уменьшить на LCM для каждой строки, если строка все-0, это дает 0, в противном случае это дает положительное число

×получить его знак, 00и положительный номер → 1

индексы истинностей, т.е. индексы 1с

выбрать первый элемент, ⊃⍸просто получает индекс первого 1

q↓⍨отбрасывает столько строк из q, снова ⎕io←0помогает вернуть правильное значение для отбрасывания ведущих строк все-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.