I'm working with signal processing in Scilab. A low pass Butterworth filter was chosen to be applied to experimental data. First, I've created a test signal and the butterworth filter just works fine. But, when I've tried to do the same steps to the experimental data an error has occurred.
The function flts shows a message which says "flts: Arguments #1 and #2: Incompatible sizes.". How can I debug this?
I've had already tried the system function and did not work. The z variable receives the experimental data. There are some comments in Portuguese (sorry).
Here are the Scilab code:
//artificial signal for the butterworth filter
//
//clear all
clear
//
//Data
//
//acceleration data (z)
z=[];
//
//
//Sampling frequency (Hz);
wap=428;
//
//Signal frequency (Hz)
//fs=6;
//
//Noise frequency (Hz)
fn=10;
//
//Cut off frequecy (fcut)
fcut=fn/wap;
//
//Butteworth filter order (k)
k=2;
//
//Time unit=2^n (unidTempo)
n=9;
unidTempo=2^n;
//
//Time length (tempoMaximo)
tempoMaximo=(1/wap)*unidTempo;
//time
tt=0:(1/wap):((unidTempo-1)*(1/wap));
t=tt';
//
//
//Extract data length from z equals to 2^n
sn=z(1:unidTempo,1);
//
//
//
//
///////////////////////////////////// FAST FOURIER TRANSFORM - FFT ////////////////////////////////////////////////////////////////////////////////////////////
//Total time and lenght of the sample
ttotal=t($);
N=length(sn);
//
//Tempo para cada amostra (tamostra)
tamostra=ttotal/N;
//
//Taxa de aquisição (T)
T=1/tamostra;
//
//Determinar 2^n, onde n deve ser menor ou igual a Nrdt1
//n= ;
_2n=N;
//
//FFT
FFT=fft(sn);
//
//Para determinar a frequência é necessário realizar N-1. Neste caso, cria-se um vetor de uma linha e depois transforma-o em colunna. Deve-se incluir a
//variável (Nfft=1:1:___), onde o último espaço deve ser igual ao número de registros de aceleração.Assim:
Nfft=1:1:N;
//
//A transformação da linha em coluna é:
Nfft_t=Nfft';
//
//O N-1 sempre apresenta o primeiro valor da célula igual a zero e é realizado com:
N_1=Nfft_t-1;
//
//Dados de frequência - o primeiro valor é sempre zero:
fft_freq=(T/N)*(N_1);
//
//Dados de magnitude
fft_mag=(T/N)*abs(FFT);
//
//Gráfico de frequência resultante - selecionar apenas metade do gráfico
plot(fft_freq,fft_mag);xlabel('Frequência (Hz)');ylabel('Magnitude (dB)');title('Frequência x Magnitude');
//
//
//
//
//
//
///////////////////////////////////////////////////////////////////////////Filtro Butterworth from iir function//
hz=iir(k,'lp','butt',[fcut 0],[])
//Change from transfer function to linear system
sl= tf2ss(hz)
//
//Filter the signal
fs=flts(sn,sl);
The input parameter to flts must be of size 1xn in your case (sl has one input), so change the last line to
fs=flts(sn',sl);
or make sure that input vector is always a row vector.
Related
I am writing this linear system solver for an university assignment, and I have incurred in quite a weird problem. I have defined a recursive function
for calculating the determinant of a square matrix through Laplace's first theorem, which seems to work just fine in all the test cases I have tried.
In the body of the program I then use a do loop to implement Cramer's rule for linear systems, calculating the determinant for the n matrices with the ith column substituted with the known terms of the system. At this moment the determinant function I have defined seems to start misbehaving, and in a pretty specific way: testing with dimension 3 matrices, the det of the matrix with the first column substituted is correct, but that of the second and third is the sum of what is supposed to be the correct determinant and the determinants of the preceding matrices. I am setting the value of the variable where I store this data to zero at every iteration of the loop (and there are no summation operators in that fragment of code so I can't see where this behavior would arise from). Like I said, I have tried quite a lot of test cases so it would seem unlikely that it is just a random occurrence. Since I am no expert in Fortran (nor in programming in general) it very well could be some very simple mistake I am completely missing, but for now I haven't been able to spot it.
module functions
implicit none
contains
recursive function determinant (m, mat2) result (det) !nel definire le funzioni recursive è necessario chiamare la proprietà RESULT
implicit none !e dichiarare esplicitamente la variabile che la funzione ritorna.
integer, intent(in) :: m
real, intent(in), dimension(m, m) :: mat2
integer :: x, sgn = -1
real :: submat(m-1, m-1), det
if (m == 1) then
det = mat2(1, 1)
else if(m == 0) then
det = 0
else if(m==2) then
det = mat2(1,1)*mat2(2,2) - mat2(1,2)*mat2(2,1) !calcolo esplicito del determinante di una matrice quadrata di dimensione 2
else
do x =1, m !il teorema di laplace viene applicato alla prima colonna della matrice
submat(1:x-1, 1:m-1) = mat2(1:x-1, 2:m) !si definisce la sottomatrice associata attraverso
submat(x:m-1, 1:m-1) = mat2(x+1:m, 2:m) !lo slicing dell'array multidimensionale di partenza
det = det + (sgn**(x+1))*mat2(x, 1) * determinant(m-1, submat) !implementazione ricorsiva del primo teorema di Laplace
end do
end if
end function determinant
end module functions
program gaia_leita
use functions
implicit none
real(KIND=16) :: start, finish
integer :: n, i, j, h
real, allocatable :: matrix(:,:), sol_vec(:), known_terms(:)
real, allocatable :: cramer_matrix(:,:)
real :: deter, cr_det = 0
write(*,*) "Questo programma calcola il determinante di una matrice M NxN"
write(*,*) "Inserire la dimensione della matrice:"
read(*,*) n
allocate(matrix(n, n))
write(*,*) "Inserire le entrate della matrice M riga per riga:"
do i = 1, n
do j = 1, n
read(*, *) matrix(i, j)
end do
end do
call cpu_time(start)
deter = determinant(n, matrix)
write(*, *) "Il determinante della matrice M è: |M| = ", deter
write(*,*) "Per risolvere il sistema lineare M*v = b inserire i valori dei termini noti b1...bn:"
allocate(known_terms(n))
allocate(sol_vec(n))
allocate(cramer_matrix(n, n))
do i = 1, n
read(*, *) known_terms(i)
end do
!metodo di cramer per la risoluzione dei sistemi lineari
if(deter == 0) then
write(*,*) "Il sistema non soddisfa le ipotesi del metodo di Cramer"
else
cramer_matrix = matrix
do i = 1, n
cr_det = 0
cramer_matrix = matrix
cramer_matrix(:, i) = known_terms(:)
do j = 1, n
do h=1, n
write(*,*) cramer_matrix(j, h)
end do
end do
cr_det = determinant(n, cramer_matrix)
write(*, *) cr_det
write(*,*)
sol_vec(i) = cr_det/ deter
write(*,*)
end do
end if
Write(*,*) "La soluzione del sistema è il vettore x = ( "
do i = 1, n
write(*,*) sol_vec(i), " "
end do
write(*,*) ")"
deallocate(matrix)
deallocate(known_terms)
deallocate(sol_vec)
deallocate(cramer_matrix)
call cpu_time(finish)
write(*,*) "Time elapsed:", finish-start, "seconds"
read(*,*)
end program gaia_leita
(ignore the comments, I am italian) Thanks a lot, I hope I'm not wasting anyone's time. Here is a test run:
Questo programma calcola il determinante di una matrice M NxN
Inserire la dimensione della matrice:
3
Inserire le entrate della matrice M riga per riga:
2
3
6
-5
-3
5
1
0
2
Il determinante della matrice M è: |M| = 51.0000000
Per risolvere il sistema lineare M*v = b inserire i valori dei termini noti b1...bn:
3
2
4
3.00000000
3.00000000
6.00000000
2.00000000
-3.00000000
5.00000000
4.00000000
0.00000000
2.00000000
102.000000
2.00000000
3.00000000
6.00000000
-5.00000000
2.00000000
5.00000000
1.00000000
4.00000000
2.00000000
-17.0000000
2.00000000
3.00000000
3.00000000
-5.00000000
-3.00000000
2.00000000
1.00000000
0.00000000
4.00000000
34.0000000
La soluzione del sistema è il vettore x = (
2.00000000
-0.333333343
0.666666687
)
The values following the substituted matrices are the determinants as given by the program: only the first one is correct, while the other ones are the sum of the correct value and the preceding values.
at the time i am in the process of learning pascal but i have some question that google can't answer, so i am trying to do a program that analyzes how much overweight does a person have relating to a set of data. the thing is that i don;t know how to make another window or to clear the window so that only the results appear in the screen, My teacher wants something like this (Don't mind the spanish ;D ) :
And Here is my code so far:
Program AddNums(output);
uses crt;
var
s, b, a, v: integer;
begin
clrscr;
GotoXY(20, 1);
writeln('Ejercicio 2 - Actividad 2');
GotoXY(25, 3);
writeln('Calculadora de Pesos');
write('Introduce la cantidad de personas para analizar sus pesos: ');
readln(s);
for a := 1 to s do
begin
writeln('Introduzca el peso de la persona numero', a, ':');
readln(v)
end;
clrscr;
if (v <= 90) then
write('Cantidad de personas con Sobrepeso: ...........', v + 1);
else if (v <= 30) then
write('Cantidad de personas con Bajo Peso: ...........', v + 1);
else if (v <= 30 AND v >= 90) then
write('Cantidad de Personas con Peso normal: ...........', v + 1);
else
write('null');
end.
And this
is the error that i am encountering right now
(35,4) Fatal: Syntax error, ";" expected but "ELSE" found
Fatal: Compilation aborted
Hope you guys help me !!
The last few lines of your code need to be corrected as shown below in order to compile, and then you need to check that the code does what you want it to. The program should then compile, and assuming you are running it in an environment like Lazarus, the IDE for Free Pascal, it will appear in a console window as #TomBrunberg has commentedThere were basically two problems with it:
The first three elses were preceded by a semicolon (;). That is a syntax error. Each else is part of an if ... then ...else block. The only circumstances when a semicolon is permitted is when it is inside a compound statement, for example a begin ... end block, as in
begin
DoSomething;
end
else
write('Cantidad de personas con Sobrepeso: ...........', v + 1)
The other problem was that you had
(v <= 30 AND v >= 90)
The syntax problem with that is that in Pascal, and has higher operator precedence than <= so the compiler tries, and fails, to evaluate 30 and v. It fails because the result should be of type Boolean, which it cannot be. To avoid that problem, you need to close the parenthesese, like this
(v <= 30) and (v >= 90)
Then, the expressions on either side of the and both evaluate to Booleans, so the compiler can successfully combine then with and. However, as #Tom has pointed out in a comment, the combined expression can never evaluate to True because v cannot be less or equal to 30 and greater or equal to 90 at the same time: perhaps you meant OR?
Corrected code
if (v <= 90) then
write('Cantidad de personas con Sobrepeso: ...........', v + 1)
else if (v <= 30) then
write('Cantidad de personas con Bajo Peso: ...........', v + 1)
else if (v <= 30) AND (v >= 90) then
write('Cantidad de Personas con Peso normal: ...........', v + 1)
else
write('null');
readln;
The readln at the end makes the program wait for you to press the Enter so that it stays on-screen long enough for you to see it - without the readln, the console window would just close and vanish.
Im trying to studie likelihood estimation of the transition and emission matrices of an Hmm via a sequence of observation provided from 2 hidden states and 3 possible values at each state
using SeqHmm to generate the sequence
#déclaration des matrices de transition et d 'emission
P.trans <- t(matrix(c(0.2,0.8,
0.7,0.3),nrow=2,ncol=2))
P.emiss <- t(matrix(c(0.2,0.6,0.2,
0.3,0.5,0.2),nrow=3,ncol=2))
# simuler un hmm avec la fonction du package seqHMM
sim <- simulate_hmm(n_sequence=1,transition_probs = P.trans,
emission_probs = P.emiss, initial_probs = c(1/2,1/2),
sequence_length = 100)
# transformer les observations comme un vecteur numeric
sim.obs <- as.numeric(gsub('\\-', ' ', sim$observations))
using Hamilton's 1988 to calculate the log-likelihood function
llh <- function(p,y){
# matrice de transition de la chaine cachée
trans.mat <- matrix(c(1-p[1],p[1],
p[2],1-p[2]), nrow=2, ncol = 2,byrow = TRUE)
# matrice d'émissions
emiss.mat <- matrix(c(p[3],1-p[3]-p[4],p[4],
p[5], p[6],1-p[5]-p[6]), nrow=2,ncol=3,byrow = TRUE)
# la longueur de la chaine
T <- length(y)
Pr <- numeric(T)
#distribution initiale
V <- c(1/2,1/2)
# calcul de la vraisemblance
for(c in 1:T){
w = numeric(nrow(trans.mat))
#i = Y[c-1]
j = y[c]
for (k in 1:nrow(trans.mat)) {
w[k] = 0
for (l in 1:nrow(trans.mat)) {
w[k] = w[k] + V[l]*trans.mat[l,k]*emiss.mat[l,j]
}
}
Pr[c]= sum(w)
V=w/sum(w)
}
# on ajout le - pour minimiser la fonction au lieu de la maximiser
bjf = -sum(log(Pr))
return(bjf)
}
using optim the minimize the - log-likelihood function
prob.init.optim <-c(0.5,0.1,0.3,0.4,0.3,0.7)
# lancer optim
optim(par=prob.init.optim, fn=llh, y=sim.obs)
it returns a negative probabilities values !! does any one can help ?
I want to generate a PWM signal. I have not achieved the expected result.
close all
clear all
fs=1000;
ts=1/fs;
t=[-5:ts:5];
fc =10; %Frecuencia señal portadora
fm = 1; %Frecuencia señal del mensaje
a = 5; %Amplitud de la señal portadora
b = 0.25; %Amplitud de la señal del mensaje
vm = b.*sin(2*pi*fm*t); %Genera la Señal del mensaje
bits = [1, 0, 1, 1];
amp = (2*bits-1);
vc = rect(t/b) + rect((t+1)/b) ...
+ rect((t+2)/b) + rect((t+3)/b)+ rect((t+4)/b)+ rect((t+5)/b)+...
rect((t-1)/b) ...
+ rect((t-2)/b) + rect((t-3)/b)+ rect((t-4)/b)+ rect((t-5)/b)
n = length(vc);
for i = 1:n
if (vm(i)>=vc(i))
pwm(i) = 1;
else
pwm(i) = 0;
end
end
I don't get the real PWM signal. Help me.
Im trying to construct an AD-converter from a potentiometer to an Arduino. I´m trying to learn MCC in MPLAB at the same time. So far I have generated a code that fits my PIC (I think...). My problem is now that my bit represented output is incorrect. This is hoe my PIC16F1827 is configured (se picture)
RA0 = input, RB1 and RB2 = EUSART and RB0,RB3,RA7,RA6,RB7,RB6,RB5,RB4 = output.
My main file look like this (se code). I get an output but its represented wrong and i can´t figure ut why...
char ADC_temp_in;
while (1) //Infinite Loop
{
// Add your application code
printf("pot_value =%d\r\n", ADC_GetConversion(channel_AN0_ADC));
ADC_temp_in = ADC_GetConversion(channel_AN0_ADC); // temp
PORTB = ADC_temp_in; //Write Lower bits to PORTB
PORTA = ADC_temp_in>>6; //Write Higher 2 bits to PORTA
__delay_ms(100); //Delay
}
VREF+ = 5V and is connected directly to VDD.
My goal is to have RB0 as LSB and RA7 as MSB with the voltage difference 0-5 V with the potentiometer.
Two things:
ADC_temp_in had to by a 16 Bit value to hold a value greater than 8 Bit.
So try: uint16_t ADC_temp_in;
Of course your function ADC_GetConversion had to return a uint_16 value.
Another thing is, to get the MSB you had to shift your value 8 times right.
PORTA = ADC_temp_in>>8;