1 | function SPresult = terms(SP,pattern,opmode) |
---|
2 | % sympoly/terms: extract or delete specific terms of a sympoly |
---|
3 | % usage: SPresult = terms(SP,pattern) |
---|
4 | % usage: SPresult = terms(SP,pattern,opmode) |
---|
5 | % |
---|
6 | % arguments: (input) |
---|
7 | % SP - any sympoly object |
---|
8 | % |
---|
9 | % pattern - either a scalar monomial sympoly |
---|
10 | % or a scalar integer, or a vector of integers |
---|
11 | % |
---|
12 | % If pattern is an integer, then it designates |
---|
13 | % the i'th subterm to operate on in SP. If a |
---|
14 | % vector of integers, then it deginates the |
---|
15 | % list of numbered terms to operate on. |
---|
16 | % |
---|
17 | % If pattern is a sympoly itself, then it |
---|
18 | % designates the explicit terms to search for. |
---|
19 | % (See the examples.) |
---|
20 | % |
---|
21 | % opmode - (OPTIONAL) character string flag, that |
---|
22 | % designates the operation to be performed. |
---|
23 | % opmode must be either 'extract', 'delete', |
---|
24 | % or empty. Case is ignored. |
---|
25 | % |
---|
26 | % opmode == 'delete' --> drop the indicated |
---|
27 | % terms from the sympoly, returning those |
---|
28 | % that remain. |
---|
29 | % |
---|
30 | % opmode == 'extract' --> extract only the |
---|
31 | % indicated terms from the sympoly, dropping |
---|
32 | % all other terms. |
---|
33 | % |
---|
34 | % DEFAULT: opmode = 'extract' |
---|
35 | % |
---|
36 | % Example: |
---|
37 | % |
---|
38 | |
---|
39 | if (nargin<1) || (nargin>3) |
---|
40 | error('terms requires exactly 2 or 3 arguments') |
---|
41 | end |
---|
42 | |
---|
43 | % default for opmode |
---|
44 | if (nargin <3) || isempty(opmode) |
---|
45 | opmode = 'extract'; |
---|
46 | elseif ~ischar(opmode) |
---|
47 | error('opmode must be character if supplied, either ''extract'' or ''delete''') |
---|
48 | else |
---|
49 | valid = {'extract', 'delete'}; |
---|
50 | ind = strmatch(lower(opmode),valid); |
---|
51 | if isempty(ind) |
---|
52 | error('opmode must be character if supplied, either ''extract'' or ''delete''') |
---|
53 | end |
---|
54 | opmode = valid{ind}; |
---|
55 | end |
---|
56 | |
---|
57 | % is SP a sympoly? |
---|
58 | if ~isa(SP,'sympoly') |
---|
59 | error('SP must be a sympoly') |
---|
60 | end |
---|
61 | |
---|
62 | % is patterns a sympoly or a numeric (positive integer) vector/scalar? |
---|
63 | if isa(pattern,'sympoly') && (numel(pattern) > 1) |
---|
64 | % pattern must be a scalar monomial pattern |
---|
65 | error('pattern must be a scalar monomial if it is a sympoly') |
---|
66 | elseif isnumeric(pattern) && ~(all(pattern(:)>0) && all(pattern(:)==round(pattern(:)))) |
---|
67 | error('pattern must be positive integer if numeric') |
---|
68 | elseif ~isnumeric(pattern) && ~isa(pattern,'sympoly') |
---|
69 | error('pattern must be a sympoly monomial or a positive integer if numeric') |
---|
70 | else |
---|
71 | pattern = pattern(:); |
---|
72 | end |
---|
73 | |
---|
74 | % is this an array or vector sympoly? |
---|
75 | if numel(SP) > 1 |
---|
76 | % it is an array |
---|
77 | SPresult = SP; |
---|
78 | for i = 1:numel(SP) |
---|
79 | SPresult(i) = terms(SP(i),pattern,opmode); |
---|
80 | end |
---|
81 | % we can quit now |
---|
82 | return |
---|
83 | end |
---|
84 | % if we drop through, then SP is a scalar sympoly |
---|
85 | |
---|
86 | % was pattern a sympoly or a numbered set of terms? |
---|
87 | if isnumeric(pattern) |
---|
88 | % a numbered set of terms, and SP is a scalar sympoly |
---|
89 | |
---|
90 | % how many terms are in SP? |
---|
91 | nsp = length(SP.Coefficient); |
---|
92 | |
---|
93 | if any(pattern> nsp) |
---|
94 | warning('SYMPOLY:TERMS:patternmismatch','SP does not have as many terms as indicated by pattern') |
---|
95 | end |
---|
96 | % drop the extranseous terms in pattern |
---|
97 | % so we do not search for them |
---|
98 | pattern(pattern>nsp) = []; |
---|
99 | |
---|
100 | if isempty(pattern) |
---|
101 | % nothing there in the pattern |
---|
102 | switch opmode |
---|
103 | case 'extract' |
---|
104 | SPresult = sympoly(0); |
---|
105 | case 'delete' |
---|
106 | SPresult = SP; |
---|
107 | end |
---|
108 | else |
---|
109 | % which terms? Which opmode? |
---|
110 | switch opmode |
---|
111 | case 'extract' |
---|
112 | SPresult = SP; |
---|
113 | SPresult.Exponent = SPresult.Exponent(pattern(:),:); |
---|
114 | SPresult.Coefficient = SPresult.Coefficient(pattern(:)); |
---|
115 | case 'delete' |
---|
116 | SPresult = SP; |
---|
117 | SPresult.Exponent(pattern,:) = []; |
---|
118 | SPresult.Coefficient(pattern,:) = []; |
---|
119 | end |
---|
120 | |
---|
121 | % clean up |
---|
122 | SPresult = clean_sympoly(SPresult); |
---|
123 | end |
---|
124 | |
---|
125 | else |
---|
126 | % pattern is a scalar sympoly, as is SP. |
---|
127 | |
---|
128 | % make sure that pattern had only one term in it |
---|
129 | if length(pattern.Coefficient) > 1 |
---|
130 | error('A sympoly pattern may only have a single polynomial term') |
---|
131 | end |
---|
132 | |
---|
133 | % ensure that SP and patterns have a |
---|
134 | % consistent set of variables |
---|
135 | [SP,pattern] = equalize_vars(SP,pattern); |
---|
136 | |
---|
137 | % look for a match between exponents in the terms |
---|
138 | nt = length(SP.Coefficient); |
---|
139 | k = all(SP.Exponent == repmat(pattern.Exponent,nt,1),2); |
---|
140 | if any(k) |
---|
141 | switch opmode |
---|
142 | case 'extract' |
---|
143 | SPresult = SP; |
---|
144 | SPresult.Exponent = SPresult.Exponent(k,:); |
---|
145 | SPresult.Coefficient = SPresult.Coefficient(k); |
---|
146 | case 'delete' |
---|
147 | SPresult = SP; |
---|
148 | SPresult.Exponent(k,:) = []; |
---|
149 | SPresult.Coefficient(k,:) = []; |
---|
150 | end |
---|
151 | else |
---|
152 | switch opmode |
---|
153 | case 'extract' |
---|
154 | % nothing extracted - so a zero sympoly |
---|
155 | SPresult = sympoly(0); |
---|
156 | case 'delete' |
---|
157 | % no deletions, so the original sympoly |
---|
158 | SPresult = SP; |
---|
159 | end |
---|
160 | end |
---|
161 | |
---|
162 | % clean up |
---|
163 | SPresult = clean_sympoly(SPresult); |
---|
164 | end |
---|
165 | |
---|
166 | |
---|
167 | |
---|
168 | |
---|
169 | |
---|
170 | |
---|
171 | |
---|