00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 package com.meapsoft;
00024
00025 import java.util.Arrays;
00026 import java.io.*;
00027 import javax.sound.sampled.*;
00028 import com.meapsoft.gui.DataDisplayPanel;
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 public class DSP
00039 {
00044 public static double[] conv(double[] a, double[] b)
00045 {
00046 double[] y = new double[a.length+b.length-1];
00047
00048
00049 if(a.length > b.length)
00050 {
00051 double[] tmp = a;
00052 a = b;
00053 b = tmp;
00054 }
00055
00056 for(int lag = 0; lag < y.length; lag++)
00057 {
00058 y[lag] = 0;
00059
00060
00061 int start = 0;
00062
00063 if(lag > a.length-1)
00064 start = lag-a.length+1;
00065
00066 int end = lag;
00067
00068 if(end > b.length-1)
00069 end = b.length-1;
00070
00071
00072 for(int n = start; n <= end; n++)
00073 {
00074
00075 y[lag] += b[n]*a[lag-n];
00076 }
00077 }
00078
00079 return(y);
00080 }
00081
00085 public static double[] xcorr(double[] a, double[] b)
00086 {
00087 int len = a.length;
00088 if(b.length > a.length)
00089 len = b.length;
00090
00091 return xcorr(a, b, len-1);
00092
00093
00094
00095
00096
00097
00098
00099 }
00100
00104 public static double[] xcorr(double[] a)
00105 {
00106 return xcorr(a, a);
00107 }
00108
00113 public static double[] xcorr(double[] a, double[] b, int maxlag)
00114 {
00115 double[] y = new double[2*maxlag+1];
00116 Arrays.fill(y, 0);
00117
00118 for(int lag = b.length-1, idx = maxlag-b.length+1;
00119 lag > -a.length; lag--, idx++)
00120 {
00121 if(idx < 0)
00122 continue;
00123
00124 if(idx >= y.length)
00125 break;
00126
00127
00128 int start = 0;
00129
00130 if(lag < 0)
00131 {
00132
00133 start = -lag;
00134 }
00135
00136 int end = a.length-1;
00137
00138 if(end > b.length-lag-1)
00139 {
00140 end = b.length-lag-1;
00141
00142 }
00143
00144
00145 for(int n = start; n <= end; n++)
00146 {
00147
00148 y[idx] += a[n]*b[lag+n];
00149 }
00150
00151 }
00152
00153 return(y);
00154 }
00155
00163 public static double[] filter(double[] b, double[] a, double[] x)
00164 {
00165 double[] y = new double[x.length];
00166
00167
00168 if(a[0] != 1)
00169 {
00170 for(int ia = 1; ia < a.length; ia++)
00171 a[ia] = a[ia]/a[0];
00172
00173 for(int ib = 0; ib < b.length; ib++)
00174 b[ib] = b[ib]/a[0];
00175 }
00176
00177 for(int t = 0; t < x.length; t++)
00178 {
00179 y[t] = 0;
00180
00181
00182 int len = b.length-1 < t ? b.length-1 : t;
00183 for(int ib = 0; ib <= len; ib++)
00184 y[t] += b[ib]*x[t-ib];
00185
00186
00187 len = a.length-1 < t ? a.length-1 : t;
00188 for(int ia = 1; ia <= len; ia++)
00189 y[t] -= a[ia]*y[t-ia];
00190 }
00191
00192 return y;
00193 }
00194
00203 public static double[] hanning(int n)
00204 {
00205 double[] wind = new double[n];
00206
00207 if(n == 1)
00208 wind[0] = 1;
00209 else
00210 for(int x = 1; x < n+1; x++)
00211 wind[x-1] = 0.5*(1 - Math.cos(2*Math.PI*x/(n+1)));
00212
00213 return wind;
00214 }
00215
00220 public static double dot(double[] a, double[] b)
00221 {
00222 double y = 0;
00223
00224 for(int x = 0; x < a.length; x++)
00225 y += a[x]*b[x];
00226
00227 return y;
00228 }
00229
00234 public static double[] times(double[] a, double[] b)
00235 {
00236 double[] y = new double[a.length];
00237
00238 for(int x = 0; x < y.length; x++)
00239 y[x] = a[x]*b[x];
00240
00241 return y;
00242 }
00243
00247 public static double[] times(double[] a, double b)
00248 {
00249 double[] y = new double[a.length];
00250
00251 for(int x = 0; x < y.length; x++)
00252 y[x] = a[x]*b;
00253
00254 return y;
00255 }
00256
00261 public static double[] rdivide(double[] a, double[] b)
00262 {
00263 double[] y = new double[a.length];
00264
00265 for(int x = 0; x < y.length; x++)
00266 y[x] = a[x]/b[x];
00267
00268 return y;
00269 }
00270
00274 public static double[] rdivide(double[] a, double b)
00275 {
00276 double[] y = new double[a.length];
00277
00278 for(int x = 0; x < y.length; x++)
00279 y[x] = a[x]/b;
00280
00281 return y;
00282 }
00283
00288 public static double[] plus(double[] a, double[] b)
00289 {
00290 double[] y = new double[a.length];
00291
00292 for(int x = 0; x < y.length; x++)
00293 y[x] = a[x]+b[x];
00294
00295 return y;
00296 }
00297
00301 public static double[] plus(double[] a, double b)
00302 {
00303 double[] y = new double[a.length];
00304
00305 for(int x = 0; x < y.length; x++)
00306 y[x] = a[x]+b;
00307
00308 return y;
00309 }
00310
00315 public static double[] minus(double[] a, double[] b)
00316 {
00317 double[] y = new double[a.length];
00318
00319 for(int x = 0; x < y.length; x++)
00320 y[x] = a[x]-b[x];
00321
00322 return y;
00323 }
00324
00328 public static double[] minus(double[] a, double b)
00329 {
00330 double[] y = new double[a.length];
00331
00332 for(int x = 0; x < y.length; x++)
00333 y[x] = a[x]-b;
00334
00335 return y;
00336 }
00337
00341 public static double[][] minus(double[][] A, double b)
00342 {
00343 double[][] Y = new double[A.length][A[0].length];
00344
00345 for(int x = 0; x < Y.length; x++)
00346 for(int y = 0; x < Y[x].length; y++)
00347 Y[x][y] = A[x][y]-b;
00348
00349 return Y;
00350 }
00351
00355 public static double[] minus(double a, double[] b)
00356 {
00357 double[] y = new double[b.length];
00358
00359 for(int x = 0; x < y.length; x++)
00360 y[x] = a-b[x];
00361
00362 return y;
00363 }
00364
00368 public static double sum(double[] a)
00369 {
00370 double y = 0;
00371
00372 for(int x = 0; x < a.length; x++)
00373 y += a[x];
00374
00375 return y;
00376 }
00377
00381 public static double[] cumsum(double[] a)
00382 {
00383 double[] A = new double[a.length];
00384
00385 A[0] = a[0];
00386 for(int x = 1; x < a.length; x++)
00387 A[x] = A[x-1] + a[x];
00388
00389 return A;
00390 }
00391
00395 public static double max(double[] a)
00396 {
00397 double y = Double.MIN_VALUE;
00398
00399 for(int x = 0; x < a.length; x++)
00400 if(a[x] > y)
00401 y = a[x];
00402
00403 return y;
00404 }
00405
00410 public static double[] max(double[] a, double[] b)
00411 {
00412 double[] y = new double[a.length];
00413
00414 for(int x = 0; x < a.length; x++)
00415 {
00416 if(a[x] > b[x])
00417 y[x] = a[x];
00418 else
00419 y[x] = b[x];
00420 }
00421
00422 return y;
00423 }
00424
00429 public static double[] max(double[] a, double b)
00430 {
00431 double[] y = new double[a.length];
00432
00433 for(int x = 0; x < a.length; x++)
00434 {
00435 if(a[x] > b)
00436 y[x] = a[x];
00437 else
00438 y[x] = b;
00439 }
00440
00441 return y;
00442 }
00443
00448 public static double[][] max(double[][] a, double b)
00449 {
00450 double[][] y = new double[a.length][a[0].length];
00451
00452 for(int r = 0; r < a.length; r++)
00453 {
00454 for(int c = 0; c < a[r].length; c++)
00455 {
00456 if(a[r][c] > b)
00457 y[r][c] = a[r][c];
00458 else
00459 y[r][c] = b;
00460 }
00461 }
00462
00463 return y;
00464 }
00465
00469 public static double[] max(double[][] a)
00470 {
00471 double[] y = new double[a.length];
00472 Arrays.fill(y, Double.MIN_VALUE);
00473
00474 for(int r = 0; r < a.length; r++)
00475 for(int c = 0; c < a[r].length; c++)
00476 if(a[r][c] > y[r])
00477 y[r] = a[r][c];
00478
00479 return y;
00480 }
00481
00485 public static double min(double[] a)
00486 {
00487 double y = Double.MAX_VALUE;
00488
00489 for(int x = 0; x < a.length; x++)
00490 if(a[x] < y)
00491 y = a[x];
00492
00493 return y;
00494 }
00495
00500 public static double[] min(double[] a, double[] b)
00501 {
00502 double[] y = new double[a.length];
00503
00504 for(int x = 0; x < a.length; x++)
00505 {
00506 if(a[x] < b[x])
00507 y[x] = a[x];
00508 else
00509 y[x] = b[x];
00510 }
00511
00512 return y;
00513 }
00514
00515
00520 public static double[] min(double[] a, double b)
00521 {
00522 double[] y = new double[a.length];
00523
00524 for(int x = 0; x < a.length; x++)
00525 {
00526 if(a[x] < b)
00527 y[x] = a[x];
00528 else
00529 y[x] = b;
00530 }
00531
00532 return y;
00533 }
00534
00539 public static double[][] min(double[][] a, double b)
00540 {
00541 double[][] y = new double[a.length][a[0].length];
00542
00543 for(int r = 0; r < a.length; r++)
00544 {
00545 for(int c = 0; c < a[r].length; c++)
00546 {
00547 if(a[r][c] < b)
00548 y[r][c] = a[r][c];
00549 else
00550 y[r][c] = b;
00551 }
00552 }
00553
00554 return y;
00555 }
00556
00557
00561 public static double[] min(double[][] a)
00562 {
00563 double[] y = new double[a.length];
00564 Arrays.fill(y, Double.MAX_VALUE);
00565
00566 for(int r = 0; r < a.length; r++)
00567 for(int c = 0; c < a[r].length; c++)
00568 if(a[r][c] < y[r])
00569 y[r] = a[r][c];
00570
00571 return y;
00572 }
00573
00574
00578 public static int argmax(double[] a)
00579 {
00580 double y = Double.MIN_VALUE;
00581 int idx = -1;
00582
00583 for(int x = 0; x < a.length; x++)
00584 {
00585 if(a[x] > y)
00586 {
00587 y = a[x];
00588 idx = x;
00589 }
00590 }
00591
00592 return idx;
00593 }
00594
00598 public static int argmin(double[] a)
00599 {
00600 double y = Double.MAX_VALUE;
00601 int idx = -1;
00602
00603 for(int x = 0; x < a.length; x++)
00604 {
00605 if(a[x] < y)
00606 {
00607 y = a[x];
00608 idx = x;
00609 }
00610 }
00611
00612 return idx;
00613 }
00614
00618 public static double[] slice(double[] a, int start, int end)
00619 {
00620 start = Math.max(start, 0);
00621 end = Math.min(end, a.length-1);
00622
00623 double[] y = new double[end-start+1];
00624
00625 for(int x = start, iy = 0; x <= end; x++, iy++)
00626 y[iy] = a[x];
00627
00628 return y;
00629 }
00630
00635 public static double[] range(int start, int end)
00636 {
00637 return range(start, end, 1);
00638
00639
00640
00641
00642
00643
00644
00645 }
00646
00651 public static double[] range(int start, int end, int increment)
00652 {
00653 double[] y = new double[1+(end-start)/increment];
00654
00655 for(int x = 0, num = start; x < y.length; x++, num += increment)
00656 y[x] = num;
00657
00658 return y;
00659 }
00660
00665 public static int[] irange(int start, int end, int increment)
00666 {
00667 int[] y = new int[1+(end-start)/increment];
00668
00669 for(int x = 0, num = start; x < y.length; x++, num += increment)
00670 y[x] = num;
00671
00672 return y;
00673 }
00674
00679 public static int[] irange(int start, int end)
00680 {
00681 return irange(start, end, 1);
00682 }
00683
00687 public static double[] subsref(double[] a, int[] idx)
00688 {
00689 double[] y = new double[idx.length];
00690
00691 for(int x = 0; x < idx.length; x++)
00692 y[x] = a[idx[x]];
00693
00694 return y;
00695 }
00696
00700 public static double[] subsref(double[] a, byte[] idx)
00701 {
00702 return subsref(a, find(idx));
00703 }
00704
00708 public static int[] find(byte[] a)
00709 {
00710 int[] v = new int[20];
00711
00712 int idx = 0;
00713 for(int x = 0; x < a.length; x++)
00714 {
00715 if(a[x] == 1)
00716 {
00717
00718
00719 v[idx++] = x;
00720
00721 if(idx == v.length)
00722 {
00723 int[] tmp = new int[2*v.length];
00724
00725 for(int i = 0; i < v.length; i++)
00726 tmp[i] = v[i];
00727
00728 v = tmp;
00729 }
00730 }
00731 }
00732
00733
00734 int[] tmp = new int[idx];
00735 for(int i = 0; i < tmp.length; i++)
00736 tmp[i] = v[i];
00737
00738
00739
00740 return tmp;
00741 }
00742
00747 public static byte[] lt(double[] a, double[] b)
00748 {
00749 byte[] y = new byte[a.length];
00750
00751 for(int x = 0; x < y.length; x++)
00752 {
00753 if(a[x] < b[x])
00754 y[x] = 1;
00755 else
00756 y[x] = 0;
00757 }
00758
00759 return y;
00760 }
00761
00766 public static byte[] lt(double[] a, double b)
00767 {
00768 byte[] y = new byte[a.length];
00769
00770 for(int x = 0; x < y.length; x++)
00771 {
00772 if(a[x] < b)
00773 y[x] = 1;
00774 else
00775 y[x] = 0;
00776 }
00777
00778 return y;
00779 }
00780
00785 public static byte[] le(double[] a, double[] b)
00786 {
00787 byte[] y = new byte[a.length];
00788
00789 for(int x = 0; x < y.length; x++)
00790 {
00791 if(a[x] <= b[x])
00792 y[x] = 1;
00793 else
00794 y[x] = 0;
00795 }
00796
00797 return y;
00798 }
00799
00804 public static byte[] le(double[] a, double b)
00805 {
00806 byte[] y = new byte[a.length];
00807
00808 for(int x = 0; x < y.length; x++)
00809 {
00810 if(a[x] <= b)
00811 y[x] = 1;
00812 else
00813 y[x] = 0;
00814 }
00815
00816 return y;
00817 }
00818
00823 public static byte[] gt(double[] a, double[] b)
00824 {
00825 byte[] y = new byte[a.length];
00826
00827 for(int x = 0; x < y.length; x++)
00828 {
00829 if(a[x] > b[x])
00830 y[x] = 1;
00831 else
00832 y[x] = 0;
00833 }
00834
00835 return y;
00836 }
00837
00842 public static byte[] gt(double[] a, double b)
00843 {
00844 byte[] y = new byte[a.length];
00845
00846 for(int x = 0; x < y.length; x++)
00847 {
00848 if(a[x] > b)
00849 y[x] = 1;
00850 else
00851 y[x] = 0;
00852 }
00853
00854 return y;
00855 }
00856
00861 public static byte[] ge(double[] a, double[] b)
00862 {
00863 byte[] y = new byte[a.length];
00864
00865 for(int x = 0; x < y.length; x++)
00866 {
00867 if(a[x] >= b[x])
00868 y[x] = 1;
00869 else
00870 y[x] = 0;
00871 }
00872
00873 return y;
00874 }
00875
00880 public static byte[] ge(double[] a, double b)
00881 {
00882 byte[] y = new byte[a.length];
00883
00884 for(int x = 0; x < y.length; x++)
00885 {
00886 if(a[x] >= b)
00887 y[x] = 1;
00888 else
00889 y[x] = 0;
00890 }
00891
00892 return y;
00893 }
00894
00898 public static double median(double[] a)
00899 {
00900
00901
00902 double[] tmp = slice(a, 0, a.length-1);
00903
00904 Arrays.sort(tmp);
00905
00906 return tmp[(int)tmp.length/2];
00907 }
00908
00912 public static double mean(double[] a)
00913 {
00914 return sum(a)/a.length;
00915 }
00916
00920 public static double[] mean(double[][] A)
00921 {
00922 double[] m = new double[A.length];
00923 int ncols = A[0].length;
00924
00925 for(int x = 0; x < A.length; x++)
00926 for(int y = 0; y < A[x].length; y++)
00927 m[x] += A[x][y]/ncols;
00928
00929 return m;
00930 }
00931
00932
00936 public static double[][] transpose(double[][] a)
00937 {
00938 double[][] y = new double[a[0].length][a.length];
00939
00940 for(int i = 0; i < a.length; i++)
00941 for(int j = 0; j < a[i].length; j++)
00942 y[j][i] = a[i][j];
00943
00944 return y;
00945 }
00946
00950 public static double[] round(double[] a)
00951 {
00952 double[] y = new double[a.length];
00953
00954 for(int x = 0; x < y.length; x++)
00955 y[x] = Math.round(a[x]);
00956
00957 return y;
00958 }
00959
00963 public static double[] abs(double[] a)
00964 {
00965 double[] y = new double[a.length];
00966
00967 for(int x = 0; x < y.length; x++)
00968 y[x] = Math.abs(a[x]);
00969
00970 return y;
00971 }
00972
00976 public static double[] cos(double[] a)
00977 {
00978 double[] y = new double[a.length];
00979
00980 for(int x = 0; x < y.length; x++)
00981 y[x] = Math.cos(a[x]);
00982
00983 return y;
00984 }
00985
00989 public static double[] sin(double[] a)
00990 {
00991 double[] y = new double[a.length];
00992
00993 for(int x = 0; x < y.length; x++)
00994 y[x] = Math.sin(a[x]);
00995
00996 return y;
00997 }
00998
01003 public static double[] power(double[] a, double b)
01004 {
01005 double[] y = new double[a.length];
01006
01007 for(int x = 0; x < y.length; x++)
01008 y[x] = Math.pow(a[x], b);
01009
01010 return y;
01011 }
01012
01016 public static double[] log(double[] a)
01017 {
01018 double[] y = new double[a.length];
01019
01020 for(int x = 0; x < y.length; x++)
01021 y[x] = Math.log(a[x]);
01022
01023 return y;
01024 }
01025
01029 public static double[] log10(double[] a)
01030 {
01031 double[] y = new double[a.length];
01032 double log10 = Math.log(10);
01033
01034 for(int x = 0; x < y.length; x++)
01035 y[x] = Math.log(a[x])/log10;
01036
01037 return y;
01038 }
01039
01043 public static double[] exp(double[] a)
01044 {
01045 double[] y = new double[a.length];
01046
01047 for(int x = 0; x < y.length; x++)
01048 y[x] = Math.exp(a[x]);
01049
01050 return y;
01051 }
01052
01053 public static double[] todouble(byte[] a)
01054 {
01055 double[] y = new double[a.length];
01056
01057 for(int x = 0; x < y.length; x++)
01058 y[x] = (double)a[x];
01059
01060 return y;
01061 }
01062
01063 public static double[] todouble(int[] a)
01064 {
01065 double[] y = new double[a.length];
01066
01067 for(int x = 0; x < y.length; x++)
01068 y[x] = (double)a[x];
01069
01070 return y;
01071 }
01072
01076 public static void setColumn(double[][] A, int n, double[] b)
01077 {
01078 for(int i=0; i < b.length; i++)
01079 A[i][n] = b[i];
01080 }
01081
01085 public static double[] getColumn(double[][] A, int n)
01086 {
01087 double[] y = new double[A.length];
01088
01089 for(int i=0; i < A.length; i++)
01090 y[i] = A[i][n];
01091
01092 return y;
01093 }
01094
01098 public static void imagesc(double[][] a)
01099 {
01100 DataDisplayPanel.spawnWindow(a);
01101 }
01102
01106 public static void imagesc(double[][] a, String s)
01107 {
01108 DataDisplayPanel.spawnWindow(a, s);
01109 }
01110
01114 public static void imagesc(double[] a)
01115 {
01116 double[][] d = new double[1][a.length];
01117 d[0] = a;
01118
01119 imagesc(transpose(d));
01120 }
01121
01125 public static void imagesc(double[] a, String s)
01126 {
01127
01128
01129
01130
01131
01132 double[][] d = new double[1][a.length];
01133 d[0] = a;
01134
01135 imagesc(transpose(d), s);
01136 }
01137
01141 public static void wavwrite(double[] d, int sr, String filename)
01142 {
01143 try
01144 {
01145 AudioWriter aw = new AudioWriter(new File(filename),
01146 new AudioFormat((int)sr, 16, 1,
01147 true, false),
01148 AudioFileFormat.Type.WAVE);
01149 aw.write(d, d.length);
01150 aw.close();
01151 }
01152 catch(IOException e)
01153 {
01154 System.out.println(e);
01155 }
01156 }
01157
01158 public static void printArray(double[] a)
01159 {
01160 for(int x = 0; x < a.length; x++)
01161 System.out.print(a[x]+" ");
01162 System.out.println("");
01163 }
01164
01165 public static void printArray(double[] a, String name)
01166 {
01167 System.out.print("name = ");
01168
01169 printArray(a);
01170 }
01171
01172 public static void main(String[] args)
01173 {
01174 double[] y = null;
01175
01176 double[] a = {-31, 1, 0, 1};
01177
01178
01179 double[] b = {1, 331};
01180
01181 int n = 10;
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198 String cmd = args[0];
01199 if(cmd.equals("conv") || cmd.equals("xcorr"))
01200 {
01201 if(cmd.equals("conv"))
01202 y = DSP.conv(a,b);
01203 else
01204 {
01205 if(args.length == 1)
01206 y = DSP.xcorr(b, a);
01207 else
01208 y = DSP.xcorr(b, a, Integer.parseInt(args[1]));
01209
01210 System.out.print("xcorr(b,a) = ");
01211 for(int x = 0; x < y.length; x++)
01212 System.out.print(y[x]+" ");
01213 System.out.println("");
01214
01215 if(args.length == 1)
01216 y = DSP.xcorr(a,b);
01217 else
01218 y = DSP.xcorr(a,b, Integer.parseInt(args[1]));
01219
01220 System.out.print("xcorr(a,b) = ");
01221 }
01222 }
01223 else if(cmd.equals("filter"))
01224 {
01225
01226
01227 double[] x = DSP.hanning(20);
01228
01229 y = DSP.filter(b,a,x);
01230 }
01231 else if(cmd.equals("hanning"))
01232 {
01233 if(args.length > 1)
01234 n = Integer.parseInt(args[1]);
01235
01236 y = DSP.hanning(n);
01237 }
01238
01239 for(int x = 0; x < y.length; x++)
01240 System.out.print(y[x]+" ");
01241
01242 System.out.println("");
01243 }
01244 }