1 | function C = findrespm(RING, OBSINDEX, PERTURB, PVALUE, varargin) |
---|
2 | %FINDRESPM computes the change in the closed orbit due to parameter perturbations |
---|
3 | % Two calling syntax options |
---|
4 | % 1. FINDRESPM(RING, OBSINDEX, PERTURBINDEX, PVALUE, 'FIELD', M, N, ORBITFUNCTION, ARGS) |
---|
5 | % 2. !!! not implemented yet FINDRESPM(RING, OBSINDEX, PERTURBGROUP, PVALUE, ORBITFUNCTION, ARGS) |
---|
6 | % |
---|
7 | % RING - ring lattice |
---|
8 | % OBSINDEX - indexes of elements where the orbit is observed (at the entrance) |
---|
9 | % PERTURBINDEX - Integer indexes of elements whose parameters are perturbed |
---|
10 | % used with syntax 1 only. |
---|
11 | % |
---|
12 | % PERTURBGROUP - cell array of AT paramgroups. See ATPARAMGROUP |
---|
13 | % used with syntax 2 only |
---|
14 | % |
---|
15 | % PVALUE - amount of peturbation |
---|
16 | % (Numeric array or scalar if all perturbations are the same magnitude) |
---|
17 | % |
---|
18 | % FIELD,M,N are only use with syntax 1. |
---|
19 | % |
---|
20 | % FIELD - field name of the parameter to perturb (string) |
---|
21 | % |
---|
22 | % M,N - index in the matrix, if the field is a matrix |
---|
23 | % For example to perturb the quadrupole field in a |
---|
24 | % multipole element |
---|
25 | % FIELD = 'PolynomB', M = 1, N = 2 |
---|
26 | % |
---|
27 | % ORBITFUNCTION - specifies which of the FINDORBIT functions is used |
---|
28 | % |
---|
29 | % 'findorbit4' (default) |
---|
30 | % 'findsyncorbit' |
---|
31 | % 'findorbit6' |
---|
32 | % |
---|
33 | % ARGS - additioanl arguments may passsed to some of the FINDORBIT functions |
---|
34 | % findorbit4 - constant momentum error dP |
---|
35 | % findsyncorbit - fixed orbit lengthening dCT |
---|
36 | % |
---|
37 | % |
---|
38 | % Returns a 1-by-4 cell array of O-by-P matrixes |
---|
39 | % where O = length(OBSINDEX) and P = length(PERTURB) |
---|
40 | % one for each of the close orbit components: X, PX, Y, PY |
---|
41 | % See also ATPARAMGROUP, FINDORBIT, FINDORBIT4, FINDORBIT6, FINDSYNCORBIT |
---|
42 | |
---|
43 | |
---|
44 | O = length(OBSINDEX); |
---|
45 | P = length(PERTURB); |
---|
46 | C = {zeros(O,P),zeros(O,P),zeros(O,P),zeros(O,P)}; |
---|
47 | |
---|
48 | if length(PVALUE) ~= P |
---|
49 | PVALUE = PVALUE(ones(1,P(1))); |
---|
50 | end |
---|
51 | |
---|
52 | |
---|
53 | if isnumeric(PERTURB) % syntax option 1 |
---|
54 | % Integer indexes of perturbed elements. |
---|
55 | % More fields must be supplied. |
---|
56 | % setfield will be used to make perturbations |
---|
57 | if nargin < 7 |
---|
58 | error('Incorrect number of inputs'); |
---|
59 | end |
---|
60 | |
---|
61 | if ~ischar(varargin{1}) % Check that the FIELD argument is a string |
---|
62 | error('The 5-th argument FIELD must be a string'); |
---|
63 | end |
---|
64 | |
---|
65 | if ~isnumeric(varargin{2}) | length(varargin{2})>1 % Check that the M argument is a scalar |
---|
66 | error('The 6-th argument FIELD must be a scalar'); |
---|
67 | end |
---|
68 | M = varargin{2}(1); |
---|
69 | |
---|
70 | if ~isnumeric(varargin{3}) | length(varargin{3})>1 % Check that the M argument is a scalar |
---|
71 | error('The 7-th argument FIELD must be a scalar'); |
---|
72 | end |
---|
73 | N = varargin{3}(1); |
---|
74 | |
---|
75 | if nargin > 7 |
---|
76 | ORBITFUNCTION = varargin{4}; |
---|
77 | else |
---|
78 | ORBITFUNCTION = 'findorbit4'; |
---|
79 | end |
---|
80 | |
---|
81 | |
---|
82 | switch ORBITFUNCTION |
---|
83 | case 'findorbit4' |
---|
84 | orbit_function_handle = @findorbit4; |
---|
85 | if nargin == 9 |
---|
86 | orbit_function_args = {varargin{5}, OBSINDEX}; |
---|
87 | else |
---|
88 | orbit_function_args = {0, OBSINDEX}; |
---|
89 | end |
---|
90 | case 'findsyncorbit' |
---|
91 | orbit_function_handle = @findsyncorbit; |
---|
92 | if nargin == 9 |
---|
93 | orbit_function_args = {varargin{5}, OBSINDEX}; |
---|
94 | else |
---|
95 | orbit_function_args = {0, OBSINDEX}; |
---|
96 | end |
---|
97 | case 'findorbit6' |
---|
98 | orbit_function_handle = @findorbit6; |
---|
99 | orbit_function_args = {OBSINDEX}; |
---|
100 | otherwise |
---|
101 | error(['Unknown FINDORBIT function: ',ORBITFUNCTION]); |
---|
102 | end |
---|
103 | |
---|
104 | %ORBIT = findorbit4(RING,0,OBSINDEX); |
---|
105 | |
---|
106 | |
---|
107 | ORBIT = feval(orbit_function_handle,RING,orbit_function_args{:}); |
---|
108 | |
---|
109 | mn = {M,N}; |
---|
110 | for i = 1:P |
---|
111 | oldvalue = getfield(RING{PERTURB(i)},varargin{1},mn); |
---|
112 | RING{PERTURB(i)} = setfield(RING{PERTURB(i)},varargin{1},mn,oldvalue+PVALUE(i)); |
---|
113 | ORBITPLUS = feval(orbit_function_handle,RING,orbit_function_args{:}); |
---|
114 | RING{PERTURB(i)} = setfield(RING{PERTURB(i)},varargin{1},mn,oldvalue); |
---|
115 | DORBIT = (ORBITPLUS - ORBIT); |
---|
116 | C{1}(:,i) = DORBIT(1,:); |
---|
117 | C{2}(:,i) = DORBIT(2,:); |
---|
118 | C{3}(:,i) = DORBIT(3,:); |
---|
119 | C{4}(:,i) = DORBIT(4,:); |
---|
120 | end |
---|
121 | end |
---|