2013-02-18 9 views

Odpowiedz

2

Alternatywą jest użycie Modelica.Blocks.Noise, aby uniknąć samodzielnego pisania kodu zewnętrznego (dodane w Modelica Standard Library 3.2.2 wydany 3 kwietnia 2016 r .; to nie pomogłoby, gdyby zadane zostało pierwotne pytanie).

Jedną z zalet Modelica.Blocks.Noise jest to, że trudne pytania z próbkowaniem, wieloma nasionami itp. Są rozwiązywane.

8

Możesz dodać szum biały w Wolfram SystemModeler poprzez zewnętrzny kod C.

kod Modelica (I zostały usunięte adnotacje schemat z kodu, tak, że może to być łatwiejsze do odczytania):

package WhiteNoise "Package for generating white noise" 
    extends Modelica.Icons.Library; 

    block NoiseNormal "Normally distributed random noise" 
    parameter Real mean=0 "Mean value of random noise"; 
    parameter Real stdev=1 "Standard deviation of random noise"; 
    parameter Real tSample=0.01 "Noise sample time"; 
    Modelica.Blocks.Interfaces.RealOutput y; 
    equation 
    when initial() then 
     WhiteNoise.initRandomNormal(); 
    end when; 
    when sample(0, tSample) then 
     y=mean + stdev*WhiteNoise.RandomNormal(time); 
    end when; 
    end NoiseNormal; 

    function initRandomNormal 
    external "C" ext_initRandomNormal() annotation(Include="#include \"ext_initRandNormal.c\""); 
    end initRandomNormal; 

    function RandomNormal 
    output Real y; 
    input Real u; 
    external "C" y=ext_RandomNormal(u) annotation(Include="#include \"ext_RandNormal.c\""); 
    end RandomNormal; 

end WhiteNoise; 

kod zewnętrzna:

ext_intRandNormal.c

#include <math.h> 
#include <limits.h> 

void ext_initRandomNormal() 
{ 
    srand(time(NULL)); 
} 

ext_RandNormal.c

#include <math.h> 
#include <limits.h> 
double ext_RandomNormal(double timein) 

{ 
    unsigned int seed = 0; 
    double v1, v2, r; 

    timein /= 100; 
    seed = (timein - floor(timein)) * UINT_MAX; 

    do 
    { 
     v1 = 2 * ((double) rand()) /((double) RAND_MAX) - 1; 
     v2 = 2 * ((double) rand()) /((double) RAND_MAX) - 1; 
     r = v1 * v1 + v2 * v2; 
    } while((r >= 1.0) || (r == 0.0)); 

    return v1 * sqrt(- 2.0 * log(r)/r); 
} 
+2

Dodałbym alternatywną funkcję 'ext_initRandomNormaWithSeed', aby umożliwić użytkownikowi przekazanie wartości początkowej. W ten sposób można odtworzyć sygnał szumu. Jaki jest sens zmiennej 'seed' w' ext_RandomNormal'? Czy czegoś brakuje? Wygląda na to, że został obliczony, ale nigdy nie był używany. –

+3

Aby być jeszcze bardziej rygorystycznym, możesz chcieć użyć 'ExternalObject', który zachowuje stan. Jeśli musisz użyć różnych źródeł "WhiteNoise" używając powyższego kodu, będą one "oddziaływać" na siebie (jeden wpłynie na drugi). –