¡La versión 12 se lanza hoy! (Y es un gran salto para Wolfram Language y Mathematica)



Enlaces rápidos


- El camino a la versión 12
- Primero, algunas matemáticas
- El cálculo de la incertidumbre
- Matemáticas clásicas, elementales y avanzadas
- Más con polígonos
- Computación con poliedros
- Geometría de estilo euclid hecha computable
- Volviéndose súper simbólico con teorías axiomáticas
- El problema del cuerpo n
- Extensiones de idiomas y conveniencias
- Más superfunciones de aprendizaje automático
- Lo último en redes neuronales
- Computación con imágenes
- Reconocimiento de voz y más con audio
- Procesamiento de lenguaje natural
- Química computacional
- Computación geográfica extendida
- Muchas mejoras de poca visualización
- Ajuste de la integración de la base de conocimiento
- Integración de Big Data desde bases de datos externas
- RDF, SPARQL y todo eso
- Optimización numérica
- Análisis de elementos finitos no lineales
- Compilador nuevo y sofisticado
- Llamar a Python y otros idiomas
- Más para Wolfram "Super Shell"
- Marionetas de un navegador web
- Microcontroladores independientes
- Llamar al lenguaje Wolfram desde Python y otros lugares
- Vinculación al Universo Unitario
- Entornos simulados para el aprendizaje automático
- Computación Blockchain (y CryptoKitty)
- Y cripto ordinario también
- Conexión a feeds de datos financieros
- Ingeniería de software y actualizaciones de plataforma
- Y mucho más ...


16 de abril de 2019 - Stephen Wolfram


El camino a la versión 12



Hoy estamos lanzando la versión 12 de Wolfram Language (y Mathematica ) en plataformas de escritorio y en Wolfram Cloud . Lanzamos la versión 11.0 en agosto de 2016 , 11.1 en marzo de 2017 , 11.2 en septiembre de 2017 y 11.3 en marzo de 2018 . Es un gran salto de la Versión 11.3 a la Versión 12.0. En total, hay 278 funciones completamente nuevas , en quizás 103 áreas, junto con miles de actualizaciones diferentes en todo el sistema:
imagen

En una " versión entera " como 12, nuestro objetivo es proporcionar nuevas áreas de funcionalidad completamente completas. Pero en cada lanzamiento también queremos ofrecer los últimos resultados de nuestros esfuerzos de I + D. En 12.0, quizás la mitad de nuestras nuevas funciones pueden considerarse áreas de acabado que se iniciaron en versiones anteriores ".1", mientras que la mitad comienza nuevas áreas. Discutiré los dos tipos de funciones en esta pieza, pero haré especial hincapié en los detalles de las novedades al pasar de 11.3 a 12.0.

Debo decir que ahora que 12.0 está terminado, estoy sorprendido de cuánto hay en él y cuánto hemos agregado desde 11.3. En mi discurso de apertura en nuestra Conferencia de Tecnología Wolfram en octubre pasado, resumí lo que teníamos hasta ese momento, e incluso eso tomó casi 4 horas. Ahora hay aún más.

Lo que hemos podido hacer es un testimonio tanto de la fortaleza de nuestro esfuerzo de I + D como de la eficacia del Wolfram Language como entorno de desarrollo. Ambas cosas, por supuesto, se han estado construyendo durante tres décadas . Pero una cosa nueva con 12.0 es que hemos estado permitiendo que la gente vea nuestro proceso de diseño detrás de escena: transmisión en vivo de más de 300 horas de mis reuniones de diseño interno . Entonces, además de todo lo demás, sospecho que esto convierte a la Versión 12.0 en la primera versión de software importante en la historia que se ha abierto de esta manera.

Bien, entonces, ¿qué hay de nuevo en 12.0? Hay algunas cosas grandes y sorprendentes, especialmente en química , geometría , incertidumbre numérica e integración de bases de datos . Pero en general, hay muchas cosas en muchas áreas, y de hecho, incluso el resumen básico de ellas en el Centro de Documentación ya tiene 19 páginas:

imagen

Primero, algunas matemáticas



Aunque hoy en día la gran mayoría de lo que hace Wolfram Language (y Mathematica) no es lo que generalmente se considera matemático, aún ponemos un esfuerzo inmenso en I + D para ampliar las fronteras de lo que se puede hacer en matemáticas. Y como primer ejemplo de lo que hemos agregado en 12.0, aquí está el ComplexPlot3D bastante colorido:

imagen

Siempre ha sido posible escribir el código de Wolfram Language para hacer trazados en el plano complejo. Pero solo ahora hemos resuelto los problemas matemáticos y de algoritmos necesarios para automatizar el proceso de trazar de manera robusta incluso funciones bastante patológicas en el plano complejo.

Hace años, recuerdo trazar minuciosamente la función dilogaritmo , con sus partes reales e imaginarias. Ahora ReImPlot simplemente lo hace:

imagen

La visualización de funciones complejas es (juego de palabras aparte) una historia compleja, con detalles que hacen una gran diferencia en lo que uno nota sobre una función. Por lo tanto, una de las cosas que hemos hecho en 12.0 es introducir formas estandarizadas cuidadosamente seleccionadas (como funciones de color con nombre) para resaltar diferentes características:

imagen

El cálculo de la incertidumbre



Las mediciones en el mundo real a menudo tienen incertidumbre que se representa como valores con ± errores. Hemos tenido paquetes adicionales para manejar "números con errores" por edades. Pero en la Versión 12.0 estamos construyendo computación con incertidumbre, y lo estamos haciendo bien.

La clave es el objeto simbólico Alrededor de [ x, δ ], que representa un valor "alrededor de x ", con incertidumbre δ :

imagen

Puedes hacer aritmética con Around , y hay un cálculo completo de cómo se combinan las incertidumbres:

imagen

Si traza los números Alrededor , se mostrarán con barras de error:

imagen

Hay muchas opciones, como aquí hay una forma de mostrar incertidumbre tanto en x como en y :

imagen

Puede tener alrededor de cantidades:

imagen

Y también puede tener objetos simbólicos Alrededor :

imagen

Pero, ¿qué es realmente un objeto Alrededor ? Es algo donde hay ciertas reglas para combinar incertidumbres, que se basan en distribuciones normales no correlacionadas. Pero no se hace ninguna declaración de que Alrededor de [ x, δ ] represente cualquier cosa que realmente en detalle siga una distribución normal, al igual que Alrededor de [ x, δ ] representa un número específicamente en el intervalo definido por el Intervalo [{ x - δ, x + δ }]. Es solo que los objetos Alrededor propagan sus errores o incertidumbres de acuerdo con reglas generales consistentes que capturan con éxito lo que generalmente se hace en la ciencia experimental.

OK, entonces digamos que haces un montón de medidas de algún valor. Puede obtener una estimación del valor, junto con su incertidumbre, utilizando MeanAround (y, sí, si las mediciones mismas tienen incertidumbres, se tendrán en cuenta al ponderar sus contribuciones):

imagen

Las funciones en todo el sistema, especialmente en el aprendizaje automático, comienzan a tener la opción ComputeUncertainty -> True , lo que les hace dar objetos Alrededor en lugar de números puros.

Alrededor puede parecer un concepto simple, pero está lleno de sutilezas, que es la razón principal por la que se ha tomado hasta ahora para que ingrese al sistema. Muchas de las sutilezas giran en torno a las correlaciones entre incertidumbres. La idea básica es que se supone que la incertidumbre de cada objeto Around es independiente. Pero a veces uno tiene valores con incertidumbres correlacionadas, por lo que, además de Around , también está VectorAround , que representa un vector de valores potencialmente correlacionados con una matriz de covarianza específica.

Hay incluso más sutileza cuando se trata de cosas como fórmulas algebraicas. Si uno reemplaza x aquí con un Around , entonces, siguiendo las reglas de Around , se supone que cada instancia no está correlacionada:

imagen

Pero probablemente uno quiera suponer aquí que aunque el valor de x puede ser incierto, será el mismo para cada instancia, y uno puede hacer esto usando la función AroundReplace (observe que el resultado es diferente):

imagen

Hay mucha sutileza en cómo mostrar números inciertos. Como cuántos ceros finales deberías poner:

imagen

O cuánta precisión de la incertidumbre debe incluir (hay un punto de corte convencional cuando los dígitos finales son 35):

imagen

En casos raros donde se conocen muchos dígitos (piense, por ejemplo, algunas constantes físicas ), uno quiere ir a una forma diferente para especificar la incertidumbre:

imagen

Y sigue y sigue. Pero gradualmente, Around comenzará a aparecer en todo el sistema. Por cierto, hay muchas otras formas de especificar los números Alrededor . Este es un número con un 10% de error relativo:

imagen

Esto es lo mejor que Around puede hacer para representar un intervalo:

imagen

Para una distribución , Around calcula la varianza:

imagen

También puede tener en cuenta la asimetría al dar incertidumbres asimétricas:

imagen

Matemáticas Clásicas, Elementales y Avanzadas



Al hacer que las matemáticas sean computacionales, siempre es un desafío poder "hacer todo bien" y no confundir o intimidar a los usuarios de primaria. La versión 12.0 presenta varias cosas para ayudar. Primero, intente resolver una ecuación quíntica irreducible:

imagen

En el pasado, esto habría mostrado un montón de objetos raíz explícitos. Pero ahora los objetos raíz están formateados como cuadros que muestran sus valores numéricos aproximados. Los cálculos funcionan exactamente igual, pero la pantalla no confronta inmediatamente a las personas con tener que saber sobre números algebraicos.

Cuando decimos Integrar , queremos decir "encontrar una integral", en el sentido de una antiderivada. Pero en el cálculo elemental, las personas quieren ver constantes explícitas de integración (como siempre lo han hecho en Wolfram | Alpha ), por lo que agregamos una opción para eso (y C [ n ] también tiene una nueva y agradable forma de salida):

imagen

Cuando comparamos nuestras capacidades de integración simbólica, lo hacemos realmente bien. Pero siempre se puede hacer más, particularmente en términos de encontrar las formas más simples de integrales (y a nivel teórico, esto es una consecuencia inevitable de la indecidibilidad de la equivalencia de expresión simbólica). En la versión 12.0, hemos seguido recogiendo en la frontera, agregando casos como:

imagen
imagen

En la versión 11.3 presentamos el análisis asintótico, pudiendo encontrar valores asintóticos de integrales, etc. La versión 12.0 agrega sumas asintóticas, recurrencias asintóticas y soluciones asintóticas a las ecuaciones:

imagen
imagen

Una de las mejores cosas de hacer cálculos matemáticos es que nos brinda nuevas formas de explicar las matemáticas en sí. Y algo que hemos estado haciendo es mejorar nuestra documentación para que explique las matemáticas y las funciones. Por ejemplo, aquí está el comienzo de la documentación sobre Límite , con diagramas y ejemplos de las principales ideas matemáticas:

imagen

Más con polígonos



Los polígonos han sido parte del Wolfram Language desde la Versión 1. Pero en la Versión 12.0 se están generalizando: ahora hay una forma sistemática de especificar agujeros en ellos. Un caso de uso geográfico clásico es el polígono para Sudáfrica, con su agujero para el país de Lesotho .

En la versión 12.0, al igual que Root , Polygon obtiene una nueva forma conveniente de visualización:

imagen

Puede calcular con él como antes:

imagen

RandomPolygon también es nuevo. Puede pedir, digamos, 5 polígonos convexos aleatorios, cada uno con 10 vértices, en 3D:

imagen

Hay muchas operaciones nuevas en polígonos. Como PolygonDecomposition , que puede, por ejemplo, descomponer un polígono en partes convexas:

imagen
imagen

Los polígonos con agujeros también introducen la necesidad de otros tipos de operaciones, como OuterPolygon , SimplePolygonQ y CanonicalizePolygon .

Computación con poliedros



Los polígonos son bastante sencillos de especificar: solo da sus vértices en orden (y si tienen agujeros, también da los vértices de los agujeros). Los poliedros son un poco más complicados: además de dar los vértices, tienes que decir cómo estos vértices forman caras. Pero en la Versión 12.0, Polyhedron le permite hacer esto en considerable generalidad, incluidos los huecos (el análogo 3D de agujeros), etc.

Pero primero, reconociendo sus más de 2000 años de historia , la Versión 12.0 introduce funciones para los cinco sólidos platónicos :

imagen

Y dados los sólidos platónicos, uno puede comenzar a computar inmediatamente con ellos:

imagen

Aquí está el ángulo sólido subtendido en el vértice 1 (ya que es platónico, todos los vértices dan el mismo ángulo):

imagen

Aquí hay una operación realizada en el poliedro:

imagen
imagen

Más allá de los sólidos platónicos, la Versión 12 también incorpora todos los " poliedros uniformes " ( n bordes ym caras se encuentran en cada vértice), y también puede obtener versiones simbólicas de poliedros de poliedros con nombre de PolyhedronData :

imagen

Puede hacer cualquier poliedro (incluido uno "aleatorio", con RandomPolyhedron ) y luego hacer los cálculos que desee en él:

imagen
imagen

Geometría de estilo euclid hecha computable



Mathematica y Wolfram Language son muy poderosos para hacer geometría computacional explícita y geometría representada en términos de álgebra . Pero, ¿qué pasa con la geometría de la forma en que se hace en los Elementos de Euclides, en el cual uno hace afirmaciones geométricas y luego ve cuáles son sus consecuencias?

Bueno, en la Versión 12, con toda la torre de tecnología que hemos construido, finalmente podemos ofrecer un nuevo estilo de cálculo matemático, que en efecto automatiza lo que Euclid estaba haciendo hace más de 2000 años. Una idea clave es introducir "escenas geométricas" simbólicas que tienen símbolos que representan construcciones como puntos, y luego definir objetos geométricos y relaciones en términos de ellos.

Por ejemplo, aquí hay una escena geométrica que representa un triángulo a, b, c y un círculo a través de a, byc , con el centro o , con la restricción de que o está en el punto medio de la línea de a a c :

imagen

Por sí solo, esto es solo una cosa simbólica. Pero podemos hacer operaciones al respecto. Por ejemplo, podemos pedir una instancia aleatoria de la misma, en la que a, b, c y o se especifiquen:

imagen

Puede generar tantas instancias aleatorias como desee. Intentamos que las instancias sean lo más genéricas posible, sin coincidencias que no estén forzadas por las restricciones:

imagen

Bien, pero ahora "juguemos Euclides" y encontremos conjeturas geométricas que sean consistentes con nuestra configuración:

imagen

Para una escena geométrica dada, puede haber muchas conjeturas posibles. Intentamos elegir los interesantes. En este caso llegamos a dos, y lo que se ilustra es el primero: que la línea ba es perpendicular a la línea cb. Como sucede, este resultado aparece en Euclides (está en el Libro 3, como parte de la Proposición 31 ), aunque generalmente se llama el teorema de Thales .

En 12.0, ahora tenemos un lenguaje simbólico completo para representar cosas típicas que aparecen en la geometría de estilo Euclides. Aquí hay una situación más compleja, correspondiente a lo que se llama el teorema de Napoleón :

imagen

En 12.0 hay muchas funciones geométricas nuevas y útiles que funcionan en coordenadas explícitas:

imagen
imagen

Para los triángulos hay 12 tipos de "centros" compatibles y, sí, puede haber coordenadas simbólicas:

imagen

Y para apoyar la configuración de enunciados geométricos también necesitamos " aserciones geométricas ". En 12.0 hay 29 tipos diferentes, como "Paralelo" , "Congruente" , "Tangente" , "Convexo" , etc. Aquí hay tres círculos que se afirma que son tangentes por pares:

imagen

Yendo súper simbólico con teorías axiomáticas



La versión 11.3 introdujo FindEquationalProof para generar representaciones simbólicas de pruebas. Pero, ¿qué axiomas deberían usarse para estas pruebas? La versión 12.0 presenta AxiomaticTheory , que proporciona axiomas para varias teorías axiomáticas comunes.

Aquí está mi sistema de axiomas favorito :

imagen

¿Qué significa esto? En cierto sentido, es una expresión simbólica más simbólica de lo que estamos acostumbrados. En algo como 1 + x no decimos cuál es el valor de x , pero imaginamos que puede tener un valor. En la expresión anterior, a, byc son puros "símbolos formales" que cumplen una función esencialmente estructural, y nunca se puede considerar que tengan valores concretos.

¿Qué pasa con el · (punto central)? En 1 + x sabemos lo que significa +. Pero el · pretende ser un operador puramente abstracto. El punto del axioma está en efecto para definir una restricción sobre lo que puede representar. En este caso particular, resulta que el axioma es un axioma para el álgebra booleana , por lo que puede representar a Nand y Nor . Pero podemos derivar las consecuencias del axioma de manera completamente formal, por ejemplo con FindEquationalProof :

imagen

Hay bastante sutileza en todo esto. En el ejemplo anterior, es útil tener · como operador, sobre todo porque se muestra muy bien. Pero no tiene un significado incorporado, y AxiomaticTheory le permite dar algo más (aquí f ) como operador:

imagen

¿Qué hace el "Nand" allí? Es un nombre para el operador (pero no debe interpretarse como algo relacionado con el valor del operador). En los axiomas para la teoría de grupos , por ejemplo, aparecen varios operadores:

imagen

Esto proporciona las representaciones predeterminadas de los distintos operadores aquí:

imagen

AxiomaticTheory sabe sobre teoremas notables para sistemas axiomáticos particulares:

imagen

La idea básica de los símbolos formales se introdujo en la Versión 7, para hacer cosas como representar variables ficticias en construcciones generadas como estas:

imagen
imagen
imagen

Puede ingresar un símbolo formal usando \ [FormalA] o Esc, a, Esc, etc. Pero en la versión 7,
\ [FormalA] se procesó como a . Y eso significaba que la expresión anterior se veía así:

imagen

Siempre pensé que esto parecía increíblemente complicado. Y para la Versión 12, queríamos simplificarlo. Probamos muchas posibilidades, pero finalmente nos decidimos por puntos grises únicos, que creo que se ven mucho mejor.

En AxiomaticTheory , tanto las variables como los operadores son "puramente simbólicos". Pero una cosa que es definitiva es la aridad de cada operador, que se puede preguntar AxiomaticTheory :

imagen
imagen

Convenientemente, la representación de operadores y aridades se puede alimentar inmediatamente a Agrupaciones , para obtener posibles expresiones que involucren variables particulares:

imagen

El problema del cuerpo n



Las teorías axiomáticas representan un área histórica clásica para las matemáticas. Otra área histórica clásica, mucho más en el lado aplicado, es el problema de los n cuerpos . La versión 12.0 presenta NBodySimulation , que ofrece simulaciones del problema de n cuerpos. Aquí hay un problema de tres cuerpos (piense en la Tierra, la Luna y el Sol ) con ciertas condiciones iniciales (y la ley de la fuerza del cuadrado inverso):

imagen

Puede preguntar sobre varios aspectos de la solución; esto traza las posiciones en función del tiempo:

imagen

Debajo, esto es solo resolver ecuaciones diferenciales, pero, un poco como SystemModel , NBodySimulation proporciona una forma conveniente de configurar las ecuaciones y manejar sus soluciones. Y sí, las leyes de fuerza estándar están incorporadas, pero puedes definir las tuyas.

Extensiones de idiomas y conveniencias



Hemos estado puliendo el núcleo del Wolfram Language durante más de 30 años, y en cada versión sucesiva terminamos introduciendo algunas nuevas extensiones y comodidades.

Hemos tenido la función Información desde la Versión 1.0, pero en 12.0 la hemos ampliado enormemente. Solía ​​dar información sobre los símbolos (aunque también se ha modernizado):

imagen

Pero ahora también proporciona información sobre muchos tipos de objetos. Aquí hay información sobre un clasificador:

imagen

Aquí hay información sobre un objeto en la nube:

imagen

Desplácese sobre las etiquetas en el "cuadro de información" y podrá encontrar los nombres de las propiedades correspondientes:

imagen

Para las entidades, la información proporciona un resumen de los valores de propiedad conocidos:

imagen

En las últimas versiones, hemos introducido muchos nuevos formularios de visualización de resumen. En la versión 11.3 presentamos Iconize , que es esencialmente una forma de crear un formulario de visualización de resumen para cualquier cosa. Iconize ha demostrado ser aún más útil de lo que anticipamos originalmente. Es ideal para ocultar una complejidad innecesaria tanto en las libretas como en partes del código Wolfram Language. En 12.0 hemos rediseñado la forma en que Iconize muestra, particularmente para que se "lea bien" dentro de las expresiones y el código.

Puede iconizar explícitamente algo:

imagen

Presione el + y verá algunos detalles:

imagen

Prensa imagen y obtendrás la expresión original nuevamente:

imagen

Si tiene muchos datos a los que desea hacer referencia en un cálculo, siempre puede almacenarlos en un archivo o en la nube (o incluso en un repositorio de datos ). Sin embargo, generalmente es más conveniente simplemente ponerlo en su computadora portátil, para que tenga todo en el mismo lugar. Una forma de evitar que los datos "se apoderen de su computadora portátil" es colocar celdas cerradas . Pero Iconize ofrece una forma mucho más flexible y elegante de hacerlo.

Cuando escribes código, a menudo es conveniente "iconizar en el lugar". El menú del botón derecho ahora le permite hacer eso:

imagen

Hablando de visualización, aquí hay algo pequeño pero conveniente que agregamos en 12.0:

imagen

Y aquí hay un par de otras "conveniencias numéricas" que agregamos:

imagen
imagen

La programación funcional siempre ha sido una parte central del Wolfram Language. Pero continuamente buscamos extenderlo e introducir nuevas primitivas generalmente útiles. Un ejemplo en la versión 12.0 es SubsetMap :

imagen
imagen

Las funciones son normalmente cosas que pueden tomar varias entradas, pero siempre dan una sola pieza de salida. Sin embargo, en áreas como la computación cuántica , uno está interesado en tener n entradas y n salidas. SubsetMap implementa eficazmente n-> n funciones, recogiendo entradas de n posiciones especificadas en una lista, aplicando alguna operación a ellas y luego volviendo a colocar los resultados en las mismas n posiciones.

Comencé a formular lo que ahora es SubsetMap hace aproximadamente un año. Y rápidamente me di cuenta de que en realidad podría haber usado esta función en todo tipo de lugares a lo largo de los años. Pero, ¿cómo debería llamarse este particular "bulto de trabajo computacional"? Mi nombre de trabajo inicial fue ArrayReplaceFunction (que acorté a ARF en mis notas). En una secuencia de reuniones (livestreamed) fuimos y salimos. Hubo ideas como ApplyAt (pero en realidad no es Apply ) y MutateAt (pero no está haciendo mutación en el sentido del valor), así como RewriteAt , Reemplazar , MultipartApply y ConstructInPlace . Hubo ideas sobre formas curriculares de "decorador de funciones", como PartAppliedFunction , PartwiseFunction , AppliedOnto , AppliedAcross y MultipartCurry .

Pero de alguna manera, cuando explicamos la función, volvimos a hablar sobre cómo funcionaba en un subconjunto de una lista y cómo era realmente como Mapa , excepto que estaba operando en múltiples elementos a la vez. Así que finalmente nos decidimos por el nombre SubsetMap . Y, en otro refuerzo de la importancia del diseño del lenguaje, es notable cómo, una vez que uno tiene un nombre para algo como esto, inmediatamente puede razonar sobre ello y ver dónde se puede usar.

Más superfunciones de aprendizaje automático



Durante muchos años hemos trabajado arduamente para que Wolfram Language sea el sistema de más alto nivel y más automatizado para realizar aprendizaje automático de última generación . Al principio, presentamos las "superfunciones" Clasificar y predecir que realizan tareas de clasificación y predicción de forma completamente automatizada, eligiendo automáticamente el mejor enfoque para la entrada particular dada. En el camino, hemos introducido otras superfunciones, como SequencePredict , ActiveClassification y FeatureExtract .

En la versión 12.0 tenemos varias superfunciones importantes nuevas de aprendizaje automático. Hay FindAnomalies , que encuentra "elementos anómalos" en los datos:

imagen

Junto con esto, está DeleteAnomalies , que elimina elementos que considera anómalos:

imagen

También hay SynthesizeMissingValues , que intenta generar valores plausibles para datos faltantes:

imagen

¿Cómo funcionan estas funciones? Todos se basan en una nueva función llamada LearnDistribution , que trata de aprender la distribución subyacente de datos, dado un cierto conjunto de ejemplos. Si los ejemplos fueran solo números, esto sería esencialmente un problema estadístico estándar, para lo cual podríamos usar algo como EstimatedDistribution . Pero el punto sobre LearnDistribution es que funciona con datos de cualquier tipo, no solo números. Aquí está aprendiendo una distribución subyacente para una colección de colores:

imagen

Una vez que tenemos esta "distribución aprendida", podemos hacer todo tipo de cosas con ella. Por ejemplo, esto genera 20 muestras aleatorias a partir de él:

imagen

Pero ahora piense en FindAnomalies . Lo que tiene que hacer es descubrir qué puntos de datos son anómalos en relación con lo que se espera. O, en otras palabras, dada la distribución subyacente de los datos, encuentra qué puntos de datos son atípicos, en el sentido de que deberían ocurrir solo con una probabilidad muy baja de acuerdo con la distribución.

Y al igual que para una distribución numérica ordinaria, podemos calcular el PDF para un dato en particular. El púrpura es muy probable dada la distribución de colores que hemos aprendido de nuestros ejemplos:

imagen

Pero el rojo es realmente muy poco probable:

imagen

Para distribuciones numéricas ordinarias, hay conceptos como CDF que nos dicen probabilidades acumulativas, digamos que obtendremos resultados que están "más lejos" que un valor particular. Para espacios de cosas arbitrarias, no existe realmente una noción de "más allá". Pero se nos ocurrió una función que llamamos RarerProbability , que nos dice cuál es la probabilidad total de generar un ejemplo con un PDF más pequeño que el que damos:

imagen
imagen

Ahora tenemos una forma de describir anomalías: son solo puntos de datos que tienen una probabilidad muy rara. Y, de hecho, FindAnomalies tiene una opción AcceptanceThreshold (con el valor predeterminado 0.001) que especifica lo que debe contar como "muy pequeño".

Bien, pero veamos cómo funciona esto en algo más complicado que los colores. Vamos a entrenar un detector de anomalías observando 1000 ejemplos de dígitos escritos a mano:

imagen

Ahora FindAnomalies puede decirnos qué ejemplos son anómalos:

imagen

Lo último en redes neuronales



Primero presentamos nuestro marco simbólico para construir, explorar y usar redes neuronales en 2016, como parte de la Versión 11. Y en todas las versiones desde entonces, hemos agregado todo tipo de características de vanguardia. En junio de 2018, presentamos nuestro repositorio de redes neuronales para facilitar el acceso a los últimos modelos de redes neuronales desde Wolfram Language, y ya hay casi 100 modelos seleccionados de muchos tipos diferentes en el repositorio, y se agregan nuevos constantemente.

Entonces, si necesita la última red neuronal "transformador" BERT (que se agregó hoy), puede obtenerla de NetModel :

imagen

Puede abrir esto y ver la red que está involucrada (y, sí, hemos actualizado la visualización de gráficos de red para la Versión 12.0):

imagen

Y puede usar inmediatamente la red, aquí para producir algún tipo de matriz de "características de significado":

imagen

En la versión 12.0 hemos introducido varios tipos de capas nuevas, en particular AttentionLayer , que permite configurar las últimas arquitecturas de "transformador", y hemos mejorado nuestras capacidades de "programación funcional de red neuronal", con elementos como NetMapThreadOperator y secuencia múltiple NetFoldOperator . Además de estas mejoras "dentro de la red", la Versión 12.0 agrega todo tipo de nuevos casos de NetEncoder y NetDecoder , como la tokenización de BPE para texto en cientos de idiomas, y la capacidad de incluir funciones personalizadas para ingresar y salir de datos redes neuronales

Pero algunas de las mejoras más importantes en la Versión 12.0 son más infraestructurales. NetTrain ahora es compatible con la capacitación de múltiples GPU , así como también con aritmética de precisión mixta y criterios flexibles de detención temprana. Continuamos utilizando el popular marco de red neuronal de bajo nivel MXNet (del cual hemos sido los principales contribuyentes ), para poder aprovechar las últimas optimizaciones de hardware. Hay nuevas opciones para ver lo que sucede durante el entrenamiento, y también hay NetMeasurements que le permite realizar 33 tipos diferentes de mediciones sobre el rendimiento de una red:

imagen

Las redes neuronales no son la única, o incluso la mejor, forma de hacer aprendizaje automático. Pero una cosa nueva en la Versión 12.0 es que ahora podemos usar redes de normalización automática en Clasificar y Predecir , para que puedan aprovechar fácilmente las redes neuronales cuando tenga sentido.

Computación con imágenes



Presentamos ImageIdentify , para identificar de qué es una imagen, en la Versión 10.1. En la Versión 12.0 hemos logrado generalizar esto, para descubrir no solo de qué es una imagen, sino también qué hay en una imagen. Entonces, por ejemplo, ImageCases nos mostrará casos de tipos conocidos de objetos en una imagen:

imagen

Para más detalles, ImageContents ofrece un conjunto de datos sobre lo que hay en una imagen:

imagen

Puede decirle a ImageCases que busque un tipo particular de cosas:

imagen

Y también puede probar para ver si una imagen contiene un tipo particular de cosas:

imagen

En cierto sentido, ImageCases es como una versión generalizada de FindFaces , para encontrar rostros humanos en una imagen. Algo nuevo en la Versión 12.0 es que FindFaces y FacialFeatures se han vuelto más eficientes y robustos, con FindFaces ahora basado en redes neuronales en lugar de procesamiento de imágenes clásico, y la red para FacialFeatures ahora es de 10 MB en lugar de 500 MB:

imagen

Funciones como ImageCases representan el procesamiento de imágenes de "estilo nuevo", de un tipo que no parecía concebible hace solo unos años. Pero aunque tales funciones le permiten a uno hacer todo tipo de cosas nuevas, todavía hay mucho valor en las técnicas más clásicas. Hemos tenido un procesamiento de imágenes clásico bastante completo en Wolfram Language durante mucho tiempo, pero seguimos haciendo mejoras incrementales.

Un ejemplo en la Versión 12.0 es el marco de ImagePyramid , para hacer el procesamiento de imágenes multiescala:

imagen

Hay varias funciones nuevas en la Versión 12.0 relacionadas con el cálculo del color. Una idea clave es ColorsNear , que representa un vecindario en el espacio de color perceptivo, aquí alrededor del color Rosa :

imagen

La noción de vecindades de color se puede utilizar, por ejemplo, en la nueva función ImageRecolor :

imagen

Reconocimiento de voz y más con audio



Mientras me siento en mi computadora escribiendo esto, le diré algo a mi computadora y lo capturaré :

imagen

Aquí hay un espectrograma del audio que capturé:

imagen

Hasta ahora podríamos hacer esto en la Versión 11.3 (aunque Spectrogram se volvió 10 veces más rápido en 12.0). Pero ahora aquí hay algo nuevo:

imagen

Estamos haciendo voz a texto! Estamos utilizando tecnología de redes neuronales de última generación, pero estoy sorprendido de lo bien que funciona. Está bastante optimizado y somos perfectamente capaces de manejar incluso piezas de audio muy largas, digamos almacenadas en archivos. Y en una computadora típica, la transcripción se ejecutará aproximadamente a la velocidad real en tiempo real, por lo que una hora de discurso tardará aproximadamente una hora en transcribirse.

En este momento consideramos que Speech Recognize es experimental, y continuaremos mejorando. Pero es interesante ver que otra tarea computacional importante se convierta en una sola función en Wolfram Language.

En la versión 12.0, también hay otras mejoras. SpeechSynthesize admite nuevos idiomas y nuevas voces (según lo enumerado por VoiceStyleData []).

Ahora hay WebAudioSearch, análogo a WebImageSearch , que le permite buscar audio en la web:

imagen

Puede recuperar objetos de audio reales:

imagen

Luego puede hacer espectrogramas u otras medidas:

imagen

Y luego, nuevo en la Versión 12.0, puede usar AudioIdentify para tratar de identificar la categoría de sonido (¿es un gallo parlante?):

imagen

Todavía consideramos AudioIdentify experimental. Es un comienzo interesante, pero definitivamente no funciona, por ejemplo, tan bien como ImageIdentify .

Una función de audio más exitosa es PitchRecognize , que trata de reconocer la frecuencia dominante en una señal de audio (utiliza métodos de redes neuronales y "clásicas"). Todavía no puede tratar con "acordes", pero funciona bastante perfectamente para "notas individuales".

Cuando se trata de audio, a menudo se quiere no solo identificar lo que hay en el audio, sino también anotarlo. La versión 12.0 introduce el comienzo de un marco de audio a gran escala. En este momento, AudioAnnotate puede marcar dónde hay silencio o dónde hay algo ruidoso. En el futuro, agregaremos identificación del hablante y límites de palabras, y mucho más. Y para seguir con esto, también tenemos funciones como AudioAnnotationLookup , para seleccionar partes de un objeto de audio que se han anotado de maneras particulares.

Debajo de toda esta funcionalidad de audio de alto nivel hay toda una infraestructura de procesamiento de audio de bajo nivel. La versión 12.0 mejora enormemente AudioBlockMap (para aplicar filtros a las señales de audio), así como también presenta funciones como ShortTimeFourier .

Un espectrograma se puede ver un poco como un análogo continuo de una partitura musical, en el que los tonos se trazan en función del tiempo. En la versión 12.0 ahora hay InverseSpectrogram, que va desde una matriz de datos de espectrograma hasta audio. Desde la versión 2 en 1991, hemos tenido Play para generar sonido a partir de una función (como Sin [100 t]). Ahora con el espectrograma inverso tenemos una manera de pasar de un "mapa de bits de frecuencia-tiempo" a un sonido. (Y sí, hay problemas difíciles sobre las mejores conjeturas para las fases cuando uno solo tiene información de magnitud).

Procesamiento del lenguaje natural



Comenzando con Wolfram | Alpha , hemos tenido capacidades de comprensión del lenguaje natural (NLU) excepcionalmente fuertes durante mucho tiempo. Y esto significa que, dado un fragmento de lenguaje natural, somos buenos para entenderlo como Wolfram Language, que luego podemos ir y calcular desde:

imagen

Pero, ¿qué pasa con el procesamiento del lenguaje natural (PNL), en el que tomamos pasajes potencialmente largos del lenguaje natural y no intentamos comprenderlos por completo, sino que solo encontramos o procesamos características particulares de ellos? Funciones como TextSentences , TextStructure , TextCases y WordCounts nos han brindado capacidades básicas en esta área por un tiempo. Pero en la Versión 12.0, al hacer uso del último aprendizaje automático, así como nuestras capacidades de base de conocimiento y NLU de larga data, ahora hemos pasado a tener capacidades de PNL muy fuertes.

La pieza central es la versión dramáticamente mejorada de TextCases . El objetivo básico de TextCases es encontrar casos de diferentes tipos de contenido en una pieza de texto. Un ejemplo de esto es la clásica tarea de PNL de "reconocimiento de entidades", con TextCases aquí para encontrar qué nombres de países aparecen en el artículo de Wikipedia sobre ocelotes :

imagen

También podríamos preguntar qué islas se mencionan, pero ahora no pediremos una interpretación de Wolfram Language:

imagen

TextCases no es perfecto, pero lo hace bastante bien:

imagen

También admite muchos tipos de contenido diferentes:

imagen

Puede pedirle que encuentre pronombres, o cláusulas relativas reducidas , o cantidades , o direcciones de correo electrónico , o ocurrencias de cualquiera de los 150 tipos de entidades (como compañías, plantas o películas ). También puede pedirle que elija fragmentos de texto que estén en lenguajes humanos o informáticos en particular, o que traten sobre temas particulares (como viajes o salud ), o que tengan un sentimiento positivo o negativo . Y puede usar construcciones como Contener para pedir combinaciones de estas cosas (como frases nominales que contienen el nombre de un río):

imagen

TextContents le permite ver, por ejemplo, detalles de todas las entidades que se detectaron en un texto en particular:

imagen

Y sí, en principio se puede usar estas capacidades a través de FindTextualAnswer para tratar de responder preguntas del texto, pero en un caso como este, los resultados pueden ser bastante extraños:

imagen

Por supuesto, puede obtener una respuesta real de nuestra base de conocimiento curada incorporada real:

imagen

Por cierto, en la Versión 12.0 hemos agregado una variedad de pequeñas "funciones de conveniencia del lenguaje natural", como Sinónimos y Antónimos :

imagen

Quimica computacional



Una de las nuevas áreas "sorpresa" en la Versión 12.0 es la química computacional. Hemos tenido datos sobre productos químicos conocidos explícitos en nuestra base de conocimiento durante mucho tiempo. Pero en la Versión 12.0 podemos calcular con moléculas que se especifican simplemente como objetos simbólicos puros. Así es como podemos especificar lo que resulta ser una molécula de agua:

imagen

Y así es como podemos hacer una representación 3D:

imagen

Podemos tratar con "productos químicos conocidos":

imagen

Podemos usar nombres arbitrarios de IUPAC :

imagen

O "inventamos" químicos, por ejemplo, especificándolos por sus cadenas SMILES :

imagen

Pero no solo estamos generando imágenes aquí. También podemos calcular cosas desde la estructura, como las simetrías:

imagen

Dada una molécula, podemos hacer cosas como resaltar enlaces carbono-oxígeno:

imagen

O resalte estructuras, digamos especificadas por cadenas SMARTS (aquí cualquier anillo de 5 miembros):

imagen

También puede hacer búsquedas de "patrones de moléculas"; los resultados salen en términos de números de átomos:

imagen

Las capacidades de química computacional que hemos agregado en la Versión 12.0 son bastante generales y bastante poderosas (con la advertencia de que hasta ahora solo tratan con moléculas orgánicas). En el nivel más bajo, ven las moléculas como gráficos etiquetados con bordes correspondientes a enlaces. Pero también saben de física y explican correctamente las valencias atómicas y las configuraciones de enlaces. No hace falta decir que hay muchos detalles (sobre estereoquímica, simetría, aromaticidad, isótopos, etc.). Pero el resultado final es que la estructura molecular y el cálculo molecular ahora se han agregado con éxito a la lista de áreas que están integradas en Wolfram Language.

Computación Geográfica Extendida



Wolfram Language ya tiene fuertes capacidades para la computación geográfica, pero la Versión 12.0 agrega más funciones y mejora algunas de las que ya estaban allí.

Por ejemplo, ahora existe RandomGeoPosition , que genera una ubicación aleatoria de lat-long. Uno podría pensar que esto sería trivial, pero, por supuesto, uno tiene que preocuparse por las transformaciones de coordenadas, y lo que lo hace mucho más trivial es que uno puede decirle que elija puntos solo dentro de una determinada región, aquí el país de Francia:

imagen

Un tema de las nuevas capacidades geográficas en la Versión 12.0 es el manejo no solo de puntos geográficos y regiones, sino también de vectores geográficos. Aquí está el vector de viento actual, por ejemplo, en la posición de la Torre Eiffel, representada como un GeoVector , con velocidad y dirección (también está GeoVectorENU , que proporciona componentes este, norte y arriba, así como GeoGridVector y GeoVectorXYZ ):

imagen

Funciones como GeoGraphics le permiten visualizar geo vectores discretos. GeoStreamPlot es el análogo geográfico de StreamPlot (o ListStreamPlot ), y muestra líneas de flujo formadas a partir de vectores geográficos (aquí desde WindDirectionData ):

imagen

La geodesia es un área matemáticamente sofisticada, y nos enorgullecemos de hacerlo bien en Wolfram Language. En la versión 12.0, hemos agregado algunas funciones nuevas para completar algunos detalles. Por ejemplo, ahora tenemos funciones como GeoGridUnitDistance y GeoGridUnitArea que dan la distorsión (básicamente, valores propios del jacobiano) asociada con diferentes proyecciones geográficas en cada posición en la Tierra (o Luna, Marte, etc.).

Muchas pequeñas mejoras de visualización



Una dirección de visualización que hemos estado desarrollando constantemente es lo que podríamos llamar "meta-gráficos": el etiquetado y la anotación de elementos gráficos. Introdujimos Callout en la Versión 11.0; en la versión 12.0 se ha extendido a cosas como gráficos 3D:

imagen

Es bastante bueno para averiguar dónde etiquetar las cosas, incluso cuando se vuelven un poco complejas:

imagen

Hay muchos detalles importantes para que los gráficos se vean realmente bien. Algo que se ha mejorado en la Versión 12.0 es garantizar que las columnas de gráficos se alineen en sus marcos, independientemente de la longitud de sus etiquetas de marca. También hemos agregado LabelVisibility , que le permite especificar las prioridades relativas con las que deben hacerse visibles las diferentes etiquetas.

Otra nueva característica de la Versión 12.0 es el diseño de trazado multipanel, donde se muestran diferentes conjuntos de datos en diferentes paneles, pero los paneles comparten ejes siempre que pueden:

imagen

Ajuste de la integración de la base de conocimiento



Nuestra base de conocimiento curada, que por ejemplo impulsa a Wolfram | Alpha, es vasta y está en continuo crecimiento. Y con cada versión de Wolfram Language estamos ajustando progresivamente su integración en el núcleo del lenguaje.

En la Versión 12.0, una cosa que estamos haciendo es exponer cientos de tipos de entidades directamente en el lenguaje:

imagen

Antes de la Versión 12.0, las páginas de ejemplo de Wolfram | Alpha servían como proxy para documentar muchos tipos de entidades. Pero ahora hay documentación de Wolfram Language para todos ellos:

imagen

Todavía hay funciones como SatelliteData , WeatherData y FinancialData que manejan tipos de entidades que rutinariamente necesitan una selección o cálculo complejo. Pero en la Versión 12.0, se puede acceder a cada tipo de entidad de la misma manera, con entrada de lenguaje natural ("control + =") y entidades y propiedades "en recuadro amarillo":

imagen

Por cierto, también se pueden usar entidades implícitamente, como aquí preguntando por los 5 elementos con los puntos de fusión más altos conocidos:

imagen

Y uno puede usar Dated para obtener una serie temporal de valores:

imagen

Integrando Big Data desde Bases de Datos Externas



Hemos hecho que sea realmente conveniente trabajar con datos integrados en la base de conocimiento de Wolfram . Tiene entidades, y es muy fácil preguntar sobre propiedades, etc.

imagen

Pero, ¿qué pasa si tienes tus propios datos? ¿Puedes configurarlo para que puedas usarlo tan fácilmente como esto? Una nueva característica importante de la Versión 11 fue la incorporación de EntityStore , en el que se pueden definir los propios tipos de entidad y luego especificar entidades, propiedades y valores.

Wolfram Data Repository contiene un montón de ejemplos de almacenes de entidades . Aquí hay uno:

imagen

Describe un tipo de entidad única: un "SWLibraryBook" . Para poder utilizar entidades de este tipo al igual que las entidades integradas, "registramos" el almacén de entidades:

imagen

Ahora podemos hacer cosas como pedir 10 entidades aleatorias de tipo "SWLibraryBook" :

imagen

Cada entidad en la tienda de la entidad tiene una variedad de propiedades. Aquí hay un conjunto de datos de los valores de propiedades para una entidad particular:

imagen

Bien, pero con esta configuración básicamente estamos leyendo todo el contenido de una entidad almacenada en la memoria. Esto hace que sea muy eficiente hacer cualquier operación de Wolfram Language que uno desee. Pero no es una buena solución escalable para grandes cantidades de datos, por ejemplo, datos que son demasiado grandes para caber en la memoria.

Pero, ¿cuál es una fuente típica de datos grandes? Muy a menudo es una base de datos, y generalmente una relacional a la que se puede acceder usando SQL . Hemos tenido nuestro paquete DatabaseLink para acceso de lectura y escritura de bajo nivel a bases de datos SQL durante más de una década. Pero en la Versión 12.0 estamos agregando algunas características incorporadas importantes que permiten manejar bases de datos relacionales externas en Wolfram Language al igual que las tiendas de entidades, o partes integradas de Wolfram Knowledgebase.

Comencemos con un ejemplo de juguete. Aquí hay una representación simbólica de una pequeña base de datos relacional que se almacena en un archivo:

imagen

Inmediatamente obtenemos un cuadro que resume lo que hay en la base de datos y nos dice que esta base de datos tiene 8 tablas. Si abrimos la caja, podemos comenzar a inspeccionar la estructura de esas tablas:

imagen

Luego podemos configurar esta base de datos relacional como un almacén de entidades en Wolfram Language. Se parece mucho a la tienda de entidades de libros de la biblioteca anterior, pero ahora los datos reales no se guardan en la memoria; en su lugar, todavía está en la base de datos relacional externa, y solo estamos definiendo una asignación ("similar a ORM") a entidades en Wolfram Language:

imagen

Ahora podemos registrar esta tienda de entidades, que configura un grupo de tipos de entidades que (al menos de manera predeterminada) llevan el nombre de los nombres de las tablas en la base de datos:

imagen

Y ahora podemos hacer "cálculos de entidad" en estos, al igual que lo haríamos en entidades integradas en la base de conocimiento de Wolfram. Cada entidad aquí corresponde a una fila en la tabla "empleados" en la base de datos:

imagen

Para un tipo de entidad dado, podemos preguntar qué propiedades tiene. Estas "propiedades" corresponden a columnas en la tabla en la base de datos subyacente:

imagen

Ahora podemos preguntar por el valor de una propiedad particular de una entidad particular:

imagen

También podemos elegir entidades dando criterios; aquí pedimos entidades de "pagos" con los 4 valores más grandes de la propiedad "cantidad":

imagen

Igualmente podemos pedir los valores de estas cantidades mayores:

imagen

De acuerdo, pero aquí es donde se vuelve más interesante: hasta ahora hemos estado mirando una pequeña base de datos respaldada por archivos. Pero podemos hacer exactamente lo mismo con una base de datos gigante alojada en un servidor externo.

Como ejemplo, conectemos a la base de datos OpenStreetMap PostgreSQL del tamaño de un terabyte que contiene lo que es básicamente el mapa de calles del mundo:

imagen

Como antes, registremos las tablas en esta base de datos como tipos de entidad. Como la mayoría de las bases de datos en la naturaleza, hay pequeños problemas técnicos en la estructura, que se solucionan, pero generan advertencias:

imagen

Pero ahora podemos hacer preguntas sobre la base de datos, como cuántos puntos geográficos o "nodos" hay en todas las calles del mundo (y, sí, es un gran número, por eso la base de datos es grande):

imagen

Aquí pedimos los nombres de los objetos con las 10 áreas más grandes (proyectadas) en la tabla planet_osm_polygon (101 GB) (y, sí, toma menos de un segundo):

imagen

Entonces, ¿cómo funciona todo esto? Básicamente, lo que sucede es que nuestra representación de Wolfram Language se está compilando en consultas SQL de bajo nivel que luego se envían para ejecutarse directamente en el servidor de la base de datos.

A veces, solicitará resultados que sean solo valores finales (como, por ejemplo, las "cantidades" anteriores). Pero en otros casos querrás algo intermedio, como una colección de entidades que han sido seleccionadas de una manera particular. Y, por supuesto, esta colección podría tener mil millones de entradas. Entonces, una característica muy importante de lo que estamos presentando en la Versión 12.0 es que podemos representar y manipular tales cosas de manera puramente simbólica, resolviéndolas a algo específico solo al final.

Volviendo a nuestra base de datos de juguetes, aquí hay un ejemplo de cómo especificaríamos una clase de entidades obtenidas agregando el límite de crédito total para todos los clientes con un valor de país dado:

imagen

Al principio, esto es solo algo simbólico. Pero si solicitamos valores específicos, se realizan consultas de bases de datos reales y obtenemos resultados específicos:

imagen

Hay una familia de nuevas funciones para configurar diferentes tipos de consultas. Y las funciones en realidad funcionan no solo para bases de datos relacionales, sino también para almacenes de entidades y para la base de conocimiento Wolfram incorporada. Entonces, por ejemplo, podemos pedir la masa atómica promedio para un período dado en la tabla periódica de elementos :

imagen

Una nueva construcción importante es EntityFunction . EntityFunction es como Function , excepto que sus variables representan entidades (o clases de entidades) y describe operaciones que pueden realizarse directamente en bases de datos externas. Aquí hay un ejemplo con datos integrados, en el que estamos definiendo una clase de entidad "filtrada" en la que el criterio de filtrado es una función que prueba los valores de la población. FilteredEntityClass en sí solo se representa simbólicamente, pero EntityList realmente realiza la consulta y resuelve una lista explícita de entidades (aquí, sin clasificar):

imagen
imagen

Además de EntityFunction , AggregatedEntityClass y SortedEntityClass , la versión 12.0 incluye SampledEntityClass (para obtener algunas entidades de una clase), ExtendedEntityClass (para agregar propiedades calculadas) y CombinedEntityClass (para combinar propiedades de diferentes clases). Con estas primitivas, uno puede construir todas las operaciones estándar de " álgebra relacional ".

En la programación estándar de bases de datos, uno generalmente termina con toda una jungla de "combinaciones" y "claves foráneas", etc. Nuestra representación de Wolfram Language le permite operar a un nivel superior, donde básicamente las uniones se convierten en composición de funciones y las claves externas son solo diferentes tipos de entidades. (Sin embargo, si desea hacer uniones explícitas, puede hacerlo, por ejemplo, usando CombinedEntityClass ).

Lo que sucede debajo del capó es que todas esas construcciones de Wolfram Language se están compilando en SQL o, más exactamente, el dialecto específico de SQL que es adecuado para la base de datos particular que está utilizando (actualmente admitimos SQLite , MySQL , PostgreSQL y MS -SQL , con soporte para OracleSQL próximamente). Cuando hacemos la compilación, verificamos automáticamente los tipos, para asegurarnos de que obtenga una consulta significativa. Incluso las especificaciones bastante simples de Wolfram Language pueden terminar convirtiéndose en muchas líneas de SQL. Por ejemplo,

imagen

produciría el siguiente SQL intermedio (aquí para consultar la base de datos SQLite):

imagen

El sistema de integración de bases de datos que tenemos en la Versión 12.0 es bastante sofisticado, y hemos estado trabajando en ello durante bastantes años. Es un importante paso adelante al permitir que Wolfram Language maneje directamente un nuevo nivel de "grandeza" en big data, y permitir que Wolfram Language haga ciencia de datos directamente en conjuntos de datos del tamaño de terabytes y más. Como encontrar qué entidades callejeras en el mundo tienen "Wolfram" en su nombre:

imagen

RDF, SPARQL y todo eso



¿Cuál es la mejor manera de representar el conocimiento sobre el mundo? Es un tema que ha sido debatido por filósofos (y otros) desde la antigüedad. A veces la gente decía que la lógica era la clave. A veces las matemáticas. A veces bases de datos relacionales. Pero ahora al menos conocemos una base sólida (o al menos, estoy bastante seguro de que lo sabemos): todo se puede representar mediante el cálculo. Esta es una idea poderosa, y en cierto sentido eso es lo que hace posible todo lo que hacemos con Wolfram Language.

Pero, ¿existen subconjuntos de cómputo general que sean útiles para representar al menos ciertos tipos de conocimiento? Uno que utilizamos ampliamente en la base de conocimiento de Wolfram es la noción de entidades ("Ciudad de Nueva York"), propiedades ("población") y sus valores ("8.6 millones de personas"). Por supuesto, tales triples no representan todo el conocimiento del mundo ("¿cuál será la posición de Marte mañana?"). Pero son un comienzo decente cuando se trata de ciertos tipos de conocimiento "estático" sobre cosas distintas.

Entonces, ¿cómo se puede formalizar este tipo de representación del conocimiento? Una respuesta es a través de bases de datos de gráficos. Y en la Versión 12.0, en alineación con muchos proyectos de "web semántica" , admitimos bases de datos de gráficos usando RDF y consultas en contra de ellos usando SPARQL . En RDF, el objeto central es un IRI ("Identificador de recursos internacionalizados"), que puede representar una entidad o una propiedad. Un " triplestore " consiste entonces en una colección de triples ("sujeto", "predicado", "objeto"), con cada elemento en cada triple siendo un IRI (o un literal, como un número). Todo el objeto se puede considerar como una base de datos de gráficos o un almacén de gráficos, o, matemáticamente, una hipergrafía. (Es una hipergrafía porque el predicado "bordes" también puede ser vértices en otros lugares).

Puede crear su propio RDFStore de la misma manera que crea un EntityStore, y de hecho puede consultar cualquier Wolfram Language EntityStore usando SPARQL al igual que consulta un RDFStore . Y dado que la parte de propiedad de entidad de Wolfram Knowledgebase puede tratarse como un almacén de entidades, también puede consultar esto. Entonces, aquí, finalmente, es un ejemplo. La lista de país-ciudad Entidad [" País "], Entidad [" Ciudad "]} en efecto representa una tienda RDF. Entonces SPARQLSelect es un operador que actúa en esta tienda. Lo que hace es intentar encontrar un triple que coincida con lo que está pidiendo, con un valor particular para la "variable SPARQL" x:

imagen
imagen

Por supuesto, también hay una manera mucho más simple de hacer esto en Wolfram Language:

imagen

Pero con SPARQL puede hacer cosas mucho más exóticas, como preguntar qué propiedades relacionan los Estados Unidos con México:

imagen

O si hay un camino basado en la relación entre países limítrofes desde Portugal a Alemania:

imagen

En principio, puede escribir una consulta SPARQL como una cadena (un poco como si pudiera escribir una cadena SQL). Pero lo que hemos hecho en la Versión 12.0 es introducir una representación simbólica de SPARQL que permite el cálculo de la representación en sí misma, lo que facilita, por ejemplo, generar automáticamente consultas SPARQL complejas. (Y es particularmente importante hacer esto porque, por sí mismas, las consultas SPARQL prácticas tienen la costumbre de ser extremadamente largas y pesadas).

Bien, pero ¿hay tiendas RDF en la naturaleza? Ha sido una esperanza a largo plazo que una gran parte de la web de alguna manera se etiquete lo suficiente como para "volverse semántica" y, de hecho, sea una tienda RDF gigante. Sería genial si esto sucediera, pero hasta ahora definitivamente no ha sucedido. Aún así, hay algunas tiendas RDF públicas por ahí, y también algunas tiendas RDF dentro de las organizaciones, y con nuestras nuevas capacidades en la Versión 12.0, estamos en una posición única para hacer cosas interesantes con ellas.

Optimización numérica



Una forma increíblemente común de problema en las aplicaciones industriales de las matemáticas es: "¿Qué configuración minimiza el costo (o maximiza la recompensa) si se deben cumplir ciertas restricciones?" Hace más de medio siglo, el llamado algoritmo simplex se inventó para resolver versiones lineales de este tipo de problema, en el que tanto la función objetivo (costo, beneficio) como las restricciones son funciones lineales de las variables en el problema. En la década de 1980 se habían inventado métodos mucho más eficientes ("punto interior"), y los hemos tenido para hacer " programación lineal " en Wolfram Language durante mucho tiempo.

¿Pero qué pasa con los problemas no lineales? Bueno, en el caso general, uno puede usar funciones como NMinimize. Y hacen un trabajo de vanguardia. Pero es un problema difícil. Sin embargo, hace algunos años, se hizo evidente que, incluso entre los problemas de optimización no lineal, existe una clase de los llamados problemas de optimización convexa que en realidad pueden resolverse casi tan eficientemente como los lineales. ("Convexo" significa que tanto el objetivo como las restricciones involucran solo funciones convexas, de modo que nada puede "moverse" cuando uno se acerca a un extremo, y no puede haber ningún mínimo local que no sea mínimo global).

En la versión 12.0, ahora tenemos implementaciones sólidas para todas las diversas clases estándar de optimización convexa. Aquí hay un caso simple, que implica minimizar una forma cuadrática con un par de restricciones lineales:

imagen

NMinimize ya podría resolver este problema en particular en la Versión 11.3:

imagen

Pero si uno tuviera más variables, el antiguo NMinimize se empantanaría rápidamente. Sin embargo, en la versión 12.0, la optimización cuadrática continuará funcionando bien, hasta más de 100,000 variables con más de 100,000 restricciones (siempre que sean bastante escasas).

En la Versión 12.0 tenemos funciones de "optimización convexa en bruto" como SemidefiniteOptimization (que maneja desigualdades de matriz lineal) y ConicOptimization (que maneja desigualdades de vector lineal). Pero funciones como NMinimize y FindMinimum también reconocerán automáticamente cuándo un problema puede resolverse de manera eficiente al transformarse en un formulario de optimización convexo.

¿Cómo se configuran los problemas de optimización convexa? Los más grandes implican restricciones en vectores enteros o matrices de variables. Y en la Versión 12.0 ahora tenemos funciones como VectorGreaterEqual (entrada como ≥) que pueden representarlas inmediatamente.

Análisis de elementos finitos no lineales



Las ecuaciones diferenciales parciales son difíciles, y hemos estado trabajando en formas cada vez más sofisticadas y generales para manejarlas durante 30 años. Primero presentamos NDSolve (para ODE) en la Versión 2, en 1991 . Tuvimos nuestras primeras PDE numéricas (1 + 1-dimensionales) a mediados de la década de 1990. En 2003 presentamos nuestro potente marco modular para manejar ecuaciones diferenciales numéricas. Pero en términos de PDE, básicamente solo estábamos tratando con regiones simples y rectangulares. Ir más allá de eso requería construir todo nuestro sistema de geometría computacional , que presentamos en la Versión 10. Y con esto, lanzamos nuestros primeros solucionadores PDE de elementos finitos . En la Versión 11, generalizamos a problemas propios .

Ahora, en la Versión 12, presentamos otra generalización importante: el análisis de elementos finitos no lineales. El análisis de elementos finitos implica descomponer regiones en pequeños triángulos discretos, tetraedros, etc., en los cuales el PDE original puede aproximarse mediante un gran número de ecuaciones acopladas. Cuando el PDE original es lineal, estas ecuaciones también serán lineales, y ese es el caso típico que las personas consideran cuando hablan de "análisis de elementos finitos".

Pero hay muchas PDE de importancia práctica que no son lineales, y para abordarlas se necesita un análisis de elementos finitos no lineales, que es lo que tenemos ahora en la Versión 12.0.

Como ejemplo, esto es lo que se necesita para resolver el PDE desagradablemente no lineal que describe la altura de una superficie mínima 2D (por ejemplo, una película de jabón idealizada), aquí sobre un anillo, con condiciones de contorno (Dirichlet) que hacen que se mueva sinusoidalmente en el bordes (como si la película de jabón estuviera suspendida de cables):

imagen

En mi computadora, toma solo un cuarto de segundo resolver esta ecuación y obtener una función de interpolación. Aquí hay una gráfica de la función de interpolación que representa la solución:

imagen

Compilador nuevo y sofisticado



Hemos dedicado mucha ingeniería a optimizar la ejecución de los programas de Wolfram Language a lo largo de los años. Ya en 1989 comenzamos a compilar automáticamente cálculos numéricos simples de precisión de máquina con instrucciones para una máquina virtual eficiente (y, de hecho, escribí el código original para esto). Con los años, hemos ampliado las capacidades de este compilador, pero siempre se ha limitado a programas bastante simples.

En la versión 12.0 estamos dando un gran paso adelante y lanzamos la primera versión de un compilador nuevo y mucho más potente en el que hemos estado trabajando durante varios años. Este compilador es capaz de manejar una gama mucho más amplia de programas (incluyendo construcciones funcionales complejas y flujos de control elaborados), y también está compilando no a una máquina virtual sino directamente a un código de máquina nativo optimizado.

En la versión 12.0 todavía consideramos el nuevo compilador experimental. Pero avanza rápidamente, y tendrá un efecto dramático en la eficiencia de muchas cosas en Wolfram Language. En la Versión 12.0, solo estamos exponiendo una "forma de kit" del nuevo compilador, con funciones de compilación específicas. Pero progresivamente haremos que el compilador funcione cada vez más automáticamente, descubriendo con el aprendizaje automático y otros métodos cuando valga la pena tomarse el tiempo para hacer qué nivel de compilación.

A nivel técnico, el nuevo compilador de la Versión 12.0 se basa en LLVM y funciona generando código LLVM, enlazando en la misma biblioteca de tiempo de ejecución de bajo nivel que usa el núcleo Wolfram Language, y llamando al núcleo completo de Wolfram Language para la funcionalidad eso no está en la biblioteca de tiempo de ejecución.

Aquí está la forma básica en que uno compila una función pura en la versión actual del nuevo compilador:

imagen

La función de código compilado resultante funciona igual que la función original, aunque más rápido:

imagen

Una gran parte de lo que permite a FunctionCompile producir una función más rápida es que le está diciendo que haga suposiciones sobre el tipo de argumento que obtendrá. Admitimos muchos tipos básicos (como " Integer32 " y " Real64 "). Pero cuando usa FunctionCompile , se compromete con tipos de argumentos particulares, por lo que se puede generar un código mucho más racionalizado.

Gran parte de la sofisticación del nuevo compilador está asociada a inferir qué tipos de datos se generarán en la ejecución de un programa. (Hay muchos algoritmos teóricos de gráficos y otros involucrados, y no hace falta decir que toda la metaprogramación para el compilador se realiza con Wolfram Language).

Aquí hay un ejemplo que implica un poco de inferencia de tipos (el tipo de fib se deduce como "Integer64" -> "Integer64" : una función entera que devuelve un número entero):

imagen

En mi computadora, cf [25] se ejecuta unas 300 veces más rápido que la función sin compilar. (Por supuesto, la versión compilada falla cuando su salida ya no es del tipo " Integer64 ", pero la versión estándar de Wolfram Language continúa funcionando bien).

El compilador ya puede manejar cientos de primitivas de programación de Wolfram Language, rastreando adecuadamente qué tipos se producen y genera código que implementa directamente estas primitivas. A veces, sin embargo, uno querrá usar funciones sofisticadas en Wolfram Language para las cuales no tiene sentido generar el código compilado propio, y donde lo que realmente quiere hacer es llamar al núcleo de Wolfram Language para estas funciones . En la versión 12.0, KernelFunction permite hacer esto:

imagen

OK, pero digamos que uno tiene una función de código compilado. ¿Qué se puede hacer con eso? Bueno, antes que nada uno puede ejecutarlo dentro del Wolfram Language. Uno también puede almacenarlo y ejecutarlo más tarde. Cualquier compilación particular se realiza para una arquitectura de procesador específica (por ejemplo, x86 de 64 bits). Pero CompiledCodeFunction mantiene automáticamente suficiente información para realizar compilaciones adicionales para una arquitectura diferente si es necesario.

Pero dada una función CompiledCode , una de las nuevas posibilidades interesantes es que se puede generar directamente un código que se puede ejecutar incluso fuera del entorno Wolfram Language. (Nuestro antiguo compilador tenía el paquete CCodeGenerate que proporcionaba capacidades ligeramente similares en casos simples, aunque incluso entonces se basa en una compleja cadena de herramientas de compiladores C, etc.)

Así es como se puede exportar código LLVM sin formato (observe que cosas como la optimización de recursión de cola se realizan automáticamente, y observe también la función simbólica y las opciones del compilador al final):

imagen

Si se utiliza FunctionCompileExportLibrary , se obtiene un archivo de biblioteca: .dylib en Mac, .dll en Windows y .so en Linux. Uno puede usar esto en Wolfram Language haciendo LibraryFunctionLoad . Pero también se puede usar en un programa externo.

Una de las cosas principales que determina la generalidad del nuevo compilador es la riqueza de su sistema de tipos. En este momento, el compilador admite 14 tipos atómicos (como " Boolean ", " Integer8 ", " Complex64 ", etc.). También admite constructores de tipos como " PackedArray ", de modo que, por ejemplo, TypeSpecifier [" PackedArray "] [ "Real64", 2 ] corresponde a una matriz empaquetada de rango real de 64 bits.

En la implementación interna del Wolfram Language (que, por cierto, está principalmente en Wolfram Language) hemos tenido una forma optimizada de almacenar matrices durante mucho tiempo. En la Versión 12.0 lo estamos exponiendo como NumericArray . A diferencia de las construcciones ordinarias de Wolfram Language, debe decirle a NumericArray en detalle cómo debe almacenar los datos. Pero luego funciona de una manera agradable y optimizada:

imagen
imagen
imagen

Llamar a Python y otros idiomas



En la Versión 11.2 presentamos ExternalEvaluate , que le permite hacer cálculos en lenguajes como Python y JavaScript desde Wolfram Language (en Python , "^" significa BitXor ):

imagen

En la Versión 11.3, introdujimos celdas de lenguaje externo, para facilitar el ingreso de programas de lenguaje externo u otra entrada directamente en un cuaderno:

imagen

En la versión 12.0, estamos ajustando la integración. Por ejemplo, dentro de una cadena de idioma externa, puede usar <* ... *> para proporcionar el código de Wolfram Language para evaluar:

imagen

Esto también funciona en celdas de lenguaje externo:

imagen

Por supuesto, Python no es Wolfram Language, por lo que muchas cosas no funcionan:

imagen

Pero ExternalEvaluate puede al menos devolver muchos tipos de datos de Python, incluidas listas (como Lista ), diccionarios (como Asociación ), imágenes (como Imagen ), fechas (como DateObject ), matrices NumPy (como NumericArray ) y conjuntos de datos de pandas (como TimeSeries , DataSet , etc.). ( ExternalEvaluate también puede devolver ExternalObject que es básicamente un identificador de un objeto que puede enviar de vuelta a Python).

También puede usar directamente funciones externas (el ord ligeramente llamado es básicamente el análogo de Python de ToCharacterCode ):

imagen

Y aquí hay una función pura de Python, representada simbólicamente en Wolfram Language:

imagen
imagen

Llamar al lenguaje Wolfram desde Python y otros lugares



¿Cómo se debe acceder al Wolfram Language? Hay muchas formas Se puede usar directamente en un cuaderno. Uno puede llamar a las API que lo ejecutan en la nube. O uno puede usar WolframScript en un shell de línea de comandos . WolframScript puede ejecutarse en un Wolfram Engine local o en un Wolfram Engine en la nube . Te permite dar directamente el código para ejecutar:

imagen

Y le permite hacer cosas como definir funciones, por ejemplo, con código en un archivo:

imagen
imagen

Junto con el lanzamiento de la Versión 12.0, también estamos lanzando nuestra primera nueva Biblioteca de cliente Wolfram Language, para Python. La idea básica de esta biblioteca es facilitar que los programas de Python llamen Wolfram Language. (Vale la pena señalar que efectivamente hemos tenido una Biblioteca de cliente de lenguaje C durante no menos de 30 años, a través de lo que ahora se llama WSTP ).

La forma en que funciona una Biblioteca de Client Language es diferente para diferentes idiomas. For Python—as an interpreted language (that was actually historically informed by early Wolfram Language)—it's particularly simple. After you set up the library , and start a session (locally or in the cloud), you can then just evaluate Wolfram Language code and get the results back in Python:

imagen

You can also directly access Wolfram Language functions (as a kind of inverse of ExternalFunction ):

imagen

And you can directly interact with things like pandas structures, NumPy arrays, etc. In fact, you can in effect just treat the whole of the Wolfram Language like a giant library that can be accessed from Python. Or, of course, you can just use the nice, integrated Wolfram Language directly, perhaps creating external APIs if you need them.

More for the Wolfram “Super Shell”



One feature of using the Wolfram Language is that it lets you get away from having to think about the details of your computer system, and about things like files and processes. But sometimes one wants to work at a systems level. And for fairly simple operations, one can just use an operating system GUI. But what about for more complicated things? In the past I usually found myself using the Unix shell . But for a long time now, I've instead used Wolfram Language.

It's certainly very convenient to have everything in a notebook, and it's been great to be able to programmatically use functions like FileNames (ls), FindList (grep), SystemProcessData (ps), RemoteRunProcess (ssh) and FileSystemScan . But in Version 12.0 we're adding a bunch of additional functions to support using the Wolfram Language as a “super shell”.

There's RemoteFile for symbolically representing a remote file (with authentication if needed)— that you can immediately use in functions like CopyFile . There's FileConvert for directly converting files between different formats.

And if you really want to dive deep, here's how you'd trace all the packets on ports 80 and 443 used in reading from wolfram.com :

imagen

Puppeting a Web Browser



Within the Wolfram Language, it's been easy for a long time to interact with web servers, using functions like URLExecute and HTTPRequest , as well as $ Cookies , etc. But in Version 12.0 we're adding something new: the ability of the Wolfram Language to control a web browser , and programmatically make it do what we want. The most immediate thing we can do is just to get an image of what a website looks like to a web browser:

imagen

The result is an image that we can compute with:

imagen

To do something more detailed, we have to start a browser session (we currently support Firefox and Chrome):

imagen

Immediately a blank browser window appears on our screen. Now we can use WebExecute to open a webpage:

imagen

Now that we've opened the page, there are lots of commands we can run. This clicks the first hyperlink containing the text “Programming Lab”:

imagen

This returns the title of the page we've reached:

imagen

You can type into fields, run JavaScript, and basically do programmatically anything you could do by hand with a web browser. Needless to say, we've been using a version of this technology for years inside our company to test all our various websites and web services. But now, in Version 12.0, we're making a streamlined version generally available.

Standalone Microcontrollers



For every general-purpose computer in the world today, there are probably 10 times as many microcontrollers —running specific computations without any general operating system. A microcontroller might cost a few cents to a few dollars, and in something like a mid-range car, there might be 30 of them.

In Version 12.0 we're introducing a Microcontroller Kit for the Wolfram Language, that lets you give symbolic specifications from which it automatically generates and deploys code to run autonomously in microcontrollers. In the typical setup, a microcontroller is continuously doing computations on data coming in from sensors, and in real time putting out signals to actuators. The most common types of computations are effectively ones in control theory and signal processing.

We've had extensive support for doing control theory and signal processing directly in the Wolfram Language for a long time. But now what's possible with the Microcontroller Kit is to take what's specified in the language and download it as embedded code in a standalone microcontroller that can be deployed anywhere (in devices, IoT, appliances, etc.).

As an example, here's how one can generate a symbolic representation of an analog signal-processing filter:

imagen

We can use this filter directly in the Wolfram Language—say using RecurrenceFilter to apply it to an audio signal. We can also do things like plot its frequency response:

imagen

To deploy the filter in a microcontroller, we first have to derive from this continuous-time representation a discrete-time approximation that can be run in a tight loop (here, every 0.1 seconds) in the microcontroller:

imagen

Now we're ready to use the Microcontroller Kit to actually deploy this to a microcontroller. The kit supports more than a hundred different types of microcontrollers. Here's how we could deploy the filter to an Arduino Uno that we have connected to a serial port on our computer:

imagen
imagen

MicrocontrollerEmbedCode works by generating appropriate C-like source code, compiling it for the microcontroller architecture you want, then actually deploying it to the microcontroller through its so-called programmer. Here's the actual source code that was generated in this particular case:

imagen

So now we have a thing like this that runs our Butterworth filter , that we can use anywhere:

imagen

If we want to check what it's doing, we can always connect it back into the Wolfram Language using DeviceOpen to open its serial port , and read and write from it.

Linking to the Unity Universe



What's the relation between the Wolfram Language and video games? Over the years, the Wolfram Language has been used behind the scenes in many aspects of game development (simulating strategies, creating geometries, analyzing outcomes, etc.). But for some time now we've been working on a closer link between Wolfram Language and the Unity game environment , and in Version 12.0 we're releasing a first version of this link.

The basic scheme is to have Unity running alongside the Wolfram Language, then to set up two-way communication, allowing both objects and commands to be exchanged. The under-the-hood plumbing is quite complex, but the result is a nice merger of the strengths of Wolfram Language and Unity.

This sets up the link, then starts a new project in Unity:

imagen
imagen

Now create some complex shape:

imagen

Then it takes just one command to put this into the Unity game as an object called " thingoid ":

imagen

Within the Wolfram Language there's a symbolic representation of the object, and UnityLink now provides hundreds of functions for manipulating such objects, always maintaining versions both in Unity and in the Wolfram Language.

It's very powerful that one can take things from the Wolfram Language and immediately put them into Unity—whether they're geometry , images , audio , geo terrain , molecular structures , 3D anatomy , or whatever. It's also very powerful that such things can then be manipulated within the Unity game, either through things like game physics, or by user action. (Eventually, one can expect to have Manipulate -like functionality, in which the controls aren't just sliders and things, but complex pieces of gameplay.)

We've done experiments with putting Wolfram Language–generated content into virtual reality since the early 1990s. But in modern times Unity has become something of a de facto standard for setting up VR/AR environments—and with UnityLink it's now straightforward to routinely put things from Wolfram Language into any modern XR environment.

One can use the Wolfram Language to prepare material for Unity games, but within a Unity game UnityLink also basically lets one just insert Wolfram Language code that can be executed during a game either on a local machine or through an API in the Wolfram Cloud . And, among other things, this makes it straightforward to put hooks into a game so the game can send “telemetry” (say to the Wolfram Data Drop ) for analysis in the Wolfram Language. (It's also possible to script the playing of the game—which is, for example, very useful for game testing.)

Writing games is a complex matter. But UnityLink provides an interesting new approach that should make it easier to prototype all sorts of games, and to learn the ideas of game development. One reason for this is that it effectively lets one script a game at a higher level by using symbolic constructs in the Wolfram Language. But another reason is that it lets the development process be done incrementally in a notebook, and explained and documented every step of the way. For example, here's what amounts to a computational essay describing the development of a “ piano game ”:

imagen

UnityLink isn't a simple thing: it contains more than 600 functions. But with those functions it's possible to access pretty much all the capabilities of Unity, and to set up pretty much any imaginable game.

Simulated Environments for Machine Learning



For something like reinforcement learning it's essential to have a manipulable external environment in the loop when one's doing machine learning. Well, ServiceExecute lets you call APIs (what's the effect of posting that tweet, or making that trade?), and DeviceExecute lets you actuate actual devices (turn the robot left) and get data from sensors (did the robot fall over?).

But for many purposes what one instead wants is to have a simulated external environment. And in a way, just the pure Wolfram Language already to some extent does that, for example providing access to a rich “computational universe” full of modifiable programs and equations ( cellular automata , differential equations , …). And, yes, the things in that computational universe can be informed by the real world—say with the realistic properties of oceans , or chemicals or mountains .

But what about environments that are more like the ones we modern humans typically learn in—full of built engineering structures and so on? Conveniently enough, SystemModel gives access to lots of realistic engineering systems. And through UnityLink we can expect to have access to rich game-based simulations of the world.

But as a first step, in Version 12.0 we're setting up connections to some simple games—in particular from the OpenAI “gym” . The interface is much as it would be for interacting with the real world, with the game accessed like a “device” (after appropriate sometimes-“open-source-painful” installation):

imagen

We can read the state of the game:

imagen

And we can show it as an image:

imagen

With a bit more effort, we can take 100 random actions in the game (always checking that we didn't “die”), then show a feature space plot of the observed states of the game:

imagen

Blockchain (and CryptoKitty) Computation



In Version 11.3 we began our first connection to the blockchain . Version 12.0 adds a lot of new features and capabilities, perhaps most notably the ability to write to public blockchains, as well as read from them. (We also have our own Wolfram Blockchain for Wolfram Cloud users.) We're currently supporting Bitcoin , Ethereum and ARK blockchains, both their mainnets and testnets (and, yes, we have our own nodes connecting directly to these blockchains).

In Version 11.3 we allowed raw reading of transactions from blockchains. In Version 12.0 we've added a layer of analysis, so that, for example, you can ask for a summary of “CK” tokens (AKA CryptoKitties ) on the Ethereum blockchain:

imagen

It's quick to look at all token transactions in history, and make a word cloud of how active different tokens have been:

imagen

But what about doing our own transaction? Let's say we want to use a Bitcoin ATM (like the one that, bizarrely, exists at a bagel store near me ) to transfer cash to a Bitcoin address. Well, first we create our crypto keys (and we need to make sure we remember our private key!):

imagen

Next, we have to take our public key and generate a Bitcoin address from it:

imagen

Make a QR code from that and you're ready to go to the ATM:

imagen

But what if we want to write to the blockchain ourselves? Here we'll use the Bitcoin testnet (so we're not spending real money). This shows an output from a transaction we did before—that includes 0.0002 bitcoin (ie 20,000 satoshi):

imagen
imagen

Now we can set up a transaction which takes this output, and, for example, sends 8000 satoshi to each of two addresses (that we defined just like for the ATM transaction):

imagen

OK, so now we've got a blockchain transaction object—that would offer a fee (shown in red because it's “actual money” you'll spend) of all the leftover cryptocurrency (here 4000 satoshi) to a miner willing to put the transaction in the blockchain. But before we can submit this transaction (and “spend the money”) we have to sign it with our private key:

imagen

Finally, we just apply BlockchainTransactionSubmit and we've submitted our transaction to be put on the blockchain:

imagen

Here's its transaction ID:

imagen

If we immediately ask about this transaction, we'll get a message saying it isn't in the blockchain:

imagen

But after we wait a few minutes, there it is—and it'll soon spread to every copy of the Bitcoin testnet blockchain:

imagen

If you're prepared to spend real money, you can use exactly the same functions to do a transaction on a main net. You can also do things like buy CryptoKitties. Functions like BlockchainContractValue can be used for any (for now, only Ethereum) smart contract, and are set up to immediately understand things like ERC-20 and ERC-721 tokens.

And Ordinary Crypto as Well



Dealing with blockchains involves lots of cryptography, some of which is new in Version 12.0 (notably, handling elliptic curves). But in Version 12.0 we're also extending our non-blockchain cryptographic functions. For example, we've now got functions for directly dealing with digital signatures . This creates a digital signature using the private key from above:

imagen
imagen

Now anyone can verify the message using the corresponding public key:

imagen

In Version 12.0, we added several new types of hashes for the Hash function, particularly to support various cryptocurrencies. We also added ways to generate and verify derived keys . Start from any password, and GenerateDerivedKey will “puff it out” to something longer (to be more secure you should add “ salt ”):

imagen

Here's a version of the derived key, suitable for use in various authentication schemes:

imagen

Connecting to Financial Data Feeds



The Wolfram Knowledgebase contains all sorts of financial data . Typically there's a financial entity (like a stock), then there's a property (like price). Here's the complete daily history of Apple's stock price (it's very impressive that it looks best on a log scale):

imagen

But while the financial data in the Wolfram Knowledgebase, and standardly available in the Wolfram Language, is continuously updated, it's not real time (mostly it's 15-minute delayed), and it doesn't have all the detail that many financial traders use. For serious finance use, however, we've developed Wolfram Finance Platform . And now, in Version 12.0, it's got direct access to Bloomberg and Reuters financial data feeds.

The way we architect the Wolfram Language, the framework for the connections to Bloomberg and Reuters is always available in the language—but it's only activated if you have Wolfram Finance Platform, as well as the appropriate Bloomberg or Reuters subscriptions. But assuming you have these, here's what it looks like to connect to the Bloomberg Terminal service:

imagen

All the financial instruments handled by the Bloomberg Terminal now become available as entities in the Wolfram Language:

imagen

Now we can ask for properties of this entity:

imagen

Altogether there are more than 60,000 properties accessible from the Bloomberg Terminal:

imagen

Here are 5 random examples (yes, they're pretty detailed; those are Bloomberg names, not ours):

imagen

We support the Bloomberg Terminal service, the Bloomberg Data License service, and the Reuters Elektron service. One sophisticated thing one can now do is to set up a continuous task to asynchronously receive data, and call a “ handler function ” every time a new piece of data comes in:

imagen

Software Engineering & Platform Updates



I've talked about lots of new functions and new functionality in the Wolfram Language. But what about the underlying infrastructure of the Wolfram Language? Well, we've been working hard on that too. For example, between Version 11.3 and Version 12.0 we've managed to fix nearly 8000 reported bugs. We've also made lots of things faster and more robust. And in general we've been tightening the software engineering of the system, for example reducing the initial download size by nearly 10% (despite all the functionality that's been added). (We've also done things like improve the predictive prefetching of knowledgebase elements from the cloud—so when you need similar data it's more likely to be already cached on your computer.)

It's a longstanding feature of the computing landscape that operating systems are continually getting updated—and to take advantage of their latest features, applications have to get updated too. We've been working for several years on a major update to our Mac notebook interface—which is finally ready in Version 12.0. As part of the update, we've rewritten and restructured large amounts of code that have been developed and polished over more than 20 years, but the result is that in Version 12.0, everything about our system on the Mac is fully 64-bit, and makes use of the latest Cocoa APIs . This means that the notebook front end is significantly faster—and can also go beyond the previous 2 GB memory limit.

There's also a platform update on Linux, where now the notebook interface fully supports Qt 5 , which allows all rendering operations to take place “headlessly”, without any X server—greatly streamlining deployment of the Wolfram Engine in the cloud. (Version 12.0 doesn't yet have high-dpi support for Windows, but that's coming very soon.)

The development of the Wolfram Cloud is in some ways separate from the development of the Wolfram Language, and Wolfram Desktop applications (though for internal compatibility we're releasing Version 12.0 at the same time in both environments). But in the past year since Version 11.3 was released, there's been dramatic progress in the Wolfram Cloud.

Especially notable are the advances in cloud notebooks—supporting more interface elements (including some, like embedded websites and videos, that aren't even yet available in desktop notebooks), as well as greatly increased robustness and speed. (Making our whole notebook interface work in a web browser is no small feat of software engineering, and in Version 12.0 there are some pretty sophisticated strategies for things like maintaining consistent fast-to-load caches, along with full symbolic DOM representations.)

In Version 12.0 there's now just a simple menu item (File > Publish to Cloud …) to publish any notebook to the cloud. And once the notebook is published, anyone in the world can interact with it—as well as make their own copy so they can edit it.

It's interesting to see how broadly the cloud has entered what can be done in the Wolfram Language. In addition to all the seamless integration of the cloud knowledgebase, and the ability to reach out to things like blockchains, there are also conveniences like Send To … sending any notebook through email, using the cloud if there's no direct email server connection available.

And a Lot Else…



Even though this has been a long piece, it's not even close to telling the whole story of what's new in Version 12.0. Along with the rest of our team, I've been working very hard on Version 12.0 for a long time now—but it's still exciting to see just how much is actually in it.

But what's critical (and a lot of work to achieve!) is that everything we've added is carefully designed to fit coherently with what's already there. From the very first version more than 30 years ago of what's now the Wolfram Language, we've been following the same core principles—and this is part of what's allowed us to so dramatically grow the system while maintaining long-term compatibility.

It's always difficult to decide exactly what to prioritize developing for each new version, but I'm very pleased with the choices we made for Version 12.0. I've given many talks over the past year, and I've been very struck with how often I've been able to say about things that come up: “Well, it so happens that that's going to be part of Version 12.0!”

I've personally been using internal preliminary builds of Version 12.0 for nearly a year, and I've come to take for granted many of its new capabilities—and to use and enjoy them a lot. So it's a great pleasure that today we have the final Version 12.0—with all these new capabilities officially in it, ready to be used by anyone and everyone…

Source: https://habr.com/ru/post/448394/


All Articles