digiproc 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +48 -0
- data/LICENSE.txt +21 -0
- data/README.md +78 -0
- data/Rakefile +37 -0
- data/TODO.md +50 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/config/environment.rb +118 -0
- data/console_tests.rb +44 -0
- data/digiproc.gemspec +49 -0
- data/examples/analog_signals/analog_to_digital.rb +31 -0
- data/examples/analog_signals/companded-signals.png +0 -0
- data/examples/analog_signals/companding.rb +68 -0
- data/examples/analog_signals/fft-plot.png +0 -0
- data/examples/analog_signals/plot_Digiproc::FFT.png +0 -0
- data/examples/analog_signals/plot_Dsp::FFT.png +0 -0
- data/examples/analog_signals/quantization-outputs.png +0 -0
- data/examples/analog_signals/quantize_compand.rb +69 -0
- data/examples/binomial_distribution/bit_error.rb +14 -0
- data/examples/binomial_distribution/dice.rb +35 -0
- data/examples/digital_signals/_coded_frequency_signal,_ts_=_1_s.png +0 -0
- data/examples/digital_signals/_coded_frequency_signal,_ts_=_2_s.png +0 -0
- data/examples/digital_signals/coded_power_spectral_density,__ts_=_1_s.png +0 -0
- data/examples/digital_signals/coded_power_spectral_density,__ts_=_2_s.png +0 -0
- data/examples/digital_signals/coded_time_signal,_ts_=_1_s.png +0 -0
- data/examples/digital_signals/coded_time_signal,_ts_=_2_s.png +0 -0
- data/examples/digital_signals/freq_sig_from_eqn,_ts_=_1_s.png +0 -0
- data/examples/digital_signals/freq_sig_from_eqn,_ts_=_2_s.png +0 -0
- data/examples/digital_signals/frequency_signal,_ts_=_1_s.png +0 -0
- data/examples/digital_signals/frequency_signal,_ts_=_2_s.png +0 -0
- data/examples/digital_signals/modulate_square_pulses.rb +9 -0
- data/examples/digital_signals/modulated_sq._pulses.png +0 -0
- data/examples/digital_signals/modulated_sq._pulses_alt.png +0 -0
- data/examples/digital_signals/power_spectral_density,__ts_=_1_s.png +0 -0
- data/examples/digital_signals/power_spectral_density,__ts_=_2_s.png +0 -0
- data/examples/digital_signals/square_signals.rb +90 -0
- data/examples/digital_signals/time_signal,_ts_=_1_s.png +0 -0
- data/examples/digital_signals/time_signal,_ts_=_2_s.png +0 -0
- data/examples/encoding/gray_code.rb +22 -0
- data/examples/encoding/psk.rb +91 -0
- data/examples/encoding/system_2_phase.png +0 -0
- data/examples/encoding/system_2_xmit_signal.png +0 -0
- data/examples/encoding/system_3_phase.png +0 -0
- data/examples/encoding/system_3_xmit_signal.png +0 -0
- data/examples/encoding/system_4_xmit_signal.png +0 -0
- data/examples/encoding/xor-dpsk-phase-signal-(sys1).png +0 -0
- data/examples/encoding/xor-dpsk-xmit-signal-(sys-1).png +0 -0
- data/examples/factories/Quickplot Graph.png +0 -0
- data/examples/factories/bandpass.rb +6 -0
- data/examples/fft/plot_Dsp::FFT.png +0 -0
- data/examples/fft/recieved_data_(time_domain).png +0 -0
- data/examples/fft/simple_fft_example.rb +47 -0
- data/examples/fft/unprocessed_fft.png +0 -0
- data/examples/filters/bandpass_filter.png +0 -0
- data/examples/filters/filter_a_signal.rb +38 -0
- data/examples/filters/white_noise_db_out_of_bp_filter.png +0 -0
- data/examples/filters/white_noise_mag_out_of_bp_filter.png +0 -0
- data/examples/filters/white_noise_spectra.png +0 -0
- data/examples/functions/compute_probability.rb +29 -0
- data/examples/functions/gram_schmidt.rb +10 -0
- data/examples/functions/minimize_energy.rb +29 -0
- data/examples/functions/orthoganalize.rb +18 -0
- data/examples/functions/simple_functions.rb +81 -0
- data/examples/linear_algebra/diverging_sys.rb +13 -0
- data/examples/linear_algebra/iterative_sys_of_eqns_methods.rb +27 -0
- data/examples/modulation_schemes/dpsk_2.png +0 -0
- data/examples/modulation_schemes/dpsk_256.png +0 -0
- data/examples/modulation_schemes/dpsk_freq_domain.rb +119 -0
- data/examples/modulation_schemes/psk.rb +36 -0
- data/examples/modulation_schemes/psk_2.png +0 -0
- data/examples/modulation_schemes/psk_256.png +0 -0
- data/examples/modulation_schemes/psksystem_1_xmit_signal.png +0 -0
- data/examples/modulation_schemes/psksystem_2_xmit_signal.png +0 -0
- data/examples/modulation_schemes/psksystem_3_xmit_signal.png +0 -0
- data/examples/modulation_schemes/system_1_xmit_signal.png +0 -0
- data/examples/modulation_schemes/system_2_xmit_signal.png +0 -0
- data/examples/modulation_schemes/system_3_xmit_signal.png +0 -0
- data/examples/quickplot/PlottableClass_plot.png +0 -0
- data/examples/quickplot/decorators.rb +13 -0
- data/examples/quickplot/direct_gruff.png +0 -0
- data/examples/quickplot/plot_PlottableClass.png +0 -0
- data/examples/quickplot/quickplot_vs_others.rb +85 -0
- data/examples/quickplot/random_data_quickplot,_dark.png +0 -0
- data/examples/quickplot/random_data_quickplot.png +0 -0
- data/examples/realized_gaussian/norm_dist_plot.png +0 -0
- data/examples/realized_gaussian/norm_dist_spectrum.png +0 -0
- data/examples/realized_gaussian/realized_gaussian_example.rb +23 -0
- data/lib/concerns/convolvable.rb +144 -0
- data/lib/concerns/data_properties.rb +223 -0
- data/lib/concerns/fourier_transformable.rb +178 -0
- data/lib/concerns/initializable.rb +43 -0
- data/lib/concerns/multipliable.rb +22 -0
- data/lib/concerns/os.rb +36 -0
- data/lib/concerns/plottable.rb +248 -0
- data/lib/concerns/requires_data.rb +8 -0
- data/lib/digiproc/version.rb +8 -0
- data/lib/digiproc.rb +2 -0
- data/lib/extensions/array_extension.rb +23 -0
- data/lib/extensions/core_extensions.rb +117 -0
- data/lib/factories/factories.rb +3 -0
- data/lib/factories/filter_factory.rb +83 -0
- data/lib/factories/window_factory.rb +22 -0
- data/lib/fft.rb +255 -0
- data/lib/filters/bandpass_filter.rb +43 -0
- data/lib/filters/bandstop_filter.rb +44 -0
- data/lib/filters/digital_filter.rb +59 -0
- data/lib/filters/highpass_filter.rb +27 -0
- data/lib/filters/lowpass_filter.rb +27 -0
- data/lib/functions.rb +221 -0
- data/lib/probability/binomial_distribution.rb +84 -0
- data/lib/probability/bit_generator.rb +94 -0
- data/lib/probability/gaussian_distribution.rb +29 -0
- data/lib/probability/probability.rb +234 -0
- data/lib/probability/theoretical_gaussian_distribution.rb +59 -0
- data/lib/quick_plot.rb +96 -0
- data/lib/rbplot.rb +219 -0
- data/lib/signals/analog_signal.rb +143 -0
- data/lib/signals/digital_signal.rb +181 -0
- data/lib/strategies/code/differential_encoding_strategy.rb +69 -0
- data/lib/strategies/code/gray_code.rb +75 -0
- data/lib/strategies/code/xor_differential_encoding_strategy.rb +100 -0
- data/lib/strategies/code/xor_differential_encoding_zero_angle_strategy.rb +103 -0
- data/lib/strategies/companding/custom_companding_strategy.rb +29 -0
- data/lib/strategies/convolution/bf_conv.rb +57 -0
- data/lib/strategies/fft/brute_force_dft_strategy.rb +31 -0
- data/lib/strategies/fft/inverse_fft_conjugate_strategy.rb +44 -0
- data/lib/strategies/fft/radix2_strategy.rb +84 -0
- data/lib/strategies/gaussian/gaussian_generator.rb +49 -0
- data/lib/strategies/linear_algebra/gauss_seidel_strategy.rb +90 -0
- data/lib/strategies/linear_algebra/jacobi_strategy.rb +81 -0
- data/lib/strategies/linear_algebra/sor2_strategy.rb +98 -0
- data/lib/strategies/linear_algebra/sor_strategy.rb +108 -0
- data/lib/strategies/modulation/phase_shift_keying_strategy.rb +96 -0
- data/lib/strategies/orthogonalize/gram_schmidt.rb +50 -0
- data/lib/strategies/strategies.rb +3 -0
- data/lib/strategies/window/blackman_window.rb +32 -0
- data/lib/strategies/window/hamming_window.rb +31 -0
- data/lib/strategies/window/hanning_window.rb +31 -0
- data/lib/strategies/window/kaiser_window.rb +27 -0
- data/lib/strategies/window/rectangular_window.rb +22 -0
- data/lib/strategies/window/window.rb +42 -0
- data/lib/systems/custom_system.rb +13 -0
- data/lib/systems/hilbert_transform.rb +6 -0
- data/lib/systems/matched_filter.rb +21 -0
- data/lib/systems/raised_cosine_filter.rb +11 -0
- data/lib/systems/system.rb +19 -0
- data/lib/systems/systems.rb +3 -0
- data/playground.rb +323 -0
- data/plots/_coded_frequency_signal,_ts_=_1_s.png +0 -0
- data/plots/_coded_frequency_signal,_ts_=_2_s.png +0 -0
- data/plots/coded_freq_sig_from_eqn,_ts_=_1_s.png +0 -0
- data/plots/coded_freq_sig_from_eqn,_ts_=_2_s.png +0 -0
- data/plots/coded_power_spectral_density,__ts_=_1_s.png +0 -0
- data/plots/coded_power_spectral_density,__ts_=_2_s.png +0 -0
- data/plots/coded_time_signal,_ts_=_1_s.png +0 -0
- data/plots/coded_time_signal,_ts_=_2_s.png +0 -0
- data/plots/dpsk_2.png +0 -0
- data/plots/freq_sig_from_eqn,_ts_=_1_s.png +0 -0
- data/plots/freq_sig_from_eqn,_ts_=_2_s.png +0 -0
- data/plots/frequency_signal,_ts_=_1_s.png +0 -0
- data/plots/frequency_signal,_ts_=_2_s.png +0 -0
- data/plots/power_spectral_density,__ts_=_1_s.png +0 -0
- data/plots/power_spectral_density,__ts_=_2_s.png +0 -0
- data/plots/psk_2.png +0 -0
- data/plots/time_signal,_ts_=_1_s.png +0 -0
- data/plots/time_signal,_ts_=_2_s.png +0 -0
- data/test-title-dark.png +0 -0
- data/test-title.png +0 -0
- metadata +322 -0
@@ -0,0 +1,68 @@
|
|
1
|
+
eqn1 = ->(t){ 8 * Math.cos(20 * Math::PI * t) }
|
2
|
+
eqn2 = ->(t){ Math.cos(20 * Math::PI * t) }
|
3
|
+
rate = 1.0 / 51.0
|
4
|
+
|
5
|
+
x1 = Digiproc::AnalogSignal.new(eqn: eqn1, sample_rate: rate, size: 6, quantization_bits: 4, quant_max: 8, quant_min: -8)
|
6
|
+
x2 = Digiproc::AnalogSignal.new(eqn: eqn2, sample_rate: rate, size: 6, quantization_bits: 4, quant_max: 8, quant_min: -8)
|
7
|
+
|
8
|
+
compression_eqn = ->(n){ n < 0 ? (-4 * ((-n) ** (1.0 / 3))) : (4 * n ** (1.0 / 3))}
|
9
|
+
expansion_eqn =->(n){ n < 0 ? ((-1.0 / 64) * ((-n) ** 3)) : ((1.0 / 64) * n ** 3)}
|
10
|
+
|
11
|
+
compander = Digiproc::Strategies::CustomCompandingStrategy.new(compression_eqn, expansion_eqn)
|
12
|
+
|
13
|
+
x3 = Digiproc::AnalogSignal.new(eqn: eqn1, sample_rate: rate, size: 6, quantization_bits: 4, quant_max: 8, quant_min: -8, companding_strategy: compander)
|
14
|
+
x4 = Digiproc::AnalogSignal.new(eqn: eqn2, sample_rate: rate, size: 6, quantization_bits: 4, quant_max: 8, quant_min: -8, companding_strategy: compander)
|
15
|
+
|
16
|
+
puts "x(1): "
|
17
|
+
puts x1.digitize.to_s
|
18
|
+
puts "Raw samples: #{x1.raw_samples}"
|
19
|
+
puts "Normalized Quantization RMS Error: #{x1.normalized_quantization_rms_error.round(3)}"
|
20
|
+
puts "\n\nx(2):"
|
21
|
+
puts x2.digitize.to_s
|
22
|
+
puts "Raw samples: #{x2.raw_samples}"
|
23
|
+
puts "Normalized Quantization RMS Error: #{x2.normalized_quantization_rms_error.round(3)}"
|
24
|
+
puts "\n\nx(1) with companding: "
|
25
|
+
puts x3.digitize.to_s
|
26
|
+
puts "Raw samples: #{x3.raw_samples}"
|
27
|
+
puts "Normalized Quantization RMS Error: #{x3.normalized_quantization_rms_error.round(3)}"
|
28
|
+
puts "\n\nx(2) with companding:"
|
29
|
+
puts x4.digitize.to_s
|
30
|
+
puts "Raw samples: #{x4.raw_samples}"
|
31
|
+
puts "Normalized Quantization RMS Error: #{x4.normalized_quantization_rms_error.round(3)}"
|
32
|
+
# binding.pry
|
33
|
+
|
34
|
+
signal = ->(t){Math.cos(2 * Math::PI * t)} #cos at 1 Hz
|
35
|
+
sample_times = (0..1000).map{ |int| int / 100.0} #Sample for 10 seconds every 0.01 seconds (100 times per period over 10 periods)
|
36
|
+
data = sample_times.map{ |time| signal.call(time) }
|
37
|
+
ft = []
|
38
|
+
for k in 0...data.length do
|
39
|
+
tot = 0
|
40
|
+
data.each_with_index do |x_n, n|
|
41
|
+
tot += x_n * Math::E ** (Complex(0,-1) * 2.0 * Math::PI * k * n / data.length.to_f)
|
42
|
+
end
|
43
|
+
ft << tot
|
44
|
+
end
|
45
|
+
|
46
|
+
fft = Digiproc::FFT.new(time_data: data)
|
47
|
+
t = Digiproc::Functions.linspace(0,1,fft.size)
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
plt = Digiproc::Rbplot.line(t, fft.dB, "discrete frequency")
|
53
|
+
plt.title('FFT Plot')
|
54
|
+
plt.path('./examples/analog_signals/')
|
55
|
+
plt.xlabel('Radians')
|
56
|
+
plt.ylabel('Decibles')
|
57
|
+
plt.xsteps(10)
|
58
|
+
plt.show
|
59
|
+
|
60
|
+
x = Digiproc::Functions.linspace(0, 6.0/51, 6)
|
61
|
+
plt = Digiproc::Rbplot.line(x, x1.digitize, 'x1')
|
62
|
+
plt.add_line(x, x2.digitize, 'x2')
|
63
|
+
plt.add_line(x, x3.digitize, 'x1 companded')
|
64
|
+
plt.add_line(x, x4.digitize, 'x2 companded')
|
65
|
+
plt.path('./examples/analog_signals/')
|
66
|
+
plt.title('Companded Signals')
|
67
|
+
plt.ylabel('Magnitude')
|
68
|
+
plt.show
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# For the signals:
|
2
|
+
# x1(t)=8cos(20πt)
|
3
|
+
# x2(t)=cos(20πt)
|
4
|
+
|
5
|
+
# Find Normalized Quantization RMS Error:
|
6
|
+
|
7
|
+
# AnalogSignal class accepts an equation, sample rate, and size. Quantization bits, quantization max and min values, and a companding equation are optional.
|
8
|
+
# Once the #digitize method is called on the initialized class:
|
9
|
+
# The digital signal is sampled at the given sample rate for the given size number of samples
|
10
|
+
# If a companding strategy is given, the compression of bits is applied to the samples
|
11
|
+
# If a number of quantization bits are inputted, the values are quantized based on the number of bits desired as well as the max and min quantization values passed in.
|
12
|
+
# To perform the quantization, you can follow the progression which starts in the #quantize method. First, the samples are mapped from the passed in max and min values to −1⟺+1 Then, the value is multiplied by the number of bits squared divided by 2. That value is rounded to the nearest integer, and then mapped back down to the original max and min values.
|
13
|
+
# After quantization, if a companding strategy was given, the quantized samples are run through the expansion algorithm.
|
14
|
+
# This leaves you with the final answer, which is returned from the #digitize method
|
15
|
+
# The normalized RMS Error average value is calculated in the #normalized_quantization_rms_error method and is done so via the original sample values and the quantized output of the #digitize method.
|
16
|
+
|
17
|
+
|
18
|
+
x1 = Digiproc::AnalogSignal.new(eqn: ->(t){ 8 * Math.cos(20 * Math::PI * t) }, sample_rate: 1.0 / 51.0, size: 6,quantization_bits: 4, quant_max: 8, quant_min: -8)
|
19
|
+
x2 = Digiproc::AnalogSignal.new(eqn: ->(t){ Math.cos(20 * Math::PI * t) }, sample_rate: 1.0 / 51.0, size: 6,quantization_bits: 4, quant_max: 8, quant_min: -8)
|
20
|
+
puts "x(1): "
|
21
|
+
x1.digitize
|
22
|
+
puts "Normalized Quantization RMS Error: #{x1.normalized_quantization_rms_error.round(3)}"
|
23
|
+
puts "\n\nx(2):"
|
24
|
+
x2.digitize
|
25
|
+
puts "Normalized Quantization RMS Error: #{x2.normalized_quantization_rms_error.round(3)}"
|
26
|
+
puts
|
27
|
+
puts "x1 raw samples: #{x1.raw_samples.map{|s| s.round(2)}}"
|
28
|
+
puts "x1 quantized samples: #{x1.quantized_samples}"
|
29
|
+
|
30
|
+
puts
|
31
|
+
|
32
|
+
puts "x2 raw samples: #{x2.raw_samples.map{|s| s.round(2)}}"
|
33
|
+
puts "x2 quantized samples: #{x2.quantized_samples}"
|
34
|
+
|
35
|
+
|
36
|
+
# Now use a compander to attempt to reduce Quantization error:
|
37
|
+
|
38
|
+
|
39
|
+
compression_eqn = ->(n){ n < 0 ? (-4 * ((-n) ** (1.0 / 3))) : (4 * n ** (1.0 / 3))}
|
40
|
+
expansion_eqn =->(n){ n < 0 ? ((-1.0 / 64) * ((-n) ** 3)) : ((1.0 / 64) * n ** 3)}
|
41
|
+
compander = Digiproc::Strategies::CustomCompandingStrategy.new(compression_eqn, expansion_eqn)
|
42
|
+
|
43
|
+
|
44
|
+
x1 = Digiproc::AnalogSignal.new(eqn: ->(t){ 8 * Math.cos(20 * Math::PI * t) }, sample_rate: 1.0 / 51.0, size: 6,quantization_bits: 4, quant_max: 8, quant_min: -8, companding_strategy: compander)
|
45
|
+
x2 = Digiproc::AnalogSignal.new(eqn: ->(t){ Math.cos(20 * Math::PI * t) }, sample_rate: 1.0 / 51.0, size: 6,quantization_bits: 4, quant_max: 8, quant_min: -8, companding_strategy: compander)
|
46
|
+
|
47
|
+
|
48
|
+
puts "\n\nx(1) with companding: "
|
49
|
+
|
50
|
+
x1.digitize
|
51
|
+
|
52
|
+
puts "Normalized Quantization RMS Error: #{x1.normalized_quantization_rms_error.round(3)}"
|
53
|
+
|
54
|
+
|
55
|
+
puts "\n\nx(2) with companding:"
|
56
|
+
|
57
|
+
x2.digitize
|
58
|
+
|
59
|
+
puts "Normalized Quantization RMS Error: #{x2.normalized_quantization_rms_error.round(3)}"
|
60
|
+
|
61
|
+
puts "x3 raw samples: #{x1.raw_samples.map{|s| s.round(2)}}"
|
62
|
+
puts "x1 quantized samples: #{x1.quantized_samples}"
|
63
|
+
|
64
|
+
puts
|
65
|
+
|
66
|
+
puts "x2 raw samples: #{x2.raw_samples.map{|s| s.round(2)}}"
|
67
|
+
puts "x2 quantized samples: #{x2.quantized_samples}"
|
68
|
+
|
69
|
+
puts "Companding then reduced Quantization error for the low-amplitude signal x2, but raised it for the higher-amplitude signal x1"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#If a word consists of 10 bits with the ability to detect and correct any single bit error
|
2
|
+
# but not multiple bit errors, what is the probability of a word being in error?
|
3
|
+
# Compare the reduction in probability of a word error by using the error correcting code.
|
4
|
+
|
5
|
+
# Given that P(error)=0.00135, as it would be for a +- 1V signal with additive white gaussian noise
|
6
|
+
# with a variance of 1/9:
|
7
|
+
|
8
|
+
|
9
|
+
bd = Digiproc::Probability::TheoreticalBinomialDistribution.new(n: 10, p: 0.00135)
|
10
|
+
puts "Probability of no errors: #{bd.probability(0)}"
|
11
|
+
puts "Probability of one error: #{bd.probability(1)}"
|
12
|
+
puts "Probability of one or more errors(if no code fix): #{bd.probability(1..10)}"
|
13
|
+
puts "Probability of two or more errors (prob after code fix): #{bd.probability(2..10)}, should equal #{1 - bd.probability(0,1)}"
|
14
|
+
puts "Reduction in error by using error correcting code: #{bd.probability(1..10) - bd.probability(2..10)}"
|
@@ -0,0 +1,35 @@
|
|
1
|
+
binomial_dist = Digiproc::Probability::TheoreticalBinomialDistribution
|
2
|
+
|
3
|
+
six_die_roll = binomial_dist.new(n: 6, p: (1.0/6))
|
4
|
+
|
5
|
+
puts "For six die rolls:"
|
6
|
+
|
7
|
+
puts "At least one of a specific number: #{1 - (1 - (1.0/6)) ** 6}"
|
8
|
+
puts "Same as above with binomial dist: #{six_die_roll.probability(1..6)}"
|
9
|
+
puts "-------------------------------"
|
10
|
+
puts "Six of a kind: #{1 - ((six_die_roll.probability(0..5)) ** 6)}"
|
11
|
+
puts "At least 5 of a kind: #{1 - ((six_die_roll.probability(0..4)) ** 6)}"
|
12
|
+
puts "At least 3 of a predetermined number: #{six_die_roll.probability(3..6)}"
|
13
|
+
puts "-------------------------------"
|
14
|
+
|
15
|
+
puts "Experimental Data"
|
16
|
+
|
17
|
+
at_least = 3
|
18
|
+
die_number = 3
|
19
|
+
count = 0
|
20
|
+
r = Random.new
|
21
|
+
total = 5000000
|
22
|
+
total.times do
|
23
|
+
rolls = {1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 0}
|
24
|
+
6.times do
|
25
|
+
num = r.rand(6) + 1
|
26
|
+
rolls[num] += 1
|
27
|
+
if rolls[die_number] == at_least
|
28
|
+
count += 1
|
29
|
+
break
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
puts "At least #{at_least} #{die_number}s (experimental data): #{count / total.to_f}"
|
35
|
+
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,9 @@
|
|
1
|
+
|
2
|
+
input_data = Array.new(10,0) + Array.new(10,1) + Array.new(20,0) + Array.new(20,1) + Array.new(40,0)
|
3
|
+
x_n = Digiproc::DigitalSignal.new(data: input_data)
|
4
|
+
lpf = Digiproc::Factories::FilterFactory.filter_for(type: 'lowpass', wc: Math::PI / 10, transition_width: 0.01, stopband_attenuation: 80).to_ds
|
5
|
+
carrier = Digiproc::DigitalSignal.new_from_eqn(eqn: ->(n){Math.cos(10.0 * 2.0 * Math::PI * n / 100) }, size: lpf.data.length)
|
6
|
+
y_n = Digiproc::DigitalSignal.new(data: (x_n.fft(2**8) * lpf.fft(2**8)).ifft.map(&:real).take(100)) * carrier * carrier
|
7
|
+
y_n_alt = x_n.ds_conv(lpf) * carrier * carrier
|
8
|
+
Digiproc::QuickPlot.plot(data: y_n.data, title: "Modulated Sq. Pulses", path: './examples/digital_signals/')
|
9
|
+
Digiproc::QuickPlot.plot(data: y_n_alt.data[274,100], title: "Modulated Sq. Pulses Alt", path: './examples/digital_signals/')
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# Define required objects and constants
|
2
|
+
r = Random.new
|
3
|
+
pulse_lens = [1,2]
|
4
|
+
plt = Digiproc::QuickPlot
|
5
|
+
fns = Digiproc::Functions
|
6
|
+
a = 1
|
7
|
+
|
8
|
+
# Random signal generator functions
|
9
|
+
def get_signal(rand_gen, a = 1)
|
10
|
+
rand_gen.rand(2) == 0 ? -a : a
|
11
|
+
end
|
12
|
+
|
13
|
+
# Create signal data
|
14
|
+
signal_size = 400
|
15
|
+
sample_rate = 0.05
|
16
|
+
signal_arr = []
|
17
|
+
signal_size.times { signal_arr << get_signal(r, a)}
|
18
|
+
|
19
|
+
#Get results with varied pulse length
|
20
|
+
pulse_lens.each do |pulse_len|
|
21
|
+
size = (1.0 / sample_rate) * signal_size * pulse_len
|
22
|
+
# Correct for sample rate so it can be compared to CT equation
|
23
|
+
signal_eqn = ->(t){ signal_arr[(t / pulse_len.to_f).floor] * sample_rate }
|
24
|
+
signal = Digiproc::AnalogSignal.new(eqn: signal_eqn, sample_rate: sample_rate, size: size)
|
25
|
+
freq_of_interest1 = 1.0 / (2 * pulse_len)
|
26
|
+
freq_of_interest2 = 1.0 / ( pulse_len)
|
27
|
+
# Test calculated equation
|
28
|
+
x_f = Proc.new do |f|
|
29
|
+
signal_arr.map.with_index{ |s, n| s.to_f * (a / (Complex(0, f * 2 * Math::PI))) * (Math::E ** (Complex(0, -f * Math::PI * 2 * n * pulse_len)) - Math::E ** (Complex(0,-f * 2 * Math::PI * pulse_len) * (1 + n))) }.sum
|
30
|
+
end
|
31
|
+
max_freq = 0.5 / (sample_rate)
|
32
|
+
freq_space = fns.linspace(0, max_freq, size)
|
33
|
+
xf_plot = fns.process(freq_space, x_f).map(&:abs)
|
34
|
+
#Equation DNE @ omega = 0
|
35
|
+
xf_plot[0] = 0
|
36
|
+
|
37
|
+
foi1_from_eqn = ((freq_of_interest1.to_f / max_freq) * xf_plot.length).to_i
|
38
|
+
foi2_from_eqn = ((freq_of_interest2.to_f / max_freq) * xf_plot.length).to_i
|
39
|
+
|
40
|
+
|
41
|
+
puts "Magnitude at 1/2T : #{xf_plot[foi1_from_eqn]}"
|
42
|
+
puts "Magnitude at 1/T : #{xf_plot[foi2_from_eqn]}"
|
43
|
+
puts
|
44
|
+
|
45
|
+
# Plot output from derived equation
|
46
|
+
plt.plot(data: xf_plot, title: "Freq Sig from Eqn, Ts = #{pulse_len} s", path: "./examples/digital_signals/")
|
47
|
+
|
48
|
+
# Plot experiment data
|
49
|
+
plt.plot(data: signal.digitize, title: "Time signal, Ts = #{pulse_len} s", path: "./examples/digital_signals/")
|
50
|
+
plt.plot(data: signal.to_ds.fft.magnitude, title: "Frequency Signal, Ts = #{pulse_len} s", path: "./examples/digital_signals/")
|
51
|
+
plt.plot(data: signal.to_ds.psd.data.map(&:real), title: "Power Spectral Density, Ts = #{pulse_len} s", path: "./examples/digital_signals/")
|
52
|
+
end
|
53
|
+
|
54
|
+
puts
|
55
|
+
puts
|
56
|
+
|
57
|
+
alpha = 1
|
58
|
+
coded_arr = Array.new(signal_size, 0)
|
59
|
+
coded_arr[0] = signal_arr.first
|
60
|
+
for i in 1...signal_size do
|
61
|
+
coded_arr[i] = signal_arr[i] + alpha * signal_arr[i-1]
|
62
|
+
end
|
63
|
+
|
64
|
+
pulse_lens.each do |pulse_len|
|
65
|
+
size = (1.0 / sample_rate) * signal_size * pulse_len
|
66
|
+
signal_eqn = ->(t){ coded_arr[(t / pulse_len.to_f).floor] * sample_rate }
|
67
|
+
signal = Digiproc::AnalogSignal.new(eqn: signal_eqn, sample_rate: sample_rate, size: size)
|
68
|
+
freq_of_interest1 = 1.0 / (2 * pulse_len)
|
69
|
+
freq_of_interest2 = 1.0 / ( pulse_len)
|
70
|
+
|
71
|
+
x_f = Proc.new do |f|
|
72
|
+
coded_arr.map.with_index{ |s, n| s.to_f * (a / (Complex(0, f * 2 * Math::PI))) * (Math::E ** (Complex(0, -f * Math::PI * 2 * n * pulse_len)) - Math::E ** (Complex(0,-f * 2 * Math::PI * pulse_len) * (1 + n))) }.sum
|
73
|
+
end
|
74
|
+
max_freq = 0.5 / (sample_rate)
|
75
|
+
freq_space = fns.linspace(0, max_freq, size)
|
76
|
+
xf_plot = fns.process(freq_space, x_f).map(&:abs)
|
77
|
+
xf_plot[0] = 0
|
78
|
+
# freq_unit = size.to_f / max_freq
|
79
|
+
foi1_from_eqn = ((freq_of_interest1.to_f / max_freq) * xf_plot.length).to_i
|
80
|
+
foi2_from_eqn = ((freq_of_interest2.to_f / max_freq) * xf_plot.length).to_i
|
81
|
+
# puts signal.to_ds.fft.magnitude[(foi1_from_eqn / 2 - 1).to_i]
|
82
|
+
puts "Coded Magnitude at 1/2T : #{xf_plot[foi1_from_eqn]}"
|
83
|
+
puts "Coded Magnitude at 1/T : #{xf_plot[foi2_from_eqn]}"
|
84
|
+
plt.plot(data: xf_plot, title: "Coded Freq Sig from Eqn, Ts = #{pulse_len} s")
|
85
|
+
|
86
|
+
#Plot test data
|
87
|
+
plt.plot(data: signal.digitize, title: "Coded Time signal, Ts = #{pulse_len} s", path: "./examples/digital_signals/")
|
88
|
+
plt.plot(data: signal.to_ds.fft.magnitude, title: " Coded Frequency Signal, Ts = #{pulse_len} s", path: "./examples/digital_signals/")
|
89
|
+
plt.plot(data: signal.to_ds.psd.data.map(&:real), title: "Coded Power Spectral Density, Ts = #{pulse_len} s", path: "./examples/digital_signals/")
|
90
|
+
end
|
Binary file
|
Binary file
|
@@ -0,0 +1,22 @@
|
|
1
|
+
## Gray code maps "normal" numbers to a binary code in which adjacent numbers
|
2
|
+
## only change by one bit. This reduced errors in the whole number when you
|
3
|
+
## there is an error decoding a single bit
|
4
|
+
|
5
|
+
gc_gen = Digiproc::Strategies::GrayCode
|
6
|
+
|
7
|
+
|
8
|
+
three_bit_gray_code = gc_gen.generate(3)
|
9
|
+
|
10
|
+
puts three_bit_gray_code.to_s
|
11
|
+
puts "In decimal:"
|
12
|
+
gray_dec = three_bit_gray_code.map{ |gc| gc.to_i(2) }
|
13
|
+
puts gray_dec.to_s
|
14
|
+
|
15
|
+
|
16
|
+
puts "decode:"
|
17
|
+
puts "map gray code back to its original number"
|
18
|
+
|
19
|
+
orig_dec = gray_dec.map{ |dec| gc_gen.to_dec(dec) }
|
20
|
+
puts orig_dec.to_s
|
21
|
+
|
22
|
+
puts orig_bin = gray_dec.map{ |dec| gc_gen.to_binary(dec)}.to_s
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# We want to transmit the data sequence 110100010110 using binary DPSK.
|
2
|
+
# Let s(t)=Acos(2πfot+θ) represent the transmitted signal in a signaling interval of duration Tb.
|
3
|
+
# Give the phase of the tranmitted signal. Begin with θ=0 for the phase of the first bit to be transmitted.
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
sig_str = "110100010110"
|
8
|
+
sig = sig_str.split('')
|
9
|
+
# diff_sig = Digiproc::Strategies::XORDifferentialEncodingStrategy.encode(sig, 2, "0")
|
10
|
+
|
11
|
+
# System 1:
|
12
|
+
#Use XOR to encode original signal with a delayed version of itself
|
13
|
+
# Map bits 0 => 0 rad, 1 => pi rad
|
14
|
+
bpsk = Digiproc::Strategies::PSK.new(modulating_signal: sig, coding_strategy: Digiproc::Strategies::XORDifferentialEncodingZeroAngleStrategy)
|
15
|
+
|
16
|
+
# System 2:
|
17
|
+
# Use XOR to encode original signal with a delayed version of itself
|
18
|
+
# Map bits 0 => pi, 1 => 3pi/2
|
19
|
+
bdpsk = Digiproc::Strategies::PSK.new(modulating_signal: sig, coding_strategy: Digiproc::Strategies::XORDifferentialEncodingStrategy)
|
20
|
+
|
21
|
+
# System 3:
|
22
|
+
# Do not XOR the bits but instead map them directly into frequencies which then are added to dealyed versions
|
23
|
+
# of themselves modulo 2pi (see the strategy used for more details)
|
24
|
+
dpsk = Digiproc::Strategies::PSK.new(modulating_signal: sig, coding_strategy:Digiproc::Strategies::DifferentialEncodingStrategy)
|
25
|
+
|
26
|
+
#System 4:
|
27
|
+
# Directly maps bits to phase without XORing and does not alter phase angles at all for transmission
|
28
|
+
dpsk2 = Digiproc::Strategies::PSK.new(modulating_signal: sig)
|
29
|
+
|
30
|
+
xvals = Digiproc::Functions.linspace(1,sig_str.length, sig_str.length + 1)
|
31
|
+
|
32
|
+
|
33
|
+
puts "System 1 Differential Signal: #{bpsk.coded_signal}"
|
34
|
+
puts "System 1 Phase: #{bpsk.phase_signal.map{ |ps| ps / Math::PI }} * pi"
|
35
|
+
puts "System 1 Decoded: #{bpsk.decode}"
|
36
|
+
|
37
|
+
dpskvals = bpsk.phase_signal.map{ |p| p / Math::PI}
|
38
|
+
path = "./examples/encoding/"
|
39
|
+
plt = Digiproc::Rbplot.line(xvals, dpskvals)
|
40
|
+
plt.xlabel("sample number")
|
41
|
+
plt.ylabel("phase ( *pi rad )")
|
42
|
+
plt.title("XOR DPSK Phase Signal (Sys1)")
|
43
|
+
plt.legend("DPSK angle")
|
44
|
+
plt.show(path)
|
45
|
+
|
46
|
+
qplt = Digiproc::QuickPlot
|
47
|
+
puts "\n\n"
|
48
|
+
puts "System 2 Differential Signal: #{bdpsk.coded_signal}"
|
49
|
+
puts "System 2 Coded Phase: #{bdpsk.phase_signal.map{ |ps| ps / Math::PI}} * pi"
|
50
|
+
puts "System 2 Decoded: #{bdpsk.decode}"
|
51
|
+
qplt.plot(data: bdpsk.phase_signal.map{ |p| p / Math::PI},y_label: "Phase", title: "System 2 Phase", path: path)
|
52
|
+
puts "\n\n"
|
53
|
+
|
54
|
+
puts "System 3 Signal: #{dpsk.coded_signal}"
|
55
|
+
puts "System 3 Coded Phase: #{dpsk.phase_signal.map{ |p| p / Math::PI}} * pi"
|
56
|
+
puts "System 3 Decoded: #{dpsk.decode}"
|
57
|
+
puts "(This is not correct)"
|
58
|
+
qplt.plot(data: dpsk.phase_signal.map{ |p| p / Math::PI},y_label: "Phase", title: "System 3 Phase", path: path)
|
59
|
+
puts "\n\n"
|
60
|
+
|
61
|
+
|
62
|
+
puts "System 4 Signal: #{dpsk2.coded_signal}"
|
63
|
+
puts "System 4 Coded Phase: #{dpsk2.phase_signal.map{ |p| p / Math::PI}} * pi"
|
64
|
+
puts "System 4 Decoded: #{dpsk2.decode}"
|
65
|
+
qplt.plot(data: dpsk2.phase_signal.map{ |p| p / Math::PI},y_label: "Phase", title: "System 3 Phase", path: path)
|
66
|
+
puts "\n\n"
|
67
|
+
|
68
|
+
|
69
|
+
yvals = bpsk.output.digitize
|
70
|
+
xvals = Digiproc::Functions.linspace(1,yvals.length, yvals.length)
|
71
|
+
plt = Digiproc::Rbplot.line(xvals, yvals)
|
72
|
+
plt.title("XOR DPSK Xmit Signal (Sys 1)")
|
73
|
+
plt.xlabel("Sample number")
|
74
|
+
plt.ylabel("Signal Amplitude")
|
75
|
+
plt.legend("DPSK Xmit Signal")
|
76
|
+
plt.theme(:dark)
|
77
|
+
plt.show(path)
|
78
|
+
|
79
|
+
|
80
|
+
qplt.plot(data: bdpsk.output.digitize, title: "System 2 Xmit Signal", y_label: "Magnitude", dark: true, path: path)
|
81
|
+
qplt.plot(data: dpsk.output.digitize, title: "System 3 Xmit Signal", y_label: "Magnitude", dark: true, path: path)
|
82
|
+
qplt.plot(data: dpsk2.output.digitize, title: "System 4 Xmit Signal", y_label: "Magnitude", dark: true, path: path)
|
83
|
+
|
84
|
+
puts "System 1 Output From Reciever: \n#{bpsk.reciever_decode}\n\n"
|
85
|
+
puts "Correctly decoded by reciever \n"
|
86
|
+
puts "System 2 Output From Reciever: \n#{bdpsk.reciever_decode}\n\n"
|
87
|
+
puts "Correctly decoded by reciever \n"
|
88
|
+
puts "System 3 Output From Reciever: \n#{dpsk.reciever_decode}\n\n"
|
89
|
+
puts "Not properly decoded by reciever"
|
90
|
+
puts "System 4 Output From Reciever: \n#{dpsk2.reciever_decode}\n\n"
|
91
|
+
puts 'Not properly decoded by reciever'
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,6 @@
|
|
1
|
+
Filter_factory = Digiproc::Factories::FilterFactory
|
2
|
+
plt = Digiproc::QuickPlot
|
3
|
+
bpfilter = Filter_factory.filter_for(type: "bandpass", wo: Math::PI / 3, bw: Math::PI / 10, transition_width: 0.1, stopband_attenuation: 80)
|
4
|
+
freq_db = bpfilter.fft.dB
|
5
|
+
# Get x values with the linspace function (start, stop, number_of_points)
|
6
|
+
plt.plot(x: Digiproc::Functions.linspace(0,1,freq_db.length) ,y: freq_db, y_label: "dB", dark: true, path: './examples/factories/')
|
Binary file
|
Binary file
|
@@ -0,0 +1,47 @@
|
|
1
|
+
plt = Digiproc::QuickPlot
|
2
|
+
prob = Digiproc::Probability
|
3
|
+
norm_dist = Digiproc::Probability::RealizedGaussianDistribution
|
4
|
+
window = BlackmanWindow.new(size: 16384)
|
5
|
+
|
6
|
+
#************ Find a signal in noise with FFT ****************
|
7
|
+
|
8
|
+
#sample every 1 ms
|
9
|
+
sample_rate = 0.001
|
10
|
+
datapoints = 16384 # use a power of 2 because FFT uses Radix 2 algorithm
|
11
|
+
#300Hz and 500Hz signals
|
12
|
+
signal = Digiproc::AnalogSignal.new(eqn: ->(t){0.2 * Math.cos(2*Math::PI * 300 * t) + 0.3 * Math.cos(2 * Math::PI * 400 * t)}, sample_rate: sample_rate, size: datapoints).to_ds
|
13
|
+
data = signal.data
|
14
|
+
noise = norm_dist.new(mean: 0, stddev: 1, size: datapoints)
|
15
|
+
#Add signal to noise data
|
16
|
+
recieved_signal = data.plus(noise.data)
|
17
|
+
|
18
|
+
#process signal with a blackman window (below shows that this is an optional step)
|
19
|
+
processed_signal_data = recieved_signal.times window.data
|
20
|
+
|
21
|
+
processed_signal = Digiproc::DigitalSignal.new(data: processed_signal_data)
|
22
|
+
|
23
|
+
fft = processed_signal.fft
|
24
|
+
|
25
|
+
#Get the
|
26
|
+
signal_locations = fft.maxima(4)
|
27
|
+
|
28
|
+
puts signal_locations
|
29
|
+
|
30
|
+
max_freq_hz = 0.5 / sample_rate
|
31
|
+
max_freq_datapoint = datapoints / 2
|
32
|
+
|
33
|
+
# Only use signals below Nyquist Frequency
|
34
|
+
signal_locations.select!{ |location| location.index < max_freq_datapoint }
|
35
|
+
|
36
|
+
signal_1_freq = signal_locations[0].index.to_f / max_freq_datapoint * max_freq_hz
|
37
|
+
signal_2_freq = signal_locations[1].index.to_f / max_freq_datapoint * max_freq_hz
|
38
|
+
|
39
|
+
puts "Most powerful signal at #{signal_1_freq} Hz"
|
40
|
+
puts "Second most powerful signal at #{signal_2_freq} Hz"
|
41
|
+
|
42
|
+
#Signal not viewable in time domain
|
43
|
+
plt.plot(data: recieved_signal, title: "Recieved data (time domain)", path: './examples/fft/' )
|
44
|
+
#Signal easily viewed in frequency domain (dB plot)
|
45
|
+
fft.plot_db(path: "./examples/fft/")
|
46
|
+
#plot unprocessed signal dB
|
47
|
+
plt.plot(data: Digiproc::DigitalSignal.new(data: recieved_signal).fft.dB , title: "Unprocessed FFT", path: './examples/fft/')
|
Binary file
|
Binary file
|
@@ -0,0 +1,38 @@
|
|
1
|
+
plt = Digiproc::QuickPlot
|
2
|
+
fns = Digiproc::Functions
|
3
|
+
prob = Digiproc::Probability
|
4
|
+
norm_dist = Digiproc::Probability::RealizedGaussianDistribution
|
5
|
+
factory = Digiproc::Factories::FilterFactory
|
6
|
+
|
7
|
+
# Make a signal with gaussian noise:
|
8
|
+
# Create "white" Gaussian noise, 0 mean
|
9
|
+
dist = norm_dist.new(mean: 0, stddev: 1, size: 16384)
|
10
|
+
|
11
|
+
# Create a bandpass filter, make FT dimensions match
|
12
|
+
bpfilter = factory.filter_for(type: "bandpass", wo: Math::PI / 2, bw: Math::PI / 5, transition_width: 0.0001, stopband_attenuation: 80)
|
13
|
+
filter_dft = Digiproc::FFT.new(time_data: bpfilter.weights, size: 16384 * 4)
|
14
|
+
|
15
|
+
# Get FT of White noise, calculate No
|
16
|
+
dist_fft = Digiproc::FFT.new(time_data: dist.data, size: 16384 * 4)
|
17
|
+
n_o = 2 * (dist_fft.magnitude.map{ |val| val ** 2}.sum.to_f / dist_fft.data.length)
|
18
|
+
|
19
|
+
# Multiply freq domain of noise and filter to get output spectra
|
20
|
+
# Calculate output energy
|
21
|
+
filter_out = dist_fft * filter_dft
|
22
|
+
total_noise_out = filter_out.magnitude.map{ |val| (val ** 2) * (1.0/ (4 * 16384)) }.sum
|
23
|
+
time_data_out = fns.ifft(filter_out.data).map(&:real)
|
24
|
+
bw = 1.0 / 10
|
25
|
+
|
26
|
+
puts "Normal Dist. Input \n\tMean:#{prob.mean(dist.data)}, Stddev: #{prob.stddev(dist.data)}"
|
27
|
+
puts "No = #{n_o}"
|
28
|
+
puts "Total Noise Energy Out: #{total_noise_out}"
|
29
|
+
puts "Output: \n\tMean: #{prob.mean(time_data_out)}, Stddev: #{prob.stddev(time_data_out)}"
|
30
|
+
puts "Calculated Noise Energy Out: #{ n_o * bw}"
|
31
|
+
|
32
|
+
f = fns.linspace(0,1,16384)
|
33
|
+
|
34
|
+
path = './examples/filters/'
|
35
|
+
plt.plot(x: f, y: filter_dft.dB, title: "Bandpass Filter", path: path)
|
36
|
+
plt.plot(x: f, y: dist_fft.magnitude, title: "White Noise Spectra", path: path)
|
37
|
+
plt.plot(x: f, y: filter_out.magnitude, title: "White Noise Mag Out of BP Filter", y_label: "Magnitude", path: path)
|
38
|
+
plt.plot(x: f, y: filter_out.dB, title: "White Noise dB Out of BP Filter", y_label: "dB", path: path)
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Use Digiproc::Probability to calculate a QAM equation and find SNR
|
2
|
+
|
3
|
+
|
4
|
+
qam_eqn = Proc.new do |db|
|
5
|
+
peb_no = 10 ** (db / 10.0)
|
6
|
+
pes_no = peb_no * Math.log(256,2)
|
7
|
+
pq = Digiproc::Probability.normal_q( Math.sqrt(pes_no * 3.0 / 255))
|
8
|
+
psmo2 = (Math.sqrt(256) - 2)
|
9
|
+
ppc1 = (1 - 2 * pq) ** 2
|
10
|
+
ppc2 = (1 - 2 * pq) * (1 - pq)
|
11
|
+
ppc3 = (1 - pq) ** 2
|
12
|
+
ps = 1 - (1.0 / 256) * ((psmo2 ** 2) * ppc1 + 4 * psmo2 * ppc2 + 4 * ppc3)
|
13
|
+
ps / Math.log(256, 2)
|
14
|
+
end
|
15
|
+
|
16
|
+
def findval(eqn, value, desired_val, step = 0.001 , tolerance = 0.000000005)
|
17
|
+
output = eqn[value]
|
18
|
+
if (output >= (desired_val - tolerance)) and (output <= (desired_val + tolerance))
|
19
|
+
return value
|
20
|
+
else
|
21
|
+
slope = (output <=> eqn[value + tolerance])
|
22
|
+
dir_to_output = output <=> desired_val
|
23
|
+
next_val = value + slope * dir_to_output * step
|
24
|
+
return findval(eqn, next_val, desired_val)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
qam = findval(qam_eqn, 25 , 0.000001)
|
29
|
+
puts "QAM Eb/No = #{qam}"
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#GramSchmidtOrgonormalize calculates orthogonal vectors if possible
|
2
|
+
# translate_center_to_origin centeres points around the origin
|
3
|
+
|
4
|
+
messages = [[1,1], [1,-1], [-1,1]]
|
5
|
+
output_vectors = Digiproc::Strategies::GramSchmidtOrthonormalize.new(messages).output
|
6
|
+
puts output_vectors.to_s
|
7
|
+
# Therefore, this signal cannot be reprisented in 3-D Space
|
8
|
+
|
9
|
+
#Minimize energy in the 2-D reprisentation
|
10
|
+
puts Digiproc::Functions.translate_center_to_origin([[1,1],[1,-1],[-1,1]]).to_s
|