Bases de Gröbner

2»

Réponses

  • Super, j'ai réussi dans le navigateur !
    Mais pas dans V8 ni dans Node, pas sûr que ce soit possible. 

    Je vais faire une application Shiny  B)

    Par contre on n'a pas le droit de faire un package > 5Mo pour CRAN. Mais il y a une technique pour télécharger un fichier à l'installation, que je ne connais pas encore.

    C'est génial, on n'a pas seulement Gröbner j'imagine avec ce fichier JS ? Il y a quoi d'autre ?
  • Saturne
    Modifié (July 2023)
  • Avec le package chromote ça marche !!! C'est une interface vers le headless browser de Chrome. GENIAL !
  • Saturne a dit :
    C'est génial, on n'a pas seulement Gröbner j'imagine avec ce fichier JS ? Il y a quoi d'autre ?
    D'abord bravo!
    Ensuite, dans giacwasm.js, il y a tout ce qu'il y a dans Xcas (sans l'interface graphique de Xcas évidemment) donc votre interface devrait permettre de factoriser, simplifier, calculer une primitive, résoudre une équa diff, inverser une matrice (avec des paramètres) ...
    Du coup, si vous pouvez expliquer comment installer/utiliser votre interface avec R, ça m'intéresse car ça peut potentiellement intéresser pas mal de monde!
  • Saturne
    Modifié (July 2023)
    Super.
    Il n'y a rien de moi à installer pour l'instant, j'ai déouvert ça tout à l'heure puis j'ai fait une sieste. Mais voilà le code avec chromote:
    library(chromote)
    
    chrm <- Chrome$new(
      path = "path/to/chrome",
      args = "--disable-gpu --headless --remote-debugging-port=9222"
    )
    chromote <- Chromote$new(browser = chrm)
    session  <- ChromoteSession$new(parent = chromote)
    ids <- session$Page$navigate("about:blank")
    
    script <- paste0(readLines("path/to/giacwasm.js"), collapse = "\n")
    . <- session$Runtime$evaluate(script)
    
    . <- session$Runtime$evaluate("
    var UI = {
      Datestart: Date.now(), 
      ready: false, 
      warnpy: false
    };
    Module.onRuntimeInitialized = function() {
      UI.ready = true; 
    ;};
    ")
    
    . <- session$Runtime$evaluate(
      "var docaseval = Module.cwrap('caseval', 'string', ['string']);"
    )
    
    result <- session$Runtime$evaluate(
      "docaseval('gbasis([x1^3-2*x1*x2, x1^2*x2-2*x2^2+x1], [x1,x2])')"
    )
    result$result$value # the result
    
    . <- session$close()
  • Saturne
    Modifié (July 2023)
    Et voici le code de l'application Shiny (que l'on voit sur mon GIF ci-dessus, moche pour l'instant). Il faut mettre le fichier JS dans le sous-dossier www du dossier qui contient ce code : 
    library(shiny)
    
    script <- "
    var UI = {
      Datestart: Date.now(), 
      ready: false, 
      warnpy: false
    };
    Module.onRuntimeInitialized = function(){
      UI.ready = true; 
      console.log('GIAC IS READY!')
    ;};
    var docaseval = Module.cwrap('caseval', 'string', ['string']);
    function groebner(gens, vars) {
      var ans = docaseval(`gbasis([${gens}], [${vars}])`);
      alert(ans);
    }
    Shiny.addCustomMessageHandler('groebner', function(message) {
      groebner(message.gens, message.vars);
    });
    "
    
    ui <- fluidPage(
      tags$head(
        tags$script(src = "giacwasm.js"),
        tags$script(HTML(script))
      ),
      textInput(
        "generators",
        "Generators: ",
        value = "x1^3 - 2*x1*x2, x1^2*x2 - 2*x2^2 + x1"
      ),
      textInput(
        "variables",
        "Variables: ",
        value = "x1, x2"
      ),
      actionButton("go", "Run")
    )
    
    server <- function(input, output, session) {
      observeEvent(input[["go"]], {
        session$sendCustomMessage(
          "groebner", 
          list("gens" = input[["generators"]], "vars" = input[["variables"]])
        )
      })
    }
    
    shinyApp(ui, server)
  • Saturne
    Modifié (July 2023)
    Bien sûr on peut faire mieux que alert(ans), et plutôt renvoyer le résultat à R. Si ça intéresse quelqu'un je peux vous montrer comment faire.
  • Saturne
    Modifié (July 2023)
    Voici comment retourner la réponse à R, dans une interface moins laide.
    library(shiny)
    library(bslib)
    
    script <- "
    var UI = {
      Datestart: Date.now(), 
      ready: false, 
      warnpy: false
    };
    Module.onRuntimeInitialized = function() {
      UI.ready = true; 
      console.log('GIAC IS READY!')
    ;};
    var docaseval = Module.cwrap('caseval', 'string', ['string']);
    function groebner(gens, vars) {
      var ans = docaseval(`gbasis([${gens}], [${vars}])`);
      Shiny.setInputValue('answer', ans);
    }
    Shiny.addCustomMessageHandler('groebner', function(message) {
      groebner(message.gens, message.vars);
    });
    "
    
    ui <- page_sidebar(
      tags$head(
        tags$script(src = "giacwasm.js"),
        tags$script(HTML(script))
      ),
      title = "Gröbner basis with GIAC",
      sidebar = sidebar(
        textInput(
          "generators",
          "Generators: ",
          value = "x1^3 - 2*x1*x2, x1^2*x2 - 2*x2^2 + x1"
        ),
        textInput(
          "variables",
          "Variables: ",
          value = "x1, x2"
        ),
        actionButton("go", "Run", class = "btn-primary")
      ),
      page_fillable(
        verbatimTextOutput("answer")
      )
    )
    
    server <- function(input, output, session) {
      
      observeEvent(input[["go"]], {
        session$sendCustomMessage(
          "groebner", 
          list("gens" = input[["generators"]], "vars" = input[["variables"]])
        )
      })
      
      output[["answer"]] <- renderText({
        input[["answer"]]
      })
    }
    
    shinyApp(ui, server)

  • Saturne
    Modifié (July 2023)
    Equation implicite d'une ellipse : 


  • En fait on pourrait même extraire les symboles avec la fonction algvar de GIAC, pour que l'utilisateur n'ait pas à les entrer. Terrifique.
  • parisse
    Modifié (July 2023)
    Je viens d'essayer de faire tourner le script, mais ça ne marche pas...
    Je suis sur une debian11, où j'ai installé R par
    sudo apt install r-base r-devel
    Il n'y a pas de package bslib pour R (apt-cache search bslib renvoie seulement une lib python), du coup je lance R puis la commande install.packages("shiny") et install.packages("bslib"), après avoir changé les droits pour pouvoir écrire dans /usr/local/lib/R/library. Tout va bien jusque là.

    Maintenant je lance
    Rscript giac_r.r
    où giac_r.r contient le script ci-dessus.
    J'obtiens alors dans le terminal:
    Attachement du package : ‘bslib’
    The following object is masked from ‘package:utils’:
        page
    Listening on http://127.0.0.1:4200

    J'ouvre Firefox sur cette adresse, il apparait l'écran de saisie, mais quand je clique sur Run rien ne se passe, j'ai dans le terminal un warning
    Warning: replacing previous import ‘lifecycle::last_warnings’ by ‘rlang::last_warnings’ when loading ‘tibble’
    et dans la console du navigateur
    [Exception... "Component returned failure code: 0x80004001 (NS_ERROR_NOT_IMPLEMENTED) [nsIAppStartup.secondsSinceLastOSRestart]" nsresult: "0x80004001 (NS_ERROR_NOT_IMPLEMENTED)" location: "JS frame :: resource:///modules/BrowserGlue.jsm :: _collectStartupConditionsTelemetry :: line 1574" data: no] BrowserGlue.jsm:1574:9
    Error: Can't find profile directory.
    et
    Exception... "File error: Not found" nsresult: "0x80520012 (NS_ERROR_FILE_NOT_FOUND)" location: "JS frame :: resource:///modules/BrowserGlue.jsm :: task :: line 2763" data: no] BrowserGlue.jsm:2763:11
    Error: Can't find profile directory. XULStore.jsm:66:15
    TypeError: p.style is undefined jquery-ui.min.js:6:19576
    update.locale file doesn't exist in either the application or GRE directories UpdateUtils.jsm:140
    NS_ERROR_FAILURE: Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIScriptSecurityManager.createContentPrincipalFromOrigin] PurgeTrackerService.jsm:386



  • Houla, bizarre. Le plus simple est d'ouvrir le fichier dans RStudio et de le sourcer ici.
  • Sinon, avez-vous bien mis le fichiers giacwasm.js dans le sous-dossier www ? 
  • Saturne
    Modifié (July 2023)
    Ceci marche pour moi, sans RStudio. Faire un dossier un shinyGIAC et y mettre dedans le fichier app.R ci-dessous ainsi que le dossier www. Puis dans un terminal, lancer la commande R -e "shiny::shinyAppDir('shinyGIAC')".
    Fichier app.R:
    library(shiny)
    library(bslib)
    
    script <- "
    var UI = {
      Datestart: Date.now(), 
      ready: false, 
      warnpy: false
    };
    Module.onRuntimeInitialized = function() {
      UI.ready = true; 
      console.log('GIAC IS READY!')
    ;};
    var docaseval = Module.cwrap('caseval', 'string', ['string']);
    function groebner(gens, vars) {
      var ans = docaseval(`gbasis([${gens}], [${vars}])`);
      Shiny.setInputValue('answer', ans);
    }
    Shiny.addCustomMessageHandler('groebner', function(message) {
      groebner(message.gens, message.vars);
    });
    "
    
    ui <- page_sidebar(
      tags$head(
        tags$script(src = "giacwasm.js"),
        tags$script(HTML(script))
      ),
      title = "Gröbner basis with GIAC",
      sidebar = sidebar(
        textInput(
          "generators",
          "Generators: ",
          value = "x1^3 - 2*x1*x2, x1^2*x2 - 2*x2^2 + x1"
        ),
        textInput(
          "variables",
          "Variables: ",
          value = "x1, x2"
        ),
        actionButton("go", "Run", class = "btn-primary")
      ),
      page_fillable(
        verbatimTextOutput("answer")
      )
    )
    
    server <- function(input, output, session) {
      
      observeEvent(input[["go"]], {
        session$sendCustomMessage(
          "groebner", 
          list("gens" = input[["generators"]], "vars" = input[["variables"]])
        )
      })
      
      output[["answer"]] <- renderText({
        input[["answer"]]
      })
    }
    
    shinyApp(ui, server)
    
  • Ca ne marche toujours pas, cette fois l'erreur est plus compréhensible
    j'ai beau essayer divers emplacements pour giacwasm.js rien ne change.
  • On peut aussi essayer  R -e "shiny::runApp('shinyGIAC')".
  • ou bien Rscript -e "shiny::runApp('shinyGIAC')"
  • PS : il est important que le fichier de l'appli se nomme app.R.
  • Saturne
    Modifié (July 2023)
    Je me suis renseigné et certains ont le même problème.
    Une solution est de faire:
    addResourcePath("prefix", "www")
    
    
    ui <- page_sidebar(
      tags$head(
        tags$script(src = "prefix/giacwasm.js"),
    
  • Je confirme qu'avec ces modifications, ca fonctionne chez moi, merci! Il faudrait encore modifier la fonction groebner et renvoyer une erreur tant que UI.ready est a false.
    Est-ce que ca pourrait etre adapté pour fournir un noyau de calcul formel non interactif a R?
  • Cool !!! 

    Oui pour un truc non-interactif on peut utiliser chromote.

    Je pense que le UI est rapidement ready, je m'amuse avec ça depuis hier et jamais eu de problème avec ça. J'ai mis defer dans le tag script, mais je ne sais pas si c'est bien utile.
  • J'ai fait ça. Normalement l'appli ne démarre pas tant que Shiny est "busy".


  • Si vous voulez, au lieu de mettre le code JavaScript dans une chaîne de caractères, vous pouvez aussi le mettre dans www, et l'inclure avec tags$script(src = ...) comme le fichier giacwasm.js

    var UI = {
      Datestart: Date.now(), 
      ready: false, 
      warnpy: false
    };
    
    Module.onRuntimeInitialized = function() {
      UI.ready = true; 
      console.log("GIAC IS READY!");
    ;};
    
    var docaseval = Module.cwrap('caseval', 'string', ['string']);
    
    function groebner(gens, vars) {
      var ans = docaseval(`gbasis([${gens}], [${vars}])`);
      Shiny.setInputValue('answer', ans);
    }
    
    Shiny.addCustomMessageHandler('groebner', function(message) {
      groebner(message.gens, message.vars);
    });
    
    Shiny.addCustomMessageHandler('giacRaw', function(message) {
      var ans = docaseval(message);
      Shiny.setInputValue('raw', ans);
    });
    

  • parisse
    Modifié (July 2023)
    J'avais mis
    function groebner(gens, vars) {
      var ans = UI.ready?docaseval(`gbasis([${gens}], [${vars}])`):'Giac is not ready, please retry!';
      Shiny.setInputValue('answer', ans);
    }
    Est-ce que vous avez un exemple de code non interactif et un endroit où on peut récupérer vos améliorations ?
    Je pourrais rajouter un lien depuis la page de développement de giac.
    Merci !
  • J'ai déjà mis un code non-interactif dans un message précédent, avec le package chromote.

    Je vous envoie en privé le gist de la dernière version l'appli Shiny, en privé pour préserver mon pseudo-anonymat ici.
  • Saturne
    Modifié (July 2023)
    Voilà comment on peut faire avec chromote avec des fonctions. Pour l'instant je n'ai trouvé que Sys.sleep(5) (attendre 5 secondes) pour attendre que le runtime soit prêt.
    library(chromote)
    
    # si find_chrome() ne marche pas, mettre le chemin vers chrome ici:
    Sys.setenv("CHROMOTE_CHROME" = "path/to/chrome")
    # ou bien le mettre dans l'argument chromePath de cette function:
    
    giacSession <- function(chromePath = find_chrome()) {
      chrm <- Chrome$new(
        path = chromePath,
        args = "--disable-gpu --headless --remote-debugging-port=9222"
      )
      chromote <- Chromote$new(browser = chrm)
      session  <- ChromoteSession$new(parent = chromote)
      ids <- session$Page$navigate("about:blank")
      script <- paste0(readLines("giacwasm.js"), collapse = "\n")
      . <- session$Runtime$evaluate(script)
      . <- session$Runtime$evaluate("
    var UI = {
      Datestart: Date.now(), 
      ready: false, 
      warnpy: false
    };
    Module.onRuntimeInitialized = function() {
      UI.ready = true; 
    ;};
    ")
      . <- session$Runtime$evaluate(
        "var docaseval = Module.cwrap('caseval', 'string', ['string']);"
      )
      Sys.sleep(5)
      session
    }
    
    giacEvaluate <- function(session, command) {
      evaluate <- session$Runtime$evaluate(
        sprintf("docaseval('%s')", command)
      )
      if(evaluate$result$type != "string") {
        stop("An error occured.")
      }  
      evaluate$result$value
    }
    
    closeGiacSession <- function(session) {
      session$close()
    }
    
    
    # exemple ####
    session <- giacSession()
    giacEvaluate(session, "2 + 3/7")
  • Saturne
    Modifié (July 2023)
    J'ai trouvé une meilleure technique que Sys.sleep(5) :
      ready <- session$Runtime$evaluate("UI.ready")$result$value
      while(!ready) {
        ready <- session$Runtime$evaluate("UI.ready")$result$value
      }
  • Saturne
    Modifié (July 2023)
    Il y a une faute dans la documentation de gbasis : l'ordre par défault n'est pas plex.
    body <-
      "[x - (3*u + 3*u*v^2 - u^3), y - (3*v + 3*u^2*v - v^3), z - (3*u^2 - 3*v^2)], [u, v, x, y, z]"
    command <- sprintf("gbasis(%s, plex)", body)
    giac$execute(command)
    # "[-3*u^2+3*v^2+z,6*u*v^2-u*z+9*u-3*x,9*u*v*y-2*u*z^2+18*u*z-9*v^2*x-6*x*z,-4*u*v*z+3*u*y-3*v*x,-9*u*x-6*v^2*z+9*v*y-z^2+9*z,-27*u*y^2+8*u*z^3-72*u*z^2+36*v^2*x*z+27*v*x*y+24*x*z^2,-2*v^3-v*z-3*v+y,243*v^2*x^2-243*v^2*y^2-1296*v^2*z-108*v*y*z^2+324*v*y*z+108*x^2*z+648*x^2+135*y^2*z-648*y^2-4*z^4+48*z^3+108*z^2-1944*z,54*v^2*y*z+27*v*x^2-27*v*y^2+8*v*z^3+72*v*z^2-9*y*z^2-27*y*z,18*v^2*z^2+54*v^2*z-54*v*y*z-27*x^2+27*y^2+z^3-18*z^2+81*z,-2187*v*x^4-69984*v*x^2-8748*v*y^4*z+2187*v*y^4-648*v*y^2*z^4-3240*v*y^2*z^3+11664*v*y^2*z^2-139968*v*y^2*z+69984*v*y^2+192*v*z^6+3456*v*z^5+15552*v*z^4-20736*v*z^3-186624*v*z^2+729*x^4*y-5832*x^2*y^3+189*x^2*y*z^3+7047*x^2*y*z^2+23328*x^2*y*z-69984*x^2*y+5103*y^5+945*y^3*z^3-1215*y^3*z^2-5832*y^3*z+69984*y^3-8*y*z^6-288*y*z^5-216*y*z^4-5184*y*z^3-93312*y*z^2+279936*y*z,-4374*v*x^2*y-8748*v*y^3*z+4374*v*y^3-648*v*y*z^4-5184*v*y*z^3-17496*v*y*z^2+729*x^4-5832*x^2*y^2+189*x^2*z^3+2430*x^2*z^2-2187*x^2*z+5103*y^4+945*y^2*z^3-972*y^2*z^2+19683*y^2*z-8*z^6+72*z^5+648*z^4-5832*z^3,27*v*x^2*z+81*v*x^2+135*v*y^2*z-81*v*y^2+8*v*z^4+96*v*z^3+216*v*z^2+81*x^2*y-81*y^3-12*y*z^3-324*y*z,8748*v*y^3*z^2+648*v*y*z^5+5832*v*y*z^4+17496*v*y*z^3+17496*v*y*z^2-729*x^4*z-2187*x^4+5832*x^2*y^2*z+4374*x^2*y^2-189*x^2*z^4-2997*x^2*z^3-5103*x^2*z^2+6561*x^2*z-5103*y^4*z-2187*y^4-945*y^2*z^4+81*y^2*z^3-16767*y^2*z^2-6561*y^2*z+8*z^7-48*z^6-864*z^5+3888*z^4+17496*z^3,-19683*x^6+59049*x^4*y^2-10935*x^4*z^3-118098*x^4*z^2+59049*x^4*z-59049*x^2*y^4-56862*x^2*y^2*z^3-118098*x^2*y^2*z-1296*x^2*z^6-34992*x^2*z^5-174960*x^2*z^4+314928*x^2*z^3+19683*y^6-10935*y^4*z^3+118098*y^4*z^2+59049*y^4*z+1296*y^2*z^6-34992*y^2*z^5+174960*y^2*z^4+314928*y^2*z^3+64*z^9-10368*z^7+419904*z^5]"
    command <- sprintf("gbasis(%s)", body)
    giac$execute(command)
    # "[8*z^5+729*u*x^3-1458*v*x^2*y+1458*u*x*y^2-729*v*y^3-135*x^2*z^2-2592*v*y*z^2+135*y^2*z^2-96*z^4-2025*x^2*z+7776*v*y*z+567*y^2*z-360*z^3+11664*u*x+3888*x^2-11664*v*y-3888*y^2+7776*z^2-23328*z,8*u*z^3-54*u*x^2+81*v*x*y-27*u*y^2-72*u*z^2+18*x*z^2+54*x*z,8*v*z^3+27*v*x^2-81*u*x*y+54*v*y^2+72*v*z^2-18*y*z^2+54*y*z,6*u*v^2-u*z+9*u-3*x,2*v^3+v*z+3*v-y,9*u*v*x-9*v^2*y-2*v*z^2-18*v*z+3*y*z,9*v^2*x-9*u*v*y+2*u*z^2-18*u*z+6*x*z,4*u*v*z+3*v*x-3*u*y,6*v^2*z+9*u*x-9*v*y+z^2-9*z,27*u*x*z+27*v*y*z+2*z^3+81*u*x+27*x^2-81*v*y-27*y^2-162*z,3*u^2-3*v^2-z]"
  • Saturne
    Modifié (July 2023)
    L'exemple de la courbe sphérique dont j'ai parlé plus haut explose la mémoire. Il y a quelque chose à faire ?
    abort(Cannot enlarge memory arrays to size 268443648 bytes (OOM). Either
    (1) compile with -s TOTAL_MEMORY=X with X higher than the current value 268435456,
    (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime, or
    (3) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ) at Error\n at jsStackTrace (<anonymous>:1:18335100)\n at stackTrace (<anonymous>:1:18335271)\n at abort (<anonymous>:1:18632699)\n at abortOnCannotGrowMemory (<anonymous>:1:18575382)\n at _emscripten_resize_heap (<anonymous>:1:18575799)\n at wasm://wasm/0345fe1a:wasm-function[3866]:0x1cba21\n at wasm://wasm/0345fe1a:wasm-function[542]:0x34667\n at wasm://wasm/0345fe1a:wasm-function[324]:0x1478e\n at wasm://wasm/0345fe1a:wasm-function[1244]:0x7fd9c\n at wasm://wasm/0345fe1a:wasm-function[3380]:0x18a938
  • Saturne
    Modifié (July 2023)
    Voici la commande qui génère ce problème. Avec Sage ça marche bien.
    basis([x - A*cost*cos2t + sint*sin2t, y - A*sint*cos2t - cost*sin2t, z - B*cos2t, A^2 + B^2 - 1, 
    cost^2 + sint^2 - 1, cos2t - cost^2 + sint^2, sin2t - 2*sint*cost], [cost, sint, cos2t, sin2t, A, B, x, y, z], plex)
  • Si j'enlève cos2t - cost^2 + sint^2, sin2t - 2*sint*cost et que je remplace cos2t et sin2t dans les polynômes d'avant, alors ça marche, mais il y a trop de polynômes dans le résultat, en comparaison avec Sage (sept vs trois).
  • C'est l'ordre plex qui fait planter.
  • ça marche :smiley: L'ordre des équations et des symboles est très important quand on fait de l'implicitisation.

  • On trouve des surfaces excellentes avec l'implicitisation. Hélas mon implémentation ne marche pas toujours, j'utilise alors Sage.


  • Regardez cet exemple. Je lance deux fois le calcul de la base de Gröbner: 

    command <- paste0(
      "gbasis([x - a*cost*(4*cost^3-3*cost) + sint*(4*cost^2-1)*sint, ",
       "y - a*sint*(4*cost^3-3*cost) - cost*(4*cost^2-1)*sint, ",
       "z - b*(4*cost^3-3*cost), cost^2 + sint^2 - 1, a^2 + b^2 - 1], ",
       "[cost, sint, x, y, z, a, b])"
    )
    result <- giac$execute(command, timeout = 120000)
    length(strsplit(result, ",")[[1]])
    # 29
    
    command <- paste0(
      "gbasis([x - a*cost*(4*cost^3-3*cost) + sint*(4*cost^2-1)*sint, ",
      "y - a*sint*(4*cost^3-3*cost) - cost*(4*cost^2-1)*sint, ",
      "z - b*(4*cost^3-3*cost), cost^2 + sint^2 - 1, a^2 + b^2 - 1], ",
      "[cost, sint, x, y, z, b, a])"
    )
    result <- giac$execute(command, timeout = 120000)
    length(strsplit(result, ",")[[1]])
    # 32
    La première base a 29 polynômes. La deuxième en a 32. Pourtant la seule chose que j'ai faite, c'est que j'ai "swappé" a et b dans la liste des variables. Comment expliquez-vous ça ?
  • Et un truc curieux : là il ne trouve pas de polynôme qui ne fait pas intervenir cost ou sint. Mais si au lieu de donner la relation A²+B²=1, je donne des valeurs numériques à A et B, alors il trouve.   
  • Alors, plex est un ordre qu'il faut éviter si on le peut. Ici, si j'ai bien compris vous voulez éliminer tout ce qui contient du t, la bonne commande est eliminate, par exemple
    eliminate([x - A*cost*cos2t + sint*sin2t, y - A*sint*cos2t - cost*sin2t, z - B*cos2t, A^2 + B^2 - 1, cost^2 + sint^2 - 1, cos2t - cost^2 + sint^2, sin2t - 2*sint*cost], [cost, sint, cos2t, sin2t])
    renvoie quasi instantanément
    [z^3*B^2-2*y^2*B^3-z^2*B^3-4*A*y^2*B-2*A*z^2*B+2*A*z*B^2+4*y^2*B+2*z^2*B-3*z*B^2+B^3-2*A*z+2*A*B+2*z-2*B,A*z^3-2*A*y^2*B-A*z^2*B+z^3+2*y^2*B+z^2*B-2*z*B^2-A*z+A*B+z-B,x^2+y^2+z^2-1,A^2+B^2-1]
    En ajoutant A à la liste des variables à éliminer, on obtient un seul polynôme, mais de degré plus grand, pas forcément mieux.
    z^6*B^2-4*y^2*z^3*B^3-2*z^5*B^3+4*y^4*B^4+4*y^2*z^2*B^4+z^4*B^4+8*y^2*z^3*B+4*z^5*B-6*z^4*B^2-4*y^2*z*B^3-4*y^2*B^4+2*z^2*B^4+4*z^4-4*z^3*B-3*z^2*B^2+2*z*B^3+B^4,x^2+y^2+z^2-1
    L'ordre utilisé par giac pour eliminate est un ordre efficace adapté que j'appelle "double revlex", i.e. un ordre revlex par rapport aux variables à éliminer suivi par un ordre revlex sur les autres variables.
    Dans vos tests, c'est normal que le nombre de polynômes varie en fonction de l'ordre des variables.
    Sinon, je n'ai pas compris le but de l'implicitisation, normalement une surface paramétrée est beaucoup plus simple à représenter graphiquement qu'une surface donnée par une équation.

    Concernant les questions sur la mémoire, giacwasm est compilé avec  -s TOTAL_MEMORY=256MB, c'est pour éviter de mettre à bout de souffle des navigateurs sur des devices qui ont peu de mémoire (par exemple smartphone). Vous pouvez le recompiler en installant emscripten 1.38 (attention, il ne faut pas utiliser de version récente d'emscripten, car elles renvoient une sortie qui ne fonctionne plus sans serveur web) et l'archive https://www-fourier.univ-grenoble-alpes.fr/~parisse/giac/emgiac_wasm.tgz, en modifiant l'option ci-dessus dans le Makefile.




  • Génial ! Je croyais que eliminate ne pouvait prendre qu'un seul polynôme, comme l'exemple dans la doc. Je vous envoie un MP pour vous montrer un avantage de l'implicitisation :smile:
  • une surface paramétrée est beaucoup plus simple à représenter graphiquement qu'une surface donnée par une équation

    Pas avec R. Il y a l'algo des marching cubes pour représenter une équation implicite, et il évalue le gradient pour les normales, ce qui donne un graphique très smooth. Les normales partant d'équations paramétriques sont plus pénibles à calculer.
  • > renvoie quasi instantanément
    [z^3*B^2-2*y^2*B^3-z^2*B^3-4*A*y^2*B-2*A*z^2*B+2*A*z*B^2+4*y^2*B+2*z^2*B-3*z*B^2+B^3-2*A*z+2*A*B+2*z-2*B,
    A*z^3-2*A*y^2*B-A*z^2*B+z^3+2*y^2*B+z^2*B-2*z*B^2-A*z+A*B+z-B,
    x^2+y^2+z^2-1,
    A^2+B^2-1]

    C'est bizarre, il y a un polynôme en plus par rapport à ce que je fais avec gbasis, le premier polynôme, kilométrique. Or la courbe est bien l'intersection de la surface définie par le deuxième polynôme et de la sphère, qui est définie par le troisième polynôme. Je m'en vais voir ce que représente ce premier polynôme.
  • J'ai vérifié, ces deux surfaces sont identiques. J'ai l'impression que si on multiplie le premier polynôme par A/B, on obtient le deuxième, mais je n'ai pas vérifié.
  • Saturne
    Modifié (August 2023)
    Voici une autre application de l'implicitisation, que j'ai emprunté ici. On part des équations paramétriques d'un tore en 4D, et on élimine tous les cos et les sin. Il reste une équation implicite de x, y, z, w. En fixant w, on peut faire un dessin. Bon, le mien n'est pas terrible, je ne sais pas pourquoi :

    Bon j'avoue, on peut aussi très bien faire un dessin d'une coupe 3D sans passer par l'implicitisation, mais c'est plus pénible.
Connectez-vous ou Inscrivez-vous pour répondre.