commit 2522e086c98627cfd75833d4e3c3cd9c1b8ab178 from: Ale date: Tue Mar 10 02:24:20 2026 UTC Add IntelliJ IDEA project configuration files and initial MATLAB testing script commit - 7446aa2455cdb0b2bd371f3c497b61b25b7aa8c8 commit + 2522e086c98627cfd75833d4e3c3cd9c1b8ab178 blob - /dev/null blob + ab1f4164edbbb088e58dd5d21bbc1f42816bc1ff (mode 644) --- /dev/null +++ .idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ blob - /dev/null blob + d6ebd4805981b8400db3e3291c74a743fef9a824 (mode 644) --- /dev/null +++ .idea/Proyecto-Fisica-2do.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file blob - /dev/null blob + a20905f6a73dacdd40ef3a87b62bd5f6a8bffce1 (mode 644) --- /dev/null +++ .idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file blob - /dev/null blob + e774d3eb9d012bc24b6283462868e49202827365 (mode 644) --- /dev/null +++ .idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file blob - /dev/null blob + 35eb1ddfbbc029bcab630581847471d7f238ec53 (mode 644) --- /dev/null +++ .idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file blob - /dev/null blob + c4af665edddab21ea8277b6eb807f960f7c7e963 (mode 644) --- /dev/null +++ script_prueba_demostracion.m @@ -0,0 +1,358 @@ +%% SCRIPT DE PRUEBA Y DEMOSTRACIÓN +% Proyecto Integrado: Láser-Fotosensor-Sonido Reconstruido +% Prueba todos los módulos sin necesidad de hardware real + +clear all; close all; clc; + +fprintf('╔════════════════════════════════════════════════════════════════╗\n'); +fprintf('║ SISTEMA DE RECONSTRUCCIÓN DE SONIDO CON LÁSER Y FOTOSENSOR ║\n'); +fprintf('║ Física 2do Semestre - Ondas, Oscilaciones y Espacios Vect. ║\n'); +fprintf('╚════════════════════════════════════════════════════════════════╝\n\n'); + +%% PARÁMETROS DEL SISTEMA +fprintf('CONFIGURANDO PARÁMETROS DEL SISTEMA...\n'); + +fs = 44100; +duracion = 3; +t = (0:1/fs:duracion-1/fs)'; +ruido_fotosensor = 0.05; + +fprintf(' ✓ Frecuencia de muestreo: %d Hz\n', fs); +fprintf(' ✓ Duración: %.1f segundos\n', duracion); +fprintf(' ✓ Número de muestras: %d\n\n', length(t)); + +%% ======================================================================== +% PRUEBA 1: GENERACIÓN DE SEÑALES ACÚSTICAS +%% ======================================================================== +fprintf('╭─ PRUEBA 1: GENERACIÓN DE SEÑALES ACÚSTICAS\n'); + +fprintf(' Generando tono puro (1000 Hz)...\n'); +f_puro = 1000; +senial_pura = 0.5 * sin(2*pi*f_puro*t); +senial_pura_ruidosa = senial_pura + ruido_fotosensor * randn(size(t)); + +fprintf(' Generando acorde musical (Do Mayor: 262-330-392 Hz)...\n'); +f_do = 262; +f_mi = 330; +f_sol = 392; +senial_acorde = 0.3*sin(2*pi*f_do*t) + 0.3*sin(2*pi*f_mi*t) + 0.3*sin(2*pi*f_sol*t); +senial_acorde_ruidosa = senial_acorde + ruido_fotosensor * randn(size(t)); + +fprintf(' Generando barrido de frecuencia (100-1000 Hz)...\n'); +senial_chirp = chirp(t, 100, duracion, 1000, 'linear') * 0.5; +senial_chirp_ruidosa = senial_chirp + ruido_fotosensor * randn(size(t)); + +fprintf(' Generando señal compleja (múltiples armónicos)...\n'); +senial_compleja = zeros(size(t)); +for k = 1:5 + senial_compleja = senial_compleja + (1/k) * sin(2*pi*f_do*k*t); +end +senial_compleja = senial_compleja * 0.5; +senial_compleja_ruidosa = senial_compleja + ruido_fotosensor * randn(size(t)); + +fprintf('╰─ Completado: 4 tipos de señales generadas\n\n'); + +%% ======================================================================== +% PRUEBA 2: ANÁLISIS ESPECTRAL (FFT) +%% ======================================================================== +fprintf('╭─ PRUEBA 2: ANÁLISIS ESPECTRAL (TRANSFORMADA DE FOURIER)\n'); + +[f1, mag1, ~] = calcular_fft_sistema(senial_pura_ruidosa, fs); +[f2, mag2, ~] = calcular_fft_sistema(senial_acorde_ruidosa, fs); +[f3, mag3, ~] = calcular_fft_sistema(senial_chirp_ruidosa, fs); +[f4, mag4, ~] = calcular_fft_sistema(senial_compleja_ruidosa, fs); + +fprintf(' Identificando componentes principales:\n\n'); + +[~, idx] = findpeaks(mag1, 'MinPeakHeight', max(mag1)*0.2); +fprintf(' Tono puro (1000 Hz):\n'); +fprintf(' Picos detectados: %s Hz\n', sprintf('%.0f ', f1(idx))); + +[~, idx] = findpeaks(mag2, 'MinPeakHeight', max(mag2)*0.2); +fprintf(' Acorde (262, 330, 392 Hz):\n'); +fprintf(' Picos detectados: %s Hz\n', sprintf('%.0f ', f2(idx))); + +fprintf('╰─ Completado: FFT calculado para todas las señales\n\n'); + +%% ======================================================================== +% PRUEBA 3: DESCOMPOSICIÓN EN VALORES SINGULARES (SVD) +%% ======================================================================== +fprintf('╭─ PRUEBA 3: ANÁLISIS SVD (ESPACIOS VECTORIALES)\n'); + +[U1, S1, V1, var1] = analizar_svd(senial_pura_ruidosa); +[U2, S2, V2, var2] = analizar_svd(senial_acorde_ruidosa); +[U3, S3, V3, var3] = analizar_svd(senial_chirp_ruidosa); +[U4, S4, V4, var4] = analizar_svd(senial_compleja_ruidosa); + +fprintf(' Rangos numéricos de matrices de trayectoria:\n\n'); +fprintf(' Tono puro: rango = %d, varianza en 5 modos = %.1f%%\n', ... + rank(U1*S1*V1'), var1(min(5, length(var1)))); +fprintf(' Acorde: rango = %d, varianza en 5 modos = %.1f%%\n', ... + rank(U2*S2*V2'), var2(min(5, length(var2)))); +fprintf(' Barrido: rango = %d, varianza en 5 modos = %.1f%%\n', ... + rank(U3*S3*V3'), var3(min(5, length(var3)))); +fprintf(' Compleja: rango = %d, varianza en 5 modos = %.1f%%\n', ... + rank(U4*S4*V4'), var4(min(5, length(var4)))); + +fprintf('\n Interpretación:\n'); +fprintf(' - Mayor rango = más información, menor redundancia\n'); +fprintf(' - Tono puro: bajo rango (señal simple)\n'); +fprintf(' - Acorde: rango moderado (3 componentes)\n'); +fprintf(' - Barrido: alto rango (contenido variante)\n'); +fprintf(' - Compleja: alto rango (muchos armónicos)\n'); +fprintf('╰─ Completado: Análisis SVD realizado\n\n'); + +%% ======================================================================== +% PRUEBA 4: FILTRADO Y RECONSTRUCCIÓN +%% ======================================================================== +fprintf('╭─ PRUEBA 4: FILTRADO Y RECONSTRUCCIÓN DE SEÑALES\n'); + +fprintf(' Reconstruyendo señales usando filtrado FFT...\n'); +senial_pura_rec = reconstruir_por_fft(senial_pura_ruidosa); +senial_acorde_rec = reconstruir_por_fft(senial_acorde_ruidosa); +senial_chirp_rec = reconstruir_por_fft(senial_chirp_ruidosa); +senial_compleja_rec = reconstruir_por_fft(senial_compleja_ruidosa); + +fprintf(' Calculando métricas de error:\n\n'); + +[err1, snr1, cor1] = calcular_metricas(senial_pura, senial_pura_rec); +[err2, snr2, cor2] = calcular_metricas(senial_acorde, senial_acorde_rec); +[err3, snr3, cor3] = calcular_metricas(senial_chirp, senial_chirp_rec); +[err4, snr4, cor4] = calcular_metricas(senial_compleja, senial_compleja_rec); + +fprintf(' Tono puro: Error RMS = %.6f, SNR = %.2f dB, Corr = %.4f\n', err1, snr1, cor1); +fprintf(' Acorde: Error RMS = %.6f, SNR = %.2f dB, Corr = %.4f\n', err2, snr2, cor2); +fprintf(' Barrido: Error RMS = %.6f, SNR = %.2f dB, Corr = %.4f\n', err3, snr3, cor3); +fprintf(' Compleja: Error RMS = %.6f, SNR = %.2f dB, Corr = %.4f\n', err4, snr4, cor4); +fprintf('╰─ Completado: Reconstrucción y validación\n\n'); + +%% ======================================================================== +% PRUEBA 5: VISUALIZACIÓN INTEGRAL +%% ======================================================================== +fprintf('╭─ PRUEBA 5: VISUALIZACIÓN DE RESULTADOS\n'); + +figure('Name', 'Sistema Láser-Fotosensor - Resultados Completos', ... + 'Position', [100, 100, 1400, 1000]); + +t_zoom = t(1:2000); + +% --- TONO PURO --- +subplot(4,4,1); +plot(t_zoom, senial_pura(1:2000), 'b-', 'LineWidth', 1.5); +title('Tono Puro - Señal Ideal', 'FontWeight', 'bold'); +xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; + +subplot(4,4,2); +h = plot(t_zoom, senial_pura_ruidosa(1:2000), 'b-', 'LineWidth', 0.8); +h.Color(4) = 0.6; +title('Tono Puro - Capturado (ruidoso)', 'FontWeight', 'bold'); +xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; + +subplot(4,4,3); +plot(t_zoom, senial_pura_rec(1:2000), 'g-', 'LineWidth', 1.5); +title('Tono Puro - Reconstruido', 'FontWeight', 'bold'); +xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; + +subplot(4,4,4); +rango_f = f1 <= 2000; +stem(f1(rango_f), mag1(rango_f), 'filled', 'MarkerSize', 4); +title(sprintf('FFT Tono Puro\n(SNR=%.1f dB)', snr1), 'FontWeight', 'bold'); +xlabel('Frecuencia (Hz)'); ylabel('|Magnitud|'); grid on; + +% --- ACORDE --- +subplot(4,4,5); +plot(t_zoom, senial_acorde(1:2000), 'r-', 'LineWidth', 1.5); +title('Acorde - Señal Ideal', 'FontWeight', 'bold'); +xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; + +subplot(4,4,6); +h = plot(t_zoom, senial_acorde_ruidosa(1:2000), 'r-', 'LineWidth', 0.8); +h.Color(4) = 0.6; +title('Acorde - Capturado (ruidoso)', 'FontWeight', 'bold'); +xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; + +subplot(4,4,7); +plot(t_zoom, senial_acorde_rec(1:2000), 'g-', 'LineWidth', 1.5); +title('Acorde - Reconstruido', 'FontWeight', 'bold'); +xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; + +subplot(4,4,8); +rango_f = f2 <= 1000; +stem(f2(rango_f), mag2(rango_f), 'filled', 'MarkerSize', 4); +title(sprintf('FFT Acorde\n(SNR=%.1f dB)', snr2), 'FontWeight', 'bold'); +xlabel('Frecuencia (Hz)'); ylabel('|Magnitud|'); grid on; + +% --- BARRIDO --- +subplot(4,4,9); +plot(t_zoom, senial_chirp(1:2000), 'm-', 'LineWidth', 1.5); +title('Barrido - Señal Ideal', 'FontWeight', 'bold'); +xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; + +subplot(4,4,10); +h = plot(t_zoom, senial_chirp_ruidosa(1:2000), 'm-', 'LineWidth', 0.8); +h.Color(4) = 0.6; +title('Barrido - Capturado (ruidoso)', 'FontWeight', 'bold'); +xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; + +subplot(4,4,11); +plot(t_zoom, senial_chirp_rec(1:2000), 'g-', 'LineWidth', 1.5); +title('Barrido - Reconstruido', 'FontWeight', 'bold'); +xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; + +subplot(4,4,12); +rango_f = f3 <= 2000; +stem(f3(rango_f), mag3(rango_f), 'filled', 'MarkerSize', 4); +title(sprintf('FFT Barrido\n(SNR=%.1f dB)', snr3), 'FontWeight', 'bold'); +xlabel('Frecuencia (Hz)'); ylabel('|Magnitud|'); grid on; + +% --- SEÑAL COMPLEJA --- +subplot(4,4,13); +plot(t_zoom, senial_compleja(1:2000), 'c-', 'LineWidth', 1.5); +title('Compleja - Señal Ideal', 'FontWeight', 'bold'); +xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; + +subplot(4,4,14); +h = plot(t_zoom, senial_compleja_ruidosa(1:2000), 'c-', 'LineWidth', 0.8); +h.Color(4) = 0.6; +title('Compleja - Capturado (ruidoso)', 'FontWeight', 'bold'); +xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; + +subplot(4,4,15); +plot(t_zoom, senial_compleja_rec(1:2000), 'g-', 'LineWidth', 1.5); +title('Compleja - Reconstruido', 'FontWeight', 'bold'); +xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; + +subplot(4,4,16); +rango_f = f4 <= 2000; +stem(f4(rango_f), mag4(rango_f), 'filled', 'MarkerSize', 4); +title(sprintf('FFT Compleja\n(SNR=%.1f dB)', snr4), 'FontWeight', 'bold'); +xlabel('Frecuencia (Hz)'); ylabel('|Magnitud|'); grid on; + +fprintf(' ✓ Visualización generada\n'); +fprintf('╰─ Completado: Gráficos de resultados\n\n'); + +%% ======================================================================== +% PRUEBA 6: ANÁLISIS SVD DETALLADO +%% ======================================================================== +fprintf('╭─ PRUEBA 6: ANÁLISIS DETALLADO SVD - ESPACIOS VECTORIALES\n'); + +figure('Name', 'Análisis SVD - Espacios Vectoriales'); + +subplot(2,2,1); +semilogy(diag(S1), 'bo-', 'LineWidth', 2, 'MarkerSize', 6); +xlabel('Modo (i)'); ylabel('Valor Singular σᵢ'); +title('SVD - Tono Puro (bajo rango)', 'FontWeight', 'bold'); +grid on; + +subplot(2,2,2); +semilogy(diag(S2), 'ro-', 'LineWidth', 2, 'MarkerSize', 6); +xlabel('Modo (i)'); ylabel('Valor Singular σᵢ'); +title('SVD - Acorde (3 componentes)', 'FontWeight', 'bold'); +grid on; + +subplot(2,2,3); +semilogy(diag(S3), 'mo-', 'LineWidth', 2, 'MarkerSize', 6); +xlabel('Modo (i)'); ylabel('Valor Singular σᵢ'); +title('SVD - Barrido (alto rango)', 'FontWeight', 'bold'); +grid on; + +subplot(2,2,4); +semilogy(diag(S4), 'co-', 'LineWidth', 2, 'MarkerSize', 6); +xlabel('Modo (i)'); ylabel('Valor Singular σᵢ'); +title('SVD - Compleja (muchos armónicos)', 'FontWeight', 'bold'); +grid on; + +fprintf(' ✓ Análisis SVD visualizado\n'); +fprintf('╰─ Completado: Estudio de descomposición matricial\n\n'); + +%% ======================================================================== +% RESUMEN Y CONCLUSIONES +%% ======================================================================== +fprintf('╔════════════════════════════════════════════════════════════════╗\n'); +fprintf('║ RESUMEN DE RESULTADOS ║\n'); +fprintf('╚════════════════════════════════════════════════════════════════╝\n\n'); + +tabla = array2table(... + [1000, err1, snr1, cor1; ... + 262, err2, snr2, cor2; ... + 100, err3, snr3, cor3; ... + 262, err4, snr4, cor4], ... + 'VariableNames', {'Frecuencia_Hz', 'Error_RMS', 'SNR_dB', 'Correlacion'}, ... + 'RowNames', {'Tono Puro', 'Acorde', 'Barrido', 'Compleja'}); + +disp(tabla); + +fprintf('\nINTERPRETACIÓN:\n'); +fprintf(' • Error RMS: Diferencia entre original y reconstruida\n'); +fprintf(' • SNR (dB): Razón señal-ruido en la reconstrucción\n'); +fprintf(' • Correlación: 1.0 = perfecta, 0.0 = sin relación\n'); + +fprintf('\n╔════════════════════════════════════════════════════════════════╗\n'); +fprintf('║ PRUEBAS COMPLETADAS EXITOSAMENTE ║\n'); +fprintf('║ ║\n'); +fprintf('║ Sistema listo para usar con datos reales del fotosensor ║\n'); +fprintf('╚════════════════════════════════════════════════════════════════╝\n\n'); + +fprintf('Archivos generados:\n'); +fprintf(' ✓ %d figuras con resultados\n', length(findobj('Type', 'figure'))); +fprintf(' ✓ Datos de prueba en memoria (variables: senial_*)\n'); +fprintf(' ✓ Métricas de validación calculadas\n'); + +%% ======================================================================== +% FUNCIONES LOCALES (siempre al final del script) +%% ======================================================================== + +function [f, mag, Y] = calcular_fft_sistema(senial, fs) + N = length(senial); + Y = fft(senial); + mag = abs(Y(1:N/2)) / N; + f = fs * (0:N/2-1) / N; +end + +function [U, S, V, varianza_ac] = analizar_svd(senial) + ventana = max(2, round(length(senial) / 100)); + cols = length(senial) - ventana + 1; + M = zeros(ventana, cols); + for i = 1:ventana + M(i,:) = senial(i : i + cols - 1)'; + end + [U, S, V] = svd(M, 'econ'); + sv = diag(S); + varianza_ac = cumsum(sv.^2) / sum(sv.^2) * 100; +end + +function senial_rec = reconstruir_por_fft(senial_ruidosa) + N = length(senial_ruidosa); + Y = fft(senial_ruidosa); + + % Magnitud del espectro unilateral (DC hasta Nyquist inclusive) + mag_pos = abs(Y(1 : floor(N/2) + 1)); + umbral = max(mag_pos) * 0.1; + + % Máscara unilateral + mascara_pos = double(mag_pos > umbral); + + % Máscara completa con simetría hermitiana correcta para N par + mascara = zeros(N, 1); + mascara(1 : floor(N/2) + 1) = mascara_pos; % DC … Nyquist + mascara(floor(N/2) + 2 : N) = flipud(mascara_pos(2 : floor(N/2))); % conjugados + + senial_rec = real(ifft(Y .* mascara)); +end + +function [error_rms, snr_val, correlacion] = calcular_metricas(original, reconstruida) + % Escalar la reconstruida para que coincida con la amplitud original + factor = (original' * reconstruida) / (reconstruida' * reconstruida); + rec_scaled = reconstruida * factor; + + error_rms = sqrt(mean((original - rec_scaled).^2)); + pot = mean(original.^2); + + if pot > 0 && error_rms > 0 + snr_val = 10 * log10(pot / error_rms^2); + else + snr_val = Inf; + end + + correlacion = (original' * rec_scaled) / (norm(original) * norm(rec_scaled)); +end \ No newline at end of file