public static bool Deconvolve2(double[,] xImage, double[,] residuals, double[,] psf, double lambda, double alpha, Random random, int maxIteration = 100, double epsilon = 1e-4) { var xImage2 = ToFloatImage(xImage); var PSFConvolution = CommonDeprecated.PSF.CalcPaddedFourierConvolution(psf, residuals.GetLength(0), residuals.GetLength(1)); var PSFCorrelation = CommonDeprecated.PSF.CalculateFourierCorrelation(psf, residuals.GetLength(0), residuals.GetLength(1)); var PSFSquared = Fourier2D.Multiply(PSFConvolution, PSFCorrelation); var bMapCalculator = new PaddedConvolver(PSFCorrelation, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1))); var resUpdateCalculator = new PaddedConvolver(PSFConvolution, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1))); var bMapUpdateCalculator = new PaddedConvolver(PSFSquared, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1))); var yBlockSize = 2; var xBlockSize = 2; var bMap = ToFloatImage(residuals); bMapCalculator.ConvolveInPlace(bMap); FitsIO.Write(bMap, "bmapFirst.fits"); var xDiff = new float[xImage.GetLength(0), xImage.GetLength(1)]; var lipschitz = ApproximateLipschitz(psf, yBlockSize, xBlockSize); var startL2 = NaiveGreedyCD.CalcDataObjective(residuals); var iter = 0; while (iter < maxIteration) { var yB = random.Next(xImage.GetLength(0) / yBlockSize); var xB = random.Next(xImage.GetLength(1) / xBlockSize); //yB = 64 / yBlockSize; //xB = 64 / xBlockSize; var block = CopyFrom(bMap, yB, xB, yBlockSize, xBlockSize); //var optimized = block * blockInversion; var update = block / lipschitz; var xOld = CopyFrom(xImage2, yB, xB, yBlockSize, xBlockSize); var optimized = xOld + update; //shrink bool containsNonZero = false; for (int i = 0; i < optimized.Count; i++) { optimized[i] = CommonDeprecated.ShrinkElasticNet(optimized[i], lambda, alpha); containsNonZero |= (optimized[i] - xOld[i]) != 0.0; } var optDiff = optimized - xOld; if (containsNonZero) { AddInto(xDiff, optDiff, yB, xB, yBlockSize, xBlockSize); AddInto(xImage2, optDiff, yB, xB, yBlockSize, xBlockSize); //FitsIO.Write(xImage2, "xImageBlock.fits"); //FitsIO.Write(xDiff, "xDiff.fits"); //update b-map bMapUpdateCalculator.ConvolveInPlace(xDiff); //FitsIO.Write(xDiff, "bMapUpdate.fits"); for (int i = 0; i < xDiff.GetLength(0); i++) { for (int j = 0; j < xDiff.GetLength(1); j++) { bMap[i, j] -= xDiff[i, j]; xDiff[i, j] = 0; } } //FitsIO.Write(bMap, "bMap2.fits"); //calc residuals for debug purposes AddInto(xDiff, optDiff, yB, xB, yBlockSize, xBlockSize); resUpdateCalculator.ConvolveInPlace(xDiff); //FitsIO.Write(xDiff, "residualsUpdate.fits"); for (int i = 0; i < xDiff.GetLength(0); i++) { for (int j = 0; j < xDiff.GetLength(1); j++) { residuals[i, j] -= xDiff[i, j]; xDiff[i, j] = 0; } } //FitsIO.Write(residuals, "residuals2.fits"); var l2 = NaiveGreedyCD.CalcDataObjective(residuals); Console.WriteLine(l2); } iter++; } for (int i = 0; i < xImage.GetLength(0); i++) { for (int j = 0; j < xImage.GetLength(1); j++) { xImage[i, j] = xImage2[i, j]; } } return(false); }
public static bool Deconvolve2(double[,] xImage, double[,] residuals, double[,] psf, double lambda, double alpha, int blockSize, int maxIteration = 100, double epsilon = 1e-4) { var xImage2 = ToFloatImage(xImage); var PSFConvolution = CommonDeprecated.PSF.CalcPaddedFourierConvolution(psf, residuals.GetLength(0), residuals.GetLength(1)); var PSFCorrelation = CommonDeprecated.PSF.CalculateFourierCorrelation(psf, residuals.GetLength(0), residuals.GetLength(1)); var PSFSquared = Fourier2D.Multiply(PSFConvolution, PSFCorrelation); var bMapCalculator = new PaddedConvolver(PSFCorrelation, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1))); var resUpdateCalculator = new PaddedConvolver(PSFConvolution, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1))); var bMapUpdateCalculator = new PaddedConvolver(PSFSquared, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1))); var yBlockSize = blockSize; var xBlockSize = blockSize; var bMap = ToFloatImage(residuals); bMapCalculator.ConvolveInPlace(bMap); var xDiff = new float[xImage.GetLength(0), xImage.GetLength(1)]; var startL2 = NaiveGreedyCD.CalcDataObjective(residuals); var theta = 2; //theta, also number of processors. var degreeOfSep = RandomCD.CountNonZero(psf); var blockCount = xImage.Length / (yBlockSize * xBlockSize); var beta = 1.0 + (degreeOfSep - 1.0) * (theta - 1.0) / (Math.Max(1.0, (blockCount - 1))); //arises from E.S.O of theta-nice sampling. Look at the original PCDM Paper for the explanation //Theta-nice sampling: take theta number of random pixels var lipschitz = RandomBlockCD2.ApproximateLipschitz(psf, yBlockSize, xBlockSize); lipschitz *= beta; lambda = lambda / (yBlockSize * xBlockSize * beta); var iter = 0; while (iter < maxIteration) { bool containsNonZero = false; var maxBlocks = GetMaxBlocks(bMap, xImage2, lipschitz, (float)lambda, (float)alpha, yBlockSize, xBlockSize, theta); foreach (var b in maxBlocks) { var yBlock = b.Item1; var xBlock = b.Item2; var block = RandomBlockCD2.CopyFrom(bMap, yBlock, xBlock, yBlockSize, xBlockSize); var update = block / lipschitz; var xOld = RandomBlockCD2.CopyFrom(xImage2, yBlock, xBlock, yBlockSize, xBlockSize); var optimized = xOld + update; //shrink for (int j = 0; j < optimized.Count; j++) { optimized[j] = CommonDeprecated.ShrinkElasticNet(optimized[j], lambda, alpha); containsNonZero |= (optimized[j] - xOld[j]) != 0.0; } var optDiff = optimized - xOld; RandomBlockCD2.AddInto(xDiff, optDiff, yBlock, xBlock, yBlockSize, xBlockSize); RandomBlockCD2.AddInto(xImage2, optDiff, yBlock, xBlock, yBlockSize, xBlockSize); } if (containsNonZero) { //FitsIO.Write(xImage2, "xImageBlock.fits"); //FitsIO.Write(xDiff, "xDiff.fits"); //update b-map bMapUpdateCalculator.ConvolveInPlace(xDiff); //FitsIO.Write(xDiff, "bMapUpdate.fits"); for (int i = 0; i < xDiff.GetLength(0); i++) { for (int j = 0; j < xDiff.GetLength(1); j++) { bMap[i, j] -= xDiff[i, j]; xDiff[i, j] = 0; } } //FitsIO.Write(bMap, "bMap2.fits"); //calc residuals for debug purposes /*if (maxBlock.Item3 < epsilon) * break;*/ //Console.WriteLine(maxBlock.Item3 + "\t yB = " + yB + "\t xB =" + xB); } iter++; } var elasticNet = 0.0; for (int i = 0; i < xImage.GetLength(0); i++) { for (int j = 0; j < xImage.GetLength(1); j++) { xDiff[i, j] = xImage2[i, j] - (float)xImage[i, j]; xImage[i, j] = xImage2[i, j]; elasticNet += lambda * 2 * lipschitz * GreedyBlockCD.ElasticNetPenalty(xImage2[i, j], (float)alpha); } } resUpdateCalculator.ConvolveInPlace(xDiff); //FitsIO.Write(xDiff, "residualsUpdate.fits"); for (int i = 0; i < xDiff.GetLength(0); i++) { for (int j = 0; j < xDiff.GetLength(1); j++) { residuals[i, j] -= xDiff[i, j]; xDiff[i, j] = 0; } } var l2Penalty = NaiveGreedyCD.CalcDataObjective(residuals); Console.WriteLine("-------------------------"); Console.WriteLine((l2Penalty + elasticNet)); var io = System.IO.File.AppendText("penalty" + yBlockSize + ".txt"); io.WriteLine("l2: " + l2Penalty + "\telastic: " + elasticNet + "\t " + (l2Penalty + elasticNet)); io.Close(); Console.WriteLine("-------------------------"); return(false); }
public static bool Deconvolve(double[,] xImage, double[,] residuals, double[,] psf, double lambda, double alpha, int maxIteration = 100, double epsilon = 1e-4) { FitsIO.Write(residuals, "res.fits"); var yBlockSize = 2; var xBlockSize = 2; var PSFCorrelated = CommonDeprecated.PSF.CalculateFourierCorrelation(psf, psf.GetLength(0), psf.GetLength(1)); var RES = FFT.Forward(residuals); var BMAPFourier = Common.Fourier2D.Multiply(RES, PSFCorrelated); var bMap = FFT.Backward(BMAPFourier, BMAPFourier.Length); //FFT.Shift(bMap); FitsIO.Write(bMap, "bMap.fits"); var PSF = FFT.Forward(CommonDeprecated.Residuals.Pad(psf, psf.GetLength(0), psf.GetLength(1)), 1.0); var PSF2Fourier = Common.Fourier2D.Multiply(PSF, PSFCorrelated); var xDiff = new double[xImage.GetLength(0), xImage.GetLength(1)]; //var blockInversion = CalcBlock(psf, yBlockSize, xBlockSize).Inverse(); var random = new Random(123); var lipschitz = ApproximateLipschitz(psf, yBlockSize, xBlockSize); var startL2 = NaiveGreedyCD.CalcDataObjective(residuals); var iter = 0; while (iter < maxIteration) { /* * var yB = random.Next(xImage.GetLength(0) / yBlockSize); * var xB = random.Next(xImage.GetLength(1) / xBlockSize); * yB = 64 / yBlockSize; * xB = 64 / xBlockSize; * var block = CopyFrom(bMap, yB, xB, yBlockSize, xBlockSize); * * //var optimized = block * blockInversion; * * var optimized = block / lipschitz /4; * var xOld = CopyFrom(xImage, yB, xB, yBlockSize, xBlockSize); * optimized = xOld + optimized; * * //shrink * for (int i = 0; i < optimized.Count; i++) * optimized[i] = Common.ShrinkElasticNet(optimized[i], lambda, alpha); * var optDiff = optimized - xOld; * //AddInto(xDiff, optDiff, yB, xB, yBlockSize, xBlockSize); * AddInto(xImage, optDiff, yB, xB, yBlockSize, xBlockSize); * FitsIO.Write(xImage, "xImageBlock.fits"); * FitsIO.Write(xDiff, "xDiff.fits"); * xDiff[64, 64] = 1.0; * * //update b-map * var XDIFF = FFT.Forward(xDiff); * XDIFF = Common.Fourier2D.Multiply(XDIFF, PSF2Fourier); * Common.Fourier2D.SubtractInPlace(BMAPFourier, XDIFF); * bMap = FFT.Backward(BMAPFourier, BMAPFourier.Length); * //FFT.Shift(bMap); * FitsIO.Write(bMap, "bMap2.fits"); * * //calc residuals for debug purposes * var XDIFF2 = FFT.Forward(xDiff); * XDIFF2 = Common.Fourier2D.Multiply(XDIFF2, PSF); * var RES2 = Common.Fourier2D.Subtract(RES, XDIFF2); * var resDebug = FFT.Backward(RES2, RES2.Length); * var L2 = NaiveGreedyCD.CalcDataObjective(resDebug); * FitsIO.Write(resDebug, "resDebug.fits"); * var xDiff3 = FFT.Backward(XDIFF2, XDIFF2.Length); * FitsIO.Write(xDiff3, "recDebug.fits"); * * //clear from xDiff * AddInto(xDiff, -optDiff, yB, xB, yBlockSize, xBlockSize);*/ iter++; } return(false); }
public static bool Deconvolve2(double[,] xImage, double[,] residuals, double[,] psf, double lambda, double alpha, int blockSize, int maxIteration = 100, double epsilon = 1e-4) { var xImage2 = ToFloatImage(xImage); var PSFConvolution = CommonDeprecated.PSF.CalcPaddedFourierConvolution(psf, residuals.GetLength(0), residuals.GetLength(1)); var PSFCorrelation = CommonDeprecated.PSF.CalculateFourierCorrelation(psf, residuals.GetLength(0), residuals.GetLength(1)); var PSFSquared = Fourier2D.Multiply(PSFConvolution, PSFCorrelation); var bMapCalculator = new PaddedConvolver(PSFCorrelation, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1))); var resUpdateCalculator = new PaddedConvolver(PSFConvolution, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1))); var bMapUpdateCalculator = new PaddedConvolver(PSFSquared, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1))); var yBlockSize = blockSize; var xBlockSize = blockSize; lambda = lambda / (yBlockSize * xBlockSize); var bMap = ToFloatImage(residuals); bMapCalculator.ConvolveInPlace(bMap); FitsIO.Write(bMap, "bmapFirst.fits"); var xDiff = new float[xImage.GetLength(0), xImage.GetLength(1)]; var lipschitz = ApproximateLipschitz(psf, yBlockSize, xBlockSize); var startL2 = NaiveGreedyCD.CalcDataObjective(residuals); var iter = 0; while (iter < maxIteration) { var maxBlock = GetMaxBlock(bMap, xImage2, lipschitz, (float)lambda, (float)alpha, yBlockSize, xBlockSize); var yB = maxBlock.Item1; var xB = maxBlock.Item2; //yB = 64 / yBlockSize; //xB = 64 / xBlockSize; var block = CopyFrom(bMap, yB, xB, yBlockSize, xBlockSize); //var optimized = block * blockInversion; var update = block / lipschitz; var xOld = CopyFrom(xImage2, yB, xB, yBlockSize, xBlockSize); var optimized = xOld + update; //shrink bool containsNonZero = false; for (int i = 0; i < optimized.Count; i++) { optimized[i] = CommonDeprecated.ShrinkElasticNet(optimized[i], lambda, alpha); containsNonZero |= (optimized[i] - xOld[i]) != 0.0; } var optDiff = optimized - xOld; if (containsNonZero) { AddInto(xDiff, optDiff, yB, xB, yBlockSize, xBlockSize); AddInto(xImage2, optDiff, yB, xB, yBlockSize, xBlockSize); //FitsIO.Write(xImage2, "xImageBlock.fits"); //FitsIO.Write(xDiff, "xDiff.fits"); //update b-map bMapUpdateCalculator.ConvolveInPlace(xDiff); //FitsIO.Write(xDiff, "bMapUpdate.fits"); for (int i = 0; i < xDiff.GetLength(0); i++) { for (int j = 0; j < xDiff.GetLength(1); j++) { bMap[i, j] -= xDiff[i, j]; xDiff[i, j] = 0; } } //FitsIO.Write(bMap, "bMap2.fits"); //calc residuals for debug purposes /*if (maxBlock.Item3 < epsilon) * break;*/ Console.WriteLine(maxBlock.Item3 + "\t yB = " + yB + "\t xB =" + xB); } iter++; } var elasticNet = 0.0; for (int i = 0; i < xImage.GetLength(0); i++) { for (int j = 0; j < xImage.GetLength(1); j++) { xDiff[i, j] = xImage2[i, j] - (float)xImage[i, j]; xImage[i, j] = xImage2[i, j]; elasticNet += lambda * 2 * lipschitz * ElasticNetPenalty(xImage2[i, j], (float)alpha); } } resUpdateCalculator.ConvolveInPlace(xDiff); //FitsIO.Write(xDiff, "residualsUpdate.fits"); for (int i = 0; i < xDiff.GetLength(0); i++) { for (int j = 0; j < xDiff.GetLength(1); j++) { residuals[i, j] -= xDiff[i, j]; xDiff[i, j] = 0; } } var l2Penalty = NaiveGreedyCD.CalcDataObjective(residuals); Console.WriteLine("-------------------------"); Console.WriteLine((l2Penalty + elasticNet)); var io = System.IO.File.AppendText("penalty" + yBlockSize + ".txt"); io.WriteLine("l2: " + l2Penalty + "\telastic: " + elasticNet + "\t " + (l2Penalty + elasticNet)); io.Close(); Console.WriteLine("-------------------------"); return(false); }