2013-02-18 15 views

risposta

2

Un'alternativa è usare Modelica.Blocks.Noise per evitare di scrivere codice esterno da soli (aggiunto in Modelica Standard Library 3.2.2 rilasciato il 3 aprile 2016; cioè non avrebbe aiutato quando è stata posta la domanda originale).

Un vantaggio di Modelica.Blocks.Noise è che le domande difficili con campionamento, più semi, ecc. Sono risolti.

8

È possibile aggiungere rumore bianco in Wolfram SystemModeler tramite codice C esterno.

codice Modelica (ho rimosso le annotazioni dello schema del codice, in modo che possa essere più facile da leggere):

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; 

codice esterno:

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

Aggiungerei una funzione alternativa 'ext_initRandomNormaWithSeed' per consentire all'utente di passare un valore di inizializzazione. In questo modo, è possibile riprodurre il segnale di rumore. Qual è il punto della variabile 'seed' in' ext_RandomNormal'? Mi sto perdendo qualcosa? Sembra essere calcolato ma mai usato. –

+3

Per essere ancora più rigidi, potresti voler usare un 'ExternalObject' che conserva lo stato. Se devi usare diverse fonti 'WhiteNoise' usando il codice sopra, esse" interagiranno "tra loro (una influenzerà l'altra). –