2 * psychlops_exp_psychophysics.h
3 * Psychlops Standard Library (Universal)
5 * Last Modified 2009/07/ by Kenchi HOSOKAWA
6 * (C) 2005 Kenchi HOSOKAWA, Kazushi MARUYA, Takao SATO
9 #ifndef HEADER_PSYCHLOPS_EXPERIMENTAL_DESIGNS_PSYCHOPHYSICS
10 #define HEADER_PSYCHLOPS_EXPERIMENTAL_DESIGNS_PSYCHOPHYSICS
15 #include "../../../core/graphic/psychlops_g_color.h"
16 #include "../../../core/graphic/psychlops_g_canvas.h"
\r
17 #include "../widgets/psychlops_widget.h"
29 namespace ExperimentalMethods {
32 class SliderInterface : public FigureDatum
\r
39 void set(Variable* target);
\r
40 virtual SliderInterface& set(double wid, double hei);
\r
41 virtual SliderInterface& set(std::string s, double hei = Font::default_font.size);
\r
42 virtual SliderInterface& set(std::wstring s, double hei = Font::default_font.size);
\r
43 virtual SliderInterface& setLabel(std::wstring s);
\r
45 virtual SliderInterface& centering(Drawable &target = *Drawable::prime);
\r
46 virtual SliderInterface& centering(const Figure &p);
\r
47 virtual SliderInterface& centering(const Point &p);
\r
48 virtual SliderInterface& centering(const double x, const double y, const double z = 0);
\r
49 virtual SliderInterface& shift(const double x, const double y, const double z = 0);
\r
50 virtual SliderInterface& draw(Drawable &target = *Drawable::prime);
\r
53 void appendTo(Group &target);
\r
58 SliderInterface slider;
\r
62 virtual void* addr() const = 0;
63 virtual std::string to_str() const = 0;
\r
64 virtual void to_str(std::ostream & outstream) const = 0;
65 virtual void to_str_ColumnCell_at(int index, std::ostream & outstream) const = 0;
66 //virtual void setByValue(double value) = 0;
67 virtual void setByRatio(double ratio) = 0;
\r
68 virtual void setByRatioInStep(double ratio) = 0;
69 virtual void setByLevel(int level) = 0;
70 virtual void increment(int modulation = 0) = 0;
71 virtual void decrement(int modulation = 0) = 0;
72 virtual bool changed() = 0;
73 //virtual void onChange(void (*callback)()) = 0;
74 virtual double getRatio() const = 0;
75 virtual Interval getInterval() const = 0;
\r
76 virtual Interval setInterval(const Interval &itvl) = 0;
77 virtual int getNumberOfLevels() const = 0;
78 virtual int getNumberOfSteps() const = 0;
79 virtual void setColumn(int number_of_cells) = 0;
80 virtual void setColumnCellByCurrentValue(int index) = 0;
81 virtual void setColumnCellByLevel(int index, int level) = 0;
83 namespace VariableInstanceImpl {
84 template<typename T> void initialize(Interval *i, std::vector<T> *step_) { *i=Interval(); step_->empty(); }
85 template<typename T> void increment(T* const link_, T delta, Interval intvl) { if(intvl.includes(*link_+delta)) *link_ += delta; }
86 template<typename T> void decrement(T* const link_, T delta, Interval intvl) { if(intvl.includes(*link_-delta)) *link_ -= delta; }
87 template<typename T> double getRatio(T* const link_, Interval intvl) { return ( intvl.bounded() ? ((*link_-intvl.int_floor()) / (double)(intvl.int_ceil()-intvl.int_floor())) : 0); }
88 template<typename T> void setByRatio(T* const link_, double ratio, Interval intvl) { *link_ = (T)Math::round(ratio*(intvl.int_ceil()-intvl.int_floor())+intvl.int_floor()); }
89 template<typename T> void setByValue(T* const link_, double value) { *link_ = (T)value; }
91 template<> void initialize<bool>(Interval *i, std::vector<bool> *step_);
92 template<> void increment<bool>(bool* const link_, bool delta, Interval intvl);
93 template<> void decrement<bool>(bool* const link_, bool delta, Interval intvl);
94 template<> double getRatio<bool>(bool* const link_, Interval intvl);
95 template<> void setByRatio<bool>(bool* const link_, double ratio, Interval intvl);
97 template<> double getRatio<float>(float* const link_, Interval intvl);
98 template<> void setByRatio<float>(float* const link_, double ratio, Interval intvl);
99 template<> double getRatio<double>(double* const link_, Interval intvl);
100 template<> void setByRatio<double>(double* const link_, double ratio, Interval intvl);
103 template<class X> class VariableInstance : public Variable {
107 std::vector<X> step_;
108 std::vector<X> column_;
109 std::vector<X> levels_;
116 VariableInstance<X>(X *link) : link_(link), backup_(*link), current_level_(0), changed_flag(false) { VariableInstanceImpl::initialize(&rng_, &step_); }
117 virtual ~VariableInstance<X>() {}
118 virtual std::string to_str() const {
119 std::stringstream tmpstr;
123 virtual void* addr() const { return (void*)link_; }
124 virtual void to_str(std::ostream & outstream) const { outstream << *link_; }
125 virtual void to_str_ColumnCell_at(int index, std::ostream & outstream) const { outstream << column_.at(index); }
126 virtual void setByRatio(double ratio) {
128 double r = std::min(1.0, std::max(0.0, ratio));
129 if(levels_.size()>1) { setByLevel(Math::round(r*(levels_.size()-1))); return; }
130 if(rng_.bounded()) { VariableInstanceImpl::setByRatio(link_, r, rng_); }
132 virtual void setByRatioInStep(double ratio) {
134 double r = std::min(1.0, std::max(0.0, ratio));
136 if(step_.size()==1) s = step_[0]; else if(step_.size()==2) s = std::min(step_[0], step_[1]);
137 if(levels_.size()>1) { setByLevel(Math::round(r*(levels_.size()-1))); return; }
\r
138 if(rng_.bounded()) {
\r
139 double step_levels = Math::round( (rng_.end.value - rng_.begin.value) / s );
140 //VariableInstanceImpl::setByRatio(link_, Math::round(step_levels*r)/step_levels , rng_);
\r
141 VariableInstanceImpl::setByValue(link_, Math::round(step_levels*r)*s + rng_.begin.value);
\r
144 virtual void setByLevel(int level) {
146 *link_ = levels_.at(level);
148 virtual void increment(int modulation = 0) {
150 if(levels_.size()<2) { if(modulation>=0 && modulation<step_.size()) VariableInstanceImpl::increment(link_, (X)step_[modulation], rng_); }
151 else { ++current_level_; if(current_level_>=levels_.size()) current_level_ = 0; setByLevel(current_level_); }
153 virtual void decrement(int modulation = 0) {
155 if(levels_.size()<2) { if(modulation>=0 && modulation<step_.size()) VariableInstanceImpl::decrement(link_, (X)step_[modulation], rng_); }
156 else { --current_level_; if(current_level_<0) current_level_ = levels_.size()-1; setByLevel(current_level_); }
158 virtual bool changed() {
160 changed_flag = false;
166 virtual double getRatio() const { return VariableInstanceImpl::getRatio(link_, rng_); }
167 virtual Interval getInterval() const { return rng_; }
\r
168 virtual Interval setInterval(const Interval &itvl) { return rng_ = itvl; }
169 virtual int getNumberOfLevels() const { return levels_.size(); }
170 virtual int getNumberOfSteps() const { return step_.size(); }
171 virtual void setColumn(int number_of_cells) { column_.assign(number_of_cells, X()); }
172 virtual void setColumnCellByCurrentValue(int index) { column_.at(index) = *link_; }
173 virtual void setColumnCellByLevel(int index, int level) { column_.at(index) = levels_.at(level); }
174 template<typename T> VariableInstance<X>& operator |(T arg) { return set(arg); }
175 VariableInstance<X>& set(const char *str) { label = str; slider.set(label); return *this; }
176 VariableInstance<X>& set(const std::string &str) { label = str; slider.set(label); return *this; }
177 VariableInstance<X>& set(const Interval &rng) { rng_ = rng; return *this; }
178 VariableInstance<X>& set(const X &d_step) {
179 step_.push_back(d_step);
182 VariableInstance<X>& set(const std::string &str, const Interval &rng, const X &d_step, const X &e_step = 0) {
189 VariableInstance<X>& setLevels(const X *arr, const int size) {
\r
190 for(int i=0; i<size; i++) {
191 levels_.push_back(arr[i]);
\r
195 VariableInstance<X>& operator ,(const X &level) {
196 levels_.push_back(level);
206 bool slider_switch_;
\r
208 std::deque<Variable *> variables;
211 template <class X> VariableInstance<X>& append(X &item) {
212 VariableInstance<X> * tmp = new VariableInstance<X>(&item);
213 variables.push_back(tmp);
216 template <class X> VariableInstance<X>& operator <<(X &item) { return append(item); }
217 Variable& operator [](const size_t index);
218 Variable& operator [](const std::string &index);
219 Variable& operator [](const char* index);
220 Variable& operator [](const void* index);
222 void console(bool on_off);
\r
223 void slider(bool on_off);
226 struct VariableConsole : public FigureDatum {
228 mutable int active_, active_bar;
230 Color bgcolor, barcolor, active_barcolor;
232 VariableConsole(const Variables& d);
233 virtual ~VariableConsole();
234 virtual VariableConsole& draw(Drawable &target = *Drawable::prime);
238 class ExperimentalMethod {
240 std::map<std::string, Variable *> invariant_;
241 Variables Independent, Dependent;
242 std::string experiment_name, result_file_location, result_file_header;
243 int ITERATION, NUM_TRIALS, CURRENT_TRIAL;
245 virtual void initialize() = 0;
246 virtual void initialize_default() = 0;
247 virtual void trial() = 0;
248 virtual void trial_default() = 0;
249 virtual bool nextCondition() = 0;
250 virtual void terminate();
251 virtual void terminate_default() = 0;
252 virtual void saveResults() = 0;
254 virtual void initialize_wait();
255 virtual void setExpname();
\r
256 virtual bool isDemo();
259 ExperimentalMethod();
260 virtual ~ExperimentalMethod();
266 class Demo : public ExperimentalMethod {
268 VariableConsole console;
270 virtual void initialize() = 0;
271 virtual void initialize_default();
272 virtual void trial() = 0;
273 virtual void trial_default();
274 virtual bool nextCondition();
275 virtual void terminate_default();
276 virtual void terminate();
277 virtual void saveResults();
278 // virtual const Demo & draw();
279 // virtual const Demo & draw(const double x, const double y, const double z = 0);
281 virtual bool isDemo();
\r
287 class Constant : public ExperimentalMethod {
289 std::vector<int> conditions_;
291 virtual void initialize() = 0;
292 virtual void initialize_default();
293 virtual void trial() = 0;
294 virtual void trial_default();
295 virtual bool nextCondition();
296 virtual void terminate_default();
298 virtual void saveResults();
299 virtual void initialize_wait();
301 //virtual int set(int vnum, int arraynum, double *array);
302 //virtual void randomize(char* dataname=NULL);
\r
303 //virtual double get(int vnum, int trial_now);
\r
314 extern ExperimentalMethods::Variables Independent;
317 enum DESIGN { DEMO };
318 ExperimentalMethods::VariableConsole console_;
322 void (*func_canvas_)(Canvas &);
323 int func_with_canvas_;
328 void setDesign(DESIGN d);
329 void setProcedure(void (*func)());
330 void setProcedure(void (*func)(Canvas &));
332 void run(Canvas &);
\r
333 void console(bool on_off);
338 } /* <- namespace Psycholops */