Commit Diff


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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
\ No newline at end of file
blob - /dev/null
blob + a20905f6a73dacdd40ef3a87b62bd5f6a8bffce1 (mode 644)
--- /dev/null
+++ .idea/misc.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectRootManager" version="2" project-jdk-name="25" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/out" />
+  </component>
+</project>
\ No newline at end of file
blob - /dev/null
blob + e774d3eb9d012bc24b6283462868e49202827365 (mode 644)
--- /dev/null
+++ .idea/modules.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/Proyecto-Fisica-2do.iml" filepath="$PROJECT_DIR$/.idea/Proyecto-Fisica-2do.iml" />
+    </modules>
+  </component>
+</project>
\ No newline at end of file
blob - /dev/null
blob + 35eb1ddfbbc029bcab630581847471d7f238ec53 (mode 644)
--- /dev/null
+++ .idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="" vcs="Git" />
+  </component>
+</project>
\ 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