[4] | 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 | |
---|