Julia: Estado de productos internos en Base

Creado en 15 ene. 2018  ·  146Comentarios  ·  Fuente: JuliaLang/julia

Si un usuario necesita definir productos internos personalizados para espacios generales de Hilbert, ¿cuál es el estado actual en Base para este tipo de generalización? https://github.com/JuliaLang/julia/issues/16573 es un problema relacionado, pero menos general. Mi preocupación es con los nuevos tipos que no son matrices.

Me gustaría proponer cambiar el nombre dot a inner , o tal vez indicar a los usuarios que definan inner(x,y) como un producto interno general entre los objetos x y y , incluido el caso de la matriz:

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

En caso de que el cambio sea razonable, ¿podría ser parte de Julia v1.0?

linear algebra

Comentario más útil

¿Debería cerrarse ya que #27401 se fusionó ahora?

Todos 146 comentarios

¿Podría explicar un poco más sobre su caso de uso y por qué es beneficioso tenerlo en Base en lugar de simplemente definirlo en su paquete? Un ejemplo concreto sería lo mejor. ¿Espera varias definiciones de inner en paquetes cargados simultáneamente?

Creo que tener una interfaz formal para estos espacios matemáticos ayudará a los usuarios a explotar mejor el sistema de tipos. Por ejemplo, esperaría que los métodos de agrupamiento funcionaran en cualquier espacio métrico. Si pudiera definir mi tipo con un producto interno, me beneficiaría de Clustering.jl listos para usar (después de que el paquete se corrija en consecuencia). También se podrían generalizar muchos otros algoritmos basados ​​en la distancia o en la proyección.

Como ejemplo concreto, me encontré con esta limitación hoy tratando de definir una geometría para datos de composición: https://github.com/juliohm/CoDa.jl Prefiero especializarme en una función bien conocida de inner definido en Base que definir mi propia interfaz que nadie más conocerá.

¿Por qué no extender dot para sus tipos de espacios Hilbert? Estoy bastante seguro de que está diseñado pensando en ser el producto interno genérico.

El concepto de producto escalar es más estricto que el concepto de producto interior. Mientras que este último se define para espacios generales, un producto punto solo se define cuando existe la noción de un sistema de coordenadas definido por una base finita. La semántica de dot(x,y) es x'*y donde x y y representan las coordenadas de los objetos en un mundo cartesiano. Los libros de texto de matemáticas rara vez mencionan el término producto escalar, ya que los autores suelen estar interesados ​​en tratar el material en espacios más generales (no necesariamente finitos ni euclidianos).

Para distinguir aún más, en un espacio de Hilbert con producto interno <x,y> (o inner(x,y) ) los objetos pueden ser infinitos y la semántica x'*y no se aplica. Por ejemplo, en el análisis funcional de datos los objetos son las funciones f y g y el producto interior suele obtenerse por integración numérica: inner(f,g) = quadrature(f*g) . Llamar a esta operación un producto escalar es engañoso.

Otro ejemplo, como señalé en mi paquete CoDa.jl , son los datos de composición. Los objetos de composición se encuentran en un mundo símplex para el cual la operación x'*y no tiene ningún sentido. Sin embargo, existe una transformación isométrica (la transformación de relación logarítmica) que se puede usar para mapear composiciones en otra geometría donde luego se puede aplicar el producto escalar con coordenadas. No es necesario trabajar con coordenadas, pero es una práctica común en este campo. El resultado puede volver a transformarse en el espacio original donde existen los objetos.

No veo ningún beneficio en mantener el término dot en el idioma, pero si uno pregunta por la compatibilidad con versiones anteriores, la generalización inner(x::AbstractVector, y::AbstractVector) = dot(x,y) funciona perfectamente.

¿Puede dar más detalles sobre las objeciones para este cambio?

¿Puede dar más detalles sobre las objeciones para este cambio?

Generalmente requerimos una buena cantidad de justificación para agregar nuevas funciones públicas a Base, esa es la objeción. Esto podría ser proporcionado por un paquete InnerProducts . ¿Por qué necesita ser integrado en el lenguaje mismo? Esta fue la primera pregunta que @andreasnoack hizo arriba: obtuvo una respuesta algo vaga de "Creo que tener una interfaz formal para estos espacios matemáticos ayudará a los usuarios a explotar mejor el sistema de tipos". No hay razón para que una interfaz definida en un paquete sea menos formal que una en Base. ¿Qué ofrece tener Base.inner que InnerProducts.inner no? Esta es una pregunta genuina que podría tener una respuesta convincente, pero no sé cuál podría ser esa respuesta, razón por la cual se hace la pregunta.

No veo un buen argumento para definir un concepto matemático básico como productos internos en otro lugar que no esté en Base. Un lenguaje cuya audiencia principal es la gente de computación científica se beneficiaría de una terminología correcta. ¿Por qué el concepto de norm se define en Base.LinAlg y inner , que está en la misma cohorte, debe definirse en un paquete? Además de esta inconsistencia, el idioma ya tiene dot , lo que me hace preguntarme por qué debería tener algo tan específico en lugar de un concepto más general.

Entonces, ¿quieres todos los conceptos matemáticos posibles en el idioma base? No tener algo definido en Base no obliga a las personas a usar una terminología incorrecta. La función norm se exporta desde LinAlg porque está definida y se usa en LinAlg . Similar para dot . ¿Está proponiendo que se cambie el nombre dot a inner ?

Entonces, ¿quieres todos los conceptos matemáticos posibles en el idioma base?

Yo nunca dije eso.

No tener algo definido en Base no obliga a las personas a usar una terminología incorrecta.

Estoy seguro de que no. El problema es promover la terminología incorrecta. Las personas con antecedentes menos matemáticos adoptarán el uso del punto porque lo ven en Base. El uso del término producto "punto" para representar el concepto de producto interno es incorrecto. También es perjudicial para la comunidad matemática, que lucha de vez en cuando para arreglar estas cicatrices que ha dejado la terminología incorrecta. Los estudiantes de mi generación constantemente tienen que consultar libros antiguos para obtener la terminología correcta, este no debería ser el caso.

¿Está proponiendo que se cambie el nombre del punto a interior?

Eso ya sería una gran mejora en mi opinión. Vea todos los ejemplos que di anteriormente sobre datos funcionales y de composición. La gente de estas comunidades nunca usaría el término dot en su trabajo. "punto" se parece más a un término informático que a cualquier otra cosa.

Cambiar el nombre dot a inner es una propuesta bastante diferente a agregar inner a Base además de dot . Esa es más una pregunta de "terminología correcta", que usted y otras personas de linalg tendrán que resolver, aunque creo recordar que lo analizamos una vez y concluimos que dot era el nombre correcto para lo que implementa esta función.

Renombrar punto a interior es una propuesta bastante diferente a agregar interior a Base además de punto.

Esto es lo que propuse en mi primer mensaje en este hilo:

Me gustaría proponer cambiar el nombre de dot a internal, o tal vez indicar a los usuarios que definan internal(x,y) como un producto interno general entre los objetos x e y.

Repito, producto punto es el término incorrecto para la operación que estoy discutiendo aquí. Producto interno, externo, escalar... estos son objetos matemáticos. "producto punto" es un objeto computacional: obtiene dos secuencias de números y realiza x1*y1 + x2*y2 + ... xn*yn , una operación inútil en otros espacios matemáticos.

Me había centrado en la segunda opción que proponías, que parece haber sido agregar Base.inner con una alternativa para llamar a Base.dot . Cualquiera de las opciones es posible, pero ambas requieren alguna justificación: para agregar una nueva operación, se necesita una razón por la que no puede estar simplemente en un paquete (de qué se trataba la parte inicial de esta discusión); para cambiar el nombre, se debe decidir que dot es el nombre incorrecto y inner es el correcto (a lo que parece haber llegado la conversación).

@juliohm Probablemente valga la pena (re)afirmar que actualmente hay un esfuerzo activo que intenta reducir Base y fomentar el uso de paquetes. En este caso dot parece ser correcto para todos los tipos que participan en el álgebra lineal proporcionada en Julia estándar (es decir Number y Array , así que sí, hay un definido y conocido , base finita en todos los casos; por lo tanto, no creo que hayamos cometido un error en la terminología, aunque puede haber mejores opciones). No estoy en contra de esta propuesta, pero quería señalar esto para aclarar por qué podría estar experimentando cierta resistencia "latente" al cambio.

También vale la pena tener en cuenta que un buen número de recién llegados a Julia pueden estar familiarizados con un producto escalar pero no con un producto interno (digamos, hicieron un poco de física en la universidad, pero no se especializaron en matemáticas), por lo que también hay algunas razones para mantenga dot (sin mencionar que tenemos un operador infijo con el que se corresponde; podríamos asignarlo a inner , supongo, pero eso es un poco menos obvio). Tampoco tenemos una función outer , o una variedad de otras operaciones posibles.

Por lo tanto, hay una carga para hacer un caso razonable de cómo poner esto en Base (o LinAlg ) es estrictamente mejor que poner esto en un paquete de usuario. La razón principal parece ser proporcionar una interfaz que otros puedan compartir y ampliar. ¿Es un resumen razonable? El argumento de permitir que el código genérico de Clustering.jl funcione con su producto interno parece bastante convincente. Además, en el contexto en el que parece que estamos dividiendo LinAlg en un paquete stdlib, estaba pensando que si tuviera que crear un paquete llamado LinearAlgebra , probablemente estaría feliz de incluir un inner función para que otros la amplíen.

Gracias @andyferris por compartir tus pensamientos. Veo la resistencia muy claramente, que es algo que no me entusiasma mucho. Sin embargo, tengo curiosidad acerca de cómo esta propuesta específica conduce al aumento del código. Para mí, parece un cambio trivial en el código con una mejora importante en la abstracción. El ejemplo con Clustering.jl es solo uno de muchos, piense en cualquier método basado en kernel que pueda funcionar con tipos de Julia arbitrarios para los que existe la noción de producto interno. MultivariateStats.jl tiene muchos de ellos.

Con respecto al comentario sobre la división de LinAlg en un paquete separado, estoy de acuerdo en que parece un buen lugar para encapsular productos matemáticos. Supongo que este paquete LinearAlgebra del futuro se importaría en una sesión de Julia de forma predeterminada y, por lo tanto, todos los usuarios tendrían acceso al concepto de inner , outer , etc. inmediatamente.

Sí, todas las bibliotecas estándar están integradas con la imagen del sistema Julia y están disponibles de forma predeterminada. Al menos para la serie v1.x, nadie necesitará escribir using LinAlg (no creo que se le cambie el nombre a LinearAlgbebra , por cierto, lo inventé como un competidor hipotético) .

Para aclarar, se cargaría con Julia estándar, por lo que no tiene que instalar nada, pero aún tendría que escribir using LinAlg para obtener los nombres que exporta.

Aquí es donde se pone extraño, ¿verdad? Ya que obtendremos los métodos * y así sucesivamente sin using LinAlg ? (en otros términos, LinAlg es un tipo pirata).

Sí, ahí es básicamente donde tendremos que trazar la línea: Base debe definir tanta funcionalidad de álgebra lineal como sea necesario para que LinAlg no sea un pirata, por lo que matmul se define en Base porque Array y * ambos lo son. Sin embargo, los tipos de matrices funky y las operaciones no básicas viven allí.

Déjame darte un ejemplo concreto y preguntarte cómo lo resolverías con la interfaz actual, tal vez esto pueda aclararme las cosas.

El objetivo es realizar un análisis factorial con datos de composición. Tengo un tipo llamado Composition y un producto interno en el espacio de las composiciones. Recojo muchas muestras (por ejemplo, muestras de rocas) y las pongo todas en un gran Vector{Composition} (por ejemplo, composición = %agua, %grano, %aire). Ahora quiero llamar a un algoritmo de análisis factorial implementado en otro paquete (por ejemplo, MultivariateStats.jl) en este vector de datos. ¿Cómo implementaría eso de forma genérica sin tener un producto inner importado de forma predeterminada?

Lo que entendí de los últimos comentarios es que tanto MultivariateStats.jl como CoDa.jl tendrían que depender de LinAlg.jl. La dependencia en MultivariateStats.jl es solo para incluir el nombre inner en el alcance. La dependencia en CoDa.jl es definir un método para inner que MultivariateStats.jl puede llamar. Es eso lo que está sugiriendo?

Parece que Composition{D} es un espacio vectorial dimensional D bajo + y * .

Estaría bastante tentado a definir el espacio vectorial dual.

Por lo tanto, podría definir adjoint(::Composition) -> DualComposition y *(::DualComposition, ::Composition) -> scalar (actualmente inner ). DualComposition no tendría que hacer mucho excepto sostener un Composition adentro.

La primera oración en https://en.wikipedia.org/wiki/Dot_product parece sugerir que dot podría ser una operación en cualquiera de los dos iterables. Podríamos hacerlo recursivo y definirlo para Number , y definir inner como la función de álgebra lineal abstracta, que se superpone para Number y AbstractArray .

Gracias @andyferris , aprecio tus pensamientos sobre el espacio dual. Sin embargo, prefiero no confiar en un nuevo tipo para esta tarea. La solución final es innecesariamente compleja.

Lo que me interesa entender es por qué algo como:

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

export inner, norm

no es bienvenido en Base? Supongo que esto es todo lo que se requiere para definir los nombres de las funciones de forma genérica para que los usuarios del lenguaje se especialicen. Tenga en cuenta que estoy haciendo estas preguntas con el interés genuino de comprender el punto de vista de los desarrolladores principales. Quiero decir esto antes de que la conversación tome la dirección equivocada nuevamente.

Desde la perspectiva de alguien interesado en las matemáticas en general, parece poco natural que estos conceptos no se exporten de forma predeterminada y, en su lugar, se definan dentro de LinAlg . Pienso en LinAlg como implementaciones de estos conceptos de alto nivel para tipos de matrices. Quizás todo mi trabajo no requiera álgebra lineal en matrices, pero aún podría beneficiarme del concepto de producto interno entre paquetes (por ejemplo, MultivariateStats.jl, Clustering.jl). Además, es posible que no desee tener LinAlg como una dependencia en mi paquete porque no lo es.

Si puedo enfatizarlo más, existe el concepto de producto interno, que es independiente de las matrices. Este concepto está representado por la sentencia export inner en Base. Existe la implementación de productos internos para objetos similares a matrices que representan las coordenadas inner(x,y) = sum(x.*y) . Esta operación se puede definir como un método alternativo en Base como el anterior, si es necesario.

Otro ejemplo de un caso de uso son los métodos de Krylov. Si tiene, por ejemplo, espacios de funciones con productos internos, entonces podría usar los métodos de Krylov para aproximar un problema lineal o un problema propio en un pequeño subespacio de dimensión finita de ese espacio de funciones de dimensión infinita.

Yo también tengo mis propios objetos que forman un vector/espacio de Hilbert pero que no forman parte de <: AbstractArray . A partir de la analogía de que también las matrices con rango N>1 forman espacios vectoriales y se pueden usar como 'vectores' en los métodos de Krylov, he llegado a confiar en el uso de vecdot y vecnorm siendo la noción generalizada de producto interior y norma. Así que he estado desarrollando un paquete con métodos Krylov que usa funciones como operadores lineales y donde los 'vectores pueden ser de cualquier tipo, siempre que los objetos de ese tipo admitan vecdot , vecnorm y algunos otras cosas ( scale! , zero , ...). Pero tal vez eso sea abusar de lo que significaban estos conceptos en Base, por lo que sería bueno aclarar la interfaz correcta aquí.

Correcto: vecdot podría cambiarse de nombre inner .

(Ahora me pregunto vagamente si norm en realidad debería llamarse matrixnorm para matrices con norm siempre coincidiendo con inner . Parece que tal vez hay dos distintos cosas que suceden con norm lo que está causando algunas dificultades para generalizarlo)

De hecho, para objetos similares a vectores generales, también es útil consultar la dimensión del espacio vectorial (por ejemplo, para verificar que la dimensión de Krylov no debe ser mayor que la dimensión del espacio completo en mi caso de uso de ejemplo). El ejemplo de matrices anidadas muestra que length no es el concepto correcto aquí, es decir, tendría que haber alguna noción recursiva de longitud para esos casos.

Ahora, para el ejemplo del uso de matrices anidadas como un vector general, vecdot y vecnorm en algunos casos ni siquiera son la noción correcta de producto interno y norma, como se explica en #25093, es decir, son no llamar recursivamente a vecdot y vecnorm . Mi interpretación de estas funciones como un producto interno genérico y una función de norma es lo que desencadenó el # 25093, pero parece que no es así como se pretendían estas funciones (no estoy seguro de qué se pretendía que hicieran en su lugar).

Así que estoy de acuerdo en que necesitamos una interfaz consistente aquí para ser utilizada en todos los paquetes, que por lo tanto pertenecería a una ubicación central (probablemente no en Base pero ciertamente en una Biblioteca estándar, por ejemplo, que uno tiene que hacer using VectorSpaces ). En cuanto a los nombres, veo dos opciones:

Opción 1 (mi interpretación hasta ahora):
el prefijo vec indica la propiedad de ese objeto al interpretarlo como un vector genérico, por lo tanto

  • vecdot y vecnorm para arreglos anidados son fijos (PR #25093)
  • se agrega una nueva definición veclength

Opción 2 (probablemente mejor): use más nombres matemáticamente correctos

  • inner
  • dimension
  • Pero, ¿qué hacer con norm ?

Y, por último, simplemente haga ping a @stevengj , ya que seguramente tendrá algunos comentarios útiles; Mis disculpas si esto es un inconveniente.

El nombre es la parte menos interesante de todo esto. No tengo problemas con el uso de la función dot para referirme a un producto interno general para espacios de Hilbert arbitrarios. No solo no hay otro significado razonable para, por ejemplo, "producto escalar de dos funciones", sino que es bastante común ver "producto escalar de funciones" en el uso informal, especialmente en entornos pedagógicos donde se intenta enfatizar la analogía con el vector de dimensión finita. espacios.

@juliohm , inner(x,y) = sum(x.*y) ni siquiera es un producto interno en general, por lo que sería una alternativa bastante terrible para poner en la base.

Pero dot ya no calcula el producto interno correcto (de hecho falla) para varios objetos en Base que se comportan como vectores, por ejemplo, matrices con rango N>1 o matrices anidadas (los vectores anidados son el único caso donde funciona correctamente). Además, el nombre genérico norm se vuelve ambiguo para las matrices, porque estoy de acuerdo con la elección actual de que esto devuelva la norma inducida, pero ocasionalmente también se requiere la "norma vectorial" (norma de Frobenius).

Por lo tanto, mi propuesta de menor impacto sería dejar de lado la semántica vecnorm(x) = norm(vec(x)) y más bien interpretar vecnorm(x) como "para que x sea un objeto de algún tipo genérico que se comporte como un espacio vectorial, calcule la norma vectorial correspondiente de x " (y similar con vecdot ). Si bien este es un cambio en la interpretación (y, por lo tanto, en la documentación), la implementación/acción real para los objetos en Base no sería muy diferente (PR #25093) y produciría el mismo resultado para la mayoría de los casos (rango N arreglos de escalares o de vectores). Una función veclength(x) que devuelve la dimensión de espacio vectorial correspondiente de x completaría la interfaz.

Los paquetes personalizados deberían aprender a implementar estas funciones cuando definen nuevos tipos que se comportan como vectores.

es bastante común ver "producto punto de funciones" en el uso informal, especialmente en entornos pedagógicos donde uno intenta enfatizar la analogía con los espacios vectoriales de dimensión finita

Por favor, no digas que el nombre no es importante, porque lo es. Lo repetiré por enésima vez: el producto interior y el producto escalar no son lo mismo. Cualquier material serio que exponga el trabajo con espacios abstractos de Hilbert nunca usará "punto". Si prefiere confiar en Wikipedia en lugar de mis palabras, aquí están las definiciones copiadas y pegadas:

Producto Interno

En álgebra lineal, un espacio de producto interno es un espacio vectorial con una estructura adicional llamada producto interno. Esta estructura adicional asocia cada par de vectores en el espacio con una cantidad escalar conocida como el producto interno de los vectores.

producto punto

En matemáticas, el producto punto o producto escalar es una operación algebraica que toma dos secuencias de números de igual longitud (generalmente vectores de coordenadas) y devuelve un solo número.


Esta resistencia a mejorar la terminología y la consistencia matemática en el idioma es desmotivante. No importa cuántos hechos les presente, no importa la cantidad de ejemplos y casos de uso, no hay otro argumento en contra que no sea "Estoy bien con el punto".

@juliohm , la terminología es una cuestión de convención, no de corrección. Estoy de acuerdo en que en el uso formal de los espacios de Hilbert, especialmente los de dimensión infinita, el término "producto interno" se usa casi exclusivamente. Pero, como dije, si busca en Google "funciones de productos punto" también encontrará muchos usos informales de esa terminología. Si dices "toma un producto escalar de dos elementos de este espacio de Hilbert", todo matemático sabrá que te estás refiriendo a un producto interno, incluso para espacios de dimensión infinita, por lo que no hay peligro real de confusión, porque no hay otro generalización estándar del término "producto escalar". Es por eso que no encuentro que el debate ortográfico de "punto" versus "interior" sea un tema central.

Es importante decidir sobre la semántica que se quiere aquí y el conjunto de funciones que los tipos deberían implementar si definen un nuevo espacio de Hilbert o un espacio de Banach. Actualmente, si desea definir un tipo que represente un nuevo espacio de Hilbert, podría decirse que debería definir dot y norm (dado que actualmente carecemos de una alternativa para este último), y supongo que adjoint si desea la asignación a un objeto de doble espacio.

Como dice @Jutho , todo esto se complica por el caso de la matriz de matrices, ya que hay varias cosas posibles que uno podría querer allí. Dado que no hay nombres estandarizados para todas las semánticas posibles, es difícil encontrar nombres/semánticas que satisfagan a todos. Vea el #25093 para la discusión de la semántica de vecdot . No tengo una buena respuesta aquí, yo mismo.

Algunas posibilidades aquí

  1. Suma de x[i]' * y[i] . Actualmente, esto es dot(x,y) . No es un producto interno para vectores de matrices (donde da una matriz), y actualmente no está definido todo para matrices multidimensionales.
  2. Suma de dot(x[i], y[i]) , incluidos los arreglos multidimensionales, y conj(x)*y para Number . Actualmente, esto es vecdot(x,y) .
  3. Algunas funciones, por ejemplo, inner(x,y) definidas para ser siempre un verdadero producto interno, y para las matrices hacen que sume inner(x[i],y[i]) , esencialmente el "vecdot recursivo" que quiere @Jutho . Pero entonces, para matrices A , este producto interno es inconsistente con la norma inducida norm(A) que es nuestra definición actual norm . Para solucionarlo, tendríamos que cambiar norm(A) para que las matrices se ajusten de forma predeterminada a la norma de Frobenius, lo que podría ser un cambio importante de gran alcance.

Una pregunta (parcialmente discutida en # 25093) es si necesitamos los tres en Base, o si podemos salirnos con la nuestra con dos (y cuáles dos, y cómo los llamamos). La propuesta de @Jutho , según tengo entendido, es esencialmente eliminar la opción 2 en Base y luego usar vecdot y vecnorm para la opción 3. Entonces tenemos un verdadero producto interno, pero la terminología es bastante exclusivo de Julia, y un poco extraño, por ejemplo, para espacios de Hilbert de dimensión infinita. Eso no sería el fin del mundo, por supuesto.

Otra posibilidad (algo independiente de lo que hagamos con vecdot ) sería volver (volver) a requerir que dot sea un verdadero producto interno. es decir, elimine el comportamiento 1 y haga que dot(x::AbstractVector, y::AbstractVector) sea igual a sum dot(x[i],y[i]) . Todavía no lo defina para matrices multidimensionales (para mantener la coherencia con norm ).

Mi inclinación personal actual sería definir dot como un verdadero producto interno (que debería ser consistente con norm ), cambiándolo a la suma de dot(x[i],y[i]) para vectores (es decir, cambiando el caso del vector de matrices), y continúa sin definirlo para arreglos multidimensionales. Luego defina vecdot para llamar recursivamente a vecdot como sugiere @Jutho , con un respaldo vecdot(x,y) = dot(x,y) . Finalmente, diga que los nuevos tipos de "espacio de Hilbert" deben definir dot y norm . Este me parece el cambio menos disruptivo y más comprensible para mí.

(Un norm(x) = sqrt(real(dot(x,x))) también es una posibilidad, aunque es algo peligroso ya que es vulnerable a un desbordamiento falso. Tenga en cuenta que no podemos usar sqrt(dot(x,x)) como respaldo por razones técnicas: queremos un resultado Real , no un resultado de Complex ).

Gracias @stevengj por esta reacción informativa. Solo un pequeño comentario:

con un respaldo vecdot(x,y) = dot(x,y) . Finalmente, diga que los nuevos tipos de "espacio de Hilbert" deben definir dot y norm .

Hay dos problemas con eso. El vecdot(x,y) = dot(x,y) no puede existir, ya que vecdot ya acepta argumentos de Any para tratar con iteradores generales. El segundo problema es que, si se expone que dot y norm son el verdadero producto interno y la norma que debe definir cualquier vector como el tipo de usuario, incluso al escribir un paquete con, por ejemplo, métodos Krylov que debería funcionar con tipos vectoriales completamente genéricos, aún no funcionará en el caso en que el usuario desee utilizar matrices anidadas o multidimensionales como objetos vectoriales. Por lo tanto, diría que vecdot y vecnorm son el producto interno general y la norma de los objetos similares a vectores. Esto también encaja muy bien con el hecho de que para las matrices, la mayoría de la gente esperará que norm sea la norma del operador/matriz inducida.

En cuanto a un caso de uso real (para mostrar que este no es un caso excepcional). Las matrices estocásticas tienen un valor propio más grande (Perron-Frobenius) para el cual el vector propio correspondiente representa una distribución de probabilidad de punto fijo. En su generalización cuántica, la distribución de probabilidad se generaliza a una matriz definida positiva (la matriz de densidad) y dicha matriz es el punto fijo (vector propio correspondiente al valor propio más grande) de un mapa completamente positivo, es decir, el mapa rho -> sum(A[i] rho A[i]^\dagger for i = 1:N) donde rho es la matriz de densidad y A[i] es una matriz para cada i (conocidos como los operadores de Kraus que representan el mapa completamente positivo). Para dimensiones de matriz grandes, un método de Arnoldi es ideal para encontrar la matriz de densidad de punto fijo.

Mi inclinación personal actual sería definir el punto como un verdadero producto interno (que debería ser consistente con la norma), cambiándolo a la suma del punto (x[i],y[i]) para vectores. Finalmente, diga que los nuevos tipos de "espacio de Hilbert" deben definir punto y norma.

Eso ya es una gran mejora. Documentar dot para tener inner semántica en Base al menos permitirá a los usuarios definir sus propios espacios sin importar bibliotecas innecesarias. No estoy contento con el nombre, pero al menos la funcionalidad estaría disponible para quienes la necesiten.

Sí, creo que sería bueno tener una interfaz documentada para implementar para tipos de "Hilbert-space".

Por supuesto, pensando en esta interfaz genérica para espacios vectoriales, si incluye norm como se sugirió anteriormente, entonces esa debería ser la norma de Frobenius para matrices (y generalizar para matrices de mayor dimensión, ya que todas las matrices son elementos de un vector espacio). En ese caso, necesitaríamos una función de "norma de operador" separada para matrices ( matnorm o opnorm o algo así, o un argumento de palabra clave en norm ...).

@andyferris , tenga en cuenta mi último comentario. norm y dot no pueden convertirse en la interfaz espacial general de Hilbert, ya que ni siquiera funcionan en objetos similares a vectores en Julia, como matrices de dimensiones superiores y matrices anidadas. Por lo tanto vecdot y vecnorm son candidatos 'mejores' (en el sentido de menos ruptura) para esto.

Retomando este tema, que considero bastante relevante para el tipo de matemáticas que espero hacer con el idioma en un futuro cercano. ¿Existe un consenso sobre lo que se hará para mejorar la generalidad y la semántica de los productos internos?

Aquí está la parte de mi ontología matemática personal relacionada con el producto.
Si pudiera ayudar a repasar la memoria/traer consenso

Bonificación: sin referencias de wikipedia

En este punto, la propuesta de @Jutho en #25093 parece el cambio menos disruptivo, aunque la terminología vec* me resulta un poco extraña en este contexto.

Estoy de acuerdo en que la terminología vec* es extraña. Es por eso que cambiar el nombre de las funciones para que tengan nombres estándar sería beneficioso para todos los usuarios.

También estoy de acuerdo en que la terminología vec* es extraña.

Estoy de acuerdo, como alternativa a vecdot podríamos introducir un nuevo método inner , pero no conozco un buen nombre para "reemplazar" vecnorm . De hecho, no encuentro vecnorm tan malo, la norma vectorial es un término bien establecido y explícito para la operación que queremos.

El problema básico aquí es con matrices y arreglos multidimensionales, para los cuales el norm(A) habitual no corresponde a un producto interno, así como con arreglos de arreglos como se discutió anteriormente. Se requiere algo de desambiguación (por ejemplo vec* o fro* ) en estos casos para indicar qué producto interno se pretende.

Podría tener una función inner que por defecto sea vecdot , pero es un poco tonto tener dos nombres para la misma función, y aún queda el problema de cómo llamar a la norma.

También encuentro extraño el nombre vecdot , de hecho, ni siquiera sabía que existía y había creado mi propia función para él... llamada inner .

Según tengo entendido, podemos desaprobar el extraño vecdot a favor de inner y darle la semántica interna del producto para que los usuarios implementen sus propios espacios.

Con respecto a los norm , eso no lo sé. Abrí este tema para discutir productos internos, quizás otro tema sería apropiado para discutir el estado de las normas en Base.

Supongo que podríamos tener inner(x,y) y innernorm(x) = sqrt(inner(x,x)) (con casos especiales optimizados para evitar el desbordamiento) en lugar de vecdot y vecnorm . innernorm es un poco inusual pero es razonablemente claro en contexto.

Pulgares arriba por este cambio. Los nombres inner y innernorm son claros y coherentes con los conceptos. Ojalá pudieran llegar a Julia v1.0.

inner y innernorm me parecen bien.

Todavía diría que, en mi opinión, nuestra función norm realmente no encaja muy bien en la función genérica y el sistema de despacho de Julia y lo que yo llamaría "interfaces claras" donde el despacho no debería estar haciendo opciones semánticas, solo opciones de implementación. Personalmente, preferiría que pudiéramos decir " norm devuelve la norma de un elemento de un espacio vectorial", donde las matrices y los operadores lineales siguen siendo elementos de espacios vectoriales (puede agregarlos y multiplicarlos por un escalar) . También podríamos tener, por ejemplo, " opnorm devuelve la norma del operador de un operador lineal" (o matnorm o lo que sea).

Por el momento tenemos " norm devuelve la norma de un elemento de un espacio vectorial, a menos que el elemento sea también un operador lineal, en cuyo caso le daremos la norma del operador". Personalmente, creo que el envío nunca debería ser sorprendente.

Es decir, preferiría una función que siempre haga la norma del vector y otra función que siempre haga la norma del operador, y ninguna función que intente hacer ambas cosas.

Me gusta aún más @andyferris :+1: Las normas específicas que no son las normas inducidas por el producto interno en el espacio podrían tener un nombre más específico. El nombre norm significaría exactamente norm(x) = sqrt(inner(x,x)) y podría redefinirse según sea necesario para los tipos de usuario.

Personalmente, preferiría que pudiéramos decir " norm devuelve la norma de un elemento de un espacio vectorial"

La función actual norm satisface esa definición. Para matrices, calcula la norma inducida (operador), que es una norma perfectamente válida para un espacio vectorial . (Los espacios vectoriales no tienen que tener productos o normas internas en absoluto).

Puede estar un poco confundido acerca de la definición de una "norma" si piensa que la norma del operador no es una "norma de un espacio vectorial".

Esta también es una distinción útil entre norm y innernorm . Si define norm , diría que solo implica que tiene un espacio de Banach (o al menos un espacio vectorial normado). Si define innernorm , implica que tiene un espacio de Hilbert (o al menos un espacio de producto interno) y que esta norma es consistente con inner .

Por ejemplo, la integración numérica adaptativa (ala quadgk) es algo que solo requiere un espacio vectorial normado, no un espacio de producto interno.

Claro, lo siento, tal vez fui un poco impreciso con mi lenguaje. Obviamente, hay muchas normas válidas para un espacio vectorial, incluidas varias normas de operadores.

Supongo que lo que quiero decir es que tal vez preferiría que la elección de qué norma sea más explícita que implícita. Y que si usa la misma función (sin, por ejemplo, argumentos de palabras clave adicionales) obtiene la "misma" norma, en cuyo caso el euclidiano parece una opción algo defendible para AbstractArray .

Esta también es una distinción útil entre norm y innernorm . Si define la norma, diría que solo implica que tiene un espacio de Banach (o al menos un espacio vectorial normado). Si define innernorm , implica que tiene un espacio de Hilbert (o al menos un espacio de producto interno) y que esta norma es consistente con inner .

Esto parece razonable, pero todavía me pregunto por qué si un objeto tiene un innernorm necesitaría un norm diferente . Alternativamente, propondría que la interfaz para el espacio de Banach requiera norm mientras que una interfaz para los espacios de productos internos proporcionaría tanto norm como inner . Estas funciones se pueden usar en código genérico que espera objetos de Banach o espacios de productos internos según corresponda (EDITAR: con la idea de que el código que funciona en espacios de Banach automáticamente también funcionará en espacios de productos internos).

Creo que está proponiendo que norm(x) siempre se refiera a algún tipo de norma euclidiana basada en elementos (es decir, una norma de Frobenius para matrices), es decir, básicamente lo que vecnorm es ahora módulo el caso recursivo. En este caso, también podríamos redefinir dot(x,y) para que sea el producto interno correspondiente ( inner también funciona, pero dot tiene la ventaja de una variante infija x ⋅ y ).

Estoy bien con esto en principio, pero sería un cambio importante y podría ser un poco tarde antes de la 0.7 para incorporarlo...

¿Es L2 un buen valor predeterminado también en alta dimensión?
Este artículo habla sobre la distancia, pero puede ser que también se refiera a la norma.
https://stats.stackexchange.com/questions/99171/por qué-la-distancia-euclidiana-no-es-una-buena-métrica-en-altas-dimensiones

En este caso, también podríamos redefinir dot(x,y) para que sea el producto interno correspondiente (inner también funciona, pero dot tiene la ventaja de una variante infija x ⋅ y)

¿Podemos deshacernos de dot por completo? La notación de infijo no debe estar relacionada con la existencia de una función llamada dot . Simplemente defina el infijo con el método inner para las matrices de Julia. ¿Es eso posible?

Eso es realmente lo que es, el producto escalar: una notación conveniente x ⋅ y para productos internos entre vectores x e y en R^n con geometría euclidiana.

@stevengj Creo que es un buen resumen, sí.

@o314 ¿L2 es un buen valor predeterminado en alta dimensionalidad? Posiblemente no, pero realmente lo odiaría si, por ejemplo, la norma elegida por norm(v::AbstractVector) dependiera de length(v) :) Tampoco me gustaría adivinar si mi matriz o una matriz de mayor dimensión es "demasiado grande para L2" - ¿Sugiero que tal vez el usuario debería marcar esto explícitamente?

@juliohm Eso es definitivamente posible, aunque como se mencionó, estos son cambios importantes que sugerimos. (Nuevamente, módulo qué hacer en el caso recursivo y discusiones anteriores sobre las posibles diferencias entre inner y dot ).

@stevengj , mi interpretación de lo que implicaba @andyferris es que, debido a la tipificación de pato, es difícil decidir si un usuario quiere interpretar un objeto como un vector (y usar un vector correspondiente p -norma) o como operador (y calcular una norma p inducida). Entonces creo que no hay más remedio que especificar explícitamente qué comportamiento se quiere. El enfoque actual es un poco extraño en el sentido de que norm intenta adivinar implícitamente si elegir la norma vectorial o la norma inducida en función de la entrada, y vecnorm es una forma de especificar explícitamente que desea la norma vectorial (que también es la razón por la que no encuentro vecnorm tan mal nombre). Un cambio más radical sería hacer que norm siempre tenga por defecto la norma vectorial y especificar explícitamente cuándo desea la norma inducida, usando un argumento (palabra clave) o una función completamente diferente.

Por otro lado, tampoco me importa el nombre innernorm , que es explícito en el sentido de que se trata de una norma interna basada en el producto (es decir, siempre p=2 en el caso euclidiano). Me resulta difícil juzgar si los objetos personalizados (vec)norm deben admitir un argumento opcional p como parte de la interfaz, ya que en algunos de mis casos de uso, solo p=2 es fácil computar.

Eso es realmente lo que es, el producto escalar: una notación conveniente x ⋅ y para productos internos entre vectores x e y en R^n con geometría euclidiana.

Estoy de acuerdo con esto, en el sentido de que no recuerdo haber visto nunca la notación x ⋅ y en el contexto de espacios vectoriales generales (por ejemplo, complejos). Creo que solo se usa la notación matemática (x,y) o la notación de Dirac < x | y > en tales casos. En electromagnetismo, a menudo se usa E ⋅ B para vectores en el espacio euclidiano tridimensional, e incluso si se usa notación compleja (es decir, fasores), esto no implica una conjugación compleja. Si es necesario, la conjugación compleja se denota explícitamente en tales casos. Así que no me importaría si dot simplemente se convirtiera en sum(x_i * y_i) sin conjugación compleja o hermítica, y inner se convirtiera en el producto interno correcto para los espacios generales de productos internos. Desafortunadamente, esto probablemente no se pueda hacer en un solo ciclo de lanzamiento.

¿Es L2 un buen valor predeterminado en alta dimensionalidad? Posiblemente no, pero realmente lo odiaría si, por ejemplo, la norma elegida por norm (v:: AbstractVector) dependiera de la longitud (v) :) Tampoco me gustaría adivinar si mi matriz o matriz de mayor dimensión es "demasiado grande para L2": ¿sugiero que tal vez el usuario debería marcar esto explícitamente?

Trabajo en el mundo BIM donde manejamos 2d y 3d, pero también 4d, 5d, 6d pueden ser 7d. Nunca vamos más allá. En cualquier momento sabemos en qué dimensiones trabajamos y qué algoritmo está involucrado. Eso es en gran medida suficiente.

No puedo expresar el punto de vista de las personas que trabajan en ML, recuperación de información, etc. Allí, puede haber una norma y es mejor. Lo que es importante en mi punto de vista es la adivinabilidad y la estabilidad. No me sorprendería en absoluto si las personas en ML necesitan un valor predeterminado diferente para sus cosas. Si no hay confusión. P.ej. se decide explícita y estáticamente en tiempo de compilación. Incluso es un lujo si se mantiene estable y consistente durante la aplicación de algoritmos.

Inspirado en array:similar No completamente implementado y pruébelo.

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

¿Podemos deshacernos del punto por completo? La notación infija no debe estar relacionada con la existencia de una función llamada punto. Simplemente defina el infijo con el método interno para las matrices de Julia. ¿Es eso posible?

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

Dot / vecdot implica usar conjugados y decidir cuándo ir a BLAS. esto tiene que ser manejado en alguna parte. Pero esto debería ser manejable en un solo espacio de nombres.

¿Es L2 un buen valor predeterminado en alta dimensionalidad? posiblemente no

L2 es también la norma más común para espacios de dimensión infinita (por ejemplo, funciones). Creo que es un valor predeterminado razonable para cualquier espacio vectorial.

Obviamente, también desea tener otras normas disponibles. Si redefinimos norm(x) para que sea L2 por elementos siempre que sea posible, entonces norm(x, p) sería Lₚ por elementos, y necesitaríamos alguna otra función (p. ej opnorm ) para el correspondiente inducido/ normas del operador.

Estoy de acuerdo con esto, en el sentido de que no recuerdo haber visto nunca la notación x ⋅ y en el contexto de espacios vectoriales generales (por ejemplo, complejos).

Di varias citas en otro hilo, IIRC (por ejemplo, BLAS usa dot para productos escalares complejos, y puede encontrar fuentes pedagógicas incluso usando el término para productos internos de funciones). El mismo término "producto interno" generalmente se introduce como "una generalización de un producto escalar". No creo que nadie se sorprenda demasiado con la notación de dot para un producto interno euclidiano, y es conveniente tener un operador infijo.

Podríamos mantener dot tal cual e introducir inner , por supuesto, pero creo que eso crearía una dicotomía confusa: en los casos más comunes, las funciones serían equivalentes, pero en casos extraños (por ejemplo, arreglos de matrices) serían diferentes.

Pero nuevamente, podría ser un poco tarde para romper los cambios, por lo que quizás tengamos que recurrir a innernorm y inner . En cualquier caso, alguien necesitaría crear un PR lo antes posible.

Si se forma una medida razonable de consenso, es posible que pueda dedicar algo de ancho de banda a explorar la implementación en una escala de tiempo relevante (corta), incluidos los posibles cambios importantes. Agradezco el impulso para aclarar la semántica de estas operaciones y darles nombres explícitos. ¡Mejor!

Veo dos opciones principales:

  • No se rompe, agrega una característica: inner(x,y) y innernorm(x) . Reemplazando vecdot y vecnorm , y recursivo para arreglos de arreglos.

  • Ruptura: cambie norm(x,p=2) para que sea siempre recursivo y basado en elementos, reemplazando vecnorm , e introduzca una nueva función opnorm para el operador/norma inducida. Haga que dot(x,y) sea el producto punto por elementos correspondiente, reemplazando vecdot . (Alternativa: cambie el nombre a inner , pero es bueno tener un operador infijo, y es molesto tener tanto dot como inner ).

Si estuviera diseñando cosas desde cero, preferiría 2, pero podría ser demasiado perturbador cambiar silenciosamente el significado de norm .

Una opción intermedia sería definir inner y innernorm (dejando en desuso vecdot y vecnorm ), y desfasando norm(matrix) a opnorm . Luego, en 1.0, vuelva a introducir norm(matrix) = innernorm(matrix) . De esa manera, las personas pueden eventualmente usar inner y norm , y dejamos dot como la bestia impar actual para vectores de matrices (que coincide con inner para vectores de números).

Una rareza sobre innernorm es que desea una forma de especificar las normas L1 o Linf "elementwise", pero ninguna de estas corresponde a un producto interno, por lo que innernorm(x,p) es un nombre poco apropiado.

Me gusta tu opción intermedia.

Como se indicó anteriormente, me gusta el nombre innernorm(x) porque implica p=2 y no debería haber un segundo argumento. Tengo objetos para los que solo sé cómo calcular la norma del producto interno. Pero con el (vec)norm actual, no me queda claro si el argumento p es parte de la interfaz Base asumida, por lo que no sé si omitir el segundo argumento o admitirlo. pero luego verifique explícitamente p != 2 y produzca un error.

Pero veo el problema de no tener ninguna forma no obsoleta de hacer vecnorm(matrix, p!=2) durante la etapa intermedia de su propuesta.

También me gusta la opción intermedia: definitivamente queremos pasar por un ciclo adecuado de desaprobación de las normas en lugar de hacer un cambio de ruptura inmediato. (Como usuario, los cambios importantes me asustan, pero veo que corregir las obsolescencias en mi código para v1.0 es como una inversión en un código limpio y claro para el futuro).

¿Necesitaríamos realmente innernorm o podríamos simplemente usar vecnorm por ahora (y desaprobar vecnorm a favor de norm más adelante)?

De hecho, no veo ningún alboroto potencial en simplemente reemplazar dot con inner ... Yo también creo que está suficientemente claro que el producto interno pretende ser una generalización de los productos escalares.

Los cambios podrían implementarse en dos RP separados:

  1. Reemplaza dot con inner y dale el significado generalizado. Opcionalmente, haga que la notación infija \cdot apunte al interior entre las matrices de Julia.
  2. Más ciclos de discusión y desaprobación en torno a las variantes y la terminología de la norma.

Tengo entendido que PR 1 podría fusionarse antes de Julia v1.0. No se está rompiendo.

Reemplazar dot con inner aún estaría fallando porque dot actualmente no es un verdadero producto interno para matrices de matrices, por lo que estaría cambiando el significado, no solo renombrando. Estoy a favor de cambiar el significado para que sea un verdadero producto interno, pero si cambia el significado (definirlo como el verdadero producto interno) no veo el problema en continuar deletreándolo como dot .

Entonces, podríamos hacer lo siguiente en 0.7:

  1. Retirar norm(matrix) a opnorm(matrix) y norm(vector of vectors) a vecnorm .
  2. Retirar dot([vector of arrays], [vector of arrays]) a una llamada a sum .
  3. Diga que vecdot(x,y) y vecnorm(x, p=2) son productos/normas internas euclidianas (para p=2 ), y hágalos recursivos (lo que es un poco disruptivo, pero en la práctica probablemente no sea un gran problema) .

Luego, en 1.0:

  1. Retirar vecnorm a norm y vecdot a dot . (¿No estoy seguro de si esto está permitido por las reglas de versión 1.0, @StefanKarpinski?)

(Tenga en cuenta que la función numpy.inner , sorprendentemente, no siempre es un producto interno. Pero la terminología de NumPy en inner y dot ha sido extraña por un tiempo).

Las razones por las que prefiero seguir deletreándolo como dot :

  • Es bueno tener una ortografía infijo.
  • Para los no matemáticos que operan en espacios vectoriales ordinarios de dimensión finita, dot es un nombre más familiar para el producto interno euclidiano. (Los matemáticos se acostumbrarán fácilmente a usar el nombre dot para la función de producto interno en espacios de Hilbert arbitrarios; "producto escalar" no tiene otro significado posible para tales espacios).
  • Tener inner y dot sería confuso, ya que coincidirían en algunos casos pero quizás en otros no (si mantenemos el significado actual dot ).
  • Fuera del álgebra lineal, inner tiene muchos otros significados potenciales en informática y, por lo tanto, es algo molesto exportar este nombre desde Base.

¿Puede dar más detalles sobre su oposición al nombre interior? todavía no entiendo
es por eso que prefieres ir en contra de una terminología que todos en este hilo parecen
¿llegar a un acuerdo?

El martes 15 de mayo de 2018 a las 5:13 a. m. Steven G. Johnson [email protected]
escribió:

(Tenga en cuenta que el numpy.inner
https://docs.scipy.org/doc/numpy-1.14.0/reference/generated/numpy.inner.html
La función, sorprendentemente, no siempre es un producto interno.)


Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/JuliaLang/julia/issues/25565#issuecomment-389144575 ,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/ADMLbdcpeWo7M4prYz76NoqUPIkfVPP3ks5tysZlgaJpZM4ReGXu
.

Ninguna de las razones me convence:

>

  • Es bueno tener una variante infija.

Sí, y la notación infija aún puede existir independientemente del cambio de nombre a
interno como se explicó anteriormente.

>

  • Para los no matemáticos que operan en dimensiones finitas ordinarias
    espacios vectoriales, punto es un nombre más familiar para el interior euclidiano
    producto. (Los matemáticos se acostumbrarán fácilmente a usar el nombre punto para
    la función de producto interno en espacios de Hilbert arbitrarios: el "producto escalar" no tiene
    otro significado posible para tales espacios.)

Este argumento no es bueno: enseñemos a la gente común el mal.
terminología porque son perezosos y no pueden aprender una nueva palabra apropiada,
y obligar a los matemáticos a utilizar la terminología equivocada en contra de su voluntad.

>

  • Tener tanto interior como punto sería confuso, ya que
    coincidir en algunos casos pero tal vez no en otros (si mantenemos el punto actual
    sentido).

No necesitamos ambos, deshágase del nombre menos general, que estamos de acuerdo es
punto en este punto.

>

  • Fuera del álgebra lineal, el interior tiene muchas otras posibilidades
    significados en informática, y por lo tanto es algo molesto para
    exportar este nombre desde Base.

Fuera del álgebra lineal, puedo encontrar muchos usos para el punto. Más aún por el
notación de punto infijo que significa cosas completamente diferentes.

>

Estoy volviendo a publicar la última publicación de @juliohm con formato fijo.


Ninguna de las razones me convence:

Es bueno tener una variante infija.

Sí, y la notación de infijo aún puede existir independientemente del cambio de nombre a interno como se explicó anteriormente.

Para los no matemáticos que operan en espacios vectoriales ordinarios de dimensión finita, punto es un nombre más familiar para el producto interno euclidiano. (Los matemáticos se adaptarán fácilmente al uso del nombre punto para la función de producto interno en espacios de Hilbert arbitrarios; "producto punto" no tiene otro significado posible para tales espacios).

Este argumento no es bueno: enseñemos a la gente común la terminología incorrecta porque son perezosos y no pueden aprender una nueva palabra apropiada, y obliguemos a los matemáticos a usar la terminología incorrecta en contra de su voluntad.

Tener tanto el interior como el punto sería confuso, ya que coincidirían en algunos casos pero tal vez no en otros (si mantenemos el significado actual del punto).

No necesitamos ambos, deshágase del nombre menos general, que estamos de acuerdo en que es un punto en este punto.

Fuera del álgebra lineal, internal tiene muchos otros significados potenciales en informática y, por lo tanto, es algo molesto exportar este nombre desde Base.

Fuera del álgebra lineal, puedo encontrar muchos usos para el punto. Aún más para la notación de punto infijo que significa cosas completamente diferentes.

Sí, y la notación de infijo aún puede existir independientemente del cambio de nombre a interno como se explicó anteriormente.

Ciertamente puede definir const ⋅ = inner , pero su terminología es inconsistente. Pensé que no te gustaba usar el "producto escalar" como un producto interno general.

Obligar a los matemáticos a usar la terminología incorrecta en contra de su voluntad.

Los matemáticos saben que la terminología no es correcta ni incorrecta, solo es convencional o no convencional (y tal vez consistente o inconsistente). (Y la mayoría de las personas no se dedican a las matemáticas porque les apasiona la ortografía prescriptiva). En mi experiencia, si les dices a los matemáticos que en la mecánica cuántica un vector se llama "estado", el adjunto se llama "daga" y un vector dual se llama "sujetador", son sublimemente despreocupados. Del mismo modo, no creo que ningún matemático experimentado parpadee más de una vez si le dices que en Julia un producto interno se escribe dot(x,y) o x ⋅ y , especialmente porque ya se entiende que los términos son sinónimos en muchos contextos. (Dudo que encuentre algún matemático que no sepa instantáneamente que se está refiriendo a un producto interno si dice "tome el producto escalar de dos funciones en este espacio de funciones").

Por otro lado, para las personas que no son matemáticos capacitados y no han estado expuestos a espacios abstractos de productos internos (es decir, la mayoría de los usuarios), mi experiencia es que la terminología desconocida es más un obstáculo. "¿Cómo obtengo un producto escalar de dos vectores en Julia?" se convertirá en una pregunta frecuente.

Realmente no hay ninguna dificultad matemática que resolver aparte de elegir la semántica. La cuestión de ortografía es puramente de conveniencia y uso.

Fuera del álgebra lineal, puedo encontrar muchos usos para el punto. Aún más para la notación de punto infijo que significa cosas completamente diferentes.

Excepto que Julia y muchos otros lenguajes de programación han tenido dot durante años y no ha sido un problema. inner sería rotura nueva.

En última instancia, la ortografía de esta función (o cualquier otra) es un asunto menor en comparación con la semántica y la ruta de desaprobación, pero creo que la balanza se inclina a favor de dot .

Ciertamente puede definir const ⋅ = interior, pero entonces su terminología es inconsistente. Pensé que no te gustaba usar el "producto escalar" como un producto interno general.

Creo que todavía no lo entiendes. No hay inconsistencia en llamar a punto un producto interno. Es un producto interno, muy específico e inútil para muchos de nosotros. Nada más que sum(x.*y) .

Si el término dot termina en que Julia tiene la semántica de inner , esto será un desastre histórico que les puedo garantizar que muchos se sentirán molestos. Puedo imaginar profesores en un salón de clases explicando cosas como: "Sabes, ahora vamos a definir el producto interno para nuestro espacio, pero alguien en Julia (@stevengj) decidió llamarlo punto".

Me aseguraré de hacer una captura de pantalla de este hilo para referencia futura si eso termina sucediendo.

Eres el único @stevengj que insiste en la terminología dot , nadie más ha manifestado su oposición. Sería bueno si pudieras reconsiderar este hecho antes de tomar una decisión.

Es un producto interno, muy específico e inútil para muchos de nosotros. Nada más que sum(x.*y).

Si cree que el "producto punto" solo puede referirse al producto interno euclidiano en ℝⁿ, entonces no debe definir const ⋅ = inner , debe definir solo ⋅(x::AbstractVector{<:Real}, y::AbstractVector{<:Real}) = inner(x,y) .

No puede tener ambas cosas: o bien inner puede usar como un sinónimo infijo (en cuyo caso el operador infijo es "incorrecto" en su lenguaje y el nombre es inconsistente) o no tiene un sinónimo infijo (excepto en un caso especial).

Puedo imaginar profesores en un salón de clases explicando cosas como: "Sabes, ahora vamos a definir el producto interno para nuestro espacio, pero alguien en Julia (@stevengj) decidió llamarlo punto".

Ja, ja, estoy dispuesto a soportar el calor de este profesor indignado imaginario. En serio, debe mirar más a su alrededor si cree que el término "producto escalar" solo se usa en ℝⁿ, o si los matemáticos se indignan si el término se usa en otros espacios de Hilbert.

esto sera un desastre historico

¿Seriamente?

Esta discusión parece estar erosionándose más allá de lo que uno podría considerar un ambiente acogedor, cívico y constructivo . Las opiniones y los antecedentes difieren, pero por favor absténgase de hacer ataques personales o culpar a alguien y asuma que todas las partes están debatiendo su punto de buena fe.

Puedo imaginar profesores en un salón de clases explicando cosas como: "Sabes, ahora vamos a definir el producto interno para nuestro espacio, pero alguien en Julia (@stevengj) decidió llamarlo punto".

También puede valer la pena señalar aquí que Steven _es_ un profesor. :guiño:

También estoy indeciso sobre la eliminación dot a favor de inner . El término dot se usa bastante, y no tener la función en Julia, cuando está en Python y MATLAB sería sorprendente. Sin embargo, también me gusta el término inner , dado que es más apropiado para espacios vectoriales que no son ℝⁿ, y especialmente para matrices.

Por cierto, mientras probaba qué métodos estaban haciendo en Julia, noté que dot solo funciona en vectores/matrices reales. ¿Es eso intencional?

Tener tanto el interior como el punto sería confuso, ya que coincidirían en algunos casos pero tal vez no en otros (si mantenemos el significado actual del punto).

@stevengj ¿Sería completamente ridículo reemplazar vecdot con inner y también mantener dot ? En este momento, ese problema exacto que está describiendo ya existe, solo con vecdot en lugar de inner .

OK... esperando, ¿cuáles son las sugerencias en vivo? ¿Son para:

  • Adopte dot como un producto interno genérico para una gama más amplia de tipos. Ya es correctamente recursivo en vectores de vectores, pero lo haríamos funcionar en matrices, etc. ( @jebej No siento que tener dot y inner sea tan útil, y como Steven dice, al menos coloquialmente usamos dot para referirnos al producto interno con bastante frecuencia, y esto no es incorrecto , es solo terminología).
  • Considere hacer que norm sea un poco más consistente con los dot anteriores y en todos los AbstractArray , eventualmente introduciendo, por ejemplo opnorm para las normas del operador (en AbstractMatrix ) y tener (en notación de nuevo a antiguo) norm(matrix) == vecnorm(matrix) después de las depreciaciones adecuadas. En este punto, ¿tal vez ya no necesitemos vecdot y vecnorm ?

¿Está bien? Creo que esto al menos nos llevaría a una historia de álgebra lineal relativamente consistente con interfaces "limpias", donde el código genérico puede usar dot y norm como un par confiable para trabajar con espacios de productos internos independiente del tipo.

@andyferris , sí, creo que si hacemos este cambio, solo necesitamos dot y norm (que ahora son las operaciones euclidianas recursivas en matrices o matrices de matrices de cualquier dimensionalidad, aunque para norma también definimos norm(x,p) como la norma p) y opnorm , y ya no tenemos vecdot o vecnorm .

Tenga en cuenta que el cambio a dot es un cambio importante porque dot actualmente no es un verdadero producto interno para vectores de matrices (#22392), algo que se debatió durante mucho tiempo en #22220 ( momento en el que eliminar vecdot no se consideró IIRC). Sin embargo, eso se introdujo en 0.7, por lo que no rompe ningún código publicado real. De hecho, dot en 0.6 ya es el producto escalar euclidiano en matrices de dimensionalidad arbitraria, algo por accidente (#22374). El cambio sugerido aquí restauraría y extendería ese comportamiento 0.6 y cambiaría norm para ser consistente con él.

Una pregunta es si norm(x,p) llamaría a norm(x[i]) o norm(x[i],p) recursivamente. Ambos son comportamientos potencialmente útiles. Me inclino por el primero porque es más general: x[i] puede ser un espacio vectorial arbitrario normado que solo define norm pero no la norma p. Llamar a norm forma recursiva también es lo que hace ahora vecnorm , por lo que es coherente con la desaprobación vecnorm a norm .

@jebej , dot tanto en maestro como en 0.6 funciona para mí en matrices complejas: dot([3im],[4im]) devuelve correctamente 12+0im , por ejemplo.

Otro buen punto acerca de cambiar norm(matrix) para que sea la norma de Frobenius es que es mucho más barato. Es común usar norm(A-B) para tener una idea de cuán grande es la diferencia entre dos matrices, pero no preocuparse demasiado por la elección específica de la norma, pero muchos usuarios no se darán cuenta de que el valor predeterminado actual norm(matrix) requiere que calculemos el SVD.

¡Es maravilloso ver cómo se forma un consenso en torno a varios puntos importantes! :) (A menos que alguien se me adelante (¡hágalo si tiene ancho de banda!) o una etiqueta alfa llegue antes, intentaré implementar los puntos de consenso actuales después del envío #26997). ¡Mejor!

Otro enlace para referencia futura: https://math.stackexchange.com/a/476742

Para ilustrar la mala denominación que aquí se está adoptando conscientemente , y la mala decisión impuesta por una sola mente. Los productos de puntos e internos tienen diferentes propiedades matemáticas. Estás obligando a toda una comunidad en contra de lo que es bien conocido en la literatura matemática.

Y para futuros lectores, qué se debería haber hecho si hubiéramos tenido una decisión colectiva:

# 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

Supongo que seremos las primeras personas en el universo en emplear el término "producto punto" para un producto interno en cualquier cosa menos ℝⁿ. ¡Qué bueno que pude imponer mi voluntad en este hilo (principalmente chantajeando a los otros desarrolladores) para forzar esta innovación en el mundo! El producto escalar ya no estará relegado a una mera "notación": en cambio, será un símbolo que signifique un producto interno (como todos deberían saber, asignar significados a los símbolos es lo opuesto a "notación").

Muy buena toma de decisiones :clap: definitivamente fue un consenso. Lea los comentarios anteriores y verá cómo todos estuvieron de acuerdo. :+1:

O tal vez debería citar algunos comentarios para que quede muy claro cómo fue un consenso:

>

Derecha: vecdot podría renombrarse como interior

por @andyferris

Opción 2 (probablemente mejor): use más nombres matemáticamente correctos

interno
dimensión
Pero, ¿qué hacer con la norma?

por @Jutho

Estoy de acuerdo, como alternativa a vecdot podríamos introducir un nuevo método interno

por @Jutho

También encuentro extraño el nombre de vecdot, de hecho, ni siquiera sabía que existía y había creado mi propia función para él... llamada interior.

por @jebej

Y muchos más...

Las personas pueden debatir a gritos entre sí y plantear muchos puntos de desacuerdo, pero aun así llegar a un consenso (aunque no siempre a la unanimidad) al ser persuadidos y al sopesar los pros y los contras. (Estoy de acuerdo en que hay pros y contras de cada opción aquí). Lamento que el resultado que parece (¡tentativamente!) Estar gelificando aquí no es el resultado que prefería, pero no estoy seguro de cómo piensa. "Impuse" mi voluntad.

(No es que se haya tomado una decisión final, por supuesto; ni siquiera hay un PR todavía, y mucho menos algo fusionado).

Ojalá pudiéramos tomar una decisión basada en la audiencia del idioma. Si alguien elige a Julia como herramienta, estoy seguro de que al menos ha oído hablar del término inner producto. Es un concepto bastante popular y lejos de ser exótico. Las cosas exóticas incluyen "homología persistente", "teoría cuántica", que están menos difundidas, y estaría en contra de incluir este tipo de terminología.

Después de todo, solo quiero tener un lenguaje que sea el mejor lenguaje para computación científica, matemáticas, etc.

@juliohm , todos los argumentos se han basado en las necesidades de quién creemos que es la audiencia, y todos nosotros estamos tratando de hacer que Julia sea el mejor lenguaje posible. Las personas razonables pueden llegar a diferentes conclusiones sobre la terminología, ya que las matemáticas no determinan la ortografía.

En primer lugar, como se mencionó anteriormente, ciertamente puedo estar de acuerdo con la propuesta actual de @stevengj y mantener dot como el nombre general del producto interno. Además, no me gusta la forma en que se desarrolla esta discusión y ciertamente me gustaría que se citara correctamente. @juliohm , la segunda cita que me atribuyes no es mía.

Dicho esto, me gustaría mencionar lo siguiente como elemento de reflexión en la consideración de los pros y los contras. Los siguientes son en su mayoría contras, pero estoy de acuerdo con los pros mencionados por @stevengj. Fácilmente podría haber casos de uso separados para que dot solo signifique sum(x[i]*y[i] for i ...) . En los casos en que la notación de puntos infijos se usa más en matemáticas, este es el significado típico. Como producto interno, la notación de puntos infijos se reserva típicamente (aunque ciertamente no exclusivamente) para espacios vectoriales reales. Otros casos de uso incluyen habilitar cosas como σ ⋅ n con σ un vector de matrices de Pauli y n un vector de escalares. Esta fue una de las motivaciones detrás de la forma en que dot se implementa actualmente, como me señalaron en otro hilo. El hecho de que BLAS decidiera usar solo dot para vectores reales y hacer una distinción entre dotu y dotc para vectores complejos es otra cuestión a considerar. Las personas con experiencia en BLAS pueden confundirse si, al tener vectores complejos, quieren calcular dot(conj(u),v) o dot(u,v) cuando quieren el verdadero producto interno (es decir dotc ). Además, podrían buscar una forma de hacer dotu sin hacer primero una copia conjugada del vector en cuestión.

@Jutho, la cita es suya, su comentario completo se copia a continuación:

Estoy de acuerdo, como alternativa a vecdot, podríamos introducir un nuevo método interno, pero no conozco un buen nombre para "reemplazar" a vecnorm. De hecho, no encuentro vecnorm tan malo, la norma vectorial es un término bien establecido y explícito para la operación que queremos.

En cualquier caso, la cita pretende mostrar cuál es el deseo de muchos aquí (al menos como un primer pensamiento natural) cuando pensamos en este tema. Si cambiaste tu deseo con el tiempo, esa es otra historia. Yo mismo nunca sacaría el término "punto" de mi cabeza durante ningún modelado con espacios de Hilbert. Se siente antinatural e inconsistente con lo que aprendí.

@Jutho : además, podrían buscar una forma de hacer dotu sin hacer primero una copia conjugada del vector en cuestión.

La posibilidad de exportar una función dotu ha surgido de vez en cuando (ver, por ejemplo, #8300). Estoy de acuerdo en que a veces es una función útil: un "producto interno" euclidiano no conjugado (ya no es realmente un producto interno) que es una forma bilineal simétrica (no sesquilineal) dotu(x,y) == dotu(y,x) (no conjugado) incluso para espacios vectoriales complejos . Pero la utilidad de esa operación no se limita a ℂⁿ; por ejemplo, este tipo de producto a menudo aparece en espacios vectoriales de dimensión infinita (funciones) para las ecuaciones de Maxwell como consecuencia de la reciprocidad (esencialmente: el operador de Maxwell en materiales con pérdida típicos es análoga a una "matriz simétrica compleja", simétrica bajo el "producto interno" no conjugado). Entonces, si definimos dot(x,y) como el producto interno euclidiano general (con el primer argumento conjugado), sería bastante natural definir una función dotu(x,y) para el producto euclidiano no conjugado en cualquier espacio vectorial donde tiene sentido. Sin embargo, no veo la posibilidad de una función dotu como argumento contra dot . En la mayoría de los casos, cuando trabaja con espacios vectoriales complejos, desea el producto conjugado, por lo que este es el comportamiento predeterminado correcto.

Pero estoy de acuerdo en que una posibilidad sería definir dot(x,y) = sum(x[i]'*y[i] for i = 1:length(x)) , que es como se define actualmente en el maestro (no 0.6), y definir inner(x,y) como el verdadero producto escalar. Esto tiene la ventaja de proporcionar ambas funciones, las cuales pueden ser útiles en ciertos casos. Sin embargo, entonces tenemos dos funciones que casi siempre coinciden, excepto en los arreglos de matrices, y sospecho que sería un poco confuso decidir cuándo usar una u otra. Muchas personas escribirían dot cuando querían decir inner , y funcionaría bien para ellos en la mayoría de los casos, pero luego su código haría algo inesperado si se pasa una matriz de matrices. Mi sospecha es que en el 99 % de los casos, la gente quiere el verdadero producto interno, y la versión de "suma del producto" se puede dejar en un paquete, si es que realmente se necesita (en lugar de simplemente llamar a sum ).

@juliohm , leí mal su publicación porque pensé que los nombres estaban arriba (en lugar de debajo) de las citas respectivas, por lo tanto, pensé que me atribuía la cita de @jebej . Mis disculpas por eso.

@stevengj , ciertamente no estaba pensando en tener dot(x,y) = sum(x[i]'*y[i] for i = 1:length(x)) como un valor predeterminado razonable. En el caso σ ⋅ n , la conjugación compleja/hermítica del primer o segundo argumento es innecesaria. Entonces, lo que estaba diciendo es que, en muchos (pero no en todos) los casos en los que se usa la notación de punto infijo en fórmulas científicas, su significado coincide con dotu , es decir, sum(x[i]*y[i] for i = 1:length(x)) sin conjugación, tampoco como producto interior en espacios vectoriales reales o como una construcción más general.

Entonces, si tuviera que hacer una propuesta alternativa (aunque no necesariamente la estoy defendiendo), es que tenga dos funciones:

  • dot(x,y) = sum(x[i]*y[i] for i...) , que sigue siendo el producto interno correcto para vectores reales (que es probablemente el caso de uso de las personas que están menos o no familiarizadas con el término producto interno), pero también permite construcciones más generales como σ ⋅ n , y por lo tanto es la función correspondiente a la notación infija

  • inner(x,y) siendo el producto interno siempre válido, con conjugación y recursividad, que será utilizado por personas en contextos más generales y técnicos.

No estoy defendiendo esto como una buena opción para adoptar en el lenguaje Julia, pero creo que así es como se usa en gran parte de la literatura. Cuando se usa el punto infijo, es como un producto interno en el contexto de vectores reales, o en una construcción más general donde solo significa contracción. Cuando se pretende un producto interno general en espacios vectoriales arbitrarios, la mayor parte de la literatura científica (pero ciertamente ha mostrado contraejemplos) cambia a <u,v> o <u|v> (donde en la primera notación todavía hay discusión sobre qué de los dos argumentos se conjuga).

Podría vivir con esta propuesta, pero igualmente podría vivir teniendo solo dot como producto interno general. Al final, es una cuestión de tener una buena documentación, y yo tampoco puedo creer que alguien tropiece con esta elección de "diseño".

@Jutho , estoy de acuerdo en que no es raro definir dot solo para significar contracción. Ciertamente, uno puede encontrar ejemplos en ambos sentidos. Por ejemplo, en lenguajes de programación y bibliotecas populares:

  • Sin conjugar: Numpy dot (y, extrañamente, interior ), Dot de Mathematica, Maxima . , BLAS dotu

  • Conjugado: Matlab's dot , Fortran's DOT_PRODUCT , Maple's DotProduct , Petsc's VecDot , Numpy vdot , BLAS dotc (tenga en cuenta que la falta de la sobrecarga en Fortran 77 hizo imposible llamar a esto dot incluso si quisieran), el punto de Eigen

Por un lado, el producto interno conjugado generalmente se presenta en los libros de texto como la extensión "natural" de la noción de "producto escalar" a vectores complejos; la versión no conjugada es, en cierto sentido, una extensión "antinatural", ya que generalmente no es Lo que quieras. (Considere el hecho de que, de los lenguajes que proporcionan una función conjugada dot en sus bibliotecas estándar (Matlab, Fortran, Julia, Maple), solo Maple proporciona una variante no conjugada, lo que sugiere una falta de demanda). Por otro lado, una función dotu no conjugada es conveniente (como complemento) en ciertos casos especiales (algunos de los cuales mencioné anteriormente).

Si tenemos dot y inner , sospecho que muchas personas terminarán usando dot por accidente cuando realmente quieren inner para que su código sea genérico. (Apuesto a que el inner de Numpy no está conjugado debido a un accidente de este tipo: lo implementaron con arreglos reales en mente y no pensaron en el caso complejo hasta que fue demasiado tarde para cambiarlo, por lo que agregaron el torpemente llamado vdot .) Mientras que si tenemos dot y (posiblemente) dotu , será más claro que dot es la opción predeterminada y dotu es la variante de caso especial.

(Estoy de acuerdo en que ⟨u,v⟩ , ⟨u|v⟩ , o (u,v) son notaciones más comunes para productos internos en espacios de Hilbert arbitrarios, son las que normalmente uso, pero esas notaciones son una no iniciador para Julia Hubo alguna discusión sobre el análisis de paréntesis Unicode como llamadas de función / macro, por ejemplo, # 8934 y # 8892, pero nunca llegó a ninguna parte y parece poco probable que esto cambie pronto).

Estoy totalmente de acuerdo con tu evaluación @stevengj .

Yo también.

Sospecho que es hora de que uno de nosotros juegue con cualquiera de las implementaciones en un PR y vea cómo sale.

@Jutho Siempre vi el producto escalar con matrices de Pauli como una abreviatura de una contracción sobre tensores de orden superior... uno de los espacios vectoriales es real, 3D.

Estoy de acuerdo en que ⟨u,v⟩, ⟨u|v⟩, o (u,v) son notaciones más comunes para productos internos en espacios arbitrarios de Hilbert (son las que normalmente uso), pero esas notaciones no son un comienzo para Julia.

En realidad, sería posible hacer que ⟨u,v⟩ funcione.

@StefanKarpinski : En realidad, sería posible hacer que ⟨u,v⟩ funcione.

Absolutamente, y apoyando esta notación precisa se sugirió en #8934, pero nunca llegó a ninguna parte. (Tenga en cuenta también que los corchetes angulares tienen otros usos comunes, por ejemplo, ⟨u⟩ a menudo denota un promedio de algún tipo). No se rompe y aún podría agregarse en algún momento, pero no parece razonable esperar en el corto término. También es bastante lento escribir \langle<tab> x, y \rangle<tab> , por lo que no es muy conveniente desde el punto de vista de la programación para una operación elemental.

y no podemos sobrecargar <> por ello, ¿verdad?

No

No puedo decir que haya leído todos los comentarios en este enorme hilo, pero solo quiero resaltar algunos puntos, algunos de los cuales se han hecho antes:

  • Distinguir entre punto e interior parece demasiado pedante. De hecho, a mis oídos, parece una tontería porque en francés solo hay un término, "producto escalar", y es difícil diferenciar entre cosas que para mí tienen el mismo nombre ;-)
  • Cuando vienes de numpy y trabajas con matrices complejas, tener dot conjugado de manera predeterminada es lo mejor que existe. No hay punto de decisión aquí, solo quería decir lo feliz que estoy de que ya no tengo que hacer estos conj(dot()) s.
  • Tener dos funciones que tienen el mismo comportamiento en la mayoría de los casos pero que a veces difieren es un mal diseño, y causa y causará confusión, con un código que debería estar llamando a una en realidad llamando a la otra, simplemente porque el usuario no lo sabe mejor. Esto es particularmente molesto con norm : si está codificando un algoritmo de optimización y quiere detenerse cada vez que norm(delta x) < eps , escribirá norm . Pero luego desea optimizar una imagen o algo así, ejecuta su código y de repente se inicia en un SVD indestructible (porque BLAS) de una gran matriz. Esto no es académico, ha causado problemas en Optim.jl y, sin duda, también en otros paquetes. Nadie sabrá que vecnorm existe a menos que tenga una razón específica para buscarlo.
  • Con base en el punto anterior, cualquier solución que fusione dot y vecdot , y norm y vecnorm es buena, incluso si elimina un poco de flexibilidad en casos de matriz de matrices. Para las normas, agregaría que, a menudo, cuando se trabaja con cosas en las que hay múltiples normas definidas (por ejemplo, matrices), lo que el usuario quiere es llamar a norm para obtener una norma, sin importarle cuál. Las normas inducidas son más a menudo de interés teórico que práctico debido a su intratabilidad computacional. También son específicos de la interpretación de matriz 2D como operador en lugar de matriz 2D como almacenamiento (una imagen es una matriz 2D, pero no es un operador en ningún sentido útil). Es bueno tener la posibilidad de computarlos, pero no merecen ser los norm predeterminados. Los valores predeterminados razonables, simples y bien documentados que tienen alternativas detectables son mejores que los intentos de inteligencia (si el usuario quiere hacer algo inteligente, déjelo hacerlo explícitamente).

Por lo tanto, +1 en @stevengj

sí, creo que si hacemos este cambio, solo necesitamos punto y norma (que ahora son las operaciones euclidianas recursivas en matrices o matrices de matrices de cualquier dimensionalidad, aunque para norma también definimos norm(x,p) como la p-norma) y opnorm, y ya no tienen vecdot ni vecnorm.

Una alternativa más "juliana" a norm/opnorm podría ser tener un tipo de operador, que podría envolver una matriz 2D, en la que norm hace opnorm. Esto se puede hacer a nivel de paquetes (varios de los cuales ya existen)

Prefiero escribir opnorm(matrix) que norm(Operator(matrix))

Voy a intervenir desde la galería de maní aquí y decir que me gusta a dónde va esto: vecnorm y vecdot siempre me han molestado. Necesitar pedir explícitamente la norma del operador, que siempre me ha parecido bastante especializado, parece mucho más sensato que tener que pedir una norma que sea mucho más rápida y fácil de calcular (por ejemplo, la norma de Frobenius). Escribir opnorm parece una buena interfaz para solicitar la norma de operador relativamente especializada.

También creo que tener una distinción sutil entre dot y inner probablemente genere confusión y un mal uso desenfrenado. Sermonear a los usuarios sobre qué función _se supone_ que deben usar cuando ambas funciones hacen lo que quieren y una de ellas es más fácil tiende a no funcionar muy bien. Mi impresión es que es relativamente raro en el código genérico que sum(x*y for (x,y) in zip(u,v)) sea realmente lo que desea cuando realmente existe un verdadero producto interno ⟨u,v⟩ . Cuando eso es realmente lo que se quiere, es bastante fácil, claro y eficiente (porque Julia es lo que es) simplemente escribir algo así para calcularlo.

Si llamar a la función u⋅v dot o inner parece la parte menos importante de todo esto. Estoy bastante seguro de que los historiadores no considerarían ninguna opción como un desastre, aunque la idea de que a los historiadores les importaría en absoluto es halagadora. Por un lado, si aceptamos mantener el significado de "verdadero producto interno" de u⋅v , entonces sí, inner es el término matemático más correcto. Por otro lado, cuando hay una sintaxis con un nombre de función correspondiente, tiende a confundir menos a los usuarios cuando el nombre coincide con la sintaxis. Dado que la sintaxis aquí usa un punto, esa regla general admite la ortografía de esta operación como dot . ¿Quizás este podría ser un caso razonable para definir const dot = inner y exportar ambos? Luego, las personas pueden usar o extender el nombre que prefieran, ya que son lo mismo. Si alguien quiere usar cualquiera de los nombres para otra cosa, puede hacerlo, y el otro nombre permanecerá disponible con su significado predeterminado. Por supuesto, eso generaría tres nombres exportados para la misma función dot , inner y , lo que parece un poco excesivo.

¿Es una opción eliminar el símbolo o reemplazarlo con <u,v> ?

Comentarios:

  • Deja clara la intención. Compara estos dos ejemplos:
<u,v> * M * x

contra

u ⋅ v * M * x
  • La sintaxis <u,v> implica asociación: primero operamos sobre u y v y luego sigue el resto de la expresión.

  • Si un usuario hizo el esfuerzo de escribir <u,v> , es muy poco probable que tuviera en mente un simple sum(x[i]*y[i]) . El símbolo es fácil de pasar por alto con los ojos y tiene muchas otras connotaciones. Particularmente, en álgebra lineal, para un espacio vectorial V sobre un campo F, el producto de un escalar α ∈ F con un vector v ∈ V se denota α ⋅ v en varios libros de texto.

  • Eliminar o reemplazar también eliminaría el problema de la exportación de varios nombres. Uno solo tendría que exportar inner y <,> para productos internos generales, con la implementación predeterminada para arreglos que coincidan con la semántica de suma iterable.

  • Si uno necesita definir un producto escalar por vector como el descrito anteriormente para un espacio vectorial V sobre un campo F, podría definir la notación para ello. El espacio vectorial se definiría completamente con una sintaxis corta y agradable, y podría extenderse a un espacio de Hilbert definiendo más <u,v> .

Definitivamente no podemos usar la sintaxis <u,v> ; la sintaxis que podríamos usar es ⟨u,v⟩ ; tenga en cuenta los corchetes Unicode, no los signos menor que y mayor que, < y > . También tenemos u'v como sintaxis para algo que es un producto punto o un producto interno. (No estoy seguro de cuál...)

Sí, lo siento, la versión Unicode. Sería muy claro de leer. También resolvería este problema con varios nombres y gratis para otros fines.

No creo que queramos usar para ningún otro propósito, parece que sería confuso.

Solo imaginando lo maravilloso que sería poder escribir un código que se vea así:

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

para vectores abstractos (o tipos) u,v,w,z ∈ V y escalares α, β ∈ F .

u'v es un producto interno (y un producto punto, si sigue la convención conjugada) solo para arreglos 1d, no para, por ejemplo, matrices. (Esta es otra razón por la que no tiene sentido limitar el punto infijo a matrices 1d, ya que ya tenemos una notación concisa para ese caso).

Stefan, "término matemático correcto" es un error de categoría: la corrección matemática no es un concepto que se aplique a la terminología/notación. (Sustituya "convencional" por "correcto". Pero entonces la preocupación se vuelve menos urgente).

Más casos de uso: https://stackoverflow.com/questions/50408177/julia-calculate-an-inner-product-using-boolean-algebra

Y una derivación formal de productos internos booleanos utilizando la notación ⟨,⟩ : https://arxiv.org/abs/0902.1290

EDITAR: enlace fijo al papel

¿Qué opinas de la propuesta de sintaxis de corchetes angulares? ¿Resolvería los problemas planteados aquí?

Entonces, ¿cuál es exactamente tu propuesta? Es más o menos esto:

  1. Obsoleto dot a inner
  2. Obsoleto u⋅v a ⟨u,v⟩

Entonces, ¿no habría una función dot ni un operador ?

¿Ese cambio sería algo razonable?

Disculpe la demora en responder, estoy en una conferencia con acceso limitado a Internet.

Y solo por claridad y exhaustividad, ¿cuál es la contrapropuesta aquí? ¿Hacer nada?

Para aclarar aún más la propuesta, hay un cambio semántico involucrado: productos internos generalizados.

Aviso: ahora hemos debatido esto hasta el punto en que existe un riesgo real de que no llegue a 0.7-alfa. Eso no significa que no se pueda cambiar después de la alfa, pero habrá mucha más renuencia a cambiar las cosas después de eso.

Sí, desearía tener las habilidades para haber presentado un PR hace mucho tiempo. Está más allá de mis habilidades hacer que suceda, aunque considero que es una característica extremadamente importante.

Incluso descontando la cuestión de la sintaxis del operador, todavía existe cierta complejidad con el sombreado de nombres y las obsolescencias de varias etapas para cada conjunto de conceptos semánticos (actual dot y vecdot y actual norm y vecnorm ).

Para el lado dot , parece que todo el espacio de opciones (nuevamente descontando operadores) es:

I. Silenciosamente rompa dot en vectores de arreglos cambiando el comportamiento en 0.7 a un producto interno sin un depwarn estándar (aunque puede advertir que el comportamiento está cambiando). Desactive vecdot a dot en 0.7 también.
II. En 0.7, desaprobar vecdot en todas las entradas a inner .
tercero En 0.7, desaprobar dot en vectores de matrices a su definición, y dot en otras entradas y vecdot en todas las entradas a inner .
IV. En 0.7, deje de usar dot y vecdot en vectores de matrices, ya sea para funciones no exportadas o para sus definiciones, y vecdot en todas las demás entradas para dot . En 1.0, agregue dot en vectores de arreglos con semántica interna de productos.

Para el lado de la norma, hay cierto consenso en torno a una ruta única (en 0.7, desaprobar norm en matrices a opnorm y posiblemente desaprobar vecnorm a innernorm ; en 1.0 , agregue norm en matrices con la semántica actual vecnorm ), pero eso también da como resultado un nombre adicional en 1.0 (ya sea vecnorm o innernorm ); de nuevo, una forma de evitarlo podría ser desaprobar vecnorm en 0.7 a su definición o a una función no exportada como Base.vecnorm en lugar de un nombre exportado.

...Creo. Espero no haber hecho las cosas más blandas de lo que ya eran.

¿Alguien que esté familiarizado con el código base puede enviar un PR para el cambio?

¿Podemos separar las normas en las que todo el mundo parece estar de acuerdo y hacer eso al menos? El bit dot versus inner es un poco más controvertido, pero no dejemos que eso obstaculice la parte que no lo es.

@StefanKarpinski , tenga en cuenta que están algo acoplados: para los tipos en los que tiene un producto de punto (interno) y una norma, deben ser consistentes.

Ok, realmente no me importa de qué manera va esto. Quien hace el trabajo tiene que decidir.

Tenía un PR ( #25093 ) para hacer que vecdot se comportara como un verdadero producto interno (y vecnorm como la norma correspondiente), haciéndolos recursivos. Esto podría ser útil como punto de partida de cómo deberían ser los futuros dot y norm . Desafortunadamente, mi falta de habilidades de git me hizo arruinar ese PR, así que lo cerré, planeando volver a él después de que se completara la sintaxis de la nueva iteración.

Sin embargo, haberme convertido en padre por segunda vez hace unos días significa que actualmente no hay espacios de "tiempo libre" en mi calendario.

habiendo sido padre por segunda vez hace unos días

¡Felicidades Juto! 🎉

¡Sí, felicidades!

Parece que podría haber cierto consenso en torno a la idea de tener dot y inner , donde:

  1. inner es un verdadero producto interno recursivo
  2. dot = dot(x,y) = sum(x[i]'*y[i] for i = 1:length(x)) conjugado o no, y por lo tanto se superpondría con dot para Vector{<:Number} o Vector{<:Real}

Con respecto a:

Muchas personas escribirían punto cuando querían decir interno, y funcionaría bien para ellos en la mayoría de los casos, pero luego su código haría algo inesperado si se pasa una matriz de matrices.

No creo que eso sea un problema. Dado que esta es una operación bastante poco común, esperaría que las personas al menos la probaran para ver qué hace y/o miraran la documentación.

Creo que lo anterior sería un gran cambio, y no muy disruptivo ya que la semántica de dot no cambia en la mayoría de los casos.

Parece que podría haber cierto consenso en torno a la idea de tener tanto dot como inner

Por el contrario, la discusión de https://github.com/JuliaLang/julia/issues/25565#issuecomment -390069503 parece estar a favor de tener uno u otro, pero no ambos, como se establece, por ejemplo, en https://github. com/JuliaLang/julia/issues/25565#issuecomment -390388230 y bien respaldado con reacciones.

Tal vez inner (y también dot ) deberían ser productos internos/puntos/escalares recursivos y el antiguo comportamiento podría implementarse en funciones como dotc(x,y) = sum(x[i]' * y[i] for i in eachindex(x)) y dotu(x,y) = sum(transpose(x[i]) * y[i] for i in eachindex(x)) ? Los nombres dotu y dotc coincidirían con los nombres BLAS correspondientes.

(Estoy de acuerdo en que ⟨u,v⟩, ⟨u|v⟩, o (u,v) son notaciones más comunes para productos internos en espacios arbitrarios de Hilbert, son las que normalmente uso, pero esas notaciones no son un comienzo para Julia. Hubo alguna discusión sobre el análisis de paréntesis Unicode como llamadas de función/macro, por ejemplo, #8934 y #8892, pero nunca llegó a ninguna parte y parece poco probable que esto cambie pronto).

@stevengj , cuando agregó este párrafo a un comentario anterior, ¿quiso decir que la sintaxis ⟨u,v⟩ es difícil de implementar en el lenguaje?

¿Hay alguna posibilidad de que esta función llegue a Julia v1.0? Tengo tantas ideas y paquetes que dependen de la noción de productos internos generales. Por favor, hágame saber si debo bajar mis expectativas. Perdón por el recordatorio constante.

¿No has visto #27401?

Gracias @jebej y gracias @ranocha por tomar la iniciativa :heart:

cuando agregó este párrafo a un comentario anterior suyo, ¿quiso decir que la sintaxis ⟨u,v⟩ es difícil de implementar en el lenguaje?

No es técnicamente difícil de agregar al analizador, pero ha resultado difícil llegar a un consenso sobre cómo (y si) representar corchetes personalizados en el lenguaje. Vea la discusión en #8934, que no llegó a ninguna parte hace 4 años y no se ha revivido desde entonces. (Agregue eso al hecho de que en diferentes campos las personas usan los mismos corchetes para muchas cosas diferentes, por ejemplo, ⟨u⟩ se usa para promedios de conjunto en física estadística). Otro problema, planteado en #8892, es la similitud visual de muchos Unicode diferentes. soportes.

Gracias @stevengj , agradezco las aclaraciones. Ya estoy muy emocionado de que vamos a tener productos internos generales estandarizados en todos los paquetes. :100: Tal vez la notación de paréntesis angular podría brillar en otro ciclo de lanzamiento en el futuro. No tan importante, pero bastante conveniente para poder escribir código que es literalmente como las matemáticas en nuestras publicaciones.

Si ⟨args...⟩ es una sintaxis válida para llamar al operador anglebrackets o algo así (cómo llamar a la función que llama esta sintaxis es un poco complicado ya que no tenemos ningún precedente), entonces la gente podría optar por cualquier significado que quieran para la sintaxis.

@StefanKarpinski , el argumento en #8934 fue que debería ser una macro. Creo que nunca llegamos a un consenso.

(Si decidimos en Base que anglebrackets(a,b) significa inner(a,b) , eso desalentará a las personas de "optar por el significado que quieran" porque la decisión ya se habrá tomado.
No es una elección terrible, por supuesto, pero puede ser innecesario asignarle un significado en Base siempre que se analicen).

No recuerdo los detalles de esa discusión, pero hacer una macro obviamente me parece una mala idea.

Con #27401 creo que podemos considerar que los productos internos se han estado tomando en serio.

Tradicionalmente, un problema se cierra solo cuando se fusiona el RP relevante...

Claro, podemos dejarlo abierto, supongo. Solo quería sacarlo de la etiqueta de clasificación.

¿Debería cerrarse ya que #27401 se fusionó ahora?

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

Keno picture Keno  ·  3Comentarios

StefanKarpinski picture StefanKarpinski  ·  3Comentarios

tkoolen picture tkoolen  ·  3Comentarios

iamed2 picture iamed2  ·  3Comentarios

TotalVerb picture TotalVerb  ·  3Comentarios