CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Aug 2007
    Posts
    78

    linear combination of 2 std::vectors

    I was wondering: is there a (more elegant, and preferably more efficient) way to do this:

    vector1[i] = a*vector2[i] + (1-a)*vector3[i];

    for every element of the vector without looping through the vectors myself. (with vectors of floats)

  2. #2
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: linear combination of 2 std::vectors

    You can use std::transform to combine two ranges into one by applying a binary (as in dyadic) function.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  3. #3
    Join Date
    Nov 2006
    Location
    Essen, Germany
    Posts
    1,344

    Re: linear combination of 2 std::vectors

    std::transform surely works, but in combination with binders it´s almost unreadable and far from elegant. If you have to deal with those operations I strongly recommend a dedicated library such as Blitz++ or the Matrix Template Library (MTL).
    - Guido

  4. #4
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: linear combination of 2 std::vectors

    std::vector is not ideal for mathematical vectors. Find another library.

  5. #5
    Join Date
    Aug 2007
    Posts
    78

    Re: linear combination of 2 std::vectors

    Thanks for the advice, I have little experience using std algorithms and functions objects, so even if it doesn't make things better, for me its still a learning opportunity.

    I am inheriting from an existing class using a vector of floats, so i cant really use anything else easily, as that vector is the result vector for the operation.

    Also i didn't know about Blitz++ or MTL, certainly interesting libs, i'll bookmark them for later. (I have once implemented 4x4 matrix inversion because i couldnt find an easy to use, free lib that did that for me)

    This is what i came up with, and it seems to work. I made a function object because I couldnt figure out how to do it with binders. Also I think it makes readability a little better, and stroustrup says: "function objects often execute faster than do ordinary functions" (18.4 in the c++ programming language 3rd edition). The linear combination im doing is for crossfading between the numerators of a filter, hence the naming:

    the function object:
    Code:
    class CrossFade
    {
    public:
    	CrossFade(float crossFadeAmount=0):m_cfa(crossFadeAmount){}
    
    	void setCrossFadeAmount(float crossFadeAmount)
    	{
    		m_cfa = crossFadeAmount;
    	}
    
    	float getCrossFadeAmount() const {return m_cfa;}
    
    	float operator()(float start, float target) const
    	{
    		return (1-m_cfa)*start + m_cfa*target;
    	}
    
    private:
    	float m_cfa;
    };
    and the (pruned) calling class + code is as follows:
    Code:
    class EFilter :
    	public Filter
    {
    public:
    	//...
    
    
    private:
    	float m_crossfadeAmount;
    	std::vector<float> m_targetNum;
    	std::vector<float> m_startNum;
    	//crossfade function object
    	CrossFade m_crossFader;
    
    	void doCrossFade();
    };
    
    
    void EFilter::doCrossFade()
    {
    	m_crossFader.setCrossFadeAmount(m_crossfadeAmount);
    	//b_ is an inherited vector of floats
    	//I should check the sizes of the vectors
    	transform(m_startNum.begin(),m_startNum.end(),m_targetNum.begin(),b_.begin(),m_crossFader);
    }
    Last edited by ejac; April 14th, 2008 at 01:19 PM. Reason: Added the consts as suggested by laserlight. Still haven't got myself into that const correctness habit.

  6. #6
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: linear combination of 2 std::vectors

    To be const-correct getCrossFadeAmount and operator() should be const member functions.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  7. #7

    Re: linear combination of 2 std::vectors

    Quote Originally Posted by ejac
    I was wondering: is there a (more elegant, and preferably more efficient) way to do this:

    vector1[i] = a*vector2[i] + (1-a)*vector3[i];

    for every element of the vector without looping through the vectors myself. (with vectors of floats)
    Why do you have to not loop through it yourself? Do you do more operations per each index than just this? If so, use a reference inside the loops to denote which entry you are referring to.

    Code:
    std::vector<MyDataStruct> arDataVector;
    
    // initialize data into vector somewhere here
    
    for (std::size_t x = 0; x < 100; ++x)
    {
        MyDataStruct & objRef = arDataVector[x];
    
        objRef.DoSomething();
        objRef.DoSomethingElse();
    }

  8. #8
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,725

    Re: linear combination of 2 std::vectors

    There is a STL class named valarray which does what you want,
    but I have never used it and I doubt that the compiler writers
    have put a lot of work optimizing it. Also, I think that they
    are fixed length.

    Code:
    #include <valarray>
    
    using namespace std;
    
    int main( )
    {
        valarray<float> v2(10);
        valarray<float> v3(10);
    
        for (int i=0; i<10; ++i)
        {
            v2[i] = i;
            v3[i] = i * i;
        }
    
        float a = 0.3f;
    
        valarray<float> v1 = a*v2 + (1-a)*v3;
    
        v2 += v3;
    
        v3 = 1.0f;
    
        return 0;
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured