C# 创建类和构造函数C的困难#
我正在尝试为我在学校做的一个项目实现一个离散傅里叶变换算法。但是创建一个类似乎很困难(不应该如此)。 我正在使用Visual Studio 2012 基本上,我需要一个名为Complex的类来存储从DFT获得的两个值;实部和虚部 这就是我迄今为止所做的:C# 创建类和构造函数C的困难#,c#,class,constructor,visual-studio-2012,C#,Class,Constructor,Visual Studio 2012,我正在尝试为我在学校做的一个项目实现一个离散傅里叶变换算法。但是创建一个类似乎很困难(不应该如此)。 我正在使用Visual Studio 2012 基本上,我需要一个名为Complex的类来存储从DFT获得的两个值;实部和虚部 这就是我迄今为止所做的: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; names
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SoundEditor_V3
{
public class Complex
{
public double real;
public double im;
public Complex()
{
real = 0;
im = 0;
}
}
}
问题是它不承认构造函数是一个构造函数,我只是在学习C#,但我在网上查到了它,它应该是这样的。
但它将我的构造函数识别为一种方法
为什么呢?
我创建的类是错误的吗
它也在我的傅立叶课堂上做同样的事情。所以每次我尝试创建一个
傅里叶对象,然后使用它的方法…没有这样的事情
例如,我这样做:
Fourier fou = new Fourier();
fou.DFT(s, N, amp, 0);
它告诉我fou是一个“字段”,但像“类型”一样使用
为什么这么说
下面是我的Fourier类的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SoundEditor_V3
{
public class Fourier
{
//FOURIER
//N = number of samples
//s is the array of samples(data)
//amp is the array where the complex result will be written to
//start is the where in the array to start
public void DFT(byte[] s, int N, ref Complex[] amp, int start)
{
Complex tem = new Complex();
int f;
int t;
for (f = 0; f < N; f++)
{
tem.real = 0;
tem.im = 0;
for (t = 0; t < N; t++)
{
tem.real += s[t + start] * Math.Cos(2 * Math.PI * t * f / N);
tem.im -= s[t + start] * Math.Sin(2 * Math.PI * t * f / N);
}
amp[f].real = tem.real;
amp[f].im = tem.im;
}
}
//INVERSE FOURIER
public void IDFT(Complex[] A, ref int[] s)
{
int N = A.Length;
int t, f;
double result;
for (t = 0; t < N; t++)
{
result = 0;
for (f = 0; f < N; f++)
{
result += A[f].real * Math.Cos(2 * Math.PI * t * f / N) - A[f].im * Math.Sin(2 * Math.PI * t * f / N);
}
s[t] = (int)Math.Round(result);
}
}
}
}
如果需要方法,请尝试以下方法:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SoundEditor_V3
{
public class Complex
{
public double real;
public double im;
public Complex()
{
real = 0;
im = 0;
}
public Setval (double newReal, double newIm)
{
real = newReal;
im = newIm;
}
}
}
对于另一个类,构造函数在哪里?;) 此调用应位于方法内部。到目前为止,它看起来直接位于一个类之下
//xfo.DFT(s, N, amp, 0);
同时为amp
添加ref
。(作为void DFT(..,ref Complex[]amp,…)
采用ref amp
参数
xfo.DFT(s, N, ref amp, 0);
哦,天哪,还有很多改进的余地 首先,您将类复合体用作结构,事实上,它不需要是类,所以请将其设为结构:
public struct Complex
{
public double Imaginary;
public double Real;
}
不需要构造函数,默认构造函数(编译器添加的构造函数)将根据字段的类型将字段设置为默认值,对于double
,默认值为0.0
(这是您分配给它们的*)
我还将im更名为Imaginate,不要告诉我你必须输入更多,因为你有intellisense。如果你不去下载Mono Develop或Visual Studio Express。哦,我能感觉到你的想法:我们不应该依赖工具。是的,这是编写易于阅读的代码的另一个原因,即使对于那些不熟悉的wi这些概念(它也使搜索更容易)
*:我想指出的是,0
是一个更严格的文本,0.0
是双精度的,但编译器会对此进行重新编译并优化转换,因此在实际应用中也是一样的
让我们转到fourier类,首先是DFT方法,我在下面复制了它(将复数域的名称重命名):
上一个程序(使用LinqPad编译)的输出为“1”
但让我们回到你的密码上来,好吗
我不知道什么是f
和t
。谢天谢地,我知道im是虚构的(是吗?),所以我不会重命名它们。但我会将它们的定义移到循环中:
Complex[] DFT(byte[] samples, int samplesCount, int start)
{
var result = new Complex[samplesCount];
Complex tem = new Complex();
for (int f = 0; f < samplesCount; f++)
{
tem.Real = 0;
tem.Imaginary = 0;
for (int t = 0; t < samplesCount; t++)
{
tem.Imaginary += samples[t + start] * Math.Cos(2 * Math.PI * t * f / samplesCount);
tem.Imaginary -= samples[t + start] * Math.Sin(2 * Math.PI * t * f / samplesCount);
}
result[f].Real = tem.Real;
result[f].Imaginary = tem.Imaginary;
}
return result;
}
我知道你真的只想处理数组的一部分。但是请耐心听我说……你会学到一些东西,这些代码无论如何都是有用的 接下来我要返回一个
IEnumerable
,它是一个接口,表示可以迭代以获取复杂类型对象的任何内容。我还将使用yield
关键字
另外,我已经去掉了sampleCount,改用samples.Length
看看它有多美:
//FOURIER
public IEnumerable<Complex> DFT(byte[] samples, int startIndex)
{
int samplesLength = samples.Length;
for (int f = 0; f < samplesLength; f++)
{
Complex resultItem = new Complex();
for (int t = 0; t < samplesLength; t++)
{
resultItem.Real += samples[t + startIndex] * Math.Cos(2 * Math.PI * t * f / samplesLength);
resultItem.Imaginary -= samples[t + startIndex] * Math.Sin(2 * Math.PI * t * f / samplesLength);
}
yield return resultItem;
}
}
现在…输出是…鼓轮
嗯,我看不到它,我忘了Console.ReadLine();
但是在添加了输出之后
Namespace.Complex
Namespace.Complex
Namespace.Complex
Namespace.Complex
Namespace.Complex
Namespace.Complex
Namespace.Complex
Namespace.Complex
等等,什么?碰巧我没有告诉它如何将复杂类型的对象转换为字符串。那么让我们补充一下:
public struct Complex
{
public double Imaginary;
public double Real;
public override string ToString()
{
return string.Format("Complex [Real: {0}, Imaginary: {1}]", Real, Imaginary);
}
}
现在我的输出是:
Complex [Real: 36, Imaginary: 0]
Complex [Real: -4, Imaginary: 9,65685424949238]
Complex [Real: -4, Imaginary: 4]
Complex [Real: -4, Imaginary: 1,65685424949239]
Complex [Real: -4, Imaginary: -3,91874033223161E-15]
Complex [Real: -4,00000000000001, Imaginary: -1,65685424949239]
Complex [Real: -4,00000000000002, Imaginary: -4,00000000000001]
Complex [Real: -3,99999999999997, Imaginary: -9,65685424949237]
输出正确吗?我没有什么奇怪的想法!我必须学习更多关于傅立叶的知识(但它看起来是合法的)
经验证,输出正确
最后一点注意:使用调试程序尝试代码,您可能会发现一个惊喜(提示:yield)。谢谢您的帮助;事实上,我最终解决了所有问题。 我无法访问我试图访问的区域中的方法。我必须将它们放在一个方法块中,因为这些都是在一个表单中编码的。 这是我的理解
但是,再次感谢您的所有建议,它们都很有用。向我们展示AMP声明。另外,这可能看起来很奇怪,但是发布整个文件以供您使用类,而不是这两行。文件中有一些非常愚蠢的输入错误会导致这些错误。这些行在方法中吗?如果您y在方法之外的类主体中编写代码。并确保在传递amp参数时使用ref关键字这是我对amp的声明,但很可能是错误的。
Complex[]amp=new Complex[N];
Complex tem=new Complex();只是初始化复杂类并将type和im变量设置为0。使用上面发布的方法,而不是tem.real=0;tem.im=0;只需替换为tem(0,0);编辑:更好的方法是创建getter/setter,这样您就可以在Fourier类中执行计算。好吧,它应该是Public Complex(){real=0;im=0;}
,但是即使没有构造函数声明,也会发生此错误。也许我把构造函数弄错了?对不起,伙计,我提到了tem(0,0),它实际上应该是tem.SetVal(0,0)。我编辑了上面的代码以反映变化。不用担心。我最终在fourier类中完成了我需要的计算,但随后我需要对DFT给我的值进行毕达哥拉斯运算。因此我需要将它们存储在复数中,但我需要创建一个复杂对象数组。我以前使用过一个struct,它似乎工作正常,但老师坚持最好将复杂系统作为一个整体来实现class@LuciferFayte所以你实际上需要一个数组。无论如何,仔细想想,你使用的是Visual Stuido 2012…然后你可以使用添加到.NET 4.0中的System.Numerics.Complex(它是一个结构)
Complex[] DFT(byte[] samples, int samplesCount, int start)
{
var result = new Complex[samplesCount];
Complex tem = new Complex();
for (int f = 0; f < samplesCount; f++)
{
tem.Real = 0;
tem.Imaginary = 0;
for (int t = 0; t < samplesCount; t++)
{
tem.Imaginary += samples[t + start] * Math.Cos(2 * Math.PI * t * f / samplesCount);
tem.Imaginary -= samples[t + start] * Math.Sin(2 * Math.PI * t * f / samplesCount);
}
result[f].Real = tem.Real;
result[f].Imaginary = tem.Imaginary;
}
return result;
}
//FOURIER
//start is the where in the array to start
Complex[] DFT(byte[] samples, int samplesCount, int start)
{
var result = new Complex[samplesCount];
Complex tem = new Complex();
for (int f = 0; f < samplesCount; f++)
{
tem.Real = 0;
tem.Imaginary = 0;
for (int t = 0; t < samplesCount; t++)
{
tem.Imaginary += samples[t + start] * Math.Cos(2 * Math.PI * t * f / samplesCount);
tem.Imaginary -= samples[t + start] * Math.Sin(2 * Math.PI * t * f / samplesCount);
}
result[f] = tem;
}
return result;
}
//FOURIER
public IEnumerable<Complex> DFT(byte[] samples, int startIndex)
{
int samplesLength = samples.Length;
for (int f = 0; f < samplesLength; f++)
{
Complex resultItem = new Complex();
for (int t = 0; t < samplesLength; t++)
{
resultItem.Real += samples[t + startIndex] * Math.Cos(2 * Math.PI * t * f / samplesLength);
resultItem.Imaginary -= samples[t + startIndex] * Math.Sin(2 * Math.PI * t * f / samplesLength);
}
yield return resultItem;
}
}
//FOURIER
public IEnumerable<Complex> DFT(byte[] samples)
{
int samplesLength = samples.Length;
for (int f = 0; f < samplesLength; f++)
{
Complex resultItem = new Complex();
for (int t = 0; t < samplesLength; t++)
{
resultItem.Real += samples[t] * Math.Cos(2 * Math.PI * t * f / samplesLength);
resultItem.Imaginary -= samples[t] * Math.Sin(2 * Math.PI * t * f / samplesLength);
}
yield return resultItem;
}
}
public static class Fourier
{
//FOURIER
public static IEnumerable<Complex> DFT(byte[] samples)
{
int samplesLength = samples.Length;
for (int f = 0; f < samplesLength; f++)
{
Complex resultItem = new Complex();
for (int t = 0; t < samplesLength; t++)
{
resultItem.Real += samples[t] * Math.Cos(2 * Math.PI * t * f / samplesLength);
resultItem.Imaginary -= samples[t] * Math.Sin(2 * Math.PI * t * f / samplesLength);
}
yield return resultItem;
}
}
}
class Program
{
static void Main(string[] args)
{
//display fourier
foreach (var item in Fourier.DFT(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }))
{
Console.WriteLine(item);
}
}
}
Namespace.Complex
Namespace.Complex
Namespace.Complex
Namespace.Complex
Namespace.Complex
Namespace.Complex
Namespace.Complex
Namespace.Complex
public struct Complex
{
public double Imaginary;
public double Real;
public override string ToString()
{
return string.Format("Complex [Real: {0}, Imaginary: {1}]", Real, Imaginary);
}
}
Complex [Real: 36, Imaginary: 0]
Complex [Real: -4, Imaginary: 9,65685424949238]
Complex [Real: -4, Imaginary: 4]
Complex [Real: -4, Imaginary: 1,65685424949239]
Complex [Real: -4, Imaginary: -3,91874033223161E-15]
Complex [Real: -4,00000000000001, Imaginary: -1,65685424949239]
Complex [Real: -4,00000000000002, Imaginary: -4,00000000000001]
Complex [Real: -3,99999999999997, Imaginary: -9,65685424949237]