Я хотел бы создать тип Julia, который содержит поля, которые имеют фиксированное отношение друг к другу. Для иллюстрации рассмотрим тип Point, который представляет точку в 2 измерениях, и которая имеет поля, представляющие как ее декартовы (x, y), так и полярные (r, theta) координаты. Эти поля должны быть связаны соотношением r * cos (theta) = x и r * sin (theta) = y, и вы должны иметь возможность построить Точку, указав либо набор координат. Возникает вопрос: какой способ создать конструктор для этого типа?Построение типов со связанными полями в Julia
2
A
ответ
4
Если вы счастливы ввести 'sub'types, то вы можете сделать что-то вроде:
type Cartesian
x::Float64; y::Float64
end
type Polar
r::Float64; t::Float64
end
type Point
x::Float64; y::Float64
r::Float64; t::Float64
end
# secondary external constructors
Point(c::Cartesian) = Point(c.x, c.y, sqrt(c.x^2+c.y^2), atan2(c.y, c.x))
Point(p::Polar) = Point(p.r * cos(p.t), p.r * sin(p.t), p.r, p.t)
Point(x::Float64, y::Float64) = Point(Cartesian(x,y)) # ... etc
В качестве альтернативы, и в отношении Криса комментарий, один способ получить лучшее из обоих миры, заключается в создании функции генерации замыкания вместо простой функции преобразования, так что после ее инициализации она сохраняет состояние и может быть использована для безотказной конвертации в полярную.
3
Вот возможная реализация:
abstract CoordSys
abstract Cartesian <: CoordSys
abstract Polar <: CoordSys
transform(r, theta, ::Type{Polar}) = r*cos(theta), r*sin(theta)
transform(x, y, ::Type{Cartesian}) = sqrt(x^2+y^2), atan2(y, x)
immutable Point{T<:AbstractFloat}
x::T
y::T
r::T
theta::T
function Point(x, y, r, theta)
x_ctrl, y_ctrl = transform(r, theta, Polar)
if isapprox(x_ctrl, x, atol = 1e-15) && isapprox(y_ctrl, y, atol = 1e-15)
new(x, y, r, theta)
else
error("Coordinates are inconsistent")
end
end
end
# These constructors take the coordinate system as an additional argument
Point{T<:AbstractFloat}(x::T, y::T, C::Type{Cartesian}) = Point{T}(x, y, transform(x,y,C)...)
Point{T<:AbstractFloat}(r::T, theta::T, C::Type{Polar}) = Point{T}(transform(r,theta,C)..., r, theta)
# Convenience methods
Point{C<:CoordSys}(x::Real, y::Real, ::Type{C}) = Point(promote(float(x), float(y))..., C)
Point(x, y) = Point(x, y, Cartesian)
Он использует внутренний конструктор для обеспечения отношений по строительству и в immutable
типа для обеспечения их также после окончания строительства.
Смежные вопросы
- 1. Сортировка Gridview со связанными полями
- 2. Понимание неизменяемых композитных типов с полями изменяемых типов в Julia
- 3. Перечислимый вид со связанными текстовыми полями
- 4. Symfony2 Индексы Doctrine со связанными полями
- 5. Подтипы конкретных типов Julia
- 6. Извлечение типов параметров в Julia
- 7. Перемещение столбцов в gridview между полями шаблона и связанными полями
- 8. Как получить глубокие копии композитных типов Julia?
- 9. Построение лексикографически упорядоченных очередей приоритетов в julia
- 10. Хеширование со связанными списками
- 11. ViewModel со связанными объектами
- 12. Проблема со связанными списками
- 13. Fun со связанными списками
- 14. quicksort со связанными списками
- 15. Перекресток со связанными списками
- 16. Проблемы со связанными списками
- 17. Julia: Создание параллельных параллельных типов
- 18. RESTful API со связанными ресурсами
- 19. ASP.NET + DataBinder.Eval с несколькими связанными полями
- 20. Можно ли копировать экземпляры типов со схожими полями?
- 21. Haskell: определение правильного интерфейса для типов данных со многими полями
- 22. Использование массива абстрактных типов в Julia
- 23. Принцип двоичного представления типов данных в Julia
- 24. Создание просмотров пользовательских типов в julia
- 25. Построение np.array с перекрывающимися полями в DTYPE
- 26. yii2 ActiveForm со связанными данными
- 27. Исключение строк со связанными значениями
- 28. Форма Sharepoint со связанными списками
- 29. Нужна помощь со связанными списками;
- 30. Laravel findOrFail со связанными данными?
Как просто сохранить его в одну сторону и иметь функцию, которая дает координаты в другой форме? –
@ChrisRackauckas В целом (для типов, более сложных, чем пример Point, который я дал), связь между полями может быть сложной и дорогостоящей для вычисления. Лучше вычислить его один раз и связать с ним постоянно. – Yly
Это не так просто, потому что, возможно, память является более важным требованием, так что, как всегда, это зависит от приложения. Для этого вам нужно написать эти функции и просто использовать их в конструкторе. В чем проблема? –