Hello World

Ceci est un tutoriel étape par étape pour réaliser des oprations très simples avec Gorgonia.

Notre objectif est d’utiliser toute la mécanique de Gorgonia pour réaliser une opération très simple :

$ f(x,y) = x + y $

avec x = 2 et y = 5

Comment ça marche ?

L’équation x + y = z peut être représentée graphiquement :

graph LR; z[z] --> add(Round edge) add[+] --> x add[+] --> y

Pour en obtenir le résultat, nous avons besoin de 4 étapes :

Créer un graphique

Créer une expression graphique vide avec cette méthode :

g := gorgonia.NewGraph()

Créer les points

Nous allons créer des points et les associer à l’ExprGraph.

var x, y, z *gorgonia.Node

Créer l’espace réservé

x et y sont des variables scalaires, nous pouvons créer le point correspond de la manière suivante:

x = gorgonia.NewScalar(g, gorgonia.Float64, gorgonia.WithName("x"))
y = gorgonia.NewScalar(g, gorgonia.Float64, gorgonia.WithName("y"))

les fonctions prennent pour argument l’Exprgraph ; le point ainsi généré est automatiquement associé au graphique.

Il faut à présent créer l’opérateur d’addition ; cet opérateur nécessite deux points et renvoie un nouveau point ‘z’:

if z, err = gorgonia.Add(x, y); err != nil {
        log.Fatal(err)
}

le point z renvoyé est ajouté au graphique même si g n’a pas été transmis à z ou à la fonction Add (addition).

Définir les valeurs

Nous avons une ExprGraph qui représente l’équation z = x + y. À présent, il est temps d’attribuer des valeurs à x et y.

Nous utilisons la fonction Let :

gorgonia.Let(x, 2.0)
gorgonia.Let(y, 2.5)

Activer le graphique

Pour lancer le graphique et calculer le résultat, il faut instancier une VM. Utilisons la TapeMachine:

machine := gorgonia.NewTapeMachine(g)
defer machine.Close()

et lancer le graphique :

if err = machine.RunAll(); err != nil {
        log.Fatal(err)
}

s’il faut lancer le graphique une deuxième fois, il faut utiliser le Reset() du vm : machine.Reset()

Obtenir le résultat

À présent, le point z contient le résultat. Nous pouvons extraire sa valeur en utilisant Value() :

fmt.Printf("%v", z.Value())

nous pourrions aussi accéder à la valeur cachée “Go” en faisant un appel à z.Value().Data() ce qui renverrait un interface{} contenant un float64 dans le cas présent

Résultat final

package main

import (
        "fmt"
        "log"

        "gorgonia.org/gorgonia"
)

func main() {
        g := gorgonia.NewGraph()

        var x, y, z *gorgonia.Node
        var err error

        // define the expression
        x = gorgonia.NewScalar(g, gorgonia.Float64, gorgonia.WithName("x"))
        y = gorgonia.NewScalar(g, gorgonia.Float64, gorgonia.WithName("y"))
        if z, err = gorgonia.Add(x, y); err != nil {
                log.Fatal(err)
        }

        // create a VM to run the program on
        machine := gorgonia.NewTapeMachine(g)
        defer machine.Close()

        // set initial values then run
        gorgonia.Let(x, 2.0)
        gorgonia.Let(y, 2.5)
        if err = machine.RunAll(); err != nil {
                log.Fatal(err)
        }

        fmt.Printf("%v", z.Value())
}
$ go run main.go
4.5