summaryrefslogtreecommitdiff
path: root/macros/mpoles.sci
diff options
context:
space:
mode:
Diffstat (limited to 'macros/mpoles.sci')
-rw-r--r--macros/mpoles.sci194
1 files changed, 99 insertions, 95 deletions
diff --git a/macros/mpoles.sci b/macros/mpoles.sci
index bba9997..4556120 100644
--- a/macros/mpoles.sci
+++ b/macros/mpoles.sci
@@ -1,124 +1,128 @@
// Copyright (C) 2018 - IIT Bombay - FOSSEE
-//
// This file must be used under the terms of the CeCILL.
// This source file is licensed as described in the file COPYING, which
// you should have received as part of this distribution. The terms
// are also available at
// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
-// Author:[insert name]
+// Original Source : https://octave.sourceforge.io/
+// Modifieded by: Abinash Singh Under FOSSEE Internship
+// Last Modified on : 3 Feb 2024
// Organization: FOSSEE, IIT Bombay
// Email: toolbox@scilab.in
+function [multp, idxp] = mpoles (p, tol, reorder)
+ if (nargin < 1)
+ error("mpoles: Invalid number of input arguments");
+ end
-function [multp, indx] = mpoles (p, tol, reorder)
-
-//Calling sequence:
-// [multp, idxp] = mpoles (p)
-// [multp, idxp] = mpoles (p, tol)
-// [multp, idxp] = mpoles (p, tol, reorder)
-// Identify unique poles in p and their associated multiplicity.
-//
-// The output is ordered from largest pole to smallest pole.
-//
-// If the relative difference of two poles is less than tol then they are
-// considered to be multiples. The default value for tol is 0.001.
-//
-// If the optional parameter reorder is zero, poles are not sorted.
-//
-// The output multp is a vector specifying the multiplicity of the poles.
-// multp(n) refers to the multiplicity of the Nth pole
-// p(idxp(n)).
-//
-//
-//
-
-// test case:
-
-// p = [2 3 1 1 2];
-// [m, n] = mpoles (p)
-// n =
-// 2.
-// 5.
-// 1.
-// 4.
-// 3.
-// m =
-// 1.
-// 1.
-// 2.
-// 1.
-// 2.
-//
-
-
-[nargout,nargin]=argn();
-
- if (nargin < 1 | nargin > 3)
- error("wrong number of input arguments");
+ if ~( type(p)== 1)
+ error ("mpoles: P must be a single or double floating point vector");
end
- if (nargin < 2 | isempty (tol))
- tol = 0.001;
- end
+ if (nargin < 2 || isempty (tol))
+ tol = 0.001;
+ elseif (~(isscalar (tol) && isreal (tol) && tol > 0))
+ error ("mpoles: TOL must be a real scalar greater than 0");
+ end
- if (nargin < 3 | isempty (reorder))
- reorder = %t;
- end
+ if (nargin < 3 || isempty (reorder))
+ reorder = %t;
+ elseif (~(isscalar (reorder) && isreal (reorder)))
+ error ("mpoles: REORDER must be a numeric or logical scalar");
+ end
Np = length (p);
-
- // Force the poles to be a column vector.
-
- p = p(:);
-
- // Sort the poles according to their magnitidues, largest first.
+ p = p(:); // force poles to be a column vector
if (reorder)
- // Sort with smallest magnitude first.
- [p, ordr] = gsort (p,"r","i");
- // Reverse order, largest maginitude first.
- n = Np:-1:1;
- p = p(n);
- ordr = ordr(n);
+ //// sort with largest magnitude first
+ [_, order] = gsort (abs(p));
+ p = p(order);
else
- ordr = 1:Np;
+ order = (1:Np).';
end
- // Find pole multiplicty by comparing the relative differnce in the
- // poles.
+ //// Create vector of tolerances for use in algorithm.
+ vtol = zeros (Np, 1, typeof(p));
+ p_nz = (p ~= 0); // non-zero poles
+ vtol(~p_nz) = tol; // use absolute tolerance for zero poles
- multp = zeros (Np, 1);
- indx = [];
+ //// Find pole multiplicity by comparing relative difference of poles.
+ multp = zeros (Np, 1, typeof(p));
+ idxp = [];
n = find (multp == 0, 1);
-
-
-
-
-
-
while (n)
- dp = abs (p-p(n));
- if (p(n) == 0.0)
- if (or (abs (p) > 0 & (abs(p)<%inf)))
- p0 = mean (abs (p(abs (p) > 0 & abs(p)<%inf)));
- else
- p0 = 1;
- end
- else
- p0 = abs (p(n));
+ dp = abs (p - p(n));
+ vtol(p_nz) = tol * abs (p(n));
+ k = find (dp < vtol);
+ //// Poles can only be members of one multiplicity group.
+ if (length (idxp))
+ k = k(~ismember (k, idxp));
end
- k = find (dp < tol * p0)';
- // Poles can only be members of one multiplicity group.
-// if (length(indx))
-// mk=members(k,indx);
-// k = (~ bool2s(mk~=0));
-// end
m = 1:length (k);
- multp(k) = m';
- indx = [indx; k];
+ multp(k) = m;
+ // disp("k")
+ // disp(k)
+ // disp("idxp")
+ // disp(idxp)
+ idxp = [idxp; k(:)];
n = find (multp == 0, 1);
end
- multp = multp(indx);
- indx = ordr(indx);
+ multp = multp(idxp);
+ idxp = order(idxp);
+endfunction
+function y = ismember(a, b) // FIXME : do this in a more efficient .
+ y = zeros(size(a,1),size(a,2));
+ for i = 1:length(a)
+ for j = 1:length(b)
+ if a(i) == b(j)
+ y(i) = 1;
+ break;
+ end
+ end
+ end
endfunction
+
+
+/*
+
+ // test
+ [mp, ip] = mpoles ([0 0], 0.01);
+ assert_checkequal (mp, [1; 2]);
+
+ // test
+ [mp, ip] = mpoles ([-1e4, -0.1, 0]);
+ assert_checkequal (mp, [1; 1; 1]);
+ assert_checkequal (ip, [1; 2; 3]);
+
+// Test single inputs
+// test
+ [mp, ip] = mpoles ([-1e4, -0.1, 0]);
+ assert_checkequal (mp,[1; 1; 1]);
+ assert_checkequal (ip, [1; 2; 3]);
+
+// Test relative tolerance criteria
+// test
+ [mp, ip] = mpoles ([1, 1.1, 1.3], .1/1.1);
+ assert_checkequal (mp, [1; 1; 1]);
+ [mp, ip] = mpoles ([1, 1.1, 1.3], .1/1.1 + %eps);
+ assert_checkequal (mp, [1; 1; 2]);
+
+// Test absolute tolerance criteria with a zero pole
+// test
+ [mp, ip] = mpoles ([0, -0.1, 0.3], .1);
+ assert_checkequal (mp, [1; 1; 1]);
+ [mp, ip] = mpoles ([0, -0.1, 0.3], .1 + %eps);
+ assert_checkequal (mp, [1; 1; 2]);
+
+//// Test input validation
+error <Invalid call> mpoles ()
+error <P must be a single or double floating point vector> mpoles (uint8 (1))
+error <TOL must be a real scalar greater than 0> mpoles (1, [1, 2])
+error <TOL must be a real scalar greater than 0> mpoles (1, 1i)
+error <TOL must be a real scalar greater than 0> mpoles (1, 0)
+error <REORDER must be a numeric or logical scalar> mpoles (1, 1, [1, 2])
+error <REORDER must be a numeric or logical scalar> mpoles (1, 1, {1})
+
+*/ \ No newline at end of file