Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 22
  1. #1

    [C++] Vettori Matematici

    Ciao a tutti.
    Sto riprovando a creare una classe di vettori matematici particolarmente ben fatta (spero non sia troppo difficile). Questa é l'interfaccia che ho scritto (non ho ancora cominciato l'implementazione). Cosa ne pensate? Ci sono tutte le funzioni necessarie? La move semantics é corretta?

    Grazie mille,
    R.

    Ps: È la prima volta che uso i templates e non ho compilato...

    Pps: Vorrei creare anche una classe Matrix... Consigliate di partire da quella e derivare Vector ma Matrix?



    codice:
    #ifndef VECTOR_H
    #define VECTOR_H
    
    #include <iostream>
    #include <utility>
    #include <vector>
    #include <initializer_list>
    
    template <typename T>
    class Vector
    {
    	// --- External Operators ---
    	friend Vector<T> operator*(const T&, const Vector<T>&);
        friend Vector<T> operator*(const vector<T>&, const T&);
        friend std::ostream& operator<<(std::ostream&, const Vettore&);
    
    public:
    	// --- Constructors ---
    	Vector<T>();
    	Vector<T>(size_t);
    	Vector<T>(const T&, const T&);
    	Vector<T>(T&&, T&&);
    	Vector<T>(const T&, const T&, const T&);
    	Vector<T>(T&&, T&&, T&&);
    	Vector<T>(const std::vector<T>&);
    	Vector<T>(const std::initializer_list<T>&);
    	Vector<T>(const Vector<T>&);
    	Vector<T>(std::vector<T>&&);
    	Vector<T>(std::initializer_list<T>&);
    	Vector<T>(Vector<T>&&);
    	
    	// --- Inner Operators ---
    	Vector<T>& operator=(const Vector<T>&);
    	Vector<T>&& operator=(Vector<T>&&);
    	
    	T& operator()(int);
    	const T& operator()(int) const;
    	
    	bool operator==(const Vettore<T>&) const;
    	bool operator!=(const Vettore<T>&) const;
    	
    	Vector<T>& operator+=(const Vector<T>e&);
        Vector<T>& operator-=(const Vector<T>&);
        Vector<T> operator+(const Vector<T>&) const;
        Vector<T> operator-(const Vector<T>&) const;
        Vector<T> operator-() const;
       	T operator*(const Vector<T>&) const;
    	
    	// --- Methods ---
    	void set();
    	void set(const T&);
    	
    	size_t size() const;
    	
    	T norm() const;
    	
    	
    private:
    	// --- Attributes ---
    	std::vector<T> vector;
    };
    
    #endif
    K. L. Thompson
    You can't trust code that you did not totally create yourself.
    A. Bogk
    UNIX is user-friendly, it just chooses its friends.

  2. #2
    Utente di HTML.it
    Registrato dal
    Feb 2009
    Messaggi
    131
    Ciao
    Io metterei il numero di dimensioni del vettore come parametro di template invece di utilizzare un vector. Questo perché la sua dimensione rimane sempre fissa dopo la creazione ed è quasi sicuramente nota a tempo di compilazione. In questo modo la classe è più efficiente e consuma meno memoria. In più evita spiacevoli errori già a tempo di compilazione, ad esempio se provi a sommare un vettore 3d con uno 4d il compilatore ti da subito errore.

  3. #3
    Originariamente inviato da XAlbeX
    Ciao
    Io metterei il numero di dimensioni del vettore come parametro di template invece di utilizzare un vector. Questo perché la sua dimensione rimane sempre fissa dopo la creazione ed è quasi sicuramente nota a tempo di compilazione. In questo modo la classe è più efficiente e consuma meno memoria. In più evita spiacevoli errori già a tempo di compilazione, ad esempio se provi a sommare un vettore 3d con uno 4d il compilatore ti da subito errore.
    Quindi utilizzare un std::array invece di un std::vector come membro della mia classe? Non é una brutta idea, la terrò in considerazione. Io ho fatto così perché magari un vettore "temporaneo" lo ridimensioni e lo riutilizzi per altri scopi e avrei gestito le operazioni matematiche tra vettori di dimensione differente con il meccanismo delle eccezioni.
    K. L. Thompson
    You can't trust code that you did not totally create yourself.
    A. Bogk
    UNIX is user-friendly, it just chooses its friends.

  4. #4
    Utente di HTML.it
    Registrato dal
    Feb 2009
    Messaggi
    131
    una curiosità.. per cosa lo userai questo codice?
    così è più facile aiutarti

  5. #5
    Originariamente inviato da XAlbeX
    una curiosità.. per cosa lo userai questo codice?
    così è più facile aiutarti
    Sto leggendo un po' di libri sulla fisica computazionale che contemplano una vasta serie di esercizi. Visto che vettori e matrici sono alla base di ogni programma, volevo evitare di riprogrammare ogni volta le stesse funzioni che agiscono su std::vector, std::array o array alla C, quindi la cosa migliore mi sembrava creare una classe Matrix e una Vector piuttosto complete ed efficienti che potrò utilizzare in tutti i programmi! ; ). Ma é più facile a dirsi che a farsi!
    K. L. Thompson
    You can't trust code that you did not totally create yourself.
    A. Bogk
    UNIX is user-friendly, it just chooses its friends.

  6. #6
    Utente di HTML.it
    Registrato dal
    Feb 2009
    Messaggi
    131
    Se ti interessa l'efficienza, i template uniti alle ottimizzazioni del compilatore possono fare miracoli..
    Per curiosità ho scritto questo codice di prova

    codice:
    #include <iostream>
    
    template <class type, unsigned int ndim> class vec
    {
    public:	
    	type data[ndim];
    
    	vec<type, ndim> operator + (vec<type, ndim> v)
    	{
    		vec<type, ndim> r;
    
    		for (unsigned int i = 0; i < ndim; i++)
    			r.data[i] = data[i] + v.data[i];
    
    		return r;
    	}
    };
    
    template <class type, unsigned int ndim> __declspec(noinline) 
    std::ostream & operator << (std::ostream &stream, vec<type, ndim> &v)
    {
    	for (unsigned int i = 0; i < ndim; i++)
    		stream << v.data[i] << ' ';
    
    	return stream;
    }
    
    template <class type, unsigned int ndim> __declspec(noinline) 
    std::istream & operator >> (std::istream &stream,vec<type, ndim> &v)
    {
    	for (unsigned int i = 0; i < ndim; i++)
    		stream >> v.data[i];
    	return stream;
    }
    
    int main ()
    {
    	const unsigned int ndim = 6;
    
    	vec<double, ndim> a;
    	vec<double, ndim> b;	
    
    	std::cin >> a >> b;
    
    	vec<double, ndim> c = a + b;
    
    	std::cout << c;
    	return 0;
    }
    E' sorprendente come il compilatore riesca a ottimizzare.. questo è l'assembly prodotto
    codice:
    	const unsigned int ndim = 6;
    
    	vec<double, ndim> a;
    	vec<double, ndim> b;	
    
    	std::cin >> a >> b;
    0094101B  mov         ebx,dword ptr [__imp_std::cin (942064h)]  
    00941021  push        edi  
    00941022  lea         eax,[esp+8]  
    00941026  call        operator>><double,6> (941150h)  
    0094102B  mov         ebx,eax  
    0094102D  lea         eax,[esp+38h]  
    00941031  call        operator>><double,6> (941150h)  
    
    	vec<double, ndim> c = a + b;
    00941036  fld         qword ptr [esp+8]  
    0094103A  fadd        qword ptr [esp+38h]
    
    	std::cout << c;
    0094103E  mov         edi,dword ptr [__imp_std::cout (942058h)]  
    00941044  lea         ebx,[esp+68h]  
    00941048  fstp        qword ptr [esp+68h]  
    0094104C  fld         qword ptr [esp+10h]  
    00941050  fadd        qword ptr [esp+40h]  
    00941054  fstp        qword ptr [esp+70h]  
    00941058  fld         qword ptr [esp+48h]  
    0094105C  fadd        qword ptr [esp+18h]  
    00941060  fstp        qword ptr [esp+78h]  
    00941064  fld         qword ptr [esp+50h]  
    00941068  fadd        qword ptr [esp+20h]  
    0094106C  fstp        qword ptr [esp+80h]  
    00941073  fld         qword ptr [esp+58h]  
    00941077  fadd        qword ptr [esp+28h]  
    0094107B  fstp        qword ptr [esp+88h]  
    00941082  fld         qword ptr [esp+60h]  
    00941086  fadd        qword ptr [esp+30h]  
    0094108A  fstp        qword ptr [esp+90h]
    00941091  call        operator<<<double,6> (941180h)  
    	return 0;
    }
    Non genera nessuna copia, nessun oggetto.. "srotola" perfino il ciclo
    Usando un std::vector probabilmente l'overhead supera anche il 200% del lavoro che dovrebbe fare. Ma questo ovviamente dipende dalle tue necessità

  7. #7
    Se interessano dei vettori matematici di dimensione fissata avevo scritto questa roba (esattamente per scopi analoghi). Invece, per vettori matematici di dimensione non fissata, la libreria standard fornisce già la classe std::valarray.
    Amaro C++, il gusto pieno dell'undefined behavior.

  8. #8
    Quindi se mi riciclassi su vettori di dimensione fissa consigliate di utilizzare gli array alla C invece degli std::array del C++11?

    Consigliate di partire dalle matrici e derivare la classe vettore?

    Ps: Già del C++ non é che sia un mago, ma di assembler proprio non capisco una mazza!xD
    K. L. Thompson
    You can't trust code that you did not totally create yourself.
    A. Bogk
    UNIX is user-friendly, it just chooses its friends.

  9. #9
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Originariamente inviato da RooccoXXI
    Quindi se mi riciclassi su vettori di dimensione fissa consigliate di utilizzare gli array alla C invece degli std::array del C++11?
    Sono la stessa cosa, solo che con std::array ti porti dietro la dimensione e non decadono in puntatori. Il modo di utilizzo è lo stesso.

    P.S
    codice:
    // errato
    Vector<T>&& operator=(Vector<T>&&);
    
    // corretto
    Vector<T>& operator=(Vector<T>&&);
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  10. #10
    Originariamente inviato da shodan
    Sono la stessa cosa, solo che con std::array ti porti dietro la dimensione e non decadono in puntatori. Il modo di utilizzo è lo stesso.
    Ma a incapsulare std::array nella mia classe non perdo niente in efficienza?
    K. L. Thompson
    You can't trust code that you did not totally create yourself.
    A. Bogk
    UNIX is user-friendly, it just chooses its friends.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.