* Bug 16320 fixed: typos in blocks interfaces + a few files
[scilab.git] / scilab / modules / scicos_blocks / macros / Sources / CURVE_c.sci
1 //  Scicos
2 //
3 //  Copyright (C) INRIA - Masoud Najafi <masoud.najafi@inria.fr>
4 //                        Serge Steer <serge.steer@inria.fr>       1993
5 //                        Habib Jreij                              1993
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 //
21 // See the file ../license.txt
22 //
23
24 function [x,y,typ]=CURVE_c(job,arg1,arg2)
25     //** 07/01/2008 : Adapted fot Scilab 5.0 by Simone Mannori
26     x=[];
27     y=[];
28     typ=[];
29
30     select job
31
32     case "set" then
33
34         x = arg1;
35         model = arg1.model;
36         graphics = arg1.graphics;
37         exprs = graphics.exprs;
38         ok = %f;
39         SaveExit = %f;
40
41         while %t do
42             Ask_again = %f;
43             [ok,Method,xx,yy,PeriodicOption,graf,exprs] = scicos_getvalue(..
44             _("Spline data"),..
45             [_("Spline Method (0..7)") ; "x" ; "y" ;
46              _("Periodic signal (y/n)?");
47              _("Launch graphic window (y/n)?")], ..
48              list("vec",1,"vec",-1, "vec",-1,"str",1,"str",1), exprs)
49             if  ~ok then
50                 break;
51             end
52
53             if PeriodicOption=="y" | PeriodicOption=="Y" then
54                 PO=1;
55             else
56                 exprs(4)="n";
57                 PO=0;
58             end
59             if graf=="y" | graf=="Y" then
60                 gui=1;
61             else
62                 exprs(5)="n";
63                 gui=0;
64             end
65
66             mtd=int(Method);
67             if mtd<0 then
68                 mtd=0
69             end;
70
71             if mtd>7 then
72                 mtd=7;
73             end
74
75             METHOD = getmethod(mtd);
76
77             if ~Ask_again then
78                 xx=xx(:);
79                 yy=yy(:);
80                 [nx,mx] = size(xx);
81                 [ny,my]=size(yy);
82                 if ~((nx==ny)&(mx==my)) then
83                     messagebox(_("Incompatible sizes of [x] and [y]"),"modal","error");
84                     Ask_again = %t;
85                 end
86             end
87
88             if ~Ask_again then //+++++++++++++++++++++++++++++++++++++++
89                 xy = [xx,yy];
90                 [xy] = cleandata(xy); // just for sorting to be able to compare data before and after poke_point(.)
91                 N= size(xy,"r");
92                 exprs(5)="n";// exprs.graf='n'
93
94                 if gui then //_______Graphic editor___________
95                     ipar=[N;mtd;PO];
96                     rpar=[];
97
98                     if (winsid() == []) then
99                         curwin = 0;
100                     else
101                         curwin = max(winsid())+1; //** prepare a brand new win
102                     end
103                     //** see below in this file; "poke_point" is very similar to "edit_curv"
104                     [orpar,oipar,ok] = poke_point(xy,ipar,rpar); //** HERE WE ARE +++++++++++++++++++++++++++++++++++
105                     if ~ok then
106                         break;
107                     end;//  exit without save
108
109                     // verifying the data change
110                     N2=oipar(1);
111                     xy2=[orpar(1:N2),orpar(N2+1:2*N2)];
112                     New_methhod=oipar(2);
113                     DChange=%f;
114                     METHOD=getmethod(New_methhod);
115                     if or(xy(:,1)<>xy2(:,1)) then,
116                         DChange=%t;
117                     end
118                     if or(xy(1:N-1,2)<>xy2(1:N2-1,2)) then,
119                         DChange=%t;
120                     end
121                     if (xy(N,2)<>xy2(N2,2) & (METHOD<>"periodic")) then,
122                         DChange=%t;
123                     end
124                     if DChange then
125                         exprs(2)=strcat(sci2exp(xy2(:,1)))
126                         exprs(3)=strcat(sci2exp(xy2(:,2)))
127                     end
128
129                     exprs(1)=sci2exp(New_methhod);
130                     if oipar(3)==1 then,
131                         perop="y";
132                     else,
133                         perop="n";
134                     end
135                     exprs(4)=perop;
136                     SaveExit=%t
137                 else//_____________________No graphics__________________________
138                     [Xdummy,Ydummy,orpar]=Do_Spline(N,mtd,xy(:,1),xy(:,2));
139                     if (METHOD=="periodic") then // periodic spline
140                         xy(N,2)=xy(1,2);
141                     end
142                     if (METHOD=="order 2" | METHOD=="not_a_knot"|METHOD=="periodic" | METHOD=="monotone"| METHOD=="fast" | METHOD=="clamped") then
143                         orpar=[xy(:,1);xy(:,2);orpar];
144                     else
145                         if (METHOD=="zero order"|METHOD=="linear")
146                             orpar=[xy(:,1);xy(:,2);]
147                         end
148                     end
149                     exprs(1)=sci2exp(mtd);// pour le cas methode>7 | method<0
150                     oipar=[N;mtd;PO]
151                     SaveExit=%t
152                 end //___________________________________________________________
153             end //++++++++++++++++++++++++++++++++++++++++++++++++++++++
154
155             if (SaveExit) then
156                 xp=find(orpar(1:oipar(1))>=0);
157                 if (xp<>[]) then
158                     model.firing=orpar(xp(1)); //first positive event
159                 else
160                     model.firing=-1;
161                 end
162                 model.rpar=orpar
163                 model.ipar=oipar
164                 graphics.exprs=exprs;
165                 x.model=model
166                 x.graphics=graphics
167                 break
168             end
169         end
170     case "define" then
171         model=scicos_model()
172         xx=[0, 1, 2];
173         yy=[10, 20, -30];
174         N=3;
175         Method=3;
176         PeriodicOption="y";
177         Graf="n"
178         model.sim=list("curve_c",4)
179         model.in=[]
180         model.out=1
181         model.rpar=[xx(:);yy(:)]
182         model.ipar=[N;Method;1]
183         model.blocktype="c"
184         model.dep_ut=[%f %t]
185         model.evtin=1
186         model.evtout=1
187         model.firing=0
188         exprs=[sci2exp(Method);sci2exp(xx);sci2exp(yy);PeriodicOption;Graf]
189
190         gr_i=[]
191         x=standard_define([2 2],model,exprs,gr_i)
192     end
193 endfunction
194
195
196 function [rpar,ipar,ok] = poke_point(ixy,iparin,rparin)
197
198     [lhs,rhs]=argn(0)
199
200     //** get_click is already defined in "editi_curv"
201     //in line definition of get_click
202     deff("[btn,xc,yc,win,Cmenu]=get_click(flag)",[
203     "if ~or(winsid() == curwin) then   Cmenu = ''Quit'';return,end,";
204     "if argn(2) == 1 then";
205     "  [btn, xc, yc, win, str] = xclick(flag);";
206     "else";
207     "  [btn, xc, yc, win, str] = xclick();";
208     "end;";
209     "if btn == -1000 then";
210     "  if win == curwin then";
211     "    Cmenu = ''Quit'';";
212     "  else";
213     "    Cmenu = ''Open/Set'';";
214     "  end,";
215     "  return,";
216     "end";
217     "if btn == -2 then";
218     "  xc = 0;yc = 0;";
219     "  try "    // added to handle unwanted menu actions in french version
220     "    execstr(''Cmenu='' + part(str, 9:length(str) - 1));";
221     "    execstr(''Cmenu='' + Cmenu);";
222     "  catch"
223     "    Cmenu=[]"
224     "  end "
225     "  return,";
226     "end";
227     "Cmenu=[]"])
228
229     ok = %f
230     if rhs==0 then
231         ixy=[];
232     end;
233
234     if size(xy,"c")<2 then
235         gcf().info_message = _(" No [y] is provided");
236         return
237     end
238
239     [xy] = cleandata(ixy)
240
241     N = size(xy,"r");
242
243     if rhs<=1 then
244         NOrder = 1;
245         PeridicOption = 0;
246         ipar = [N;NOrder;PeridicOption]
247         rpar = []
248     else
249         if rhs==2 then
250             NOrder = iparin(2);
251             PeridicOption = iparin(3);
252             ipar = iparin;
253             rpar = [];
254         else
255             if rhs==3 then
256                 NOrder = iparin(2);
257                 PeridicOption = iparin(3);
258                 ipar = iparin;
259                 rpar = rparin
260             end
261         end //** ???
262     end //** ???
263
264     Amp=[];
265     wp=[];
266     phase=[];
267     offset=[];
268     np1=[];
269     Sin_exprs = list(string(Amp),string(wp), string(phase),string(offset),string(np1));
270     sAmp=[];
271     sTp=[];
272     sdelay=[];
273     Sawt1_exprs = list(string(sAmp),string(sTp),string(sdelay));
274     sAmp2=[];
275     sTp2 = [];
276     Sawt2_exprs = list(string(sAmp2),string(sTp2));
277
278     Amp3=[];
279     Tp3=[];
280     Pw3=[];
281     Pd3=[];
282     Bias3=[];
283     Pulse_exprs=list(string(Amp3), string(Tp3),string(Pw3),string(Pd3),string(Bias3))
284
285     mean4=[];
286     var4=[];
287     seed4=[];
288     sample4=[];
289     np4=[];
290     random_n_exprs=list(string(mean4),string(var4), string(seed4),string(sample4),string(np4))
291
292     min5=[];
293     max5=[];
294     seed5=[];
295     sample5=[];
296     np5=[];
297     random_u_exprs=list(string(min5), string(max5), string(seed5),string(sample5),string(np5))
298
299     // bornes initiales du graphique
300     xmx = max(xy(:,1));
301     xmn=min(xy(:,1)),
302     xmn=max(xmn,0);
303     ymx = max(xy(:,2));
304     ymn=min(xy(:,2));
305     dx = xmx-xmn;
306     dy = ymx-ymn
307
308     if dx==0 then
309         dx=max(xmx/2,1),
310     end;
311     xmx = xmx+dx/50;
312
313     if dy==0 then
314         dy=max(ymx/2,1),
315     end;
316     ymn = ymn-dy/50;
317     ymx = ymx+dy/50;
318
319     rect = [xmn,ymn;xmx,ymx];
320
321     // initial draw
322     f = scf(curwin);
323
324
325     menu_r = [];
326     menu_s = [];
327     menu_o = ["zero order","linear","order 2","not_a_knot","periodic","monotone","fast","clamped"]
328     menu_d = _(["Clear"; "Data Bounds"; "Load from text file"; "Save to text file"; "Load from Excel"; "Periodic signal"])'
329     menu_t=["sine","sawtooth1","sawtooth2","pulse","random normal","random uniform"]
330     menu_e= _(["Help"; "Exit without save"; "Save/Exit"])';
331     MENU= ["Autoscale", "Spline", "Data", "Standards", "Exit"];
332     menus = list(MENU,menu_s,menu_o,menu_d,menu_t,menu_e);
333
334     scam="menus(1)(1)"
335     w="menus(3)(";
336     r=")";
337     Orderm=w(ones(menu_o))+string(1:size(menu_o,"*"))+r(ones(menu_o))
338     w="menus(4)(";
339     r=")";
340     Datam=w(ones(menu_d))+string(1:size(menu_d,"*"))+r(ones(menu_d))
341     w="menus(5)(";
342     r=")";
343     Standm=w(ones(menu_t))+string(1:size(menu_t,"*"))+r(ones(menu_t))
344     w="menus(6)(";
345     r=")";
346     Exitm=w(ones(menu_e))+string(1:size(menu_e,"*"))+r(ones(menu_e))
347
348     execstr("Autoscale_"+string(curwin)+"=scam")
349     execstr("Spline_"+string(curwin)+"=Orderm")
350     execstr("Data_"+string(curwin)+"=Datam")
351     execstr("Standards_"+string(curwin)+"=Standm")
352     execstr("Exit_"+string(curwin)+"=Exitm")
353
354     addmenu(curwin,MENU(1))
355     addmenu(curwin,MENU(2),menu_o)
356     addmenu(curwin,MENU(3),menu_d)
357     addmenu(curwin,MENU(4),menu_t)
358     addmenu(curwin,MENU(5),menu_e)
359     //===================================================================
360
361     drawlater();
362     a = gca();
363     a.data_bounds  = rect;
364     a.axes_visible = "on";
365     a.clip_state   = "on";
366     xtitle( "", "time", "Output" ) ;
367     a.title.font_size=2;
368     a.title.font_style=4;
369     a.title.foreground=2;
370
371     a.grid=[2 2];
372     xpolys(xy(:,1),xy(:,2),[-1]);   //children(2)
373     xpolys(xy(:,1),xy(:,2),[5]);    //children(1)
374     splines = a.children(1).children
375     points  = a.children(2).children
376     //---------------------------------------
377     [rpar,ipar]=AutoScale(a,xy,ipar,rpar)
378     drawnow();
379     // -- boucle principale
380
381     lines(0);
382     while %t then //=================================================
383         N = size(xy,"r");
384         [btn,xc,yc,win,Cmenu] = get_click(); //** see
385         if ((win>0) & (win<>curwin)) then
386             Cmenu = _("Mouse click is offside!");
387         end
388         if Cmenu==[] then
389             Cmenu="edit",
390         end
391         if (Cmenu=="Exit") |(Cmenu=="Quit" ) then,
392             ipar=[];
393             rpar=[];
394             ok=%f;
395             return;
396         end
397         //-------------------------------------------------------------------
398         if ((Cmenu=="zero order") | (Cmenu=="linear") | (Cmenu=="order 2")| ...
399             (Cmenu=="not_a_knot")| (Cmenu=="periodic")| (Cmenu=="monotone")| ...
400             (Cmenu=="fast")| (Cmenu=="clamped")) then
401
402             select  Cmenu
403             case "zero order" then
404                 NOrder=0;
405             case "linear" then
406                 NOrder=1;
407             case "order 2" then
408                 NOrder=2;
409             case "not_a_knot" then
410                 NOrder=3;
411             case "periodic" then
412                 NOrder=4;
413             case "monotone" then
414                 NOrder=5;
415             case "fast" then
416                 NOrder=6;
417             case "clamped" then
418                 NOrder=7;
419             end
420             ipar(2)=NOrder;
421             [rpar,ipar]=AutoScale(a,xy,ipar,rpar)
422         end
423         //-------------------------------------------------------------------
424         select Cmenu
425         case _("Data Bounds") then
426             rectx=findrect(a);
427             [mok, xmn1, xmx1, ymn1, ymx1] = scicos_getvalue(..
428             _("Enter new bounds"), ["xmin";"xmax"; "ymin";"ymax"], ..
429             list("vec", 1,"vec", 1,"vec", 1,"vec", 1), string(rectx(:)))
430             //drawlater();
431             if mok then
432                 if (xmn1 > xmx1 | ymn1 > ymx1) then
433                     gcf().info_message = _("Incorrect bounds")
434                     mok=%f;
435                 end
436                 if xmn1<0 then
437                     gcf().info_message = _("X should be positive")
438                     mok=%f;
439                 end
440                 if mok then
441                     a.data_bounds=[xmn1, ymn1; xmx1, ymx1];
442                 end
443             end
444             //drawnow();
445             //-------------------------------------------------------------------
446         case "Autoscale" then
447             [rpar,ipar]=AutoScale(a,xy,ipar,rpar)
448             //-------------------------------------------------------------------
449         case "Periodic signal" then
450             if PeridicOption==1 then,
451                 ans0="y",
452             else,
453                 ans0="n",
454             end;
455             [mok,myans]=scicos_getvalue(_("Generating periodic signal"),["y/n"],list("str",1),list(ans0));
456             if ((myans=="y")|(myans=="Y")) then,
457                 PeridicOption=1,
458             else,
459                 PeridicOption=0;
460             end;
461             ipar(3)=PeridicOption;
462             [rpar,ipar]=AutoScale(a,xy,ipar,rpar)
463             //-------------------------------------------------------------------
464         case "sine" then
465             [mok,Amp,wp,phase,offset,np1,Sin_exprs2]=scicos_getvalue(..
466             _("Sine parameters"), ...
467             _(["Amplitude" ;
468                "Frequency (rad/s)";
469                "Phase (rad)";
470                "Bias";
471                "Number of points"]), ..
472             list("vec",1,"vec",1,"vec",1, "vec",1,"vec",1), Sin_exprs)
473             if np1< 2 then
474                 np1=2;
475             end
476             if mok & wp>0  then
477                 NOrder=3;
478                 ipar(2)=NOrder;
479                 phase=atan(tan(phase));
480                 xt=linspace(0,%pi*2/wp,np1)';
481                 yt=Amp*sin(wp*xt+phase)+offset;
482                 xy=[xt,yt];
483                 [rpar,ipar]=AutoScale(a,xy,ipar,rpar)
484                 Sin_exprs=Sin_exprs2
485             end
486             //-------------------------------------------------------------------
487         case "sawtooth1" then
488             [mok,sAmp,sTp,sdelay,Sawt1_exprs2]=scicos_getvalue(..
489             _("Sawtooth signal parameters"), ...
490             _(["Amplitude" ; "Period" ; "delay"]), ...
491             list("vec",1,"vec",1,"vec",1),Sawt1_exprs)
492             if mok & sTp>0 then
493                 NOrder=1;
494                 ipar(2)=NOrder;
495                 if sdelay<sTp then
496                     xt=[0;sdelay;sTp];
497                     yt=[0;0;sAmp];
498                 else
499                     xt=[0];
500                     yt=[0];
501                 end
502                 xy=[xt,yt];
503                 [rpar,ipar]=AutoScale(a,xy,ipar,rpar);
504                 Sawt1_exprs=Sawt1_exprs2
505             end
506             //-------------------------------------------------------------------
507         case "sawtooth2" then
508             [mok,sAmp2,sTp2,Sawt2_exprs2]=scicos_getvalue(..
509             _("Sawtooth signal parameters"), ..
510             _(["Amplitude" ; "Period"]), list("vec",1,"vec",1), Sawt2_exprs)
511             if mok & sTp2>0 then
512                 NOrder=1;
513                 ipar(2)=NOrder;
514                 xt=[0;sTp2];
515                 yt=[sAmp2;-sAmp2];
516                 xy=[xt,yt];
517                 [rpar,ipar]=AutoScale(a,xy,ipar,rpar);
518                 Sawt2_exprs=Sawt2_exprs2
519             end
520             //-------------------------------------------------------------------
521         case "pulse" then
522             [mok,Amp3,Tp3,Pw3,Pd3,Bias3,Pulse_exprs2] = scicos_getvalue(..
523             _("Square wave pulse signal"), ..
524             _(["Amplitude";"Period (sec)";
525                "Pulse width (% of period)";
526                "Phase delay (s)";
527                "Bias"]), ..
528             list("vec",1, "vec",1,"vec",1,"vec",1,"vec",1), Pulse_exprs);
529             if mok & Tp3>0  then
530                 NOrder=0;
531                 ipar(2)=NOrder;
532                 if (Pd3>0) then
533                     xt=0;
534                     yt=Bias3;
535                 else
536                     xt=[];
537                     yt=[];
538                 end
539                 //otherwise there would be double points at 0
540                 if Pd3<Tp3 then
541                     if Pw3>0 then
542                         xt=[xt;Pd3; Pw3*Tp3/100+Pd3;Tp3];
543                         yt=[yt;Amp3+Bias3;Bias3;Bias3];
544                     else
545                         xt=[0;Tp3];yt=[Bias3;Bias3];
546                     end
547                 else
548                     xt=[0;Tp3];yt=[Bias3;Bias3];
549                 end
550
551                 xy=[xt,yt];
552                 [rpar,ipar]=AutoScale(a,xy,ipar,rpar);
553                 Pulse_exprs=Pulse_exprs2;
554             end
555             //-------------------------------------------------------------------
556         case "random normal" then
557             [mok,mean4,var4,seed4,sample4,np4,random_n_exprs2]=scicos_getvalue(..
558             _("Normal (Gaussian) random signal"), ...
559             _(["Mean";"Variance";"Initial seed";"Sample time";"Number of points"]),..
560             list("vec",1,"vec",1,"vec",1,"vec",1,"vec",1), random_n_exprs)
561             if mok & sample4>0 then
562                 NOrder=0;
563                 ipar(2)=NOrder;
564                 rand("normal");
565                 rand("seed",seed4);
566                 xt=0:sample4:sample4*(np4-1);
567                 xt=xt(:);
568                 yt=mean4+sqrt(var4)*rand(np4,1);
569                 xy=[xt,yt];
570                 [rpar,ipar]=AutoScale(a,xy,ipar,rpar);
571                 random_n_exprs2=random_n_exprs;
572             end
573             //-------------------------------------------------------------------
574         case "random uniform" then
575             [mok,min5,max5,seed5,sample5,np5,random_u_exprs2]=scicos_getvalue(..
576             _("Uniform random signal"), ...
577             _(["Minimum";"Maximum";"Initial seed";"Sample time";"Number of points"]),..
578             list("vec",1,"vec",1,"vec",1,"vec",1,"vec",1), random_u_exprs)
579             if mok & sample5>0 then
580                 NOrder=0;
581                 ipar(2)=NOrder;
582                 rand("uniform");
583                 rand("seed",seed5);
584                 xt=0:sample5:sample5*(np5-1);
585                 xt=xt(:);
586                 yt=min5+(max5-min5)*rand(np5,1);
587                 xy=[xt,yt];
588                 [rpar,ipar]=AutoScale(a,xy,ipar,rpar);
589                 random_u_exprs2=random_u_exprs;
590
591             end
592             //-------------------------------------------------------------------
593         case _("Save/Exit") then
594             NOrder=ipar(2);
595             PeridicOption=ipar(3);
596
597             METHOD=getmethod(NOrder);
598             if (METHOD=="periodic") then // periodic spline
599                 xy(N,2)=xy(1,2);
600             end
601
602             if (METHOD=="order 2" | METHOD=="not_a_knot"|METHOD=="periodic" | METHOD=="monotone"| METHOD=="fast" | METHOD=="clamped") then
603                 rpar=[xy(:,1);xy(:,2);rpar];
604             else
605                 if (METHOD=="zero order"|METHOD=="linear")
606                     rpar=[xy(:,1);xy(:,2);]
607                 end
608             end
609
610             ok=%t
611             delete(f);
612             return
613             //-------------------------------------------------------------------
614         case _("Exit without save") then
615             ipar=[];
616             rpar=[];
617             ok=%f
618             delete(f);
619             return
620             //-------------------------------------------------------------------
621         case _("Clear") then
622             xy=[0,0];
623             NOrder=0;
624             ipar(2)=NOrder;
625             [rpar,ipar]=AutoScale(a,xy,ipar,rpar)
626             //----------------------------------------------------------------
627         case "Edit text data NOT IN USE" then
628             //  editvar xy;
629             [mok,xt,yt]=scicos_getvalue(_("Enter x and y data"),["x";"y"],..
630             list("vec",-1,"vec",-1), ..
631             list(strcat(sci2exp(xy(:,1))),strcat(sci2exp(xy(:,2)))));
632             if mok then,
633                 xy=[xt,yt];
634                 [xy]=cleandata(xy),
635                 [rpar,ipar]=AutoScale(a,xy,ipar,rpar)
636             end
637             //---------------------------------------------------------------
638         case _("Help") then
639             t1 = _("Mouse-left click: adding a new point")
640             t2 = _("Mouse-right click: remove a point")
641             t3 = _("Mouse-left double click: edit a point''s coordinates")
642             t4 = _("Mouse-left button press/drag/release: move a  point")
643             t5 = _("Change the window size: Data menu -> Databounds")
644             messagebox([t1;t2;t3;t4;t5],"modal","info");
645             //---------------------------------------------------------------
646         case _("Load from Excel") then
647             [tok,xytt]=ReadExcel()
648             if tok then
649                 xy=xytt;
650                 NOrder=1
651                 ipar(2)=NOrder;
652                 [rpar,ipar]=AutoScale(a,xy,ipar,rpar)
653             end
654             //---------------------------------------------------------------
655         case _("Load from text file") then
656             [tok,xytt]=ReadFromFile()
657             if tok then
658                 xy=xytt;
659                 NOrder=1
660                 ipar(2)=NOrder;
661                 [rpar,ipar]=AutoScale(a,xy,ipar,rpar)
662             end
663             //---------------------------------------------------------------
664         case _("Save to text file") then
665             [sok]=SaveToFile(xy)
666             //---------------------------------------------------------------
667         case "Replot" then
668             if xy<>[] then
669                 drawlater();
670                 points.data=xy;
671                 [rpar,ipar]=drawSplin(a,xy,ipar,rpar);
672                 drawnow()
673             end
674             //----------------------------------------------------------
675         case "edit" then
676             HIT=%f
677             if N<>0 then
678                 xt=xy(:,1);
679                 yt=xy(:,2);
680                 dist=((xt-ones(N,1)*xc))^2+((yt-ones(N,1)*yc))^2
681                 [dca,k]=min(dist);
682                 rectx=a.data_bounds;
683                 ex=abs(rectx(2,1)-rectx(1,1))/80;
684                 ey=abs(rectx(2,2)-rectx(1,2))/80;
685                 if (abs(xc-xt(k))<ex & abs(yc-yt(k))<ey) then
686                     HIT=%t
687                 end
688             end
689
690             //_________________________
691             //  if ~((NOrder==-1|NOrder==-2|NOrder==-3|NOrder==-4)) then
692             if (~HIT)&(btn==0 | btn==3) then    // add point
693                 if (xc>=0) then
694                     if (xc==0) then
695                         zz=find(x==0);
696                         xy(zz,:)=[];
697                     end
698                     xy=[xy;xc,yc];
699                     [xtt,k2]=gsort(xy(:,1),"r","i");xy=xy(k2,:)
700                     drawlater();
701                     points.data=xy;
702                     [rpar,ipar]=drawSplin(a,xy,ipar,rpar);
703                     drawnow();
704                 end
705             end
706
707             if (HIT)&(btn==2 | btn==5) then  //   remove point
708                 if (xy(k,1)>0) |( xy(k,1)==0 & (size(find(xy(:,1)==0),"*")>1)) then
709                     xy(k,:)=[];
710                 end
711                 drawlater();
712                 points.data = xy;
713                 [rpar,ipar] = drawSplin(a,xy,ipar,rpar);
714                 drawnow();
715             end
716
717             if (HIT)&(btn==0) then             // move point
718                 [xy,rpar,ipar] = movept(a,xy,ipar,rpar,k)
719             end
720
721             if (HIT)&(btn==10) then             // change data:: double click
722                 [mok,xt,yt]=scicos_getvalue(_("Enter new x and y"),["x";"y"],...
723                 list("vec",1,"vec",1),list(sci2exp(xy(k,1)),sci2exp(xy(k,2))));
724                 if mok then
725                     xy(k,:) = [xt,yt];
726                     [xy] = cleandata(xy)
727                     drawlater();
728                     points.data=xy;
729                     [rpar,ipar]=AutoScale(a,xy,ipar,rpar)
730                     drawnow()
731                 end
732             end
733
734             //  end
735             //_________________________________
736
737         end
738         //----------------------------------------------------------
739     end
740 endfunction
741 //========================================================================
742 function [orpar,oipar] = drawSplin(a,xy,iipar,irpar)
743     N=size(xy,"r");// new size of xy
744     x=xy(:,1);
745     y=xy(:,2);
746     points=a.children(2).children
747     splines=a.children(1).children
748     order=iipar(2);
749     periodicoption=iipar(3);
750     orpar=irpar;
751
752     METHOD=getmethod(order);
753
754     if periodicoption==1 then
755         PERIODIC="periodic, T="+string(x(N)-x(1));
756     else
757         PERIODIC="aperiodic";
758     end
759     msg = _("%d points,  Method: %s,  %s")
760     a.title.text = msprintf(msg, N, METHOD, PERIODIC);
761
762     if (N==0) then,
763         return;
764     end
765     if (N==1) then,
766         order=0;
767     end
768     //  NP=50;// number of intermediate points between two data points
769     [X,Y,orpar]=Do_Spline(N,order,x,y);
770     if (periodicoption==1) then
771         X=[X;X($)];
772         Y=[Y;Y(1)];
773     else
774         xmx=max(points.data(:,1));  xmn=min(points.data(:,1));
775         XMX=max(0,xmx);
776         XMN=max(0,xmn);
777         xmx1=max(a.x_ticks.locations)
778         XMX=max(XMX,xmx1);
779         X=[X;XMX];
780         Y=[Y;Y($)];
781     end
782     //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
783     splines.data=[X,Y];
784     oipar=[N;iipar(2);periodicoption]
785 endfunction
786 //=============================================================
787 function [xyt,orpar,oipar]=movept(a,xy,iipar,irpar,k)
788     //on bouge un point existant
789     points=a.children(2).children
790     splines=a.children(1).children
791     oipar=iipar
792     orpar=irpar
793     order=iipar(2);
794     x=xy(:,1);
795     y=xy(:,2);
796
797     if (x(k)==0) then
798         zz=find(x==0);
799         x(zz)=[];
800         y(zz)=[];
801         ZERO_POINT=%t
802     else
803         x(k)=[];
804         y(k)=[];
805         ZERO_POINT=%f
806     end
807
808     btn=-1
809
810     while ~(btn==3 | btn==0| btn==10| btn==-5)
811         rep=xgetmouse([%t %t]); xc=rep(1);yc=rep(2);btn=rep(3);
812         if (ZERO_POINT) then
813             xc=0;
814         else
815             if (xc<=0) then
816                 zz=find(x==0);
817                 x(zz)=[];
818                 y(zz)=[];
819                 ZERO_POINT=%t;
820                 xc=0;
821             end
822         end
823
824         xt=[x;xc];
825         yt=[y;yc];
826         [xt,k2]=gsort(xt,"r","i");yt=yt(k2)
827         xyt=[xt,yt];
828
829         drawlater();
830         points.data=xyt;
831         [orpar,oipar]=drawSplin(a,xyt,oipar,orpar);
832         drawnow()
833     end
834
835 endfunction
836
837 //==========================================================
838 function rectx = findrect(a)
839     splines=a.children(1).children
840     points=a.children(2).children
841
842     if (points.data==[]) then
843         rectx=a.data_bounds;
844         return;
845     end
846
847
848     ymx1=max(splines.data(:,2));
849     ymn1=min(splines.data(:,2))
850
851     xmx=max(points.data(:,1));
852     xmn=min(points.data(:,1));
853     ymx=max(points.data(:,2));
854     ymn=min(points.data(:,2));
855
856
857     XMX=max(0,xmx);
858     XMN=max(0,xmn);
859     YMX=max(ymx,ymx1);
860     YMN=min(ymn,ymn1);
861
862     dx=XMX-XMN;
863     dy=YMX-YMN
864     if dx==0 then
865         dx=max(XMX/2,1),
866     end;
867     XMX=XMX+dx/50
868     if dy==0 then
869         dy=max(YMX/2,1),
870     end;
871     YMN=YMN-dy/50;
872     YMX=YMX+dy/50;
873     rectx=[XMN,YMN;XMX,YMX];
874 endfunction
875
876 //============================================================
877 function [tok,xyo]=ReadExcel()
878     TA=["A";"B";"C";"D";"E";"F";"G";"H";"I";"J";"K";"L";"M";"N";"O";"P"; ...
879     "Q";"R";"S";"T";"U";"V";"W";"X";"Y";"Z";"a";"b";"c";"d";"e";"f"; ...
880     "g";"h";"i";"j";"k";"l";"m";"n";"o";"p";"q";"r";"s";"t";"u";"v"; ...
881     "w";"x";"y";"z"];
882     TN=["0","1","2","3","4","5","6","7","8","9"];
883     xyo=[];
884     tok=%f;
885     while %t
886         [zok,filen,sheetN,xa,ya]=scicos_getvalue(_("Excel data file"),..
887         _(["Filename";"Sheet # ";"X[start:Stop]";"Y[start:stop]"]),..
888         list("str",1,"vec",1,"str",1,"str",1), ...
889         list(["Classeur1.xls"],["1"],["C5:C25"],["D5:D25"]));
890         if ~zok then
891             break,
892         end
893
894         try
895             [fd,SST,Sheetnames,Sheetpos] = xls_open(filen);
896         catch
897             msg = _("Scicos cannot find the excel file ''%s''.")
898             gcf().info_message = msprintf(msg, filen);
899             break;
900         end
901         try
902             N=size(Sheetnames,"*");
903             if ((sheetN<=N) &(sheetN>0)) then
904                 [Value,TextInd] = xls_read(fd,Sheetpos(sheetN))
905                 mclose(fd)
906             end
907             xa=strsubst(xa," ","");
908             px=strindex(xa,":");
909             ya=strsubst(ya," ","");
910             py=strindex(ya,":");
911             x1=part(xa,1:px-1);
912             x2=part(xa,px+1:length(xa));
913             y1=part(ya,1:py-1);
914             y2=part(ya,py+1:length(ya));
915
916             x1p=min(strindex(x1,TN));
917             if x1p==[] then,
918                 gcf().info_message = msprintf(_("Bad address in X: %s"), x1);
919                 break,
920             end
921             x11=part(x1,1:x1p-1);
922             x12=part(x1,x1p:length(x1));
923
924             x2p=min(strindex(x2,TN));
925             if x2p==[] then,
926                 gcf().info_message = msprintf(_("Bad address in X: %s"), x2);
927             break, end
928             x21=par
929             t(x2,1:x2p-1);
930             x22=part(x2,x2p:length(x2));
931
932             y1p=min(strindex(y1,TN));
933             if y1p==[] then,
934                 gcf().info_message = msprintf(_("Bad address in Y: %s"), y1);
935                 break,
936             end
937             y11=part(y1,1:y1p-1);
938             y12=part(y1,y1p:length(y1));
939
940             y2p=min(strindex(y2,TN));
941             if y2p==[] then,
942                 gcf().info_message = msprintf(_("Bad address in Y: %s"), y2);
943                 break,
944             end
945             y21=part(y2,1:y2p-1);
946             y22=part(y2,y2p:length(y2));
947
948             // x11 x12: x21 x22
949
950             lx11=length(x11);
951             lx21=length(x21);
952             ly11=length(y11);
953             ly21=length(y21)
954             xstC=0;
955             for i=1:lx11,
956                 xstC=xstC+modulo(find(TA==part(x11,lx11-i+1)),26)*26^(i-1);
957             end
958             xenC=0;
959             for i=1:lx21,
960                 xenC=xenC+modulo(find(TA==part(x21,lx21-i+1)),26)*26^(i-1);
961             end
962             ystC=0;
963             for i=1:ly11,
964                 ystC=ystC+modulo(find(TA==part(y11,ly11-i+1)),26)*26^(i-1);
965             end
966             yenC=0;
967             for i=1:ly11,
968                 yenC=yenC+modulo(find(TA==part(y21,ly21-i+1)),26)*26^(i-1);
969             end
970
971             xstR=evstr(x12);
972             xenR=evstr(x22);
973             ystR=evstr(y12);
974             yenR=evstr(y22);
975
976             [mv,nv]=size(Value)
977
978             if ~(xstR<=mv & xstR>0 & xenR<=mv & xenR>0&ystR<=mv & ystR>0&yenR<=mv&yenR>0 ) then
979                 gcf().info_message = _("Error in Row data addresses");
980                 break
981             end
982             if ~(xstC<=nv & xstC>0 & xenC<=nv & xenC>0&ystC<=nv & ystC>0&yenC<=nv&yenC>0 ) then
983                 gcf().info_message = _("Error in Column data addresses");
984                 break
985             end
986
987             xo=Value(min(xstR,xenR):max(xstR,xenR),min(xstC,xenC):max(xstC,xenC));
988             yo=Value(min(ystR,yenR):max(ystR,yenR),min(ystC,yenC):max(ystC,yenC));
989             [nx,mx]=size(xo);// adjusting the x and y size
990             [ny,my]=size(yo);
991             N=min(nx,ny);
992             xo=xo(1:N,:);
993             yo=yo(1:N,:);
994
995             xyo=[xo,yo];
996             [xyo]=cleandata(xyo)
997
998             tok=%t;
999             break,
1000         catch
1001             gcf().info_message = _("Scicos cannot read your Excel file. Please verify the parameters");
1002             break
1003         end
1004     end
1005
1006 endfunction
1007 //---------------------------------------------------------------
1008 function [xyo]=cleandata(xye)
1009     xe=xye(:,1)
1010     ye=xye(:,2)
1011
1012     [nx,mx]=size(xe);// adjusting the x and y size
1013     [ny,my]=size(ye);
1014     N=min(nx,ny);
1015     xe=xe(1:N,:);
1016     ye=ye(1:N,:);
1017
1018     // checking for NULL data
1019     for i=1:N
1020         if (xe(i)<>xe(i)) then
1021             gcf().info_message = msprintf(_("x contains no data:x(%d)"), i);
1022             return;
1023         end
1024         if (ye(i)<>ye(i)) then
1025             gcf().info_message = msprintf(_("Y contains no data:y(%d)"), i);
1026             return;
1027         end
1028     end
1029     zz=find(xe<0);
1030     xe(zz)=[];
1031     ye(zz)=[]
1032     if (find(xe==0)==[]) then // add zero point
1033         xe($+1)=0;
1034         ye($+1)=0;
1035     end
1036
1037     [xo,k2]=gsort(xe,"r","i");
1038     yo=ye(k2)
1039
1040     xyo=[xo,yo];
1041 endfunction
1042 //---------------------------------------------------------------
1043 function  [orpar,oipar] = AutoScale(a,xy,inipar,inrpar)
1044     drawlater();
1045     oipar = inipar
1046     orpar = inrpar
1047     points = a.children(2).children
1048     splines = a.children(1).children
1049     points.data = xy;
1050     splines.data = xy;
1051     [orpar,oipar] = drawSplin(a,xy,oipar,orpar);
1052     rectx=findrect(a);
1053     a.data_bounds = rectx;
1054     drawnow()
1055 endfunction
1056 //============================
1057 function METHOD = getmethod(order)
1058     select order
1059     case 0 then,
1060         METHOD="zero order"
1061     case 1 then,
1062         METHOD="linear"
1063     case 2 then,
1064         METHOD="order 2"
1065     case 3 then,
1066         METHOD="not_a_knot"
1067     case 4 then,
1068         METHOD="periodic"
1069     case 5 then,
1070         METHOD="monotone"
1071     case 6 then,
1072         METHOD="fast"
1073     case 7 then,
1074         METHOD="clamped"
1075     end
1076 endfunction
1077 //=======================================
1078 function [sok,xye] = ReadFromFile()
1079     xye=[];sok=%f;
1080     while %t
1081         [sok,filen,Cformat,Cx,Cy]=scicos_getvalue(_("Text data file "), ..
1082         _(["Filename";"Reading [C] format";"Abscissa column";"Output column"]), ..
1083         list("str",1,"str",1,"vec",1,"vec",1), ...
1084         list(["mydatafile.dat"],["%g %g"],["1"],["2"]));
1085         if ~sok then
1086             break,
1087         end
1088         px=strindex(Cformat,"%");
1089         NC=size(px,"*");
1090         if NC==[] then,
1091             gcf().info_message = _("Bad format in reading data file");
1092             sok=%f;
1093             break;
1094         end
1095         Lx=[];
1096         try
1097             fd=mopen(filen,"r");
1098             Lx=mfscanf(-1,fd,Cformat);
1099             mclose(fd);
1100         catch
1101             gcf().info_message = msprintf(_("Scicos cannot open the data file: %s"), filen);
1102             break;
1103         end
1104
1105         [nD,mD] = size(Lx);
1106         if ((mD==0) | (nD==0)) then,
1107             gcf().info_message = _("No data read");
1108             sok=%f;
1109             break;
1110         end
1111         if (mD<>NC) then,
1112             gcf().info_message = _("Bad format");
1113             sok=%f;
1114             break;
1115         end
1116
1117         xe=Lx(:,Cx);
1118         ye=Lx(:,Cy);
1119         xye=[xe,ye];
1120         [xye]=cleandata(xye)
1121         sok=%t;
1122         break,
1123     end
1124 endfunction
1125 //=======================================
1126 function [sok]=SaveToFile(xye)
1127     xe=xye(:,1)
1128     ye=xye(:,2)
1129     sok=%f;
1130     while %t
1131         [sok,filen,Cformat]=scicos_getvalue(_("Text data file"), ..
1132         _(["Filename";"Writing [C] format"]), list("str",1,"str",1), ...
1133         list(["mydatafile.dat"],["%g %g"]));
1134         if ~sok then
1135             break,
1136         end
1137         px=strindex(Cformat,"%");
1138         NC=size(px,"*");
1139         if NC<>2 then,
1140             gcf().info_message = _("Bad format in writing data file");
1141             sok=%f;
1142             break;
1143         end
1144
1145         Cformat=Cformat+"\n";
1146
1147         try
1148             fd=mopen(filen,"w");
1149             mfprintf(fd,Cformat,xe,ye);
1150             mclose(fd);
1151         catch
1152             gcf().info_message = msprintf(_("Scicos cannot open the data file: %s"),filen);
1153             break;
1154         end
1155
1156         sok=%t;
1157         break,
1158     end
1159 endfunction
1160 //=========================================================
1161 function [X,Y,orpar]=Do_Spline(N,order,x,y)
1162     X=[];
1163     Y=[];
1164     orpar=[];
1165
1166     METHOD=getmethod(order);
1167
1168     if (METHOD=="zero order") then
1169         X=x(1);
1170         Y=y(1);
1171         for i=1:N-1
1172             X=[X;x(i);x(i+1);x(i+1)];
1173             Y=[Y;y(i);y(i);y(i+1)];
1174         end
1175         return
1176     end
1177     //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1178     if (METHOD=="linear") then
1179         X=[];
1180         for i=1:N
1181             X=[X;x(i)];
1182             Y=[Y;y(i)];
1183         end
1184         return
1185     end
1186     //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1187     if (N<25) then
1188         NP=10;
1189     else
1190         if (N<50) then
1191             NP=5;
1192         else
1193             if (N<100) then
1194                 NP=2;
1195             else
1196                 if (N<200) then
1197                     NP=1;
1198                 else
1199                     NP=0;
1200                 end;
1201             end;
1202         end;
1203     end
1204     for i=1:N-1
1205         X=[X;linspace(x(i),x(i+1),NP+2)']; // pour tous sauf "linear" et "zero order"
1206     end
1207     //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1208     if (N>2) & (METHOD=="order 2") then
1209         Z=ORDER2(x,y);
1210         A=Z(1:N-1);
1211         B=Z(N:2*N-2);
1212         C=Z(2*N-1:3*N-3);
1213
1214         for j=1:size(X,"*")
1215             for i=N-1:-1:1
1216                 if X(j)>=x(i) then,
1217                     break;
1218                 end
1219             end
1220             Y(j)=A(i)*(X(j)-x(i))^2+B(i)*(X(j)-x(i))+C(i);
1221         end
1222         orpar=matrix(Z,-1,1)
1223     end
1224     //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1225     if (METHOD=="not_a_knot") then
1226         try
1227             d = splin(x, y, METHOD);
1228             Y = interp(X, x, y, d);
1229             orpar=d(:);
1230         catch
1231         err = msprintf(_("ERROR in SPLINE: %s"), METHOD);
1232         if gui then
1233         gcf().info_message = err; 
1234         else
1235         messagebox(lasterror(), err);
1236         end
1237         end
1238
1239     end
1240     //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1241     if (METHOD=="periodic") then
1242         if y(1)<>y(N) then
1243             y(N)=y(1)
1244         end
1245         try
1246             d = splin(x, y,METHOD);
1247             Y = interp(X, x, y, d);
1248             orpar=d(:);
1249         catch
1250         err = msprintf(_("ERROR in SPLINE: %s"), METHOD);
1251         if gui then
1252         gcf().info_message = err
1253         else
1254         messagebox(lasterror(), err);
1255         end
1256         end
1257     end
1258     //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1259     if (METHOD=="monotone" ) then
1260         try
1261             d = splin(x, y, METHOD);
1262             Y = interp(X, x, y, d);
1263             orpar=d(:);
1264         catch
1265         err = msprintf(_("ERROR in SPLINE: %s"), METHOD);
1266         if gui then
1267         gcf().info_message = err
1268         else
1269         messagebox(lasterror(), err);
1270         end
1271         end
1272     end
1273     //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1274     if (METHOD=="fast") then
1275         try
1276             d = splin(x, y, METHOD);
1277             Y = interp(X, x, y, d);
1278             orpar=d(:);
1279         catch
1280         err = msprintf(_("ERROR in SPLINE: %s"), METHOD);
1281         if gui then
1282         gcf().info_message = err
1283         else
1284         messagebox(lasterror(), err);
1285         end
1286         end
1287     end
1288     //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1289     if (METHOD=="clamped") then
1290         try
1291             d = splin(x, y, METHOD,[0;0]);
1292             Y = interp(X, x, y, d);
1293             orpar=d(:);
1294         catch
1295         err = msprintf(_("ERROR in SPLINE: %s"), METHOD);
1296         if gui then
1297         gcf().info_message = err
1298         else
1299         messagebox(lasterror(), err);
1300         end
1301         end
1302     end
1303
1304 endfunction
1305 //=================================================
1306 function [Z]=ORDER2(x,y)
1307     N=size(x,"*")-1;
1308     A=zeros(3*N-1,N*3);
1309     B=zeros(3*N-1,1);
1310     for i=1:N
1311         j=3*(i-1)+1;
1312         A(j,i+2*N)=1;
1313         B(j)=y(i);
1314         A(j+1,i)=(x(i+1)-x(i))^2;
1315         A(j+1,i+N)=x(i+1)-x(i);
1316         A(j+1,i+2*N)=1;
1317         B(j+1)=y(i+1);
1318     end
1319
1320     for i=1:N-1
1321         j=3*(i-1)+1;
1322         A(j+2,i)=2*(x(i+1)-x(i));
1323         A(j+2,i+N)=1;
1324         A(j+2,i+N+1)=-1;
1325     end
1326
1327     Q=zeros(3*N,3*N);
1328     for i=1:N
1329         Q(i,i)=4*(x(i+1)-x(i))^2
1330         Q(i,i+N)=2*(x(i+1)-x(i))
1331         Q(i+N,i)=2*(x(i+1)-x(i))
1332         Q(i+N,i+N)=1;
1333     end
1334
1335     At=[Q,A';A,zeros(3*N-1,3*N-1)]
1336     Bt=[zeros(3*N,1);B]
1337     Zt=At\Bt;
1338     Z=Zt(1:3*N,1)
1339 endfunction
1340 //===================================================