source: PSPA/madxPSPA/src/mad_match.c @ 447

Last change on this file since 447 was 430, checked in by touze, 11 years ago

import madx-5.01.00

File size: 37.3 KB
Line 
1#include "madx.h"
2#include <float.h>
3
4// private interface
5
6static void
7match_prepare_varypos(void)
8  /* keeps constraints from nodes, reexpands, adds constraints to nodes */
9{
10  struct node* node = current_sequ->ex_start;
11  struct constraint_list** tmplist = (struct constraint_list**)
12    mymalloc("match_prepare_varypos",current_sequ->n_nodes * sizeof(struct constraint_list*));
13  int i = 0;
14  while (node != NULL)
15  {
16    tmplist[i] = current_sequ->all_nodes[i]->cl; i++;
17    if (node == current_sequ->ex_end) break;
18    node = node->next;
19  }
20  expand_curr_sequ(0);
21  i = 0;
22  node = current_sequ->ex_start;
23  while (node != NULL)
24  {
25    current_sequ->all_nodes[i]->cl = tmplist[i]; i++;
26    if (node == current_sequ->ex_end) break;
27    node = node->next;
28  }
29  myfree("match_prepare_varypos", tmplist);
30}
31
32static void
33mtjacprint(int m, int n,double* jac,struct in_cmd* cmd)
34{
35  int i,j,k,l,t;
36  double *SV,*U,*VT;
37  double tmp;
38  char *knobfilename, *jacfilename;
39  FILE *knobfile=NULL, *jacfile=NULL;
40  k=0;
41  jacfilename=command_par_string("jacfile",cmd->clone);
42  knobfilename=command_par_string("knobfile",cmd->clone);
43  if (jacfilename) jacfile=fopen(jacfilename,"w");
44  fprintf(prt_file, "\n\nJACOBIAN:\n");
45  fprintf(prt_file, "%4s %16s %10s %20s\n","Node","Constraint","Variable","Derivative");
46  fprintf(prt_file, "---------------------------------------------------------------\n");
47  for(i=0;i<MAX_MATCH_MACRO;i++)
48  {
49    if (match2_macro_name[i]==NULL) break;
50    for(j=0;j<MAX_MATCH_CONS;j++)
51    {
52      if (match2_cons_name[i][j]==NULL) break;
53      if ( strcmp(match2_cons_name[i][j],"0")!=0 )
54        if (jacfilename)
55          fprintf(jacfile, "%16s:=%+20.10e",match2_cons_name[i][j],match2_cons_value[i][j]);
56      for(l=0;l<n;l++)
57      {
58        fprintf(prt_file, "%4s ",match2_macro_name[i]);
59        fprintf(prt_file, "%16s ",match2_cons_name[i][j]);
60        fprintf(prt_file, "%10s ",command_par_string("name",stored_match_var->commands[l]));
61        fprintf(prt_file, "%20.10e",jac[l*m+k]);
62        fprintf(prt_file, "\n");
63      if (jacfilename) if ( strcmp(match2_cons_name[i][j],"0")!=0 )
64        fprintf(jacfile, "%+20.10e*%16s",jac[l*m+k],
65                command_par_string("name",stored_match_var->commands[l]));
66      }
67      if (jacfilename) if ( strcmp(match2_cons_name[i][j],"0")!=0 )
68      fprintf(jacfile, ";\n");
69      k++;
70    }
71  }
72  if (jacfilename) fclose(jacfile);
73  fprintf(prt_file, "\n\nSINGULAR VALUE DECOMPOSITION:\n");
74  SV=(double *)mymalloc("match_match",(total_const+total_vars)*sizeof(double));
75  VT=(double *)mymalloc("match_match",(total_vars*total_vars)*sizeof(double));
76  U=(double *)mymalloc("match_match",(total_const*total_const)*sizeof(double));
77  mtsvd_(&total_const,&total_vars,jac,SV,U,VT);
78  k=0;
79  l=0;
80  fprintf(prt_file, "%-25s %12s %-34s\n",
81          "Variable vector","---> Sing. val.","* Node constraint vector");
82  fprintf(prt_file, "--------------------------------------------------------------------\n");
83  for(i=0;i<imax(n,m);i++){
84    for(j=0;j<imax(n,m);j++){
85      if ( (i<n)&&(j<n)) {
86        fprintf(prt_file, "%-12s",command_par_string("name",stored_match_var->commands[j]));
87        fprintf(prt_file, "%12.5g ",VT[j*n+i]);
88      }
89      else { fprintf(prt_file, "%24s",""); }
90
91      if ( (i<imin(n,m)) &&(j==0))   {
92        fprintf(prt_file, "%12.5g ",SV[i]);
93      }
94      else { fprintf(prt_file, "%12s ",""); }
95
96      if ( (i<m)&&(j<m) ) {
97        if (match2_cons_name[k][l]==NULL) {
98          k++;
99          l=0;
100        }
101        /*        fprintf(prt_file, "%i %i",k,l);*/
102        fprintf(prt_file, "%12.5g ",U[i*m+j]);
103        /*        fprintf(prt_file, "%10s ",match2_macro_name[k]);*/
104        fprintf(prt_file, "%10s ",match2_cons_name[k][l]);
105        l++;
106      }
107      else { fprintf(prt_file, "%22s",""); }
108      fprintf(prt_file, "\n");
109    }
110    l=0;
111    k=0;
112    fprintf(prt_file, "\n");
113    fprintf(prt_file, "\n");
114  }
115  /* Print knob file */
116  if (knobfilename) {
117    knobfile=fopen(knobfilename,"w");
118    k=0;
119    l=0;
120    for(i=0;i<n;i++){
121      k=0; l=0;
122      fprintf(knobfile, "%-12s := %+15.8e ",
123              command_par_string("name",stored_match_var->commands[i]),
124              get_variable(command_par_string("name",stored_match_var->commands[i])));
125      for(j=0;j<m;j++){
126        if (match2_cons_name[k][l]==NULL) { k++; l=0; }
127        /* Compute M-1=V SV-1 UT*/
128        /* M-1[i,j] = sum_t^min(m,n)   V[i,t]  / SV[t] * U[j,t] ) */
129        /*          = sum_t^min(m,n)  VT[t,i] / SV[t] * U[j,t]  ) */
130        /* in fortran M[i,j]=M[i+j*n] */
131        tmp=0;
132        for(t=0;t<imin(m,n);t++) {
133          if (SV[t]>jac_cond) { tmp+=VT[t+n*i]/SV[t]*U[j+t*m]; }
134          /*        fprintf(prt_file,"VT %d,%d,%12.5e ",t,i,VT[t+n*i]);*/
135          /*        fprintf(prt_file,"SV %d,%12.5e ",t,SV[t]);*/
136          /*        fprintf(prt_file,"U  %d,%d,%12.5e\n",j,t,U[j+t*m]);*/
137        }
138        /*      fprintf(prt_file,"M-1 %d,%d,%e \n",i,j,tmp);*/
139        if ( strcmp(match2_cons_name[k][l],"0")!=0 ) {
140          fprintf(knobfile, "%+15.8e*%s",tmp,match2_cons_name[k][l]);
141        };
142        l++;
143      }
144      fprintf(knobfile, ";\n");
145    }
146    fclose(knobfile);
147  }
148}
149
150static void
151match_action(struct in_cmd* cmd)
152{
153  int i;
154  int iseed, iprint;
155  int izero = 0;
156  int local_calls;
157  int local_call_lim;
158
159  if (match_is_on == kMatch_PTCknobs)
160  {
161    madx_mpk_run(cmd);
162    return;
163  }
164
165
166  if (stored_match_var->curr == 0)
167  {
168    warning("no vary command seen,","match command terminated");
169    match_is_on = 0;
170    set_option("match_is_on", &izero);
171    return;
172  }
173  total_vars = stored_match_var->curr;
174  penalty = zero;
175
176  match_calls = command_par_value("calls", cmd->clone);
177  match_tol = command_par_value("tolerance", cmd->clone);
178  fprintf(prt_file, "number of variables:    %d\n", total_vars);
179  fprintf(prt_file, "user given constraints: %d\n", comm_constraints->curr);
180  fprintf(prt_file, "total constraints:      %d\n\n", total_const);
181  vary_vect = new_double_array(total_vars);
182  vary_dvect = new_double_array(total_vars);
183  fun_vect = new_double_array(total_const);
184
185  current_call_lim += match_calls;
186
187  local_call_lim = command_par_value("calls", cmd->clone);
188  local_calls = 0;
189       
190  if (strcmp(cmd->tok_list->p[0], "lmdif") == 0 && total_vars > total_const)
191  {
192    print_match_summary = 0;
193    warning("number of variables larger than number of constraints:", "match command ignored");
194    return;
195  }
196  else if (strcmp(cmd->tok_list->p[0], "lmdif") == 0 && total_vars <= total_const)
197  {
198    print_match_summary = 1;
199    match_work[0] = new_double_array(total_vars);
200    match_work[1] = new_double_array(total_vars*total_const);
201    match_work[2] = new_double_array(total_vars);
202    match_work[3] = new_double_array(total_vars);
203    match_work[4] = new_double_array(total_vars);
204    match_work[5] = new_double_array(total_vars);
205    match_work[6] = new_double_array(total_vars);
206    match_work[7] = new_double_array(total_const);
207    match_work[8] = new_double_array(total_const);
208    match_work[9] = new_double_array(total_vars);
209    fprintf(prt_file, "START LMDIF:\n\n");
210    mtlmdf_(&total_const, &total_vars,
211            &match_tol, &local_calls, &local_call_lim,
212            vary_vect->a, vary_dvect->a, fun_vect->a, match_work[0]->a,
213            match_work[1]->a, match_work[2]->a, match_work[3]->a,
214            match_work[4]->a, match_work[5]->a, match_work[6]->a,
215            match_work[7]->a,match_work[9]->a);
216  }
217  else if (strcmp(cmd->tok_list->p[0], "jacobian") == 0)
218  {
219    print_match_summary = 0;
220       
221    jac_strategy = command_par_value("strategy", cmd->clone);
222    jac_cool = command_par_value("cool", cmd->clone);
223    jac_repeat = command_par_value("repeat", cmd->clone);
224    jac_balance = command_par_value("balance", cmd->clone);
225    jac_random = command_par_value("random", cmd->clone);
226    jac_bisec = command_par_value("bisec", cmd->clone);
227    jac_cond = command_par_value("cond", cmd->clone);
228    match_work[0] = new_double_array(total_vars*total_const);
229    match_work[1] = new_double_array(total_const);
230    match_work[2] = new_double_array(total_const);
231    match_work[3] = new_double_array(total_vars);
232    match_work[4] = new_double_array(total_vars);
233    fprintf(prt_file, "START JACOBIAN:\n\n");
234    mtjac_(&total_const, &total_vars,
235           &jac_strategy, &jac_cool,&jac_balance, &jac_random,
236           &jac_repeat,&jac_bisec,&jac_cond,&match_is_on,
237           &match_tol, &local_calls, &local_call_lim,
238           vary_vect->a, vary_dvect->a, fun_vect->a,
239           match_work[0]->a,match_work[1]->a,match_work[2]->a,
240           match_work[3]->a,match_work[4]->a);
241/*    if (jac_strategy==2 && match_is_on==2) {*/
242    if (jac_strategy==2) {
243      mtjacprint(total_const,total_vars,match_work[0]->a,cmd);
244    }
245  }
246  else if (strcmp(cmd->tok_list->p[0], "migrad") == 0 && total_vars <= total_const)
247  {
248    print_match_summary = 1;
249    mig_strategy = command_par_value("strategy", cmd->clone);
250    match_work[0] = new_double_array(total_vars*total_vars);
251    match_work[1] = new_double_array(7*total_vars);
252    match_work[2] = new_double_array(total_vars);
253    match_work[3] = new_double_array(total_vars);
254    match_work[4] = new_double_array(total_vars);
255    match_work[5] = new_double_array(total_vars*total_vars);
256    match_work[6] = new_double_array(total_vars);
257    match_work[7] = new_double_array(total_vars);
258    fprintf(prt_file, "START MIGRAD:\n\n");
259    mtmigr_(&total_const, &total_vars, &mig_strategy,
260            &match_tol, &local_calls, &local_call_lim,
261            vary_vect->a, vary_dvect->a, fun_vect->a,
262            match_work[0]->a, match_work[1]->a, match_work[2]->a,
263            match_work[3]->a, match_work[4]->a, match_work[5]->a,
264            match_work[6]->a, match_work[7]->a);
265  }
266  else if (strcmp(cmd->tok_list->p[0], "simplex") == 0)
267  {
268    print_match_summary = 1;
269    match_work[0] = new_double_array(total_vars*(total_vars+1));
270    match_work[1] = new_double_array(total_vars+1);
271    match_work[2] = new_double_array(4*total_vars);
272    fprintf(prt_file, "START SIMPLEX:\n\n");
273    mtsimp_(&total_const, &total_vars,
274            &match_tol, &local_calls, &local_call_lim,
275            vary_vect->a, vary_dvect->a, fun_vect->a,
276            match_work[0]->a, match_work[1]->a, match_work[2]->a);
277  }
278  else if (strcmp(cmd->tok_list->p[0], "siman") == 0)
279  {
280    print_match_summary = 1;
281    iseed = 1;
282    iprint = 0;
283    match_work[0] = new_double_array(total_vars+1);
284    match_i_work[1] = new_int_array(total_vars+1);
285    match_work[2] = new_double_array(total_vars+1);
286    match_work[3] = new_double_array(total_vars+1);
287    match_work[4] = new_double_array(total_vars+1);
288    match_work[5] = new_double_array(total_vars+1);
289    match_work[6] = new_double_array(total_vars+1);
290    fprintf(prt_file, "START SIMAN:\n\n");
291    mtsa_(&total_const, &total_vars,
292          &match_tol, &local_calls, &local_call_lim,
293          vary_vect->a, fun_vect->a,&iseed,&iprint,
294          match_work[0]->a, match_i_work[1]->i, match_work[2]->a,
295          match_work[3]->a, match_work[4]->a, match_work[5]->a,
296          match_work[6]->a);
297  }
298  for (i = 0; i < MATCH_WORK; i++)
299    match_work[i] = delete_double_array(match_work[i]);
300}
301
302#if 0 // not used...
303static void
304match_cell(struct in_cmd* cmd)
305{
306  (void)cmd;
307}
308#endif
309
310static void
311match_constraint(struct in_cmd* cmd)
312{
313  char* name;
314  struct command_parameter* cp;
315  struct name_list* nl = cmd->clone->par_names;
316  struct command_parameter_list* pl = cmd->clone->par;
317  struct sequence* sequ;
318  struct node* nodes[2];
319  struct node* c_node;
320  int pos, n, low, up; // , k // not used
321
322  if(match_is_on==2)
323  {
324    match2_constraint(cmd);
325  }
326  else if (match_is_on == kMatch_PTCknobs)
327  {
328    madx_mpk_addconstraint(in->buffers[in->curr]->c_a->c);
329  }
330  else
331  { /* old match */
332    pos = name_list_pos("sequence", nl);
333    if(nl->inform[pos]) { /* sequence specified */
334      cp = cmd->clone->par->parameters[pos];
335      for (n = 0; n < match_sequs->curr; n++)
336        if (strcmp(cp->string, match_sequs->sequs[n]->name) == 0)
337          break;
338
339      if (n == match_sequs->curr) {
340        warning(cp->string," :sequence not selected by MATCH, skipped");
341        return;
342      }
343
344      low = up = n;
345    }
346    else {
347      low = 0; up = match_sequs->curr - 1;
348    }
349
350    for (n = low; n <= up; n++) {
351      sequ = match_sequs->sequs[n];
352      pos = name_list_pos("range", nl);
353      if (pos > -1 && nl->inform[pos]) { /* parameter has been read */
354        name = pl->parameters[pos]->string;
355        if (get_ex_range(name, sequ, nodes) == 0)  return; // (k = not used
356      }
357      else {
358        nodes[0] = sequ->ex_start; nodes[1] = sequ->ex_end;
359      }
360      c_node = nodes[0];
361      comm_constraints->curr=0;
362      fill_constraint_list(1, cmd->clone, comm_constraints);
363
364      while (c_node)
365      {
366        if (pass_select(c_node->p_elem->name, cmd->clone) != 0)
367          update_node_constraints(c_node, comm_constraints);
368        if (c_node == nodes[1]) break;
369        c_node = c_node->next;
370      }
371    }
372  }
373}
374
375static void
376match_couple(struct in_cmd* cmd)
377{
378  (void)cmd;
379}
380
381static void
382match_end(struct in_cmd* cmd)
383{
384  int i;
385  struct node* c_node;
386  int izero = 0;
387  if (fun_vect == NULL )
388  {
389    fprintf(prt_file, "WARNING: No matching method selected.\n");
390    return;
391  }
392
393 
394  if (match_is_on==kMatch_UseMacro) {
395    match2_end(cmd);
396    return;
397  }
398
399  if (match_is_on == kMatch_PTCknobs) {
400    madx_mpk_end();
401    return;
402  }
403
404  /* write out all final constraint values and vary parameters */
405  penalty = zero;
406  if (get_option("varylength") != zero) match_prepare_varypos();
407  pro_twiss();
408  current_const = 0;
409  fprintf(prt_file, "\n");
410  fprintf(prt_file, "MATCH SUMMARY\n\n");
411  fprintf(prt_file, "Node_Name                  Constraint   Type  Target Value       Final Value        Penalty\n");
412  fprintf(prt_file, "--------------------------------------------------------------------------------------------------\n");
413  print_match_summary = 1;
414  set_option("match_summary", &print_match_summary);
415  for (i = 0; i < match_num_seqs; i++)
416  {
417    current_twiss = local_twiss[i]->clone;
418    pro_twiss();
419    if (twiss_success && print_match_summary == 1)
420    {
421      collect_(&current_const, &penalty, fun_vect->a);
422    }
423  }
424  fprintf(prt_file, "\n\n");
425
426  fprintf(prt_file, "Final Penalty Function = %16.8e\n\n",penalty);
427
428
429
430  fprintf(prt_file, "\n\n");
431/*  fprintf(prt_file, "Variable                   Final Value        Lower Limit        Upper Limit\n");*/
432/*  fprintf(prt_file, "-------------------------------------------------------------------------------\n");*/
433/*  if ((print_match_summary == 1) && vary_vect )*/
434/*  {*/
435/*    |+ drop first int* passed variable mtgetc_(&stored_match_var->curr, vary_vect->a, vary_dvect->a); +|*/
436/*    mtgetc_(vary_vect->a, vary_dvect->a); |+ mtgeti->mtgetc +|*/
437/*  }*/
438/*  fprintf(prt_file, "\n");*/
439  match2_print_var(cmd);
440  fprintf(prt_file, "END MATCH SUMMARY\n\n");
441  print_match_summary = 0;
442  set_option("match_summary", &print_match_summary);
443  i = 0; set_option("match_local", &i); /* flag */
444  /* End summary of matching job */
445
446  for (i = 0; i < match_num_seqs; i++)
447  {
448    c_node = match_sequs->sequs[i]->ex_start;
449    while(c_node != NULL) /* drop all constraint lists at nodes */
450    {
451      if (c_node->cl) c_node->cl = delete_constraint_list(c_node->cl);
452      if (c_node == match_sequs->sequs[i]->ex_end) break;
453      c_node = c_node->next;
454    }
455  }
456  current_gweight = delete_command(current_gweight);
457  current_weight = delete_command(current_weight);
458  for (i = 0; i < comm_constraints->curr; i++)
459    delete_constraint(comm_constraints->constraints[i]);
460  for (i = 0; i < sequences->curr; i++)
461  {
462    if (sequences->sequs[i]->cl != NULL)  sequences->sequs[i]->cl
463                                            = delete_constraint_list(sequences->sequs[i]->cl);
464  }
465  vary_vect = delete_double_array(vary_vect);
466  vary_dvect = delete_double_array(vary_dvect);
467  fun_vect = delete_double_array(fun_vect);
468  comm_constraints->curr = 0;
469  stored_match_var = delete_command_list(stored_match_var);
470  for (i = 0; i < match_num_seqs; i++) if (local_twiss[i])
471  {
472    if (local_twiss[i]->clone) delete_command(local_twiss[i]->clone);
473    local_twiss[i] = delete_in_cmd(local_twiss[i]);
474  }
475  vary_cnt = 0;
476  match_is_on = 0;
477  set_option("match_is_on", &izero);
478  match_sequs->curr = 0;
479  current_call_lim = 0;
480  current_calls = 0;
481  total_const = 0;
482  set_option("twiss_print", &keep_tw_print);
483
484
485  fprintf(prt_file, "VARIABLE \"TAR\" SET TO %16.8e\n",penalty);
486/*  sprintf(assign_cmd,"tar= %16.8e ;",penalty);*/
487/*  pro_input(assign_cmd);*/
488  set_variable("tar",&penalty);
489}
490
491static void
492match_fix(struct in_cmd* cmd)
493{
494  (void)cmd;
495}
496
497static void
498match_global(struct in_cmd* cmd)
499{
500  struct command_parameter* cp;
501  struct name_list* nl = cmd->clone->par_names;
502  struct sequence* sequ;
503  int pos, n, low, up;
504  pos = name_list_pos("sequence", nl);
505  if(nl->inform[pos]) /* sequence specified */
506  {
507    cp = cmd->clone->par->parameters[pos];
508    for (n = 0; n < match_sequs->curr; n++)
509    {
510      if (strcmp(cp->string, match_sequs->sequs[n]->name) == 0) break;
511    }
512    if (n == match_sequs->curr)
513    {
514      warning(cp->string," :sequence not selected by MATCH, skipped");
515      return;
516    }
517    low = up = n;
518  }
519  else
520  {
521    low = 0; up = match_sequs->curr - 1;
522  }
523  for (n = low; n <= up; n++)
524  {
525    sequ = match_sequs->sequs[n];
526    if (sequ->cl == NULL) sequ->cl = new_constraint_list(10);
527    comm_constraints->curr=0;
528    fill_constraint_list(2, cmd->clone, comm_constraints);
529    update_sequ_constraints(sequ, comm_constraints);
530  }
531  print_match_summary = 1;
532}
533
534static void
535match_gweight(struct in_cmd* cmd)
536{
537  struct name_list* nl = cmd->clone->par_names;
538  struct command_parameter_list* plc = cmd->clone->par;
539  struct command_parameter_list* pl = current_gweight->par;
540  int j;
541
542  (void)cmd;
543  for (j = 0; j < pl->curr; j++)
544  {
545    if (nl->inform[j])
546    {
547      pl->parameters[j]->double_value = plc->parameters[j]->double_value;
548      pl->parameters[j]->expr = plc->parameters[j]->expr;
549    }
550  }
551}
552
553static void
554match_level(struct in_cmd* cmd)
555{
556  (void)cmd;
557}
558
559static void
560match_match(struct in_cmd* cmd)
561{
562  struct name_list* tnl; /* local name list for TWISS input definition */
563  double match_beta_value;
564  struct command* comm;
565  struct command_parameter* cp;
566  struct name_list* nl = cmd->clone->par_names;
567  struct command_parameter_list* pl = cmd->clone->par;
568  struct sequence* sequ;
569  int i, j, pos, n, spos, tpos, chrom_flg;
570  int izero = 0, ione = 1, slow;
571  char *dpp;
572
573  if (match_is_on)
574  {
575    warning("already inside match:", "ignored");
576    return;
577  }
578  set_option("match_is_on", &ione);
579  keep_tw_print = get_option("twiss_print");
580  set_option("twiss_print", &izero);
581
582  pos=name_list_pos("use_macro", nl);
583  if(nl->inform[pos]) {
584    match2_match(cmd);
585    return;
586  }
587
588  pos=name_list_pos("use_ptcknob", nl);
589  if(nl->inform[pos]) {
590    match_is_on = kMatch_PTCknobs;
591    madx_mpk_prepare();
592    return;
593  }
594
595  match_is_on = 1;
596  pos = name_list_pos("sequence", nl);
597  fprintf(prt_file, "START MATCHING\n\n");
598  if(nl->inform[pos]) /* sequence specified */
599  {
600    cp = cmd->clone->par->parameters[pos];
601    if ((n = cp->m_string->curr) > match_sequs->max)
602    {
603      warning("excess sequence names", "skipped");
604      n =  match_sequs->max;
605    }
606    for (i = 0; i < n; i++)
607    {
608      if ((pos = name_list_pos(cp->m_string->p[i], sequences->list)) < 0)
609        warning("unknown sequence", "skipped");
610      else
611      {
612        if ((sequ = sequences->sequs[pos]) == NULL
613            || sequ->ex_start == NULL)
614        {
615          warning(sequ->name," :sequence not active, match killed");
616          match_is_on = 0;
617          return;
618        }
619        match_sequs->sequs[match_sequs->curr++] = sequ;
620      }
621    }
622    if (match_sequs->curr == 0)
623    {
624      warning("no active sequence,","match killed");
625      match_is_on = 0;
626      return;
627    }
628  }
629  else match_sequs->sequs[match_sequs->curr++] = current_sequ;
630  pos = name_list_pos("vlength", nl);
631  if(nl->inform[pos]) i = pl->parameters[pos]->double_value;
632  else i = 0;
633  set_option("varylength", &i);
634
635  /* START SLOW-CHECK */
636  pos = name_list_pos("slow", nl);
637  if(nl->inform[pos]) slow = pl->parameters[pos]->double_value;
638  else slow = 0;
639  set_option("slow_match", &slow);
640  /* END SLOW-CHECK */
641
642  /* START CHK-SEQ */
643  current_match = cmd->clone;
644  pos = name_list_pos("sequence", nl);
645  if(nl->inform[pos]) /* sequence specified */
646  {
647    cp = cmd->clone->par->parameters[pos];
648    match_num_seqs = cp->m_string->curr;
649    fprintf(prt_file, "number of sequences: %d\n", match_num_seqs);
650    for (i = 0; i < match_num_seqs; i++)
651    {
652      match_seqs[i] = buffer(cp->m_string->p[i]);
653      /* check if the specified sequence is defined */
654      if ((pos = name_list_pos(match_seqs[i], sequences->list)) > -1)
655      {
656        current_sequ = sequences->sequs[pos];
657        fprintf(prt_file, "sequence name: %s\n", current_sequ->name);
658
659        /* START defining a TWISS input command for each sequence */
660        local_twiss[i] = new_in_cmd(10);
661        local_twiss[i]->type = 0;
662        local_twiss[i]->clone = local_twiss[i]->cmd_def
663          = clone_command(find_command("twiss", defined_commands));
664        tnl = local_twiss[i]->cmd_def->par_names;
665        tpos = name_list_pos("sequence", tnl);
666        local_twiss[i]->cmd_def->par->parameters[tpos]->string = match_seqs[i];
667        local_twiss[i]->cmd_def->par_names->inform[tpos] = 1;
668        if (slow)
669          {
670           tpos = name_list_pos("save", tnl);
671           local_twiss[i]->cmd_def->par->parameters[tpos]->string = NULL;
672           local_twiss[i]->cmd_def->par_names->inform[tpos] = 1;
673          }
674        /* END defining a TWISS input command for each sequence */
675      }
676      else
677      {
678        warning("unknown sequence ignored:", match_seqs[i]);
679        return;
680      }
681    }
682  }
683  else
684  {
685    /* START defining a TWISS input command for default sequence */
686    match_num_seqs = 1;
687    local_twiss[0] = new_in_cmd(10);
688    local_twiss[0]->type = 0;
689    local_twiss[0]->clone = local_twiss[0]->cmd_def
690      = clone_command(find_command("twiss", defined_commands));
691    tnl = local_twiss[0]->cmd_def->par_names;
692    tpos = name_list_pos("sequence", tnl);
693    local_twiss[0]->cmd_def->par->parameters[tpos]->string = current_sequ->name;
694    local_twiss[0]->cmd_def->par_names->inform[tpos] = 1;
695    if (slow)
696      {
697       tpos = name_list_pos("save", tnl);
698       local_twiss[0]->cmd_def->par->parameters[tpos]->string = NULL;
699       local_twiss[0]->cmd_def->par_names->inform[tpos] = 1;
700      }
701     /* END defining a TWISS input command for default sequence */
702  }
703  if (current_sequ == NULL || current_sequ->ex_start == NULL)
704  {
705    warning("MATCH called without active sequence,", "ignored");
706    return;
707  }
708  /* END CHK-SEQ */
709
710  for (i = 0; i < match_num_seqs; i++)
711  {
712    for (j = 0; j < local_twiss[i]->cmd_def->par->curr; j++)
713    {
714      tnl = local_twiss[i]->cmd_def->par_names;
715      tpos = name_list_pos("sequence", tnl);
716      if (slow) spos = name_list_pos("save", tnl);
717      else      spos = -1;
718      if (j != tpos  && j != spos) 
719      local_twiss[i]->cmd_def->par_names->inform[j] = 0;
720    }
721  }
722
723  /* START CHK-BETA-INPUT */
724  /* START CHK-BETA0 */
725  pos = name_list_pos("beta0", nl);
726  if(nl->inform[pos]) /* beta0 specified */
727  {
728    cp = cmd->clone->par->parameters[pos];
729    match_num_beta = cp->m_string->curr;
730    fprintf(prt_file, "number of beta0s: %d\n", match_num_beta);
731    for (i = 0; i < match_num_beta; i++)
732    {
733      match_beta[i] = buffer(cp->m_string->p[i]);
734      fprintf(prt_file, "BETA0 name: %s\n", match_beta[i]);
735      /* START defining a TWISS input command for each sequence */
736      tnl = local_twiss[i]->cmd_def->par_names;
737      tpos = name_list_pos("beta0", tnl);
738      local_twiss[i]->cmd_def->par_names->inform[tpos] = 1;
739      local_twiss[i]->cmd_def->par->parameters[tpos]->string = match_beta[i];
740      /* END defining a TWISS input command for each sequence */
741    }
742  }
743  /* END CHK-BETA0 */
744
745  /* START CHK-RANGE */
746  pos = name_list_pos("range", nl);
747  if(nl->inform[pos]) /* range specified */
748  {
749    cp = cmd->clone->par->parameters[pos];
750    match_num_range = cp->m_string->curr;
751    for (i = 0; i < match_num_range; i++)
752    {
753      match_range[i] = buffer(cp->m_string->p[i]);
754      /* START adding range to TWISS input command for each sequence */
755      tnl = local_twiss[i]->cmd_def->par_names;
756      tpos = name_list_pos("range", tnl);
757      local_twiss[i]->cmd_def->par_names->inform[tpos] = 1;
758      local_twiss[i]->cmd_def->par->parameters[tpos]->string
759        = match_range[i];
760      /* END adding range to TWISS input command for each sequence */
761    }
762  }
763  /* END CHK-RANGE */
764
765  /* START CHK-USEORBIT */
766  pos = name_list_pos("useorbit", nl);
767  if(nl->inform[pos]) /* useorbit specified */
768  {
769    cp = cmd->clone->par->parameters[pos];
770    for (i = 0; i < cp->m_string->curr; i++)
771    {
772      /* START adding useorbit to TWISS input command for each sequence */
773      tnl = local_twiss[i]->cmd_def->par_names;
774      tpos = name_list_pos("useorbit", tnl);
775      local_twiss[i]->cmd_def->par_names->inform[tpos] = 1;
776      local_twiss[i]->cmd_def->par->parameters[tpos]->string
777        = buffer(cp->m_string->p[i]);
778      /* END adding range to TWISS input command for each sequence */
779    }
780  }
781  /* END CHK-USEORBIT */
782
783  /* START CHK-KEEPORBIT */
784  pos = name_list_pos("keeporbit", nl);
785  if(nl->inform[pos]) /* keeporbit specified */
786  {
787    cp = cmd->clone->par->parameters[pos];
788    for (i = 0; i < cp->m_string->curr; i++)
789    {
790      /* START adding keeporbit to TWISS input command for each sequence */
791      tnl = local_twiss[i]->cmd_def->par_names;
792      tpos = name_list_pos("keeporbit", tnl);
793      local_twiss[i]->cmd_def->par_names->inform[tpos] = 1;
794      local_twiss[i]->cmd_def->par->parameters[tpos]->string
795        = buffer(cp->m_string->p[i]);
796      /* END adding range to TWISS input command for each sequence */
797    }
798  }
799  /* END CHK-KEEPORBIT */
800
801  /* START CHK-R-MATRIX */
802  pos = name_list_pos("rmatrix", nl);
803  if(nl->inform[pos]) /* rmatrix specified */
804  {
805    cp = cmd->clone->par->parameters[pos];
806    for (i = 0; i < match_num_seqs; i++)
807    {
808      /* START adding rmatrix to TWISS input command for each sequence */
809      tnl = local_twiss[i]->cmd_def->par_names;
810      tpos = name_list_pos("rmatrix", tnl);
811      local_twiss[i]->cmd_def->par_names->inform[tpos] = 1;
812      local_twiss[i]->cmd_def->par->parameters[tpos]->double_value
813        = 1;
814      /* END adding rmatrix to TWISS input command for each sequence */
815    }
816  }
817  /* END CHK-R-MATRIX */
818
819  /* START CHK-CHROM */
820  pos = name_list_pos("chrom", nl);
821  chrom_flg = cmd->clone->par->parameters[pos]->double_value;
822  if(chrom_flg) /* chrom specified */
823  {
824    for (i = 0; i < match_num_seqs; i++)
825    {
826      /* START adding chrom to TWISS input command for each sequence */
827      tnl = local_twiss[i]->cmd_def->par_names;
828      tpos = name_list_pos("chrom", tnl);
829      local_twiss[i]->cmd_def->par_names->inform[tpos] = 1;
830      local_twiss[i]->cmd_def->par->parameters[tpos]->double_value
831        = 1;
832      set_option("twiss_chrom",&ione);
833      /* END adding chrom to TWISS input command for each sequence */
834    }
835  }
836  else set_option("twiss_chrom",&izero);
837  /* END CHK-CHROM */
838
839  /* START CHK-SECTORMAP */
840  pos = name_list_pos("sectormap", nl);
841  if(nl->inform[pos]) /* sectormap specified */
842  {
843    cp = cmd->clone->par->parameters[pos];
844    for (i = 0; i < match_num_seqs; i++)
845    {
846      /* START adding sectormap to TWISS input command for each sequence */
847      tnl = local_twiss[i]->cmd_def->par_names;
848      tpos = name_list_pos("sectormap", tnl);
849      local_twiss[i]->cmd_def->par_names->inform[tpos] = 1;
850      local_twiss[i]->cmd_def->par->parameters[tpos]->double_value
851        = 1;
852      /* END adding sectormap to TWISS input command for each sequence */
853    }
854  }
855  /* END CHK-CHROM */
856
857  /* START CHK-DELTAP */
858  pos = name_list_pos("deltap", nl);
859  if(nl->inform[pos]) /* deltap specified */
860  {
861    cp = cmd->clone->par->parameters[pos];
862    for (i = 0; i < match_num_seqs; i++)
863    {
864      /* START adding deltap to TWISS input command for each sequence */
865      tnl = local_twiss[i]->cmd_def->par_names;
866      tpos = name_list_pos("deltap", tnl);
867      local_twiss[i]->cmd_def->par_names->inform[tpos] = 1;
868      dpp=mymalloc("match_match",20);
869      sprintf(dpp,"%e",cp->double_array->a[0]);
870      local_twiss[i]->cmd_def->par->parameters[tpos]->string
871        = dpp;
872      /*       END adding deltap to TWISS input command for each sequence */
873      /*      fprintf(prt_file, "entry value: %f\n", cp->double_array->a[0]);*/
874      /*      twiss_deltas->curr=1;*/
875      /*      twiss_deltas->a[0]=cp->double_array->a[0];*/
876    }
877  }
878  /* END CHK-DELTAP */
879
880  /* START CHK-ENTRIES of TYPE DOUBLE-REAL */
881  for (j = 0; j < nl->curr; j++)
882  {
883    if(nl->inform[j]) /* initial conditions are specified
884                         at the match command level */
885    {
886      cp = cmd->clone->par->parameters[j];
887      match_num_beta = 0;
888      if(cp->type == 2)
889      {
890        match_num_beta = 1;
891      }
892      if(cp->type == 12)
893      {
894        match_num_beta = cp->double_array->curr;
895      }
896      if(match_num_beta > 0)
897      {
898        fprintf(prt_file, "entry name: %s\n", cmd->clone->par_names->names[j]);
899        fprintf(prt_file, "number of entries: %d\n", match_num_beta);
900      }
901      for (i = 0; i < match_num_beta; i++)
902      {
903        /* START defining a TWISS input command for each sequence */
904        match_beta_value = cp->double_array->a[i];
905        fprintf(prt_file, "entry value: %f\n", match_beta_value);
906        tnl = local_twiss[i]->cmd_def->par_names;
907        tpos = name_list_pos(cmd->clone->par_names->names[j], tnl);
908        local_twiss[i]->cmd_def->par_names->inform[tpos] = 1;
909        local_twiss[i]->cmd_def->par->parameters[tpos]->double_value
910          = cp->double_array->a[i];
911        /*        fprintf(prt_file, "entry value: %f %f\n", match_beta_value, cp->double_array->a[i]);*/
912        /* END defining a TWISS input command for each sequence */
913      }
914    }
915  }
916  /* END CHK-ENTRIES of TYPE DOUBLE-REAL */
917  /* END CHK-BETA-INPUT */
918
919  /* START generating a TWISS table via 'pro_twiss' */
920  for (i = 0; i < match_num_seqs; i++)
921  {
922    /* fprintf(prt_file, "%s %s\n", "call TWISS from MATCH: sequence =",
923       match_sequs->sequs[i]->name); */
924    current_twiss = local_twiss[i]->clone;
925    pro_twiss();
926  }
927  /* END generating a TWISS table via 'pro_twiss' */
928
929  /* for (i = 0; i < match_sequs->curr; i++)
930     puts(match_sequs->sequs[i]->name); */
931  if ((comm = find_command("weight", defined_commands)) != NULL)
932    current_weight = clone_command(comm);
933  else fatal_error("no weight command in dictionary,","good bye");
934  if ((comm = find_command("gweight", defined_commands)) != NULL)
935    current_gweight = clone_command(comm);
936  else fatal_error("no gweight command in dictionary,","good bye");
937
938}
939
940static void
941match_rmatrix(struct in_cmd* cmd)
942{
943  (void)cmd;
944}
945
946static void
947match_tmatrix(struct in_cmd* cmd)
948{
949  (void)cmd;
950}
951
952static void
953match_vary(struct in_cmd* cmd)
954{
955  int pos;
956  double value;
957  struct name_list* nl = cmd->clone->par_names;
958  struct command_parameter_list* pl = cmd->clone->par;
959
960  if (stored_match_var == NULL) stored_match_var = new_command_list("vary", 100);
961  pos = name_list_pos("name", nl);
962  if (nl->inform[pos])
963  {
964    value=get_variable(pl->parameters[pos]->string);
965    set_value("vary","init",&value);
966    cmd->clone_flag = 1;
967    add_to_command_list(pl->parameters[pos]->string,
968                        cmd->clone, stored_match_var, 1);
969  }
970}
971
972static void
973match_weight(struct in_cmd* cmd)
974{
975  struct name_list* nl = cmd->clone->par_names;
976  struct command_parameter_list* plc = cmd->clone->par;
977  struct command_parameter_list* pl = current_weight->par;
978  int j;
979  for (j = 0; j < pl->curr; j++)
980  {
981    if (nl->inform[j])
982    {
983      pl->parameters[j]->double_value = plc->parameters[j]->double_value;
984      pl->parameters[j]->expr = plc->parameters[j]->expr;
985    }
986  }
987}
988
989// public interface
990
991void
992pro_match(struct in_cmd* cmd)
993  /* controls the matching module */
994{
995  /* changed the sequence of if statements so that MAD
996     can go through the whole matching sequence */
997
998  if (strcmp(cmd->tok_list->p[0], "match") == 0)
999  {
1000    match_match(cmd);
1001  }
1002  else if (strcmp(cmd->tok_list->p[0], "cell") == 0)
1003  {
1004    warning("CELL command no longer valid, ","use MATCH");
1005    return;
1006  }
1007  else if (match_is_on == 0)
1008  {
1009    warning("no MATCH command seen,","ignored");
1010    return;
1011  }
1012  else if (strcmp(cmd->tok_list->p[0], "endmatch") == 0)
1013  {
1014    match_end(cmd);
1015  }
1016  else if (strcmp(cmd->tok_list->p[0], "migrad") == 0 ||
1017           strcmp(cmd->tok_list->p[0], "lmdif") == 0 ||
1018           strcmp(cmd->tok_list->p[0], "jacobian") == 0 ||
1019           strcmp(cmd->tok_list->p[0], "simplex") == 0)
1020  {
1021    match_action(cmd);
1022  }
1023  else if (strcmp(cmd->tok_list->p[0], "constraint") == 0)
1024  {
1025    match_constraint(cmd);
1026  }
1027  else if (strcmp(cmd->tok_list->p[0], "couple") == 0)
1028  {
1029    match_couple(cmd);
1030  }
1031  else if (strcmp(cmd->tok_list->p[0], "fix") == 0)
1032  {
1033    match_fix(cmd);
1034  }
1035  else if (strcmp(cmd->tok_list->p[0], "global") == 0)
1036  {
1037    match_global(cmd);
1038  }
1039  else if (strcmp(cmd->tok_list->p[0], "level") == 0)
1040  {
1041    match_level(cmd);
1042  }
1043  else if (strcmp(cmd->tok_list->p[0], "vary") == 0)
1044  {
1045    match_vary(cmd);
1046  }
1047  else if (strcmp(cmd->tok_list->p[0], "weight") == 0)
1048  {
1049    match_weight(cmd);
1050  }
1051  else if (strcmp(cmd->tok_list->p[0], "gweight") == 0)
1052  {
1053    match_gweight(cmd);
1054  }
1055  else if (strcmp(cmd->tok_list->p[0], "rmatrix") == 0)
1056  {
1057    match_rmatrix(cmd);
1058  }
1059  else if (strcmp(cmd->tok_list->p[0], "tmatrix") == 0)
1060  {
1061    match_tmatrix(cmd);
1062  }
1063  else if (strcmp(cmd->tok_list->p[0], "global") == 0)
1064  {
1065    match_global(cmd);
1066  }
1067  else if (strcmp(cmd->tok_list->p[0], "use_macro") == 0)
1068  {
1069    match2_macro(cmd);
1070  }
1071}
1072
1073int
1074next_vary(char* name, int* name_l, double* lower, double* upper, double* step, int* slope, double* opt)
1075  /* returns the next variable to be varied during match;
1076     0 = none, else count */
1077{
1078  int i, pos, ncp, nbl, len;
1079  double l_step;
1080  char* v_name;
1081  struct name_list* nl;
1082  struct command* comm;
1083  struct command_parameter_list* pl;
1084  if (vary_cnt == stored_match_var->curr)
1085  {
1086    vary_cnt = 0; return 0;
1087  }
1088  comm = stored_match_var->commands[vary_cnt];
1089  nl = comm->par_names;
1090  pl = comm->par;
1091  pos = name_list_pos("name", nl);
1092  v_name = pl->parameters[pos]->string;
1093  len = strlen(v_name);
1094  ncp = len < *name_l ? len : *name_l; // min(len, *name_l)
1095  nbl = *name_l - ncp;
1096  strncpy(name, v_name, ncp);
1097  for (i = 0; i < nbl; i++) name[ncp+i] = ' ';
1098  *lower = command_par_value("lower", comm);
1099  *upper = command_par_value("upper", comm);
1100  if ((l_step = command_par_value("step", comm)) < ten_m_12) l_step = ten_m_12;
1101  *step = l_step;
1102  *slope = command_par_value("slope", comm);
1103  *opt = command_par_value("opt", comm);
1104  return ++vary_cnt;
1105}
1106
1107// public interface used by fortran code
1108
1109void
1110mtcond(int* print_flag, int* nf, double* fun_vec, int* stab_flag)
1111{
1112  int i,j,k=0;
1113  char execute[40];
1114  static int nconserrs = 0; /*number of call finihed with error*/
1115
1116  if (match_is_on==2)
1117  {
1118    for(i=0; i<MAX_MATCH_MACRO; i++)
1119    {
1120      if (match2_macro_name[i]==NULL) break;
1121
1122      sprintf(execute,"exec, %s;",match2_macro_name[i]);
1123      match_is_on=0;
1124      pro_input(execute);
1125      match_is_on=2;
1126      if (!geterrorflag())
1127      {
1128        *stab_flag=0;
1129        k=match2_evaluate_exressions(i,k,fun_vec);
1130        nconserrs = 0;
1131      }
1132      else
1133      {
1134        nconserrs++;
1135        if (nconserrs > 5)
1136        { /*return the error code only after 5 consecutive fails*/
1137          *stab_flag=1; return;
1138        }
1139        else
1140        { /*otherwise just put all the constraints to max double value*/
1141          *stab_flag=0;
1142          for(j=0; j < *nf; j++)
1143          {
1144            fun_vec[j] = DBL_MAX;
1145          }
1146        }
1147      }
1148    }
1149  }
1150  else
1151  { /* old match */
1152    current_const = 0;
1153    penalty = zero;
1154    set_option("match_print", print_flag);
1155    /* mtgeti_(&stored_match_var->curr, vary_vect->a, vary_dvect->a); */
1156    for (i = 0; i < match_num_seqs; i++)
1157    {
1158      /* fprintf(prt_file, "%s %s\n", "call TWISS from matching: sequence=",
1159         match_sequs->sequs[i]->name); */
1160      current_twiss = local_twiss[i]->clone;
1161      if (get_option("varylength") != zero) match_prepare_varypos();
1162
1163      if (get_option("rmatrix") != zero) fprintf(prt_file, "%s\n", "call TWISS with RMATRIX");
1164      /* match with chrom */
1165      if (get_option("chrom") != zero) fprintf(prt_file, "%s\n", "call TWISS with CHROM");
1166      /* match with deltap */
1167      if (get_option("deltap") != zero) fprintf(prt_file, "%s\n", "call TWISS with DELTAP");
1168      /* match with deltap */
1169      if (get_option("sectormap") != zero) fprintf(prt_file, "%s\n", "call TWISS with SECTORMAP");
1170
1171      pro_twiss();
1172      if (twiss_success && !geterrorflag())
1173      {
1174        *stab_flag = 0;
1175        collect_(&current_const, &penalty, fun_vec);
1176        /* Do not write the penalty function here.
1177          'lmdif' still needs to check if the iteration was succesfull!
1178          the penalty function should only be printed from the
1179          'lmdif' routine. */
1180        /* fprintf(prt_file, "penalty function: %e\n", penalty); */
1181      }
1182      else
1183      {
1184        *stab_flag = 1; break;  /* Twiss failed - give up */
1185      }
1186    }
1187  } /* old match */
1188}
1189
1190int
1191mtputconsname(char* noden, int* nodei , char* consn, int* consi)
1192{
1193  int i,j;
1194  i=(*nodei)-1;
1195  j=(*consi)-1;
1196  match2_macro_name[i]=(char *)mymalloc("match_match",20);
1197  strncpy(match2_macro_name[i],noden,20);
1198  match2_macro_name[i][19]='\0';
1199  match2_cons_name[i][j]=(char *)mymalloc("match_match",20);
1200  strncpy(match2_cons_name[i][j],consn,20);
1201  match2_cons_name[i][j][19]='\0';
1202  return 0;
1203}
Note: See TracBrowser for help on using the repository browser.