1

-1から1までの単一の正弦波値が与えられ、正弦波周期が与えられた場合、ベクトルの最後の値が与えられた正弦波である周期長の正弦波ベクトルを返す、Octaveの.oct関数を書き込もうとしています。波の値。これまでの私のコードは次のとおりです。

#include <octave/oct.h>
#include <octave/dColVector.h>
#include <math.h>
#define PI 3.14159265

DEFUN_DLD (sinewave_recreate, args, , "args(0) sinewave value, args(1) is period")
{
octave_value_list retval;

double sinewave_value = args(0).double_value (); 
double period = args(1).double_value ();  
ColumnVector output_sinewave(period);                
double degrees_inc = 360 / period;
double output_sinewave_degrees;

output_sinewave_degrees = asin( sinewave_value ) * 180 / PI;
output_sinewave(period-1) = sin( output_sinewave_degrees * PI / 180 );

for (octave_idx_type ii (1); ii < period; ii++) // Start the loop
   {
   output_sinewave_degrees = output_sinewave_degrees - degrees_inc;

   if ( output_sinewave_degrees < 0 )
   {
   output_sinewave_degrees += 360 ;
   }  

   output_sinewave( period-1-ii ) = sin( output_sinewave_degrees * PI / 180 );
   }

retval(0) = output_sinewave;                                                          

return retval;                                                                        
}

しかし、斑点のある結果を与えています。これは、正弦波を非常に正確に再現する場合もあれば、かなり離れている場合もあることを意味します。これは、特定の正弦波を作成し、時間の最後の値を取得し、これを関数に接続して時間の経過とともに正弦波を逆方向に再作成し、2つのプロットを比較するだけで決定しました。明らかに私は何か間違ったことをしているが、何を特定できないようだ。

4

4 に答える 4

4

いくつかの三角関数公式から始めましょう:

sin(x)^2 + cos(x)^2 == 1
sin(x+y) == sin(x)*cos(y) + sin(y)*cos(x)
cos(x+y) == cos(x)*cos(y) - sin(x)*sin(y)

ある点での正弦と余弦が与えられると、事前計算と:の後xに、サイズのステップの後の値を正確に計算できます。dsd = sin(d)cd = cos(d)

sin(x+d) = sin(x)*cd + cos(x)*sd
cos(x+d) = cos(x)*cd - sin(x)*sd

初期の正弦値が与えられると、初期の正弦値を計算できます。

cos(x) = sqrt(1 - sin(x)^2)

2つの可能な平方根値に対応して、2つの可能な解決策があることに注意してください。また、これらの恒等式のすべての角度はラジアンでありd、波を戻る場合は負である必要があることに注意してください。

于 2010-10-19T12:06:02.073 に答える
1

cos(x)には2つの可能な解決策があるというマイクのメモにより、正弦波の位相のあいまいさを解決する必要があることに気づきました。この関数での2番目の成功した試みは、次のとおりです。

#include <octave/oct.h>
#include <octave/dColVector.h>
#include <math.h>
#define PI 3.14159265

DEFUN_DLD (sinewave_recreate_3, args, , "args(0) sinewave value, args(1) is period, args(2) is the phase")
{
octave_value_list retval;

double sinewave_value = args(0).double_value (); 
double period = args(1).double_value ();  
double phase = args(2).double_value ();
ColumnVector output_sinewave(period);                
double X0 = asin(sinewave_value);

if (sinewave_value < 0 & phase > 180 & phase < 270)
 {
 X0 = PI + (0 - X0); 
 }

if (sinewave_value < 0 & phase >= 270)
 {
 X0 = X0 + 2 * PI; 
 }

if (sinewave_value > 0 & phase > 90)
 {
 X0 = PI - X0; 
 }

if (sinewave_value > 0 & phase < 0)
 {
 X0 = X0 + PI / 2; 
 }

double dx = PI / 180 * (360/period);

for (octave_idx_type ii (0); ii < period; ii++) // Start the loop
 {
 output_sinewave(period-1-ii) = sin(X0 - dx * ii); 
 }

retval(0) = output_sinewave;                                                          

return retval;                                                                        
}

Keynslugにも感謝します。

于 2010-10-20T01:09:16.047 に答える
1

簡単な式があります。Pythonの例を次に示します。

import math
import numpy as np

# We are supposing step is equal to 1degree
T = math.radians(1.0/360.0)
PrevBeforePrevValue = np.sin(math.radians(49.0))            # y(t-2)
PrevValue = np.sin(math.radians(50.0))                      # y(t-1)

ValueNowRecursiveFormula = ((2.0*(4.0-T*T))/(4.0+T*T))*PrevValue - PrevBeforePrevValue

print("From RECURSIVE formula - " + str(ValueNowRecursiveFormula))

詳細はここで見つけることができます:http: //howtodoit.com.ua/en/on-the-way-of-developing-recursive-sinewave-generator/

于 2015-04-13T08:16:39.807 に答える
0

あなたは通り抜けるより簡単な方法を試みるかもしれません。覚えておいてください

y = sin(x)

その場合、の1次導関数は次のようにyなります。

dy/dx = cos(x)

したがって、計算のすべてのステップで、次の値にy等しいデルタの現在の値に追加します。

dy = cos(x) * dx

ただし、副作用として精度が低下する可能性があります。あなたはそれを何でも調べることができます。HTH。


わずかに改善された方程式はより正確になる傾向があるようです。

dy = cos(x + dx/2) * dx

これを見てください。

于 2010-10-19T06:47:39.397 に答える