]> Creatis software - CreaPhase.git/blob - octave_packages/nnet-0.1.13/mapstd.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / nnet-0.1.13 / mapstd.m
1 ## Copyright (C) 2009 Luiz Angelo Daros de Luca <luizluca@gmail.com>
2 ##
3 ##
4 ## This program is free software; you can redistribute it and/or modify it
5 ## under the terms of the GNU General Public License as published by
6 ## the Free Software Foundation; either version 2, or (at your option)
7 ## any later version.
8 ##
9 ## This program is distributed in the hope that it will be useful, but
10 ## WITHOUT ANY WARRANTY; without even the implied warranty of
11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 ## General Public License for more details.
13 ##
14 ## You should have received a copy of the GNU General Public License
15 ## along with this program; see the file COPYING.  If not, see
16 ## <http://www.gnu.org/licenses/>.
17
18 ## -*- texinfo -*-
19 ## @deftypefn {Function File} [@var{YY},@var{PS}] = mapstd (@var{XX},@var{ymean},@var{ystd})
20 ## Map values to mean 0 and standard derivation to 1.
21 ##
22 ## @example
23 ## [YY,PS] = mapstd(XX,ymean,ystd)
24 ##
25 ##    Apply the conversion and returns YY as (YY-ymean)/ystd.
26 ##
27 ## [YY,PS] = mapstd(XX,FP)
28 ##
29 ##    Apply the conversion but using an struct to inform target mean/stddev.
30 ##    This is the same of [YY,PS]=mapstd(XX,FP.ymean, FP.ystd).
31 ##
32 ## YY = mapstd('apply',XX,PS)
33 ##
34 ##    Reapply the conversion based on a previous operation data.
35 ##    PS stores the mean and stddev of the first XX used.
36 ##
37 ## XX = mapstd('reverse',YY,PS)
38 ##
39 ##    Reverse a conversion of a previous applied operation.
40 ##
41 ## dx_dy = mapstd('dx',XX,YY,PS)
42 ##
43 ##    Returns the derivative of Y with respect to X.
44 ##
45 ## dx_dy = mapstd('dx',XX,[],PS)
46 ##
47 ##    Returns the derivative (less efficient).
48 ##
49 ## name = mapstd('name');
50 ##
51 ##    Returns the name of this convesion process.
52 ##
53 ## FP = mapstd('pdefaults');
54 ##
55 ##    Returns the default process parameters.
56 ##
57 ## names = mapstd('pnames');
58 ##
59 ##    Returns the description of the process parameters.
60 ##
61 ## mapstd('pcheck',FP);
62 ##
63 ##    Raises an error if FP has some inconsistent.
64 ## @end example
65 ##
66 ## @end deftypefn
67
68 function [out1,out2]=mapstd(in1,in2,in3,in4)
69   #
70   # Map values to mean 0 and standard derivation to 1.
71   #
72   # [YY,PS] = mapstd(XX,ymean,ystd)
73   #
74   #    Apply the conversion and returns YY as (YY-ymean)/ystd.
75   #
76   # [YY,PS] = mapstd(XX,FP)
77   #
78   #    Apply the conversion but using an struct to inform target mean/stddev.
79   #    This is the same of [YY,PS]=mapstd(XX,FP.ymean, FP.ystd).
80   #
81   # YY = mapstd('apply',XX,PS)
82   #
83   #    Reapply the conversion based on a previous operation data.
84   #    PS stores the mean and stddev of the first XX used.
85   #
86   # XX = mapstd('reverse',YY,PS)
87   #
88   #    Reverse a conversion of a previous applied operation.
89   #
90   # dx_dy = mapstd('dx',XX,YY,PS)
91   #
92   #    Returns the derivative of Y with respect to X.
93   #
94   # dx_dy = mapstd('dx',XX,[],PS)
95   #
96   #    Returns the derivative (less efficient).
97   #
98   # name = mapstd('name');
99   #
100   #    Returns the name of this convesion process.
101   #
102   # FP = mapstd('pdefaults');
103   #
104   #    Returns the default process parameters.
105   #
106   # names = mapstd('pnames');
107   #
108   #    Returns the description of the process parameters.
109   #
110   # mapstd('pcheck',FP);
111   #
112   #    Raises an error if FP has some inconsistent.
113   #
114
115   if nargin==0
116     error("Not enough arguments.")
117   endif
118
119   # Defaults
120   ps.name="mapstd";
121   ps.ymean=0;
122   ps.ystd=1;
123
124   if ischar(in1)
125     switch in1
126         case "name"
127             if nargout>1
128                 error("Too many output arguments");
129             endif
130             if nargin>1
131                 error("Too many input arguments");
132             endif
133             out1="Map Mean and Standard Deviation";
134             return;
135         case "pdefaults"
136             if nargout>1
137                 error("Too many output arguments");
138             endif
139             if nargin>1
140                 error("Too many input arguments");
141             endif
142             out1=ps;
143         case "pcheck"
144             if nargout>1
145                 error("Too many output arguments");
146             endif
147             if nargin<2
148                 error("Not enough input arguments");
149             endif
150             if nargin>2
151                 error("Too many input arguments");
152             endif
153             
154             fp=in2;           
155             if ~isstruct(fp)
156                 error("FP must be a struct")                
157             elseif ~isfield(fp,"ymean")
158                 error("FP must include ymean field")
159             elseif ~isfield(fp,"ystd")
160                 error("FP must include ystd field")
161             elseif isdouble(fp.ymean)
162                 error("FP.ymean must be a real scalar value")
163             elseif isdouble(fp.ystd)
164                 error("FP.ystd must be a real scalar value")
165             else
166                 out1='';
167             endif
168             return;
169         # MATLAB uses pnames but documents as pdesc (that does not work)
170         case "pnames"
171             if nargout>1
172                 error("Too many output arguments");
173             endif
174             if nargin>1
175                 error("Too many input arguments");
176             endif
177             # MATLAB seems to be buggy in the second element
178             #out1={'Mean value for each row of Y.','Maximum value for each
179             #row of Y.'};            
180             out1={"Mean value for each row of Y.","Standart deviation value for each row of Y."};                        
181         case "apply"
182             if nargin<3
183                 error("Not enough input arguments");
184             endif
185             if nargin>3
186                 error("Too many input arguments");
187             endif
188             if nargout>1
189                 error("Too many output arguments");
190             endif
191             xx=in2;
192             ps=in3;
193             yy=apply(xx,ps);
194             out1=yy;
195             out2=ps;
196             return;
197         case "reverse"
198             if nargin<3
199                 error("Not enough input arguments");
200             endif
201             if nargin>3
202                 error("Too many input arguments");
203             endif
204             if nargout>1
205                 error("Too many output arguments");
206             endif
207             yy=in2;
208             ps=in3;
209             xx=reverse(yy,ps);
210             out1=xx;
211             out2=ps;
212             return;
213         case "dx"
214             if nargin<3
215                 error("Not enough input arguments");
216             endif
217             if nargin>3
218                 error("Too many input arguments");
219             endif
220             if nargout>1
221                 error("Too many output arguments");
222             endif
223             xx=in2;
224             yy=in3;
225             ps=in4;
226             xx_yy=derivate(xx,yy,ps);
227             out1=xx_yy;
228             return;
229     endswitch
230   else
231     xx=in1;
232     ps.xrows=size(xx,1);
233     ps.yrows=size(xx,1);
234     ps.xmean=mean(xx,2);
235     ps.xstd=std(xx,0,2);      
236     
237     if nargin==1
238         # All correct
239     elseif nargin==2
240         if isstruct(in2)
241             ps.ymean=in2.ymean;
242             ps.ystd=in2.ystd;
243         else
244             ps.ymean=in2;
245         endif
246     elseif nargin == 3
247         ps.ymean=in2;
248         ps.ystd=in3;
249     else
250         error("Too many input arguments");
251     endif
252     
253     out1=apply(xx,ps);   
254     out2=ps;
255   endif
256
257   # Verify args
258   function checkargs(values,ps)
259     # check xx is matrix
260     if ~isnumeric(values)
261         error("Just numeric values are accepted")
262     endif
263     # check ps is struct
264     if ~isstruct(ps)
265         error("PS should be a struct")
266     endif
267     # check ymean,ystd
268     if ~isa(ps.ymean,"double")
269         error("PS.ymean should be a double")
270     endif
271     if ~isa(ps.ystd,"double")
272         error("PS.ystd should be a double")
273     endif
274     if ~all(size(ps.ymean)==[1 1])
275         error("PS.ymean should be a scalar")
276     endif
277     if ~all(size(ps.ystd)==[1 1])
278         error("PS.ystd should be a scalar")
279     endif
280     # check xmean,ystd
281     if ~isnumeric(ps.xmean)
282         error("PS.xmean should be a numeric")
283     endif
284     if ~isnumeric(ps.xstd)
285         error("PS.xstd should be a numeric")
286     endif
287     if ~all(size(ps.xmean)==size(ps.xstd))
288         error("Size of PS.xmean and PS.xstd must match")
289     endif
290   endfunction
291
292   # Apply the mapping operation
293   function [yy]=apply(xx,ps)
294     checkargs(xx,ps)
295
296     if ~all(size(xx,1)==size(ps.xmean,1))
297         error("Size of XX rows should match PS.xmean and PS.xstd")
298     endif
299     # Avoid multiply/division by zero
300     ps.xstd(ps.xstd == 0) = 1;
301     yy=(xx - (ps.xmean*ones(1,size(xx,2)))) ./ (ps.xstd*ones(1,size(xx,2)));
302     yy=(yy + ps.ymean) .* ps.ystd;
303   endfunction
304
305   # Reverse the mapping operation
306   function [xx]=reverse(yy,ps)
307     checkargs(yy,ps)
308     if ~all(size(yy,1)==size(ps.xmean,1))
309         error("Size of YY rows should match PS.xmean and PS.xstd")
310     endif
311     # Avoid multiply/division by zero
312     ps.xstd(ps.xstd == 0) = 1;
313     yy=(yy ./ ps.ystd) - ps.ymean;
314     xx=(yy .* (ps.xstd*ones(1,size(yy,2)))) + (ps.xmean*ones(1,size(yy,2)));
315   endfunction
316
317   # I don't know why this exists but matlab implements it
318   function [dy_dx]=derivate(xx,yy,ps)
319     checkargs(yy,ps)
320     checkargs(xx,ps)
321
322     cols = size(xx,2);
323     diagonal = diag(ps.ystd ./ ps.xstd);
324     dy_dx = diagonal(:,:,ones(1,cols));
325   endfunction
326
327 #end
328
329 endfunction