Hi there,

I'm trying to develop some old code (for a class to model affine transformations) which was working thanks to a Daniweb member. The old code is

void IFS::eval(float x, float y, float& a, float&b)
{


    a = (matrix[0]*x + matrix[1]*y + matrix[2]);
    b = (matrix[3]*x + matrix[4]*y + matrix[5]);

}

Which evaluates an affine transformation. However, now I would like this code to evaluate as many affine transformations as wished. So i took out x,y and replaced with vectors a[j] and b[j]. This is the new code:

void IFS::eval(vector <float>& a, vector <float>& b)
{
    a[0]=0.0;
    b[0]=0.0;
    for (int j= 0; j<=50000; j++)
    {
        a[j] = (matrix[0]*a[j] + matrix[1]*b[j] + matrix[2]);
        b[j] = (matrix[3]*a[j] + matrix[4]*b[j] + matrix[5]);
    }

}

Which now brings about 23 errors. I think possibly it's because I haven't overloaded the << operator to handle the vectors a[j]? Is it possible to overload << for two different inputs? Does anyone know what I am doing wrong?

Thank you very much for any help.

You'll have to share some specifics about the first few errors returned and some more code. Without specifics, we really can only make wild guesses.

You're speculating about the '<<' operator, but it doesn't appear anyhere in the code that you have posted. This means that either you posted the wrong code or that's not the problem.

Sorry, sorry, I just didn't want to post too much code. But OK so the other related bits of code are:

private:
vector <float>a;
vector <float>b;

and in int main ()

vector<float>    
a[0]=0.0;    
vector<float>    
b[0]=0.0;    
int j;    
f_1.eval(a[j], b[j]);    
std::cout << "("<< a[j] << " " << b[j] << ")" << std::endl;

i don't feel like that declaration of int j is right but it gave me the least errors.
also the constructors:

float IFS::set_j(int j, const float& p, const float& q)
{    
for (j=0; j<=50000; j++)    
a[j]=p;    
b[j]=q;} 
float IFS::get_j(int j)const
{    
return (a[j], b[j]);
}
float IFS::set_j(int j, const float& p, const float& q)
{
    for (j=0; j<=50000; j++)
    a[j]=p;
    b[j]=q;
}

float IFS::get_j(int j)const
{
    return (a[j], b[j]);
}

Now the errors i get are

error: no match for 'operator<<' in 'std::operator<< [with _Traits = std::char_traits<char>](((std::basic_ostream<char>&)(& std::cout)), ((const char*)"(")) << a[j]'|error: no match for 'operator<<' in 'std::operator<< [with _Traits = std::char_traits<char>](((std::basic_ostream<char>&)(& std::cout)), ((const char*)"(")) << a[j]'|

and this 18 times:

candidates are: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>::__ostream_type& (*)(std::basic_ostream<_CharT, _Traits>::__ostream_type&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]|candidates are: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>::__ostream_type& (*)(std::basic_ostream<_CharT, _Traits>::__ostream_type&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]|

that is why i thought it was to do with my overloading of the << which i have only done for inputing a 3x3 matrix.

Any help would be greatly appreciated though i understand it's a bit of a mess.
Thank you.

You're using operator<< as an INPUT operator? Are you sure that's correct?

Member Avatar for embooglement

The code you posted for your main method makes no sense. I'll start first by pointing this out: line 5 in your main method code, "int j", creates an integer, but doesn't initialize it to anything. So anything you use j for is going to be junk. The next thing, your eval function takes two std::vector<float>'s as arguments. Now, I'm assuming the "a" and "b" that appear in your main method are supposed to be std::vector<float>'s, though that is most certainly not what they are according to what you posted. That said, assuming a and b were actually vectors, you would pass them as "f_1.eval(a, b);" Using operator[] on a vector returns a reference to whatever it's storing. In this case "a[j]" was returning a float, not a vector. And as I said before, j is junk, so it's unlikely this was even a float that the vector actually contained.

Those are just a couple problems, though the code is riddled with errors else where as well. But I hope that helps you get started fixing them.

Hey Fbody and embooglement,

Yeah I understand that code is pretty terrible. I think I'm actually going to take a different tact today. Will let you know, thanks for your help.

Hi okay, so my change of tact is a lot more complicated. I feel like what i'm trying to do should be simple. So before I had

void IFS::eval(float x, float y, float& a, float&b)
{      
       a = (matrix[0]*x + matrix[1]*y + matrix[2]); 
       b = (matrix[3]*x + matrix[4]*y + matrix[5]);
}

but i want to be able to reiterate it, so all i want to do is change the arguments from floats to vectors of floats.. or so i thought.

void IFS::eval(std::vector<float>& a, std::vector<float>&b)
{     
       a[0]=0.0;
       b[0]=0.0;
       for(int i=0; i<=50000; ++i)
       {
       a[i] = (matrix[0]*a[i-1] + matrix[1]*b[i-1] + matrix[2]); 
       b[i] = (matrix[3]*a[i-1] + matrix[4]*b[i-1] + matrix[5]);
       }
}

i've also changed the int main () to:

size_t size = 50000;
    std::vector<float>a(size);
    std::vector<float>b(size);
    for (int i=0; i<size; ++i)
    f_1.eval(a, b);
    std::cout << "("<< a[i] << " " << b[i] << ")" << std::endl;

and now my 2 errors are:
if you use -fpermissive g++ will accept your code
and name lookup of 'i' changed for ISO 'for' scoping.

I think it's a bit better, but still rubbish, sorry c++ is really not my strong point.
Again, any help would be much appreciated, the last lot was certainly helpful - thanks.

Oh dear sorry:
actually not so sure a[-1] is a good idea... actually i've changed it to

void IFS::eval(std::vector<float>&a, std::vector<float>&b)
{

    a[0] = 0.0;
    b[0] = 0.0;
    for(int i=0; i<=50000; ++i)
    {
        a[i+1] = (matrix[0]*a[i] + matrix[1]*b[i] + matrix[2]);
        b[i+1] = (matrix[3]*a[i] + matrix[4]*b[i] + matrix[5]);
    }

}

also fyi, those two errors are referring to line 6 of the int main ()

Thank-you very much.

Member Avatar for embooglement

Looks like you forgot curly braces for the for loop in main. It should be

for (int i=0; i<size; ++i)
{
    f_1.eval(a, b);
    std::cout << "("<< a[i] << " " << b[i] << ")" << std::endl;
}

The reason it was giving you that error was because you were trying to use the variable "i" outside it's scope, which is only the for loop.

If I recall correctly, C used to allow a variable declared in a for loop parentheses thingy to be used after the for loop's block, which is likely why your compiler mentioned something about changing i's name lookup.

Also worth noting, when you have something like a for loop or an if statement without curly braces after it, the next statement (anything ending in a semicolon) is taken to be the block. So your for loop would call "f_1.eval(a,b);", but not the print statements after it, because there is a semicolon between those.

Brilliant. Really brilliant. Thank you so much. Sorry that was a silly mistake to make, hopefully won't do it again now that i understand what exactly those curly brackets are doing.
I just have one last query, I wonder if you can help me with? It is working really nicely except for the fact that b[i+1] is refusing to be equal to 0 which makes the whole process stop. In that case all i get printed out is (1
(similarly for a[i+1])
Have you any ideas why this is? No worries if not, thank you so much for your previous help.

That would be because (0 + 1) = 1

I'm not familiar with "affine transformations", so I may be asking a stupid question, but why do you have the "+1" in there? Is it required?

No, that (1 is corresponding to the value of a. So i'm printing out (a b), which could give me for example
(1.5 0.5)

but when i do a transformation, so that the answer should be
(a b) = (1 0)
all i get printed out is
(1

The [i+1] is there so that i can start with a and then do successive iterations to find a[i+1] using a for loop.

Do you see what I mean?

Member Avatar for embooglement

Well, I'm still not certain why you need the +1 either, but I will say this: You've been using std::vector, but you've been treating it like an array, and so during your for loop you're going to be accessing data that doesn't belong to it, because, at least if I recall correctly, using operator[] on a vector doesn't do any bounds checking. The last iteration in the for loop is going to be accessing out of bounds data. So, when i=49999, i.e. the last step in the for loop, you call a[i+1], which is going to be equivalent to a[50000]. This is out of bounds data that doesn't belong to the vector. Really at this point, there's no reason for your code to be using vectors at all, because it treats them no differently than it would an array. I highly recommend looking up the functions for vector. You could likely come up with a much better solution to your problem using some of it's list-style functions, like push_back and size. Moreover, you wouldn't need to choose an arbitrary size at the beginning, because vectors can grow, and can be whatever size is most effective for the project.

commented: definitely +5

Hmm well I kind of got round that by changing it to a = ...*a[i-1]... and also by allowing the user to enter the size of the vector and setting i<size, or something like this. Even though it wasn't ideal i was pleased with its functionability. Only since it's been working and since attempting to develop it more (to allow for randomness etc) i've realised it's not really what i want to do. Thank you so much for your help getting it to work though.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.