a2b1a295afb374bf0efdbfb926b90f9bdf0561ed
[scilab.git] / scilab / modules / elementary_functions / macros / nthroot.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) Scilab Enterprises - 2012 - Adeline CARNIS
3 //
4 // This file must be used under the terms of the CeCILL.
5 // This source file is licensed as described in the file COPYING, which
6 // you should have received as part of this distribution.  The terms
7 // are also available at
8 // http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
9
10 function y = nthroot(x,n)
11
12     rhs = argn(2);
13
14     // If the number of input arguments is wrong
15     if rhs <> 2 then
16         error(msprintf(gettext("%s: Wrong number of input argument(s): %d expected.\n"), "nthroot", 2));
17     end
18
19     // If x or n are not real
20     if ((typeof(x) <> "constant" | ~isreal(x)) | (typeof(n) <> "constant" | ~isreal(n))) then
21         error(msprintf(gettext("%s: Wrong type for input argument(s) #%d: Real arguments expected.\n"),"nthroot", 2));
22     end
23
24     // If n is a vector which size is different from x's
25     if (size(n,"*")>1 & size(n,"*")<>size(x,"*")) then
26         error(msprintf(gettext("%s: Wrong size for input argument(s) #%d: vectors should have same size.\n"),"nthroot", 2));
27     end
28
29     reste = modulo(n,2);
30     // Making 'reste' one element
31     if (size(n,"*")>1) then
32         reste = or(reste(find(x<0))<>0);
33     end
34     y = x;
35
36     if (or(n==0) & (x>=0 | isnan(x))) then
37         // If n = 0 and x = 1 or x = %nan then y = %nan
38         y(find((x==1 | isnan(x)) & n==0)) = %nan;
39         // If n = 0 and x>1 then y = %inf
40         y(find(x>1 & n==0)) = %inf;
41         // If n = 0 and x = %eps then y = 0
42         y(find(x==%eps & n==0)) = 0;
43     end
44
45     if (x==[]) then
46         y = [];
47     elseif (n==[]) then
48         y = x;
49         // If n = %nan and x is positive then y = %nan
50     elseif (isnan(n) & or(x >= 0)) then
51         y(find(x>=0)) = %nan;
52     elseif (or (or(x(:)<0) & (or(n~=fix(n)) | reste==0 | reste==%f))) then
53         error(msprintf(gettext("%s: If x is negative, then n must contain odd integers only.\n"),"nthroot"));
54         // If n ~=0 and n ~= %nan
55     elseif (or(n~=0) & ~isnan(n)) then
56         // If x = 0 and n is negative and n i~= %nan
57         [m1,m2] = size(x(find(x==0 & n<0 & ~isinf(n))));
58         y(find(x==0 & n<0 & ~isinf(n))) = (x(find(x==0 & n<0 & ~isinf(n)))+ones(m1,m2)) .*%inf;
59         if (size(n,"*") == 1) then
60             // If x = 0 and n is positive and n ~= %nan
61             y(find(x==0 & (n>0 |isinf(n)))) = x(find(x==0 & (n>0 |isinf(n)))).^(1 ./n(find(n<>0)));
62             // If x is positive
63             y(find(x>0)) = x(find(x>0)).^(1 ./n(find(n<>0)));
64             // If x is negative
65             y(find(x<0)) = sign(x(find(x<0))).*(abs(x(find(x<0)))).^(1 ./n(find(n<>0)));
66         else
67             // If x = 0 and n is positive and n ~= %nan
68             y(find(x==0 & (n>0 |isinf(n)))) = x(find(x==0 & (n>0 |isinf(n)))).^(1 ./n(find(x==0 & n<>0)));
69             // If x is positive
70             y(find(x>0 & n<>0)) = x(find(x>0 & n<>0)).^(1 ./n(find(x>0 & n<>0)));
71             // If x is negative
72             y(find(x<0 & n<>0)) = sign(x(find(x<0 & n<>0))).*(abs(x(find(x<0)))).^(1 ./n(find(x<0 & n<>0)));
73         end
74     end
75
76 endfunction