begin process at 2012 02 08 09:24:15
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Maths & Algorithmes

 > COS ET SIN PLUS RAPIDE QUE MATH.H

COS ET SIN PLUS RAPIDE QUE MATH.H


 Information sur la source

Note :
10 / 10 - par 1 personne
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Maths & Algorithmes Niveau :Débutant Date de création :24/07/2004 Vu / téléchargé :12 383 / 505

Auteur : djl

Ecrire un message privé
Commentaire sur cette source (35)
Ajouter un commentaire et/ou une note

 Description

C'est juste un header définissant 2 fonctions, tr_cos et tr_sin, permettant le calcul du cosinus et du sinus d'un réel  plus rapidement que les fonctions standards, en indexant sur des tableaux contenant les resultats precalculés


performance : environ 3 fois plus rapide que math.h, et 10 fois plus rapide si le réel passé en paramètre se trouve dans l'intervalle [ -pi, pi ]

précision : de 3 à 4 chiffres pour la partie décimale par rapport aux résultats des fonctions de math.h, avec 20000 pour taille des tableaux
pour augmenter la précision il suffit d'augmenter la taille des tableaux (aucun impact sur les performances )

par ex :

#define TRIGO_ARRAY_SIZE 60000
#include "trigo.h"


 Conclusion

Ca peut etre utile pour un moteur 3d par exemple
je pense qu'on peut encore ameliorer les performances, surtout dans le cas ou n est hors de l'intervalle
[-pi, pi]

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources du même auteur

Source avec Zip Source avec une capture [C++/DEVCPP] EXPLORATEUR EN OPENGL
Source avec Zip Source avec une capture TABLEAU 2D GENERIQUE MATRICE...
Source avec Zip CLASSE PILE&TABLEAU GENERIQUE
Source avec Zip Source avec une capture PETIT DOOM LIKE EN OPENGL [VC++]
Source avec Zip Source avec une capture LABYRINTHE 3D [OPENGL/VISUAL C++ 6.0]

 Sources de la même categorie

Source avec Zip UN EXAMPLE D'APPLICATION EN CUDA DE L'ALGORITHME DE SCAN POU... par oguzaras
Source avec Zip Source avec une capture CHIFFREMENT DE VIGENERE par lajouad
Source avec Zip Source avec une capture ANALYSE SYNTAXIQUE par lajouad
Source avec Zip Source avec une capture STRUCTURE D'UNE MATRICE PAR LES LISTE LINÉAIRE (NON CONTUGUS... par benzarabel
Source avec Zip Source avec une capture DESSINER UNE ARBRE BINAIRE( MODE CONSOLE): par benzarabel

Commentaires et avis

Commentaire de coucou747 le 24/07/2004 13:44:04 administrateur CS

bah moi ça va m'aider a comprendre comment fonctionne time.h.... lol j'ai regardé ton code, j'ai pas compris grand chose enfin bon, si ça marche...
tu pourrais détailler un peu ? expliquer pourquois ça marche ? En général, je suis plutot pas mauvais en math, mais dès que je vais sur ce site, je déprime... lol

Commentaire de garslouche le 24/07/2004 15:15:16

Euh.... arrete moi si je me trompe mais j'ai decortiqué ton code et d'apres ce que jai compris c'est juste que tu calcules 20000 valeurs de cos que tu stockes dans un tableau une fois au début, et ensuite tu renvoies la valeur la plus proche ...
Je ne vois pas en quoi c'est plus rapide que math.h puisque tu commences par appeler 20000 fois la fonction cos de math.h !

Si tu veux savoir comment un ordi calcule un cos tu peux regarder ma source "math.h reprogrammé"

Commentaire de Xs le 24/07/2004 15:50:42

Salut !

garslouche > c'est la méthode al plus rapide et la plus courante dans un jeu : on stock et on prend après. Les 20000 fois au départ tu t'en fiches : elles se font dans l'initialisation de ton jeu (et si c'est en thread, c'est encore plus invisible).

djl > j'ai lu ton code. Si je fais tr_cos(95851) je crois que je vais devoir patienter un bout de temps avant d'avoir l'abscisse curviligne de 95851 dans [-Pi;Pi].

Donc si tu veux calculer le sinus d'un réel "b" tel que b > 0 (sinon y'a une petite modif a faire) tu dois résoudre
b - k*Pi > -Pi/2 & b - k*PI < Pi/2 (la 1er equation est utile : ca n'induit pas b < 0 )

Je trouve que  b/Pi -1/2 < k < b/Pi+1/2.
Donc pour le sinus de b (b > 0), tu calculs b/Pi+1/2 que tu castes en "int" (pour obtenir aisement la partie entiere) puis tu déduis k*Pi de b . Et la zoup, en 1 division, une addition, une soustraction, une multiplication, tu obtiens l'indice du tableau v_sin.

Pour le cos, tu résouds b-k*Pi < PI & b-k*pi > PI (peut etre qu'il y a une différence pour b < 0).

Bon, je peux me tromper, mais je suis sur qu'il y a NETTEMENT plus rapide que des incrémentations ( tu te rends compte ? au lieu d'un grand nombre d'inc tu fais juste v_sin[b-((int)(b/Pi+1/2)*Pi]
ca semble barbare mais c'est rapide)

cordialement

Commentaire de garslouche le 24/07/2004 16:38:46

Xs > Je suis d'accord que cette méthode a des applications. Je voulais simplement dire que le titre est trompeur : il laisse supposer un algo plus efficace que celui de math.h. Et pour le calcul de l'indice du tableau je suis entièrement d'accord avec toi. Un calcul simple est bien plus efficace que ces incrémentations hasardeuses.

Commentaire de djl le 24/07/2004 17:50:56

ces icrementations n'ont rien d'hasardeuses, et c'est aussi rapide que fmod et j'ai bien conscience que c'est pas ce qu'il ya de plus efficace mais c'est le seul moyen que je connaisse, maintenant je vais essayer de voir avec la methode de Xs

sinon j'ai aussi bien preciser que c'etait 10 fois plus rapide dans l'intervalle et precalculer 20000 fois cos et sin c'est rien du moment qu'apres c'est rapide , ya que ca dans les jeux (dans certains, les 3/4 du temps de chargements c'est du precalcul)
si tu ve jeux te sort la version c++ qui fait l'initialisation à la compilation (par le preprocesseur) mais gar à la taille du prog

Xs > je vais essayer de mettre en place de cette maniere, en fait ce qu'il faut c'est une fonction qui calcul le modulo d'un reel plus rapide que fmod (ou alors j'utilise fmod ?)

Commentaire de Xs le 24/07/2004 20:15:38

bah c'est comme tu veux :D
J'avais totallement oublié fmod.

Mais bon, corrigez moi si j'ai tord, je pense pas que fmod soit plus rapide que ce que je présente : je ne crois pas qu'on puisse faire plus cours... (sauf peut etre avec de l'asm, hein brunews)

Donc en prennant ma méthode tu economises quelques cycles (genre ceux d'appel a fmod). :D

Commentaire de BlackGoddess le 26/07/2004 14:41:05

peut etre sortir une version en c++ avec métaprogrammation template, pour que les valeurs précalculées soient résolues à la compilation plutot qu'a l'execution ? (attention au temps de compilation apres :p)

Commentaire de djl le 26/07/2004 19:42:16

oui, ca va faire bosser le preprocesseur c++ ;)

et comme je l'ai dit, attention à la taille de l'exe

Commentaire de Xs le 26/07/2004 22:37:20

BlackGoldness : peux tu donner un léger exemple de métaprog template ? Ca m'interesse grandement

Commentaire de djl le 26/07/2004 22:55:58

un truc du genre (toujours dans le but de faaire generer du code par le preprocessuer c++)

double v_cos[100];

template<int N> void init()
{
       v_cos[N] = cos((double)N);
       init<N-1>();
}

template<> void init<0>()
{
      v_cos[0] = cos(0.0);
}

et l'appel de init<100>() genera le code completement deroulé

je te conseil le addison wesley sur les template, ya que ca

Commentaire de Xs le 27/07/2004 00:07:43

ah merci, c'est tout con mais j'y avais jamais pensé

Commentaire de BlackGoddess le 27/07/2004 15:44:15

oui, ca va faire bosser le preprocesseur c++ ;)
=> oulala :o
non ca fait bosser le compilo, pas le préprocesseur ...

l'exemple de djl se contente de déplier la boucle, pas le calcul du cosinus ...

il faudrait faire une opération comme :

template<int i>
int f()
{
  return i;
}

int my_cos<int val>()
{
   return f</* calcul du cosinus */>();
}

bon c pas terrible, c la 1ere solution qui me passe par la tete ...
ensuite, coupler cette solution a celle de djl pour obtenir un tableau de valeur entierement résolu a la compilation

Commentaire de djl le 27/07/2004 18:50:08

oui , mon truc ne calcul pas le cos, mais la je vois pas comment faire

pour le
"oui, ca va faire bosser le preprocesseur c++ ;)
=> oulala :o"

désolé mais c'est le preprocesseur qui travaille, c'est une certitude, le compilo ne connais pas les templates et le code doit etre genere avant la compilation

les template sont un mechanisme de generation de code, quel rapport avec la compilation ?

a ton avis pourquoi on appel ca meta programmation ?

Commentaire de coucou747 le 27/07/2004 23:10:52 administrateur CS

Pour déterminer ton cosinus :

i=0;
for (x=-rayon,x<rayon, x++){
for (y=-rayon,y<rayon, x++){
/*formule permetant de calculer la longueur séparant l'origine de (x;y)*/
if (sqrt( y*y + x*x)=rayon){
pointx[i]=x;
point[i]=y;
i++;
}}}

ici, t'as tout les points du cercle, selon le rayon demandé, tu remplace le rayon par 1, et t'as cosinus en fonction du sinus, tu cherches un peu tu peux trouver une fonction permetant de faire ceci...

Commentaire de BlackGoddess le 28/07/2004 11:06:35

mmh me semblait que le préprocesseur ne regardait que les lignes commencant par un (dièse)

as-tu un lien pour montrer ta 'certitude' ?

Commentaire de coucou747 le 28/07/2004 14:27:16 administrateur CS

tout dépends a qui tu parles lol
moi, je ne sais rien du préprocesseur, mai en math, je me débrouille

Commentaire de BlackGoddess le 28/07/2004 15:25:09

oui oui pour les maths je te fais confiance lol
c t a djl que je parlais :p

Commentaire de djl le 28/07/2004 21:32:00

t'avais raison, c'est  bien le travail du compilateur, mais il fait quand meme le travail d'un preprocesseur

dans la logique ca pourait etre fais par un preprocesseur mais seul un compilateur permet de faire des controle statique (verification de code)

je suis pas sur que parler dans ce cas de preprocesseur c++ soit totalement faux mais je retir quand meme ce que j'ai dit ;)

coucou747 >merci, je vais voir avec ta solution, mais au niveau perf je sais pas si ca sera plus rapide qu'un tableau

Commentaire de coucou747 le 28/07/2004 21:34:36 administrateur CS

ça ne seras surement pas plus rapide qu'un tableau, mais ça te permetra de ne pas inclure math.h
ça te permet de faire vraiment ta fonction...

Commentaire de djl le 28/07/2004 21:39:29

t'inquiete pas,a defaut de ne pas etre rapide, l'algo m'interesse pour les raison que tu as cités

Commentaire de coucou747 le 28/07/2004 21:44:07 administrateur CS

moi aussi ça m'interese, en fait, j'ai pondu ça comme ça mais je ne l'ai jamais mis dans un de mes programme, donc, on est en compétition, on pourrais pas s'entre aider ?
ce serais plus simple
Moi, je vais commencer par expérimenter ce soir sur tibasic, puis demain sur pc, si j'y arrives...

Commentaire de djl le 28/07/2004 21:46:56

des que j'ai le temps je lee faiis, tu remarqueras que pour sqrt il faut inclure math.h

Commentaire de coucou747 le 28/07/2004 21:55:14 administrateur CS

euh on peut s'arranger sans je crois, y a un algo ici pour ne pas s'en servir, et
if a=sqrt(b)
c'est pareil que
if (a*a=b)

Commentaire de djl le 28/07/2004 22:07:53

c'est meme mieux

Commentaire de coucou747 le 28/07/2004 22:11:19 administrateur CS

bah oui, c'est plus rapide

Commentaire de BlackGoddess le 29/07/2004 10:00:06

l'avantage de décomposer le cosinus en opération simple peut permettre d'en faire un algo a la compilation aussi.

J'essayerais d'en faire une ebauche qd j'aurais un moment ...

djl -> oui, puis ca me paraissait bizarre que ce soit le role du préprocesseur d'évaluer des expressions en paramètres templates ...
et oui, je suis d'accord avec toi, du point de vue conceptuel on pourrait voir ca comme un préprocesseur c++

Commentaire de coucou747 le 29/07/2004 12:56:49 administrateur CS

en fait, on commence par faire ;

int long unsigned n[1000]
for (x=0 x<1000;x++){
for (y=0 y<1000;y++){
if (x*x+y*y==1000000){
n[x]=y;
}
int diametre=3141592;
on a obtenu un quart de cercle de rayon 1000 (1000 pour être précis)
ensuite, on cherche a combien doit être la distance entre deux points du cercle séparés d'un degré...

diametre=(diametre-diametre%360)/360;

ensuite, caclul basique :
int cos[90];
int sin[90];
x=0;
y=0;
j=0
for (i=0;i<1000;i++){
if ( (n[i]-y)*(n[i]-y)+(i-x)*(i-x)==diametre*diametre)
x=i;
y=n[i];
sin[j]=y;
cos[i]=x;
}
}

Commentaire de djl le 07/08/2004 18:54:20

et apres on obtient cos(n) n en degré dans l'intervalle [0, 90] c'est ca?

Commentaire de BeLZeL le 01/10/2004 21:48:04

Attention à l'utilisation de rand() dans un "benchmark".

Avec 3 000 000 de valeurs, j'ai un facteur de x3 et avec 30 000 000, j'arrive à un facteur 9.

Commentaire de coucou747 le 01/10/2004 22:31:42 administrateur CS

ma méthode ne marche pas car : segmentation fault...
pas assez de mémoire pour arriver a tout calculer...
expérimentation sur mon site

Commentaire de zup2000 le 14/12/2004 01:58:16

je c je sui un peu en retar mé mieu fau tar que jamai!en faite si tu veu calculé un cosinus il te fau calculé son devellopement limité!!

pour la fonction cosinus son devellopement limité en 0 est :

1-(x²/2)+((x²)²/24).......
au plus tu ajoutera de therme au plus tu sera preci!voila jespere tavoir aidé!

Commentaire de BeLZeL le 01/10/2005 21:03:54

En changeant quelques options de mon compilo (devcpp), j'ai des cos et des sin "classiques" plus rapides qu'avec ce code.

Pour DevCpp 4.9.9.2, avec mon Duron 1 GHz :
Editeur de liens : retirer les symboles de l'exe : [YES]
Génération du code : générer instructions : [i586]
Génération du code : utiliser les fonctions spécifiques : [MMX]
Optimisations du code : Toutes

En moyenne, les fonctions classiques sont 3 fois plus efficaces ! (170ms au lieu de 510ms)

Sans changer les options, les fonctions classiques (1500ms) sont 2 fois moins rapide que les fonctions modifiées (750ms).

Commentaire de ghino1987 le 14/04/2008 20:29:43

tu peux m aider a tracé la fonction sinus

Commentaire de BoboLaricot le 16/10/2008 12:20:00

J'ai lu ton code et je m'interroge,
Pourquoi stocker une table des sinus quand on sait que sin(x)=cos(x-PI/2) ?

A ta place je mettrai ça dans la fonction sinus :

float sinus(float)
{
     return cosinus[x+PI/2]
}

Ca fait quand même une grosse économie de mémoire, non ?

Commentaire de BoboLaricot le 16/10/2008 12:20:49

Erreur de frappe : "return cosinus(x-PI/2)"

 Ajouter un commentaire




Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,889 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales