source: MML/trunk/machine/SOLEIL/common/toolbox/SymbolicPolynomials/SymbolicPolynomials/@sympoly/syndivide.m @ 4

Last change on this file since 4 was 4, checked in by zhangj, 10 years ago

Initial import--MML version from SOLEIL@2013

File size: 2.8 KB
Line 
1function [q,r,rflag] = syntheticdivision(snumer,sdenom)
2% syntheticdivision: quotient and remainder of a synthetic polynomial division
3% usage: [q,r] = syntheticdivision(snumer,sdenom)
4%
5% arguments: (input)
6%  snumer - scalar sympoly object - Numerator polynomial
7%
8%  sdenom - scalar sympoly object - Denomenator polynomial
9%
10% arguments: (output)
11%  q - quotient sympoly
12%
13%  r - remainder sympoly
14%
15%  rflag - scalar boolean flag - denotes if the remainder term
16%      was judged to be zero.
17%
18%      rflag == 0 --> the remainder was zero to within a tolerance
19%      rflag == 1 --> the remainder was greater than the tolerance
20
21% are they both sympolys?
22if ~isa(snumer,'sympoly')
23  snumer = sympoly(snumer);
24end
25if ~isa(sdenom,'sympoly')
26  sdenom = sympoly(sdenom);
27end
28
29% monomial sympoly == 0 (right now)
30monomial = sympoly(1);
31
32% make all variable sets the same
33[snumer,sdenom,monomial] = equalize_vars(snumer,sdenom,monomial);
34
35% shift the sympolys to have all positive exponents
36% The shift will be zero for variables which have all
37% positive exponents already.
38sh = min(0,min(snumer.Exponent,[],1));
39numershift = monomial;
40numershift.Exponent = sh;
41nt = size(snumer.Exponent,1);
42snumer.Exponent = snumer.Exponent - repmat(sh,nt,1);
43
44sh = min(0,min(sdenom.Exponent,[],1));
45denomshift = monomial;
46denomshift.Exponent = sh;
47nt = size(sdenom.Exponent,1);
48sdenom.Exponent = sdenom.Exponent - repmat(sh,nt,1);
49
50% initialize the quotient and remainder sympolys
51q = sympoly(0);
52r = snumer;
53
54% highest order term in the denomenator sympoly
55order = sum(sdenom.Exponent,2);
56[order,ind] = max(order);
57denorder = sdenom.Exponent(ind,:);
58denomcoef = sdenom.Coefficient(ind);
59
60% set up a while loop to do the synthetic division
61divflag = 1;
62tol = 1e-12*max(abs(snumer.Coefficient))/max(abs(sdenom.Coefficient));
63rflag = logical(0);
64while divflag
65  % find the highest order term in the remainder sympoly
66  order = sum(r.Exponent,2);
67  [order,ind] = max(order);
68  if order>=sum(denorder)
69    % "divide"
70    remorder = r.Exponent(ind,:);
71    remCoef = r.Coefficient(ind);
72   
73    % another piece to add in to q
74    monomial.Exponent = remorder - denorder;
75    monomial.Coefficient = remCoef/denomcoef;
76    q = q + monomial;
77
78    % and decrement the remainder
79    r = r - monomial*sdenom;
80    r = equalize_vars(r,monomial);
81
82    % Is there anything left in the remainder that has a
83    % positive exponent? If so, then continue the while loop.
84    if all(r.Exponent(:)<0)
85      divflag = 0;
86      rflag = logical(1);
87    elseif all(r.Exponent(:)<=0) && all(abs(r.Coefficient)<=tol)
88      divflag = 0;
89    end
90  else
91    % there is a non-zero remainder
92    divflag = 0;
93    if any(abs(r.Coefficient)>=tol)
94      rflag = logical(1);
95    end
96  end
97end
98
99% when all is done, unshift the sympolys
100shift = numershift./denomshift;
101q = q*shift;
102r = r*shift;
103
Note: See TracBrowser for help on using the repository browser.