|
-
April 14th, 2008, 09:19 AM
#1
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)
-
April 14th, 2008, 09:30 AM
#2
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.
-
April 14th, 2008, 09:49 AM
#3
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
-
April 14th, 2008, 10:17 AM
#4
Re: linear combination of 2 std::vectors
std::vector is not ideal for mathematical vectors. Find another library.
-
April 14th, 2008, 12:12 PM
#5
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.
-
April 14th, 2008, 12:28 PM
#6
Re: linear combination of 2 std::vectors
To be const-correct getCrossFadeAmount and operator() should be const member functions.
-
April 14th, 2008, 05:26 PM
#7
Re: linear combination of 2 std::vectors
 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();
}
-
April 14th, 2008, 07:42 PM
#8
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|