diff --git a/src/Numerics/FindRoots.cs b/src/Numerics/FindRoots.cs index 1bff87f6..d3817640 100644 --- a/src/Numerics/FindRoots.cs +++ b/src/Numerics/FindRoots.cs @@ -3,9 +3,9 @@ // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com -// +// // Copyright (c) 2009-2013 Math.NET -// +// // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without @@ -14,10 +14,10 @@ // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: -// +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -105,5 +105,63 @@ namespace MathNet.Numerics return new Tuple(q/a, c/q); } + + /// + /// Find all roots of the Chebychev polynomial of the first kind. + /// + /// The polynomial order and therefore the number of roots. + /// The real domain interval begin where to start sampling. + /// The real domain interval end where to stop sampling. + /// Samples in [a,b] at (b+a)/2+(b-1)/2*cos(pi*(2i-1)/(2n)) + public static double[] ChebychevPolynomialFirstKind(int degree, double intervalBegin = -1d, double intervalEnd = 1d) + { + if (degree < 1) + { + return new double[0]; + } + + // transform to map to [-1..1] interval + double location = 0.5*(intervalBegin + intervalEnd); + double scale = 0.5*(intervalEnd - intervalBegin); + + // evaluate first kind chebyshev nodes + double angleFactor = Constants.Pi/(2*degree); + + var samples = new double[degree]; + for (int i = 0; i < samples.Length; i++) + { + samples[i] = location + scale*Math.Cos(((2*i) + 1)*angleFactor); + } + return samples; + } + + /// + /// Find all roots of the Chebychev polynomial of the second kind. + /// + /// The polynomial order and therefore the number of roots. + /// The real domain interval begin where to start sampling. + /// The real domain interval end where to stop sampling. + /// Samples in [a,b] at (b+a)/2+(b-1)/2*cos(pi*i/(n-1)) + public static double[] ChebychevPolynomialSecondKind(int degree, double intervalBegin = -1d, double intervalEnd = 1d) + { + if (degree < 1) + { + return new double[0]; + } + + // transform to map to [-1..1] interval + double location = 0.5*(intervalBegin + intervalEnd); + double scale = 0.5*(intervalEnd - intervalBegin); + + // evaluate second kind chebyshev nodes + double angleFactor = Constants.Pi/(degree + 1); + + var samples = new double[degree]; + for (int i = 0; i < samples.Length; i++) + { + samples[i] = location + scale*Math.Cos((i + 1)*angleFactor); + } + return samples; + } } } diff --git a/src/Numerics/Signals/SignalGenerator.Chebyshev.cs b/src/Numerics/Signals/SignalGenerator.Chebyshev.cs index 5b2049f0..898aa7fb 100644 --- a/src/Numerics/Signals/SignalGenerator.Chebyshev.cs +++ b/src/Numerics/Signals/SignalGenerator.Chebyshev.cs @@ -48,36 +48,19 @@ namespace MathNet.Numerics.Signals /// Vector of the function sampled in [a,b] at (b+a)/2+(b-1)/2*cos(pi*(2i-1)/(2n)) /// /// + [Obsolete] public static T[] ChebyshevNodesFirstKind( Func function, double intervalBegin, double intervalEnd, int sampleCount) { - if (ReferenceEquals(function, null)) - { - throw new ArgumentNullException("function"); - } - - if (sampleCount < 1) - { - throw new ArgumentOutOfRangeException("sampleCount"); - } - - // transform to map to [-1..1] interval - double transformSummand = 0.5 * (intervalBegin + intervalEnd); - double transformFactor = 0.5 * (intervalEnd - intervalBegin); - - // evaluate first kind chebyshev nodes - double angleFactor = Constants.Pi / (2 * sampleCount); - - var samples = new T[sampleCount]; - + var roots = FindRoots.ChebychevPolynomialFirstKind(sampleCount, intervalBegin, intervalEnd); + var samples = new T[roots.Length]; for (int i = 0; i < samples.Length; i++) { - samples[i] = function(transformSummand + transformFactor * Math.Cos(((2 * i) + 1) * angleFactor)); + samples[i] = function(roots[i]); } - return samples; } @@ -92,36 +75,19 @@ namespace MathNet.Numerics.Signals /// Vector of the function sampled in [a,b] at (b+a)/2+(b-1)/2*cos(pi*i/(n-1)) /// /// + [Obsolete] public static T[] ChebyshevNodesSecondKind( Func function, double intervalBegin, double intervalEnd, int sampleCount) { - if (ReferenceEquals(function, null)) - { - throw new ArgumentNullException("function"); - } - - if (sampleCount < 1) - { - throw new ArgumentOutOfRangeException("sampleCount"); - } - - // transform to map to [-1..1] interval - double transformSummand = 0.5 * (intervalBegin + intervalEnd); - double transformFactor = 0.5 * (intervalEnd - intervalBegin); - - // evaluate second kind chebyshev nodes - double angleFactor = Constants.Pi / (sampleCount + 1); - - var samples = new T[sampleCount]; - + var roots = FindRoots.ChebychevPolynomialSecondKind(sampleCount, intervalBegin, intervalEnd); + var samples = new T[roots.Length]; for (int i = 0; i < samples.Length; i++) { - samples[i] = function(transformSummand + transformFactor * Math.Cos((i + 1) * angleFactor)); + samples[i] = function(roots[i]); } - return samples; } }