FftwPlanRC.cs 3.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #region Copyright and License
  2. /*
  3. This file is part of FFTW.NET, a wrapper around the FFTW library
  4. for the .NET framework.
  5. Copyright (C) 2017 Tobias Meyer
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. */
  15. #endregion
  16. using System;
  17. using System.Numerics;
  18. namespace FFTW.NET
  19. {
  20. public sealed class FftwPlanRC : FftwPlan<double, Complex>
  21. {
  22. public IPinnedArray<double> BufferReal => Buffer1;
  23. public IPinnedArray<Complex> BufferComplex => Buffer2;
  24. FftwPlanRC(IPinnedArray<double> bufferReal, IPinnedArray<Complex> bufferComplex, int rank, int[] n, bool verifyRankAndSize, DftDirection direction, PlannerFlags plannerFlags, int nThreads)
  25. : base(bufferReal, bufferComplex, rank, n, verifyRankAndSize, direction, plannerFlags, nThreads) { }
  26. protected override IntPtr GetPlan(int rank, int[] n, IntPtr bufferReal, IntPtr bufferComplex, DftDirection direction, PlannerFlags plannerFlags)
  27. {
  28. if (direction == DftDirection.Forwards)
  29. return FftwInterop.GetDelegate<FftwInterop.fftw_plan_dft_r2c>()(rank, n, bufferReal, bufferComplex, plannerFlags);
  30. else
  31. return FftwInterop.GetDelegate<FftwInterop.fftw_plan_dft_c2r>()(rank, n, bufferComplex, bufferReal, plannerFlags);
  32. }
  33. protected override void VerifyRankAndSize(IPinnedArray<double> bufferReal, IPinnedArray<Complex> bufferComplex)
  34. {
  35. if (bufferReal.Rank != bufferComplex.Rank)
  36. throw new ArgumentException($"{nameof(bufferReal)} and {nameof(bufferComplex)} must have the same rank and size.");
  37. for (int i = 0; i < bufferReal.Rank-1; i++)
  38. {
  39. if (bufferReal.GetLength(i) != bufferComplex.GetLength(i))
  40. throw new ArgumentException($"Lenght of {nameof(bufferComplex)} must be equal to n[0]*...*(n[n.Length - 1] / 2 + 1) with n being the size of {nameof(bufferReal)}.");
  41. }
  42. if (bufferReal.GetLength(bufferReal.Rank - 1) / 2 + 1 != bufferComplex.GetLength(bufferReal.Rank - 1))
  43. throw new ArgumentException($"Lenght of {nameof(bufferComplex)} must be equal to n[0]*...*(n[n.Length - 1] / 2 + 1) with n being the size of {nameof(bufferReal)}.");
  44. }
  45. protected override void VerifyMinSize(IPinnedArray<double> bufferReal, IPinnedArray<Complex> bufferComplex, int[] n)
  46. {
  47. int sizeComplex;
  48. int sizeReal = 1;
  49. checked
  50. {
  51. for (int i = 0; i < n.Length - 1; i++)
  52. sizeReal *= n[i];
  53. sizeComplex = sizeReal * (n[n.Length - 1] / 2 + 1);
  54. sizeReal *= n[n.Length - 1];
  55. }
  56. if (bufferReal.Length < sizeReal)
  57. throw new ArgumentException($"{nameof(bufferReal)} is too small.");
  58. if (bufferComplex.Length < sizeComplex)
  59. throw new ArgumentException($"{nameof(bufferComplex)} is too small.");
  60. }
  61. /// <summary>
  62. /// Initializes a new plan using the provided input and output buffers.
  63. /// These buffers may be overwritten during initialization.
  64. /// </summary>
  65. public static FftwPlanRC Create(IPinnedArray<double> bufferReal, IPinnedArray<Complex> bufferComplex, DftDirection direction, PlannerFlags plannerFlags = PlannerFlags.Default, int nThreads = 1)
  66. {
  67. FftwPlanRC plan = new FftwPlanRC(bufferReal, bufferComplex, bufferReal.Rank, bufferReal.GetSize(), true, direction, plannerFlags, nThreads);
  68. if (plan.IsZero)
  69. return null;
  70. return plan;
  71. }
  72. internal static FftwPlanRC Create(IPinnedArray<double> bufferReal, IPinnedArray<Complex> bufferComplex, int rank, int[] n, DftDirection direction, PlannerFlags plannerFlags, int nThreads)
  73. {
  74. FftwPlanRC plan = new FftwPlanRC(bufferReal, bufferComplex, rank, n, false, direction, plannerFlags, nThreads);
  75. if (plan.IsZero)
  76. return null;
  77. return plan;
  78. }
  79. }
  80. }