func Decompose(f []float64, maxImf int) int { h := make([]float64, len(f)) residual := make([]float64, len(f)) copy(h, f) copy(residual, f) const eps = 0.05 imfCount := 0 loopCount := 0 rmin := 0.0 rmax := 0.0 monotonic := false n := len(f) imfs := algebra.NewMat(n, maxImf) for { fmt.Printf("loop %d\n", loopCount) loopCount = loopCount + 1 util.DumpSlice("current h", h) fmt.Printf("Sifting...\n") minMean, zeroCrossings, minCount, maxCount := Sift(h) extrema := minCount + maxCount fmt.Printf("found minMean of %f\n", minMean) fmt.Printf("min mean %f zc %d ex %d %d\n", minMean, zeroCrossings, minCount, maxCount) pointMatch := ((zeroCrossings-extrema < 2) || (extrema-zeroCrossings < 2)) if (minMean < eps) && pointMatch { fmt.Printf("storing imf at index %d\n", imfCount) for i := 0; i < n; i++ { imfs[i][imfCount] = h[i] } imfCount = imfCount + 1 fmt.Printf("found imf number %d\n", imfCount) util.SliceSub(residual, h, residual) copy(h, residual) if imfCount >= maxImf { break } rmin, rmax, monotonic = util.SliceStats(residual) if monotonic { fmt.Printf("terminating with monotonic residual\n") } if (rmax - rmin) < eps { fmt.Printf("terminating with small residual %f\n", rmax-rmin) } } } algebra.MatInfo(imfs) return imfCount }
func TestSolver(n int) { fmt.Printf("Testing TDMA Solver\n") now := time.Now() seed := now.Unix() rand.Seed(seed) A := algebra.NewMat(n, n) x := make([]float64, n) b := make([]float64, n) for i := 0; i < n; i++ { x[i] = rand.Float64() A[i][i] = rand.Float64() if i < (n - 1) { A[i+1][i] = rand.Float64() A[i][i+1] = rand.Float64() } } algebra.MatMul(A, x, b) algebra.MatInfo(A) util.DumpSlice("x", x) util.DumpSlice("b", b) diag := make([]float64, n) unk := make([]float64, n) od_l := make([]float64, n) od_u := make([]float64, n) for i := 0; i < n; i++ { diag[i] = A[i][i] if i > 0 { od_l[i] = A[i][i-1] } if i < (n - 1) { od_u[i] = A[i][i+1] } } cp := make([]float64, n) dp := make([]float64, n) //util.DumpSlice("diag",diag) //util.DumpSlice("od_lower",od_l) //util.DumpSlice("od_upper",od_u) solver.Tdma(od_l, diag, od_u, b, unk, cp, dp) util.DumpSlice("result", unk) }
func TestMatMul() { a := algebra.NewMat(3, 4) x := make([]float64, 4) b := make([]float64, 3) for i := 0; i < len(x); i++ { x[i] = float64(i + 1) } v := 1.0 for r, row := range a { for c, _ := range row { a[r][c] = v v = v + 1.0 } } util.DumpSlice("x", x) algebra.MatInfo(a) algebra.MatMul(a, x, b) util.DumpSlice("b", b) }
func Sift(h []float64) (float64, int, int, int) { inEnergy := util.Energy(h) n := len(h) minVals := make([]float64, n) minLocs := make([]float64, n) maxVals := make([]float64, n) maxLocs := make([]float64, n) upperEnvelope := make([]float64, n) lowerEnvelope := make([]float64, n) var mean float64 var smallestMean float64 var zeroCrossings int detail := algebra.NewMat(n, 5) minVals, minLocs, maxVals, maxLocs, zeroCrossings = peaks.Detect(h, minVals, minLocs, maxVals, maxLocs, 0.1, true) fmt.Printf("found %d minima and %d maxima and %d zero crossings\n", len(minVals), len(maxVals), zeroCrossings) util.DumpSlice("minima", minVals) util.DumpSlice("minlocs", minLocs) util.DumpSlice("maxima", maxVals) util.DumpSlice("maxlocs", maxLocs) fmt.Printf("getting upper envelope\n") upperEnvelope = resample.Resamp(maxLocs, maxVals, upperEnvelope) //util.DumpSlice("upper",upperEnvelope) fmt.Printf("getting lower envelope\n") lowerEnvelope = resample.Resamp(minLocs, minVals, lowerEnvelope) //util.DumpSlice("lower",lowerEnvelope) for i := 0; i < n; i++ { detail[i][0] = h[i] detail[i][1] = upperEnvelope[i] detail[i][2] = lowerEnvelope[i] } fmt.Printf("subtracting the mean\n") for i := 0; i < n; i++ { mean = 0.5 * (upperEnvelope[i] + lowerEnvelope[i]) h[i] = h[i] - mean detail[i][3] = mean detail[i][4] = h[i] if i == 0 { smallestMean = math.Abs(mean) } else { smallestMean = math.Min(math.Abs(mean), smallestMean) } } algebra.MatInfo(detail) outEnergy := util.Energy(h) fmt.Printf("... reduced energy from %f to %f\n", inEnergy, outEnergy) return smallestMean, zeroCrossings, len(minVals), len(maxVals) }