Essayez de porter le programme «Programmation informatique numérique FORTRAN77» vers C et Python (partie 1)

introduction

Je vis en tant qu'ingénieur en développement d'applications depuis longtemps, mais quand je me suis demandé si je devais essayer quelque chose dans la saison en cours ou étudier les mathématiques. J'ai soudain remarqué. Au départ, j'avais des mathématiques dans la matière que je suivais, alors j'aurais dû le faire dans cette université. Intelligence artificielle, reconnaissance de formes, etc. Je l'ai complètement oublié. Donc, j'ai d'abord tiré cela des différents textes que j'avais laissés. Programmation de calculs numériques

Première édition mai 1986. Si vous recherchez sur Google pour la programmation de calculs numériques, c'est toujours un succès après 33 ans. Il n'y a pas beaucoup de livres comme celui-ci.

Pour le moment, j'essaierai de porter le code de ce livre vers C et Python après avoir examiné. Il y en a 32 au total, mais je vais y aller doucement.

Après cela, le code qui sort est écrit dans Visual Studio Code sur Mac. Fortran et C sont compilés à l'aide de gcc.

Génération d'epsilon informatique

Erreur d'arrondi

Résumé du chapitre 1, P.4-5. Les nombres dans le programme sont fondamentalement tronqués ou arrondis. L'erreur causée par la troncature ou l'arrondi est appelée ** erreur d'arrondi **. La limite supérieure de l'erreur relative qui se produit lors de la troncature en virgule flottante β-aire à n chiffres est

\frac{\beta^{-n}}{\beta^{-1}} = \beta^{-(n-1)}

Erreur d'arrondi maximale par rapport à ce 1

\epsilon_M = \beta^{-(n-1)}

Est une valeur spécifique au système à virgule flottante utilisé, et s'appelle ** machine epsilon **. Cette valeur est

1\oplus\epsilon_M> 1 \tag{1}

Peut également être défini comme le plus petit nombre à virgule flottante positive satisfaisant. $ \ Oplus $ signifie effectuer une opération de troncature ou d'arrondi après l'ajout.

Code Fortran

Programme Fortran basé sur la définition de (1).

maceps.f


      SUBROUTINE MACEPS(EPSMAC)
        EPSMAC = 1.0
100    CONTINUE
       IF (1.0 + EPSMAC .LE. 1.0) THEN
        EPSMAC = 2 * EPSMAC
        RETURN
       END IF
       EPSMAC = EPSMAC * 0.5
       GO TO 100
      END 
    
      program maceps_main
        call maceps(epsmac)
        write(*,*)epsmac
      end program maceps_main

Le code dans le livre n'était que la partie sous-programme, donc la partie principale (4 lignes du bas) a été ajoutée. La minuscule est le code que j'ai ajouté et la majuscule est le livre (Fortran est insensible à la casse).

Le résultat de l'exécution est

   1.19209290E-07

Sera.

Comprendre le code

Soudain, c'est une instruction GO TO du premier code. Non, ça ne peut pas être aidé. L'auteur (décédé) est un grand professeur d'analyse numérique, pas un ingénieur. Pour le moment, réveillons-le dans l'organigramme. maceps_flowchart1.png

Ouaip. Pour le moment, si un nouveau venu apporte un tel flux, il se déchaînera.

C'est pourquoi j'ai réécrit l'organigramme. maceps_flowchart2.png

Dans les bases du diagramme de flux JIS, la condition de boucle est la condition de fin, mais en C et Python à porter à partir de maintenant, la condition de boucle est la condition de continuation, donc sous cette forme.

Code C

maceps.c


#include <stdio.h>
#include <float.h>

void maceps(float *epsmac){
    *epsmac = 1.0f;
    while((1.0f + *epsmac) > 1.0f)
    {
        *epsmac *= 0.5;
    }
    *epsmac *=2;
}

int main(void){
    float epsmac;

    maceps(&epsmac);

    printf("%.8E\n", epsmac);
    printf("%.8E\n", FLT_EPSILON);

    return 0;
}

Puisque le code Fortran est à virgule flottante simple précision, nous utilisons également float en C. Je voulais le faire correspondre avec le code de base Fortran, j'ai donc passé des variables du main avec un pointeur et l'ai affiché dans le main.   Ainsi, en C, l'ordinateur epsilon est défini par une constante dans float.h, donc j'ai également affiché cela (FLT_EPSILON) dans le main.

Le résultat de l'exécution est

1.19209290E-07
1.19209290E-07

Sera.

Code Python

maceps.py


import numpy as np
def maceps(epsmac):
    epsmac[0] = 1.0
    epsmac[1] = 1.0
    while epsmac[1]+epsmac[0] > epsmac[1]:
        epsmac[0] = epsmac[0] * 0.5
    epsmac[0] = epsmac[0] * 2    
    return

epsmac = np.array([0,0],dtype=np.float32)

maceps(epsmac)

print("%.8E" % epsmac[0])
print("%.8E" % np.finfo(np.float32).eps)

Les nombres à virgule flottante standard Python sont à double précision, utilisez donc numpy pour faire correspondre la virgule flottante à simple précision. Et puisque l'ordinateur epsilon est défini dans numpy ainsi que C, cela est également affiché.

Le résultat de l'exécution est

1.19209290E-07
1.19209290E-07

est. Ce code, @konandoiruasa, a souligné dans un commentaire que "s'il y a une opération avec une constante, ce sera float64." Merci beaucoup. Veuillez vous référer au remède.

Résumé

EPSMAC est divisé en deux lors de la répétition (= multiplié par 0,5). La formule utilisée pour la condition de répétition, 1.0 + EPSMAC > 1.0 Si cela ne tient pas, cela signifie que la valeur avant la dernière division est la valeur minimale qui satisfait cela, alors arrêtez de répéter et doublez pour annuler la dernière division. Autrement dit, la valeur positive minimale qui satisfait la formule (1) = la différence entre le nombre minimal supérieur à 1 et 1 = epsilon de l'ordinateur.

Recommended Posts

Essayez de porter le programme «Programmation informatique numérique FORTRAN77» vers C et Python (partie 1)
Essayez de porter le programme "FORTRAN77 Numerical Computing Programming" vers C et Python (partie 3)
Essayez de porter le programme "FORTRAN77 Numerical Computing Programming" vers C et Python (partie 2)
Essayez de résoudre le livre des défis de programmation avec python3
[Introduction à Python3 Jour 1] Programmation et Python
[Introduction à Python] J'ai comparé les conventions de nommage de C # et Python.
Ecrire un programme qui abuse du programme et envoie 100 e-mails
Essayer d'implémenter et de comprendre les arborescences de segments étape par étape (python)
Mettez Cabocha 0.68 dans Windows et essayez d'analyser la dépendance avec Python
Langage C pour voir et se souvenir de la partie 2 Appeler le langage C à partir de la chaîne Python (argument)
Langage C pour voir et se souvenir de la partie 1 Appeler le langage C depuis Python (bonjour le monde)
Portage et modification du solveur de doublets de python2 vers python3.
Essayez d'écrire du code python pour générer du code go - Essayez de porter JSON-to-Go et ainsi de suite
Python amateur tente de résumer la liste ①
Langage C pour voir et se souvenir de la partie 4 Appelez le langage C depuis Python (argument) double
Langage C pour voir et se souvenir de la partie 5 Appel du langage C à partir du tableau Python (argument)
Langage C pour voir et se souvenir de la partie 3 Appelez le langage C depuis Python (argument) c = a + b
Comment utiliser la bibliothèque C en Python
Comment générer une séquence en Python et C ++
Essayez de résoudre le problème de l'héritage de classe Python
Essayez de résoudre le diagramme homme-machine avec Python
Essayez d'utiliser le framework Web Python Tornado Partie 1
Essayez d'utiliser le framework Web Python Tornado Partie 2
Tutoriel "Cython" pour rendre Python explosif: Passez l'objet de classe C ++ à l'objet de classe côté Python. Partie 2
L'histoire du portage du code de C vers Go (et vers la spécification du langage)
Réfléchissez à la programmation de Python sur votre iPad
Essayez de créer un module Python en langage C
[Python] Essayez de lire la bonne réponse au problème FizzBuzz
Visualisons la pièce avec tarte aux râpes, partie 1
Essayez de résoudre le problème d'affectation du médecin de formation avec Python
Essayez le fonctionnement de la base de données avec Python et visualisez avec d3
Essayez d'incorporer Python dans un programme C ++ avec pybind11
Conseils et précautions lors du portage des programmes MATLAB vers Python
python Spécifie la fonction à exécuter lorsque le programme se termine
J'ai senti que j'avais porté le code Python en C ++ 98.
Comment profiter de Python sur Android !! Programmation en déplacement !!
Aller à la langue pour voir et se souvenir du langage Partie 7 C en langage GO
[C / C ++] Passez la valeur calculée en C / C ++ à une fonction python pour exécuter le processus et utilisez cette valeur en C / C ++.
Tutoriel "Cython" pour rendre Python explosif: Passez un objet de classe C ++ à un objet de classe côté Python. Partie ①
Comment démarrer le PC à une heure fixe chaque matin et exécuter le programme python
Essayez d'importer dans la base de données en manipulant ShapeFile d'informations numériques sur les terres nationales avec Python
Une histoire sur le portage du code de "Essayez de comprendre comment fonctionne Linux" sur Rust
[Python] Un programme pour trouver le nombre de pommes et d'oranges qui peuvent être récoltées
[Introduction à cx_Oracle] (Partie 6) Mappage des types de données DB et Python
Essayez de le faire avec GUI, PyQt en Python
Essayez d'utiliser l'API Twitter rapidement et facilement avec Python
Essayez d'obtenir la liste des fonctions du paquet Python> os
Je voulais résoudre le concours de programmation Panasonic 2020 avec Python
Essayez de vous connecter à Supervisord via XML RPC pour démarrer / arrêter le programme
Mesurons le résultat de l'exécution du programme avec C ++, Java, Python.
Ecrire un programme python pour trouver la distance d'édition [python] [distance Levenshtein]
Considérez si la programmation était un anime en Python et C
[Part.2] Exploration avec Python! Cliquez sur la page Web pour vous déplacer!
J'ai essayé d'illustrer le temps et le temps du langage C
Essayez d'ouvrir une sous-fenêtre avec PyQt5 et Python
Créer un environnement Python et transférer des données vers le serveur
J'ai essayé de programmer le test du chi carré en Python et Java.
Essayez d'automatiser le fonctionnement des périphériques réseau avec Python
Résolution avec Ruby et Python AtCoder ABC011 C Méthode de planification dynamique
Je veux connaître la nature de Python et pip
J'ai essayé d'énumérer les différences entre java et python