Hi,
I just came across some GP examples in Beagle 3.0.3 and which to know the
<NegativeOpSet> and <PositiveOpSet>.
Further I'd like know about future plans and things todo for OpenBeagle 4.0. I
see somthing arround this mail list.
tks
Rafael Cabral
Hi Rafael,
On Oct 26, 2009, at 8:38 AM, rcabral82 wrote:
> Hi,
>
> I just came across some GP examples in Beagle 3.0.3 and which to
> know the <NegativeOpSet> and <PositiveOpSet>.
These two XML tags are childs of the IfThenElseOp. This designate
simply the operators that are applied when the condition of the if-
then-else is true (PositiveOpSet) or false (NegativeOpSet).
> Further I'd like know about future plans and things todo for
> OpenBeagle 4.0. I see somthing arround this mail list.
There is an alpha version of version 4.0.0 available on the Web page.
There is beta version is half-completed, and developments are
suspended since several months, as I am completely swamped by my
different duties. I hope it will be better for me in few weeks, but
given the general tendency, developments will probably resume slowly,
and take some time to achieve a new version to be released. The
changes made with version 4.0.0 beta will be significant. I prefer to
get this completed before making any announcements
Christian
> tks
> Rafael Cabral
>
>
>
> ------------------------------------
>
> Yahoo! Groups Links
>
>
>
Christian Gagné
http://vision.gel.ulaval.ca/~cgagne
Hi Christian,
I just suggest that Positive and Negative could be replaced by True and False.
:)
Another suggestion about the OB development is keep a list of interesting
improvements to do and submit that to Google Summer of Code next year.
Thanks in advance.
Rafael Cabral
--- In openbeagle@yahoogroups.com, Christian Gagné <cgagne@...> wrote:
>
> Hi Rafael,
>
> On Oct 26, 2009, at 8:38 AM, rcabral82 wrote:
>
> > Hi,
> >
> > I just came across some GP examples in Beagle 3.0.3 and which to
> > know the <NegativeOpSet> and <PositiveOpSet>.
>
> These two XML tags are childs of the IfThenElseOp. This designate
> simply the operators that are applied when the condition of the if-
> then-else is true (PositiveOpSet) or false (NegativeOpSet).
>
> > Further I'd like know about future plans and things todo for
> > OpenBeagle 4.0. I see somthing arround this mail list.
>
> There is an alpha version of version 4.0.0 available on the Web page.
> There is beta version is half-completed, and developments are
> suspended since several months, as I am completely swamped by my
> different duties. I hope it will be better for me in few weeks, but
> given the general tendency, developments will probably resume slowly,
> and take some time to achieve a new version to be released. The
> changes made with version 4.0.0 beta will be significant. I prefer to
> get this completed before making any announcements
>
> Christian
>
>
>
> > tks
> > Rafael Cabral
> >
> >
> >
> > ------------------------------------
> >
> > Yahoo! Groups Links
> >
> >
> >
>
> Christian Gagné
> http://vision.gel.ulaval.ca/~cgagne
>
On 10/26/09 6:32 AM, Christian Gagné wrote:
> ...But if you do something like... Compiler with consider these
> three types as different, and therefore use different RTTI type ID /
> type ID strings... An equivalent solution would be:
>
> class A { ... };
> class B : public A { ... }; // No method declaration out of class constructors
and destructors
> class C : public C { ... }; // Same than B
>
> These will be different C++ types, but will be equivalent.
I tried that approach and ran into a problem with operator= in my ephemeral
constant for this type. When I used:
class Fraction : public Beagle::Double
{
public:
Fraction (void) : Beagle::Double () {}
Fraction (const double& d) : Beagle::Double (d) {}
virtual ~Fraction() {}
};
I tried to write an operator= based on what I saw in Double.hpp (using
operator+= as a model) but none of my efforts made the error go away. Is the
problem the lack of Fraction::operator= or is it something else?
../beagle-3.0.3/beagle/GP/include/beagle/GP/EphemeralT.hpp:192: error: no match
for 'operator=' in 'lResult =
((Beagle::GP::EphemeralT<Fraction>*)this)->Beagle::GP::EphemeralT<Fraction>::mVa\
lue. Beagle::PointerT<T, BaseType>::operator* [with T =
Beagle::WrapperT<double>, BaseType = Beagle::Pointer]()'
/Users/cwr/Documents/code/TextureSynthesisTest/GP.cpp:115: note: candidates are:
Fraction Fraction::operator=(const Fraction&)
../beagle-3.0.3/beagle/GP/include/beagle/GP/EphemeralT.hpp:159: error: no match
for 'operator=' in 'lValueT =
((Beagle::GP::EphemeralT<Fraction>*)this)->Beagle::GP::EphemeralT<Fraction>::mVa\
lue. Beagle::PointerT<T, BaseType>::operator* [with T =
Beagle::WrapperT<double>, BaseType = Beagle::Pointer]()'
/Users/cwr/Documents/code/TextureSynthesisTest/GP.cpp:115: note: candidates are:
Fraction Fraction::operator=(const Fraction&)
Hi Craig,
As far as you don't need to do special management of your class
attributes, which happen, for example, when you have pointers
referring to heap allocated data, you don't need to define operator=.
The C++ will define a default one for you, that will copy all class
attributes, which is probably just what you needed.
The error message indicates the following, which get my attention.
Fraction Fraction::operator=(const Fraction&)
The return value is a Fraction, therefore the operator= will make a
copy, which will be returned by copy, which will call again operator=,
which will make a copy, and return it by copy and so on. Either the
compiler will be confused, or there will be infinite recursion at run
time when this operator will be called.
Signature for you operator= should be:
Fraction& Fraction::operator=(const Fraction&)
With the return value being a reference.
I don't know if that will solve your problem, but that's certainly a
good starting point.
Best,
Christian
On Oct 28, 2009, at 8:51 PM, Craig Reynolds wrote:
> On 10/26/09 6:32 AM, Christian Gagné wrote:
>> ...But if you do something like... Compiler with consider these
>> three types as different, and therefore use different RTTI type ID /
>> type ID strings... An equivalent solution would be:
>>
>> class A { ... };
>> class B : public A { ... }; // No method declaration out of class
>> constructors and destructors
>> class C : public C { ... }; // Same than B
>>
>> These will be different C++ types, but will be equivalent.
>
>
> I tried that approach and ran into a problem with operator= in my
> ephemeral constant for this type. When I used:
>
> class Fraction : public Beagle::Double
> {
> public:
> Fraction (void) : Beagle::Double () {}
> Fraction (const double& d) : Beagle::Double (d) {}
> virtual ~Fraction() {}
> };
>
> I tried to write an operator= based on what I saw in Double.hpp
> (using operator+= as a model) but none of my efforts made the error
> go away. Is the problem the lack of Fraction::operator= or is it
> something else?
>
>
>
> ../beagle-3.0.3/beagle/GP/include/beagle/GP/EphemeralT.hpp:192:
> error: no match for 'operator=' in 'lResult =
> ((Beagle::GP::EphemeralT<Fraction>*)this)-
> >Beagle::GP::EphemeralT<Fraction>::mValue. Beagle::PointerT<T,
> BaseType>::operator* [with T = Beagle::WrapperT<double>, BaseType =
> Beagle::Pointer]()'
> /Users/cwr/Documents/code/TextureSynthesisTest/GP.cpp:115: note:
> candidates are: Fraction Fraction::operator=(const Fraction&)
> ../beagle-3.0.3/beagle/GP/include/beagle/GP/EphemeralT.hpp:159:
> error: no match for 'operator=' in 'lValueT =
> ((Beagle::GP::EphemeralT<Fraction>*)this)-
> >Beagle::GP::EphemeralT<Fraction>::mValue. Beagle::PointerT<T,
> BaseType>::operator* [with T = Beagle::WrapperT<double>, BaseType =
> Beagle::Pointer]()'
> /Users/cwr/Documents/code/TextureSynthesisTest/GP.cpp:115: note:
> candidates are: Fraction Fraction::operator=(const Fraction&)
>
>
> ------------------------------------
>
> Yahoo! Groups Links
>
>
>
Christian Gagné
http://vision.gel.ulaval.ca/~cgagne
I first tried defining operator= as Christian suggested, but the compiler error
remained. While writing an isolated test case, by a lucky typo, I discovered a
"solution". An assignment from the base class (Double) to the derived class
(Fraction) made the error go away. Then I tried a GP run and it seemed to hang,
perhaps in a copy loop as Christian speculated? Using a configuration that
normally takes a few seconds to complete the first generation, I let this run
for more than 5 minutes and it never completed a generation. The code (below,
forgive the terse format) compiles without error but appears to be broken in
some subtle way. EphemeralFraction is just a copy of EphemeralDouble modified
to produce values between 0 and 1.
class Fraction : public Beagle::Double
{
public:
Fraction (void) : Beagle::Double () {}
Fraction (const double& d) : Beagle::Double (d) {}
virtual ~Fraction() {}
Fraction& operator= (const Beagle::Double& d)
{setWrappedValue(d.getWrappedValue()); return *this;}
};
class EphemeralFraction : public Beagle::GP::EphemeralT<Fraction>
{
public:
typedef
Beagle::AllocatorT<EphemeralFraction,Beagle::GP::EphemeralT<Fraction>::Alloc>
Alloc;
typedef
Beagle::PointerT<EphemeralFraction,Beagle::GP::EphemeralT<Fraction>::Handle>
Handle;
typedef
Beagle::ContainerT<EphemeralFraction,Beagle::GP::EphemeralT<Fraction>::Bag> Bag;
explicit EphemeralFraction(Fraction::Handle inValue=NULL, string
inName="Fraction") : Beagle::GP::EphemeralT<Fraction>(inValue, inName) { }
virtual ~EphemeralFraction() { }
virtual Beagle::GP::Primitive::Handle
EphemeralFraction::generate(Beagle::string inName, Beagle::GP::Context&
ioContext)
{
Beagle_StackTraceBeginM();
Fraction::Handle lValue = new
Fraction(ioContext.getSystem().getRandomizer().rollUniform(0.0,1.0));
return new EphemeralFraction(lValue, inName);
Beagle_StackTraceEndM("GP::Primitive::Handle
GP::EphemeralFraction::generate(string inName, GP::Context& ioContext)");
}
};
Christian Gagné wrote:
> Hi Craig,
>
> As far as you don't need to do special management of your class
> attributes, which happen, for example, when you have pointers referring
> to heap allocated data, you don't need to define operator=. The C++ will
> define a default one for you, that will copy all class attributes, which
> is probably just what you needed.
>
> The error message indicates the following, which get my attention.
>
> Fraction Fraction::operator=(const Fraction&)
>
> The return value is a Fraction, therefore the operator= will make a
> copy, which will be returned by copy, which will call again operator=,
> which will make a copy, and return it by copy and so on. Either the
> compiler will be confused, or there will be infinite recursion at run
> time when this operator will be called.
>
> Signature for you operator= should be:
>
> Fraction& Fraction::operator=(const Fraction&)
>
> With the return value being a reference.
>
> I don't know if that will solve your problem, but that's certainly a
> good starting point.
>
> Best,
>
> Christian
>
>
> On Oct 28, 2009, at 8:51 PM, Craig Reynolds wrote:
>
>> On 10/26/09 6:32 AM, Christian Gagné wrote:
>>> ...But if you do something like... Compiler with consider these
>>> three types as different, and therefore use different RTTI type ID /
>>> type ID strings... An equivalent solution would be:
>>>
>>> class A { ... };
>>> class B : public A { ... }; // No method declaration out of class
>>> constructors and destructors
>>> class C : public C { ... }; // Same than B
>>>
>>> These will be different C++ types, but will be equivalent.
>>
>>
>> I tried that approach and ran into a problem with operator= in my
>> ephemeral constant for this type. When I used:
>>
>> class Fraction : public Beagle::Double
>> {
>> public:
>> Fraction (void) : Beagle::Double () {}
>> Fraction (const double& d) : Beagle::Double (d) {}
>> virtual ~Fraction() {}
>> };
>>
>> I tried to write an operator= based on what I saw in Double.hpp (using
>> operator+= as a model) but none of my efforts made the error go away.
>> Is the problem the lack of Fraction::operator= or is it something else?
>>
>>
>>
>> ../beagle-3.0.3/beagle/GP/include/beagle/GP/EphemeralT.hpp:192: error:
>> no match for 'operator=' in 'lResult =
>>
((Beagle::GP::EphemeralT<Fraction>*)this)->Beagle::GP::EphemeralT<Fraction>::mVa\
lue.
>> Beagle::PointerT<T, BaseType>::operator* [with T =
>> Beagle::WrapperT<double>, BaseType = Beagle::Pointer]()'
>> /Users/cwr/Documents/code/TextureSynthesisTest/GP.cpp:115: note:
>> candidates are: Fraction Fraction::operator=(const Fraction&)
>> ../beagle-3.0.3/beagle/GP/include/beagle/GP/EphemeralT.hpp:159: error:
>> no match for 'operator=' in 'lValueT =
>>
((Beagle::GP::EphemeralT<Fraction>*)this)->Beagle::GP::EphemeralT<Fraction>::mVa\
lue.
>> Beagle::PointerT<T, BaseType>::operator* [with T =
>> Beagle::WrapperT<double>, BaseType = Beagle::Pointer]()'
>> /Users/cwr/Documents/code/TextureSynthesisTest/GP.cpp:115: note:
>> candidates are: Fraction Fraction::operator=(const Fraction&)
Hi Craig,
On Oct 29, 2009, at 2:59 PM, Craig Reynolds wrote:
> I first tried defining operator= as Christian suggested, but the
> compiler error remained. While writing an isolated test case, by a
> lucky typo, I discovered a "solution". An assignment from the base
> class (Double) to the derived class (Fraction) made the error go away.
Ah, I didn't notice this from you explanations/code. Indeed, assigning
base object to a derived object is not handled by default by the C++
language, you need to implement an operator= for allowing that.
> Then I tried a GP run and it seemed to hang, perhaps in a copy loop
> as Christian speculated? Using a configuration that normally takes
> a few seconds to complete the first generation, I let this run for
> more than 5 minutes and it never completed a generation. The code
> (below, forgive the terse format) compiles without error but appears
> to be broken in some subtle way. EphemeralFraction is just a copy
> of EphemeralDouble modified to produce values between 0 and 1.
My intuition is rather that your typing and GP configuration lead to
dead ends in the population initialization process. Possibly, typing
constraints can't be respected by some of the initialization
configuration. A common example of that is minimum tree depth
initialization. By default, it is 2. Therefore, given ramped half-and-
half initialization, it might be requested to generate trees of size
2, using full (or grow) method. This can be incompatible with some
STGP constraints, which are valid only with trees of depth 3 or more.
Open BEAGLE is not able to detect these problems, it would be very
difficult in the general case to do that. Therefore, in that case,
initialization operator will loop indefinitely, trying to generate
individuals of some depth, without being able to obtain anyone that
are respecting the STGP constraints.
From here, best approach is to review the list of primitives you are
using, including their typing, and check that this is not bogus, and
initialization is possible for all depths and tree construction
methods used.
Best,
Christian
>
>
> class Fraction : public Beagle::Double
> {
> public:
> Fraction (void) : Beagle::Double () {}
> Fraction (const double& d) : Beagle::Double (d) {}
> virtual ~Fraction() {}
> Fraction& operator= (const Beagle::Double& d) {setWrappedValue
> (d.getWrappedValue()); return *this;}
> };
>
> class EphemeralFraction : public Beagle::GP::EphemeralT<Fraction>
> {
>
> public:
> typedef
> Beagle
> ::AllocatorT
> <EphemeralFraction,Beagle::GP::EphemeralT<Fraction>::Alloc> Alloc;
> typedef
> Beagle
> ::PointerT
> <EphemeralFraction,Beagle::GP::EphemeralT<Fraction>::Handle> Handle;
> typedef
> Beagle
> ::ContainerT
> <EphemeralFraction,Beagle::GP::EphemeralT<Fraction>::Bag> Bag;
> explicit EphemeralFraction(Fraction::Handle inValue=NULL, string
> inName="Fraction") : Beagle::GP::EphemeralT<Fraction>(inValue,
> inName) { }
> virtual ~EphemeralFraction() { }
> virtual Beagle::GP::Primitive::Handle EphemeralFraction::generate
> (Beagle::string inName, Beagle::GP::Context& ioContext)
> {
> Beagle_StackTraceBeginM();
> Fraction::Handle lValue = new Fraction(ioContext.getSystem
> ().getRandomizer().rollUniform(0.0,1.0));
> return new EphemeralFraction(lValue, inName);
> Beagle_StackTraceEndM("GP::Primitive::Handle
> GP::EphemeralFraction::generate(string inName, GP::Context&
> ioContext)");
> }
> };
>
>
>
>
> Christian Gagné wrote:
>> Hi Craig,
>> As far as you don't need to do special management of your class
>> attributes, which happen, for example, when you have pointers
>> referring to heap allocated data, you don't need to define
>> operator=. The C++ will define a default one for you, that will
>> copy all class attributes, which is probably just what you needed.
>> The error message indicates the following, which get my attention.
>> Fraction Fraction::operator=(const Fraction&)
>> The return value is a Fraction, therefore the operator= will make a
>> copy, which will be returned by copy, which will call again
>> operator=, which will make a copy, and return it by copy and so on.
>> Either the compiler will be confused, or there will be infinite
>> recursion at run time when this operator will be called.
>> Signature for you operator= should be:
>> Fraction& Fraction::operator=(const Fraction&)
>> With the return value being a reference.
>> I don't know if that will solve your problem, but that's certainly
>> a good starting point.
>> Best,
>> Christian
>> On Oct 28, 2009, at 8:51 PM, Craig Reynolds wrote:
>>> On 10/26/09 6:32 AM, Christian Gagné wrote:
>>>> ...But if you do something like... Compiler with consider these
>>>> three types as different, and therefore use different RTTI type
>>>> ID /
>>>> type ID strings... An equivalent solution would be:
>>>>
>>>> class A { ... };
>>>> class B : public A { ... }; // No method declaration out of class
>>>> constructors and destructors
>>>> class C : public C { ... }; // Same than B
>>>>
>>>> These will be different C++ types, but will be equivalent.
>>>
>>>
>>> I tried that approach and ran into a problem with operator= in my
>>> ephemeral constant for this type. When I used:
>>>
>>> class Fraction : public Beagle::Double
>>> {
>>> public:
>>> Fraction (void) : Beagle::Double () {}
>>> Fraction (const double& d) : Beagle::Double (d) {}
>>> virtual ~Fraction() {}
>>> };
>>>
>>> I tried to write an operator= based on what I saw in Double.hpp
>>> (using operator+= as a model) but none of my efforts made the
>>> error go away. Is the problem the lack of Fraction::operator= or
>>> is it something else?
>>>
>>>
>>>
>>> ../beagle-3.0.3/beagle/GP/include/beagle/GP/EphemeralT.hpp:192:
>>> error: no match for 'operator=' in 'lResult =
>>> ((Beagle::GP::EphemeralT<Fraction>*)this)-
>>> >Beagle::GP::EphemeralT<Fraction>::mValue. Beagle::PointerT<T,
>>> BaseType>::operator* [with T = Beagle::WrapperT<double>, BaseType
>>> = Beagle::Pointer]()'
>>> /Users/cwr/Documents/code/TextureSynthesisTest/GP.cpp:115: note:
>>> candidates are: Fraction Fraction::operator=(const Fraction&)
>>> ../beagle-3.0.3/beagle/GP/include/beagle/GP/EphemeralT.hpp:159:
>>> error: no match for 'operator=' in 'lValueT =
>>> ((Beagle::GP::EphemeralT<Fraction>*)this)-
>>> >Beagle::GP::EphemeralT<Fraction>::mValue. Beagle::PointerT<T,
>>> BaseType>::operator* [with T = Beagle::WrapperT<double>, BaseType
>>> = Beagle::Pointer]()'
>>> /Users/cwr/Documents/code/TextureSynthesisTest/GP.cpp:115: note:
>>> candidates are: Fraction Fraction::operator=(const Fraction&)
Christian Gagné
http://vision.gel.ulaval.ca/~cgagne
Christian Gagné wrote:
> Hi Craig,
>
> On Oct 29, 2009, at 2:59 PM, Craig Reynolds wrote:
>
>> I first tried defining operator= as Christian suggested, but the
>> compiler error remained. While writing an isolated test case, by a
>> lucky typo, I discovered a "solution". An assignment from the base
>> class (Double) to the derived class (Fraction) made the error go away.
>
> Ah, I didn't notice this from you explanations/code. Indeed, assigning
> base object to a derived object is not handled by default by the C++
> language, you need to implement an operator= for allowing that.
To be clear, "I" do no such assignments, at least not explicitly. All I do is
write the two definitions below and then add EphemeralFraction to the primitive
set for my STGP run.
>> Then I tried a GP run and it seemed to hang, perhaps in a copy loop as
>> Christian speculated? Using a configuration that normally takes a few
>> seconds to complete the first generation, I let this run for more than
>> 5 minutes and it never completed a generation. The code (below,
>> forgive the terse format) compiles without error but appears to be
>> broken in some subtle way. EphemeralFraction is just a copy of
>> EphemeralDouble modified to produce values between 0 and 1.
>
> My intuition is rather that your typing and GP configuration lead to
> dead ends in the population initialization process. Possibly, typing
> constraints can't be respected by some of the initialization
> configuration. A common example of that is minimum tree depth
> initialization. By default, it is 2. Therefore, given ramped
> half-and-half initialization, it might be requested to generate trees of
> size 2, using full (or grow) method. This can be incompatible with some
> STGP constraints, which are valid only with trees of depth 3 or more.
> Open BEAGLE is not able to detect these problems, it would be very
> difficult in the general case to do that. Therefore, in that case,
> initialization operator will loop indefinitely, trying to generate
> individuals of some depth, without being able to obtain anyone that are
> respecting the STGP constraints.
>
> From here, best approach is to review the list of primitives you are
> using, including their typing, and check that this is not bogus, and
> initialization is possible for all depths and tree construction methods
> used.
I am familiar with this problem, but do not see how it is relevant here. If I
use:
typedef Beagle::Double Fraction;
then everything runs fine (except for the confusion between my Fraction and
SmallFloat types). If I replace the typedef for Fraction with the class
definition below then OB apparently gets into a loop.
> Best,
>
> Christian
>
>
>
>>
>>
>> class Fraction : public Beagle::Double
>> {
>> public:
>> Fraction (void) : Beagle::Double () {}
>> Fraction (const double& d) : Beagle::Double (d) {}
>> virtual ~Fraction() {}
>> Fraction& operator= (const Beagle::Double& d)
>> {setWrappedValue(d.getWrappedValue()); return *this;}
>> };
>>
>> class EphemeralFraction : public Beagle::GP::EphemeralT<Fraction>
>> {
>>
>> public:
>> typedef
>> Beagle::AllocatorT<EphemeralFraction,Beagle::GP::EphemeralT<Fraction>::Alloc>
>> Alloc;
>> typedef
>> Beagle::PointerT<EphemeralFraction,Beagle::GP::EphemeralT<Fraction>::Handle>
>> Handle;
>> typedef
>> Beagle::ContainerT<EphemeralFraction,Beagle::GP::EphemeralT<Fraction>::Bag>
>> Bag;
>> explicit EphemeralFraction(Fraction::Handle inValue=NULL, string
>> inName="Fraction") : Beagle::GP::EphemeralT<Fraction>(inValue, inName)
>> { }
>> virtual ~EphemeralFraction() { }
>> virtual Beagle::GP::Primitive::Handle
>> EphemeralFraction::generate(Beagle::string inName,
>> Beagle::GP::Context& ioContext)
>> {
>> Beagle_StackTraceBeginM();
>> Fraction::Handle lValue = new
>> Fraction(ioContext.getSystem().getRandomizer().rollUniform(0.0,1.0));
>> return new EphemeralFraction(lValue, inName);
>> Beagle_StackTraceEndM("GP::Primitive::Handle
>> GP::EphemeralFraction::generate(string inName, GP::Context& ioContext)");
>> }
>> };
>>
>>
>>
>>
>> Christian Gagné wrote:
>>> Hi Craig,
>>> As far as you don't need to do special management of your class
>>> attributes, which happen, for example, when you have pointers
>>> referring to heap allocated data, you don't need to define operator=.
>>> The C++ will define a default one for you, that will copy all class
>>> attributes, which is probably just what you needed.
>>> The error message indicates the following, which get my attention.
>>> Fraction Fraction::operator=(const Fraction&)
>>> The return value is a Fraction, therefore the operator= will make a
>>> copy, which will be returned by copy, which will call again
>>> operator=, which will make a copy, and return it by copy and so on.
>>> Either the compiler will be confused, or there will be infinite
>>> recursion at run time when this operator will be called.
>>> Signature for you operator= should be:
>>> Fraction& Fraction::operator=(const Fraction&)
>>> With the return value being a reference.
>>> I don't know if that will solve your problem, but that's certainly a
>>> good starting point.
>>> Best,
>>> Christian
>>> On Oct 28, 2009, at 8:51 PM, Craig Reynolds wrote:
>>>> On 10/26/09 6:32 AM, Christian Gagné wrote:
>>>>> ...But if you do something like... Compiler with consider these
>>>>> three types as different, and therefore use different RTTI type ID /
>>>>> type ID strings... An equivalent solution would be:
>>>>>
>>>>> class A { ... };
>>>>> class B : public A { ... }; // No method declaration out of class
>>>>> constructors and destructors
>>>>> class C : public C { ... }; // Same than B
>>>>>
>>>>> These will be different C++ types, but will be equivalent.
>>>>
>>>>
>>>> I tried that approach and ran into a problem with operator= in my
>>>> ephemeral constant for this type. When I used:
>>>>
>>>> class Fraction : public Beagle::Double
>>>> {
>>>> public:
>>>> Fraction (void) : Beagle::Double () {}
>>>> Fraction (const double& d) : Beagle::Double (d) {}
>>>> virtual ~Fraction() {}
>>>> };
>>>>
>>>> I tried to write an operator= based on what I saw in Double.hpp
>>>> (using operator+= as a model) but none of my efforts made the error
>>>> go away. Is the problem the lack of Fraction::operator= or is it
>>>> something else?
>>>>
>>>>
>>>>
>>>> ../beagle-3.0.3/beagle/GP/include/beagle/GP/EphemeralT.hpp:192:
>>>> error: no match for 'operator=' in 'lResult =
>>>>
((Beagle::GP::EphemeralT<Fraction>*)this)->Beagle::GP::EphemeralT<Fraction>::mVa\
lue.
>>>> Beagle::PointerT<T, BaseType>::operator* [with T =
>>>> Beagle::WrapperT<double>, BaseType = Beagle::Pointer]()'
>>>> /Users/cwr/Documents/code/TextureSynthesisTest/GP.cpp:115: note:
>>>> candidates are: Fraction Fraction::operator=(const Fraction&)
>>>> ../beagle-3.0.3/beagle/GP/include/beagle/GP/EphemeralT.hpp:159:
>>>> error: no match for 'operator=' in 'lValueT =
>>>>
((Beagle::GP::EphemeralT<Fraction>*)this)->Beagle::GP::EphemeralT<Fraction>::mVa\
lue.
>>>> Beagle::PointerT<T, BaseType>::operator* [with T =
>>>> Beagle::WrapperT<double>, BaseType = Beagle::Pointer]()'
>>>> /Users/cwr/Documents/code/TextureSynthesisTest/GP.cpp:115: note:
>>>> candidates are: Fraction Fraction::operator=(const Fraction&)
>
> Christian Gagné
> http://vision.gel.ulaval.ca/~cgagne
>
>
>
>
>
Hi,
On Oct 30, 2009, at 10:41 AM, Craig Reynolds wrote:
> Christian Gagné wrote:
>> Hi Craig,
>>
>> On Oct 29, 2009, at 2:59 PM, Craig Reynolds wrote:
>>
>>> I first tried defining operator= as Christian suggested, but the
>>> compiler error remained. While writing an isolated test case, by a
>>> lucky typo, I discovered a "solution". An assignment from the base
>>> class (Double) to the derived class (Fraction) made the error go
>>> away.
>>
>> Ah, I didn't notice this from you explanations/code. Indeed,
>> assigning
>> base object to a derived object is not handled by default by the C++
>> language, you need to implement an operator= for allowing that.
>
> To be clear, "I" do no such assignments, at least not explicitly.
> All I do is write the two definitions below and then add
> EphemeralFraction to the primitive set for my STGP run.
Ah. There is maybe something you trying to do that require this
operator= for assignment of base object to derived object to be called.
>>> Then I tried a GP run and it seemed to hang, perhaps in a copy
>>> loop as
>>> Christian speculated? Using a configuration that normally takes a
>>> few
>>> seconds to complete the first generation, I let this run for more
>>> than
>>> 5 minutes and it never completed a generation. The code (below,
>>> forgive the terse format) compiles without error but appears to be
>>> broken in some subtle way. EphemeralFraction is just a copy of
>>> EphemeralDouble modified to produce values between 0 and 1.
>>
>> My intuition is rather that your typing and GP configuration lead to
>> dead ends in the population initialization process. Possibly, typing
>> constraints can't be respected by some of the initialization
>> configuration. A common example of that is minimum tree depth
>> initialization. By default, it is 2. Therefore, given ramped
>> half-and-half initialization, it might be requested to generate
>> trees of
>> size 2, using full (or grow) method. This can be incompatible with
>> some
>> STGP constraints, which are valid only with trees of depth 3 or more.
>> Open BEAGLE is not able to detect these problems, it would be very
>> difficult in the general case to do that. Therefore, in that case,
>> initialization operator will loop indefinitely, trying to generate
>> individuals of some depth, without being able to obtain anyone that
>> are
>> respecting the STGP constraints.
>>
>> From here, best approach is to review the list of primitives you are
>> using, including their typing, and check that this is not bogus, and
>> initialization is possible for all depths and tree construction
>> methods
>> used.
>
> I am familiar with this problem, but do not see how it is relevant
> here. If I use:
>
> typedef Beagle::Double Fraction;
>
> then everything runs fine (except for the confusion between my
> Fraction and SmallFloat types). If I replace the typedef for
> Fraction with the class definition below then OB apparently gets
> into a loop.
That's because with the definition of Fraction as a class, Double and
Fraction are considered as different types. Beagle will never mix
them. I am quite sure that is the cause of your problem. Enumerate the
return/arguments types of all your primitives, and check whether there
will be bogus combinations. I expect you will find some.
Christian
>> Best,
>>
>> Christian
>>
>>
>>
>>>
>>>
>>> class Fraction : public Beagle::Double
>>> {
>>> public:
>>> Fraction (void) : Beagle::Double () {}
>>> Fraction (const double& d) : Beagle::Double (d) {}
>>> virtual ~Fraction() {}
>>> Fraction& operator= (const Beagle::Double& d)
>>> {setWrappedValue(d.getWrappedValue()); return *this;}
>>> };
>>>
>>> class EphemeralFraction : public Beagle::GP::EphemeralT<Fraction>
>>> {
>>>
>>> public:
>>> typedef
>>> Beagle
>>> ::AllocatorT
>>> <EphemeralFraction,Beagle::GP::EphemeralT<Fraction>::Alloc>
>>> Alloc;
>>> typedef
>>> Beagle
>>> ::PointerT
>>> <EphemeralFraction,Beagle::GP::EphemeralT<Fraction>::Handle>
>>> Handle;
>>> typedef
>>> Beagle
>>> ::ContainerT
>>> <EphemeralFraction,Beagle::GP::EphemeralT<Fraction>::Bag>
>>> Bag;
>>> explicit EphemeralFraction(Fraction::Handle inValue=NULL, string
>>> inName="Fraction") : Beagle::GP::EphemeralT<Fraction>(inValue,
>>> inName)
>>> { }
>>> virtual ~EphemeralFraction() { }
>>> virtual Beagle::GP::Primitive::Handle
>>> EphemeralFraction::generate(Beagle::string inName,
>>> Beagle::GP::Context& ioContext)
>>> {
>>> Beagle_StackTraceBeginM();
>>> Fraction::Handle lValue = new
>>> Fraction(ioContext.getSystem().getRandomizer().rollUniform
>>> (0.0,1.0));
>>> return new EphemeralFraction(lValue, inName);
>>> Beagle_StackTraceEndM("GP::Primitive::Handle
>>> GP::EphemeralFraction::generate(string inName, GP::Context&
>>> ioContext)");
>>> }
>>> };
>>>
>>>
>>>
>>>
>>> Christian Gagné wrote:
>>>> Hi Craig,
>>>> As far as you don't need to do special management of your class
>>>> attributes, which happen, for example, when you have pointers
>>>> referring to heap allocated data, you don't need to define
>>>> operator=.
>>>> The C++ will define a default one for you, that will copy all class
>>>> attributes, which is probably just what you needed.
>>>> The error message indicates the following, which get my attention.
>>>> Fraction Fraction::operator=(const Fraction&)
>>>> The return value is a Fraction, therefore the operator= will make a
>>>> copy, which will be returned by copy, which will call again
>>>> operator=, which will make a copy, and return it by copy and so on.
>>>> Either the compiler will be confused, or there will be infinite
>>>> recursion at run time when this operator will be called.
>>>> Signature for you operator= should be:
>>>> Fraction& Fraction::operator=(const Fraction&)
>>>> With the return value being a reference.
>>>> I don't know if that will solve your problem, but that's
>>>> certainly a
>>>> good starting point.
>>>> Best,
>>>> Christian
>>>> On Oct 28, 2009, at 8:51 PM, Craig Reynolds wrote:
>>>>> On 10/26/09 6:32 AM, Christian Gagné wrote:
>>>>>> ...But if you do something like... Compiler with consider these
>>>>>> three types as different, and therefore use different RTTI type
>>>>>> ID /
>>>>>> type ID strings... An equivalent solution would be:
>>>>>>
>>>>>> class A { ... };
>>>>>> class B : public A { ... }; // No method declaration out of class
>>>>>> constructors and destructors
>>>>>> class C : public C { ... }; // Same than B
>>>>>>
>>>>>> These will be different C++ types, but will be equivalent.
>>>>>
>>>>>
>>>>> I tried that approach and ran into a problem with operator= in my
>>>>> ephemeral constant for this type. When I used:
>>>>>
>>>>> class Fraction : public Beagle::Double
>>>>> {
>>>>> public:
>>>>> Fraction (void) : Beagle::Double () {}
>>>>> Fraction (const double& d) : Beagle::Double (d) {}
>>>>> virtual ~Fraction() {}
>>>>> };
>>>>>
>>>>> I tried to write an operator= based on what I saw in Double.hpp
>>>>> (using operator+= as a model) but none of my efforts made the
>>>>> error
>>>>> go away. Is the problem the lack of Fraction::operator= or is it
>>>>> something else?
>>>>>
>>>>>
>>>>>
>>>>> ../beagle-3.0.3/beagle/GP/include/beagle/GP/EphemeralT.hpp:192:
>>>>> error: no match for 'operator=' in 'lResult =
>>>>> ((Beagle::GP::EphemeralT<Fraction>*)this)-
>>>>> >Beagle::GP::EphemeralT<Fraction>::mValue.
>>>>> Beagle::PointerT<T, BaseType>::operator* [with T =
>>>>> Beagle::WrapperT<double>, BaseType = Beagle::Pointer]()'
>>>>> /Users/cwr/Documents/code/TextureSynthesisTest/GP.cpp:115: note:
>>>>> candidates are: Fraction Fraction::operator=(const Fraction&)
>>>>> ../beagle-3.0.3/beagle/GP/include/beagle/GP/EphemeralT.hpp:159:
>>>>> error: no match for 'operator=' in 'lValueT =
>>>>> ((Beagle::GP::EphemeralT<Fraction>*)this)-
>>>>> >Beagle::GP::EphemeralT<Fraction>::mValue.
>>>>> Beagle::PointerT<T, BaseType>::operator* [with T =
>>>>> Beagle::WrapperT<double>, BaseType = Beagle::Pointer]()'
>>>>> /Users/cwr/Documents/code/TextureSynthesisTest/GP.cpp:115: note:
>>>>> candidates are: Fraction Fraction::operator=(const Fraction&)
>>
>> Christian Gagné
>> http://vision.gel.ulaval.ca/~cgagne
>>
>>
>>
>>
>>
>
>
>
> ------------------------------------
>
> Yahoo! Groups Links
>
>
>
Christian Gagné
http://vision.gel.ulaval.ca/~cgagne
Christian Gagné wrote:
> ...I am quite sure that is the cause of your problem. Enumerate the
> return/arguments types of all your primitives, and check whether there
> will be bogus combinations. I expect you will find some.
Sigh. The line were EphemeralFraction is inserted into the primitives had been
commented out for testing. Thanks for pointing me to the problem, sorry for
making you repeat the advice.
Craig
In my STGP application I now have 3 kinds of "ranged numeric values" (Fraction,
SmallFloat and SmallPosFloat (actually double not float)). For each I define an
OB wrapped type subclassed from Double, an ephemeral constant class based on
that type (a clone of EphemeralDouble), and a mutation operator for that
ephemeral constant class (a clone of MutationEphemeralDoubleOp). Everything
builds and runs OK -- the STGP trees look fine -- but I now suspect that no
mutation is actually happening.
I was about to try implementing the "constant jiggling" approach, so I
duplicated and renamed MutationEphemeralOpT to MutationJiggleEphemeralOpT. With
some debug printing, I can see the three kinds of mutation operator being
called. But when I looked closer at the
Beagle::GP::MutationJiggleEphemeralOpT<T>::mutate method, I found that control
never reached the section of code labeled "// Mutate parameter value." It seems
to exit at "if(lPotentialParam.empty()) return false;" In all cases
mEphemeralName->getWrappedValue() is "E" -- the name associated with Double
which should not exist in my STGP, so there are no "potential parameters" to
mutate. That was mysterious until I noticed that the initialize method (from
MutationEphemeralOpT) sets mEphemeralName to "E" unless
ioSystem.getRegister().isRegistered(mEphemeralNameParamName)
Any idea why that might be happening? My XML configuration file sets a value
for gp.mutephFraction.indpb (etc.) There is a clause for
GP-MutationEphemeralFractionOp (etc.) inside the MainLoopSet. I do a
"lEvolver->addOperator(new MutationEphemeralFractionOp)" etc. Is there some
other registration step I am not doing? Do I have to declare
gp.mutephFraction.primit somewhere?
Other random questions:
I tried to call Beagle::GP::EphemeralT<T>::getValue to examine the actual
numerical value of a given ephemeral constant. It threw a
Beagle_InternalExceptionM ("Could not execute as the constant value is
missing!") OK, I will call getValue only when haveValue is true. That got the
same exception. When I looked at the source, haveValue *always* returns true!
Shouldn't it return mValue as a bool?
What does this mean?
<Log>Applying "SteadyStateOp"</Log>
<Log>Sum of probabilities of breeder operators children to replacement
strategy named "SteadyStateOp" is different from 1.0 (value: 1.2)</Log>
On 10/9/09 10:39 AM, Christian Gagné wrote:
> Hi Craig,
>
> I was about to answer you on that topic. I agree that current
> mutation of ephemeral random variables may look not optimal, that
> slightly changing value of the ephemeral random values will probably
> be less drastic that completely replacing it. It was a choice I made
> at the time, as I wanted to have a general ephemeral random value
> mutation operator to provide users with. I remember I had in mind at
> that time to provide another version similar to what you proposed.
> But it seems that I passed onto something else and I didn't
> implemented it.
>
> Implementing a "constant jiggling" operator specific for
> double-valued ephemerals seems to me relatively simple to do,
> starting from MutationEphemeralOpT code. Just need to change the code
> from calling EphemeralT::generate to getting the double value and
> modify it.
>
> Coding a general version, for constant jiggling mutation operator,
> being it for Double, Int, or anything else is more complicated. It
> would require to add a constant variation method to add to EphemeralT
> template, and to implement it for all types of ephemerals. Having
> time, I would go for that if I had to code it, but it seems that my
> schedule is quite heavy these days, so I'll not have time to give it
> a try.
>
> Best,
>
> Christian
>
>
>
> On Oct 9, 2009, at 1:27 PM, Craig Reynolds wrote:
>
>> I started to prototype this approach, adding a generic "adjust
>> ephemeral constants" operator that calls a virtual mutation method
>> on a variant of EphemeralT. But as I looked at the code
>> (EphemeralT, EphemeralDouble, MutationEphemeralOpT and
>> MutationEphemeralDoubleOp) it seemed like the constructor and
>> generate methods of EphemeralT "almost" do this ("if the value is
>> NULL, act a an ephemeral generator") or could be made to do this
>> with a tiny patch. The code is still a bit mysterious to me (the
>> way the functionality is spread across four classes) so rather than
>> wander off in the wrong direction, I will wait for some advice from
>> Christian. My ephemeral constants can stay unmutated for now while
>> I work on other parts of my project.
>>
>>
>> On 10/7/09 12:26 PM, Craig Reynolds wrote:
>>>
>>> ...I was also surprised that MutationEphemeralDoubleOp appears to
>>> simply replace one value for an ephemeral constant with another.
>>> In my previous experience with GP I had implemented this as an
>>> incremental "adjustment" to the previous value of the constant.
>>> For example the new value would be a random number between 0.95
>>> and 1.05 multiplied by the old value. Other GPers called this
>>> mutation operator "constant jiggling". The intuition was that a
>>> program might have evolved that was almost correct, but just
>>> needed to have some of its "parameters" tweaked. Is there a
>>> reason to prefer replacement over adjustment when mutating
>>> ephemeral constants? Might an "adjustment" style mutation be
>>> added in a future version of OB?
>>>
>>> Perhaps I should wait until I have a fuller understanding of
>>> MutationEphemeralDoubleOp but I wondered if it would make sense
>>> for a single generic MutationEphemeralOp to work on all kinds of
>>> EphemeralT by calling a virtual method on the ephemeral constant
>>> to return a new mutated value, which could optionally be an
>>> incremental adjustment of the old value. That is: must the author
>>> of a new kind of ephemeral constant also define a new kind of
>>> mutation operator for it? Or can the process be simplified to
>>> just adding one more method to the new ephemeral constant class?
>>> Sorry if I'm missing something obvious.
Hi Craig,
On Nov 3, 2009, at 12:44 PM, Craig Reynolds wrote:
> In my STGP application I now have 3 kinds of "ranged numeric
> values" (Fraction, SmallFloat and SmallPosFloat (actually double not
> float)). For each I define an OB wrapped type subclassed from
> Double, an ephemeral constant class based on that type (a clone of
> EphemeralDouble), and a mutation operator for that ephemeral
> constant class (a clone of MutationEphemeralDoubleOp). Everything
> builds and runs OK -- the STGP trees look fine -- but I now suspect
> that no mutation is actually happening.
>
> I was about to try implementing the "constant jiggling" approach, so
> I duplicated and renamed MutationEphemeralOpT to
> MutationJiggleEphemeralOpT. With some debug printing, I can see the
> three kinds of mutation operator being called. But when I looked
> closer at the Beagle::GP::MutationJiggleEphemeralOpT<T>::mutate
> method, I found that control never reached the section of code
> labeled "// Mutate parameter value." It seems to exit at "if
> (lPotentialParam.empty()) return false;" In all cases
> mEphemeralName->getWrappedValue() is "E" -- the name associated with
> Double which should not exist in my STGP, so there are no "potential
> parameters" to mutate. That was mysterious until I noticed that the
> initialize method (from MutationEphemeralOpT) sets mEphemeralName to
> "E" unless ioSystem.getRegister().isRegistered
> (mEphemeralNameParamName)
>
> Any idea why that might be happening? My XML configuration file
> sets a value for gp.mutephFraction.indpb (etc.) There is a clause
> for GP-MutationEphemeralFractionOp (etc.) inside the MainLoopSet. I
> do a "lEvolver->addOperator(new MutationEphemeralFractionOp)" etc.
> Is there some other registration step I am not doing? Do I have to
> declare gp.mutephFraction.primit somewhere?
It is difficult to tell being where I am. That's true that the
MutationEphemeralOpT looks for primitives of a certain name, by
default "E". That name is specified in parameter "gp.muteph.primit",
or the equivalent in your mutation operator. The name used should
match the name of the ephemeral constants in your tree. Otherwise, it
is expected that nothing will happen, as the mutation operator is
first looking for nodes in the tree with of the given primitive name.
If there are no of the given name, no mutation is done.
> Other random questions:
>
> I tried to call Beagle::GP::EphemeralT<T>::getValue to examine the
> actual numerical value of a given ephemeral constant. It threw a
> Beagle_InternalExceptionM ("Could not execute as the constant value
> is missing!") OK, I will call getValue only when haveValue is
> true. That got the same exception. When I looked at the source,
> haveValue *always* returns true! Shouldn't it return mValue as a
> bool?
That's true, and that's odd. I can't tell if it is a bug, I would need
to check further, but that doesn't look like something correct..
> What does this mean?
> <Log>Applying "SteadyStateOp"</Log>
> <Log>Sum of probabilities of breeder operators children to
> replacement strategy named "SteadyStateOp" is different from 1.0
> (value: 1.2)</Log>
The probabilities of the operators that can be done in the steady-
state loop (crossover, mutations) do not sum to one. Given that, they
will be normalized inside the steady-state loop.
Christian
>
>
>
> On 10/9/09 10:39 AM, Christian Gagné wrote:
>> Hi Craig,
>> I was about to answer you on that topic. I agree that current
>> mutation of ephemeral random variables may look not optimal, that
>> slightly changing value of the ephemeral random values will probably
>> be less drastic that completely replacing it. It was a choice I made
>> at the time, as I wanted to have a general ephemeral random value
>> mutation operator to provide users with. I remember I had in mind at
>> that time to provide another version similar to what you proposed.
>> But it seems that I passed onto something else and I didn't
>> implemented it.
>> Implementing a "constant jiggling" operator specific for
>> double-valued ephemerals seems to me relatively simple to do,
>> starting from MutationEphemeralOpT code. Just need to change the code
>> from calling EphemeralT::generate to getting the double value and
>> modify it.
>> Coding a general version, for constant jiggling mutation operator,
>> being it for Double, Int, or anything else is more complicated. It
>> would require to add a constant variation method to add to EphemeralT
>> template, and to implement it for all types of ephemerals. Having
>> time, I would go for that if I had to code it, but it seems that my
>> schedule is quite heavy these days, so I'll not have time to give it
>> a try.
>> Best,
>> Christian
>> On Oct 9, 2009, at 1:27 PM, Craig Reynolds wrote:
>>> I started to prototype this approach, adding a generic "adjust
>>> ephemeral constants" operator that calls a virtual mutation method
>>> on a variant of EphemeralT. But as I looked at the code
>>> (EphemeralT, EphemeralDouble, MutationEphemeralOpT and
>>> MutationEphemeralDoubleOp) it seemed like the constructor and
>>> generate methods of EphemeralT "almost" do this ("if the value is
>>> NULL, act a an ephemeral generator") or could be made to do this
>>> with a tiny patch. The code is still a bit mysterious to me (the
>>> way the functionality is spread across four classes) so rather than
>>> wander off in the wrong direction, I will wait for some advice from
>>> Christian. My ephemeral constants can stay unmutated for now while
>>> I work on other parts of my project.
>>> On 10/7/09 12:26 PM, Craig Reynolds wrote:
>>>> ...I was also surprised that MutationEphemeralDoubleOp appears to
>>>> simply replace one value for an ephemeral constant with another.
>>>> In my previous experience with GP I had implemented this as an
>>>> incremental "adjustment" to the previous value of the constant.
>>>> For example the new value would be a random number between 0.95
>>>> and 1.05 multiplied by the old value. Other GPers called this
>>>> mutation operator "constant jiggling". The intuition was that a
>>>> program might have evolved that was almost correct, but just
>>>> needed to have some of its "parameters" tweaked. Is there a
>>>> reason to prefer replacement over adjustment when mutating
>>>> ephemeral constants? Might an "adjustment" style mutation be
>>>> added in a future version of OB?
>>>> Perhaps I should wait until I have a fuller understanding of
>>>> MutationEphemeralDoubleOp but I wondered if it would make sense
>>>> for a single generic MutationEphemeralOp to work on all kinds of
>>>> EphemeralT by calling a virtual method on the ephemeral constant
>>>> to return a new mutated value, which could optionally be an
>>>> incremental adjustment of the old value. That is: must the author
>>>> of a new kind of ephemeral constant also define a new kind of
>>>> mutation operator for it? Or can the process be simplified to
>>>> just adding one more method to the new ephemeral constant class?
>>>> Sorry if I'm missing something obvious.
Christian Gagné
http://vision.gel.ulaval.ca/~cgagne
Thanks Christian, with your comments I found my problem. I needed to add 3
items for the ".primit" names to my configuration file:
<Entry key="gp.mutephFraction.primit">Fraction</Entry>
<Entry key="gp.mutephSmallFloat.primit">SmallFloat</Entry>
<Entry key="gp.mutephSmallPosFloat.primit">SmallPosFloat</Entry>
That is what I was trying to ask about in my previous note. It would have been
more obvious to me that I needed to do this if there was a corresponding entry
for MutationEphemeralDoubleOp in supplied sample code. I think I previously
suggested that in 4.0.0 there be sample code that uses EphemeralDouble. However
an attempt to do "programming by example" (say grepping the OB tree for
"muteph") in this case would have been complicated by the fact that
MutationEphemeralOpT has a "bias" toward Doubles. From the perspective of an
STGP user that seems counterproductive. Perhaps it is there for the sake of
"non-ST" GP?
In any case, thanks for the quick hint that got me going again,
Craig
Christian Gagné wrote:
> Hi Craig,
>
> On Nov 3, 2009, at 12:44 PM, Craig Reynolds wrote:
>
>> ...I was about to try implementing the "constant jiggling"
>> approach... In all cases mEphemeralName->getWrappedValue() is "E"
>> -- the name associated with Double which should not exist in my
>> STGP, so there are no "potential parameters" to mutate. That was
>> mysterious until I noticed that the initialize method (from
>> MutationEphemeralOpT) sets mEphemeralName to "E" unless
>> ioSystem.getRegister().isRegistered(mEphemeralNameParamName)
>>
>> Any idea why that might be happening? My XML configuration file
>> sets a value for gp.mutephFraction.indpb (etc.) There is a clause
>> for GP-MutationEphemeralFractionOp (etc.) inside the MainLoopSet.
>> I do a "lEvolver->addOperator(new MutationEphemeralFractionOp)"
>> etc. Is there some other registration step I am not doing? Do I
>> have to declare gp.mutephFraction.primit somewhere?
>
> It is difficult to tell being where I am. That's true that the
> MutationEphemeralOpT looks for primitives of a certain name, by
> default "E". That name is specified in parameter "gp.muteph.primit",
> or the equivalent in your mutation operator. The name used should
> match the name of the ephemeral constants in your tree. Otherwise, it
> is expected that nothing will happen, as the mutation operator is
> first looking for nodes in the tree with of the given primitive name.
> If there are no of the given name, no mutation is done.
Finally this works! I seem to be successfully doing "constant jiggling" on my
three classes of "ranged Doubles". I tried two version of where this new mutate
method should go. First I tried putting it on the ephemeral constant class
(like EphemeralDouble), decided the modularity was messy, and moved it to the
wrapped number class (like Double, "T" in the code below). I modified just a
portion of Beagle::GP::MutationJiggleEphemeralOpT<T>::mutate. Where it used to
say:
// Mutate parameter value.
GP::Primitive::Handle lSelectedPrimit =
(*lSelectedTree)[lPotentialParam[lSelectedParam].second].mPrimitive;
typename GP::EphemeralT<T>::Handle lSelectedEphemeral =
castHandleT<typename GP::EphemeralT<T> >(lSelectedPrimit);
GP::Primitive::Handle lGeneratedPrimit =
lSelectedEphemeral->generate(mEphemeralName->getWrappedValue(), lContext);
(*lSelectedTree)[lPotentialParam[lSelectedParam].second].mPrimitive =
lGeneratedPrimit;
Beagle_LogVerboseM(
ioContext.getSystem().getLogger(),
"mutation", "Beagle::GP::MutationJiggleEphemeralOpT",
string("Changing the ephemeral from ")+lSelectedPrimit->serialize()+
string(" to ")+lGeneratedPrimit->serialize()
);
it now says:
// Mutate parameter value.
GP::Primitive::Handle lSelectedPrimit =
(*lSelectedTree)[lPotentialParam[lSelectedParam].second].mPrimitive;
typename GP::EphemeralT<T>::Handle lSelectedEphemeral =
castHandleT<typename GP::EphemeralT<T> >(lSelectedPrimit);
std::cout << "Jiggle mutation -- before: " << lSelectedEphemeral->serialize();
T temp;
lSelectedEphemeral->getValue (temp);
temp.setWrappedValue(temp.mutate(lContext));
lSelectedEphemeral->setValue (temp);
std::cout << " after: " << lSelectedEphemeral->serialize() << std::endl;
// Beagle_LogVerboseM(
// ioContext.getSystem().getLogger(),
// "mutation", "Beagle::GP::MutationJiggleEphemeralOpT",
// string("Changing the ephemeral from ")+lSelectedPrimit->serialize()+
// string(" to ")+lGeneratedPrimit->serialize()
// );
those print outs convince me that it is working correctly, but I am easily
fooled:
Jiggle mutation -- before: <SmallFloat value="-0.644849"/> after: <SmallFloat
value="-0.418695"/>
Jiggle mutation -- before: <Fraction value="0.0677889"/> after: <Fraction
value="0.111499"/>
Jiggle mutation -- before: <Fraction value="0.0910494"/> after: <Fraction
value="0.0992486"/>
Jiggle mutation -- before: <Fraction value="0.655258"/> after: <Fraction
value="0.628954"/>
Jiggle mutation -- before: <SmallFloat value="1.27035"/> after: <SmallFloat
value="1.28836"/>
Jiggle mutation -- before: <SmallPosFloat value="3.10858"/> after:
<SmallPosFloat value="2.83929"/>
My only problem at this point is that I broke the Beagle_LogVerboseM at the end
of that code fragment. I would appreciate suggestions on how to repair it. I
would also appreciate a review of my code for doing things "the OB way"
Thanks for all the help,
Craig
Hi Craig,
Ok, so you added a mutate() method to the T type, that is the Doubles,
Fraction, etc. It seems to work well for your case, so that's fine for
your application. But if I were to add this constant jiggling thing to
Open BEAGLE, I would keep the mutate() function in the
Beagle::GP::MutationJiggleEphemeralOp class. I always tried to avoid
bloating the interface of the wrapped classes with many methods of no
general use.
A simple solution there would be to define a mutation operator
specifically for Double type, that is a
Beagle::GP::MutationJiggleEphemeralDoubleOp class. Still, it would be
quite general, and would work for your case, given that your Fraction,
SmallFloat, SmallPosFloat types are all derived from Double.
For the Logging thing, I see two solutions:
- Make two calls to the logger, log the value before, and then log the
value after.
- Put the value before in a string or temporary variable. That reduces
the number of log entries, but add overheads even when log level is low.
In Beagle, I would implement the first approach, as I always try to
reduce these kind of overheads.
Best,
Christian
On Nov 3, 2009, at 9:35 PM, Craig Reynolds wrote:
> Finally this works! I seem to be successfully doing "constant
> jiggling" on my three classes of "ranged Doubles". I tried two
> version of where this new mutate method should go. First I tried
> putting it on the ephemeral constant class (like EphemeralDouble),
> decided the modularity was messy, and moved it to the wrapped number
> class (like Double, "T" in the code below). I modified just a
> portion of Beagle::GP::MutationJiggleEphemeralOpT<T>::mutate. Where
> it used to say:
>
>
> // Mutate parameter value.
> GP::Primitive::Handle lSelectedPrimit =
> (*lSelectedTree)[lPotentialParam[lSelectedParam].second].mPrimitive;
> typename GP::EphemeralT<T>::Handle lSelectedEphemeral =
> castHandleT<typename GP::EphemeralT<T> >(lSelectedPrimit);
> GP::Primitive::Handle lGeneratedPrimit =
> lSelectedEphemeral->generate(mEphemeralName->getWrappedValue(),
> lContext);
> (*lSelectedTree)[lPotentialParam[lSelectedParam].second].mPrimitive
> = lGeneratedPrimit;
>
> Beagle_LogVerboseM(
> ioContext.getSystem().getLogger(),
> "mutation", "Beagle::GP::MutationJiggleEphemeralOpT",
> string("Changing the ephemeral from ")+lSelectedPrimit->serialize()+
> string(" to ")+lGeneratedPrimit->serialize()
> );
>
>
> it now says:
>
>
> // Mutate parameter value.
> GP::Primitive::Handle lSelectedPrimit =
> (*lSelectedTree)[lPotentialParam[lSelectedParam].second].mPrimitive;
> typename GP::EphemeralT<T>::Handle lSelectedEphemeral =
> castHandleT<typename GP::EphemeralT<T> >(lSelectedPrimit);
> std::cout << "Jiggle mutation -- before: " << lSelectedEphemeral-
> >serialize();
> T temp;
> lSelectedEphemeral->getValue (temp);
> temp.setWrappedValue(temp.mutate(lContext));
> lSelectedEphemeral->setValue (temp);
> std::cout << " after: " << lSelectedEphemeral->serialize() <<
> std::endl;
>
> // Beagle_LogVerboseM(
> // ioContext.getSystem().getLogger(),
> // "mutation", "Beagle::GP::MutationJiggleEphemeralOpT",
> // string("Changing the ephemeral from ")+lSelectedPrimit-
> >serialize()+
> // string(" to ")+lGeneratedPrimit->serialize()
> // );
>
>
> those print outs convince me that it is working correctly, but I am
> easily fooled:
> Jiggle mutation -- before: <SmallFloat value="-0.644849"/> after:
> <SmallFloat value="-0.418695"/>
> Jiggle mutation -- before: <Fraction value="0.0677889"/> after:
> <Fraction value="0.111499"/>
> Jiggle mutation -- before: <Fraction value="0.0910494"/> after:
> <Fraction value="0.0992486"/>
> Jiggle mutation -- before: <Fraction value="0.655258"/> after:
> <Fraction value="0.628954"/>
> Jiggle mutation -- before: <SmallFloat value="1.27035"/> after:
> <SmallFloat value="1.28836"/>
> Jiggle mutation -- before: <SmallPosFloat value="3.10858"/> after:
> <SmallPosFloat value="2.83929"/>
>
> My only problem at this point is that I broke the Beagle_LogVerboseM
> at the end of that code fragment. I would appreciate suggestions on
> how to repair it. I would also appreciate a review of my code for
> doing things "the OB way"
>
>
> Thanks for all the help,
> Craig
Christian Gagné
http://vision.gel.ulaval.ca/~cgagne
To be clear, my goal was to get my application working as quickly as possible.
Your concern is the design integrity of Open BEAGLE. (Well and supporting your
users, for which I again thank you.) I will toss off suggestions but I
recognize that you are the one who decides on future changes to Open BEAGLE.
That said, the reason I liked putting the mutate method on the STGP type (like
Double or Fraction, not on the ephemeral constant or the mutation operator) is
that it serves to localize the behavior of the type. In my application, the
three "ranged doubles" types have distinct mutation behavior. (The mutate
method is the same but it depends on bounds max() and min() methods defined
procedurally on the type: double Fraction::max (void) {return 1.0;}) I like the
idea that an OB end-user would just define an STGP type and then use templates
to make an ephemeral constant based on it, and a mutation operator based on
that.
I understand the desire to keep interfaces simple, and that this feature is only
relevant to STGP. Still WrapperT (hence Double?) already has about 30 methods
(Public Types, Public Member Functions and Related Functions) listed on
http://beagle.gel.ulaval.ca/refmanual/beagle/html/d3/d83/classBeagle_1_1WrapperT\
.html (These pages may be obsolete but note that Double is not listed on
http://beagle.gel.ulaval.ca/refmanual/beagle/html/annotated.html)
Best,
Craig
Christian Gagné wrote:
> Ok, so you added a mutate() method to the T type, that is the Doubles,
> Fraction, etc. It seems to work well for your case, so that's fine for
> your application. But if I were to add this constant jiggling thing to
> Open BEAGLE, I would keep the mutate() function in the
> Beagle::GP::MutationJiggleEphemeralOp class. I always tried to avoid
> bloating the interface of the wrapped classes with many methods of no
> general use.
>
> A simple solution there would be to define a mutation operator
> specifically for Double type, that is a
> Beagle::GP::MutationJiggleEphemeralDoubleOp class. Still, it would be
> quite general, and would work for your case, given that your Fraction,
> SmallFloat, SmallPosFloat types are all derived from Double.
Dear all,
I have a question with open beagle's normalization of crossover, mutation and
reproduction probabilities. For example,
If I specify crossover and mutation probabilities in command line with:
./symbreg -OBec.pop.size=100,gp.cx.indpb=0.75,gp.mutstd.indpb=0.25
I also output a dump file with:
./symbreg
-OBec.pop.size=100,gp.cx.indpb=0.75,gp.mutstd.indpb=0.25,dump=dump.conf
In dump.conf, we can see this:
<?xml version="1.0" encoding="ISO-8859-1"?>
<Beagle version="3.1.0">
<!--This file is the result of a configuration dump-->
<Evolver>
<BootStrapSet>
<GP-InitHalfOp repropb="ec.repro.prob"/>
<SymbRegEvalOp/>
<GP-StatsCalcFitnessSimpleOp/>
<TermMaxGenOp/>
<MilestoneWriteOp/>
</BootStrapSet>
<MainLoopSet>
<SelectTournamentOp repropb="ec.repro.prob"/>
<GP-CrossoverOp matingpb="gp.cx.indpb" distrpb="gp.cx.distrpb"/>
<GP-MutationStandardOp mutationpb="gp.mutstd.indpb"
maxdepth="gp.mutstd.maxdepth"/>
<SymbRegEvalOp/>
<MigrationRingOp/>
<GP-StatsCalcFitnessSimpleOp/>
<TermMaxGenOp/>
<MilestoneWriteOp/>
</MainLoopSet>
</Evolver>
<System>
<Register>
<Entry key="ec.hof.demesize">0</Entry>
<Entry key="ec.hof.vivasize">1</Entry>
<Entry key="ec.init.seedsfile"/>
<Entry key="ec.mig.interval">1</Entry>
<Entry key="ec.mig.size">5</Entry>
<Entry key="ec.pop.size">100</Entry>
<Entry key="ec.rand.seed">0</Entry>
<Entry key="ec.repro.prob">0.1</Entry>
<Entry key="ec.sel.tournsize">7</Entry>
<Entry key="ec.term.maxgen">50</Entry>
<Entry key="ec.test.indi"/>
<Entry key="gp.cx.distrpb">0.9</Entry>
<Entry key="gp.cx.indpb">0.75</Entry>
<Entry key="gp.init.kozagrow">0</Entry>
<Entry key="gp.init.maxdepth">5</Entry>
<Entry key="gp.init.maxtree">1</Entry>
<Entry key="gp.init.mindepth">2</Entry>
<Entry key="gp.init.mintree">1</Entry>
<Entry key="gp.mutstd.indpb">0.25</Entry>
<Entry key="gp.mutstd.maxdepth">5</Entry>
<Entry key="gp.tree.maxargs">0,2</Entry>
<Entry key="gp.tree.maxdepth">17</Entry>
<Entry key="gp.tree.minargs">0,2</Entry>
<Entry key="gp.try">2</Entry>
<Entry key="lg.console.level">2</Entry>
<Entry key="lg.file.level">3</Entry>
<Entry key="lg.file.name">beagle.log</Entry>
<Entry key="lg.show.class">0</Entry>
<Entry key="lg.show.level">0</Entry>
<Entry key="lg.show.type">0</Entry>
<Entry key="ms.write.compress">1</Entry>
<Entry key="ms.write.interval">0</Entry>
<Entry key="ms.write.over">1</Entry>
<Entry key="ms.write.perdeme">0</Entry>
<Entry key="ms.write.prefix">beagle</Entry>
</Register>
The entry for ec.repro.prob is 0.1, the entry for gp.cx.indpb is 0.75 and the
entry for gp.mutstd.indpb is 0.25. The sum is 1.1, not 1. Does Open Beagle
normalize probabilities? That is the probability for reproduction is 0.1/1.1,
for crossover is 0.75/1.1 and mutation is 0.25/1.1. Or do crossover and mutation
happen when no reproduction happens: that is, probability for reproduction is
0.1, for crossover is 0.75*0.9, and for mutation is 0.25*0.9?
thanks,
Linge
[Non-text portions of this message have been removed]
Bai Linge wrote:
> ...The entry for ec.repro.prob is 0.1, the entry for gp.cx.indpb is
> 0.75 and the entry for gp.mutstd.indpb is 0.25. The sum is 1.1, not
> 1. Does Open Beagle normalize probabilities? That is the probability
> for reproduction is 0.1/1.1, for crossover is 0.75/1.1 and mutation
> is 0.25/1.1. Or do crossover and mutation happen when no reproduction
> happens: that is, probability for reproduction is 0.1, for crossover
> is 0.75*0.9, and for mutation is 0.25*0.9?
I'm not the authority, but I think the answer is yes based on a recent reply
from Christian:
On Nov 3, 2009, at 12:44 PM, Craig Reynolds wrote:
> What does this mean?
> <Log>Applying "SteadyStateOp"</Log>
> <Log>Sum of probabilities of breeder operators children to replacement
> strategy named "SteadyStateOp" is different from 1.0 (value: 1.2)</Log>
On 11/3/09 10:19 AM, Christian Gagné wrote:
> The probabilities of the operators that can be done in the
> steady-state loop (crossover, mutations) do not sum to one. Given
> that, they will be normalized inside the steady-state loop.
I was also curious if there is a significance to the difference in "last names"
between ec.repro.PROB and gp.cx.INDPB? Do they both measure the same kind of
independent probability?
Hi Linge,
Open BEAGLE normalize probabilities only when that is required. In the
case your are presenting, where all operators are done one after the
other, no normalization is done. When a normalization is done, a
warning message is written in the logs.
Case where normalization of probabilities is done is mainly below a
replacement strategy operators. All operators directly under this
operator are selected with uniform probability, so if the sum of their
associated probability is not 1, it needs to be normalized for being
used as weigths of the replacement strategy operator. Example of
replacement strategy operators are GenerationalOp, SteadyStateOp,
MuCommaLambdaOp, NSGA2Op.
In your case, you are not doing this, so no worry.
Christian
On Nov 6, 2009, at 11:30 AM, Bai Linge wrote:
> Dear all,
>
> I have a question with open beagle's normalization of crossover,
> mutation and reproduction probabilities. For example,
>
> If I specify crossover and mutation probabilities in command line
> with:
> ./symbreg -OBec.pop.size=100,gp.cx.indpb=0.75,gp.mutstd.indpb=0.25
>
> I also output a dump file with:
> ./symbreg -
> OBec.pop.size=100,gp.cx.indpb=0.75,gp.mutstd.indpb=0.25,dump=dump.conf
>
> In dump.conf, we can see this:
> <?xml version="1.0" encoding="ISO-8859-1"?>
> <Beagle version="3.1.0">
> <!--This file is the result of a configuration dump-->
> <Evolver>
> <BootStrapSet>
> <GP-InitHalfOp repropb="ec.repro.prob"/>
> <SymbRegEvalOp/>
> <GP-StatsCalcFitnessSimpleOp/>
> <TermMaxGenOp/>
> <MilestoneWriteOp/>
> </BootStrapSet>
> <MainLoopSet>
> <SelectTournamentOp repropb="ec.repro.prob"/>
> <GP-CrossoverOp matingpb="gp.cx.indpb" distrpb="gp.cx.distrpb"/>
> <GP-MutationStandardOp mutationpb="gp.mutstd.indpb"
> maxdepth="gp.mutstd.maxdepth"/>
> <SymbRegEvalOp/>
> <MigrationRingOp/>
> <GP-StatsCalcFitnessSimpleOp/>
> <TermMaxGenOp/>
> <MilestoneWriteOp/>
> </MainLoopSet>
> </Evolver>
> <System>
> <Register>
> <Entry key="ec.hof.demesize">0</Entry>
> <Entry key="ec.hof.vivasize">1</Entry>
> <Entry key="ec.init.seedsfile"/>
> <Entry key="ec.mig.interval">1</Entry>
> <Entry key="ec.mig.size">5</Entry>
> <Entry key="ec.pop.size">100</Entry>
> <Entry key="ec.rand.seed">0</Entry>
> <Entry key="ec.repro.prob">0.1</Entry>
> <Entry key="ec.sel.tournsize">7</Entry>
> <Entry key="ec.term.maxgen">50</Entry>
> <Entry key="ec.test.indi"/>
> <Entry key="gp.cx.distrpb">0.9</Entry>
> <Entry key="gp.cx.indpb">0.75</Entry>
> <Entry key="gp.init.kozagrow">0</Entry>
> <Entry key="gp.init.maxdepth">5</Entry>
> <Entry key="gp.init.maxtree">1</Entry>
> <Entry key="gp.init.mindepth">2</Entry>
> <Entry key="gp.init.mintree">1</Entry>
> <Entry key="gp.mutstd.indpb">0.25</Entry>
> <Entry key="gp.mutstd.maxdepth">5</Entry>
> <Entry key="gp.tree.maxargs">0,2</Entry>
> <Entry key="gp.tree.maxdepth">17</Entry>
> <Entry key="gp.tree.minargs">0,2</Entry>
> <Entry key="gp.try">2</Entry>
> <Entry key="lg.console.level">2</Entry>
> <Entry key="lg.file.level">3</Entry>
> <Entry key="lg.file.name">beagle.log</Entry>
> <Entry key="lg.show.class">0</Entry>
> <Entry key="lg.show.level">0</Entry>
> <Entry key="lg.show.type">0</Entry>
> <Entry key="ms.write.compress">1</Entry>
> <Entry key="ms.write.interval">0</Entry>
> <Entry key="ms.write.over">1</Entry>
> <Entry key="ms.write.perdeme">0</Entry>
> <Entry key="ms.write.prefix">beagle</Entry>
> </Register>
>
> The entry for ec.repro.prob is 0.1, the entry for gp.cx.indpb is
> 0.75 and the entry for gp.mutstd.indpb is 0.25. The sum is 1.1, not
> 1. Does Open Beagle normalize probabilities? That is the probability
> for reproduction is 0.1/1.1, for crossover is 0.75/1.1 and mutation
> is 0.25/1.1. Or do crossover and mutation happen when no
> reproduction happens: that is, probability for reproduction is 0.1,
> for crossover is 0.75*0.9, and for mutation is 0.25*0.9?
>
> thanks,
> Linge
>
>
>
>
>
> [Non-text portions of this message have been removed]
>
>
>
> ------------------------------------
>
> Yahoo! Groups Links
>
>
>
Christian Gagné
http://vision.gel.ulaval.ca/~cgagne
Hi,
On Nov 6, 2009, at 1:14 PM, Craig Reynolds wrote:
> Bai Linge wrote:
>> ...The entry for ec.repro.prob is 0.1, the entry for gp.cx.indpb is
>> 0.75 and the entry for gp.mutstd.indpb is 0.25. The sum is 1.1, not
>> 1. Does Open Beagle normalize probabilities? That is the probability
>> for reproduction is 0.1/1.1, for crossover is 0.75/1.1 and mutation
>> is 0.25/1.1. Or do crossover and mutation happen when no reproduction
>> happens: that is, probability for reproduction is 0.1, for crossover
>> is 0.75*0.9, and for mutation is 0.25*0.9?
>
> I'm not the authority, but I think the answer is yes based on a
> recent reply from Christian:
As I said, it depends on the circumstances. When this is done, a
warning message is given in the logs.
> On Nov 3, 2009, at 12:44 PM, Craig Reynolds wrote:
>> What does this mean?
>> <Log>Applying "SteadyStateOp"</Log>
>> <Log>Sum of probabilities of breeder operators children to
>> replacement
>> strategy named "SteadyStateOp" is different from 1.0 (value: 1.2)</
>> Log>
>
> On 11/3/09 10:19 AM, Christian Gagné wrote:
>> The probabilities of the operators that can be done in the
>> steady-state loop (crossover, mutations) do not sum to one. Given
>> that, they will be normalized inside the steady-state loop.
>
> I was also curious if there is a significance to the difference in
> "last names" between ec.repro.PROB and gp.cx.INDPB? Do they both
> measure the same kind of independent probability?
That simply because the GP crossover operator has two probabilities,
that is the probability of mating in individual (gp.cx.indpb) and
distribution probability between selecting branches or leaves
(gp.cx.distrpb). That the only reason why this name is used. For
reproduction operator, there only one probability, hence a simpler name.
Christian
>
> ------------------------------------
>
> Yahoo! Groups Links
>
>
>
Christian Gagné
http://vision.gel.ulaval.ca/~cgagne
I've been working away adding the "glue" code between Open BEAGLE STGP and my
pre-existing texture synthesis library. The other day I started seeing
allocation errors which I assume are due to filling up the heap. This was not a
surprise because I knew I was allocating my texture objects (specializations of
the base Texture) and letting them "leak" away without deleting them. It hadn't
been a problem since my procedural texture objects contain just a handful of
numeric parameters and so are very small. Reconstructing the time line, I think
I saw the alloc error after I added a Texture operator called Row. It differs
in that it was implemented with a pixel cache (2d array) to save it from
calculating the same pixels multiple times. I decided it might be time to
correctly handle deletion. (Although just turning off the pixel caching and
continuing to blithely ignore memory management is a possible short term
work-around.) This was the code I wrote back at the time of th
e conversation below:
class OBTexturePointer : public Beagle::Object {public: Texture* texture;};
inline std::ostream& operator<<(std::ostream&, const OBTexturePointer&)
{assert(false);}
inline std::istream& operator>>(std::istream&, OBTexturePointer&)
{assert(false);}
typedef Beagle::WrapperT<OBTexturePointer> GP_Texture_Type;
Where GP_Texture_Type is my STGP root type. My STGP texture operators return
this type and many have parameters of this type. Looking at it now and reading
what Christian wrote at the time, I see I did not follow his advice (inherit
from Beagle::Object, etc.) So now I am looking for advice about how to do it
correctly. For context, my STGP primitives have code like this:
virtual void GP_UniformColor::execute(Beagle::GP::Datum& outDatum,
Beagle::GP::Context& ioContext)
{
GP_Pixel_Type lArg;
get1stArgument(lArg, ioContext);
GP_Texture_Type& lResult = Beagle::castObjectT<GP_Texture_Type&>(outDatum);
lResult.getWrappedValue().texture = new UniformColor
(lArg.getWrappedValue());
}
I tried simply deleting the Texture pointed to by a GP_Texture_Type when it was
deleted, but that seemed to be the wrong thing, it crashed immediately, probably
because it is not respecting the reference counting scheme used throughout Open
BEAGLE (via PACC?).
Is using WrapperT<OBTexturePointer> to define GP_Texture_Type the wrong
approach? Is there a class analogous GP_Texture_Type that I could use as an
example of a good implementation?
Thanks,
Craig
On 10/19/09 6:35 AM, Christian Gagné wrote:
> On Oct 16, 2009, at 9:53 PM, Craig Reynolds wrote:
>> Christian Gagné wrote:
>>> ...A solution for that would be to define a datum that will
>>> contain a pointer to you Texture class, and change the value of
>>> the pointer.
>>
>> I was going to define a new "handle" class with just a Texture*
>> member and wrap it, but it occurred to me that perhaps I could just
>> wrap a Texture* directly:
>>
>> typedef Beagle::WrapperT<Texture*> GP_Texture_Type;
>>
>> Maybe that was what Christian was suggesting? I had to tweak two or
>> three places in my code to accommodate the change from reference
>> to pointer type, and add a operator>> for Texture*. After that it
>> seemed to run fine. Right now I am allocating new Texture-based
>> instances during the fitness test and letting them leak, I'll have
>> to make sure they get deleted.
>
> Wrappers have not been designed for wrapping pointers, especially if
> these pointers refere to a heap-allocated object. I would rather
> advice you to code a class used as datum from scratch, which class
> will inherit from Beagle::Object and implement some of the basic
> functions (e.g. read/write). This class will have as member a
> Texture*, where allocation/deletion of the refered object will be
> managed as you want it to be.
Hello,
I noticed I have duplicate individuals in my population.
For example the first individual of the generation 0 is copied two times in the
generation 1.
I checked if one of the duplicate individual was just selected then reproduced
and the other one could be the result of a crossover but it is not the case.
Is there a mistake or is it usual to have such a duplication?
How can I avoid this?
I tried to modify the probabilities in the configuration file but nothing
worked.
Thank you,
N.
I'm sorry that this issue has come back. Sorry also to add to Prof Gagné's
queue.
I had convinced myself that my jiggle mutation was working in conjunction with
my 3 (now 4) kinds of ephemeral constants (all based on Double). Yesterday I
evolved a small and interesting program. I analyzed it in detail and noticed a
mismatch between the result of OB's serialize and the resulting texture image
produced from the execute method. See an image and some commentary at the top
of this post: http://www.red3d.com/cwr/texsyn/diary.html#20091112
Today I found that this is apparently related to my jiggle mutations. When I
set the probabilities of my mutations to zero the mismatch problem went away.
The image produced during the STGP run corresponds to the serialized tree. I can
hand-convert the XML back to c, compile it, and render an identical image. So
apparently my mutation code changes *something* but misses something else?
Perhaps my attempt to modify the ephemeral constant in place is not working as I
assumed? It is as if a value for the ephemeral constant is cached somewhere
else, so there is the original value AND the jiggled value? Somehow serialize
sees one value and execute sees another? I think the relevant code is in the
fragments below. (Although for context I will send Christian a copy of the
entire file.)
Thanks,
Craig
On 11/3/09 6:35 PM, Craig Reynolds wrote:
> Finally this works! I seem to be successfully doing "constant jiggling"
> on my three classes of "ranged Doubles". I tried two version of where
> this new mutate method should go. First I tried putting it on the
> ephemeral constant class (like EphemeralDouble), decided the modularity
> was messy, and moved it to the wrapped number class (like Double, "T" in
> the code below). I modified just a portion of
> Beagle::GP::MutationJiggleEphemeralOpT<T>::mutate. Where it used to say:
>
>
> // Mutate parameter value.
> GP::Primitive::Handle lSelectedPrimit =
> (*lSelectedTree)[lPotentialParam[lSelectedParam].second].mPrimitive;
> typename GP::EphemeralT<T>::Handle lSelectedEphemeral =
> castHandleT<typename GP::EphemeralT<T> >(lSelectedPrimit);
> GP::Primitive::Handle lGeneratedPrimit =
> lSelectedEphemeral->generate(mEphemeralName->getWrappedValue(), lContext);
> (*lSelectedTree)[lPotentialParam[lSelectedParam].second].mPrimitive =
lGeneratedPrimit;
>
> Beagle_LogVerboseM(
> ioContext.getSystem().getLogger(),
> "mutation", "Beagle::GP::MutationJiggleEphemeralOpT",
> string("Changing the ephemeral from ")+lSelectedPrimit->serialize()+
> string(" to ")+lGeneratedPrimit->serialize()
> );
>
>
> it now says:
>
>
> // Mutate parameter value.
> GP::Primitive::Handle lSelectedPrimit =
> (*lSelectedTree)[lPotentialParam[lSelectedParam].second].mPrimitive;
> typename GP::EphemeralT<T>::Handle lSelectedEphemeral =
> castHandleT<typename GP::EphemeralT<T> >(lSelectedPrimit);
> std::cout << "Jiggle mutation -- before: " <<
lSelectedEphemeral->serialize();
> T temp;
> lSelectedEphemeral->getValue (temp);
> temp.setWrappedValue(temp.mutate(lContext));
> lSelectedEphemeral->setValue (temp);
> std::cout << " after: " << lSelectedEphemeral->serialize() << std::endl;
>
> // Beagle_LogVerboseM(
> // ioContext.getSystem().getLogger(),
> // "mutation", "Beagle::GP::MutationJiggleEphemeralOpT",
> // string("Changing the ephemeral from ")+lSelectedPrimit->serialize()+
> // string(" to ")+lGeneratedPrimit->serialize()
> // );
>
>
> those print outs convince me that it is working correctly, but I am
> easily fooled:
> Jiggle mutation -- before: <SmallFloat value="-0.644849"/> after:
> <SmallFloat value="-0.418695"/>
> Jiggle mutation -- before: <Fraction value="0.0677889"/> after:
> <Fraction value="0.111499"/>
> Jiggle mutation -- before: <Fraction value="0.0910494"/> after:
> <Fraction value="0.0992486"/>
> Jiggle mutation -- before: <Fraction value="0.655258"/> after:
> <Fraction value="0.628954"/>
> Jiggle mutation -- before: <SmallFloat value="1.27035"/> after:
> <SmallFloat value="1.28836"/>
> Jiggle mutation -- before: <SmallPosFloat value="3.10858"/> after:
> <SmallPosFloat value="2.83929"/>
>
> My only problem at this point is that I broke the Beagle_LogVerboseM at
> the end of that code fragment. I would appreciate suggestions on how to
> repair it. I would also appreciate a review of my code for doing things
> "the OB way"
>
>
> Thanks for all the help,
> Craig
>
Hi Craig,
On Nov 12, 2009, at 4:04 PM, Craig Reynolds wrote:
> I've been working away adding the "glue" code between Open BEAGLE STGP and my
pre-existing texture synthesis library. The other day I started seeing
allocation errors which I assume are due to filling up the heap. This was not a
surprise because I knew I was allocating my texture objects (specializations of
the base Texture) and letting them "leak" away without deleting them. It hadn't
been a problem since my procedural texture objects contain just a handful of
numeric parameters and so are very small. Reconstructing the time line, I think
I saw the alloc error after I added a Texture operator called Row. It differs
in that it was implemented with a pixel cache (2d array) to save it from
calculating the same pixels multiple times. I decided it might be time to
correctly handle deletion. (Although just turning off the pixel caching and
continuing to blithely ignore memory management is a possible short term
work-around.) This was the code I wrote back at the time of th
> e conversation below:
>
> class OBTexturePointer : public Beagle::Object {public: Texture* texture;};
> inline std::ostream& operator<<(std::ostream&, const OBTexturePointer&)
{assert(false);}
> inline std::istream& operator>>(std::istream&, OBTexturePointer&)
{assert(false);}
> typedef Beagle::WrapperT<OBTexturePointer> GP_Texture_Type;
>
> Where GP_Texture_Type is my STGP root type. My STGP texture operators return
this type and many have parameters of this type. Looking at it now and reading
what Christian wrote at the time, I see I did not follow his advice (inherit
from Beagle::Object, etc.) So now I am looking for advice about how to do it
correctly. For context, my STGP primitives have code like this:
>
> virtual void GP_UniformColor::execute(Beagle::GP::Datum& outDatum,
Beagle::GP::Context& ioContext)
> {
> GP_Pixel_Type lArg;
> get1stArgument(lArg, ioContext);
> GP_Texture_Type& lResult = Beagle::castObjectT<GP_Texture_Type&>(outDatum);
> lResult.getWrappedValue().texture = new UniformColor
(lArg.getWrappedValue());
> }
>
> I tried simply deleting the Texture pointed to by a GP_Texture_Type when it
was deleted, but that seemed to be the wrong thing, it crashed immediately,
probably because it is not respecting the reference counting scheme used
throughout Open BEAGLE (via PACC?).
It all depends on how you did your code and how the logic of your system is
done. But in general, it looks to me like a method prone to have various bugs
associated to using pointers to memory that have been deleted, which is likely
to make the program crashing.
> Is using WrapperT<OBTexturePointer> to define GP_Texture_Type the wrong
approach? Is there a class analogous GP_Texture_Type that I could use as an
example of a good implementation?
Wrapping your pointer class OBTexturePointer is not necessary a bad thing. It
can guess what you are doing, although it is not 100% obvious to me.
A quick fix to make you code to work would be to code your class as the
following.
class OBTexturePointer : public Beagle::Object {
public:
OBTexturePointer(Texture* inTexture=NULL) : mTexture(inTexture) { }
~OBTexturePointer() {
if(mTexture!=NULL) delete mTexture;
}
Texture* mTexture;
};
That way, you should avoid any problem unless you intend to make copies of your
OBTexturePointer without making copies of the Texture* member. If you intend to
work that way, you will still have problem. I would then advice you to define a
new class directly derived from Beagle::Object, and take advantage of the smart
pointers. This thing really does some magic with C++, virtually emulating
garbage collection (with some limitations, mainly not having reference cycles).
For an example on defining a class derived making a non-Open BEAGLE class
derived from a Beagle::Object, check the code of the Beagle::Vector class. It
directly integrate the PACC::Vector class into Open BEAGLE. The interface is the
same, with some added functionnalities from Open BEAGLE like the smart pointers
and allocators. I think for your case, such an approach might be quite
appropriated.
Best,
Christian
> Thanks,
> Craig
>
>
> On 10/19/09 6:35 AM, Christian Gagné wrote:
>> On Oct 16, 2009, at 9:53 PM, Craig Reynolds wrote:
>>> Christian Gagné wrote:
>>>> ...A solution for that would be to define a datum that will
>>>> contain a pointer to you Texture class, and change the value of
>>>> the pointer.
>>> I was going to define a new "handle" class with just a Texture*
>>> member and wrap it, but it occurred to me that perhaps I could just
>>> wrap a Texture* directly:
>>> typedef Beagle::WrapperT<Texture*> GP_Texture_Type;
>>> Maybe that was what Christian was suggesting? I had to tweak two or
>>> three places in my code to accommodate the change from reference
>>> to pointer type, and add a operator>> for Texture*. After that it
>>> seemed to run fine. Right now I am allocating new Texture-based
>>> instances during the fitness test and letting them leak, I'll have
>>> to make sure they get deleted.
>> Wrappers have not been designed for wrapping pointers, especially if these
pointers refere to a heap-allocated object. I would rather
>> advice you to code a class used as datum from scratch, which class
>> will inherit from Beagle::Object and implement some of the basic
>> functions (e.g. read/write). This class will have as member a
>> Texture*, where allocation/deletion of the refered object will be
>> managed as you want it to be.
>
Christian Gagné
http://vision.gel.ulaval.ca/~cgagne
Hi Craig,
On Nov 13, 2009, at 2:31 PM, Craig Reynolds wrote:
> I'm sorry that this issue has come back. Sorry also to add to Prof Gagné's
queue.
>
> I had convinced myself that my jiggle mutation was working in conjunction with
my 3 (now 4) kinds of ephemeral constants (all based on Double). Yesterday I
evolved a small and interesting program. I analyzed it in detail and noticed a
mismatch between the result of OB's serialize and the resulting texture image
produced from the execute method. See an image and some commentary at the top
of this post: http://www.red3d.com/cwr/texsyn/diary.html#20091112
>
> Today I found that this is apparently related to my jiggle mutations. When I
set the probabilities of my mutations to zero the mismatch problem went away.
The image produced during the STGP run corresponds to the serialized tree. I can
hand-convert the XML back to c, compile it, and render an identical image. So
apparently my mutation code changes *something* but misses something else?
Perhaps my attempt to modify the ephemeral constant in place is not working as I
assumed? It is as if a value for the ephemeral constant is cached somewhere
else, so there is the original value AND the jiggled value? Somehow serialize
sees one value and execute sees another? I think the relevant code is in the
fragments below. (Although for context I will send Christian a copy of the
entire file.)
It looks like the cause of your problem is that you are modifying the value of a
ephemeral random "in place" in the GP tree, without cloning it first. Indeed,
this instance of an ephemeral constant is possibly used in many other GP trees,
or even by other node in the same tree. Each node in a GP tree have a smart
pointer (Primitive::Handle) to their associated primitive, such that when an
individual is copied (mainly by selection), only the tree structure is
duplicated, while the primitives are not copied (the copy of the tree refers to
the original primitives).
I saw in you code that you are not copying the ephemeral constant before
modifying them by jiggling mutation. There is probably many nodes in different
trees that are using that constant, so that a jiggling mutation on one node
affect other nodes refering to the same ephemeral constants.
What you need to do is to make a fresh copy of the ephemeral constant (to be
sure no other nodes are refering to it), assign that fresh copy to replace the
existing one, and then modify the copy of the constant by jiggling mutation.
Hope my explanations are clear,
Christian
> Thanks,
> Craig
>
>
>
> On 11/3/09 6:35 PM, Craig Reynolds wrote:
>> Finally this works! I seem to be successfully doing "constant jiggling" on
my three classes of "ranged Doubles". I tried two version of where this new
mutate method should go. First I tried putting it on the ephemeral constant
class (like EphemeralDouble), decided the modularity was messy, and moved it to
the wrapped number class (like Double, "T" in the code below). I modified just
a portion of Beagle::GP::MutationJiggleEphemeralOpT<T>::mutate. Where it used
to say:
>> // Mutate parameter value.
>> GP::Primitive::Handle lSelectedPrimit =
>> (*lSelectedTree)[lPotentialParam[lSelectedParam].second].mPrimitive;
>> typename GP::EphemeralT<T>::Handle lSelectedEphemeral =
>> castHandleT<typename GP::EphemeralT<T> >(lSelectedPrimit);
>> GP::Primitive::Handle lGeneratedPrimit =
>> lSelectedEphemeral->generate(mEphemeralName->getWrappedValue(), lContext);
>> (*lSelectedTree)[lPotentialParam[lSelectedParam].second].mPrimitive =
lGeneratedPrimit;
>> Beagle_LogVerboseM(
>> ioContext.getSystem().getLogger(),
>> "mutation", "Beagle::GP::MutationJiggleEphemeralOpT",
>> string("Changing the ephemeral from ")+lSelectedPrimit->serialize()+
>> string(" to ")+lGeneratedPrimit->serialize()
>> );
>> it now says:
>> // Mutate parameter value.
>> GP::Primitive::Handle lSelectedPrimit =
>> (*lSelectedTree)[lPotentialParam[lSelectedParam].second].mPrimitive;
>> typename GP::EphemeralT<T>::Handle lSelectedEphemeral =
>> castHandleT<typename GP::EphemeralT<T> >(lSelectedPrimit);
>> std::cout << "Jiggle mutation -- before: " <<
lSelectedEphemeral->serialize();
>> T temp;
>> lSelectedEphemeral->getValue (temp);
temp.setWrappedValue(temp.mutate(lContext));
>> lSelectedEphemeral->setValue (temp);
>> std::cout << " after: " << lSelectedEphemeral->serialize() << std::endl;
>> // Beagle_LogVerboseM(
>> // ioContext.getSystem().getLogger(),
>> // "mutation", "Beagle::GP::MutationJiggleEphemeralOpT",
>> // string("Changing the ephemeral from ")+lSelectedPrimit->serialize()+
>> // string(" to ")+lGeneratedPrimit->serialize()
>> // );
>> those print outs convince me that it is working correctly, but I am easily
fooled:
>> Jiggle mutation -- before: <SmallFloat value="-0.644849"/> after:
<SmallFloat value="-0.418695"/>
>> Jiggle mutation -- before: <Fraction value="0.0677889"/> after: <Fraction
value="0.111499"/>
>> Jiggle mutation -- before: <Fraction value="0.0910494"/> after: <Fraction
value="0.0992486"/>
>> Jiggle mutation -- before: <Fraction value="0.655258"/> after: <Fraction
value="0.628954"/>
>> Jiggle mutation -- before: <SmallFloat value="1.27035"/> after: <SmallFloat
value="1.28836"/>
>> Jiggle mutation -- before: <SmallPosFloat value="3.10858"/> after:
<SmallPosFloat value="2.83929"/>
>> My only problem at this point is that I broke the Beagle_LogVerboseM at the
end of that code fragment. I would appreciate suggestions on how to repair it.
I would also appreciate a review of my code for doing things "the OB way"
>> Thanks for all the help,
>> Craig
>
Christian Gagné
http://vision.gel.ulaval.ca/~cgagne
Christian's suggestions on Nov 14 helped me fix the problem with my jiggling
constants and my memory leak. I've been adding the rest of my texture synthesis
library to the GP primitive set, cleaning up the prototype implementations as I
go.
I am starting to think about the next phase of my project. It will need some
kind of "batch" evolution process where several new individuals are created (via
crossover, mutation, etc.), they are fitness tested as a group, then inserted
into the population. I'm hoping this is not too far outside the normal
operation of Open BEAGLE that this kind of "replacement strategy" can be put
together from existing elements of OB. I would appreciate some hints about how
to approach this using Open BEAGLE and particularly pointers to anything in the
sample code that might be similar to this.
The basic idea is that these "batches" of individuals will be assigned fitness
based on their performance relative to their cohorts/classmates/nestmates. So I
need to have constructed the batch of individuals before I can assign a fitness
to any of them.
Thanks,
Craig
Hi Craig,
There are many ways for doing that, it depends on what you intended to do
precisely. Are the groups predefined and fixed for all the evolution? Are they
mating or selected with individuals from other groups? If the yes (groups are
predefined) and no (they are not mating of solutions), you could consider to
organise them as demes. With that you can control exchanges between demes
through some form of migration.
Also, you can consider to make use of coevolution, which is available in Open
BEAGLE. That may be a solution to your problem.
And finally, maybe you just need to apply evaluation on the whole current
population. Be aware that you can overwrite the EvaluationOp::operate function
if you wish, which is controling how a complete population is evaluated
(assuming that the evaluation operator is not in a breeder tree). That is maybe
the level of control that you require.
In short, I see 4-5 different methods to do something similar to what you wanted
to do. With more details, I may be able to guide you toward the best one. But
for now, the best I can say is that it is certainly possible to do what you
wanted to do.
Christian
On Nov 24, 2009, at 2:34 PM, Craig Reynolds wrote:
> Christian's suggestions on Nov 14 helped me fix the problem with my jiggling
constants and my memory leak. I've been adding the rest of my texture synthesis
library to the GP primitive set, cleaning up the prototype implementations as I
go.
>
> I am starting to think about the next phase of my project. It will need some
kind of "batch" evolution process where several new individuals are created (via
crossover, mutation, etc.), they are fitness tested as a group, then inserted
into the population. I'm hoping this is not too far outside the normal
operation of Open BEAGLE that this kind of "replacement strategy" can be put
together from existing elements of OB. I would appreciate some hints about how
to approach this using Open BEAGLE and particularly pointers to anything in the
sample code that might be similar to this.
>
> The basic idea is that these "batches" of individuals will be assigned fitness
based on their performance relative to their cohorts/classmates/nestmates. So I
need to have constructed the batch of individuals before I can assign a fitness
to any of them.
>
> Thanks,
> Craig
>
>
> ------------------------------------
>
> Yahoo! Groups Links
>
>
>
Christian Gagné
http://vision.gel.ulaval.ca/~cgagne
Ah, those are interesting variations, but perhaps more complicated than what I
have in mind. My groups are temporary and do not form demes for reproduction.
Imagine students entering a classroom at random. When the room is full they
take a test. The tests are scored and the students are assigned a fitness based
on their rank in the classroom. After that the students leave the classroom and
join the general population and have no further connection with their
"classmates".
Lets assume I'm using steady-state reproduction. I have not looked at this part
of Open BEAGLE but I assume the main loop is something like:
(1) make new individual (crossover, mutation, etc.)
(2) run fitness test
(3) choose old individual in population to delete
(4) insert new individual into population
Now I just want to do that in batches of N individuals:
(1) make N new individuals
(2) run the rank-based fitness test on the group of N
(3) choose N old individuals in population to delete
(4) insert N new individuals into population
I assume N will be on the order of 10. I hope my explanation was clear, let me
know if not.
Thanks,
Craig
Christian Gagné wrote:
> Hi Craig,
>
> There are many ways for doing that, it depends on what you intended to do
precisely. Are the groups predefined and fixed for all the evolution? Are they
mating or selected with individuals from other groups? If the yes (groups are
predefined) and no (they are not mating of solutions), you could consider to
organise them as demes. With that you can control exchanges between demes
through some form of migration.
>
> Also, you can consider to make use of coevolution, which is available in Open
BEAGLE. That may be a solution to your problem.
>
> And finally, maybe you just need to apply evaluation on the whole current
population. Be aware that you can overwrite the EvaluationOp::operate function
if you wish, which is controling how a complete population is evaluated
(assuming that the evaluation operator is not in a breeder tree). That is maybe
the level of control that you require.
>
> In short, I see 4-5 different methods to do something similar to what you
wanted to do. With more details, I may be able to guide you toward the best one.
But for now, the best I can say is that it is certainly possible to do what you
wanted to do.
>
> Christian
>
>
>
> On Nov 24, 2009, at 2:34 PM, Craig Reynolds wrote:
>
>> Christian's suggestions on Nov 14 helped me fix the problem with my jiggling
constants and my memory leak. I've been adding the rest of my texture synthesis
library to the GP primitive set, cleaning up the prototype implementations as I
go.
>>
>> I am starting to think about the next phase of my project. It will need some
kind of "batch" evolution process where several new individuals are created (via
crossover, mutation, etc.), they are fitness tested as a group, then inserted
into the population. I'm hoping this is not too far outside the normal
operation of Open BEAGLE that this kind of "replacement strategy" can be put
together from existing elements of OB. I would appreciate some hints about how
to approach this using Open BEAGLE and particularly pointers to anything in the
sample code that might be similar to this.
>>
>> The basic idea is that these "batches" of individuals will be assigned
fitness based on their performance relative to their
cohorts/classmates/nestmates. So I need to have constructed the batch of
individuals before I can assign a fitness to any of them.
>>
>> Thanks,
>> Craig
Hi Craig,
I see what you want to do. The best solution I see would be to define a new
custom replacement strategy that would replace both the SteadyStateOp and
EvaluationOp in your algorithm. That operator will generate K new individuals at
the time, and then evaluate them in group, repeating the process until N new
individuals have been generated.
Code-wise, the best approach would be to define a new class inheriting from
SteadyStateOp, and will overdefine the operate() method. That overdefinition can
be made by starting from the current code of SteadyStateOp::operate. The
difference will be that instead of going from 1 to N (where N is defined in
ec.pop.size parameter), you will have two loops. The inner one will generate K
new individuals, much like it is currently done in SteadyStateOp, then will
evaluate their fitness according to what you have in mind, and then will insert
these new evaluated individuals in the population, as done in SteadyStateOp. The
outer loop will do this process N/K times.
I hope my explanations are clear, if not don't hesitate to contact me again,
Christian
On Nov 24, 2009, at 8:08 PM, Craig Reynolds wrote:
> Ah, those are interesting variations, but perhaps more complicated than what I
have in mind. My groups are temporary and do not form demes for reproduction.
Imagine students entering a classroom at random. When the room is full they
take a test. The tests are scored and the students are assigned a fitness based
on their rank in the classroom. After that the students leave the classroom and
join the general population and have no further connection with their
"classmates".
>
> Lets assume I'm using steady-state reproduction. I have not looked at this
part of Open BEAGLE but I assume the main loop is something like:
>
> (1) make new individual (crossover, mutation, etc.)
> (2) run fitness test
> (3) choose old individual in population to delete (4) insert new individual
into population
>
> Now I just want to do that in batches of N individuals:
>
> (1) make N new individuals
> (2) run the rank-based fitness test on the group of N
> (3) choose N old individuals in population to delete (4) insert N new
individuals into population
>
> I assume N will be on the order of 10. I hope my explanation was clear, let
me know if not.
>
> Thanks,
> Craig
>
>
> Christian Gagné wrote:
>> Hi Craig,
>> There are many ways for doing that, it depends on what you intended to do
precisely. Are the groups predefined and fixed for all the evolution? Are they
mating or selected with individuals from other groups? If the yes (groups are
predefined) and no (they are not mating of solutions), you could consider to
organise them as demes. With that you can control exchanges between demes
through some form of migration.
>> Also, you can consider to make use of coevolution, which is available in Open
BEAGLE. That may be a solution to your problem.
>> And finally, maybe you just need to apply evaluation on the whole current
population. Be aware that you can overwrite the EvaluationOp::operate function
if you wish, which is controling how a complete population is evaluated
(assuming that the evaluation operator is not in a breeder tree). That is maybe
the level of control that you require.
>> In short, I see 4-5 different methods to do something similar to what you
wanted to do. With more details, I may be able to guide you toward the best one.
But for now, the best I can say is that it is certainly possible to do what you
wanted to do.
>> Christian
>> On Nov 24, 2009, at 2:34 PM, Craig Reynolds wrote:
>>> Christian's suggestions on Nov 14 helped me fix the problem with my jiggling
constants and my memory leak. I've been adding the rest of my texture synthesis
library to the GP primitive set, cleaning up the prototype implementations as I
go.
>>>
>>> I am starting to think about the next phase of my project. It will need
some kind of "batch" evolution process where several new individuals are created
(via crossover, mutation, etc.), they are fitness tested as a group, then
inserted into the population. I'm hoping this is not too far outside the normal
operation of Open BEAGLE that this kind of "replacement strategy" can be put
together from existing elements of OB. I would appreciate some hints about how
to approach this using Open BEAGLE and particularly pointers to anything in the
sample code that might be similar to this.
>>>
>>> The basic idea is that these "batches" of individuals will be assigned
fitness based on their performance relative to their
cohorts/classmates/nestmates. So I need to have constructed the batch of
individuals before I can assign a fitness to any of them.
>>>
>>> Thanks,
>>> Craig
Christian Gagné
http://vision.gel.ulaval.ca/~cgagne