OSDN Git Service

first
[psychlops/cpp.git] / psychlops / extension / standard / psychophysics / psychlops_exp_psychophysics.h
1 /*
2  *  psychlops_exp_psychophysics.h
3  *  Psychlops Standard Library (Universal)
4  *
5  *  Last Modified 2009/07/ by Kenchi HOSOKAWA
6  *  (C) 2005 Kenchi HOSOKAWA, Kazushi MARUYA, Takao SATO
7  */
8
9 #ifndef HEADER_PSYCHLOPS_EXPERIMENTAL_DESIGNS_PSYCHOPHYSICS
10 #define HEADER_PSYCHLOPS_EXPERIMENTAL_DESIGNS_PSYCHOPHYSICS
11
12 #include <deque>
13 #include <string>
14
15 #include "../../../core/graphic/psychlops_g_color.h"
16 #include "../../../core/graphic/psychlops_g_canvas.h"\r
17 #include "../widgets/psychlops_widget.h"
18
19 #ifdef max
20 #undef max
21 #endif
22 #ifdef min
23 #undef min
24 #endif
25
26 namespace Psychlops {
27
28
29 namespace ExperimentalMethods {
30 \r
31         class Variable;\r
32         class SliderInterface : public FigureDatum\r
33         {\r
34         protected:\r
35                 void *body;\r
36         public:\r
37                 SliderInterface();\r
38                 ~SliderInterface();\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
44 \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
51                 bool changed();\r
52                 operator double();\r
53                 void appendTo(Group &target);\r
54         };\r
55
56         class Variable {
57                 public:\r
58                 SliderInterface slider;\r
59
60                 std::string label;\r
61                 virtual ~Variable();
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;
82         };
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; }
90
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);
96
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);
101         }
102
103         template<class X> class VariableInstance : public Variable {
104                 private:
105                 X * const link_;
106                 const X backup_;
107                 std::vector<X> step_;
108                 std::vector<X> column_;
109                 std::vector<X> levels_;
110                 int current_level_;
111                 bool changed_flag;
112                 public:
113                 Interval rng_;
114
115                 public:
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;
120                         tmpstr << *link_;
121                         return tmpstr.str();
122                 }
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) {
127                         changed_flag = true;
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_); }
131                 }\r
132                 virtual void setByRatioInStep(double ratio) {
133                         changed_flag = true;
134                         double r = std::min(1.0, std::max(0.0, ratio));
135                         double s = 1;\r
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
142                         }
143                 }
144                 virtual void setByLevel(int level) {
145                         changed_flag = true;
146                         *link_ = levels_.at(level);
147                 }
148                 virtual void increment(int modulation = 0) {
149                         changed_flag = true;
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_); }
152                 }
153                 virtual void decrement(int modulation = 0) {
154                         changed_flag = true;
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_); }
157                 }
158                 virtual bool changed() {
159                         if(changed_flag) {
160                                 changed_flag = false;
161                                 return true;
162                         } else {
163                                 return false;
164                         }
165                 }
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);
180                         return *this;
181                 }
182                 VariableInstance<X>& set(const std::string &str, const Interval &rng, const X &d_step, const X &e_step = 0) {
183                         set(str);
184                         set(rng);
185                         set(d_step);
186                         set(e_step);
187                         return *this;
188                 }
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
192                         }
193                         return *this;
194                 }
195                 VariableInstance<X>& operator ,(const X &level) {
196                         levels_.push_back(level);
197                         return *this;
198                 }
199         };
200
201
202
203         struct Variables {\r
204                 void* proc___;\r
205                 Group sliders_;\r
206                 bool slider_switch_;\r
207
208                 std::deque<Variable *> variables;
209                 Variables();\r
210                 ~Variables();
211                 template <class X> VariableInstance<X>& append(X &item) {
212                         VariableInstance<X> * tmp = new VariableInstance<X>(&item);
213                         variables.push_back(tmp);
214                         return *tmp;
215                 }
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);
221                 bool changed();\r
222                 void console(bool on_off);\r
223                 void slider(bool on_off);
224         };
225
226         struct VariableConsole : public FigureDatum {
227                 const Variables& o;
228                 mutable int active_, active_bar;
229                 Color fgcolor[2];
230                 Color bgcolor, barcolor, active_barcolor;
231
232                 VariableConsole(const Variables& d);
233                 virtual ~VariableConsole();
234                 virtual VariableConsole& draw(Drawable &target = *Drawable::prime);
235         };
236
237
238         class ExperimentalMethod {
239                 protected:
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;
244
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;
253
254                 virtual void initialize_wait();
255                 virtual void setExpname();\r
256                 virtual bool isDemo();
257
258                 public:
259                 ExperimentalMethod();
260                 virtual ~ExperimentalMethod();
261
262                 virtual void run();
263         };
264
265
266         class Demo : public ExperimentalMethod {
267                 protected:
268                 VariableConsole console;
269
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);
280 \r
281                 virtual bool isDemo();\r
282
283                 Demo();
284                 virtual ~Demo();
285         };
286
287         class Constant : public ExperimentalMethod {
288                 protected:
289                 std::vector<int> conditions_;
290
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();
297 \r
298                 virtual void saveResults();
299                 virtual void initialize_wait();
300 \r
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
304
305                 public:
306                 Constant();
307                 virtual ~Constant();
308         };
309
310 }
311
312
313
314         extern ExperimentalMethods::Variables Independent;
315         class Procedure {
316                 public:
317                 enum DESIGN { DEMO };
318                 ExperimentalMethods::VariableConsole console_;
319
320                 private:
321                 void (*func_)();
322                 void (*func_canvas_)(Canvas &);
323                 int func_with_canvas_;
324                 DESIGN design_;
325
326                 public:
327                 Procedure();
328                 void setDesign(DESIGN d);
329                 void setProcedure(void (*func)());
330                 void setProcedure(void (*func)(Canvas &));
331                 void run();
332                 void run(Canvas &);\r
333                 void console(bool on_off);
334         };
335
336
337
338 }       /*      <- namespace Psycholops         */
339
340
341 #endif