Julia: Состояние внутренних продуктов в базе

Созданный на 15 янв. 2018  ·  146Комментарии  ·  Источник: JuliaLang/julia

Если пользователю необходимо определить собственные внутренние продукты для общих гильбертовых пространств, каково текущее состояние в Base для этого типа обобщения? https://github.com/JuliaLang/julia/issues/16573 — связанная, но менее общая проблема. Меня беспокоят новые типы, которые не являются массивами.

Я хотел бы предложить переименовать dot в inner или, возможно, предложить пользователям определить inner(x,y) как общий внутренний продукт между объектами x и y , включая случай с массивом:

inner(x::AbstractVector, y::AbstractVector) = dot(x, y)

Если изменение разумно, может ли оно быть частью Julia v1.0?

linear algebra

Самый полезный комментарий

Должно ли это быть закрыто, так как # 27401 теперь объединен?

Все 146 Комментарий

Не могли бы вы немного подробнее объяснить свой вариант использования и почему выгодно иметь его в базе, а не просто определять в своем пакете? Лучше всего будет конкретный пример. Вы ожидаете, что несколько определений inner в пакетах будут загружаться одновременно?

Я думаю, наличие формального интерфейса для этих математических пространств поможет пользователям лучше использовать систему типов. Например, я ожидаю, что методы кластеризации будут работать в любом метрическом пространстве. Если бы я мог определить свой тип с помощью внутреннего продукта, я бы выиграл Clustering.jl из коробки (после того, как пакет будет соответствующим образом исправлен). Многие другие алгоритмы, основанные на расстоянии или проекции, также могут быть обобщены.

В качестве конкретного примера, я столкнулся с этим ограничением сегодня, пытаясь определить геометрию для композиционных данных: https://github.com/juliohm/CoDa.jl . Я предпочел бы специализироваться на известной функции inner определено в Base, чем определить мой собственный интерфейс, о котором никто другой не узнает.

Почему бы не расширить dot для ваших типов гильбертова пространства? Я почти уверен, что он разработан с учетом общего внутреннего продукта.

Концепция скалярного произведения более строгая, чем концепция внутреннего продукта. В то время как последний определен для общих пространств, скалярное произведение определяется только тогда, когда существует понятие системы координат, определяемой конечным базисом. Семантика dot(x,y) — это x'*y , где x и y представляют координаты объектов в декартовом мире. В учебниках по математике термин скалярное произведение редко упоминается, поскольку авторы обычно заинтересованы в рассмотрении материала в более общих (не обязательно конечных или евклидовых) пространствах.

Чтобы еще больше различать, в гильбертовом пространстве со скалярным произведением <x,y> (или inner(x,y) ) объекты могут быть бесконечными, и семантика x'*y не применяется. Например, в функциональном анализе данных объектами являются функции f и g , а внутренний продукт обычно получается численным интегрированием: inner(f,g) = quadrature(f*g) . Называть эту операцию скалярным произведением вводит в заблуждение.

Другой пример, как я указал в своем пакете CoDa.jl , — это композиционные данные. Композиционные объекты лежат в симплексном мире, для которого операция x'*y не имеет смысла. Однако существует изометрическое преобразование (преобразование логарифмического отношения), которое можно использовать для сопоставления композиций с другой геометрией, где затем можно применить скалярное произведение с координатами. Работать с координатами необязательно, но это обычная практика в этой области. Результат может быть преобразован обратно в исходное пространство, где существуют объекты.

Я не вижу смысла в сохранении термина dot в языке, но если кто-то требует обратной совместимости, то обобщение inner(x::AbstractVector, y::AbstractVector) = dot(x,y) работает отлично.

Можете ли вы уточнить возражения против этого изменения?

Можете ли вы уточнить возражения против этого изменения?

Как правило, мы требуем достаточного количества обоснований для добавления новых общедоступных функций в Base, это возражение. Это может быть обеспечено пакетом InnerProducts . Зачем это нужно встраивать в сам язык? Это был первый вопрос, который @andreasnoack задал выше — он получил несколько расплывчатый ответ: «Я думаю, наличие формального интерфейса для этих математических пространств поможет пользователям лучше использовать систему типов». Нет причин, по которым интерфейс, определенный в пакете, менее формален, чем интерфейс в Base. Что дает наличие Base.inner , чего нет у InnerProducts.inner ? Это настоящий вопрос, на который можно было бы дать убедительный ответ, но я не знаю, каким может быть этот ответ, поэтому вопрос и задается.

Я не вижу хорошего аргумента для определения базовой математической концепции, такой как внутренние продукты, в другом месте, кроме Base. Язык, основной аудиторией которого являются люди, занимающиеся научными вычислениями, выиграет от правильной терминологии. Почему понятие norm определено в Base.LinAlg , а inner из той же когорты должно быть определено в пакете? Помимо этого несоответствия, в языке уже есть dot , что заставляет меня задаться вопросом, почему в нем должно быть что-то настолько конкретное, а не более общее понятие?

Итак, вы хотите, чтобы все возможные математические понятия были в базовом языке? Если что-то не определено в Base, это не заставляет людей использовать неправильную терминологию. Функция norm экспортируется из LinAlg , поскольку она определена и используется в LinAlg . Аналогично для dot . Вы предлагаете переименовать dot в inner ?

Итак, вы хотите, чтобы все возможные математические понятия были в базовом языке?

Я никогда этого не говорил.

Если что-то не определено в Base, это не заставляет людей использовать неправильную терминологию.

Я уверен, что это не так. Продвижение неправильной терминологии является проблемой. Люди, не имеющие математического образования, примут использование точки, потому что видят ее в Base. Использование термина «точечный» продукт для представления концепции внутреннего продукта неверно. Это также вредно для математического сообщества, которое время от времени пытается исправить эти шрамы, оставленные неправильной терминологией. Ученикам моего поколения постоянно приходится обращаться к старым книгам, чтобы понять правильную терминологию, этого не должно быть.

Вы предлагаете переименовать точку во внутреннюю?

На мой взгляд, это уже было бы значительным улучшением. См. все приведенные выше примеры функциональных и композиционных данных. Люди в этих сообществах никогда бы не использовали термин dot в своей работе. «точка» больше похожа на термин компьютерной науки, чем на что-либо еще.

Переименование dot в inner — это совсем другое предложение, чем добавление inner в Base в дополнение к dot . Это скорее вопрос о «правильной терминологии», который вам и другим специалистам по linalg придется решить, хотя я, кажется, припоминаю, что однажды мы обсудили это и пришли к выводу, что dot было правильным названием для того, что реализует эта функция.

Об этом было небольшое обсуждение в https://github.com/JuliaLang/julia/issues/22227 и https://github.com/JuliaLang/julia/pull/22220 .

Переименование точки в inner — это совсем другое предложение, чем добавление inner в Base в дополнение к dot.

Вот что я предложил в своем первом сообщении в этой теме:

Я хотел бы предложить переименовать точку во внутреннюю или, возможно, указать пользователям определять внутреннюю (x, y) как общий внутренний продукт между объектами x и y.

Я повторяю, что скалярный продукт — это неправильный термин для операции, которую я здесь обсуждаю. Внутреннее, внешнее, скалярное произведение... это математические объекты. «точечный продукт» — это вычислительный объект: он получает две последовательности чисел и выполняет x1*y1 + x2*y2 + ... xn*yn , бесполезную операцию в других математических пространствах.

Я сосредоточился на втором предложенном вами варианте, который, кажется, добавлял Base.inner с запасным вариантом для вызова Base.dot . Возможен любой вариант, но оба требуют некоторого обоснования: чтобы добавить новую операцию, нужна причина, по которой она не может быть просто в пакете (о чем была начальная часть этого обсуждения); чтобы переименовать, нужно решить, что dot — это неправильное имя, а inner — правильное (о чем разговор вроде бы и зашел).

@juliohm Вероятно, стоит (повторно) заявить, что в настоящее время предпринимаются активные усилия, направленные на сокращение Base и поощрение использования пакетов. В этом случае dot кажется правильным для всех типов, участвующих в линейной алгебре, представленных в стандарте Julia (т.е. Number и Array — так что да, есть определенное, известное , конечный базис во всех случаях - таким образом, я не думаю, что мы допустили ошибку в терминологии, хотя может быть и лучший выбор). Я не против этого предложения, но хотел указать на это, чтобы прояснить, почему вы можете испытывать некоторое «скрытое» сопротивление изменениям.

Также стоит иметь в виду, что довольно много новичков в Julia могут быть знакомы с скалярным произведением, но не с внутренним произведением (скажем, они немного изучали физику в университете, но не специализируются на математике), поэтому есть также некоторые причины сохраняйте dot (не говоря уже о том, что у нас есть инфиксный оператор, которому он соответствует - я полагаю, мы могли бы просто сопоставить его с inner , но это немного менее очевидно). У нас также нет функции outer или множества других возможных операций.

Таким образом, необходимо привести разумные доводы в пользу того, что поместить это в Base (или LinAlg ) строго лучше, чем поместить это в пользовательский пакет. Основная причина, по- видимому , заключается в том, чтобы предоставить интерфейс, которым могут делиться и расширять другие - это разумное резюме? Аргумент о том, чтобы позволить общему коду из Clustering.jl работать с вашим внутренним продуктом, кажется довольно убедительным. Кроме того, в контексте того, что мы, похоже, разделяем LinAlg на пакет stdlib, я подумал, что если бы мне пришлось создавать пакет под названием LinearAlgebra , я, вероятно, был бы счастлив включить inner функция для расширения другими.

Спасибо @andyferris за то, что поделились своими мыслями. Я очень ясно вижу сопротивление, что меня не очень волнует. Тем не менее, мне любопытно, как это конкретное предложение приводит к увеличению кода? Мне это кажется тривиальным изменением кода с существенным улучшением абстракции. Пример с Clustering.jl — лишь один из многих, подумайте о любом методе на основе ядра, который можно заставить работать с произвольными типами Julia, для которых существует понятие внутреннего продукта. В MultivariateStats.jl их предостаточно.

Что касается комментария о разделении LinAlg на отдельный пакет, я согласен, что это хорошее место для инкапсуляции математических продуктов. Я предполагаю, что этот пакет LinearAlgebra будущего будет импортирован в сеанс Julia по умолчанию, и поэтому все пользователи будут иметь доступ к концепции inner , outer и т. д. немедленно.

Да, все стандартные библиотеки собраны вместе с образом системы Julia и доступны по умолчанию. По крайней мере, для серии v1.x никому не нужно будет вводить using LinAlg (я не думаю, что она будет переименована в LinearAlgbebra , кстати, я просто придумал это как гипотетический конкурент) .

Чтобы уточнить, он будет загружен стандартной Джулией, поэтому вам не нужно ничего устанавливать, но вам все равно придется написать using LinAlg , чтобы получить имена, которые он экспортирует.

Вот где это становится странным, верно, поскольку мы получим методы * и так далее без using LinAlg ? (другими словами, LinAlg — это тип пирата).

Да, в основном здесь нам придется подвести черту: Base должен определить столько функций линейной алгебры, сколько необходимо, чтобы сделать LinAlg не пиратским, поэтому matmul определен в Base, потому что Array и * оба есть. Однако там живут причудливые матричные типы и небазовые операции.

Позвольте мне привести вам конкретный пример и спросить, как бы вы решили это с текущим интерфейсом, возможно, это прояснит для меня ситуацию.

Цель состоит в том, чтобы выполнить факторный анализ с композиционными данными. У меня есть тип под названием Composition и внутренний продукт в пространстве композиций. Я собираю много образцов (например, образцы горных пород) и помещаю их все в большой Vector{Composition} (например, состав = %вода, %зерно, %воздух). Теперь я хочу вызвать алгоритм факторного анализа, реализованный в другом пакете (например, MultivariateStats.jl) для этого вектора данных. Как бы вы реализовали это в общем, если бы продукт на inner не был импортирован по умолчанию?

Из последних комментариев я понял, что и MultivariateStats.jl, и CoDa.jl должны зависеть от LinAlg.jl. Зависимость в MultivariateStats.jl предназначена только для включения имени inner в область видимости. Зависимость в CoDa.jl заключается в определении метода для inner , который может быть вызван MultivariateStats.jl. Это то, что вы предлагаете?

Кажется, Composition{D} — это размерное векторное пространство D при + и * .

У меня возникло бы искушение определить двойственное векторное пространство.

Итак, вы можете определить adjoint(::Composition) -> DualComposition и *(::DualComposition, ::Composition) -> scalar (в настоящее время inner ). DualComposition не нужно было бы ничего делать, кроме как держать внутри Composition .

Первое предложение в https://en.wikipedia.org/wiki/Dot_product , кажется , предполагает, что dot может быть операцией на любых двух итерируемых объектах. Мы могли бы сделать его рекурсивным и определить для Number , а также определить inner как абстрактную функцию линейной алгебры, которая перекрывается для Number и AbstractArray .

Спасибо, @andyferris , я ценю ваши мысли о двойном пространстве. Однако я бы не стал полагаться на новый тип для этой задачи. Окончательное решение излишне сложно.

Мне интересно понять, почему что-то вроде:

inner(x,y) = sum(x.*y)
norm(x) = sqrt(inner(x,x))

export inner, norm

не приветствуется в Базе? Я предполагаю, что это все, что требуется для определения общих имен функций, чтобы пользователи языка могли специализироваться на них. Имейте в виду, что я задаю эти вопросы с искренним интересом понять точку зрения основных разработчиков. Я хочу сказать это, прежде чем разговор снова пойдет в неправильном направлении.

С точки зрения человека, интересующегося математикой в ​​целом, кажется неестественным, что эти понятия не экспортируются по умолчанию, а вместо этого определяются внутри LinAlg . Я думаю о LinAlg как о реализации этих концепций высокого уровня для типов массивов. Возможно, вся моя работа не требует линейной алгебры для массивов, но я все же мог бы извлечь выгоду из концепции внутреннего продукта между пакетами (например, MultivariateStats.jl, Clustering.jl). Кроме того, я могу не захотеть иметь LinAlg в качестве зависимости в моем пакете, потому что это не так.

Если я могу подчеркнуть это дальше, существует концепция внутреннего продукта, которая не зависит от массивов. Эта концепция представлена ​​оператором export inner в Base. Существует реализация внутренних продуктов для массивоподобных объектов, представляющих координаты inner(x,y) = sum(x.*y) . Эта операция может быть определена как запасной метод в Base, как указано выше, если это необходимо.

Другой пример варианта использования — методы Крылова. Если у вас есть, например, функциональные пространства со скалярными произведениями, то вы можете использовать методы Крылова для аппроксимации линейной задачи или собственной задачи в небольшом конечномерном подпространстве этого бесконечномерного функционального пространства.

У меня тоже есть свои объекты, которые образуют векторное/гильбертово пространство, но не являются частью <: AbstractArray . По аналогии с тем, что массивы с рангом N>1 также образуют векторные пространства и могут использоваться в качестве «векторов» в методах Крылова, я пришел к использованию vecdot и vecnorm являющееся обобщенным понятием внутреннего продукта и нормы. Поэтому я разработал пакет с методами Крылова, который использует функции как линейные операторы и где «векторы могут быть любого типа, при условии, что объекты этого типа поддерживают vecdot , vecnorm и несколько другие вещи ( scale! , zero , ...). Но, возможно, это злоупотребление тем, что имелось в виду под этими понятиями в Base, поэтому было бы хорошо исправить здесь правильный интерфейс.

Правильно — vecdot можно переименовать в inner .

(Теперь я смутно задаюсь вопросом, действительно ли norm следует называть matrixnorm для матриц с norm , всегда совпадающим с inner . Кажется, что, возможно, есть два разных что-то происходит с norm , что вызывает некоторые трудности с его обобщением)

На самом деле, для общих векторных объектов также полезно запрашивать размерность векторного пространства (например, чтобы убедиться, что размерность Крылова не должна быть больше, чем размерность полного пространства в моем примере использования). Пример вложенных массивов показывает, что length здесь не подходит, т. е. для таких случаев должно быть какое-то рекурсивное понятие длины.

Теперь для примера использования вложенных массивов в качестве общего вектора, vecdot и vecnorm в некоторых случаях даже не являются правильным понятием внутреннего продукта и нормы, как обсуждалось в #25093, т.е. не вызывая рекурсивно vecdot и vecnorm . Моя интерпретация этих функций как общего внутреннего продукта и функции нормы - это то, что вызвало # 25093, но кажется, что эти функции могли быть не такими, как предполагалось (не знаю, для чего они были предназначены).

Так что я согласен с тем, что здесь нам нужен согласованный интерфейс для использования во всех пакетах, который, следовательно, должен находиться в центральном месте (вероятно, не в Base, но определенно в стандартной библиотеке, например, такой, что нужно сделать using VectorSpaces ). Что касается именования, я вижу два варианта:

Вариант 1 (моя интерпретация до сих пор):
префикс vec указывает на свойство этого объекта при интерпретации его как общего вектора, следовательно

  • vecdot и vecnorm для вложенных массивов исправлены (PR #25093)
  • добавлено новое определение veclength

Вариант 2 (вероятно, лучше): использовать более математически правильные имена

  • inner
  • dimension
  • Но что делать с norm ?

И, наконец, просто пингуйте @stevengj , так как у него наверняка есть несколько полезных комментариев; мои извинения, если это неудобно.

Имя — наименее интересная часть всего этого. У меня нет проблем с использованием функции dot для ссылки на общий скалярный продукт для произвольных гильбертовых пространств. Мало того, что нет другого разумного значения, например, для «точечного произведения двух функций», довольно часто можно увидеть «точечный продукт функций» в неформальном использовании, особенно в педагогических условиях, где кто-то пытается подчеркнуть аналогию с конечномерным вектором. пространства.

@juliohm , inner(x,y) = sum(x.*y) вообще не является внутренним продуктом, так что это было бы довольно ужасным запасным вариантом для использования в базе.

Но dot уже не вычисляет правильный скалярный продукт (фактически терпит неудачу) для различных объектов в базе, которые ведут себя как векторы, например массивы с рангом N>1 или вложенные массивы (вложенные векторы являются единственным случаем там, где это работает правильно). Кроме того, общее имя norm становится двусмысленным для матриц, потому что я согласен с текущим выбором, что это возвращает индуцированную норму, но иногда также требуется «векторная норма» (норма Фробениуса).

Следовательно, мое предложение с наименьшим воздействием будет заключаться в том, чтобы отказаться от семантики vecnorm(x) = norm(vec(x)) и скорее интерпретировать vecnorm(x) как «для x , являющегося объектом некоторого универсального типа, который ведет себя как векторное пространство, вычислить соответствующую векторную норму x " (и аналогично с vecdot ). Хотя это сдвиг в интерпретации (и, следовательно, в документации), фактическая реализация/действие для объектов в Base не будет сильно отличаться (PR # 25093) и даст тот же результат в большинстве случаев (массивы ранжирования N скаляров или векторов). Функция veclength(x) , которая возвращает соответствующую размерность векторного пространства x , дополнит интерфейс.

Затем пользовательские пакеты должны научиться реализовывать эти функции, когда они определяют новые типы, которые ведут себя как векторы.

довольно часто можно увидеть «точечный продукт функций» в неформальном использовании, особенно в педагогических условиях, где кто-то пытается подчеркнуть аналогию с конечномерными векторными пространствами.

Пожалуйста, не говорите, что имя неважно, потому что это так. Повторю в n-й раз: скалярный продукт и скалярный продукт — не одно и то же. В любом серьезном материале, раскрывающем работу с абстрактными гильбертовыми пространствами, никогда не будет использоваться «точка». Если вы предпочитаете доверять Википедии, а не моим словам, вот определения, скопированные и вставленные:

Внутренний продукт

В линейной алгебре пространство внутреннего произведения — это векторное пространство с дополнительной структурой , называемой внутренним произведением. Эта дополнительная структура связывает каждую пару векторов в пространстве со скалярной величиной , известной как внутреннее произведение векторов.

Скалярное произведение

В математике скалярное произведение или скалярное произведение — это алгебраическая операция , которая берет две последовательности чисел одинаковой длины (обычно вектора координат) и возвращает одно число.


Это сопротивление улучшению терминологии и математической согласованности языка демотивирует. Сколько бы фактов я вам ни представил, сколько бы примеров и вариантов использования не было, кроме «меня все устраивает с точкой» нет контраргумента.

@juliohm , терминология - это вопрос условности, а не правильности. Я согласен с тем, что при формальном использовании гильбертовых пространств, особенно бесконечномерных, термин «внутренний продукт» используется практически исключительно. Но, как я уже сказал, если вы погуглите «функции точечного произведения», вы также найдете множество неформальных вариантов использования этой терминологии. Если вы скажете «возьмите скалярное произведение двух элементов этого гильбертова пространства», каждый математик будет знать, что вы имеете в виду скалярное произведение, даже для бесконечномерных пространств, так что реальной опасности путаницы нет, потому что другого нет. стандартное обобщение термина «точечный продукт». Вот почему я не считаю споры о правописании «точка» и «внутренний» центральным вопросом.

Здесь важно определиться с желаемой семантикой и набором функций, которые типы должны реализовывать, если они определяют новое гильбертово или банахово пространство. В настоящее время, если вы хотите определить тип, представляющий новое гильбертово пространство, вы, вероятно, должны определить dot и norm (поскольку у нас в настоящее время нет запасного варианта для последнего), и я думаю, что adjoint , если вы хотите отобразить объект с двойным пространством.

Как говорит @Jutho , все это усложняется случаем массива массивов, поскольку есть несколько возможных вещей, которые могут понадобиться. Поскольку не существует стандартизированных имен для всех возможных семантик, трудно найти имена/семантики, которые удовлетворили бы всех. См. #25093 для обсуждения семантики vecdot . У меня самого здесь нет хорошего ответа.

Некоторые возможности здесь

  1. Сумма x[i]' * y[i] . В настоящее время это dot(x,y) . Не внутренний продукт для векторов матриц (где он дает матрицу) и в настоящее время не определен для многомерных массивов.
  2. Сумма dot(x[i], y[i]) , в том числе для многомерных массивов, и conj(x)*y для Number . В настоящее время это vecdot(x,y) .
  3. Некоторая функция, например inner(x,y) , определена как всегда истинный внутренний продукт, а для массивов она составляет сумму inner(x[i],y[i]) — по сути, «рекурсивная vecdot», которую хочет @Jutho . Но тогда для матриц A это скалярное произведение несовместимо с индуцированной нормой norm(A) , которая является нашим текущим определением norm . Чтобы исправить это, нам пришлось бы изменить norm(A) для матриц, чтобы они по умолчанию соответствовали норме Фробениуса, что потенциально могло бы иметь далеко идущие критические изменения.

Вопрос (частично обсуждаемый в № 25093) заключается в том, нужны ли нам все три из них в базе, или мы можем обойтись двумя (и какими двумя, и как мы их называем). Насколько я понимаю, предложение @Jutho состоит в том, чтобы исключить вариант 2 в Base, а затем использовать vecdot и vecnorm для варианта 3. Тогда у нас есть настоящий внутренний продукт, но терминология довольно уникален для Джулии и немного странен, например, для бесконечномерных гильбертовых пространств. Конечно, это не был бы конец света.

Другая возможность (отчасти независимая от того, что мы делаем с vecdot ) состоит в том, чтобы вернуться (назад) к требованию, чтобы dot было истинным внутренним продуктом. т.е. исключить поведение 1 и сделать dot(x::AbstractVector, y::AbstractVector) равным sum dot(x[i],y[i]) . По-прежнему не определяйте его для многомерных массивов (чтобы оставаться в соответствии с norm ).

Моя текущая личная склонность состояла бы в том, чтобы определить dot как истинное внутреннее произведение (которое должно быть совместимо с norm ), изменив его на сумму dot(x[i],y[i]) для векторов (т.е. изменив случай вектора матриц) и продолжает не определять его для многомерных массивов. Затем определите vecdot для рекурсивного вызова vecdot , как предлагает @Jutho , с запасным вариантом vecdot(x,y) = dot(x,y) . Наконец, скажем, что новые типы "гильбертова пространства" должны определять dot и norm . Это кажется мне наименее разрушительным и наиболее понятным изменением.

(Резервный вариант norm(x) = sqrt(real(dot(x,x))) также возможен, хотя он несколько опасен, поскольку уязвим для ложного переполнения. Обратите внимание, что мы не можем использовать sqrt(dot(x,x)) в качестве резервного варианта по техническим причинам: нам нужен Результат Real , а не результат Complex .)

Спасибо @stevengj за эту информативную реакцию. Всего один небольшой комментарий:

с запасным вариантом vecdot(x,y) = dot(x,y) . Наконец, скажем, что новые типы "гильбертового пространства" должны определять dot и norm .

Есть две проблемы с этим. Запасной вариант vecdot(x,y) = dot(x,y) не может существовать, поскольку vecdot уже принимает аргументы Any для работы с общими итераторами. Вторая проблема заключается в том, что если dot и norm выставлены как истинное скалярное произведение и норма, которые должен определять любой вектор, такой как пользовательский тип, то даже при написании пакета с, например, методами Крылова, которые должен работать с полностью универсальными векторными типами, он все равно не будет работать в случае, когда пользователь хочет использовать вложенные или многомерные массивы в качестве векторных объектов. Поэтому я бы сказал, что vecdot и vecnorm являются общим скалярным произведением и нормой векторных объектов. Это также хорошо согласуется с тем фактом, что для матриц большинство людей действительно ожидает, что norm будет индуцированной нормой матрицы/оператора.

Что касается фактического варианта использования (чтобы показать, что это не какой-то исключительный случай). Стохастические матрицы имеют наибольшее (Перрона-Фробениуса) собственное значение, для которого соответствующий собственный вектор представляет собой распределение вероятностей с фиксированной точкой. В его квантовом обобщении распределение вероятностей обобщается на положительно определенную матрицу (матрицу плотности), и такая матрица является неподвижной точкой (собственный вектор, соответствующий наибольшему собственному значению) полностью положительного отображения, т. е. отображения rho -> sum(A[i] rho A[i]^\dagger for i = 1:N) где, таким образом, rho — матрица плотности, а A[i] — матрица для каждого i (известного как операторы Крауса, представляющие полностью положительное отображение). Для больших размеров матрицы метод Арнольди идеально подходит для нахождения матрицы плотности с фиксированной точкой.

Моя текущая личная склонность заключалась бы в том, чтобы определить точку как истинный внутренний продукт (который должен соответствовать норме), изменив его на сумму точек (x [i], y [i]) для векторов. Наконец, скажем, что новые типы «гильбертова пространства» должны определять точку и норму.

Это уже огромное улучшение. Документирование dot inner в Base позволит пользователям, по крайней мере, определять свои собственные пространства без импорта ненужных библиотек. Я не в восторге от именования, но, по крайней мере, функционал будет доступен для тех, кто в нем нуждается.

Да, я думаю, было бы неплохо иметь задокументированный интерфейс для реализации типов в "гильбертовом пространстве".

Конечно, если подумать об этом универсальном интерфейсе для векторных пространств, если он включает norm , как было предложено выше, то это должно быть нормой Фробениуса для матриц (и обобщать для многомерных массивов, поскольку все массивы являются элементами вектора). пространство). В этом случае нам понадобится отдельная функция "операторная норма" для матриц ( matnorm или opnorm или что-то в этом роде, или аргумент ключевого слова для norm ...).

@andyferris , обратите внимание на мой последний комментарий. norm и dot не могут стать общим интерфейсом гильбертова пространства, поскольку они даже не работают с векторными объектами в Julia, такими как многомерные массивы и вложенные массивы. Следовательно, vecdot и vecnorm являются «лучшими» (в смысле наименее ломающихся) кандидатами на это.

Возрождение этой темы, которую я считаю весьма актуальной для того типа математики, который я ожидаю сделать с языком в ближайшем будущем. Есть ли консенсус относительно того, что будет сделано для улучшения общности и семантики внутренних продуктов?

Вот часть моей личной математической онтологии, касающейся продукта.
Если бы это могло помочь освежить память / прийти к консенсусу

Бонус: нет ссылок на википедию

На данный момент предложение @Jutho в # 25093 кажется наименее разрушительным изменением, хотя терминология vec* немного странная для меня в этом контексте.

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

Я также согласен с тем, что терминология vec* странная.

Я согласен, в качестве альтернативы vecdot мы могли бы ввести новый метод inner , но я не знаю подходящего названия для «замены» vecnorm . На самом деле, я не считаю vecnorm такими уж плохими, векторная норма — это устоявшийся и явный термин для той операции, которую мы хотим.

Основная проблема здесь связана с матрицами и многомерными массивами, для которых обычный norm(A) не соответствует скалярному произведению, а также с массивами массивов, как обсуждалось выше. В этих случаях требуется некоторое устранение неоднозначности (например, vec* или fro* ), чтобы указать, какой внутренний продукт предназначен.

У вас может быть функция inner , которая по умолчанию имеет значение vecdot , но немного глупо иметь два имени для одной и той же функции, и по-прежнему существует проблема того, что называть нормой.

Я также нахожу имя vecdot странным, на самом деле я даже не знал, что оно существует, и сделал для него свою собственную функцию... под названием inner .

Насколько я понимаю, мы можем просто отказаться от нечетного vecdot в пользу inner и дать ему семантику внутреннего продукта, чтобы пользователи могли реализовать свои собственные пространства.

Что касается norm , этого я не знаю. Я открыл этот вопрос для обсуждения внутренних продуктов, возможно, для обсуждения состояния норм в Базе будет уместным другой вопрос.

Я предполагаю, что мы могли бы иметь inner(x,y) и innernorm(x) = sqrt(inner(x,x)) (с оптимизированными особыми случаями, чтобы избежать переполнения) вместо vecdot и vecnorm . innernorm немного необычно, но достаточно ясно в контексте.

Недурно за это изменение. Имена inner и innernorm понятны и соответствуют понятиям. Я бы хотел, чтобы они смогли добраться до Джулии v1.0.

inner и innernorm мне кажутся нормальными.

Я бы все же сказал, что, по моему мнению, наша функция norm не очень хорошо вписывается в общую систему функций и диспетчеризации Джулии и в то, что я бы назвал «четкими интерфейсами», где диспетчеризация не должна выполняться. семантические варианты, просто варианты реализации. Лично я бы предпочел, чтобы мы могли сказать, что " norm возвращает норму элемента векторного пространства", где матрицы и линейные операторы по-прежнему являются элементами векторных пространств (вы можете добавить их и умножить на скаляр) . Мы могли бы также иметь, например, " opnorm возвращает операторную норму линейного оператора" (или matnorm или что-то еще).

На данный момент у нас есть " norm возвращает норму элемента векторного пространства, если только этот элемент не является также линейным оператором, и в этом случае вместо этого мы дадим вам норму оператора". Я лично считаю, что отправка никогда не должна удивлять.

Т.е. я бы предпочел одну функцию, которая всегда выполняет векторную норму, и другую функцию, которая всегда выполняет операторную норму, и никакой функции, которая пытается выполнять и то, и другое.

Нравится даже лучше @andyferris :+1: Конкретные нормы, которые не являются нормами, индуцированными внутренним продуктом в пространстве, могут иметь более конкретное название. Имя norm будет означать ровно norm(x) = sqrt(inner(x,x)) и может быть переопределено по мере необходимости для типов пользователей.

Лично я бы предпочел, чтобы мы могли сказать: « norm возвращает норму элемента векторного пространства».

Текущая функция norm удовлетворяет этому определению. Для матриц он вычисляет индуцированную (операторную) норму, которая является вполне допустимой нормой для векторного пространства . (Векторные пространства вообще не должны иметь внутренних продуктов или норм.)

Вы можете немного запутаться в определении «нормы», если считаете, что операторная норма не является «нормой векторного пространства».

Это также полезное различие между norm и innernorm . Если вы определяете norm , я бы сказал, что это подразумевает только то, что у вас есть банахово пространство (или, по крайней мере, нормированное векторное пространство). Если вы определяете innernorm , это означает, что у вас есть гильбертово пространство (или, по крайней мере, внутреннее пространство произведения) и что эта норма согласуется с inner .

Например, для адаптивного численного интегрирования (ala quadgk) требуется только нормированное векторное пространство, а не пространство внутреннего произведения.

Конечно, извините, возможно, я был слишком неточен в своих выражениях. Очевидно, что для векторного пространства существует много допустимых норм, включая различные операторные нормы.

Я предполагаю, что я имею в виду, что , может быть, я предпочел бы, чтобы выбор нормы был более явным, чем неявным? И что, если вы используете ту же функцию (например, без дополнительных аргументов ключевого слова), вы получаете «ту же» норму, и в этом случае евклидова кажется несколько оправданным выбором для AbstractArray .

Это также полезное различие между norm и innernorm . Если вы определяете норму, я бы сказал, что это подразумевает только то, что у вас есть банахово пространство (или, по крайней мере, нормированное векторное пространство). Если вы определяете innernorm , это означает, что у вас есть гильбертово пространство (или, по крайней мере, внутреннее пространство продукта) и что эта норма согласуется с inner .

Это кажется разумным, но мне все равно интересно, почему, если у объекта есть innernorm , ему нужен другой norm ? В качестве альтернативы я бы предложил, чтобы интерфейс для банахова пространства требовал norm , в то время как интерфейс для внутренних пространств продукта предоставлял бы как norm , так и inner . Затем эти функции можно использовать в универсальном коде, который ожидает объекты банаховых пространств или пространств внутреннего продукта в зависимости от обстоятельств (EDIT: с мыслью, что код, работающий в банаховых пространствах, автоматически также будет работать в пространствах внутреннего продукта).

Я думаю, вы предлагаете, чтобы norm(x) всегда относились к какой-то поэлементной евклидовой норме (т. е. к норме Фробениуса для матриц), т.е. в основном к тому, что vecnorm теперь представляет собой по модулю рекурсивного случая. В этом случае мы могли бы также переопределить dot(x,y) как соответствующий скалярный продукт ( inner тоже работает, но dot имеет преимущество инфиксного варианта x ⋅ y ).

В принципе, я согласен с этим, но это будет кардинальное изменение, и может быть немного поздно до 0.7, чтобы внести это…

Является ли L2 хорошим значением по умолчанию для больших размеров?
В этой статье речь идет о расстоянии, но может быть и о норме.
https://stats.stackexchange.com/questions/99171/why-is-euclidean-distance-not-a-good-metric-in-high-dimensions

В этом случае мы могли бы также переопределить точку (x, y) как соответствующий внутренний продукт (внутренний тоже работает, но точка имеет преимущество инфиксного варианта x ⋅ y)

Можем ли мы полностью избавиться от dot ? Инфиксная нотация не должна быть связана с существованием функции с именем dot . Просто определите инфикс с помощью метода inner для массивов Джулии. Это возможно?

Это действительно то, что это такое, скалярное произведение: удобное обозначение x ⋅ y для скалярных произведений между векторами x и y в R ^ n с евклидовой геометрией.

@stevengj Думаю, это хорошее резюме, да.

@ o314 Является ли L2 хорошим значением по умолчанию для высокой размерности? Возможно, нет, но я бы действительно возненавидел, если бы, например, норма, выбранная norm(v::AbstractVector) , зависела от length(v) :) В равной степени мне бы не хотелось сомневаться в том, является ли моя матрица или многомерный массив «слишком большой для L2» - я бы предположил, что, возможно, это должно быть явно отмечено пользователем?

@juliohm Это определенно возможно, хотя, как уже упоминалось, это критические изменения, которые мы предлагаем. (Опять же, по модулю того, что делать в рекурсивном случае и более ранних дискуссиях о возможных различиях между inner и dot ).

@stevengj , моя интерпретация того, что имел в виду @andyferris , заключается в том, что из-за утиной печати трудно решить, хочет ли пользователь интерпретировать объект как вектор (и использовать соответствующий вектор p -норму) или как оператор (и вычислить индуцированную p -норму). Поэтому я думаю, что нет другого выбора, кроме как явно указать, какое поведение требуется. Текущий подход немного странен в том смысле, что norm пытается неявно угадать, выбрать ли векторную норму или индуцированную норму на основе входных данных, а vecnorm — это способ явно указать, что вы хотите векторная норма (именно поэтому я не нахожу vecnorm таким плохим именем). Более радикальным изменением было бы сделать так, чтобы norm всегда по умолчанию использовало векторную норму и явно указывало, когда вы хотите индуцированную норму, используя аргумент (ключевое слово) или вообще другую функцию.

С другой стороны, я также не возражаю против имени innernorm , которое явно указывает на то, что это норма, основанная на внутреннем продукте (т.е. всегда p=2 в евклидовом случае). Мне трудно судить, должны ли пользовательские объекты (vec)norm поддерживать необязательный аргумент p как часть интерфейса, поскольку в некоторых моих случаях использования просто p=2 вычислить.

Это действительно то, что это такое, скалярное произведение: удобное обозначение x ⋅ y для скалярных произведений между векторами x и y в R ^ n с евклидовой геометрией.

Я согласен с этим в том смысле, что не припоминаю, чтобы когда-либо видел обозначение x ⋅ y в контексте общих (например, комплексных) векторных пространств. Я думаю, что в таких случаях используется только математическая запись (x,y) или запись Дирака < x | y > . В электромагнетизме часто используется E ⋅ B для векторов в трехмерном евклидовом пространстве, и даже если используется комплексное обозначение (т.е. вектора), это не подразумевает комплексного сопряжения. При необходимости комплексное сопряжение в таких случаях указывается явно. Поэтому я не возражал бы, если бы dot просто превратилось sum(x_i * y_i) без комплексного или эрмитова сопряжения, а inner стало бы правильным скалярным произведением для общих пространств внутреннего произведения. К сожалению, это невозможно сделать за один цикл выпуска.

Является ли L2 хорошим значением по умолчанию для высокой размерности? Возможно, нет, но мне бы очень не понравилось, если бы, например, норма, выбранная с помощью norm(v::AbstractVector), зависела от длины(v) :) В равной степени мне не хотелось бы сомневаться в том, является ли моя матрица или многомерный массив «слишком большой для L2» - я бы предположил, что, возможно, это должно быть явно отмечено пользователем?

Я работаю в мире BIM , где мы работаем с 2d и 3d, но также 4d, 5d, 6d может быть 7d. Мы никогда не идем дальше. В любой момент мы знаем, в каких измерениях мы работаем и какой алгоритм задействован. Этого достаточно.

Не могу выразить точку зрения людей, которые работают в ОД, информационном поиске и т.д. Там норминфа может быть лучше. Что важно в моем POV, так это угадываемость и стабильность. Я совсем не удивлюсь, если людям в ML нужны разные дефолты для своих вещей. Если не будет путаницы. Например. это определяется явно и статически во время компиляции. Это даже роскошь, если он остается стабильным и непротиворечивым во время применения алгоритмов.

Вдохновлено массивом: аналогично Не полностью реализовано и протестировано.

norm2 = x -> x |> inner |> sqrt
norminf = ...
NMAX = 10
for N in 1:NMAX
    <strong i="13">@eval</strong> begin norm(a::Array{T,N}) where {T} = norm2 end
end
norm(a::Array{T,n}) where {T} = norminf

Можем ли мы полностью избавиться от точки? Инфиксная нотация не должна быть связана с существованием функции с именем точка. Просто определите инфикс с помощью внутреннего метода для массивов Джулии. Это возможно?

norm(x::AbstractVector, p::Real=2) = vecnorm(x, p) # https://github.com/JuliaLang/julia/blob/master/stdlib/LinearAlgebra/src/generic.jl#L498
vecdot(x::Number, y::Number) = conj(x) * y # https://github.com/JuliaLang/julia/blob/master/stdlib/LinearAlgebra/src/generic.jl#L657
dot(x::Number, y::Number) = vecdot(x, y) # https://github.com/JuliaLang/julia/blob/master/stdlib/LinearAlgebra/src/generic.jl#L659
function dot(x::AbstractVector, y::AbstractVector) # https://github.com/JuliaLang/julia/blob/master/stdlib/LinearAlgebra/src/generic.jl#L677

# Call optimized BLAS methods for vectors of numbers
dot(x::AbstractVector{<:Number}, y::AbstractVector{<:Number}) = vecdot(x, y) # https://github.com/JuliaLang/julia/blob/master/stdlib/LinearAlgebra/src/generic.jl#L698

Точка/векдот подразумевает использование сопряжения и решение, когда перейти к BLAS. это должно быть обработано где-то. Но это должно быть управляемо в одном пространстве имен.

Является ли L2 хорошим значением по умолчанию для высокой размерности? Возможно, нет

L2 также является наиболее распространенной нормой для бесконечномерных пространств (например, функций). Я думаю, что это разумное значение по умолчанию для любого векторного пространства.

Очевидно, вы хотите, чтобы были доступны и другие нормы. Если мы переопределим norm(x) как поэлементно L2 везде, где это возможно, то norm(x, p) будет поэлементно Lₚ, и нам потребуется какая-то другая функция (например, opnorm ) для соответствующего индуцированного/ операторские нормы.

Я согласен с этим в том смысле, что не помню, чтобы когда-либо видел обозначение x ⋅ y в контексте общих (например, комплексных) векторных пространств.

Я дал несколько цитат в другой ветке, IIRC (например, BLAS использует dot для комплексного скалярного произведения, и вы можете найти педагогические источники, даже используя термин для внутренних продуктов функций). Сам термин «внутренний продукт» обычно вводится как «обобщение скалярного продукта». Я не думаю, что кого-то слишком удивит нотация dot для евклидова скалярного произведения, а иметь инфиксный оператор удобно.

Конечно, мы могли бы оставить dot как есть и ввести inner , но я думаю, что это создало бы запутанную дихотомию — в наиболее распространенных случаях функции были бы эквивалентны, но в нечетных случаях (например, массивы матриц) они будут отличаться.

Но опять же, может быть немного поздно вносить критические изменения, поэтому нам, возможно, придется прибегнуть к innernorm и inner . В любом случае, кто-то должен был бы создать PR как можно скорее.

Если разумная мера консенсуса сформируется, я, возможно, смогу выделить часть полосы пропускания для изучения реализации в соответствующем (коротком) временном масштабе, включая потенциальные критические изменения. Я ценю стремление прояснить семантику этих операций и дать им явные имена. Лучший!

Я вижу два основных варианта:

  • Не ломается, добавляет функцию: inner(x,y) и innernorm(x) . Замена vecdot и vecnorm и рекурсия для массивов массивов.

  • Нарушение: измените norm(x,p=2) , чтобы он всегда был поэлементным и рекурсивным, заменив vecnorm , и введите новую функцию opnorm для операторной/индуцированной нормы. Сделайте dot(x,y) соответствующим поэлементным скалярным произведением, заменив vecdot . (Альтернатива: переименовать в inner , но хорошо иметь инфиксный оператор, и раздражает наличие одновременно dot и inner .)

Если бы я разрабатывал вещи с нуля, я бы предпочел 2, но это может быть слишком разрушительно, чтобы молча изменить значение norm .

Одним из промежуточных вариантов может быть определение inner и innernorm (устаревающие vecdot и vecnorm ) и прекращение поддержки norm(matrix) до opnorm . Затем в версии 1.0 повторно введите norm(matrix) = innernorm(matrix) . Таким образом, люди могут в конечном итоге просто использовать inner и norm , а мы оставляем dot в качестве текущего нечетного зверя для векторов-массивов (совпадающих с inner ).

Одна странность в отношении innernorm заключается в том, что вам нужен способ указать «элементарные» нормы L1 или Linf, но ни один из них не соответствует внутреннему продукту, поэтому innernorm(x,p) является немного неправильным.

Мне нравится ваш промежуточный вариант.

Как указано выше, мне нравится имя innernorm(x) , потому что оно подразумевает p=2 и не должно быть второго аргумента. У меня есть объекты, для которых я знаю только, как вычислить норму внутреннего продукта. Но с текущим (vec)norm мне неясно, является ли аргумент p частью предполагаемого базового интерфейса, и поэтому я не знаю, опускать ли второй аргумент или поддерживать это, но затем явно проверьте p != 2 и выдайте ошибку.

Но я вижу проблему в том, что на промежуточном этапе вашего предложения нет нерекомендуемого способа сделать vecnorm(matrix, p!=2) .

Мне также нравится промежуточный вариант — мы определенно хотим пройти через надлежащий цикл устаревания норм, а не вносить немедленное критическое изменение. (Как пользователя меня пугают критические изменения, но я вижу, что исправление устаревших версий в моем коде для версии 1.0 похоже на инвестиции в чистый, понятный код на будущее).

Нужны ли нам на самом деле innernorm или мы можем просто использовать vecnorm сейчас (и отказаться vecnorm в пользу norm позже)?

На самом деле я не вижу никакого потенциального возмущения простой заменой dot на inner ... Я тоже думаю, что достаточно ясно, что внутренний продукт должен быть обобщением скалярных произведений.

Изменения могут быть реализованы в двух отдельных PR:

  1. Замените dot на inner и придайте ему обобщенное значение. При необходимости сделайте нотацию инфикса \cdot указывающей на внутреннюю между массивами Джулии.
  2. Дополнительные циклы обсуждения и устаревания вариантов норм и терминологии.

Насколько я понимаю, PR 1 можно было объединить до версии Julia v1.0. Это не ломается.

Замена dot на inner по-прежнему будет неработоспособной, потому что dot в настоящее время не является истинным внутренним продуктом для массивов массивов, поэтому вы измените значение, а не просто переименуете. Я за то, чтобы изменить значение, чтобы оно было истинным внутренним продуктом, но если вы измените значение (определив его как истинный внутренний продукт), я не вижу проблемы в том, чтобы продолжать писать его как dot .

Итак, мы могли бы сделать следующее в 0.7:

  1. Прекратить поддержку с norm(matrix) до opnorm(matrix) и с norm(vector of vectors) до vecnorm .
  2. Устарело dot([vector of arrays], [vector of arrays]) для вызова sum .
  3. Скажите, что vecdot(x,y) и vecnorm(x, p=2) являются евклидовыми внутренними продуктами/нормами (для p=2 ) и сделайте их рекурсивными (что немного ломает, но на практике, вероятно, не имеет большого значения) .

Затем в 1.0:

  1. Прекращена поддержка с vecnorm до norm и с vecdot до dot . (Не уверен, что это разрешено правилами выпуска 1.0, @StefanKarpinski?)

(Обратите внимание, что функция numpy.inner , как ни удивительно, не всегда является внутренним продуктом. Но терминология NumPy для inner и dot какое-то время была странной.)

Причины, по которым я предпочитаю продолжать писать как dot :

  • Хорошо иметь инфиксное написание.
  • Для нематематиков, работающих с обычными конечномерными векторными пространствами, dot — более знакомое название евклидова скалярного произведения. (Математики легко приспособятся к использованию имени dot для функции внутреннего произведения в произвольных гильбертовых пространствах — «точечный продукт» не имеет другого возможного значения для таких пространств.)
  • Имея как inner , так и dot , можно было бы сбить с толку, поскольку в некоторых случаях они совпадали бы, а в других — нет (если мы сохраним текущее значение dot ).
  • Помимо линейной алгебры, inner имеет множество других возможных значений в компьютерных науках, поэтому экспортировать это имя из Base несколько раздражает.

Не могли бы вы рассказать о своем неприятии имени «внутренний»? я все еще не понимаю
поэтому вы предпочитаете идти против терминологии, которую все в этой ветке кажутся
Соглашаться?

Вт, 15 мая 2018 г., 5:13 Стивен Дж. Джонсон, [email protected]
написал:

(Обратите внимание, что numpy.inner
https://docs.scipy.org/doc/numpy-1.14.0/reference/generated/numpy.inner.html
функция, как это ни удивительно, не всегда является внутренним продуктом.)


Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/JuliaLang/julia/issues/25565#issuecomment-389144575 ,
или заглушить тему
https://github.com/notifications/unsubscribe-auth/ADMLbdcpeWo7M4prYz76NoqUPIkfVPP3ks5tysZlgaJpZM4ReGXu
.

Ни одна из причин не является для меня убедительной:

>

  • Хорошо иметь инфиксный вариант.

Да и инфиксная нотация все равно может существовать независимо от переименования в
внутренний, как описано выше.

>

  • Для нематематиков, работающих с обычными конечномерными
    векторные пространства, точка — более привычное название евклидовой внутренней
    товар. (Математики легко приспособятся к использованию имени точка для
    функция внутреннего произведения на произвольных гильбертовых пространствах — «точечный продукт» не имеет
    другое возможное значение таких пространств.)

Этот аргумент не годится: давайте учить простых людей неправильному
терминологию, потому что они ленивы и не могут выучить новое подходящее слово,
и заставить математиков использовать неправильную терминологию против их воли.

>

  • Имея и внутреннюю часть, и точку, можно было бы сбить с толку, поскольку они
    в некоторых случаях совпадают, но могут и не совпадать (если мы сохраним текущую точку
    имея в виду).

Нам не нужны оба, избавьтесь от менее общего имени, которое, как мы согласны,
точка в этом месте.

>

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

Помимо линейной алгебры, я могу найти много применений для точки. Тем более для
точечная инфиксная нотация, означающая совершенно разные вещи.

>

Я публикую последний пост @juliohm с фиксированным форматированием.


Ни одна из причин не является для меня убедительной:

Хорошо иметь инфиксный вариант.

Да, и инфиксная нотация все еще может существовать независимо от переименования во внутреннее, как объяснялось выше.

Для нематематиков, работающих с обычными конечномерными векторными пространствами, точка — более знакомое название евклидова скалярного произведения. (Математики легко приспособятся к использованию имени точка для функции скалярного произведения в произвольных гильбертовых пространствах — «точечный продукт» не имеет другого возможного значения для таких пространств.)

Этот аргумент не годится: давайте учить простых людей неправильной терминологии, потому что они ленивы и не могут выучить новое подходящее слово, и заставлять математиков использовать неправильную терминологию против их воли.

Наличие как внутреннего, так и точки может привести к путанице, поскольку в некоторых случаях они будут совпадать, а в других — нет (если мы сохраним текущее значение точки).

Нам не нужны оба, избавьтесь от менее общего имени, которое, как мы согласны, на данный момент является точкой.

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

Помимо линейной алгебры, я могу найти много применений для точки. Тем более точечная инфиксная нотация, означающая совершенно разные вещи.

Да, и инфиксная нотация все еще может существовать независимо от переименования во внутреннее, как объяснялось выше.

Вы, конечно, можете определить const ⋅ = inner , но тогда ваша терминология непоследовательна. Я думал, вам не нравится использовать «точечный продукт» в качестве общего внутреннего продукта?

заставить математиков использовать неправильную терминологию против их воли

Математики знают, что терминология не может быть ни правильной, ни неправильной, она может быть только условной или нетрадиционной (и может быть последовательной или непоследовательной). (И большинство людей не занимаются математикой, потому что им нравится предписывающее написание.) По моему опыту, если вы скажете математикам, что в квантовой механике вектор называется «состоянием», сопряженный называется «кинжалом», а дуальный вектор называется "бюстгальтер", они возвышенно равнодушны. Точно так же я не думаю, что любой опытный математик моргнет более одного раза, если вы скажете ему, что в Джулии внутренний продукт пишется как dot(x,y) или x ⋅ y , тем более что термины уже понимаются как синонимы во многих контекстах. (Сомневаюсь, что вы найдете математика, который не поймет сразу, что вы имеете в виду внутренний продукт, если скажете: «Возьмите скалярное произведение двух функций в этом функциональном пространстве».)

С другой стороны, для людей, которые не являются математиками и не знакомятся с абстрактными пространствами внутреннего продукта (то есть для большинства пользователей), мой опыт показывает, что незнакомая терминология является большим препятствием. «Как взять скалярное произведение двух векторов в Джулии?» станет FAQ.

Здесь действительно нет никакой математической трудности, которую нужно решить, кроме выбора семантики. Вопрос правописания чисто вопрос удобства и использования.

Помимо линейной алгебры, я могу найти много применений для точки. Тем более точечная инфиксная нотация, означающая совершенно разные вещи.

За исключением того, что у Джулии и многих других языков программирования уже много лет есть dot , и это не было проблемой. inner будет новой поломкой.

В конечном счете, написание этой (или любой другой) функции является второстепенным вопросом по сравнению с семантикой и путем устаревания, но я думаю, что баланс склоняется в пользу dot .

Конечно, вы можете определить const ⋅ = inner, но тогда ваша терминология непоследовательна. Я думал, вам не нравится использовать «точечный продукт» в качестве общего внутреннего продукта?

Я думаю, вы все еще не понимаете. Нет противоречия в том, что точка называется внутренним продуктом. Это внутренний продукт, очень специфический и бесполезный для многих из нас. Не более чем sum(x.*y) .

Если термин dot окажется в Джулии с семантикой inner , это будет исторической катастрофой, и я могу вам гарантировать, что многие почувствуют раздражение. Я могу представить, как профессора в классе будут объяснять что-то вроде: «Вы знаете, сейчас мы собираемся определить внутренний продукт для нашего пространства, но в Джулии кто-то (@stevengj) решил назвать его точкой».

Я позабочусь о том, чтобы сделать скриншот этой ветки для дальнейшего использования, если это произойдет.

Вы единственный, кто @stevengj настаивает на терминологии dot , больше никто не возражал против нее. Было бы неплохо, если бы вы могли пересмотреть этот факт, прежде чем принимать решение.

Это внутренний продукт, очень специфический и бесполезный для многих из нас. Не более чем сумма (x. * y).

Если вы считаете, что «точечный продукт» может относиться только к евклидову скалярному произведению в ℝⁿ, тогда вам не следует определять const ⋅ = inner , вы должны определять только ⋅(x::AbstractVector{<:Real}, y::AbstractVector{<:Real}) = inner(x,y) .

У вас не может быть двух способов: либо inner может использовать в качестве инфиксного синонима (в этом случае инфиксный оператор является «неправильным» в вашем языке, а наименование непоследовательно) или у него нет инфиксного синонима (за исключением одного особого случая).

Я могу представить, как профессора в классе будут объяснять что-то вроде: «Вы знаете, сейчас мы собираемся определить внутренний продукт для нашего пространства, но в Джулии кто-то (@stevengj) решил назвать его точкой».

Ха-ха, я готов выдержать нападки этого воображаемого возмущенного профессора. Серьезно, вам нужно больше осмотреться, если вы думаете, что термин «точечный продукт» когда-либо используется только в ℝⁿ, или что математики возмущены, если этот термин используется в других гильбертовых пространствах.

это будет историческая катастрофа

Серьезно?

Эта дискуссия, похоже, выходит за рамки того, что можно было бы назвать доброжелательной, цивилизованной и конструктивной атмосферой . Мнения и предыстория различаются, но, пожалуйста, воздержитесь от личных нападок или возложения вины на кого-либо и предполагайте, что все стороны добросовестно обсуждают свою точку зрения.

Я могу представить, как профессора в классе будут объяснять что-то вроде: «Вы знаете, сейчас мы собираемся определить внутренний продукт для нашего пространства, но в Джулии кто-то (@stevengj) решил назвать его точкой».

Здесь также может быть полезно отметить, что Стивен _является_ профессором. :подмигивание:

Я также нахожусь на грани удаления dot в пользу inner . Термин dot довольно широко используется, и отсутствие функции в Julia, когда она есть в Python и MATLAB, было бы удивительным. Однако мне также нравится термин inner , учитывая, что он больше подходит для векторных пространств, отличных от ℝⁿ, и особенно для матриц.

Кстати, когда я тестировал, какие методы работают в Джулии, я заметил, что dot работает только с реальными векторами/матрицами. Это намеренно?

Наличие как внутреннего, так и точки может привести к путанице, поскольку в некоторых случаях они будут совпадать, а в других — нет (если мы сохраним текущее значение точки).

@stevengj Было бы совершенно нелепо заменить vecdot на inner , а также сохранить dot ? Прямо сейчас та самая проблема, которую вы описываете, уже существует, просто с vecdot вместо inner .

ОК... с нетерпением жду, каковы живые предложения? Должны ли они:

  • Используйте dot как универсальный внутренний продукт для более широкого диапазона типов. Это уже правильно рекурсивно для векторов-векторов, но мы заставим его работать с матрицами и т. д. ( @jebej Я не чувствую, что наличие dot и inner полезно, и Стивен говорит, что мы, по крайней мере, в разговорной речи довольно часто используем dot для обозначения внутреннего продукта, и это не неправильно — это просто терминология).
  • Подумайте о том, чтобы сделать norm немного более совместимым с приведенным выше dot и во всех AbstractArray , в конечном итоге введя, например, opnorm для норм оператора (на AbstractMatrix ) и имеющий (в нотации от нового к старому) norm(matrix) == vecnorm(matrix) после соответствующих устареваний. На данный момент, возможно, нам больше не нужны vecdot и vecnorm ?

Это правильно? Я думаю, что это, по крайней мере, приведет нас к относительно последовательной истории линейной алгебры с «чистыми» интерфейсами, где общий код может использовать dot и norm в качестве надежной пары для работы с пространствами внутреннего произведения. независимо от типа.

@andyferris , да, я думаю, что если мы внесем это изменение, нам понадобятся только dot и norm (которые теперь являются рекурсивными евклидовыми операциями над массивами или массивами массивов любой размерности, хотя для нормы мы также определяем norm(x,p) как p-норму) и opnorm , и больше не имеем vecdot или vecnorm .

Обратите внимание, что изменение на dot является критическим изменением, потому что dot в настоящее время не является истинным скалярным произведением для векторов матриц (#22392), что долгое время обсуждалось в #22220 ( в этот момент устранение vecdot не считалось IIRC). Однако это было введено в 0.7, поэтому оно не нарушает какой-либо фактически выпущенный код. Фактически, dot в версии 0.6 уже является евклидовым скалярным произведением на массивах произвольной размерности, несколько случайно (#22374). Предлагаемое здесь изменение восстановит и расширит это поведение 0.6 и изменит norm , чтобы оно соответствовало ему.

Один вопрос заключается в том, будет ли norm(x,p) вызывать norm(x[i]) или norm(x[i],p) рекурсивно. Оба поведения потенциально полезны. Я склоняюсь к первому, потому что он более общий — x[i] может быть некоторым произвольным нормированным векторным пространством, которое определяет только norm , но не p-норму. Рекурсивный вызов norm также является тем, что сейчас делает vecnorm , поэтому он согласуется с отказом vecnorm до norm .

@jebej , dot как на master, так и на 0.6 работает для меня со сложными массивами: например, dot([3im],[4im]) правильно возвращает 12+0im .

Еще один хороший момент в изменении norm(matrix) на норму Фробениуса заключается в том, что это намного дешевле. Обычно просто используют norm(A-B) , чтобы понять, насколько велика разница между двумя матрицами, но не слишком заботясь о конкретном выборе нормы, но многие пользователи не поймут, что текущее значение по умолчанию norm(matrix) требует, чтобы мы вычислили SVD.

Замечательно видеть консенсус, формирующийся вокруг нескольких основных моментов! :) (Если кто-то не опередит меня в этом (пожалуйста, сделайте это, если у вас есть пропускная способность!) или альфа-тег не сработает раньше, я попытаюсь реализовать текущие точки консенсуса после отправки # 26997.) Лучшее!

Еще одна ссылка для дальнейшего использования: https://math.stackexchange.com/a/476742

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

И для будущих читателей, что следовало бы сделать вместо этого, если бы у нас было коллективное решение:

# make dot what it is, a NOTATION
⋅(x::AbstractVector, y::AbstractVector) = sum(x[i]*y[i] for i in indices(x))

# replace the name dot by the more general inner
inner(x, y) = # anything

Я предполагаю, что мы просто будем первыми людьми во вселенной , которые будут использовать термин « точечный продукт» для внутреннего продукта для чего-либо, кроме ℝⁿ. Хорошо, что я смог навязать эту ветку свою волю (в основном, шантажируя других разработчиков), чтобы заставить это новшество появиться в мире! Скалярный продукт больше не будет сводиться к простому «обозначению»: вместо этого он будет символом, который означает внутренний продукт (как всем должно быть известно, присвоение значений символам противоположно «обозначению»).

Очень хорошее решение :clap: это был определенно консенсус. Прочитайте комментарии выше, и вы увидите, как все согласились. :+1:

Или, может быть, я должен процитировать некоторые комментарии, чтобы было очень ясно, как это был консенсус:

>

Правильно — vecdot можно было бы переименовать во внутренний

от @andyferris

Вариант 2 (вероятно, лучше): использовать более математически правильные имена

внутренний
измерение
Но что делать с нормой?

от @Jutho

Я согласен, в качестве альтернативы vecdot мы могли бы ввести новый метод inner

от @Jutho

Я также нахожу имя vecdot странным, на самом деле, я даже не знал, что оно существует, и сделал для него свою собственную функцию... под названием inner.

от @jebej

И многое другое...

Люди могут бурно спорить друг с другом и выдвигать множество спорных моментов, но все же приходить к консенсусу (хотя и не всегда к единодушию) путем убеждения и взвешивания плюсов и минусов. (Я согласен с тем, что здесь есть как плюсы, так и минусы каждого варианта.) Мне жаль, что результат, который кажется (предварительно!) здесь склеивающимся, не тот результат, который вы предпочли, но я не уверен, как вы думаете Я «навязал» свою волю.

(Конечно, не то чтобы какое-то окончательное решение было принято — пока нет даже PR, не говоря уже о слиянии.)

Я только хотел бы, чтобы мы могли принять решение, основанное на аудитории языка. Если кто-то выбирает Джулию в качестве инструмента, я уверен, что этот человек хотя бы слышал термин «продукт inner ». Это довольно популярная концепция и далеко не экзотика. К экзотическим вещам относятся «постоянная гомология», «квантовая теория», они менее распространены, и я был бы против включения такого рода терминологии.

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

@juliohm , все аргументы были основаны на потребностях того, кем, по нашему мнению, является аудитория, и все мы пытаемся сделать язык Julia настолько хорошим, насколько это возможно. Разумные люди могут прийти к разным выводам о терминологии, так как математика не определяет орфографию.

Во-первых, как упоминалось выше, я, безусловно, могу согласиться с текущим предложением @stevengj и придерживаться dot в качестве общего названия внутреннего продукта. Кроме того, мне не нравится ход этой дискуссии, и я, безусловно, хотел бы, чтобы меня правильно цитировали. @juliohm , вторая цитата, которую ты приписываешь мне, не моя.

При этом я хотел бы упомянуть следующее как пищу для размышлений при рассмотрении плюсов и минусов. Ниже приведены в основном минусы, но я согласен с плюсами, упомянутыми @stevengj. Легко могут быть отдельные варианты использования для того, чтобы dot просто означало sum(x[i]*y[i] for i ...) . В тех случаях, когда в математике чаще всего используется инфиксно-точечная нотация, это действительно обычно имеет значение. Как внутренний продукт, инфиксно-точечная нотация обычно (хотя, конечно, не исключительно) зарезервирована для реальных векторных пространств. Другие варианты использования включают в себя включение таких вещей, как σ ⋅ n с σ вектором матриц Паули и n вектором скаляров. Это было одной из причин того, как в настоящее время реализована dot , как мне было указано в какой-то другой теме. Тот факт, что BLAS решил использовать только dot для реальных векторов и провести различие между dotu и dotc для сложных векторов, является еще одной проблемой, которую следует учитывать. Люди с опытом BLAS могут запутаться, хотят ли они, имея сложные векторы, вычислить dot(conj(u),v) или dot(u,v) , когда им нужен истинный внутренний продукт (т.е. dotc ). Кроме того, они могут искать способ сделать dotu без предварительного создания сопряженной копии имеющегося вектора.

@Jutho цитата ваша, ваш полный комментарий скопирован ниже:

Я согласен, в качестве альтернативы vecdot мы могли бы ввести новый метод inner, но я не знаю подходящего названия для «замены» vecnorm. На самом деле, я не считаю vecnorm таким уж плохим, векторная норма — это устоявшийся и явный термин для той операции, которую мы хотим.

В любом случае цитирование призвано показать, каково здесь желание многих (хотя бы в качестве первой естественной мысли), когда мы думаем об этом предмете. Если со временем вы изменили свое желание, это уже другая история. Сам я никогда бы не выкинул из головы термин «точка» при любом моделировании с гильбертовыми пространствами. Это кажется неестественным и несовместимым с тем, что я узнал.

@Jutho : Кроме того, они могут искать способ сделать dotu без предварительного создания сопряженной копии имеющегося вектора.

Время от времени появляется возможность экспорта функции dotu (см., например, #8300). Я согласен, что иногда это полезная функция: несопряженный евклидов «скалярный продукт» (на самом деле уже не скалярный продукт), который представляет собой симметричную билинейную (не полуторалинейную) форму dotu(x,y) == dotu(y,x) (не сопряженную) даже для комплексных векторных пространств. . Но полезность этой операции не ограничивается ℂⁿ — например, этот вид произведения часто проявляется в бесконечномерных векторных пространствах (функциях) для уравнений Максвелла как следствие взаимности (по существу: оператор Максвелла в типичных материалах с потерями равен аналогично «комплексно-симметричной матрице» — симметричной относительно несопряженного «скалярного произведения»). Итак, если мы определим dot(x,y) как общее евклидово скалярное произведение (с сопряженным первым аргументом), было бы вполне естественно определить функцию dotu(x,y) для несопряженного евклидова произведения на любом векторном пространстве где это имеет смысл. Однако я не вижу возможности использования функции dotu в качестве аргумента против dot . В большинстве случаев, когда вы работаете со сложными векторными пространствами, вам нужен сопряженный продукт, так что это правильное поведение по умолчанию.

Но я согласен с тем, что одной из возможностей было бы определить dot(x,y) = sum(x[i]'*y[i] for i = 1:length(x)) , как это в настоящее время определено в мастере (не 0,6), и определить inner(x,y) как истинное скалярное произведение. Это имеет то преимущество, что предоставляет обе функции, обе из которых могут быть полезны в определенных случаях. Однако тогда у нас есть две функции, которые почти всегда совпадают, за исключением массивов матриц, и я подозреваю, что было бы немного запутанно решить, когда использовать одну или другую. Многие люди написали бы dot , имея в виду inner , и в большинстве случаев это сработало бы для них нормально, но тогда их код сделал бы что-то неожиданное, если бы ему был передан массив матриц. Я подозреваю, что в 99% случаев людям нужен истинный внутренний продукт, а версию «сумма продукта» можно оставить пакету, если он вообще нужен (в отличие от простого вызова sum ).

@juliohm , я неправильно прочитал ваш пост, так как думал, что имена были выше (а не ниже) соответствующих цитат, поэтому я подумал, что вы приписали цитату @jebej мне. Мои извинения за это.

@stevengj , я, конечно, не думал о том, чтобы dot(x,y) = sum(x[i]'*y[i] for i = 1:length(x)) было разумным значением по умолчанию. В случае σ ⋅ n сложное/эрмитово сопряжение первого или второго аргумента не требуется. Итак, я имел в виду, что во многих (но не во всех) случаях, когда в научных формулах используется инфиксно-точечная нотация, ее значение совпадает с dotu , т.е. sum(x[i]*y[i] for i = 1:length(x)) без спряжения, либо как скалярное произведение на вещественных векторных пространствах или как более общая конструкция.

Итак, если бы я сделал альтернативное предложение (хотя я не обязательно его защищаю), оно должно было бы выполнять две функции:

  • dot(x,y) = sum(x[i]*y[i] for i...) , который по-прежнему является правильным внутренним произведением для реальных векторов (что, вероятно, используется людьми, которые менее или не знакомы с термином внутреннего продукта), но также допускает более общие конструкции, такие как σ ⋅ n и, таким образом, является функцией, соответствующей инфиксной нотации

  • inner(x,y) — всегда действительный внутренний продукт с сопряжением и рекурсией, который будет использоваться людьми в более общих технических контекстах.

Я не защищаю это как хороший выбор для использования в языке Julia, но я действительно думаю, что именно так он используется в большей части литературы. Когда используется инфиксная точка, это либо внутренний продукт в контексте реальных векторов, либо какая-то более общая конструкция, где она просто означает сокращение. Когда речь идет об общем скалярном произведении на произвольных векторных пространствах, большая часть научной литературы (но вы, конечно же, привели встречные примеры) переключается на <u,v> или <u|v> (где в первых обозначениях все еще обсуждается, какой из двух аргументов сопряжено).

Я мог бы жить с этим предложением, но в равной степени я мог бы жить и с тем, что общий внутренний продукт составляет всего dot . В конце концов, все дело в хорошей документации, и я тоже не могу поверить, что кто-то споткнется об этот выбор «дизайна».

@Jutho , я согласен, что нередко определяют dot просто как сокращение. Конечно, можно найти примеры и в том, и в другом случае. Например, в языках программирования и популярных библиотеках:

  • Несопряженные: Numpy dot (и, как ни странно, inner ), Mathematica Dot , Maxima . , BLAS dotu

  • Сопряженные: dot в Matlab, DOT_PRODUCT в Fortran, DotProduct в Maple, VecDot в Petsc, Numpy vdot , BLAS dotc (обратите внимание, что отсутствие перегрузка в Fortran 77 сделала невозможным вызов этой dot даже при желании), точка Эйгена

С одной стороны, сопряженный скалярный продукт обычно вводится в учебниках как « естественное» расширение понятия «скалярного произведения» для комплексных векторов — несопряженная версия является в некотором смысле «неестественным» расширением, поскольку оно обычно не то, что ты хочешь. (Учтите тот факт, что из языков, которые предоставляют сопряженную функцию dot в своих стандартных библиотеках — Matlab, Fortran, Julia, Maple — только Maple предоставляет несопряженный вариант, намекая на отсутствие спроса.) с другой стороны, несопряженная функция dotu удобна (как дополнение) в некоторых частных случаях (некоторые из которых я упомянул выше).

Если у нас есть и dot , и inner , я подозреваю, что многие люди в конечном итоге будут использовать dot случайно, когда они действительно хотят inner , чтобы их код был общий. (Держу пари, что inner в Numpy является несопряжённым именно из-за такой случайности — они реализовали его, имея в виду реальные массивы, и не думали о сложном случае, пока не стало слишком поздно что-то менять, поэтому они добавили неловко названный vdot .) Принимая во внимание, что если у нас есть dot и (возможно) dotu , будет яснее, что dot является выбором по умолчанию, а dotu — вариант для особых случаев.

(Я согласен с тем, что ⟨u,v⟩ , ⟨u|v⟩ или (u,v) являются более распространенными обозначениями для скалярных произведений в произвольных гильбертовых пространствах — это то, что я обычно использую сам, — но эти обозначения представляют собой nonstarter для Джулии Было некоторое обсуждение синтаксического анализа скобок Unicode как вызовов функций/макросов, например # 8934 и # 8892, но это никуда не ушло, и вряд ли это скоро изменится.)

Я полностью согласен с вашей оценкой @stevenj .

Я тоже.

Я подозреваю, что пришло время для одного из нас поиграть с любой реализацией в PR и посмотреть, что из этого выйдет.

@Jutho Я всегда видел скалярное произведение с матрицами Паули как сокращение для сокращения тензоров более высокого порядка ... одно из векторных пространств реальное, трехмерное.

Я согласен с тем, что ⟨u,v⟩, ⟨u|v⟩ или (u,v) являются более распространенными обозначениями для скалярных произведений в произвольных гильбертовых пространствах — это то, что я обычно использую сам, — но эти обозначения не подходят для Джулии.

На самом деле было бы возможно заставить ⟨u,v⟩ работать.

@StefanKarpinski : на самом деле можно заставить ⟨u,v⟩ работать.

Абсолютно, и поддержка этой точной записи была предложена в # 8934, но она никуда не делась. (Обратите также внимание, что угловые скобки имеют и другие распространенные применения, например, ⟨u⟩ часто обозначает какое-то среднее значение.) Это неразрывно и все еще может быть добавлено в какой-то момент, но не кажется разумным ожидать в ближайшем будущем. срок. Также довольно медленно набирать \langle<tab> x, y \rangle<tab> , так что это не очень удобно с точки зрения программирования для элементарной операции.

и мы не можем перегрузить <> для этого, верно?

Нет

Не могу сказать, что прочитал все комментарии в этой огромной ветке, но я просто хочу выделить несколько моментов, некоторые из которых уже были сделаны ранее:

  • Различие между точкой и внутренним кажется чрезмерно педантичным. Действительно, на мой слух это кажется бессмысленным, потому что во французском языке есть только один термин - «скалярное произведение» - и трудно различать вещи, которые для меня имеют одно и то же имя ;-)
  • Когда вы приходите из numpy и работаете со сложными массивами, лучше всего иметь сопряжение dot по умолчанию. Здесь нет точки принятия решения, я просто хотел сказать, как я рад, что мне больше не нужно делать эти conj(dot()) s!
  • Наличие двух функций, которые в большинстве случаев имеют одинаковое поведение, но иногда различаются, является плохим дизайном и вызывает и будет вызывать путаницу, когда код, который должен вызывать одну, на самом деле вызывает другую, просто потому, что пользователь не знает лучше. Это особенно раздражает с norm : если вы кодируете алгоритм оптимизации и хотите остановиться всякий раз, когда norm(delta x) < eps , вы собираетесь написать norm . Но потом вы хотите оптимизировать изображение или что-то в этом роде, вы запускаете свой код, и он внезапно запускает неубиваемый (потому что BLAS) SVD большого массива. Это не является академическим, это вызвало проблемы в Optim.jl и, несомненно, в других пакетах. Никто не узнает, что vecnorm существует, если у него нет конкретной причины его искать.
  • Основываясь на предыдущем пункте, любое решение, объединяющее dot и vecdot , а также norm и vecnorm , является хорошим, даже если оно устраняет некоторую гибкость в случаи массива массивов. Что касается норм, я бы добавил, что часто при работе с вещами, для которых определено несколько норм (например, матрицы), пользователь хочет вызвать norm , чтобы получить норму, не особо заботясь о том, какая именно. Индуцированные нормы чаще всего представляют теоретический, а не практический интерес из-за их вычислительной сложности. Они также специфичны для интерпретации 2D-массива как оператора, а не интерпретации 2D-массива как хранилища (изображение представляет собой 2D-массив, но это не оператор в каком-либо полезном смысле). Хорошо иметь возможность вычислять их, но они не заслуживают быть norm по умолчанию. Разумные, простые и хорошо задокументированные значения по умолчанию, которые имеют поддающиеся обнаружению альтернативы, лучше, чем попытка ума (если пользователь хочет сделать что-то умное, позвольте ему сделать это явно).

Поэтому +1 к @stevengj

да, я думаю, что если мы внесем это изменение, нам понадобятся только точка и норма (которые теперь являются рекурсивными евклидовыми операциями над массивами или массивами-массивами любой размерности, хотя для нормы мы также определяем норму (x, p) как p-норма) и opnorm, и больше не имеют vecdot или vecnorm.

Более «юлианской» альтернативой норме/опнорме может быть тип оператора, который может обернуть 2D-массив, на котором norm выполняет операцию opnorm. Это можно сделать на уровне пакетов (несколько из которых уже существуют)

Я скорее наберу opnorm(matrix) , чем norm(Operator(matrix))

Я собираюсь вмешаться из галереи арахиса и сказать, что мне нравится, куда это идет — vecnorm и vecdot всегда меня беспокоили. Необходимость явно запрашивать операторную норму — которая всегда казалась мне довольно специализированной — кажется гораздо более разумной, чем необходимость запрашивать норму, которую намного быстрее и проще вычислить (например, норму Фробениуса). Написание opnorm кажется прекрасным интерфейсом для запроса относительно специализированной операторной нормы.

Я также чувствую, что тонкое различие между dot и inner может привести к путанице и безудержному неправильному использованию. Читать пользователям лекции о том, какую функцию им _предполагается_ использовать, когда обе функции делают то, что они хотят, а одна из них проще, как правило, не очень хорошо работает. У меня сложилось впечатление, что в универсальном коде относительно редко sum(x*y for (x,y) in zip(u,v)) действительно то, что вам нужно, когда действительно существует истинный внутренний продукт ⟨u,v⟩ . Когда это действительно то, что нужно, довольно просто, ясно и эффективно (потому что Джулия — это то, что есть) просто написать что-то подобное для вычисления.

Вызывать ли функцию $ u⋅v dot или inner кажется наименее важной частью всего этого. Я почти уверен, что ни один из вариантов не будет воспринят историками как катастрофа, хотя мысль о том, что историков это вообще волнует, безусловно, лестна. С одной стороны, если мы согласны сохранить значение «истинного внутреннего продукта» u⋅v , тогда да, inner является более правильным математическим термином. С другой стороны, когда есть синтаксис с соответствующим именем функции, это, как правило, меньше смущает пользователей, когда имя соответствует синтаксису. Поскольку в синтаксисе здесь используется точка, это эмпирическое правило поддерживает написание этой операции как dot . Возможно, это может быть разумным случаем для определения const dot = inner и экспорта обоих? Затем люди могут использовать или расширять любое имя, которое они предпочитают, поскольку это одно и то же. Если кто-то хочет использовать любое имя для чего-то другого, он может это сделать, а другое имя останется доступным с его значением по умолчанию. Конечно, это сделало бы три экспортируемых имени для одной и той же функции dot , inner и что кажется немного чрезмерным.

Можно ли удалить символ или заменить его на <u,v> ?

Комментарии:

  • Это делает намерение ясным. Сравните эти два примера:
<u,v> * M * x

против.

u ⋅ v * M * x
  • Синтаксис <u,v> подразумевает ассоциацию: сначала мы работаем с u и v , а затем следует остальная часть выражения.

  • Если пользователь пытался набрать <u,v> , маловероятно, что он имел в виду простое sum(x[i]*y[i]) . Символ легко пропустить глазами, и он имеет много других значений. В частности, в линейной алгебре для векторного пространства V над полем F произведение скаляра α ∈ F на вектор v ∈ V α ⋅ v .

  • Удаление или замена также устранит проблему экспорта нескольких имен. Нужно было бы экспортировать только inner и <,> для общих внутренних продуктов с реализацией по умолчанию для массивов, соответствующих семантике итерируемого суммирования.

  • Если нужно определить скалярное произведение на вектор, как описано выше, для векторного пространства V над полем F, он/она сможет определить для него нотацию . Тогда векторное пространство будет полностью определено с помощью красивого короткого синтаксиса и может быть расширено до гильбертова пространства путем дальнейшего определения <u,v> .

Мы определенно не можем использовать синтаксис <u,v> ; мы могли бы использовать синтаксис ⟨u,v⟩ обратите внимание на скобки Юникода, а не на знаки «меньше» и «больше», < и > . У нас также есть u'v в качестве синтаксиса для чего-то, что является точечным продуктом или внутренним продуктом? (не знаю какой...)

Да, извините, версия юникода. Было бы очень понятно читать. Это также решило бы эту проблему с несколькими именами и освободило бы для других целей.

Я не думаю, что мы хотим использовать для каких-либо других целей — это может привести к путанице.

Просто представьте, как замечательно было бы иметь возможность писать код, который выглядит так:

⟨α ⋅ u, v⟩ + ⟨β ⋅ w, z⟩

для абстрактных векторов (или типов) u,v,w,z ∈ V и скаляров α, β ∈ F .

u'v — это внутренний продукт (и точечный продукт, если вы следуете соглашению о сопряжении) только для одномерных массивов, а не, например, для матриц. (Это еще одна причина, по которой бессмысленно ограничивать инфиксную точку массивами из 1d, поскольку для этого случая у нас уже есть краткое обозначение.)

Стефан, «правильный математический термин» — это ошибка категории, а математическая правильность — это не понятие, применимое к терминологии/обозначениям. (Замените «правильным» на «обычный». Но тогда проблема станет менее актуальной.)

Другие варианты использования: https://stackoverflow.com/questions/50408177/julia-calculate-an-inner-product-using-boolean-алгебра

И формальный вывод логических внутренних продуктов с использованием нотации ⟨,⟩ : https://arxiv.org/abs/0902.1290

РЕДАКТИРОВАТЬ: исправлена ​​ссылка на бумагу

Что вы думаете о предложении по синтаксису угловых скобок? Решит ли это поднятые здесь вопросы?

Так в чем конкретно состоит ваше предложение? Это примерно так:

  1. Превратить dot в inner
  2. Прекратить поддержку u⋅v до ⟨u,v⟩

Тогда не будет ни функции dot , ни оператора ?

Будет ли это изменение разумным?

Извините за задержку с ответом, я нахожусь на конференции с ограниченным доступом в Интернет.

И просто для ясности и полноты, в чем здесь встречное предложение? Ничего не делать?

Чтобы еще больше прояснить это предложение, в него вовлечено семантическое изменение: обобщенные внутренние продукты.

Внимание: мы обсудили это до такой степени, что существует реальный риск того, что он не войдет в 0,7-альфа. Это не значит, что его нельзя изменить после альфы, но после этого будет гораздо больше нежелания что-то менять.

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

Даже если не учитывать вопрос о синтаксисе оператора, по-прежнему существует некоторая сложность с затенением имен и многоэтапным отказом от поддержки каждого набора семантических понятий (текущие dot и vecdot и текущие norm и vecnorm ).

Для стороны dot кажется, что все пространство вариантов (опять же без учета операторов):

I. Тихо сломать dot на векторах массивов, изменив поведение в 0.7 на внутренний продукт без стандартного depwarn (хотя можно предупредить, что поведение меняется). Кроме того, в версии 0.7 устарело значение с vecdot до dot .
II. В версии 0.7 vecdot для всех входных данных заменено на inner .
III. В версии 0.7 устарели dot для векторов массивов до их определения, dot для других входных данных и vecdot для всех входных данных до inner .
IV. В версии 0.7 устарели как dot , так и vecdot для векторов массивов либо для неэкспортированных функций, либо для их определений, а vecdot для всех остальных входных данных до dot . В версии 1.0 добавьте dot к векторам массивов с семантикой внутреннего произведения.

Что касается норм, существует некоторый консенсус относительно единого пути (в 0.7 устареть norm на матрицах до opnorm и, возможно, устареть с vecnorm до innernorm ; в 1.0 , добавьте norm к матрицам с текущей семантикой vecnorm ), но это также приводит к дополнительному имени в 1.0 (либо vecnorm , либо innernorm ); Опять же, способ избежать этого может состоять в том, чтобы объявить vecnorm устаревшим в 0.7 до его определения или неэкспортированной функции, такой как Base.vecnorm , а не до экспортированного имени.

...Я думаю. Надеюсь, я не сделал вещи более мягкими, чем они уже были.

Может ли кто-нибудь, знакомый с кодовой базой, отправить PR для изменения?

Можем ли мы отделить стандартные вещи, с которыми, кажется, все согласны, и сделать хотя бы это? Бит dot против inner немного более спорный, но давайте не позволим этому поставить в тупик ту часть, которая не является.

@StefanKarpinski , обратите внимание, что они несколько связаны: для типов, в которых есть как точечный (внутренний) продукт, так и норма, они должны быть согласованы.

Ладно, мне все равно, как все пойдет. Кто делает работу, тот и решает.

У меня был PR ( #25093 ), чтобы заставить vecdot вести себя как истинное внутреннее произведение (и vecnorm как соответствующую норму), сделав их рекурсивными. Это может быть полезно в качестве отправной точки того, как должны выглядеть будущие dot и norm . К сожалению, отсутствие навыков работы с git заставило меня испортить этот PR, поэтому я закрыл его, планируя вернуться к нему после того, как новый синтаксис итерации будет завершен.

Однако то, что несколько дней назад я стал отцом во второй раз, означает, что в моем календаре сейчас нет «свободного времени».

только что стал отцом во второй раз несколько дней назад

Поздравляем Юто! 🎉

Да, поздравляю!

Похоже, что может сформироваться некоторый консенсус относительно идеи иметь как dot , так и inner , где:

  1. inner — настоящий рекурсивный скалярный продукт
  2. dot = dot(x,y) = sum(x[i]'*y[i] for i = 1:length(x)) сопряжено или нет, и поэтому будет перекрываться с dot для Vector{<:Number} или Vector{<:Real}

Касательно:

Многие люди написали бы точку, когда имели в виду внутренний, и в большинстве случаев это сработало бы для них нормально, но тогда их код сделал бы что-то неожиданное, если бы ему был передан массив матриц.

Я не верю, что это будет проблемой. Поскольку это довольно необычная операция, я ожидаю, что люди, по крайней мере, попробуют ее, чтобы увидеть, что она делает, и/или заглянут в документацию.

Я думаю, что приведенное выше было бы большим изменением, и не очень разрушительным, поскольку семантика dot не меняется в большинстве случаев.

Похоже, что может сформироваться некоторый консенсус относительно идеи иметь как dot , так и inner

Напротив, обсуждение с https://github.com/JuliaLang/julia/issues/25565#issuecomment -390069503, по-видимому, благоприятствует использованию одного или другого, но не обоих, как, например, изложено в https://github. com/JuliaLang/julia/issues/25565#issuecomment -390388230 и хорошо подкреплены реакциями.

Возможно, inner (а также dot ) должны быть рекурсивными внутренними/точечными/скалярными произведениями, а старое поведение может быть реализовано в таких функциях, как dotc(x,y) = sum(x[i]' * y[i] for i in eachindex(x)) и dotu(x,y) = sum(transpose(x[i]) * y[i] for i in eachindex(x)) ? Имена dotu и dotc будут соответствовать соответствующим именам BLAS.

(Я согласен с тем, что ⟨u,v⟩, ⟨u|v⟩ или (u,v) являются более распространенными обозначениями скалярных произведений в произвольных гильбертовых пространствах — это то, что я обычно использую сам, — но эти обозначения не подходят для Джулии. , Было некоторое обсуждение синтаксического анализа скобок Unicode как вызовов функций/макросов, например, #8934 и #8892, но это никуда не ушло, и вряд ли это скоро изменится.)

@stevengj , когда вы сами добавили этот абзац к предыдущему комментарию, вы имели в виду, что синтаксис ⟨u,v⟩ сложно реализовать в языке?

Есть ли шанс, что эта функция попадет в Julia v1.0? У меня так много идей и пакетов, которые зависят от понятия общих внутренних продуктов. Пожалуйста, дайте мне знать, если я должен снизить свои ожидания. Извините за постоянное напоминание.

Вы не видели #27401?

Спасибо @jebej и спасибо @ranocha за инициативу :heart:

когда вы сами добавили этот абзац к предыдущему комментарию, вы имели в виду, что синтаксис ⟨u,v⟩ сложно реализовать в языке?

Технически это не сложно добавить в синтаксический анализатор, но оказалось трудно прийти к единому мнению о том, как (и нужно ли) представлять пользовательские скобки в языке. См. обсуждение #8934, которое 4 года назад никуда не делось и с тех пор не возрождалось. (Добавьте это к тому факту, что в разных областях люди используют одни и те же скобки для разных вещей, например, ⟨u⟩ используется для средних значений по ансамблю в статистической физике.) Еще одна проблема, поднятая в № 8892, — это визуальное сходство многих разных Unicode. кронштейны.

Спасибо @stevengj , я ценю разъяснения. Я уже очень рад, что у нас будут общие внутренние продукты, стандартизированные для разных упаковок. :100: Возможно, обозначение угловых скобок могло бы проявить себя в другом выпуске в будущем. Не так важно, но вполне удобно иметь возможность писать код, буквально похожий на математику в наших публикациях.

Если ⟨args...⟩ является допустимым синтаксисом для вызова оператора anglebrackets или чего-то подобного (как вызвать функцию, которую вызывает этот синтаксис, на самом деле довольно сложно, поскольку у нас нет прецедента), тогда люди могли бы выбрать любое значение, которое они хотят для синтаксиса.

@StefanKarpinski , аргумент № 8934 заключался в том, что это должен быть макрос. Я не думаю, что мы когда-либо пришли к консенсусу.

(Если мы решим в Base, что anglebrackets(a,b) означает inner(a,b) , это оттолкнет людей от «выбора любого значения, которое они хотят», потому что решение уже принято.
Это, конечно, не самый плохой выбор, но может быть ненужным присваивать этому значению значение в Base, пока они анализируются.)

Я не помню подробностей этого обсуждения, но создание макроса кажется мне явно плохой идеей.

С # 27401, я думаю, мы можем считать, что внутренние продукты воспринимаются серьезно.

Традиционно вопрос закрывается только при объединении соответствующего PR...

Конечно, мы можем оставить его открытым, я думаю. Просто хотел убрать его с этикетки сортировки.

Должно ли это быть закрыто, так как # 27401 теперь объединен?

Была ли эта страница полезной?
0 / 5 - 0 рейтинги