Решение интеграла в преобразовании Фурье
Численным методам этот интеграл не решить из за наличия комплексной мнимой единицы,порекомендовали Формула Эйлера с разложением подынтегральной функции на косинус и синус
Вопрос возник с применением Формулы Эйлера
Получается нужно вручную разделить формулу на 2 части присвоить согласно формуле Эйлера каждую часть к интегралу.
Или существует другой вариант?
public void frmEiler(int U,int T)
{
double x1=0,x2=0;
///U*Math.Exp(-j * w * t) dt///формула
double j = Math.Sqrt(-1);// мнимая единица
double f = 0,w = 0;
int t = 1;
f = 1 / T;
w = 2 * Math.PI * f;
Math.Exp(-j * w * t) =U* Math.Cos(w * t) + j * Math.Sin(t);
x1=Math.Cos(w * t);
x2=j * Math.Sin(t);
}
public double func1(double x1)
{
///1-ая часть подыинтегральной функции
return;
}
public double func2(double x2)
{
///2-ая часть подыинтегральной функции
return;
}
Ответ
Скорее всего с помощью формулы Эйлера Вы решили избавиться от мнимой единицы, чтобы вычислить численно интегралы. Я в математике не силен, не знаю верно ли, но решил попробовать.
Получается нужно вручную разделить формулу на 2 части присвоить
согласно формуле Эйлера каждую часть к интегралу
По формуле Эйлера нужно вычислить интеграл sin'а и интеграл cos'а. Дальше из полученных результатов получить комплексное число.
Что я делал
Я создал класс NumericalIntegration, который интегрирует функцию с помощью Численного интегрирования. Т.к. существует несколько методов решения (я буду называть их способы, чтобы не путать с термином метод в программировании), поэтому я решил создать интерфейс, который будет подразумевать какой-то способ решения. А реализация этого интерфейса уже будет конкретным способом решения. Я так сделал, чтобы при разработки можно было добавить еще какие-то способы решения.
interface NumericalIntegrationRule
{
double Calculate(Func
У способа решения должен быть метод, который принимает функцию func, отрезок интегрирования [min,max] и число подинтервалов n, т.е. насколько частей делим отрезок, чем больше отрезков, тем больше точность интегрирования. Конечно же, лучше было бы сделать погрешность, но я по-быстрому заложился на количество отрезков. Можете сами потом изменить это.
А в классе интегрирования NumericalIntegration уже будет вызов нужного способа решения. Нужный способ передается через конструктор. Плюс добавил параметры по умолчанию: число отрезков.
class NumericalIntegration
{
public readonly NumericalIntegrationRule DefaultRule = null;
public readonly int DefaultSubintervalsCount = 100000;
public NumericalIntegration()
{
DefaultRule = new TrapezoidalRule();
}
public NumericalIntegration(NumericalIntegrationRule defaultRule)
{
DefaultRule = defaultRule;
}
public NumericalIntegration(NumericalIntegrationRule defaultRule, int defaultSubintervalsCount) : this(defaultRule)
{
DefaultSubintervalsCount = defaultSubintervalsCount;
}
public double Calculate(NumericalIntegrationRule rule, Func
public double Calculate(Func
Я реализовал только метод трапеций:
class TrapezoidalRule : NumericalIntegrationRule
{
public double Calculate(Func
for (double i = min; i < max; i += step)
result += ((func(i) + func(i + step)) / 2) * step;
return result;
}
}
А можно было бы на каждый способ решения в классе NumericalIntegration создать отдельный метод этого CalculateWithTrapezoidalRule, CalculateWithRectangleRule и т.д.
Теперь у нас есть классы для численного интегрирования. Можно их использовать для нахождения спектральной плотности. Я не в курсе как у Вас устроена система, поэтому я работал в консольном приложении и в этом приложении вынес расчет плотности в отдельный статический метод:
static Complex GetSpectralDensity(double amplitude, double frequency, double time)
{
NumericalIntegration integration = new NumericalIntegration();
double real = amplitude * integration.Calculate(x => Math.Cos(-frequency * x), 0, time);
double imaginary = amplitude * integration.Calculate(x => Math.Sin(-frequency * x), 0, time);
return new Complex(real, imaginary);
}
Все как в формуле Эйлера: интегрируются обе части, а потом на основе их результатов создается комплексное число, которое и будет равно значения плотности.
Дальше, решил проверить результаты моей программы с результатами Mathcad.
Mathcad, вроде бы, говорит, что результаты, вычисленные после преобразования по формуле Эйлера, будут такие же, как и результаты, полученные без преобразования.
Проверил на этих же данных и свою программу.
static void Main(string[] args)
{
double amplitude = 25;
double time = 50;
for (int frequency = -100, counter = 0; frequency <= 100; frequency++, counter++)
Console.WriteLine("{0}: {1}", counter, GetSpectralDensity(amplitude, frequency, time).ToString());
}
Вроде бы, похоже. Попробуйте реализовать другие способы решения и вычислить с помощью их.
Забыл сказать, что я использовал сборку System.Numerics.dll для представления комплексного числа. Надеюсь, ее то можно использовать :)
Комментариев нет:
Отправить комментарий