From cd3c53886d9682a1d516ec394fa612bb24eb0141 Mon Sep 17 00:00:00 2001 From: Chris Kalonakis Date: Mon, 18 Dec 2023 12:20:53 +0200 Subject: [PATCH] Update -Implemented Zhuoran's reference compression algorithm as a memory/speed tradeoff for locations with high memory requirement -Optimized the custom BigNum implementation, which decreases the reference calculation time in shallow areas -Optimized the mpfr/mpir reference calculations by reducing the number of JNA calls -Implemented Zhuoran's multithreaded BLA table generation code. (It mostly affects areas with high iteration count, when using compression) -Modified the drawing algorithms to include more tiling options -Added convergent bailout as an option -The zoom sequence renderer of Image Expander will now save the render settings and also the zoom factor on every step -Added an aspect ratio option in zoom sequence renderer as a temporary workaround, until I implement non-square image format -Bug Fixes and general improvements --- Changelog.txt | 11 + README.txt | 2 +- lib/big-math-2.3.2.jar | Bin 0 -> 58140 bytes .../jnoise/core/api/annotations/Vector1D.java | 8 + .../jnoise/core/api/annotations/Vector2D.java | 8 + .../jnoise/core/api/annotations/Vector3D.java | 8 + .../jnoise/core/api/annotations/Vector4D.java | 8 + .../jnoise/core/api/functions/Combiner.java | 106 +- .../jnoise/core/api/noisegen/NoiseResult.java | 4 +- .../SeededExplicitNoiseGenerator.java | 5 - .../api/pipeline/ExplicitNoiseSource.java | 5 - .../api/transformers/DetailedTransformer.java | 42 +- .../articdive/jnoise/core/util/MathUtil.java | 37 + .../jnoise/core/util/vectors/Vector.java | 45 - .../jnoise/core/util/vectors/Vector1D.java | 31 - .../jnoise/core/util/vectors/Vector2D.java | 39 - .../jnoise/core/util/vectors/Vector3D.java | 46 - .../jnoise/core/util/vectors/Vector4D.java | 52 - .../interpolation/Interpolation.java | 22 +- .../FastSimplexNoiseGenerator.java | 348 +- .../SuperSimplexNoiseGenerator.java | 348 +- .../pattern/CheckerboardNoiseGenerator.java | 3 - .../pattern/CylinderNoiseGenerator.java | 3 - .../pattern/SphereNoiseGenerator.java | 3 - .../noisegen/perlin/PerlinNoiseGenerator.java | 174 +- .../gaussian/GaussianWhiteNoiseGenerator.java | 306 +- .../random/white/WhiteNoiseGenerator.java | 4 - .../noisegen/value/ValueNoiseGenerator.java | 6 - .../noisegen/worley/WorleyNoiseGenerator.java | 81 +- .../noisegen/worley/WorleyNoiseResult.java | 11 +- .../bailout_conditions/BailoutCondition.java | 2 +- src/fractalzoomer/core/BigComplex.java | 4 + src/fractalzoomer/core/BigIntNum.java | 75 +- src/fractalzoomer/core/BigIntNumComplex.java | 21 + src/fractalzoomer/core/BigNum.java | 3743 +------------ src/fractalzoomer/core/BigNum30.java | 4727 +++++++++++++++++ src/fractalzoomer/core/BigNum32.java | 2497 +++++++++ src/fractalzoomer/core/BigNum60.java | 3626 +++++++++++++ src/fractalzoomer/core/BigNum64.java | 2733 ++++++++++ src/fractalzoomer/core/BigNumComplex.java | 63 +- src/fractalzoomer/core/Complex.java | 6 +- .../core/CompressedDeepReference.java | 337 ++ .../core/CompressedDoubleReference.java | 270 + src/fractalzoomer/core/DDComplex.java | 14 + src/fractalzoomer/core/DeepReference.java | 15 +- src/fractalzoomer/core/DoubleDouble.java | 2 + src/fractalzoomer/core/DoubleReference.java | 16 +- src/fractalzoomer/core/DrawOrbit.java | 208 +- src/fractalzoomer/core/GenericComplex.java | 11 +- src/fractalzoomer/core/MantExpComplex.java | 55 +- .../core/MantExpComplexFull.java | 55 + src/fractalzoomer/core/MpfrBigNumComplex.java | 14 + src/fractalzoomer/core/MpirBigNumComplex.java | 13 + src/fractalzoomer/core/MyApfloat.java | 35 +- .../core/ReferenceCompressor.java | 659 +++ src/fractalzoomer/core/ReferenceData.java | 116 +- .../core/ReferenceDecompressor.java | 944 ++++ src/fractalzoomer/core/ReferenceDeepData.java | 113 +- src/fractalzoomer/core/TaskDraw.java | 790 +-- src/fractalzoomer/core/Waypoint.java | 53 + .../MeanNoOutliersAntialiasingAlgorithm.java | 40 +- src/fractalzoomer/core/bla/BLAS.java | 332 +- .../core/domain_coloring/DomainColoring.java | 35 +- .../BoundaryTracing2Draw.java | 15 +- .../BoundaryTracing3Draw.java | 15 +- ...daryTracingColorsAndIterationDataDraw.java | 31 +- .../BoundaryTracingDraw.java | 31 +- .../drawing_algorithms/BruteForce2Draw.java | 30 +- .../drawing_algorithms/BruteForceDraw.java | 97 +- .../BruteForceInterleavedDraw.java | 719 +++ .../CircularBruteForceDraw.java | 157 +- ...ntGuessing2ColorsAndIterationDataDraw.java | 48 + ...ularSuccessiveRefinementGuessing2Draw.java | 1029 ++++ ...cularSuccessiveRefinementGuessingDraw.java | 359 +- .../MarianiSilver2Draw.java | 33 +- ...ianiSilver3ColorsAndIterationDataDraw.java | 67 + .../MarianiSilver3Draw.java | 1550 ++++++ ...rianiSilverColorsAndIterationDataDraw.java | 2 + .../drawing_algorithms/MarianiSilverDraw.java | 85 +- .../drawing_algorithms/SolidGuessingDraw.java | 30 +- ...ntGuessing2ColorsAndIterationDataDraw.java | 49 + .../SuccessiveRefinementGuessing2Draw.java | 902 ++++ .../SuccessiveRefinementGuessingDraw.java | 301 +- .../drawing_algorithms/TiledGuessingDraw.java | 27 +- src/fractalzoomer/core/la/ATInfo.java | 4 +- src/fractalzoomer/core/la/GenericLAInfo.java | 95 +- src/fractalzoomer/core/la/LAInfoBase.java | 39 +- src/fractalzoomer/core/la/LAInfoBaseDeep.java | 38 +- src/fractalzoomer/core/la/LAReference.java | 788 ++- src/fractalzoomer/core/la/impl/LAInfo.java | 103 +- .../core/la/impl/LAInfoDeep.java | 110 +- .../core/la/impl/LAInfoDeepDetection2.java | 95 +- .../la/impl/LAInfoDeepDetection2Full.java | 102 +- .../core/la/impl/LAInfoDeepFull.java | 110 +- .../core/la/impl/LAInfoDetection2.java | 79 +- .../LAInfoDeepDetection2FullRI.java | 94 +- .../impl_refindex/LAInfoDeepDetection2RI.java | 90 +- .../la/impl_refindex/LAInfoDeepFullRI.java | 103 +- .../core/la/impl_refindex/LAInfoDeepRI.java | 98 +- .../la/impl_refindex/LAInfoDetection2RI.java | 74 +- .../core/la/impl_refindex/LAInfoRI.java | 91 +- src/fractalzoomer/core/location/Location.java | 23 +- .../delta/CartesianLocationDelta.java | 5 +- .../delta/CartesianLocationDeltaDeep.java | 5 +- ...artesianLocationNormalBigNumArbitrary.java | 16 +- src/fractalzoomer/core/mpfr/LibMpfr.java | 9 +- src/fractalzoomer/core/mpfr/MpfrBigNum.java | 98 +- src/fractalzoomer/core/mpfr/custom_mpfr.c | 387 +- src/fractalzoomer/core/mpir/LibMpir.java | 9 +- src/fractalzoomer/core/mpir/MpirBigNum.java | 93 +- src/fractalzoomer/core/mpir/custom_mpir.c | 174 +- src/fractalzoomer/core/unused/BigDecNum.java | 2 + .../core/unused/BigDecNumComplex.java | 6 + src/fractalzoomer/core/unused/BigNum64.java | 1810 ------- .../core/unused/MantExpSoft.java | 6 +- .../fractal_options/PlanePointOption.java | 2 + .../initial_value/DefaultInitialValue.java | 6 + .../DefaultInitialValueWithFactor.java | 6 + .../initial_value/InitialValue.java | 6 + .../VariableConditionalInitialValue.java | 6 + .../initial_value/VariableInitialValue.java | 6 + .../perturbation/DefaultPerturbation.java | 6 + .../perturbation/Perturbation.java | 6 + .../VariableConditionalPerturbation.java | 6 + .../perturbation/VariablePerturbation.java | 6 + .../functions/EscapingOrConverging.java | 8 +- .../functions/ExtendedConvergentType.java | 110 +- src/fractalzoomer/functions/Fractal.java | 681 ++- src/fractalzoomer/functions/Julia.java | 106 +- .../newtonvariant/LambertWVariation.java | 6 +- .../BuffaloMandelbrot.java | 24 +- .../CelticMandelbrot.java | 25 +- .../m_like_generalization/Formula47.java | 37 +- .../PerpendicularBuffaloMandelbrot.java | 24 +- .../PerpendicularBurningShip.java | 24 +- .../PerpendicularCelticMandelbrot.java | 24 +- .../PerpendicularMandelbrot.java | 24 +- .../c_azb_dze/Formula48.java | 993 ++++ .../NewtonThirdDegreeParameterSpace.java | 631 ++- src/fractalzoomer/functions/general/Nova.java | 336 +- .../functions/lambda/Lambda.java | 235 +- .../functions/magnet/Magnet1.java | 583 +- .../functions/magnet/Magnet13.java | 12 +- .../functions/magnet/Magnet14.java | 12 +- .../functions/magnet/Magnet2.java | 12 +- .../functions/magnet/Magnet23.java | 12 +- .../functions/magnet/Magnet24.java | 12 +- .../functions/magnet/MagnetPataki2.java | 85 +- .../functions/magnet/MagnetPataki3.java | 87 +- .../functions/magnet/MagnetPataki4.java | 88 +- .../functions/magnet/MagnetPataki5.java | 87 +- .../functions/magnet/MagnetPatakiType.java | 20 +- .../functions/magnet/MagnetType.java | 16 +- .../functions/mandelbrot/Mandelbar.java | 27 +- .../functions/mandelbrot/Mandelbrot.java | 301 +- .../functions/mandelbrot/MandelbrotCubed.java | 116 +- .../mandelbrot/MandelbrotEighth.java | 13 +- .../functions/mandelbrot/MandelbrotFifth.java | 118 +- .../mandelbrot/MandelbrotFourth.java | 179 +- .../functions/mandelbrot/MandelbrotNinth.java | 13 +- .../functions/mandelbrot/MandelbrotNth.java | 13 +- .../mandelbrot/MandelbrotSeventh.java | 13 +- .../functions/mandelbrot/MandelbrotSixth.java | 13 +- .../functions/mandelbrot/MandelbrotTenth.java | 13 +- .../RootFindingMethods.java | 43 +- .../abbasbandy/Abbasbandy3.java | 8 +- .../abbasbandy/Abbasbandy4.java | 8 +- .../abbasbandy/AbbasbandyCos.java | 8 +- .../abbasbandy/AbbasbandyFormula.java | 7 +- .../abbasbandy/AbbasbandyGeneralized3.java | 8 +- .../abbasbandy/AbbasbandyGeneralized8.java | 8 +- .../abbasbandy/AbbasbandyPoly.java | 9 +- .../AbbasbandyRootFindingMethod.java | 2 +- .../abbasbandy/AbbasbandySin.java | 8 +- .../abbasbandy2/Abbasbandy23.java | 9 +- .../abbasbandy2/Abbasbandy24.java | 9 +- .../abbasbandy2/Abbasbandy2Cos.java | 8 +- .../abbasbandy2/Abbasbandy2Formula.java | 7 +- .../abbasbandy2/Abbasbandy2Generalized3.java | 9 +- .../abbasbandy2/Abbasbandy2Generalized8.java | 9 +- .../abbasbandy2/Abbasbandy2Poly.java | 9 +- .../abbasbandy2/Abbasbandy2Sin.java | 10 +- .../abbasbandy3/Abbasbandy33.java | 8 +- .../abbasbandy3/Abbasbandy34.java | 9 +- .../abbasbandy3/Abbasbandy3Cos.java | 8 +- .../abbasbandy3/Abbasbandy3Formula.java | 7 +- .../abbasbandy3/Abbasbandy3Generalized3.java | 9 +- .../abbasbandy3/Abbasbandy3Generalized8.java | 9 +- .../abbasbandy3/Abbasbandy3Poly.java | 9 +- .../Abbasbandy3RootFindingMethod.java | 4 +- .../abbasbandy3/Abbasbandy3Sin.java | 8 +- .../aberth_ehrlich/AberthEhrlich3.java | 6 +- .../aberth_ehrlich/AberthEhrlich4.java | 6 +- .../AberthEhrlichGeneralized3.java | 6 +- .../AberthEhrlichGeneralized8.java | 6 +- .../aberth_ehrlich/AberthEhrlichPoly.java | 7 +- .../bairstow/Bairstow3.java | 7 +- .../bairstow/Bairstow4.java | 7 +- .../bairstow/BairstowGeneralized3.java | 7 +- .../bairstow/BairstowGeneralized8.java | 7 +- .../bairstow/BairstowPoly.java | 8 +- .../changbum_chun1/ChangBumChun13.java | 6 +- .../changbum_chun1/ChangBumChun14.java | 6 +- .../changbum_chun1/ChangBumChun1Cos.java | 6 +- .../changbum_chun1/ChangBumChun1Formula.java | 7 +- .../ChangBumChun1Generalized3.java | 6 +- .../ChangBumChun1Generalized8.java | 6 +- .../changbum_chun1/ChangBumChun1Poly.java | 6 +- .../ChangBumChun1RootFindingMethod.java | 2 +- .../changbum_chun1/ChangBumChun1Sin.java | 6 +- .../changbum_chun2/ChangBumChun23.java | 6 +- .../changbum_chun2/ChangBumChun24.java | 6 +- .../changbum_chun2/ChangBumChun2Cos.java | 6 +- .../changbum_chun2/ChangBumChun2Formula.java | 7 +- .../ChangBumChun2Generalized3.java | 6 +- .../ChangBumChun2Generalized8.java | 6 +- .../changbum_chun2/ChangBumChun2Poly.java | 6 +- .../changbum_chun2/ChangBumChun2Sin.java | 6 +- .../changbum_chun3/ChangBumChun33.java | 6 +- .../changbum_chun3/ChangBumChun34.java | 6 +- .../changbum_chun3/ChangBumChun3Cos.java | 6 +- .../changbum_chun3/ChangBumChun3Formula.java | 7 +- .../ChangBumChun3Generalized3.java | 6 +- .../ChangBumChun3Generalized8.java | 6 +- .../changbum_chun3/ChangBumChun3Poly.java | 6 +- .../changbum_chun3/ChangBumChun3Sin.java | 6 +- .../chun_ham/ChunHam3.java | 7 +- .../chun_ham/ChunHam4.java | 7 +- .../chun_ham/ChunHamCos.java | 7 +- .../chun_ham/ChunHamFormula.java | 7 +- .../chun_ham/ChunHamGeneralized3.java | 7 +- .../chun_ham/ChunHamGeneralized8.java | 7 +- .../chun_ham/ChunHamPoly.java | 7 +- .../chun_ham/ChunHamRootFindingMethod.java | 2 +- .../chun_ham/ChunHamSin.java | 7 +- .../chun_kim/ChunKim3.java | 8 +- .../chun_kim/ChunKim4.java | 8 +- .../chun_kim/ChunKimCos.java | 8 +- .../chun_kim/ChunKimFormula.java | 7 +- .../chun_kim/ChunKimGeneralized3.java | 8 +- .../chun_kim/ChunKimGeneralized8.java | 8 +- .../chun_kim/ChunKimPoly.java | 9 +- .../chun_kim/ChunKimSin.java | 8 +- .../ContraHarmonicNewton3.java | 8 +- .../ContraHarmonicNewton4.java | 8 +- .../ContraHarmonicNewtonCos.java | 8 +- .../ContraHarmonicNewtonFormula.java | 7 +- .../ContraHarmonicNewtonGeneralized3.java | 8 +- .../ContraHarmonicNewtonGeneralized8.java | 8 +- .../ContraHarmonicNewtonPoly.java | 9 +- .../ContraHarmonicNewtonSin.java | 8 +- .../durand_kerner/DurandKerner3.java | 8 +- .../durand_kerner/DurandKerner4.java | 8 +- .../DurandKernerGeneralized3.java | 8 +- .../DurandKernerGeneralized8.java | 8 +- .../durand_kerner/DurandKernerPoly.java | 9 +- .../euler_chebyshev/EulerChebyshev3.java | 8 +- .../euler_chebyshev/EulerChebyshev4.java | 8 +- .../euler_chebyshev/EulerChebyshevCos.java | 8 +- .../EulerChebyshevFormula.java | 7 +- .../EulerChebyshevGeneralized3.java | 8 +- .../EulerChebyshevGeneralized8.java | 8 +- .../euler_chebyshev/EulerChebyshevPoly.java | 8 +- .../euler_chebyshev/EulerChebyshevSin.java | 10 +- .../ezzati_saleki1/EzzatiSaleki13.java | 6 +- .../ezzati_saleki1/EzzatiSaleki14.java | 6 +- .../ezzati_saleki1/EzzatiSaleki1Cos.java | 6 +- .../ezzati_saleki1/EzzatiSaleki1Formula.java | 7 +- .../EzzatiSaleki1Generalized3.java | 6 +- .../EzzatiSaleki1Generalized8.java | 6 +- .../ezzati_saleki1/EzzatiSaleki1Poly.java | 6 +- .../ezzati_saleki1/EzzatiSaleki1Sin.java | 6 +- .../ezzati_saleki2/EzzatiSaleki23.java | 6 +- .../ezzati_saleki2/EzzatiSaleki24.java | 6 +- .../ezzati_saleki2/EzzatiSaleki2Cos.java | 6 +- .../ezzati_saleki2/EzzatiSaleki2Formula.java | 7 +- .../EzzatiSaleki2Generalized3.java | 6 +- .../EzzatiSaleki2Generalized8.java | 6 +- .../ezzati_saleki2/EzzatiSaleki2Poly.java | 6 +- .../EzzatiSaleki2RootFindingMethod.java | 2 +- .../ezzati_saleki2/EzzatiSaleki2Sin.java | 6 +- .../root_finding_methods/feng/Feng3.java | 6 +- .../root_finding_methods/feng/Feng4.java | 6 +- .../root_finding_methods/feng/FengCos.java | 6 +- .../feng/FengFormula.java | 7 +- .../feng/FengGeneralized3.java | 6 +- .../feng/FengGeneralized8.java | 6 +- .../root_finding_methods/feng/FengPoly.java | 6 +- .../root_finding_methods/feng/FengSin.java | 6 +- .../root_finding_methods/halley/Halley3.java | 8 +- .../root_finding_methods/halley/Halley4.java | 9 +- .../halley/HalleyCos.java | 10 +- .../halley/HalleyFormula.java | 8 +- .../halley/HalleyGeneralized3.java | 9 +- .../halley/HalleyGeneralized8.java | 9 +- .../halley/HalleyPoly.java | 9 +- .../halley/HalleySin.java | 10 +- .../HarmonicSimpsonNewton3.java | 8 +- .../HarmonicSimpsonNewton4.java | 8 +- .../HarmonicSimpsonNewtonCos.java | 8 +- .../HarmonicSimpsonNewtonFormula.java | 7 +- .../HarmonicSimpsonNewtonGeneralized3.java | 8 +- .../HarmonicSimpsonNewtonGeneralized8.java | 8 +- .../HarmonicSimpsonNewtonPoly.java | 9 +- .../HarmonicSimpsonNewtonSin.java | 8 +- .../homeier1/Homeier13.java | 8 +- .../homeier1/Homeier14.java | 8 +- .../homeier1/Homeier1Cos.java | 8 +- .../homeier1/Homeier1Formula.java | 7 +- .../homeier1/Homeier1Generalized3.java | 8 +- .../homeier1/Homeier1Generalized8.java | 8 +- .../homeier1/Homeier1Poly.java | 9 +- .../homeier1/Homeier1Sin.java | 8 +- .../homeier2/Homeier23.java | 8 +- .../homeier2/Homeier24.java | 8 +- .../homeier2/Homeier2Cos.java | 8 +- .../homeier2/Homeier2Formula.java | 7 +- .../homeier2/Homeier2Generalized3.java | 8 +- .../homeier2/Homeier2Generalized8.java | 8 +- .../homeier2/Homeier2Poly.java | 9 +- .../homeier2/Homeier2Sin.java | 8 +- .../householder/Householder3.java | 8 +- .../householder/Householder4.java | 8 +- .../householder/HouseholderCos.java | 10 +- .../householder/HouseholderFormula.java | 7 +- .../householder/HouseholderGeneralized3.java | 8 +- .../householder/HouseholderGeneralized8.java | 8 +- .../householder/HouseholderPoly.java | 8 +- .../householder/HouseholderSin.java | 10 +- .../householder3/Householder33.java | 9 +- .../householder3/Householder34.java | 9 +- .../householder3/Householder3Cos.java | 8 +- .../householder3/Householder3Formula.java | 7 +- .../Householder3Generalized3.java | 9 +- .../Householder3Generalized8.java | 9 +- .../householder3/Householder3Poly.java | 8 +- .../Householder3RootFindingMethod.java | 2 +- .../householder3/Householder3Sin.java | 8 +- .../root_finding_methods/jaratt/Jaratt3.java | 8 +- .../root_finding_methods/jaratt/Jaratt4.java | 8 +- .../jaratt/JarattCos.java | 8 +- .../jaratt/JarattFormula.java | 8 +- .../jaratt/JarattGeneralized3.java | 8 +- .../jaratt/JarattGeneralized8.java | 8 +- .../jaratt/JarattPoly.java | 9 +- .../jaratt/JarattRootFindingMethod.java | 4 +- .../jaratt/JarattSin.java | 8 +- .../jaratt2/Jaratt23.java | 8 +- .../jaratt2/Jaratt24.java | 8 +- .../jaratt2/Jaratt2Cos.java | 8 +- .../jaratt2/Jaratt2Formula.java | 8 +- .../jaratt2/Jaratt2Generalized3.java | 8 +- .../jaratt2/Jaratt2Generalized8.java | 8 +- .../jaratt2/Jaratt2Poly.java | 9 +- .../jaratt2/Jaratt2RootFindingMethod.java | 2 +- .../jaratt2/Jaratt2Sin.java | 8 +- .../kim_chun/KimChun3.java | 8 +- .../kim_chun/KimChun4.java | 8 +- .../kim_chun/KimChunCos.java | 8 +- .../kim_chun/KimChunFormula.java | 7 +- .../kim_chun/KimChunGeneralized3.java | 8 +- .../kim_chun/KimChunGeneralized8.java | 8 +- .../kim_chun/KimChunPoly.java | 9 +- .../kim_chun/KimChunSin.java | 8 +- .../root_finding_methods/king1/King13.java | 6 +- .../root_finding_methods/king1/King14.java | 7 +- .../root_finding_methods/king1/King1Cos.java | 7 +- .../king1/King1Formula.java | 8 +- .../king1/King1Generalized3.java | 6 +- .../king1/King1Generalized8.java | 7 +- .../root_finding_methods/king1/King1Poly.java | 6 +- .../king1/King1RootFindingMethod.java | 2 +- .../root_finding_methods/king1/King1Sin.java | 6 +- .../root_finding_methods/king3/King33.java | 6 +- .../root_finding_methods/king3/King34.java | 7 +- .../root_finding_methods/king3/King3Cos.java | 7 +- .../king3/King3Formula.java | 8 +- .../king3/King3Generalized3.java | 6 +- .../king3/King3Generalized8.java | 6 +- .../root_finding_methods/king3/King3Poly.java | 6 +- .../king3/King3RootFindingMethod.java | 2 +- .../root_finding_methods/king3/King3Sin.java | 7 +- .../kou_li_wang1/KouLiWang13.java | 6 +- .../kou_li_wang1/KouLiWang14.java | 6 +- .../kou_li_wang1/KouLiWang1Cos.java | 6 +- .../kou_li_wang1/KouLiWang1Formula.java | 7 +- .../kou_li_wang1/KouLiWang1Generalized3.java | 6 +- .../kou_li_wang1/KouLiWang1Generalized8.java | 6 +- .../kou_li_wang1/KouLiWang1Poly.java | 6 +- .../kou_li_wang1/KouLiWang1Sin.java | 6 +- .../laguerre/Laguerre3.java | 8 +- .../laguerre/Laguerre4.java | 9 +- .../laguerre/LaguerreCos.java | 10 +- .../laguerre/LaguerreFormula.java | 7 +- .../laguerre/LaguerreGeneralized3.java | 9 +- .../laguerre/LaguerreGeneralized8.java | 9 +- .../laguerre/LaguerrePoly.java | 9 +- .../laguerre/LaguerreSin.java | 10 +- .../maheshweri/Maheshweri3.java | 7 +- .../maheshweri/Maheshweri4.java | 7 +- .../maheshweri/MaheshweriCos.java | 7 +- .../maheshweri/MaheshweriFormula.java | 7 +- .../maheshweri/MaheshweriGeneralized3.java | 7 +- .../maheshweri/MaheshweriGeneralized8.java | 7 +- .../maheshweri/MaheshweriPoly.java | 7 +- .../MaheshweriRootFindingMethod.java | 2 +- .../maheshweri/MaheshweriSin.java | 7 +- .../midpoint/Midpoint3.java | 8 +- .../midpoint/Midpoint4.java | 8 +- .../midpoint/MidpointCos.java | 8 +- .../midpoint/MidpointFormula.java | 7 +- .../midpoint/MidpointGeneralized3.java | 8 +- .../midpoint/MidpointGeneralized8.java | 8 +- .../midpoint/MidpointPoly.java | 9 +- .../midpoint/MidpointSin.java | 8 +- .../root_finding_methods/muller/Muller3.java | 8 +- .../root_finding_methods/muller/Muller4.java | 8 +- .../muller/MullerCos.java | 8 +- .../muller/MullerFormula.java | 8 +- .../muller/MullerGeneralized3.java | 8 +- .../muller/MullerGeneralized8.java | 8 +- .../muller/MullerPoly.java | 8 +- .../muller/MullerSin.java | 8 +- .../nedzhibov/Nedzhibov3.java | 8 +- .../nedzhibov/Nedzhibov4.java | 8 +- .../nedzhibov/NedzhibovCos.java | 8 +- .../nedzhibov/NedzhibovFormula.java | 7 +- .../nedzhibov/NedzhibovGeneralized3.java | 8 +- .../nedzhibov/NedzhibovGeneralized8.java | 8 +- .../nedzhibov/NedzhibovPoly.java | 9 +- .../nedzhibov/NedzhibovSin.java | 8 +- .../root_finding_methods/newton/Newton3.java | 354 +- .../root_finding_methods/newton/Newton4.java | 8 +- .../newton/NewtonCos.java | 6 +- .../newton/NewtonFormula.java | 8 +- .../newton/NewtonGeneralized3.java | 8 +- .../newton/NewtonGeneralized8.java | 6 +- .../newton/NewtonPoly.java | 8 +- .../newton/NewtonSin.java | 10 +- .../newton_hines/NewtonHines3.java | 6 +- .../newton_hines/NewtonHines4.java | 9 +- .../newton_hines/NewtonHinesCos.java | 10 +- .../newton_hines/NewtonHinesFormula.java | 7 +- .../newton_hines/NewtonHinesGeneralized3.java | 9 +- .../newton_hines/NewtonHinesGeneralized8.java | 7 +- .../newton_hines/NewtonHinesPoly.java | 9 +- .../newton_hines/NewtonHinesSin.java | 10 +- .../noor_gupta/NoorGupta3.java | 7 +- .../noor_gupta/NoorGupta4.java | 7 +- .../noor_gupta/NoorGuptaCos.java | 7 +- .../noor_gupta/NoorGuptaFormula.java | 7 +- .../noor_gupta/NoorGuptaGeneralized3.java | 7 +- .../noor_gupta/NoorGuptaGeneralized8.java | 7 +- .../noor_gupta/NoorGuptaPoly.java | 7 +- .../noor_gupta/NoorGuptaSin.java | 7 +- .../parhalley/Parhalley3.java | 8 +- .../parhalley/Parhalley4.java | 9 +- .../parhalley/ParhalleyCos.java | 10 +- .../parhalley/ParhalleyFormula.java | 7 +- .../parhalley/ParhalleyGeneralized3.java | 9 +- .../parhalley/ParhalleyGeneralized8.java | 9 +- .../parhalley/ParhalleyPoly.java | 9 +- .../parhalley/ParhalleySin.java | 10 +- .../popovski1/Popovski13.java | 9 +- .../popovski1/Popovski14.java | 9 +- .../popovski1/Popovski1Cos.java | 10 +- .../popovski1/Popovski1Formula.java | 7 +- .../popovski1/Popovski1Generalized3.java | 9 +- .../popovski1/Popovski1Generalized8.java | 9 +- .../popovski1/Popovski1Poly.java | 9 +- .../popovski1/Popovski1Sin.java | 10 +- .../rafis_rafiullah/RafisRafiullah3.java | 8 +- .../rafis_rafiullah/RafisRafiullah4.java | 8 +- .../rafis_rafiullah/RafisRafiullahCos.java | 8 +- .../RafisRafiullahFormula.java | 7 +- .../RafisRafiullahGeneralized3.java | 8 +- .../RafisRafiullahGeneralized8.java | 8 +- .../rafis_rafiullah/RafisRafiullahPoly.java | 9 +- .../rafis_rafiullah/RafisRafiullahSin.java | 8 +- .../rafiullah1/Rafiullah13.java | 8 +- .../rafiullah1/Rafiullah14.java | 8 +- .../rafiullah1/Rafiullah1Cos.java | 8 +- .../rafiullah1/Rafiullah1Formula.java | 7 +- .../rafiullah1/Rafiullah1Generalized3.java | 8 +- .../rafiullah1/Rafiullah1Generalized8.java | 8 +- .../rafiullah1/Rafiullah1Poly.java | 9 +- .../rafiullah1/Rafiullah1Sin.java | 8 +- .../schroder/Schroder3.java | 8 +- .../schroder/Schroder4.java | 8 +- .../schroder/SchroderCos.java | 10 +- .../schroder/SchroderFormula.java | 7 +- .../schroder/SchroderGeneralized3.java | 8 +- .../schroder/SchroderGeneralized8.java | 6 +- .../schroder/SchroderPoly.java | 8 +- .../schroder/SchroderSin.java | 10 +- .../root_finding_methods/secant/Secant3.java | 2 +- .../root_finding_methods/secant/Secant4.java | 2 +- .../secant/SecantCos.java | 6 +- .../secant/SecantFormula.java | 7 +- .../secant/SecantGeneralized3.java | 2 +- .../secant/SecantGeneralized8.java | 2 +- .../secant/SecantPoly.java | 2 +- .../simpson_newton/SimpsonNewton3.java | 9 +- .../simpson_newton/SimpsonNewton4.java | 9 +- .../simpson_newton/SimpsonNewtonCos.java | 9 +- .../simpson_newton/SimpsonNewtonFormula.java | 7 +- .../SimpsonNewtonGeneralized3.java | 9 +- .../SimpsonNewtonGeneralized8.java | 9 +- .../simpson_newton/SimpsonNewtonPoly.java | 8 +- .../simpson_newton/SimpsonNewtonSin.java | 9 +- .../steffensen/Steffensen3.java | 8 +- .../steffensen/Steffensen4.java | 8 +- .../steffensen/SteffensenFormula.java | 7 +- .../steffensen/SteffensenGeneralized3.java | 8 +- .../steffensen/SteffensenPoly.java | 8 +- .../stirling/Stirling3.java | 7 +- .../stirling/Stirling4.java | 7 +- .../stirling/StirlingCos.java | 7 +- .../stirling/StirlingFormula.java | 7 +- .../stirling/StirlingGeneralized3.java | 7 +- .../stirling/StirlingGeneralized8.java | 7 +- .../stirling/StirlingPoly.java | 6 +- .../stirling/StirlingSin.java | 7 +- .../super_halley/SuperHalley3.java | 9 +- .../super_halley/SuperHalley4.java | 8 +- .../super_halley/SuperHalleyCos.java | 10 +- .../super_halley/SuperHalleyFormula.java | 7 +- .../super_halley/SuperHalleyGeneralized3.java | 8 +- .../super_halley/SuperHalleyGeneralized8.java | 8 +- .../super_halley/SuperHalleyPoly.java | 8 +- .../super_halley/SuperHalleySin.java | 10 +- .../third_order_newton/ThirdOrderNewton3.java | 6 +- .../third_order_newton/ThirdOrderNewton4.java | 6 +- .../ThirdOrderNewtonCos.java | 6 +- .../ThirdOrderNewtonFormula.java | 7 +- .../ThirdOrderNewtonGeneralized3.java | 6 +- .../ThirdOrderNewtonGeneralized8.java | 6 +- .../ThirdOrderNewtonPoly.java | 6 +- .../ThirdOrderNewtonRootFindingMethod.java | 2 +- .../ThirdOrderNewtonSin.java | 6 +- .../traub_ostrowski/TraubOstrowski3.java | 6 +- .../traub_ostrowski/TraubOstrowski4.java | 6 +- .../traub_ostrowski/TraubOstrowskiCos.java | 6 +- .../TraubOstrowskiFormula.java | 7 +- .../TraubOstrowskiGeneralized3.java | 6 +- .../TraubOstrowskiGeneralized8.java | 6 +- .../traub_ostrowski/TraubOstrowskiPoly.java | 6 +- .../TraubOstrowskiRootFindingMethod.java | 2 +- .../traub_ostrowski/TraubOstrowskiSin.java | 6 +- .../WeerakoonFernando3.java | 8 +- .../WeerakoonFernando4.java | 8 +- .../WeerakoonFernandoCos.java | 8 +- .../WeerakoonFernandoFormula.java | 7 +- .../WeerakoonFernandoGeneralized3.java | 8 +- .../WeerakoonFernandoGeneralized8.java | 8 +- .../WeerakoonFernandoPoly.java | 9 +- .../WeerakoonFernandoRootFindingMethod.java | 2 +- .../WeerakoonFernandoSin.java | 8 +- .../whittaker/Whittaker3.java | 8 +- .../whittaker/Whittaker4.java | 9 +- .../whittaker/WhittakerCos.java | 10 +- .../whittaker/WhittakerFormula.java | 7 +- .../whittaker/WhittakerGeneralized3.java | 9 +- .../whittaker/WhittakerGeneralized8.java | 9 +- .../whittaker/WhittakerPoly.java | 9 +- .../whittaker/WhittakerSin.java | 8 +- .../WhittakerDoubleConvex3.java | 8 +- .../WhittakerDoubleConvex4.java | 9 +- .../WhittakerDoubleConvexCos.java | 10 +- .../WhittakerDoubleConvexFormula.java | 7 +- .../WhittakerDoubleConvexGeneralized3.java | 9 +- .../WhittakerDoubleConvexGeneralized8.java | 9 +- .../WhittakerDoubleConvexPoly.java | 9 +- .../WhittakerDoubleConvexSin.java | 10 +- .../UserFormulaConditionalConverging.java | 11 +- .../user_formulas/UserFormulaConverging.java | 11 +- .../UserFormulaCoupledConverging.java | 11 +- .../UserFormulaIterationBasedConverging.java | 9 +- .../user_formulas/UserFormulaNova.java | 12 +- src/fractalzoomer/gui/CenterSizeDialog.java | 4 +- .../gui/CenterSizeJuliaDialog.java | 4 +- src/fractalzoomer/gui/ColorCyclingDialog.java | 94 +- src/fractalzoomer/gui/ColorDensityDialog.java | 6 +- .../gui/ColorIntensityDialog.java | 2 +- .../gui/ColorPaletteEditorPanel.java | 2 +- .../gui/ContourFactorDialog.java | 2 +- .../gui/ConvergentBailoutDialog.java | 118 + src/fractalzoomer/gui/CornersDialog.java | 8 +- .../gui/CustomPaletteEditorFrame.java | 188 +- src/fractalzoomer/gui/D3Dialog.java | 52 - .../gui/DomainColoringFrame.java | 1 + .../gui/DrawingAlgorithmsFrame.java | 154 +- src/fractalzoomer/gui/FileMenu.java | 2 +- .../gui/FractalFunctionsMenu.java | 6 + .../gui/HighPrecisionDialog.java | 6 + .../gui/HistogramColoringDialog.java | 20 +- .../gui/HueGeneratedPalettes.java | 2 +- src/fractalzoomer/gui/IterationDialog.java | 3 +- src/fractalzoomer/gui/JuliaSeedDialog.java | 4 +- .../gui/MagnificationDialog.java | 8 +- src/fractalzoomer/gui/MainPanel.java | 45 +- src/fractalzoomer/gui/OptionsMenu.java | 20 + src/fractalzoomer/gui/PeriodDialog.java | 3 +- .../gui/PerturbationTheoryDialog.java | 61 +- .../gui/PerturbationTheoryHelpDialog.java | 6 +- .../gui/PolarProjectionDialog.java | 4 +- src/fractalzoomer/gui/RotationDialog.java | 4 +- .../gui/SequenceRenderDialog.java | 202 +- src/fractalzoomer/gui/SplashFrame.java | 13 +- src/fractalzoomer/gui/ToolsOptionsMenu.java | 20 +- src/fractalzoomer/gui/VariablesDialog.java | 2 +- .../gui/ZoomingFactorDialog.java | 4 +- .../help/Fractal_Zoomer_Help.chm | Bin 367248 -> 368092 bytes .../icons/convergent_bailout.png | Bin 0 -> 5030 bytes src/fractalzoomer/icons/load_small.png | Bin 0 -> 4914 bytes src/fractalzoomer/main/CommonFunctions.java | 118 +- src/fractalzoomer/main/Constants.java | 11 +- .../main/ImageExpanderWindow.java | 675 ++- src/fractalzoomer/main/MainWindow.java | 1060 +++- .../ApproximationDefaultSettings.java | 9 +- .../app_settings/ColorCyclingSettings.java | 19 + .../main/app_settings/D3Settings.java | 7 - .../main/app_settings/FunctionSettings.java | 2 + .../HistogramColoringSettings.java | 2 + .../main/app_settings/Settings.java | 70 +- .../app_settings/ZoomSequenceSettings.java | 55 + .../native/linux-x86-64/libmpfr.so | Bin 1249072 -> 1249224 bytes src/fractalzoomer/native/linux-x86/libmpfr.so | Bin 1245784 -> 1245920 bytes .../native/win32-x86-64/libgmp-10.dll | Bin 1205573 -> 1205573 bytes .../native/win32-x86-64/libmpfr-6.dll | Bin 1845085 -> 1846759 bytes .../native/win32-x86-64/mpir_haswell_avx2.dll | Bin 577536 -> 580096 bytes .../mpir_sandybridge_ivybridge.dll | Bin 579072 -> 581632 bytes .../native/win32-x86-64/mpir_skylake_avx2.dll | Bin 582144 -> 584704 bytes .../native/win32-x86/libgmp-10.dll | Bin 999208 -> 999208 bytes .../native/win32-x86/libmpfr-6.dll | Bin 1624144 -> 1626332 bytes .../palettes/PaletteColorNormal.java | 6 +- .../palettes/PaletteColorSmooth.java | 68 +- src/fractalzoomer/palettes/PresetPalette.java | 4 +- .../AtanTransferFunction.java | 4 +- .../CbrtTransferFunction.java | 8 +- .../ForthrtTransferFunction.java | 8 +- .../LinearTransferFunction.java | 4 +- .../LogLogTransferFunction.java | 4 +- .../LogarithmTransferFunction.java | 5 +- .../SqrtTransferFunction.java | 8 +- .../transfer_functions/TransferFunction.java | 2 + .../planes/general/LambdaPlane.java | 2 +- .../settings/SettingsFractals1090.java | 54 + .../UserTrueColorAlgorithm.java | 2 +- src/fractalzoomer/utils/ImageRepainter.java | 58 - .../utils/JsonPalettesContainer.java | 25 +- src/fractalzoomer/utils/MathUtils.java | 2 +- src/fractalzoomer/utils/TaskStatistic.java | 10 +- test/Test.java | 2 +- test/TestBigNum.java | 72 - test/TestBigNum30.java | 242 + test/TestBigNum32.java | 223 + test/TestBigNum60.java | 158 + test/TestBigNum64.java | 222 + test/TestComplex.java | 2 +- test/TestDerivative.java | 1 + test/TestRootFindingMethodUniquenes.java | 1 + 662 files changed, 34018 insertions(+), 12659 deletions(-) create mode 100644 lib/big-math-2.3.2.jar create mode 100644 src/de/articdive/jnoise/core/api/annotations/Vector1D.java create mode 100644 src/de/articdive/jnoise/core/api/annotations/Vector2D.java create mode 100644 src/de/articdive/jnoise/core/api/annotations/Vector3D.java create mode 100644 src/de/articdive/jnoise/core/api/annotations/Vector4D.java delete mode 100644 src/de/articdive/jnoise/core/util/vectors/Vector.java delete mode 100644 src/de/articdive/jnoise/core/util/vectors/Vector1D.java delete mode 100644 src/de/articdive/jnoise/core/util/vectors/Vector2D.java delete mode 100644 src/de/articdive/jnoise/core/util/vectors/Vector3D.java delete mode 100644 src/de/articdive/jnoise/core/util/vectors/Vector4D.java create mode 100644 src/fractalzoomer/core/BigNum30.java create mode 100644 src/fractalzoomer/core/BigNum32.java create mode 100644 src/fractalzoomer/core/BigNum60.java create mode 100644 src/fractalzoomer/core/BigNum64.java create mode 100644 src/fractalzoomer/core/CompressedDeepReference.java create mode 100644 src/fractalzoomer/core/CompressedDoubleReference.java create mode 100644 src/fractalzoomer/core/ReferenceCompressor.java create mode 100644 src/fractalzoomer/core/ReferenceDecompressor.java create mode 100644 src/fractalzoomer/core/Waypoint.java create mode 100644 src/fractalzoomer/core/drawing_algorithms/BruteForceInterleavedDraw.java create mode 100644 src/fractalzoomer/core/drawing_algorithms/CircularSuccessiveRefinementGuessing2ColorsAndIterationDataDraw.java create mode 100644 src/fractalzoomer/core/drawing_algorithms/CircularSuccessiveRefinementGuessing2Draw.java create mode 100644 src/fractalzoomer/core/drawing_algorithms/MarianiSilver3ColorsAndIterationDataDraw.java create mode 100644 src/fractalzoomer/core/drawing_algorithms/MarianiSilver3Draw.java create mode 100644 src/fractalzoomer/core/drawing_algorithms/SuccessiveRefinementGuessing2ColorsAndIterationDataDraw.java create mode 100644 src/fractalzoomer/core/drawing_algorithms/SuccessiveRefinementGuessing2Draw.java delete mode 100644 src/fractalzoomer/core/unused/BigNum64.java create mode 100644 src/fractalzoomer/functions/formulas/m_like_generalization/c_azb_dze/Formula48.java create mode 100644 src/fractalzoomer/gui/ConvergentBailoutDialog.java create mode 100644 src/fractalzoomer/icons/convergent_bailout.png create mode 100644 src/fractalzoomer/icons/load_small.png create mode 100644 src/fractalzoomer/main/app_settings/ColorCyclingSettings.java create mode 100644 src/fractalzoomer/main/app_settings/ZoomSequenceSettings.java create mode 100644 src/fractalzoomer/settings/SettingsFractals1090.java delete mode 100644 src/fractalzoomer/utils/ImageRepainter.java delete mode 100644 test/TestBigNum.java create mode 100644 test/TestBigNum30.java create mode 100644 test/TestBigNum32.java create mode 100644 test/TestBigNum60.java create mode 100644 test/TestBigNum64.java diff --git a/Changelog.txt b/Changelog.txt index a69d84b4e..af093c435 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,3 +1,14 @@ +Version 1.0.9.0 + -Implemented Zhuoran's reference compression algorithm as a memory/speed tradeoff for locations with high memory requirement + -Optimized the custom BigNum implementation, which decreases the reference calculation time in shallow areas + -Optimized the mpfr/mpir reference calculations by reducing the number of JNA calls + -Implemented Zhuoran's multithreaded BLA table generation code. (It mostly affects areas with high iteration count, when using compression) + -Modified the drawing algorithms to include more tiling options + -Added convergent bailout as an option + -The zoom sequence renderer of Image Expander will now save the render settings and also the zoom factor on every step + -Added an aspect ratio option in zoom sequence renderer as a temporary workaround, until I implement non-square image format + -Bug Fixes and general improvements + Version 1.0.8.9 -Implemented a non-blocking (Only for the pixel calculation part) successive refinement method with pixel guessing -Optimized the pixel calculation for Mandelbrot by unwrapping some calculations diff --git a/README.txt b/README.txt index 5f21cf1e5..b6acbe746 100644 --- a/README.txt +++ b/README.txt @@ -1,4 +1,4 @@ -Fractal Zoomer 1.0.8.9 +Fractal Zoomer 1.0.9.0 The most complete fractal generating software using java! diff --git a/lib/big-math-2.3.2.jar b/lib/big-math-2.3.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..7b419cf5752f85bf7222144a7989f2c201823011 GIT binary patch literal 58140 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 R9SFpR{uzg$|Mng1{SW?j6^sA? literal 0 HcmV?d00001 diff --git a/src/de/articdive/jnoise/core/api/annotations/Vector1D.java b/src/de/articdive/jnoise/core/api/annotations/Vector1D.java new file mode 100644 index 000000000..a73260b0e --- /dev/null +++ b/src/de/articdive/jnoise/core/api/annotations/Vector1D.java @@ -0,0 +1,8 @@ +package de.articdive.jnoise.core.api.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface Vector1D { +} diff --git a/src/de/articdive/jnoise/core/api/annotations/Vector2D.java b/src/de/articdive/jnoise/core/api/annotations/Vector2D.java new file mode 100644 index 000000000..70291a86e --- /dev/null +++ b/src/de/articdive/jnoise/core/api/annotations/Vector2D.java @@ -0,0 +1,8 @@ +package de.articdive.jnoise.core.api.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface Vector2D { +} diff --git a/src/de/articdive/jnoise/core/api/annotations/Vector3D.java b/src/de/articdive/jnoise/core/api/annotations/Vector3D.java new file mode 100644 index 000000000..9bb647e47 --- /dev/null +++ b/src/de/articdive/jnoise/core/api/annotations/Vector3D.java @@ -0,0 +1,8 @@ +package de.articdive.jnoise.core.api.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface Vector3D { +} diff --git a/src/de/articdive/jnoise/core/api/annotations/Vector4D.java b/src/de/articdive/jnoise/core/api/annotations/Vector4D.java new file mode 100644 index 000000000..3a6f3bfb1 --- /dev/null +++ b/src/de/articdive/jnoise/core/api/annotations/Vector4D.java @@ -0,0 +1,8 @@ +package de.articdive.jnoise.core.api.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface Vector4D { +} diff --git a/src/de/articdive/jnoise/core/api/functions/Combiner.java b/src/de/articdive/jnoise/core/api/functions/Combiner.java index e90650999..df52b2911 100644 --- a/src/de/articdive/jnoise/core/api/functions/Combiner.java +++ b/src/de/articdive/jnoise/core/api/functions/Combiner.java @@ -1,54 +1,54 @@ -package de.articdive.jnoise.core.api.functions; - -import de.articdive.jnoise.core.util.MathUtil; - -/** - * Interface marking the implementing class as a function that combines to double values into 1 double value. - * As an example this is used to mark the minimization function in Worley Noise. - * - * @author Articdive - */ -@FunctionalInterface -public interface Combiner { - Combiner ADD = Double::sum; - Combiner MULTIPLY = (a, b) -> a * b; - Combiner MAX = Math::max; - Combiner MIN = Math::min; - Combiner POW = Math::pow; - - Combiner EXPONENTIAL_SMOOTH_MIN = (a, b) -> { - double res = MathUtil.exp2(-32.0 * a) + MathUtil.exp2(-32.0 * b); - return -MathUtil.log2(res) / 32.0; - }; - Combiner POWER_SMOOTH_MIN = (a, b) -> { - a = Math.pow(a, 8); - b = Math.pow(b, 8); - return Math.pow((a * b) / (a + b), 1.0 / 8); - }; - Combiner POLYNOMIAL_SMOOTH_MIN = (a, b) -> { - double h = Math.max(0.1 - Math.abs(a - b), 0.0) / 0.1; - return Math.min(a, b) - h * h * 0.1 * (1.0 / 4.0); - }; - - /** - * Combines two double values into one double value. - * - * @param a first double. - * @param b second double. - * @return the resulting double. - * @deprecated Use {@link #applyTo(double, double)} - makes more sense with conventions. - */ - @Deprecated - default double combine(double a, double b) { - return applyTo(a, b); - } - - /** - * Combines two double values into one double value. - * - * @param a first double. - * @param b second double. - * @return the resulting double. - */ - double applyTo(double a, double b); +package de.articdive.jnoise.core.api.functions; + +import de.articdive.jnoise.core.util.MathUtil; + +/** + * Interface marking the implementing class as a function that combines to double values into 1 double value. + * As an example this is used to mark the minimization function in Worley Noise. + * + * @author Articdive + */ +@FunctionalInterface +public interface Combiner { + Combiner ADD = Double::sum; + Combiner MULTIPLY = (a, b) -> a * b; + Combiner MAX = Math::max; + Combiner MIN = Math::min; + Combiner POW = Math::pow; + + Combiner EXPONENTIAL_SMOOTH_MIN = (a, b) -> { + double res = MathUtil.exp2(-32.0 * a) + MathUtil.exp2(-32.0 * b); + return -MathUtil.log2(res) / 32.0; + }; + Combiner POWER_SMOOTH_MIN = (a, b) -> { + a = Math.pow(a, 8); + b = Math.pow(b, 8); + return Math.pow((a * b) / (a + b), 1.0 / 8); + }; + Combiner POLYNOMIAL_SMOOTH_MIN = (a, b) -> { + double h = Math.max(0.1 - Math.abs(a - b), 0.0) / 0.1; + return Math.min(a, b) - h * h * 0.1 * (1.0 / 4.0); + }; + + /** + * Combines two double values into one double value. + * + * @param a first double. + * @param b second double. + * @return the resulting double. + * @deprecated Use {@link #applyTo(double, double)} - makes more sense with conventions. + */ + @Deprecated + default double combine(double a, double b) { + return applyTo(a, b); + } + + /** + * Combines two double values into one double value. + * + * @param a first double. + * @param b second double. + * @return the resulting double. + */ + double applyTo(double a, double b); } \ No newline at end of file diff --git a/src/de/articdive/jnoise/core/api/noisegen/NoiseResult.java b/src/de/articdive/jnoise/core/api/noisegen/NoiseResult.java index 3bd74ae47..886abd8e4 100644 --- a/src/de/articdive/jnoise/core/api/noisegen/NoiseResult.java +++ b/src/de/articdive/jnoise/core/api/noisegen/NoiseResult.java @@ -1,10 +1,8 @@ package de.articdive.jnoise.core.api.noisegen; -import de.articdive.jnoise.core.util.vectors.Vector; - /** * Interface that denotes a noise result, which is used to wrap the results of an entire noise generation step. - * Useful when there are multiple result types, i.e. not only a double but e.g. a {@link Vector}. + * Useful when there are multiple result types, i.e. not only a double but e.g. a vector. * * @author Articdive */ diff --git a/src/de/articdive/jnoise/core/api/noisegen/SeededExplicitNoiseGenerator.java b/src/de/articdive/jnoise/core/api/noisegen/SeededExplicitNoiseGenerator.java index 8bb28917c..80f780757 100644 --- a/src/de/articdive/jnoise/core/api/noisegen/SeededExplicitNoiseGenerator.java +++ b/src/de/articdive/jnoise/core/api/noisegen/SeededExplicitNoiseGenerator.java @@ -1,7 +1,6 @@ package de.articdive.jnoise.core.api.noisegen; - /** * Interface that denotes a {@link SeededNoiseGenerator}, which can additionally evaluate a {@link NoiseResult} at a location. * @@ -16,7 +15,6 @@ public interface SeededExplicitNoiseGenerator extends Ex * @param seed seed for the {@link SeededNoiseGenerator} to use. * @return {@link NR} denoting the noise value at the 1D point. */ - NR evaluateNoiseResult(double x, long seed); /** @@ -27,7 +25,6 @@ public interface SeededExplicitNoiseGenerator extends Ex * @param seed seed for the {@link SeededNoiseGenerator} to use. * @return {@link NR} denoting the noise value at the 2D point. */ - NR evaluateNoiseResult(double x, double y, long seed); /** @@ -39,7 +36,6 @@ public interface SeededExplicitNoiseGenerator extends Ex * @param seed seed for the {@link SeededNoiseGenerator} to use. * @return {@link NR} denoting the noise value at the 3D point. */ - NR evaluateNoiseResult(double x, double y, double z, long seed); /** @@ -52,6 +48,5 @@ public interface SeededExplicitNoiseGenerator extends Ex * @param seed seed for the {@link SeededNoiseGenerator} to use. * @return {@link NR} denoting the noise value at the 4D point. */ - NR evaluateNoiseResult(double x, double y, double z, double w, long seed); } diff --git a/src/de/articdive/jnoise/core/api/pipeline/ExplicitNoiseSource.java b/src/de/articdive/jnoise/core/api/pipeline/ExplicitNoiseSource.java index 3ccee543d..147c9c05f 100644 --- a/src/de/articdive/jnoise/core/api/pipeline/ExplicitNoiseSource.java +++ b/src/de/articdive/jnoise/core/api/pipeline/ExplicitNoiseSource.java @@ -2,7 +2,6 @@ import de.articdive.jnoise.core.api.noisegen.NoiseResult; - /** * Interface that denotes an explicit {@link NoiseSource}, which can evaluate a {@link NoiseResult} at a location. * Used everywhere where a {@link NoiseSource} has a non-double as a result. @@ -16,7 +15,6 @@ public interface ExplicitNoiseSource extends NoiseSource * @param x X-Coordinate of the 1D point. * @return {@link NR} denoting the noise value at the 1D point. */ - NR evaluateNoiseResult(double x); /** @@ -26,7 +24,6 @@ public interface ExplicitNoiseSource extends NoiseSource * @param y Y-Coordinate of the 2D point. * @return {@link NR} denoting the noise value at the 2D point. */ - NR evaluateNoiseResult(double x, double y); /** @@ -37,7 +34,6 @@ public interface ExplicitNoiseSource extends NoiseSource * @param z Z-Coordinate of the 3D point. * @return {@link NR} denoting the noise value at the 3D point. */ - NR evaluateNoiseResult(double x, double y, double z); /** @@ -49,6 +45,5 @@ public interface ExplicitNoiseSource extends NoiseSource * @param w W-Coordinate of the 4D point. * @return {@link NR} denoting the noise value at the 4D point. */ - NR evaluateNoiseResult(double x, double y, double z, double w); } diff --git a/src/de/articdive/jnoise/core/api/transformers/DetailedTransformer.java b/src/de/articdive/jnoise/core/api/transformers/DetailedTransformer.java index 349e2e394..42c2b5173 100644 --- a/src/de/articdive/jnoise/core/api/transformers/DetailedTransformer.java +++ b/src/de/articdive/jnoise/core/api/transformers/DetailedTransformer.java @@ -1,9 +1,9 @@ package de.articdive.jnoise.core.api.transformers; -import de.articdive.jnoise.core.util.vectors.Vector2D; -import de.articdive.jnoise.core.util.vectors.Vector3D; -import de.articdive.jnoise.core.util.vectors.Vector4D; - +import de.articdive.jnoise.core.api.annotations.Vector1D; +import de.articdive.jnoise.core.api.annotations.Vector2D; +import de.articdive.jnoise.core.api.annotations.Vector3D; +import de.articdive.jnoise.core.api.annotations.Vector4D; /** * Interface that denotes a detailed transformer, which is used to transform coordinate tuples parts before the noise generation step. @@ -13,40 +13,30 @@ */ public interface DetailedTransformer { /** - * Transforms an x coordinate before noise evaluation. + * Transforms an x coordinate before noise evaluation via a side-effect. * - * @param x coordinate to transform. - * @return transformed x coordinate. + * @param vec1D a double array representing a 1D vector containing the x coordinate to transform. */ - double transform(double x); + void transform1D(@Vector1D double[] vec1D); /** - * Transforms an x and y coordinate before noise evaluation. + * Transforms an x and y coordinate before noise evaluation via a side-effect. * - * @param x X coordinate to transform. - * @param y Y coordinate to transform. - * @return {@link Vector2D} containing the transformed x and y coordinates. + * @param vec2D a double array representing a 2D vector containing the x and y coordinate to transform. */ - Vector2D transform(double x, double y); + void transform2D(@Vector2D double[] vec2D); /** - * Transforms an x, y and z coordinate before noise evaluation. + * Transforms an x, y and z coordinate before noise evaluation via a side-effect. * - * @param x X coordinate to transform. - * @param y Y coordinate to transform. - * @param z Z coordinate to transform. - * @return {@link Vector3D} containing the transformed x, y and z coordinates. + * @param vec3D a double array representing a 3D vector containing the x, y and z coordinate to transform. */ - Vector3D transform(double x, double y, double z); + void transform3D(@Vector3D double[] vec3D); /** - * Transforms an x, y, z and w coordinate before noise evaluation. + * Transforms an x, y, z and w coordinate before noise evaluation via a side-effect. * - * @param x X coordinate to transform. - * @param y Y coordinate to transform. - * @param z Z coordinate to transform. - * @param w W coordinate to transform. - * @return {@link Vector4D} containing the transformed x, y, z and w coordinates. + * @param vec4D a double array representing a 4D vector containing the x, y, z and w coordinate to transform. */ - Vector4D transform(double x, double y, double z, double w); + void transform4D(@Vector4D double[] vec4D); } diff --git a/src/de/articdive/jnoise/core/util/MathUtil.java b/src/de/articdive/jnoise/core/util/MathUtil.java index 334d747d5..ffb563386 100644 --- a/src/de/articdive/jnoise/core/util/MathUtil.java +++ b/src/de/articdive/jnoise/core/util/MathUtil.java @@ -1,5 +1,9 @@ package de.articdive.jnoise.core.util; +import de.articdive.jnoise.core.api.annotations.Vector2D; +import de.articdive.jnoise.core.api.annotations.Vector3D; +import de.articdive.jnoise.core.api.annotations.Vector4D; + /** * Utility class for mathematical functions. * @@ -29,4 +33,37 @@ public static double exp2(double x) { public static double log2(double x) { return Math.log(x) / Math.log(2); } + + /** + * Calculates the dot product of the specified 2D vectors. + * + * @param a a double array representing a 2D vector. + * @param b a double array representing a 2D vector. + * @return the dot product of the two 2D vectors. + */ + public static double dot2D(@Vector2D double[] a, @Vector2D double[] b) { + return (a[0] * b[0]) + (a[1] * b[1]); + } + + /** + * Calculates the dot product of the specified 3D vectors. + * + * @param a a double array representing a 3D vector. + * @param b a double array representing a 3D vector. + * @return the dot product of the two 3D vectors. + */ + public static double dot3D(@Vector3D double[] a, @Vector3D double[] b) { + return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]); + } + + /** + * Calculates the dot product of the specified 4D vectors. + * + * @param a a double array representing a 4D vector. + * @param b a double array representing a 4D vector. + * @return the dot product of the two 4D vectors. + */ + public static double dot4D(@Vector4D double[] a, @Vector4D double[] b) { + return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]) + (a[3] * b[3]); + } } diff --git a/src/de/articdive/jnoise/core/util/vectors/Vector.java b/src/de/articdive/jnoise/core/util/vectors/Vector.java deleted file mode 100644 index 2ef97d6ce..000000000 --- a/src/de/articdive/jnoise/core/util/vectors/Vector.java +++ /dev/null @@ -1,45 +0,0 @@ -package de.articdive.jnoise.core.util.vectors; - -/** - * Interface that denotes a mathematical vector. - * - * @author Articdive - */ -public interface Vector { - /** - * Gets the length of the Vector on the X axis. - * - * @return X component of the {@link Vector}. - */ - double x(); - - /** - * Gets the length of the Vector on the Y axis. - * - * @return Y component of the {@link Vector}. - * @throws UnsupportedOperationException if the Vector does not have a Y component. - */ - default double y() { - throw new UnsupportedOperationException("This vector does not have a Y component."); - } - - /** - * Gets the length of the Vector on the Z axis. - * - * @return Z component of the {@link Vector}. - * @throws UnsupportedOperationException if the Vector does not have a Z component. - */ - default double z() { - throw new UnsupportedOperationException("This vector does not have a Z component."); - } - - /** - * Gets the length of the Vector on the W axis. - * - * @return W component of the {@link Vector}. - * @throws UnsupportedOperationException if the Vector does not have a W component. - */ - default double w() { - throw new UnsupportedOperationException("This vector does not have a W component."); - } -} diff --git a/src/de/articdive/jnoise/core/util/vectors/Vector1D.java b/src/de/articdive/jnoise/core/util/vectors/Vector1D.java deleted file mode 100644 index fc6878011..000000000 --- a/src/de/articdive/jnoise/core/util/vectors/Vector1D.java +++ /dev/null @@ -1,31 +0,0 @@ -package de.articdive.jnoise.core.util.vectors; - - -/** - * Record that denotes a mathematical 1D vector with an X component. - * - * @author Articdive - */ -public class Vector1D implements Vector { - - private double x; - - public Vector1D(double x) { - this.x = x; - } - - /** - * Calculates the dot product of this vector with another 1D vector. - * - * @param vector1D {@link Vector1D} other vector to calculate the dot product with. - * @return the dot product of the two vectors. - */ - public double dot(Vector1D vector1D) { - return (x * vector1D.x); - } - - @Override - public double x() { - return x; - } -} diff --git a/src/de/articdive/jnoise/core/util/vectors/Vector2D.java b/src/de/articdive/jnoise/core/util/vectors/Vector2D.java deleted file mode 100644 index dd36fe330..000000000 --- a/src/de/articdive/jnoise/core/util/vectors/Vector2D.java +++ /dev/null @@ -1,39 +0,0 @@ -package de.articdive.jnoise.core.util.vectors; - - - -/** - * Record that denotes a mathematical 2D vector with an X and Y component. - * - * @author Articdive - */ -public class Vector2D implements Vector { - private double x; - private double y; - - public Vector2D(double x, double y) { - this.x = x; - this.y = y; - } - - - /** - * Calculates the dot product of this vector with another 2D vector. - * - * @param vector2D {@link Vector2D} other vector to calculate the dot product with. - * @return the dot product of the two vectors. - */ - public double dot( Vector2D vector2D) { - return (x * vector2D.x) + (y * vector2D.y); - } - - @Override - public double x() { - return x; - } - - @Override - public double y() { - return y; - } -} \ No newline at end of file diff --git a/src/de/articdive/jnoise/core/util/vectors/Vector3D.java b/src/de/articdive/jnoise/core/util/vectors/Vector3D.java deleted file mode 100644 index c82dced7d..000000000 --- a/src/de/articdive/jnoise/core/util/vectors/Vector3D.java +++ /dev/null @@ -1,46 +0,0 @@ -package de.articdive.jnoise.core.util.vectors; - - - -/** - * Record that denotes a mathematical 3D vector with an X, Y and Z component. - * - * @author Articdive - */ -public class Vector3D implements Vector { - - private double x; - private double y; - private double z; - - public Vector3D(double x, double y, double z) { - this.x = x; - this.y = y; - this.z = z; - } - - /** - * Calculates the dot product of this vector with another 3D vector. - * - * @param vector3D {@link Vector3D} other vector to calculate the dot product with. - * @return the dot product of the two vectors. - */ - public double dot( Vector3D vector3D) { - return (x * vector3D.x) + (y * vector3D.y) + (z * vector3D.z); - } - - @Override - public double x() { - return x; - } - - @Override - public double y() { - return y; - } - - @Override - public double z() { - return z; - } -} \ No newline at end of file diff --git a/src/de/articdive/jnoise/core/util/vectors/Vector4D.java b/src/de/articdive/jnoise/core/util/vectors/Vector4D.java deleted file mode 100644 index 2ef0b931a..000000000 --- a/src/de/articdive/jnoise/core/util/vectors/Vector4D.java +++ /dev/null @@ -1,52 +0,0 @@ -package de.articdive.jnoise.core.util.vectors; - - - -/** - * Record that denotes a mathematical 4D vector with an X, Y, Z and W component. - * - * @author Articdive - */ -public class Vector4D implements Vector { - private double x; - private double y; - private double z; - private double w; - - public Vector4D(double x, double y, double z, double w) { - this.x = x; - this.y = y; - this.z = z; - this.w = w; - } - - /** - * Calculates the dot product of this vector with another 4D vector. - * - * @param vector4D {@link Vector4D} other vector to calculate the dot product with. - * @return the dot product of the two vectors. - */ - public double dot( Vector4D vector4D) { - return (x * vector4D.x) + (y * vector4D.y) + (z * vector4D.z) + (w * vector4D.w); - } - - @Override - public double x() { - return x; - } - - @Override - public double y() { - return y; - } - - @Override - public double z() { - return z; - } - - @Override - public double w() { - return w; - } -} \ No newline at end of file diff --git a/src/de/articdive/jnoise/generators/noise_parameters/interpolation/Interpolation.java b/src/de/articdive/jnoise/generators/noise_parameters/interpolation/Interpolation.java index d3bb75d04..6e7197023 100644 --- a/src/de/articdive/jnoise/generators/noise_parameters/interpolation/Interpolation.java +++ b/src/de/articdive/jnoise/generators/noise_parameters/interpolation/Interpolation.java @@ -1,11 +1,11 @@ -package de.articdive.jnoise.generators.noise_parameters.interpolation; - -/** - * @author Articdive - * @deprecated Moved to {@link de.articdive.jnoise.core.api.functions.Interpolation} - * - */ -@Deprecated -@FunctionalInterface -public interface Interpolation extends de.articdive.jnoise.core.api.functions.Interpolation { -} +package de.articdive.jnoise.generators.noise_parameters.interpolation; + +/** + * @author Articdive + * @deprecated Moved to {@link de.articdive.jnoise.core.api.functions.Interpolation} + * + */ +@Deprecated +@FunctionalInterface +public interface Interpolation extends de.articdive.jnoise.core.api.functions.Interpolation { +} diff --git a/src/de/articdive/jnoise/generators/noisegen/opensimplex/FastSimplexNoiseGenerator.java b/src/de/articdive/jnoise/generators/noisegen/opensimplex/FastSimplexNoiseGenerator.java index 0169d7d3b..857bad3f5 100644 --- a/src/de/articdive/jnoise/generators/noisegen/opensimplex/FastSimplexNoiseGenerator.java +++ b/src/de/articdive/jnoise/generators/noisegen/opensimplex/FastSimplexNoiseGenerator.java @@ -1,182 +1,166 @@ -package de.articdive.jnoise.generators.noisegen.opensimplex; - -import de.articdive.jnoise.core.api.noisegen.SeededNoiseGenerator; -import de.articdive.jnoise.core.api.pipeline.NoiseSourceBuilder; -import de.articdive.jnoise.generators.noise_parameters.simplex_variants.Simplex2DVariant; -import de.articdive.jnoise.generators.noise_parameters.simplex_variants.Simplex3DVariant; -import de.articdive.jnoise.generators.noise_parameters.simplex_variants.Simplex4DVariant; - - -/** - * Uses KdotJPG's the fast variant of OpenSimplex2 Noise located at https://github.com/KdotJPG/OpenSimplex2. - * The bounds of FastOpenSimplex2 Noise are: [-1, 1]. - * - * @author Articdive - */ -public final class FastSimplexNoiseGenerator implements SeededNoiseGenerator { - private final long seed; - private final Simplex2DVariant variant2D; - private final Simplex3DVariant variant3D; - private final Simplex4DVariant variant4D; - - private FastSimplexNoiseGenerator( - long seed, - Simplex2DVariant variant2D, - Simplex3DVariant variant3D, - Simplex4DVariant variant4D - ) { - this.seed = seed; - this.variant2D = variant2D; - this.variant3D = variant3D; - this.variant4D = variant4D; - } - - @Override - public double evaluateNoise(double x, long seed) { - return OpenSimplex2F.noise2(seed, x, 1.0); - } - - @Override - public double evaluateNoise(double x, double y, long seed) { - switch (variant2D) { - case IMPROVE_X: return OpenSimplex2F.noise2_ImproveX(seed, x, y); - case CLASSIC: return OpenSimplex2F.noise2(seed, x, y); - }; - return 0; - } - - @Override - public double evaluateNoise(double x, double y, double z, long seed) { - switch (variant3D) { - case IMPROVE_XY: return OpenSimplex2F.noise3_ImproveXY(seed, x, y, z); - case IMPROVE_XZ: return OpenSimplex2F.noise3_ImproveXZ(seed, x, y, z); - case CLASSIC: return OpenSimplex2F.noise3_Fallback(seed, x, y, z); - }; - return 0 ; - } - - @Override - public double evaluateNoise(double x, double y, double z, double w, long seed) { - switch (variant4D) { - case IMPROVE_XY_IMPROVE_ZW: return OpenSimplex2F.noise4_ImproveXY_ImproveZW(seed, x, y, z, w); - case IMPROVE_XYZ_IMPROVE_XZ: return OpenSimplex2F.noise4_ImproveXYZ_ImproveXZ(seed, x, y, z, w); - case IMPROVE_XYZ_IMPROVE_XY: return OpenSimplex2F.noise4_ImproveXYZ_ImproveXY(seed, x, y, z, w); - case IMRPOVE_XYZ: return OpenSimplex2F.noise4_ImproveXYZ(seed, x, y, z, w); - case CLASSIC: return OpenSimplex2F.noise4_Fallback(seed, x, y, z, w); - }; - return 0; - } - - @Override - public double evaluateNoise(double x) { - return evaluateNoise(x, seed); - } - - @Override - public double evaluateNoise(double x, double y) { - return evaluateNoise(x, y, seed); - - } - - @Override - public double evaluateNoise(double x, double y, double z) { - return evaluateNoise(x, y, z, seed); - } - - @Override - public double evaluateNoise(double x, double y, double z, double w) { - return evaluateNoise(x, y, z, w, seed); - } - - @Override - public long getSeed() { - return seed; - } - - /** - * Gets a {@link FastSimplexNoiseBuilder} to build a {@link FastSimplexNoiseGenerator}. - * - * @return {@link FastSimplexNoiseBuilder}. - */ - - public static FastSimplexNoiseBuilder newBuilder() { - return new FastSimplexNoiseBuilder(); - } - - /** - * Builder for the {@link FastSimplexNoiseGenerator}. - */ - public static final class FastSimplexNoiseBuilder implements NoiseSourceBuilder { - private long seed = 1729; - private Simplex2DVariant variant2D = Simplex2DVariant.CLASSIC; - private Simplex3DVariant variant3D = Simplex3DVariant.CLASSIC; - private Simplex4DVariant variant4D = Simplex4DVariant.CLASSIC; - - private FastSimplexNoiseBuilder() { - - } - - /** - * Sets the seed for the {@link FastSimplexNoiseGenerator}. - * - * @param seed the new seed for the {@link FastSimplexNoiseGenerator}. - * @return {@link FastSimplexNoiseBuilder} this - */ - - public FastSimplexNoiseBuilder setSeed(long seed) { - this.seed = seed; - return this; - } - - /** - * Sets the variant used for 2D OpenSimplex noise - * - * @param variant2D the new {@link Simplex2DVariant} for the {@link FastSimplexNoiseGenerator}. - * @return {@link FastSimplexNoiseBuilder} this - */ - - public FastSimplexNoiseBuilder setVariant2D(Simplex2DVariant variant2D) { - if (variant2D == null) { - throw new IllegalArgumentException("Simplex 2D Variant cannot be null."); - } - this.variant2D = variant2D; - return this; - } - - /** - * Sets the variant used for 3D OpenSimplex noise - * - * @param variant3D the new {@link Simplex3DVariant} for the {@link FastSimplexNoiseGenerator}. - * @return {@link FastSimplexNoiseBuilder} this - */ - - public FastSimplexNoiseBuilder setVariant3D(Simplex3DVariant variant3D) { - if (variant3D == null) { - throw new IllegalArgumentException("Simplex 3D Variant cannot be null."); - } - this.variant3D = variant3D; - return this; - } - - /** - * Sets the variant used for 4D OpenSimplex noise - * - * @param variant4D the new {@link Simplex4DVariant} for the {@link FastSimplexNoiseGenerator}. - * @return {@link FastSimplexNoiseBuilder} this - */ - - public FastSimplexNoiseBuilder setVariant4D(Simplex4DVariant variant4D) { - if (variant4D == null) { - throw new IllegalArgumentException("Simplex 4D Variant cannot be null."); - } - this.variant4D = variant4D; - return this; - } - - @Override - - public FastSimplexNoiseGenerator build() { - return new FastSimplexNoiseGenerator(seed, variant2D, variant3D, variant4D); - } - } -} +package de.articdive.jnoise.generators.noisegen.opensimplex; + +import de.articdive.jnoise.core.api.noisegen.SeededNoiseGenerator; +import de.articdive.jnoise.core.api.pipeline.NoiseSourceBuilder; +import de.articdive.jnoise.generators.noise_parameters.simplex_variants.Simplex2DVariant; +import de.articdive.jnoise.generators.noise_parameters.simplex_variants.Simplex3DVariant; +import de.articdive.jnoise.generators.noise_parameters.simplex_variants.Simplex4DVariant; + +/** + * Uses KdotJPG's the fast variant of OpenSimplex2 Noise located at https://github.com/KdotJPG/OpenSimplex2. + * The bounds of FastOpenSimplex2 Noise are: [-1, 1]. + * + * @author Articdive + */ +public final class FastSimplexNoiseGenerator implements SeededNoiseGenerator { + private final long seed; + private final Simplex2DVariant variant2D; + private final Simplex3DVariant variant3D; + private final Simplex4DVariant variant4D; + + private FastSimplexNoiseGenerator( + long seed, + Simplex2DVariant variant2D, + Simplex3DVariant variant3D, + Simplex4DVariant variant4D + ) { + this.seed = seed; + this.variant2D = variant2D; + this.variant3D = variant3D; + this.variant4D = variant4D; + } + + @Override + public double evaluateNoise(double x, long seed) { + return OpenSimplex2F.noise2(seed, x, 1.0); + } + + @Override + public double evaluateNoise(double x, double y, long seed) { + switch (variant2D) { + case IMPROVE_X: return OpenSimplex2F.noise2_ImproveX(seed, x, y); + case CLASSIC: return OpenSimplex2F.noise2(seed, x, y); + } + return 0; + } + + @Override + public double evaluateNoise(double x, double y, double z, long seed) { + switch (variant3D) { + case IMPROVE_XY: return OpenSimplex2F.noise3_ImproveXY(seed, x, y, z); + case IMPROVE_XZ: return OpenSimplex2F.noise3_ImproveXZ(seed, x, y, z); + case CLASSIC: return OpenSimplex2F.noise3_Fallback(seed, x, y, z); + } + return 0; + } + + @Override + public double evaluateNoise(double x, double y, double z, double w, long seed) { + switch (variant4D) { + case IMPROVE_XY_IMPROVE_ZW: return OpenSimplex2F.noise4_ImproveXY_ImproveZW(seed, x, y, z, w); + case IMPROVE_XYZ_IMPROVE_XZ: return OpenSimplex2F.noise4_ImproveXYZ_ImproveXZ(seed, x, y, z, w); + case IMPROVE_XYZ_IMPROVE_XY: return OpenSimplex2F.noise4_ImproveXYZ_ImproveXY(seed, x, y, z, w); + case IMRPOVE_XYZ: return OpenSimplex2F.noise4_ImproveXYZ(seed, x, y, z, w); + case CLASSIC: return OpenSimplex2F.noise4_Fallback(seed, x, y, z, w); + } + return 0; + } + + @Override + public double evaluateNoise(double x) { + return evaluateNoise(x, seed); + } + + @Override + public double evaluateNoise(double x, double y) { + return evaluateNoise(x, y, seed); + + } + + @Override + public double evaluateNoise(double x, double y, double z) { + return evaluateNoise(x, y, z, seed); + } + + @Override + public double evaluateNoise(double x, double y, double z, double w) { + return evaluateNoise(x, y, z, w, seed); + } + + @Override + public long getSeed() { + return seed; + } + + /** + * Gets a {@link FastSimplexNoiseBuilder} to build a {@link FastSimplexNoiseGenerator}. + * + * @return {@link FastSimplexNoiseBuilder}. + */ + public static FastSimplexNoiseBuilder newBuilder() { + return new FastSimplexNoiseBuilder(); + } + + /** + * Builder for the {@link FastSimplexNoiseGenerator}. + */ + public static final class FastSimplexNoiseBuilder implements NoiseSourceBuilder { + private long seed = 1729; + private Simplex2DVariant variant2D = Simplex2DVariant.CLASSIC; + private Simplex3DVariant variant3D = Simplex3DVariant.CLASSIC; + private Simplex4DVariant variant4D = Simplex4DVariant.CLASSIC; + + private FastSimplexNoiseBuilder() { + + } + + /** + * Sets the seed for the {@link FastSimplexNoiseGenerator}. + * + * @param seed the new seed for the {@link FastSimplexNoiseGenerator}. + * @return {@link FastSimplexNoiseBuilder} this + */ + public FastSimplexNoiseBuilder setSeed(long seed) { + this.seed = seed; + return this; + } + + /** + * Sets the variant used for 2D OpenSimplex noise + * + * @param variant2D the new {@link Simplex2DVariant} for the {@link FastSimplexNoiseGenerator}. + * @return {@link FastSimplexNoiseBuilder} this + */ + public FastSimplexNoiseBuilder setVariant2D(Simplex2DVariant variant2D) { + this.variant2D = variant2D; + return this; + } + + /** + * Sets the variant used for 3D OpenSimplex noise + * + * @param variant3D the new {@link Simplex3DVariant} for the {@link FastSimplexNoiseGenerator}. + * @return {@link FastSimplexNoiseBuilder} this + */ + public FastSimplexNoiseBuilder setVariant3D(Simplex3DVariant variant3D) { + this.variant3D = variant3D; + return this; + } + + /** + * Sets the variant used for 4D OpenSimplex noise + * + * @param variant4D the new {@link Simplex4DVariant} for the {@link FastSimplexNoiseGenerator}. + * @return {@link FastSimplexNoiseBuilder} this + */ + public FastSimplexNoiseBuilder setVariant4D(Simplex4DVariant variant4D) { + this.variant4D = variant4D; + return this; + } + + @Override + public FastSimplexNoiseGenerator build() { + return new FastSimplexNoiseGenerator(seed, variant2D, variant3D, variant4D); + } + } +} diff --git a/src/de/articdive/jnoise/generators/noisegen/opensimplex/SuperSimplexNoiseGenerator.java b/src/de/articdive/jnoise/generators/noisegen/opensimplex/SuperSimplexNoiseGenerator.java index f26d47c49..f16bd976a 100644 --- a/src/de/articdive/jnoise/generators/noisegen/opensimplex/SuperSimplexNoiseGenerator.java +++ b/src/de/articdive/jnoise/generators/noisegen/opensimplex/SuperSimplexNoiseGenerator.java @@ -1,182 +1,166 @@ -package de.articdive.jnoise.generators.noisegen.opensimplex; - -import de.articdive.jnoise.core.api.noisegen.SeededNoiseGenerator; -import de.articdive.jnoise.core.api.pipeline.NoiseSourceBuilder; -import de.articdive.jnoise.generators.noise_parameters.simplex_variants.Simplex2DVariant; -import de.articdive.jnoise.generators.noise_parameters.simplex_variants.Simplex3DVariant; -import de.articdive.jnoise.generators.noise_parameters.simplex_variants.Simplex4DVariant; - - -/** - * Uses KdotJPG's the super variant of OpenSimplex2 Noise located at https://github.com/KdotJPG/OpenSimplex2. - * The bounds of SuperOpenSimplex2 Noise are: [-1, 1]. - * - * @author Articdive - */ -public final class SuperSimplexNoiseGenerator implements SeededNoiseGenerator { - private final long seed; - private final Simplex2DVariant variant2D; - private final Simplex3DVariant variant3D; - private final Simplex4DVariant variant4D; - - private SuperSimplexNoiseGenerator( - long seed, - Simplex2DVariant variant2D, - Simplex3DVariant variant3D, - Simplex4DVariant variant4D - ) { - this.seed = seed; - this.variant2D = variant2D; - this.variant3D = variant3D; - this.variant4D = variant4D; - } - - @Override - public double evaluateNoise(double x, long seed) { - return OpenSimplex2S.noise2(seed, x, 1.0); - } - - @Override - public double evaluateNoise(double x, double y, long seed) { - switch (variant2D) { - case IMPROVE_X: return OpenSimplex2S.noise2_ImproveX(seed, x, y); - case CLASSIC: return OpenSimplex2S.noise2(seed, x, y); - }; - return 0; - } - - @Override - public double evaluateNoise(double x, double y, double z, long seed) { - switch (variant3D) { - case IMPROVE_XY: return OpenSimplex2S.noise3_ImproveXY(seed, x, y, z); - case IMPROVE_XZ: return OpenSimplex2S.noise3_ImproveXZ(seed, x, y, z); - case CLASSIC: return OpenSimplex2S.noise3_Fallback(seed, x, y, z); - }; - return 0 ; - } - - @Override - public double evaluateNoise(double x, double y, double z, double w, long seed) { - switch (variant4D) { - case IMPROVE_XY_IMPROVE_ZW: return OpenSimplex2S.noise4_ImproveXY_ImproveZW(seed, x, y, z, w); - case IMPROVE_XYZ_IMPROVE_XY: return OpenSimplex2S.noise4_ImproveXYZ_ImproveXY(seed, x, y, z, w); - case IMPROVE_XYZ_IMPROVE_XZ: return OpenSimplex2S.noise4_ImproveXYZ_ImproveXZ(seed, x, y, z, w); - case IMRPOVE_XYZ: return OpenSimplex2S.noise4_ImproveXYZ(seed, x, y, z, w); - case CLASSIC: return OpenSimplex2S.noise4_Fallback(seed, x, y, z, w); - }; - return 0; - } - - @Override - public double evaluateNoise(double x) { - return evaluateNoise(x, seed); - } - - @Override - public double evaluateNoise(double x, double y) { - return evaluateNoise(x, y, seed); - - } - - @Override - public double evaluateNoise(double x, double y, double z) { - return evaluateNoise(x, y, z, seed); - } - - @Override - public double evaluateNoise(double x, double y, double z, double w) { - return evaluateNoise(x, y, z, w, seed); - } - - @Override - public long getSeed() { - return seed; - } - - /** - * Gets a {@link SuperSimplexNoiseBuilder} to build a {@link SuperSimplexNoiseGenerator}. - * - * @return {@link SuperSimplexNoiseBuilder}. - */ - - public static SuperSimplexNoiseBuilder newBuilder() { - return new SuperSimplexNoiseBuilder(); - } - - /** - * Builder for the {@link SuperSimplexNoiseGenerator}. - */ - public static final class SuperSimplexNoiseBuilder implements NoiseSourceBuilder { - private long seed = 1729; - private Simplex2DVariant variant2D = Simplex2DVariant.CLASSIC; - private Simplex3DVariant variant3D = Simplex3DVariant.CLASSIC; - private Simplex4DVariant variant4D = Simplex4DVariant.CLASSIC; - - private SuperSimplexNoiseBuilder() { - - } - - /** - * Sets the seed for the {@link SuperSimplexNoiseGenerator}. - * - * @param seed the new seed for the {@link SuperSimplexNoiseGenerator}. - * @return {@link SuperSimplexNoiseBuilder} this - */ - - public SuperSimplexNoiseBuilder setSeed(long seed) { - this.seed = seed; - return this; - } - - /** - * Sets the variant used for 2D OpenSimplex noise - * - * @param variant2D the new {@link Simplex2DVariant} for the {@link SuperSimplexNoiseGenerator}. - * @return {@link SuperSimplexNoiseBuilder} this - */ - - public SuperSimplexNoiseBuilder setVariant2D(Simplex2DVariant variant2D) { - if (variant2D == null) { - throw new IllegalArgumentException("Simplex 2D Variant cannot be null."); - } - this.variant2D = variant2D; - return this; - } - - /** - * Sets the variant used for 3D OpenSimplex noise - * - * @param variant3D the new {@link Simplex3DVariant} for the {@link SuperSimplexNoiseGenerator}. - * @return {@link SuperSimplexNoiseBuilder} this - */ - - public SuperSimplexNoiseBuilder setVariant3D(Simplex3DVariant variant3D) { - if (variant3D == null) { - throw new IllegalArgumentException("Simplex 3D Variant cannot be null."); - } - this.variant3D = variant3D; - return this; - } - - /** - * Sets the variant used for 4D OpenSimplex noise - * - * @param variant4D the new {@link Simplex4DVariant} for the {@link SuperSimplexNoiseGenerator}. - * @return {@link SuperSimplexNoiseBuilder} this - */ - - public SuperSimplexNoiseBuilder setVariant4D(Simplex4DVariant variant4D) { - if (variant4D == null) { - throw new IllegalArgumentException("Simplex 4D Variant cannot be null."); - } - this.variant4D = variant4D; - return this; - } - - @Override - - public SuperSimplexNoiseGenerator build() { - return new SuperSimplexNoiseGenerator(seed, variant2D, variant3D, variant4D); - } - } -} +package de.articdive.jnoise.generators.noisegen.opensimplex; + +import de.articdive.jnoise.core.api.noisegen.SeededNoiseGenerator; +import de.articdive.jnoise.core.api.pipeline.NoiseSourceBuilder; +import de.articdive.jnoise.generators.noise_parameters.simplex_variants.Simplex2DVariant; +import de.articdive.jnoise.generators.noise_parameters.simplex_variants.Simplex3DVariant; +import de.articdive.jnoise.generators.noise_parameters.simplex_variants.Simplex4DVariant; + +/** + * Uses KdotJPG's the super variant of OpenSimplex2 Noise located at https://github.com/KdotJPG/OpenSimplex2. + * The bounds of SuperOpenSimplex2 Noise are: [-1, 1]. + * + * @author Articdive + */ +public final class SuperSimplexNoiseGenerator implements SeededNoiseGenerator { + private final long seed; + private final Simplex2DVariant variant2D; + private final Simplex3DVariant variant3D; + private final Simplex4DVariant variant4D; + + private SuperSimplexNoiseGenerator( + long seed, + Simplex2DVariant variant2D, + Simplex3DVariant variant3D, + Simplex4DVariant variant4D + ) { + this.seed = seed; + this.variant2D = variant2D; + this.variant3D = variant3D; + this.variant4D = variant4D; + } + + @Override + public double evaluateNoise(double x, long seed) { + return OpenSimplex2S.noise2(seed, x, 1.0); + } + + @Override + public double evaluateNoise(double x, double y, long seed) { + switch (variant2D) { + case IMPROVE_X: return OpenSimplex2S.noise2_ImproveX(seed, x, y); + case CLASSIC: return OpenSimplex2S.noise2(seed, x, y); + } + return 0; + } + + @Override + public double evaluateNoise(double x, double y, double z, long seed) { + switch (variant3D) { + case IMPROVE_XY: return OpenSimplex2S.noise3_ImproveXY(seed, x, y, z); + case IMPROVE_XZ: return OpenSimplex2S.noise3_ImproveXZ(seed, x, y, z); + case CLASSIC: return OpenSimplex2S.noise3_Fallback(seed, x, y, z); + } + return 0; + } + + @Override + public double evaluateNoise(double x, double y, double z, double w, long seed) { + switch (variant4D) { + case IMPROVE_XY_IMPROVE_ZW: return OpenSimplex2S.noise4_ImproveXY_ImproveZW(seed, x, y, z, w); + case IMPROVE_XYZ_IMPROVE_XY: return OpenSimplex2S.noise4_ImproveXYZ_ImproveXY(seed, x, y, z, w); + case IMPROVE_XYZ_IMPROVE_XZ: return OpenSimplex2S.noise4_ImproveXYZ_ImproveXZ(seed, x, y, z, w); + case IMRPOVE_XYZ: return OpenSimplex2S.noise4_ImproveXYZ(seed, x, y, z, w); + case CLASSIC: return OpenSimplex2S.noise4_Fallback(seed, x, y, z, w); + } + return 0; + } + + @Override + public double evaluateNoise(double x) { + return evaluateNoise(x, seed); + } + + @Override + public double evaluateNoise(double x, double y) { + return evaluateNoise(x, y, seed); + + } + + @Override + public double evaluateNoise(double x, double y, double z) { + return evaluateNoise(x, y, z, seed); + } + + @Override + public double evaluateNoise(double x, double y, double z, double w) { + return evaluateNoise(x, y, z, w, seed); + } + + @Override + public long getSeed() { + return seed; + } + + /** + * Gets a {@link SuperSimplexNoiseBuilder} to build a {@link SuperSimplexNoiseGenerator}. + * + * @return {@link SuperSimplexNoiseBuilder}. + */ + public static SuperSimplexNoiseBuilder newBuilder() { + return new SuperSimplexNoiseBuilder(); + } + + /** + * Builder for the {@link SuperSimplexNoiseGenerator}. + */ + public static final class SuperSimplexNoiseBuilder implements NoiseSourceBuilder { + private long seed = 1729; + private Simplex2DVariant variant2D = Simplex2DVariant.CLASSIC; + private Simplex3DVariant variant3D = Simplex3DVariant.CLASSIC; + private Simplex4DVariant variant4D = Simplex4DVariant.CLASSIC; + + private SuperSimplexNoiseBuilder() { + + } + + /** + * Sets the seed for the {@link SuperSimplexNoiseGenerator}. + * + * @param seed the new seed for the {@link SuperSimplexNoiseGenerator}. + * @return {@link SuperSimplexNoiseBuilder} this + */ + public SuperSimplexNoiseBuilder setSeed(long seed) { + this.seed = seed; + return this; + } + + /** + * Sets the variant used for 2D OpenSimplex noise + * + * @param variant2D the new {@link Simplex2DVariant} for the {@link SuperSimplexNoiseGenerator}. + * @return {@link SuperSimplexNoiseBuilder} this + */ + public SuperSimplexNoiseBuilder setVariant2D(Simplex2DVariant variant2D) { + this.variant2D = variant2D; + return this; + } + + /** + * Sets the variant used for 3D OpenSimplex noise + * + * @param variant3D the new {@link Simplex3DVariant} for the {@link SuperSimplexNoiseGenerator}. + * @return {@link SuperSimplexNoiseBuilder} this + */ + public SuperSimplexNoiseBuilder setVariant3D(Simplex3DVariant variant3D) { + this.variant3D = variant3D; + return this; + } + + /** + * Sets the variant used for 4D OpenSimplex noise + * + * @param variant4D the new {@link Simplex4DVariant} for the {@link SuperSimplexNoiseGenerator}. + * @return {@link SuperSimplexNoiseBuilder} this + */ + public SuperSimplexNoiseBuilder setVariant4D(Simplex4DVariant variant4D) { + this.variant4D = variant4D; + return this; + } + + @Override + public SuperSimplexNoiseGenerator build() { + return new SuperSimplexNoiseGenerator(seed, variant2D, variant3D, variant4D); + } + } +} diff --git a/src/de/articdive/jnoise/generators/noisegen/pattern/CheckerboardNoiseGenerator.java b/src/de/articdive/jnoise/generators/noisegen/pattern/CheckerboardNoiseGenerator.java index 426dfd8a3..3425083b3 100644 --- a/src/de/articdive/jnoise/generators/noisegen/pattern/CheckerboardNoiseGenerator.java +++ b/src/de/articdive/jnoise/generators/noisegen/pattern/CheckerboardNoiseGenerator.java @@ -3,7 +3,6 @@ import de.articdive.jnoise.core.api.noisegen.NoiseGenerator; import de.articdive.jnoise.core.api.pipeline.NoiseSourceBuilder; - /** * A noise generator that returns a checkerboard of unit-sized blocks alternating between 0.0 and 1.0. * Useful when combined with the scale transformer, as you can create blocks of any size. @@ -50,7 +49,6 @@ public double evaluateNoise(double x, double y, double z, double w) { * * @return {@link CheckerboardNoiseBuilder}. */ - public static CheckerboardNoiseBuilder newBuilder() { return new CheckerboardNoiseBuilder(); } @@ -65,7 +63,6 @@ private CheckerboardNoiseBuilder() { } @Override - public CheckerboardNoiseGenerator build() { return new CheckerboardNoiseGenerator(); } diff --git a/src/de/articdive/jnoise/generators/noisegen/pattern/CylinderNoiseGenerator.java b/src/de/articdive/jnoise/generators/noisegen/pattern/CylinderNoiseGenerator.java index b0c13d81e..1f1cf907c 100644 --- a/src/de/articdive/jnoise/generators/noisegen/pattern/CylinderNoiseGenerator.java +++ b/src/de/articdive/jnoise/generators/noisegen/pattern/CylinderNoiseGenerator.java @@ -3,7 +3,6 @@ import de.articdive.jnoise.core.api.noisegen.NoiseGenerator; import de.articdive.jnoise.core.api.pipeline.NoiseSourceBuilder; - /** * A noise generator that returns a concentric cylinders (centered on the origin) extending infinitely. * Returns 1.0 when on a cylinder side, and 0.0 when perfectly between two cylinders. @@ -58,7 +57,6 @@ public double evaluateNoise(double x, double y, double z, double w) { * * @return {@link CylinderNoiseBuilder}. */ - public static CylinderNoiseBuilder newBuilder() { return new CylinderNoiseBuilder(); } @@ -73,7 +71,6 @@ private CylinderNoiseBuilder() { } @Override - public CylinderNoiseGenerator build() { return new CylinderNoiseGenerator(); } diff --git a/src/de/articdive/jnoise/generators/noisegen/pattern/SphereNoiseGenerator.java b/src/de/articdive/jnoise/generators/noisegen/pattern/SphereNoiseGenerator.java index 404555da1..891d33446 100644 --- a/src/de/articdive/jnoise/generators/noisegen/pattern/SphereNoiseGenerator.java +++ b/src/de/articdive/jnoise/generators/noisegen/pattern/SphereNoiseGenerator.java @@ -3,7 +3,6 @@ import de.articdive.jnoise.core.api.noisegen.NoiseGenerator; import de.articdive.jnoise.core.api.pipeline.NoiseSourceBuilder; - /** * A noise generator that returns a concentric spheres (centered on the origin) extending infinitely. * Returns 0.0 when on a circle, and 1.0 when between two circles. @@ -60,7 +59,6 @@ public double evaluateNoise(double x, double y, double z, double w) { * * @return {@link SphereNoiseBuilder}. */ - public static SphereNoiseBuilder newBuilder() { return new SphereNoiseBuilder(); } @@ -75,7 +73,6 @@ private SphereNoiseBuilder() { } @Override - public SphereNoiseGenerator build() { return new SphereNoiseGenerator(); } diff --git a/src/de/articdive/jnoise/generators/noisegen/perlin/PerlinNoiseGenerator.java b/src/de/articdive/jnoise/generators/noisegen/perlin/PerlinNoiseGenerator.java index 98306e79d..ccf409598 100644 --- a/src/de/articdive/jnoise/generators/noisegen/perlin/PerlinNoiseGenerator.java +++ b/src/de/articdive/jnoise/generators/noisegen/perlin/PerlinNoiseGenerator.java @@ -4,12 +4,12 @@ import de.articdive.jnoise.core.api.noisegen.SeededNoiseGenerator; import de.articdive.jnoise.core.api.pipeline.NoiseSourceBuilder; import de.articdive.jnoise.core.util.HashUtil; -import de.articdive.jnoise.core.util.vectors.Vector1D; -import de.articdive.jnoise.core.util.vectors.Vector2D; -import de.articdive.jnoise.core.util.vectors.Vector3D; -import de.articdive.jnoise.core.util.vectors.Vector4D; import de.articdive.jnoise.generators.noise_parameters.fade_functions.FadeFunction; +import static de.articdive.jnoise.core.util.MathUtil.dot2D; +import static de.articdive.jnoise.core.util.MathUtil.dot3D; +import static de.articdive.jnoise.core.util.MathUtil.dot4D; + /** * Based on Ken Perlin's implementation of Perlin Noise. * The bounds of this Perlin Noise implementation are: [-sqrt(n/2), sqrt(n/2)] (n being the dimension). @@ -17,50 +17,50 @@ * @author Articdive */ public final class PerlinNoiseGenerator implements SeededNoiseGenerator { - private static final Vector1D[] VECTOR_1D = new Vector1D[]{ - new Vector1D(1), new Vector1D(-1) + private static final double[] VECTOR_1D = new double[]{ + 1, -1 }; - private static final Vector2D[] VECTOR_2D = new Vector2D[]{ - new Vector2D(1, 1), new Vector2D(-1, 1), new Vector2D(1, -1), new Vector2D(-1, -1), + private static final double[][] VECTOR_2D = new double[][]{ + new double[]{1, 1}, new double[]{-1, 1}, new double[]{1, -1}, new double[]{-1, -1}, - new Vector2D(0, 1), new Vector2D(0, -1), new Vector2D(1, 0), new Vector2D(-1, 0) + new double[]{0, 1}, new double[]{0, -1}, new double[]{1, 0}, new double[]{-1, 0} }; - private static final Vector3D[] VECTOR_3D = new Vector3D[]{ - new Vector3D(1, 1, 1), new Vector3D(-1, 1, 1), - new Vector3D(1, -1, 1), new Vector3D(-1, -1, 1), - new Vector3D(1, 1, -1), new Vector3D(-1, 1, -1), - new Vector3D(1, -1, -1), new Vector3D(-1, -1, -1), + private static final double[][] VECTOR_3D = new double[][]{ + new double[]{1, 1, 1}, new double[]{-1, 1, 1}, + new double[]{1, -1, 1}, new double[]{-1, -1, 1}, + new double[]{1, 1, -1}, new double[]{-1, 1, -1}, + new double[]{1, -1, -1}, new double[]{-1, -1, -1}, - new Vector3D(0, 1, 1), new Vector3D(0, -1, 1), new Vector3D(0, 1, -1), new Vector3D(0, -1, -1), - new Vector3D(1, 0, 1), new Vector3D(-1, 0, 1), new Vector3D(1, 0, -1), new Vector3D(-1, 0, -1), - new Vector3D(1, 1, 0), new Vector3D(-1, 1, 0), new Vector3D(1, -1, 0), new Vector3D(-1, -1, 0) + new double[]{0, 1, 1}, new double[]{0, -1, 1}, new double[]{0, 1, -1}, new double[]{0, -1, -1}, + new double[]{1, 0, 1}, new double[]{-1, 0, 1}, new double[]{1, 0, -1}, new double[]{-1, 0, -1}, + new double[]{1, 1, 0}, new double[]{-1, 1, 0}, new double[]{1, -1, 0}, new double[]{-1, -1, 0} }; - private static final Vector4D[] VECTOR_4D = new Vector4D[]{ - new Vector4D(1, 1, 1, 1), new Vector4D(1, 1, -1, 1), - new Vector4D(1, -1, 1, 1), new Vector4D(1, -1, -1, 1), - new Vector4D(-1, 1, 1, 1), new Vector4D(-1, 1, -1, 1), - new Vector4D(-1, -1, 1, 1), new Vector4D(-1, -1, -1, 1), - new Vector4D(1, 1, 1, -1), new Vector4D(1, 1, -1, -1), - new Vector4D(1, -1, 1, -1), new Vector4D(1, -1, -1, -1), - new Vector4D(-1, 1, 1, -1), new Vector4D(-1, 1, -1, -1), - new Vector4D(-1, -1, 1, -1), new Vector4D(-1, -1, -1, -1), + private static final double[][] VECTOR_4D = new double[][]{ + new double[]{1, 1, 1, 1}, new double[]{1, 1, -1, 1}, + new double[]{1, -1, 1, 1}, new double[]{1, -1, -1, 1}, + new double[]{-1, 1, 1, 1}, new double[]{-1, 1, -1, 1}, + new double[]{-1, -1, 1, 1}, new double[]{-1, -1, -1, 1}, + new double[]{1, 1, 1, -1}, new double[]{1, 1, -1, -1}, + new double[]{1, -1, 1, -1}, new double[]{1, -1, -1, -1}, + new double[]{-1, 1, 1, -1}, new double[]{-1, 1, -1, -1}, + new double[]{-1, -1, 1, -1}, new double[]{-1, -1, -1, -1}, - new Vector4D(0, 1, 1, 1), new Vector4D(0, 1, -1, 1), - new Vector4D(0, -1, 1, 1), new Vector4D(0, -1, -1, 1), - new Vector4D(0, 1, 1, -1), new Vector4D(0, 1, -1, -1), - new Vector4D(0, -1, 1, -1), new Vector4D(0, -1, -1, -1), - new Vector4D(1, 0, 1, 1), new Vector4D(1, 0, -1, 1), - new Vector4D(-1, 0, 1, 1), new Vector4D(-1, 0, -1, 1), - new Vector4D(1, 0, 1, -1), new Vector4D(1, 0, -1, -1), - new Vector4D(-1, 0, 1, -1), new Vector4D(-1, 0, -1, -1), - new Vector4D(1, 1, 0, 1), new Vector4D(1, -1, 0, 1), - new Vector4D(-1, 1, 0, 1), new Vector4D(-1, -1, 0, 1), - new Vector4D(1, 1, 0, -1), new Vector4D(1, -1, 0, -1), - new Vector4D(-1, 1, 0, -1), new Vector4D(-1, -1, 0, -1), - new Vector4D(1, 1, 1, 0), new Vector4D(1, -1, 1, 0), - new Vector4D(-1, 1, 1, 0), new Vector4D(-1, -1, 1, 0), - new Vector4D(1, 1, -1, 0), new Vector4D(1, -1, -1, 0), - new Vector4D(-1, 1, -1, 0), new Vector4D(-1, -1, -1, 0) + new double[]{0, 1, 1, 1}, new double[]{0, 1, -1, 1}, + new double[]{0, -1, 1, 1}, new double[]{0, -1, -1, 1}, + new double[]{0, 1, 1, -1}, new double[]{0, 1, -1, -1}, + new double[]{0, -1, 1, -1}, new double[]{0, -1, -1, -1}, + new double[]{1, 0, 1, 1}, new double[]{1, 0, -1, 1}, + new double[]{-1, 0, 1, 1}, new double[]{-1, 0, -1, 1}, + new double[]{1, 0, 1, -1}, new double[]{1, 0, -1, -1}, + new double[]{-1, 0, 1, -1}, new double[]{-1, 0, -1, -1}, + new double[]{1, 1, 0, 1}, new double[]{1, -1, 0, 1}, + new double[]{-1, 1, 0, 1}, new double[]{-1, -1, 0, 1}, + new double[]{1, 1, 0, -1}, new double[]{1, -1, 0, -1}, + new double[]{-1, 1, 0, -1}, new double[]{-1, -1, 0, -1}, + new double[]{1, 1, 1, 0}, new double[]{1, -1, 1, 0}, + new double[]{-1, 1, 1, 0}, new double[]{-1, -1, 1, 0}, + new double[]{1, 1, -1, 0}, new double[]{1, -1, -1, 0}, + new double[]{-1, 1, -1, 0}, new double[]{-1, -1, -1, 0} }; private final long seed; @@ -86,8 +86,8 @@ public double evaluateNoise(double x, long seed) { }; double[] dots = new double[]{ // (VECTOR_1D.length - 1) = 1. - new Vector1D(x).dot(VECTOR_1D[HashUtil.hash1D(seed, iX) & 1]), - new Vector1D(x - 1).dot(VECTOR_1D[HashUtil.hash1D(seed, iX + 1) & 1]) + x * VECTOR_1D[HashUtil.hash1D(seed, iX) & 1], + (x - 1) * VECTOR_1D[HashUtil.hash1D(seed, iX + 1) & 1] }; return interpolation.lerp(fractals, dots); @@ -109,10 +109,10 @@ public double evaluateNoise(double x, double y, long seed) { }; double[] dots = new double[]{ // (VECTOR_2D.length - 1) = 7. - new Vector2D(x, y).dot(VECTOR_2D[HashUtil.hash2D(seed, iX, iY) & 7]), - new Vector2D(x - 1, y).dot(VECTOR_2D[HashUtil.hash2D(seed, iX + 1, iY) & 7]), - new Vector2D(x, y - 1).dot(VECTOR_2D[HashUtil.hash2D(seed, iX, iY + 1) & 7]), - new Vector2D(x - 1, y - 1).dot(VECTOR_2D[HashUtil.hash2D(seed, iX + 1, iY + 1) & 7]) + dot2D(new double[]{x, y}, VECTOR_2D[HashUtil.hash2D(seed, iX, iY) & 7]), + dot2D(new double[]{x - 1, y}, VECTOR_2D[HashUtil.hash2D(seed, iX + 1, iY) & 7]), + dot2D(new double[]{x, y - 1}, VECTOR_2D[HashUtil.hash2D(seed, iX, iY + 1) & 7]), + dot2D(new double[]{x - 1, y - 1}, VECTOR_2D[HashUtil.hash2D(seed, iX + 1, iY + 1) & 7]), }; return interpolation.lerp(fractals, dots); @@ -136,22 +136,14 @@ public double evaluateNoise(double x, double y, double z, long seed) { }; double[] dots = new double[]{ // (VECTOR_3D.length - 1) = 19. - new Vector3D(x, y, z) - .dot(VECTOR_3D[HashUtil.hash3D(seed, iX, iY, iZ) & 19]), - new Vector3D(x - 1, y, z) - .dot(VECTOR_3D[HashUtil.hash3D(seed, iX + 1, iY, iZ) & 19]), - new Vector3D(x, y - 1, z) - .dot(VECTOR_3D[HashUtil.hash3D(seed, iX, iY + 1, iZ) & 19]), - new Vector3D(x - 1, y - 1, z) - .dot(VECTOR_3D[HashUtil.hash3D(seed, iX + 1, iY + 1, iZ) & 19]), - new Vector3D(x, y, z - 1) - .dot(VECTOR_3D[HashUtil.hash3D(seed, iX, iY, iZ + 1) & 19]), - new Vector3D(x - 1, y, z - 1) - .dot(VECTOR_3D[HashUtil.hash3D(seed, iX + 1, iY, iZ + 1) & 19]), - new Vector3D(x, y - 1, z - 1) - .dot(VECTOR_3D[HashUtil.hash3D(seed, iX, iY + 1, iZ + 1) & 19]), - new Vector3D(x - 1, y - 1, z - 1) - .dot(VECTOR_3D[HashUtil.hash3D(seed, iX + 1, iY + 1, iZ + 1) & 19]) + dot3D(new double[]{x, y, z}, VECTOR_3D[HashUtil.hash3D(seed, iX, iY, iZ) & 19]), + dot3D(new double[]{x - 1, y, z}, VECTOR_3D[HashUtil.hash3D(seed, iX + 1, iY, iZ) & 19]), + dot3D(new double[]{x, y - 1, z}, VECTOR_3D[HashUtil.hash3D(seed, iX, iY + 1, iZ) & 19]), + dot3D(new double[]{x - 1, y - 1, z}, VECTOR_3D[HashUtil.hash3D(seed, iX + 1, iY + 1, iZ) & 19]), + dot3D(new double[]{x, y, z - 1}, VECTOR_3D[HashUtil.hash3D(seed, iX, iY, iZ + 1) & 19]), + dot3D(new double[]{x - 1, y, z - 1}, VECTOR_3D[HashUtil.hash3D(seed, iX + 1, iY, iZ + 1) & 19]), + dot3D(new double[]{x, y - 1, z - 1}, VECTOR_3D[HashUtil.hash3D(seed, iX, iY + 1, iZ + 1) & 19]), + dot3D(new double[]{x - 1, y - 1, z - 1}, VECTOR_3D[HashUtil.hash3D(seed, iX + 1, iY + 1, iZ + 1) & 19]) }; return interpolation.lerp(fractals, dots); } @@ -177,38 +169,22 @@ public double evaluateNoise(double x, double y, double z, double w, long seed) { }; double[] dots = new double[]{ // (VECTOR_4D.length - 1) = 19. - new Vector4D(x, y, z, w) - .dot(VECTOR_4D[HashUtil.hash4D(seed, iX, iY, iZ, iW) & 47]), - new Vector4D(x - 1, y, z, w) - .dot(VECTOR_4D[HashUtil.hash4D(seed, iX + 1, iY, iZ, iW) & 47]), - new Vector4D(x, y - 1, z, w) - .dot(VECTOR_4D[HashUtil.hash4D(seed, iX, iY + 1, iZ, iW) & 47]), - new Vector4D(x - 1, y - 1, z, w) - .dot(VECTOR_4D[HashUtil.hash4D(seed, iX + 1, iY + 1, iZ, iW) & 47]), - new Vector4D(x, y, z - 1, w) - .dot(VECTOR_4D[HashUtil.hash4D(seed, iX, iY, iZ + 1, iW) & 47]), - new Vector4D(x - 1, y, z - 1, w) - .dot(VECTOR_4D[HashUtil.hash4D(seed, iX + 1, iY, iZ + 1, iW) & 47]), - new Vector4D(x, y - 1, z - 1, w) - .dot(VECTOR_4D[HashUtil.hash4D(seed, iX, iY + 1, iZ + 1, iW) & 47]), - new Vector4D(x - 1, y - 1, z - 1, w) - .dot(VECTOR_4D[HashUtil.hash4D(seed, iX + 1, iY + 1, iZ + 1, iW) & 47]), - new Vector4D(x, y, z, w - 1) - .dot(VECTOR_4D[HashUtil.hash4D(seed, iX, iY, iZ, iW + 1) & 47]), - new Vector4D(x - 1, y, z, w - 1) - .dot(VECTOR_4D[HashUtil.hash4D(seed, iX + 1, iY, iZ, iW + 1) & 47]), - new Vector4D(x, y - 1, z, w - 1) - .dot(VECTOR_4D[HashUtil.hash4D(seed, iX, iY + 1, iZ, iW + 1) & 47]), - new Vector4D(x - 1, y - 1, z, w - 1) - .dot(VECTOR_4D[HashUtil.hash4D(seed, iX + 1, iY + 1, iZ, iW + 1) & 47]), - new Vector4D(x, y, z - 1, w - 1) - .dot(VECTOR_4D[HashUtil.hash4D(seed, iX, iY, iZ + 1, iW + 1) & 47]), - new Vector4D(x - 1, y, z - 1, w - 1) - .dot(VECTOR_4D[HashUtil.hash4D(seed, iX + 1, iY, iZ + 1, iW + 1) & 47]), - new Vector4D(x, y - 1, z - 1, w - 1) - .dot(VECTOR_4D[HashUtil.hash4D(seed, iX, iY + 1, iZ + 1, iW + 1) & 47]), - new Vector4D(x - 1, y - 1, z - 1, w - 1) - .dot(VECTOR_4D[HashUtil.hash4D(seed, iX + 1, iY + 1, iZ + 1, iW + 1) & 47]) + dot4D(new double[]{x, y, z, w}, VECTOR_4D[HashUtil.hash4D(seed, iX, iY, iZ, iW) & 47]), + dot4D(new double[]{x - 1, y, z, w}, VECTOR_4D[HashUtil.hash4D(seed, iX + 1, iY, iZ, iW) & 47]), + dot4D(new double[]{x, y - 1, z, w}, VECTOR_4D[HashUtil.hash4D(seed, iX, iY + 1, iZ, iW) & 47]), + dot4D(new double[]{x - 1, y - 1, z, w}, VECTOR_4D[HashUtil.hash4D(seed, iX + 1, iY + 1, iZ, iW) & 47]), + dot4D(new double[]{x, y, z - 1, w}, VECTOR_4D[HashUtil.hash4D(seed, iX, iY, iZ + 1, iW) & 47]), + dot4D(new double[]{x - 1, y, z - 1, w}, VECTOR_4D[HashUtil.hash4D(seed, iX + 1, iY, iZ + 1, iW) & 47]), + dot4D(new double[]{x, y - 1, z - 1, w}, VECTOR_4D[HashUtil.hash4D(seed, iX, iY + 1, iZ + 1, iW) & 47]), + dot4D(new double[]{x - 1, y - 1, z - 1, w}, VECTOR_4D[HashUtil.hash4D(seed, iX + 1, iY + 1, iZ + 1, iW) & 47]), + dot4D(new double[]{x, y, z, w - 1}, VECTOR_4D[HashUtil.hash4D(seed, iX, iY, iZ, iW + 1) & 47]), + dot4D(new double[]{x - 1, y, z, w - 1}, VECTOR_4D[HashUtil.hash4D(seed, iX + 1, iY, iZ, iW + 1) & 47]), + dot4D(new double[]{x, y - 1, z, w - 1}, VECTOR_4D[HashUtil.hash4D(seed, iX, iY + 1, iZ, iW + 1) & 47]), + dot4D(new double[]{x - 1, y - 1, z, w - 1}, VECTOR_4D[HashUtil.hash4D(seed, iX + 1, iY + 1, iZ, iW + 1) & 47]), + dot4D(new double[]{x, y, z - 1, w - 1}, VECTOR_4D[HashUtil.hash4D(seed, iX, iY, iZ + 1, iW + 1) & 47]), + dot4D(new double[]{x - 1, y, z - 1, w - 1}, VECTOR_4D[HashUtil.hash4D(seed, iX + 1, iY, iZ + 1, iW + 1) & 47]), + dot4D(new double[]{x, y - 1, z - 1, w - 1}, VECTOR_4D[HashUtil.hash4D(seed, iX, iY + 1, iZ + 1, iW + 1) & 47]), + dot4D(new double[]{x - 1, y - 1, z - 1, w - 1}, VECTOR_4D[HashUtil.hash4D(seed, iX + 1, iY + 1, iZ + 1, iW + 1) & 47]) }; return interpolation.lerp(fractals, dots); } @@ -277,9 +253,6 @@ public PerlinNoiseBuilder setSeed(long seed) { * @return {@link PerlinNoiseBuilder} this */ public PerlinNoiseBuilder setInterpolation(Interpolation interpolation) { - if (interpolation == null) { - throw new IllegalArgumentException("Interpolation cannot be null."); - } this.interpolation = interpolation; return this; } @@ -291,9 +264,6 @@ public PerlinNoiseBuilder setInterpolation(Interpolation interpolation) { * @return {@link PerlinNoiseBuilder} this */ public PerlinNoiseBuilder setFadeFunction(FadeFunction fadeFunction) { - if (fadeFunction == null) { - throw new IllegalArgumentException("Fade function cannot be null."); - } this.fadeFunction = fadeFunction; return this; } diff --git a/src/de/articdive/jnoise/generators/noisegen/random/gaussian/GaussianWhiteNoiseGenerator.java b/src/de/articdive/jnoise/generators/noisegen/random/gaussian/GaussianWhiteNoiseGenerator.java index e4a02a3c7..8e8c62144 100644 --- a/src/de/articdive/jnoise/generators/noisegen/random/gaussian/GaussianWhiteNoiseGenerator.java +++ b/src/de/articdive/jnoise/generators/noisegen/random/gaussian/GaussianWhiteNoiseGenerator.java @@ -1,153 +1,153 @@ -package de.articdive.jnoise.generators.noisegen.random.gaussian; - -import de.articdive.jnoise.core.api.noisegen.SeededNoiseGenerator; -import de.articdive.jnoise.core.api.pipeline.NoiseSourceBuilder; -import de.articdive.jnoise.core.util.HashUtil; - -import java.util.Random; - -/** - * There are no bounds on this implementation (Asymptotes on both sides of a gaussian distribution). - * It is recommended to use a clamp. - * - * @author Articdive - */ -public final class GaussianWhiteNoiseGenerator implements SeededNoiseGenerator { - private final long seed; - private final double mean; - private final double stddev; - - private GaussianWhiteNoiseGenerator(long seed, double mean, double stddev) { - this.seed = seed; - this.mean = mean; - this.stddev = stddev; - } - - public double evaluateNoise(double x, long seed) { - long iX = (long) Math.floor(x); - - Random random = new Random(HashUtil.hash1D(seed, iX)); - - return random.nextGaussian() * stddev + mean; - } - - @Override - public double evaluateNoise(double x, double y, long seed) { - long iX = (long) Math.floor(x); - long iY = (long) Math.floor(y); - - Random random = new Random(HashUtil.hash2D(seed, iX, iY)); - - return random.nextGaussian() * stddev + mean; - } - - @Override - public double evaluateNoise(double x, double y, double z, long seed) { - long iX = (long) Math.floor(x); - long iY = (long) Math.floor(y); - long iZ = (long) Math.floor(z); - - Random random = new Random(HashUtil.hash3D(seed, iX, iY, iZ)); - - return random.nextGaussian() * stddev + mean; - } - - @Override - public double evaluateNoise(double x, double y, double z, double w, long seed) { - long iX = (long) Math.floor(x); - long iY = (long) Math.floor(y); - long iZ = (long) Math.floor(z); - long iW = (long) Math.floor(w); - - Random random = new Random(HashUtil.hash4D(seed, iX, iY, iZ, iW)); - - return random.nextGaussian() * stddev + mean; - } - - @Override - public double evaluateNoise(double x) { - return evaluateNoise(x, seed); - } - - @Override - public double evaluateNoise(double x, double y) { - return evaluateNoise(x, y, seed); - } - - @Override - public double evaluateNoise(double x, double y, double z) { - return evaluateNoise(x, y, z, seed); - } - - @Override - public double evaluateNoise(double x, double y, double z, double w) { - return evaluateNoise(x, y, z, w, seed); - } - - @Override - public long getSeed() { - return seed; - } - - /** - * Gets a {@link GaussianWhiteNoiseBuilder} to build a {@link GaussianWhiteNoiseGenerator}. - * - * @return {@link GaussianWhiteNoiseBuilder}. - */ - public static GaussianWhiteNoiseBuilder newBuilder() { - return new GaussianWhiteNoiseBuilder(); - } - - /** - * Builder for the {@link GaussianWhiteNoiseGenerator}. - */ - public static final class GaussianWhiteNoiseBuilder implements NoiseSourceBuilder { - private long seed = 1729; - - private double mean = 0.0; - - private double stddev = 1 / 3.0; - - private GaussianWhiteNoiseBuilder() { - - } - - /** - * Sets the seed for the {@link GaussianWhiteNoiseGenerator}. - * - * @param seed the new seed for the {@link GaussianWhiteNoiseGenerator}. - * @return {@link GaussianWhiteNoiseBuilder} this - */ - public GaussianWhiteNoiseGenerator.GaussianWhiteNoiseBuilder setSeed(long seed) { - this.seed = seed; - return this; - } - - /** - * Sets the mean for the gaussian distribution in the {@link GaussianWhiteNoiseGenerator} - * - * @param mean the new mean for the {@link GaussianWhiteNoiseGenerator} - * @return {@link GaussianWhiteNoiseBuilder} this - */ - public GaussianWhiteNoiseBuilder setMean(double mean) { - this.mean = mean; - return this; - } - - /** - * Sets the standard deviation for the gaussian distribution in the {@link GaussianWhiteNoiseGenerator} - * - * @param stddev the new standard deviation for the {@link GaussianWhiteNoiseGenerator} - * @return {@link GaussianWhiteNoiseBuilder} this - */ - public GaussianWhiteNoiseBuilder setStandardDeviation(double stddev) { - this.stddev = stddev; - return this; - } - - @Override - public GaussianWhiteNoiseGenerator build() { - return new GaussianWhiteNoiseGenerator(seed, mean, stddev); - } - } -} +package de.articdive.jnoise.generators.noisegen.random.gaussian; + +import de.articdive.jnoise.core.api.noisegen.SeededNoiseGenerator; +import de.articdive.jnoise.core.api.pipeline.NoiseSourceBuilder; +import de.articdive.jnoise.core.util.HashUtil; + +import java.util.Random; + +/** + * There are no bounds on this implementation (Asymptotes on both sides of a gaussian distribution). + * It is recommended to use a clamp. + * + * @author Articdive + */ +public final class GaussianWhiteNoiseGenerator implements SeededNoiseGenerator { + private final long seed; + private final double mean; + private final double stddev; + + private GaussianWhiteNoiseGenerator(long seed, double mean, double stddev) { + this.seed = seed; + this.mean = mean; + this.stddev = stddev; + } + + public double evaluateNoise(double x, long seed) { + long iX = (long) Math.floor(x); + + Random random = new Random(HashUtil.hash1D(seed, iX)); + + return random.nextGaussian() * stddev + mean; + } + + @Override + public double evaluateNoise(double x, double y, long seed) { + long iX = (long) Math.floor(x); + long iY = (long) Math.floor(y); + + Random random = new Random(HashUtil.hash2D(seed, iX, iY)); + + return random.nextGaussian() * stddev + mean; + } + + @Override + public double evaluateNoise(double x, double y, double z, long seed) { + long iX = (long) Math.floor(x); + long iY = (long) Math.floor(y); + long iZ = (long) Math.floor(z); + + Random random = new Random(HashUtil.hash3D(seed, iX, iY, iZ)); + + return random.nextGaussian() * stddev + mean; + } + + @Override + public double evaluateNoise(double x, double y, double z, double w, long seed) { + long iX = (long) Math.floor(x); + long iY = (long) Math.floor(y); + long iZ = (long) Math.floor(z); + long iW = (long) Math.floor(w); + + Random random = new Random(HashUtil.hash4D(seed, iX, iY, iZ, iW)); + + return random.nextGaussian() * stddev + mean; + } + + @Override + public double evaluateNoise(double x) { + return evaluateNoise(x, seed); + } + + @Override + public double evaluateNoise(double x, double y) { + return evaluateNoise(x, y, seed); + } + + @Override + public double evaluateNoise(double x, double y, double z) { + return evaluateNoise(x, y, z, seed); + } + + @Override + public double evaluateNoise(double x, double y, double z, double w) { + return evaluateNoise(x, y, z, w, seed); + } + + @Override + public long getSeed() { + return seed; + } + + /** + * Gets a {@link GaussianWhiteNoiseBuilder} to build a {@link GaussianWhiteNoiseGenerator}. + * + * @return {@link GaussianWhiteNoiseBuilder}. + */ + public static GaussianWhiteNoiseBuilder newBuilder() { + return new GaussianWhiteNoiseBuilder(); + } + + /** + * Builder for the {@link GaussianWhiteNoiseGenerator}. + */ + public static final class GaussianWhiteNoiseBuilder implements NoiseSourceBuilder { + private long seed = 1729; + + private double mean = 0.0; + + private double stddev = 1 / 3.0; + + private GaussianWhiteNoiseBuilder() { + + } + + /** + * Sets the seed for the {@link GaussianWhiteNoiseGenerator}. + * + * @param seed the new seed for the {@link GaussianWhiteNoiseGenerator}. + * @return {@link GaussianWhiteNoiseBuilder} this + */ + public GaussianWhiteNoiseGenerator.GaussianWhiteNoiseBuilder setSeed(long seed) { + this.seed = seed; + return this; + } + + /** + * Sets the mean for the gaussian distribution in the {@link GaussianWhiteNoiseGenerator} + * + * @param mean the new mean for the {@link GaussianWhiteNoiseGenerator} + * @return {@link GaussianWhiteNoiseBuilder} this + */ + public GaussianWhiteNoiseBuilder setMean(double mean) { + this.mean = mean; + return this; + } + + /** + * Sets the standard deviation for the gaussian distribution in the {@link GaussianWhiteNoiseGenerator} + * + * @param stddev the new standard deviation for the {@link GaussianWhiteNoiseGenerator} + * @return {@link GaussianWhiteNoiseBuilder} this + */ + public GaussianWhiteNoiseBuilder setStandardDeviation(double stddev) { + this.stddev = stddev; + return this; + } + + @Override + public GaussianWhiteNoiseGenerator build() { + return new GaussianWhiteNoiseGenerator(seed, mean, stddev); + } + } +} diff --git a/src/de/articdive/jnoise/generators/noisegen/random/white/WhiteNoiseGenerator.java b/src/de/articdive/jnoise/generators/noisegen/random/white/WhiteNoiseGenerator.java index 5b1a780c6..991a1fe38 100644 --- a/src/de/articdive/jnoise/generators/noisegen/random/white/WhiteNoiseGenerator.java +++ b/src/de/articdive/jnoise/generators/noisegen/random/white/WhiteNoiseGenerator.java @@ -3,7 +3,6 @@ import de.articdive.jnoise.core.api.noisegen.SeededNoiseGenerator; import de.articdive.jnoise.core.api.pipeline.NoiseSourceBuilder; - import static de.articdive.jnoise.core.util.HashUtil.W_PRIME; import static de.articdive.jnoise.core.util.HashUtil.X_PRIME; import static de.articdive.jnoise.core.util.HashUtil.Y_PRIME; @@ -100,7 +99,6 @@ private static double evaluateCoord4D(long x, long y, long z, long w, long seed) * * @return {@link WhiteNoiseBuilder}. */ - public static WhiteNoiseBuilder newBuilder() { return new WhiteNoiseBuilder(); } @@ -121,14 +119,12 @@ private WhiteNoiseBuilder() { * @param seed the new seed for the {@link WhiteNoiseGenerator}. * @return {@link WhiteNoiseBuilder} this */ - public WhiteNoiseBuilder setSeed(long seed) { this.seed = seed; return this; } @Override - public WhiteNoiseGenerator build() { return new WhiteNoiseGenerator(seed); } diff --git a/src/de/articdive/jnoise/generators/noisegen/value/ValueNoiseGenerator.java b/src/de/articdive/jnoise/generators/noisegen/value/ValueNoiseGenerator.java index d89eb664b..3a8ca3bae 100644 --- a/src/de/articdive/jnoise/generators/noisegen/value/ValueNoiseGenerator.java +++ b/src/de/articdive/jnoise/generators/noisegen/value/ValueNoiseGenerator.java @@ -209,9 +209,6 @@ public ValueNoiseBuilder setSeed(long seed) { * @return {@link ValueNoiseBuilder} this */ public ValueNoiseBuilder setInterpolation(Interpolation interpolation) { - if (interpolation == null) { - throw new IllegalArgumentException("Interpolation cannot be null."); - } this.interpolation = interpolation; return this; } @@ -223,9 +220,6 @@ public ValueNoiseBuilder setInterpolation(Interpolation interpolation) { * @return {@link ValueNoiseBuilder} this */ public ValueNoiseBuilder setFadeFunction(FadeFunction fadeFunction) { - if (fadeFunction == null) { - throw new IllegalArgumentException("Fade function cannot be null."); - } this.fadeFunction = fadeFunction; return this; } diff --git a/src/de/articdive/jnoise/generators/noisegen/worley/WorleyNoiseGenerator.java b/src/de/articdive/jnoise/generators/noisegen/worley/WorleyNoiseGenerator.java index 0bb4656e7..cc190563b 100644 --- a/src/de/articdive/jnoise/generators/noisegen/worley/WorleyNoiseGenerator.java +++ b/src/de/articdive/jnoise/generators/noisegen/worley/WorleyNoiseGenerator.java @@ -4,17 +4,11 @@ import de.articdive.jnoise.core.api.noisegen.SeededExplicitNoiseGenerator; import de.articdive.jnoise.core.api.pipeline.NoiseSourceBuilder; import de.articdive.jnoise.core.util.HashUtil; -import de.articdive.jnoise.core.util.vectors.Vector; -import de.articdive.jnoise.core.util.vectors.Vector1D; -import de.articdive.jnoise.core.util.vectors.Vector2D; -import de.articdive.jnoise.core.util.vectors.Vector3D; -import de.articdive.jnoise.core.util.vectors.Vector4D; import de.articdive.jnoise.generators.noise_parameters.distance_functions.DistanceFunction; import de.articdive.jnoise.generators.noise_parameters.distance_functions.DistanceFunctionType; import de.articdive.jnoise.generators.noise_parameters.return_type_functions.ReturnDistanceFunction; import de.articdive.jnoise.generators.noise_parameters.return_type_functions.ReturnDistanceFunctionType; - import java.util.Arrays; import java.util.Random; import java.util.function.IntToLongFunction; @@ -27,7 +21,7 @@ * * @author Articdive */ -public final class WorleyNoiseGenerator implements SeededExplicitNoiseGenerator> { +public final class WorleyNoiseGenerator implements SeededExplicitNoiseGenerator { private final long seed; private final int depth; @@ -86,13 +80,12 @@ public double evaluateNoise(double x, double y, double z, double w) { } @Override - - public WorleyNoiseResult evaluateNoiseResult(double x, long seed) { + public WorleyNoiseResult evaluateNoiseResult(double x, long seed) { long iX = (long) Math.floor(x); double[] distancesStack = new double[depth]; Arrays.fill(distancesStack, Double.MAX_VALUE); // distancesStack[0] is the shortest distance. - Vector1D closestPoint = null; + double[] closestPoint = new double[1]; //TODO: Add Grid size as a parameter in all worley noise types. (Here it is 3) for (int xOffset = -1; xOffset <= 1; xOffset++) { @@ -116,23 +109,22 @@ public WorleyNoiseResult evaluateNoiseResult(double x, long seed) { } if (distance < distancesStack[0]) { distancesStack[0] = minFunction.applyTo(distance, distancesStack[0]); - closestPoint = new Vector1D(pointX); + closestPoint[0] = pointX; } } } - return new WorleyNoiseResult<>(returnDistanceFunction.applyAsDouble(distancesStack), closestPoint); + return new WorleyNoiseResult(returnDistanceFunction.applyAsDouble(distancesStack), closestPoint); } @Override - - public WorleyNoiseResult evaluateNoiseResult(double x, double y, long seed) { + public WorleyNoiseResult evaluateNoiseResult(double x, double y, long seed) { long iX = (long) Math.floor(x); long iY = (long) Math.floor(y); double[] distancesStack = new double[depth]; Arrays.fill(distancesStack, Double.MAX_VALUE); // distancesStack[0] is the shortest distance. - Vector2D closestPoint = null; + double[] closestPoint = new double[2]; for (int xOffset = -1; xOffset <= 1; xOffset++) { long secX = iX + xOffset; @@ -161,24 +153,24 @@ public WorleyNoiseResult evaluateNoiseResult(double x, double y, long se } if (distance < distancesStack[0]) { distancesStack[0] = minFunction.applyTo(distance, distancesStack[0]); - closestPoint = new Vector2D(pointX, pointY); + closestPoint[0] = pointX; + closestPoint[1] = pointY; } } } } - return new WorleyNoiseResult<>(returnDistanceFunction.applyAsDouble(distancesStack), closestPoint); + return new WorleyNoiseResult(returnDistanceFunction.applyAsDouble(distancesStack), closestPoint); } @Override - - public WorleyNoiseResult evaluateNoiseResult(double x, double y, double z, long seed) { + public WorleyNoiseResult evaluateNoiseResult(double x, double y, double z, long seed) { long iX = (long) Math.floor(x); long iY = (long) Math.floor(y); long iZ = (long) Math.floor(z); double[] distancesStack = new double[depth]; Arrays.fill(distancesStack, Double.MAX_VALUE); // distancesStack[0] is the shortest distance. - Vector3D closestPoint = null; + double[] closestPoint = new double[3]; for (int xOffset = -1; xOffset <= 1; xOffset++) { long secX = iX + xOffset; @@ -212,19 +204,20 @@ public WorleyNoiseResult evaluateNoiseResult(double x, double y, double } if (distance < distancesStack[0]) { distancesStack[0] = minFunction.applyTo(distance, distancesStack[0]); - closestPoint = new Vector3D(pointX, pointY, pointZ); + closestPoint[0] = pointX; + closestPoint[1] = pointY; + closestPoint[2] = pointZ; } } } } } - return new WorleyNoiseResult<>(returnDistanceFunction.applyAsDouble(distancesStack), closestPoint); + return new WorleyNoiseResult(returnDistanceFunction.applyAsDouble(distancesStack), closestPoint); } @Override - - public WorleyNoiseResult evaluateNoiseResult(double x, double y, double z, double w, long seed) { + public WorleyNoiseResult evaluateNoiseResult(double x, double y, double z, double w, long seed) { long iX = (long) Math.floor(x); long iY = (long) Math.floor(y); long iZ = (long) Math.floor(z); @@ -232,7 +225,7 @@ public WorleyNoiseResult evaluateNoiseResult(double x, double y, double double[] distancesStack = new double[depth]; Arrays.fill(distancesStack, Double.MAX_VALUE); // distancesStack[0] is the shortest distance. - Vector4D closestPoint = null; + double[] closestPoint = new double[4]; for (int xOffset = -1; xOffset <= 1; xOffset++) { long secX = iX + xOffset; @@ -272,7 +265,10 @@ public WorleyNoiseResult evaluateNoiseResult(double x, double y, double } if (distance < distancesStack[0]) { distancesStack[0] = minFunction.applyTo(distance, distancesStack[0]); - closestPoint = new Vector4D(pointX, pointY, pointZ, pointW); + closestPoint[0] = pointX; + closestPoint[1] = pointY; + closestPoint[2] = pointZ; + closestPoint[3] = pointW; } } } @@ -280,30 +276,26 @@ public WorleyNoiseResult evaluateNoiseResult(double x, double y, double } } } - return new WorleyNoiseResult<>(returnDistanceFunction.applyAsDouble(distancesStack), closestPoint); + return new WorleyNoiseResult(returnDistanceFunction.applyAsDouble(distancesStack), closestPoint); } @Override - - public WorleyNoiseResult evaluateNoiseResult(double x) { + public WorleyNoiseResult evaluateNoiseResult(double x) { return evaluateNoiseResult(x, seed); } @Override - - public WorleyNoiseResult evaluateNoiseResult(double x, double y) { + public WorleyNoiseResult evaluateNoiseResult(double x, double y) { return evaluateNoiseResult(x, y, seed); } @Override - - public WorleyNoiseResult evaluateNoiseResult(double x, double y, double z) { + public WorleyNoiseResult evaluateNoiseResult(double x, double y, double z) { return evaluateNoiseResult(x, y, z, seed); } @Override - - public WorleyNoiseResult evaluateNoiseResult(double x, double y, double z, double w) { + public WorleyNoiseResult evaluateNoiseResult(double x, double y, double z, double w) { return evaluateNoiseResult(x, y, z, w, seed); } @@ -317,7 +309,6 @@ public long getSeed() { * * @return {@link WorleyNoiseBuilder}. */ - public static WorleyNoiseBuilder newBuilder() { return new WorleyNoiseBuilder(); } @@ -343,7 +334,6 @@ private WorleyNoiseBuilder() { * @param seed the new seed for the {@link WorleyNoiseGenerator}. * @return {@link WorleyNoiseBuilder} this */ - public WorleyNoiseBuilder setSeed(long seed) { this.seed = seed; return this; @@ -358,7 +348,6 @@ public WorleyNoiseBuilder setSeed(long seed) { * @param depth The new depth for the {@link WorleyNoiseGenerator}. * @return {@link WorleyNoiseBuilder} this */ - public WorleyNoiseBuilder setDepth(int depth) { this.depth = depth; return this; @@ -370,11 +359,7 @@ public WorleyNoiseBuilder setDepth(int depth) { * @param distanceFunction The new {@link DistanceFunction} for the {@link WorleyNoiseGenerator}. * @return {@link WorleyNoiseBuilder} this */ - public WorleyNoiseBuilder setDistanceFunction(DistanceFunction distanceFunction) { - if (distanceFunction == null) { - throw new IllegalArgumentException("Distance function cannot be null."); - } this.distanceFunction = distanceFunction; return this; } @@ -388,11 +373,7 @@ public WorleyNoiseBuilder setDistanceFunction(DistanceFunction distanceFunction) * @param fpAmountFunction The new (feature point amount function) for the {@link WorleyNoiseGenerator} * @return {@link WorleyNoiseBuilder} this */ - public WorleyNoiseBuilder setFeaturePointAmountFunction(IntToLongFunction fpAmountFunction) { - if (fpAmountFunction == null) { - throw new IllegalArgumentException("Featurepoint amount function cannot be null."); - } this.fpAmountFunction = fpAmountFunction; return this; } @@ -407,11 +388,7 @@ public WorleyNoiseBuilder setFeaturePointAmountFunction(IntToLongFunction fpAmou * @param returnDistanceFunction The new return distance function for the {@link WorleyNoiseGenerator}. * @return {@link WorleyNoiseBuilder} this */ - public WorleyNoiseBuilder setReturnDistanceFunction(ReturnDistanceFunction returnDistanceFunction) { - if (returnDistanceFunction == null) { - throw new IllegalArgumentException("Return distance function cannot be null."); - } this.returnDistanceFunction = returnDistanceFunction; return this; } @@ -424,15 +401,11 @@ public WorleyNoiseBuilder setReturnDistanceFunction(ReturnDistanceFunction retur * @return {@link WorleyNoiseBuilder} this */ public WorleyNoiseBuilder setMinFunction(Combiner minFunction) { - if (minFunction == null) { - throw new IllegalArgumentException("Minimization function cannot be null."); - } this.minFunction = minFunction; return this; } @Override - public WorleyNoiseGenerator build() { if (!returnDistanceFunction.isValidArrayLength(depth)) { throw new IllegalArgumentException("Invalid depth for the specified return distance function!"); diff --git a/src/de/articdive/jnoise/generators/noisegen/worley/WorleyNoiseResult.java b/src/de/articdive/jnoise/generators/noisegen/worley/WorleyNoiseResult.java index a9255b659..21afb1a7e 100644 --- a/src/de/articdive/jnoise/generators/noisegen/worley/WorleyNoiseResult.java +++ b/src/de/articdive/jnoise/generators/noisegen/worley/WorleyNoiseResult.java @@ -2,19 +2,18 @@ import de.articdive.jnoise.core.api.modifiers.NoiseModifier; import de.articdive.jnoise.core.api.noisegen.NoiseResult; -import de.articdive.jnoise.core.util.vectors.Vector; /** * This class wraps the result of Worley Noise. * * @author Articdive */ -public final class WorleyNoiseResult implements NoiseResult { - private final V closestPoint; +public final class WorleyNoiseResult implements NoiseResult { + private final double[] closestPoint; private final double unmodifiedValue; private double value; - WorleyNoiseResult(double value, V closestPoint) { + WorleyNoiseResult(double value, double[] closestPoint) { this.unmodifiedValue = value; this.value = value; this.closestPoint = closestPoint; @@ -52,9 +51,9 @@ public double getUnmodifiedValue() { /** * Returns the feature point to the specified noise coordinates. * - * @return {@link V} containing the closest point. + * @return array of double representing the location vector of the closest point. */ - public V getClosestPoint() { + public double[] getClosestPoint() { return closestPoint; } } diff --git a/src/fractalzoomer/bailout_conditions/BailoutCondition.java b/src/fractalzoomer/bailout_conditions/BailoutCondition.java index c43731eb5..1958e2c7e 100644 --- a/src/fractalzoomer/bailout_conditions/BailoutCondition.java +++ b/src/fractalzoomer/bailout_conditions/BailoutCondition.java @@ -46,7 +46,7 @@ protected BailoutCondition(double bound) { if(TaskDraw.PERTURBATION_THEORY || TaskDraw.HIGH_PRECISION_CALCULATION) { ddbound = new MyApfloat(bound); ddcbound = new DoubleDouble(bound); - bnbound = new BigNum(bound); + bnbound = BigNum.create(bound); binbound = new BigIntNum(bound); } diff --git a/src/fractalzoomer/core/BigComplex.java b/src/fractalzoomer/core/BigComplex.java index b8c6f907d..c7358264c 100644 --- a/src/fractalzoomer/core/BigComplex.java +++ b/src/fractalzoomer/core/BigComplex.java @@ -457,6 +457,7 @@ public final BigComplex exp() { /* * 1 / z */ + @Override public final BigComplex reciprocal() { Apfloat temp = MyApfloat.fp.divide(MyApfloat.ONE, MyApfloat.fp.add(MyApfloat.fp.multiply(re, re), MyApfloat.fp.multiply(im, im))); @@ -1081,4 +1082,7 @@ public BigComplex absNegateIm_mutable() { @Override public BigComplex absre_mutable() { return absre(); } + + @Override + public BigComplex toBigComplex() {return this;} } diff --git a/src/fractalzoomer/core/BigIntNum.java b/src/fractalzoomer/core/BigIntNum.java index f1fbb1b92..1c5bb0d6d 100644 --- a/src/fractalzoomer/core/BigIntNum.java +++ b/src/fractalzoomer/core/BigIntNum.java @@ -12,11 +12,15 @@ public class BigIntNum { //This fixed point representation stores 64 bits as the integer part and fracDigits as the fractional part + public static long getPrecision() { + return (long)fracDigits * SHIFT32; + } private static final int INTEGER_PART = 2; private static final int INTEGER_PART_BYTES = INTEGER_PART << 2; public static final int SHIFT8 = 8; public static final int SHIFT32 = 32; + public static final int SHIFT32M1 = SHIFT32 - 1; public static final int MSHIFTP52 = 52 - SHIFT8; @@ -32,8 +36,9 @@ public class BigIntNum { public static int fracDigitsBitsp1 = fracDigitsBits + 1; private static BigIntNum ONESHIFTED = new BigIntNum(ONE.digits.shiftLeft(fracDigitsBits)); - public static int THREADS_THRESHOLD = 265; + public static int THREADS_THRESHOLD = 245; public static boolean use_threads = false; + // public static boolean use_threads2 = false; private long mantissa; private boolean hasMantissa; @@ -41,9 +46,22 @@ public class BigIntNum { public static void reinitialize(double digits) { - int temp = (int)(digits / SHIFT32); + double res = digits / SHIFT32; + int temp = (int) (res); + + if (temp == 0) { + temp = 1; + } else if (digits % SHIFT32 != 0) { + //0 is floor + if(TaskDraw.BIGNUM_INITIALIZATION_ALGORITHM == 1) { //always + temp++; + } + else if (TaskDraw.BIGNUM_INITIALIZATION_ALGORITHM == 2) { //round + temp = (int)(res + 0.5); + } + } - fracDigits = (temp + 1) * TaskDraw.BIGNUM_PRECISION_FACTOR; + fracDigits = temp * TaskDraw.BIGNUM_PRECISION_FACTOR; totalDigits = fracDigits + INTEGER_PART; totalDigitsByteCount = totalDigits << 2; @@ -58,6 +76,7 @@ public static void reinitialize(double digits) { use_threads = TaskDraw.USE_THREADS_IN_BIGNUM_LIBS && fracDigits >= THREADS_THRESHOLD && Runtime.getRuntime().availableProcessors() >= 2; + //use_threads2 = TaskDraw.USE_THREADS_IN_BIGNUM_LIBS && fracDigits >= THREADS_THRESHOLD && Runtime.getRuntime().availableProcessors() >= 3; } public BigIntNum() { @@ -577,7 +596,7 @@ else if(a.compare(oneFourth) < 0) { BigIntNum newX = x.mult(oneHalf.sub(aHalf.mult(x.square()))); // x = (3/2 - (a/2)*x^2)*x byte[] bytes = new byte[totalDigitsByteCount]; - bytes[totalDigitsByteCount - 1] = 0x1F; + bytes[totalDigitsByteCount - 1] = 0x3; BigIntNum epsilon = new BigIntNum(new BigInteger(1, bytes)); int iter = 0; @@ -636,4 +655,52 @@ public boolean isNegative() { return digits.signum() == -1; } + public int getBitLength() { + return digits.bitLength(); + } + + public String bits() { + + String value = ""; + + BigInteger nv = digits.abs(); + + for(int i = 0; i < fracDigits; i++) { + int v = nv.intValue(); + + String temp = ""; + for (int j = SHIFT32M1; j >= 0; j--) { + temp += "" + ((v >>> j) & 0x1); + } + + value = temp + value; + + nv = nv.shiftRight(SHIFT32); + } + + value = "." + value; + + for(int i = 0; i < INTEGER_PART; i++) { + int v = nv.intValue(); + + String temp = ""; + for (int j = SHIFT32M1; j >= 0; j--) { + temp += "" + ((v >>> j) & 0x1); + } + + value = temp + value; + + nv = nv.shiftRight(SHIFT32); + } + + if(digits.signum() == -1) { + value = "-" + value; + } + + return value; + + } + + public Apfloat toApfloat() { return new MyApfloat(bits(), 2).toRadix(10);} + } diff --git a/src/fractalzoomer/core/BigIntNumComplex.java b/src/fractalzoomer/core/BigIntNumComplex.java index 87d1c5b6d..68b40dfab 100644 --- a/src/fractalzoomer/core/BigIntNumComplex.java +++ b/src/fractalzoomer/core/BigIntNumComplex.java @@ -324,6 +324,7 @@ public final BigIntNumComplex i_divide(double number) { } + @Override public final BigIntNumComplex reciprocal() { BigIntNum temp = re.square().add(im.square()).reciprocal(); @@ -634,6 +635,23 @@ public final BigIntNumComplex square_plus_c(GenericComplex cn) { BigIntNumComplex c = (BigIntNumComplex)cn; +// if(BigIntNum.use_threads2) { +// Future temp1 = TaskDraw.reference_thread_executor2.submit(() -> re.square()); +// Future temp2 = TaskDraw.reference_thread_executor2.submit(() -> im.square()); +// Future temp3 = TaskDraw.reference_thread_executor2.submit(() -> re.add(im).square()); +// +// try { +// BigIntNum resqr = temp1.get(); +// BigIntNum imsqr = temp2.get(); +// BigIntNum resqrpimsqr = temp3.get(); +// +// return new BigIntNumComplex(resqr.sub(imsqr).add(c.re), resqrpimsqr.sub(resqr).sub(imsqr).add(c.im)); +// } +// catch (Exception ex) { +// return new BigIntNumComplex(); +// } +// } +// else if(BigIntNum.use_threads) { Future temp1 = TaskDraw.reference_thread_executor.submit(() -> re.add(im).mult(re.sub(im)).add(c.re)); Future temp2 = TaskDraw.reference_thread_executor.submit(() -> re.mult(im).mult2().add(c.im)); @@ -1007,4 +1025,7 @@ public BigIntNumComplex absNegateIm_mutable() { @Override public BigIntNumComplex absre_mutable() { return absre(); } + + @Override + public BigComplex toBigComplex() {return new BigComplex(re.toApfloat(), im.toApfloat());} } diff --git a/src/fractalzoomer/core/BigNum.java b/src/fractalzoomer/core/BigNum.java index e94e69cd6..76b52d591 100644 --- a/src/fractalzoomer/core/BigNum.java +++ b/src/fractalzoomer/core/BigNum.java @@ -1,3689 +1,288 @@ package fractalzoomer.core; import org.apfloat.Apfloat; -import org.apfloat.internal.LongMemoryDataStorage; -import java.util.Arrays; +public abstract class BigNum { + protected int sign; + protected boolean isOne; + protected long scale; + protected int offset; + protected int bitOffset; -import static fractalzoomer.core.MyApfloat.TWO; -import static org.apfloat.internal.LongRadixConstants.BASE_DIGITS; - -public class BigNum { - private int[] digits = null; - private int sign; - private boolean isOne; - private long scale; - private int offset; - private int bitOffset; - public static int fracDigits = 2; - public static int fracDigitsm1 = fracDigits - 1; - public static int fracDigitsp1 = fracDigits + 1; - - public static int fracDigitsHalf = fracDigits >> 1; - - public static final long MASK = 0x3FFFFFFFL; - public static final int MASKINT = 0x3FFFFFFF; - public static final int SHIFT = 30; - public static final long MASKD0 = 0x7FFFFFFFL; - public static final long MASK31 = 0x40000000L; - public static final int SHIFTM1 = SHIFT - 1; - public static final int SHIFTM52 = SHIFT - 52; - public static final int MSHIFTP52 = 52 - SHIFT; - public static boolean useToDouble2 = fracDigits > 120; - public static boolean useKaratsuba = fracDigits > 40; - public static int initialLength = (fracDigits >> 1) - ((fracDigitsp1) % 2); - - public static boolean evenFracDigits = (fracDigits & 1) == 0; - - private static final double TWO_TO_SHIFT = Math.pow(2,-SHIFT); + //protected static boolean use_threads2 = false; public static int SQRT_MAX_ITERATIONS = 30; - public static int THREADS_THRESHOLD = 283; - public static boolean use_threads = false; - - public static void reinitialize(double digits) { - //Lets always have even fracDigits - int temp = (int)(digits / SHIFT); +// public static boolean useThreads2() { +// if(TaskDraw.BUILT_IT_BIGNUM_IMPLEMENTATION == 1) { +// return BigNum64.use_threads2; +// } +// return use_threads2; +// } - if(temp == 0) { - temp = 1; - } - else if(digits % SHIFT != 0) { - temp++; - } + private static int automaticBignumLib; - if((temp & 1) == 0) { - fracDigits = temp * TaskDraw.BIGNUM_PRECISION_FACTOR; - } - else { - fracDigits = (temp + 1) * TaskDraw.BIGNUM_PRECISION_FACTOR; - } - fracDigitsm1 = fracDigits - 1; - fracDigitsp1 = fracDigits + 1; - useToDouble2 = fracDigits > 120; - useKaratsuba = fracDigits > 40; - fracDigitsHalf = fracDigits >> 1; - initialLength = fracDigitsHalf - ((fracDigitsp1) % 2); - evenFracDigits = (fracDigits & 1) == 0; + public static void reinitialize(double digits) { + BigNum30.reinitialize(digits); + BigNum60.reinitialize(digits); + BigNum32.reinitialize(digits); + BigNum64.reinitialize(digits); - use_threads = TaskDraw.USE_THREADS_IN_BIGNUM_LIBS && fracDigits >= THREADS_THRESHOLD && Runtime.getRuntime().availableProcessors() >= 2; + automaticBignumLib = BigNum30.fracDigits >= 62 ? 0 : 1; } public static void reinitializeTest(double digits) { - fracDigits = ((int)(digits / SHIFT) + 1) * TaskDraw.BIGNUM_PRECISION_FACTOR;//should be two if comparing with 64version - - fracDigitsm1 = fracDigits - 1; - fracDigitsp1 = fracDigits + 1; - useToDouble2 = fracDigits > 120; - useKaratsuba = fracDigits > 40; - fracDigitsHalf = fracDigits >> 1; - initialLength = fracDigitsHalf - ((fracDigitsp1) % 2); - evenFracDigits = (fracDigits & 1) == 0; - } - - public static BigNum getMax() { - BigNum n = new BigNum(); - n.digits[0] = (int)MASKD0; - n.sign = 1; - return n; + BigNum30.reinitializeTest(digits); + BigNum60.reinitializeTest(digits); + BigNum32.reinitializeTest(digits); + BigNum64.reinitializeTest(digits); } - public BigNum() { - digits = new int[fracDigitsp1]; - sign = 0; - isOne = false; - scale = 0; - offset = -1; - bitOffset = -1; - } - - public BigNum(BigNum other) { - digits = Arrays.copyOf(other.digits, other.digits.length); - sign = other.sign; - isOne = other.isOne; - scale = 0; - offset = -1; - bitOffset = -1; + private static final String ZEROS = "0000000000000000000000000000000000000000000000000000000000000000"; + public static String toHexString(long l) { + String s = Long.toHexString(l); + return ZEROS.substring(0,16-s.length())+s; } - public BigNum(int val) { - digits = new int[fracDigitsp1]; - digits[0] = val; - isOne = val == 1 || val == -1; - sign = (int)Math.signum(val); - scale = 0; - offset = -1; - bitOffset = -1; + public static String toHexString(int i) { + String s = Integer.toHexString(i).toUpperCase(); + return ZEROS.substring(0,8-s.length())+s; } - public BigNum(double val) { - - digits = new int[fracDigitsp1]; - - scale = 0; - offset = -1; - bitOffset = -1; + protected static int getImplementation() { - if(val == 0 ) { - sign = 0; - isOne = false; - return; + if(TaskDraw.BUILT_IT_BIGNUM_IMPLEMENTATION == 0) { + return automaticBignumLib; } - else if(Math.abs(val) == 1) { - isOne = true; - sign = (int)val; - digits[0] = 1; - return; - } - - sign = (int)Math.signum(val); - val = Math.abs(val); - digits[0] = (int)(val); - double fractionalPart = val - (int) val; - - if(fractionalPart != 0) { - - long bits = Double.doubleToRawLongBits(fractionalPart); - long f_exp = ((bits & 0x7FF0000000000000L) >>> 52) - Double.MAX_EXPONENT; - long mantissa = (bits & 0xFFFFFFFFFFFFFL) | (0x10000000000000L); - - if(f_exp < 0) { - - long posExp = -f_exp; - - int index = (int) (posExp / SHIFT) + 1; - int bitOffset = (int) (posExp % SHIFT); - - if (bitOffset == 0) { - index--; - bitOffset = SHIFT; - } - int k; - int i = index; - for (k = 53; k > 0 && i < digits.length; i++) { - int r; - - if (k > SHIFT) { - - if (k == 53) { - r = MSHIFTP52 + bitOffset; - k -= 53 - r; - } else { - r = k - SHIFT; - k -= SHIFT; - } - - digits[i] = (int) ((mantissa >>> r) & MASK); - } else { - - r = SHIFT - k; - k -= k; - - - //if(r >= 0) { - digits[i] = (int) ((mantissa << r) & MASK); - //} - //else { - // digits[i] = (int) ((mantissa >>> (-r)) & MASK); - // } - } - - } - } - - } + return TaskDraw.BUILT_IT_BIGNUM_IMPLEMENTATION - 1; } - //Has similarities with the double constructor - public BigNum(MantExp inputVal) { - - digits = new int[fracDigitsp1]; - - scale = 0; - offset = -1; - bitOffset = -1; - - inputVal.Normalize(); - double doubleMantissa = inputVal.getMantissa(); - long inputExp = inputVal.getExp(); + public static boolean useThreads() { + int impl = getImplementation(); - if(doubleMantissa == 0) { - sign = 0; - isOne = false; - return; + if(impl == 0) { + return BigNum30.use_threads; } - else if(Math.abs(doubleMantissa) == 1 && inputExp == 0) { - isOne = true; - sign = (int)doubleMantissa; - digits[0] = 1; - return; + else if(impl == 1) { + return BigNum60.use_threads; } - - sign = (int)Math.signum(doubleMantissa); - double val = Math.abs(doubleMantissa); - - - long bits = Double.doubleToRawLongBits(val); - long f_exp = ((bits & 0x7FF0000000000000L) >>> 52) - Double.MAX_EXPONENT; - long mantissa = (bits & 0xFFFFFFFFFFFFFL) | (0x10000000000000L); - - - long totalExp = f_exp + inputExp; - - int index; - int bitOffset; - if(totalExp < 0) { - long posExp = Math.abs(totalExp); - index = (int) (posExp / SHIFT) + 1; - bitOffset = (int) (posExp % SHIFT); + else if (impl == 2){ + return BigNum32.use_threads; } else { - index = (int) (-totalExp / SHIFT); - bitOffset = (int) (totalExp % SHIFT); - } - - - int k; - int i = index; - for (k = 53; k > 0 && i < digits.length; i++) { - int r; - - if (k > SHIFT) { - - if(i == -1) { - i = 0; - r = MSHIFTP52; - k -= 53 - r; - digits[i] = (int) ((mantissa >>> r) & MASKD0); - } - else if(i == 0) { - r = 52 - bitOffset; - k -= 53 - r; - digits[i] = (int) ((mantissa >>> r) & MASKD0); - } - else if (i > 0) { - if (k == 53) { - r = MSHIFTP52 + bitOffset; - k -= 53 - r; - } else { - r = k - SHIFT; - k -= SHIFT; - } - - digits[i] = (int) ((mantissa >>> r) & MASK); - } - } else { - - r = SHIFT - k; - k -= k; - - - //if(r >= 0) { - digits[i] = (int) ((mantissa << r) & MASK); - //} - //else { - // digits[i] = (int) ((mantissa >>> (-r)) & MASK); - // } - } - + return BigNum64.use_threads; } } - public BigNum(String val) { - this(new MyApfloat(val)); - } - - public BigNum(Apfloat val) { - - scale = 0; - this.offset = -1; - bitOffset = -1; - - Apfloat baseTwo = val.toRadix(2); + public static BigNum create() { - sign = baseTwo.getImpl().signum(); - - isOne = false; - - digits = new int[fracDigitsp1]; - - LongMemoryDataStorage str = (LongMemoryDataStorage)baseTwo.getImpl().getDataStorage(); - - if(str == null || sign == 0) { //for zero - return; + int impl = getImplementation(); + if(impl == 0) { + return new BigNum30(); } - - long[] data = str.getData(); - - if(data.length == 1 && data[0] == 1) { - isOne = true; + else if(impl == 1) { + return new BigNum60(); } - - int base_digits = BASE_DIGITS[2]; - - int offset = (int)str.getOffset(); - - int exponent = (int)baseTwo.getImpl().getExponent(); - - if(exponent == 1) { - int index = data.length >= 2 ? 1 : 0; - digits[0] = (int)(MASKD0 & data[index]); - offset++; + else if(impl == 2) { + return new BigNum32(); } - - int dataOffset = exponent < 0 ? Math.abs(exponent) * base_digits : 0; - - for(int i = dataOffset, j = 0; ; i++, j++) { - - int index2 = (i / SHIFT) + 1; - int index = j / base_digits + offset; - - if(index2 >= digits.length || index >= data.length) { - break; - } - - int shift = base_digits - (j % base_digits) - 1; - int bit = (int) ((data[index] >>> shift) & 0x1); - - digits[index2] |= bit << (SHIFT - (i % SHIFT) - 1); + else { + return new BigNum64(); } } - public long getScale() { - - if(sign == 0) { - return Long.MIN_VALUE; + public static BigNum copy(BigNum other) { + if(other instanceof BigNum30) { + return new BigNum30((BigNum30) other); } - - if(offset != -1) { - return scale; + else if(other instanceof BigNum60) { + return new BigNum60((BigNum60) other); } - - int i; - int digit = 0; - for(i = 0; i < digits.length; i++) { - digit = digits[i]; - if(digit != 0) { - break; - } + else if (other instanceof BigNum32){ + return new BigNum32((BigNum32) other); } - - if(i == digits.length) { - return Long.MIN_VALUE; + else { + return new BigNum64((BigNum64) other); } - - /*int r; - for(r = i == 0 ? SHIFT : SHIFTM1; r >= 0; r--) { - if(digits[i] >>> r != 0) { - break; - } - }*/ - - offset = i; - long v = digit; - double d = v & ~(v >>> 1); - //int r = (int)(((Double.doubleToRawLongBits(d) >> 52) & 0x7ff) - 1023); //Fix for the 64 bit, not needed here - bitOffset = (int)((Double.doubleToRawLongBits(d) >> 52) - 1023); - //r |= (r >> 31); //Fix for zero, not needed here - - //bitOffset = 31 - Integer.numberOfLeadingZeros(digit); - - scale = i == 0 ? bitOffset : -(((long)i) * SHIFT) + bitOffset; - - return scale; - } - public static BigNum getNegative(BigNum other) { - - BigNum copy = new BigNum(); - copy.sign = other.sign; - copy.isOne = other.isOne; - - int[] otherDigits = other.digits; - int[] digits = copy.digits; - - int s = (~otherDigits[fracDigits] & MASKINT) + 1; - digits[fracDigits] = s & MASKINT; - for (int i = fracDigitsm1; i > 0 ; i--) { - s = (~otherDigits[i] & MASKINT) + (s>>>SHIFT); - digits[i] = s & MASKINT; + public static BigNum create(int val) { + int impl = getImplementation(); + if(impl == 0) { + return new BigNum30(val); } - - s = (~otherDigits[0]) + (s>>>SHIFT); - digits[0] = s; - - return copy; - } - - public void negSelf() { - - if(sign == 0) { - return; + else if(impl == 1) { + return new BigNum60(val); } - /*if(digits[fracDigits]>0) { - digits[fracDigits] = (int)((digits[fracDigits]-1)^MASK); - for(int i=fracDigits-1; i>0; i--) digits[i] ^= MASK; - digits[0] = ~digits[0]; - } else { - long s = digits[fracDigits-1]-1; digits[fracDigits-1] = (int)(~s&MASK); - for(int i=fracDigits-2; i>0; i--) { - s = digits[i]+(s>>SHIFT); digits[i] = (int)(~s&MASK); - } - digits[0] = (int)(~(digits[0]+(s>>SHIFT))); - }*/ - - int s = (~digits[fracDigits] & MASKINT) + 1; - digits[fracDigits] = s & MASKINT; - for (int i = fracDigitsm1; i > 0 ; i--) { - s = (~digits[i] & MASKINT) + (s>>>SHIFT); - digits[i] = s & MASKINT; + else if(impl == 2) { + return new BigNum32(val); } - - s = (~digits[0]) + (s>>>SHIFT); - digits[0] = s; - - } - - public BigNum negate() { - - BigNum res = new BigNum(this); - - res.sign *= -1; - - return res; - - } - - public BigNum abs() { - - BigNum res = new BigNum(this); - - if(sign == -1) { - res.sign = 1; + else { + return new BigNum64(val); } - - return res; } - public BigNum abs_mutable() { - - if(sign == -1) { - sign = 1; + public static BigNum create(double val) { + int impl = getImplementation(); + if(impl == 0) { + return new BigNum30(val); } - - return this; - } - - @Override - public String toString() { - StringBuilder ret = new StringBuilder((sign == -1 ? "-" : "") + toHexString(digits[0])); - for(int i=1; i<=fracDigits; i++) { - ret.append(i==1 ? "." : " "); - ret.append(toHexString(digits[i])); + else if(impl == 1) { + return new BigNum60(val); } - return doubleValue() + " " + ret.toString(); - } - - public void print() { - - Apfloat sum = MyApfloat.ZERO; - int decimal_bit_count = -1; - - if(sign == -1) { - System.out.print("-"); + else if(impl == 2) { + return new BigNum32(val); } - for (int i = 0; i < digits.length; i++) { - - if (i == 0) { - boolean zero = true; - for (int j = SHIFTM1; j >= 0; j--) { - sum = MyApfloat.fp.add(sum, MyApfloat.fp.multiply(MyApfloat.fp.pow(TWO, j), new MyApfloat((digits[i] >> j) & 0x1))); - - if (((digits[i] >> j) & 0x1) == 1) { - zero = false; - } - - if (!zero) { - System.out.print((digits[i] >> j) & 0x1); - } - } - if(zero) { - System.out.print("0"); - } - System.out.print("."); - } else { - for (int j = SHIFTM1; j >= 0; j--) { - sum = MyApfloat.fp.add(sum, MyApfloat.fp.multiply(MyApfloat.fp.pow(TWO, decimal_bit_count), new MyApfloat((digits[i] >> j) & 0x1))); - decimal_bit_count--; - - System.out.print((digits[i] >> j) & 0x1); - - } - - } + else { + return new BigNum64(val); } - - //sum = MyApfloat.fp.multiply(sum, new MyApfloat(sign)); - - System.out.println(); - //System.out.println(sum.toRadix(2).toString(true)); - //System.out.println(sum); - - - } - public int compare(BigNum other) { - - int signA = sign; - - int[] otherDigits = other.digits; - - int signB = other.sign; - - if(signA < signB) { - return -1; - } - else if(signA > signB) { - return 1; + public static BigNum create(Apfloat val) { + int impl = getImplementation(); + if(impl == 0) { + return new BigNum30(val); } - else {//if(signA == signB) - if (signA == 0) { - return 0; - } - - if(signA < 0) { - for (int i = 0; i < digits.length; i++) { - int digit = digits[i]; - int otherDigit = otherDigits[i]; - if (digit < otherDigit) { - return 1; - } else if (digit > otherDigit) { - return -1; - } - } - } - else { - for (int i = 0; i < digits.length; i++) { - int digit = digits[i]; - int otherDigit = otherDigits[i]; - if (digit < otherDigit) { - return -1; - } else if (digit > otherDigit) { - return 1; - } - } - } + else if(impl == 1) { + return new BigNum60(val); } - - return 0; - - } - - public int compareBothPositive(BigNum other) { - - int signA = sign; - int signB = other.sign; - - if(signA == 0 && signB == 0) { - return 0; + else if(impl == 2) { + return new BigNum32(val); } - - int[] otherDigits = other.digits; - - for (int i = 0; i < digits.length; i++) { - int digit = digits[i]; - int otherDigit = otherDigits[i]; - if (digit < otherDigit) { - return -1; - } else if (digit > otherDigit) { - return 1; - } + else { + return new BigNum64(val); } - - return 0; - } - public double doubleValue2() { - - int[] digits = this.digits; - - int i; - int digit = 0; - for(i = 0; i < digits.length; i++) { - digit = digits[i]; - if(digit != 0) { - break; - } + public static BigNum create(String val) { + int impl = getImplementation(); + if(impl == 0) { + return new BigNum30(val); } - - if(i == digits.length) { - return 0; + else if(impl == 1) { + return new BigNum60(val); } - - /*int r; - for(r = i == 0 ? SHIFT : SHIFTM1; r >= 0; r--) { - if(digits[i] >>> r != 0) { - break; - } - }*/ - - offset = i; - long v = digit; - double d = v & ~(v >>> 1); - //int r = (int)(((Double.doubleToRawLongBits(d) >> 52) & 0x7ff) - 1023); //Fix for the 64 bit, not needed here - bitOffset = (int)((Double.doubleToRawLongBits(d) >> 52) - 1023); - //r |= (r >> 31); //Fix for zero, not needed here - //bitOffset = 31 - Integer.numberOfLeadingZeros(digit); - - scale = i == 0 ? bitOffset : -(((long)i) * SHIFT) + bitOffset; - - if (scale < Double.MIN_EXPONENT) { //accounting for +1 - return 0.0; + else if(impl == 2) { + return new BigNum32(val); } - else if (scale >= Double.MAX_EXPONENT) { - return sign == -1 ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; + else { + return new BigNum64(val); } + } - long mantissa = 0; - - mantissa |= v << (52 - bitOffset); - i++; - - int k; - for(k = bitOffset ; k < 52 && i < digits.length; k+=SHIFT, i++) { - long val = digits[i]; - int temp = 52 - k; - - if(temp > SHIFT) { - mantissa |= val << (temp - SHIFT); - mantissa &= 0xFFFFFFFFFFFFFL; - } - else { - int temp2 = k + SHIFTM52; - mantissa |= val >>> temp2; - mantissa &= 0xFFFFFFFFFFFFFL; + public static long getPrecision() { - if(temp2 == 0 && i + 1 < digits.length) { - long val2 = digits[i + 1]; - mantissa += (val2 >>> (SHIFTM1)) & 0x1; - } - else { - mantissa += (val >>> (temp2 - 1)) & 0x1; - } - } - } + int impl = getImplementation(); - long finalScale = scale + (mantissa >>> 52); - if (finalScale <= Double.MIN_EXPONENT) { - return 0.0; + if(impl == 0) { + return BigNum30.getPrecision(); } - else if (finalScale >= Double.MAX_EXPONENT) { - return sign == -1 ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; + else if(impl == 1) { + return BigNum60.getPrecision(); } - - // Bit 63 (the bit that is selected by the mask 0x8000000000000000L) represents the sign of the floating-point number. - // Bits 62-52 (the bits that are selected by the mask 0x7ff0000000000000L) represent the exponent. - // Bits 51-0 (the bits that are selected by the mask 0x000fffffffffffffL) represent the significand (sometimes called the mantissa) of the floating-point number. - - if(sign == -1) { - return Double.longBitsToDouble( (0x8000000000000000L) | (mantissa & 0xFFFFFFFFFFFFFL) | ((finalScale + Double.MAX_EXPONENT) << 52)); + else if(impl == 2) { + return BigNum32.getPrecision(); } else { - return Double.longBitsToDouble((mantissa & 0xFFFFFFFFFFFFFL) | ((finalScale + Double.MAX_EXPONENT) << 52)); + return BigNum64.getPrecision(); } } - public double doubleValue() { + public static String getName() { + int impl = getImplementation(); - if (sign == 0) { - return 0; + if(impl == 0) { + return BigNum30.getName(); } - - if(isOne) { - return sign; + else if(impl == 1) { + return BigNum60.getName(); } - - if(useToDouble2) { - return doubleValue2(); + else if(impl == 2) { + return BigNum32.getName(); } - - double ret = 0; - - - /*if(digits[0]>=0) { - for(int i=fracDigits; i>=0; i--) { - ret *= TWO_TO_SHIFT; - ret += digits[i]; - } - } else { - ret--; - for(int i=fracDigits; i>0; i--) { - ret += digits[i] - MASK; - ret *= TWO_TO_SHIFT; - } - ret += digits[0]+1; - }*/ - - for(int i=fracDigits; i>=0; i--) { - ret *= TWO_TO_SHIFT; - ret += digits[i]; + else { + return BigNum64.getName(); } - - ret *= sign; - return ret; } - public BigNum add(BigNum a) { - - BigNum result = new BigNum(); - - int[] otherDigits = a.digits; - int otherSign = a.sign; - - int[] resDigits = result.digits; - - int[] digits = this.digits; - int sign = this.sign; - - if(sign == 0 || otherSign == 0) { - if(sign == 0 && otherSign == 0){ - return result; - } - else if(sign == 0) { - result.sign = otherSign; - result.isOne = a.isOne; - System.arraycopy(otherDigits, 0, resDigits, 0, otherDigits.length); - } - else { - result.sign = sign; - result.isOne = isOne; - System.arraycopy(digits, 0, resDigits, 0, digits.length); - } - return result; - } - - if(sign != otherSign) { - if(sign == -1) { - BigNum copy = getNegative(this); - digits = copy.digits; - } - else - { - BigNum copy = getNegative(a); - otherDigits = copy.digits; - } + public static BigNum max(BigNum a, BigNum b) { + if(a instanceof BigNum30) { + return BigNum30.max((BigNum30) a, (BigNum30) b); } - - int s = 0; - int isNonZero = 0; - int temp; - for(int i=fracDigits; i>0; i--) { - s += digits[i] + otherDigits[i]; - temp = s & MASKINT; - isNonZero |= temp; - resDigits[i] = temp; - s >>>= SHIFT; + else if(a instanceof BigNum60) { + return BigNum60.max((BigNum60) a, (BigNum60) b); } - temp = digits[0] + otherDigits[0] + s; - result.isOne = (temp == 1 || temp == -1) && isNonZero == 0; - isNonZero |= temp; - resDigits[0] = temp; - - if(sign != otherSign) { - if(resDigits[0] < 0) { - result.sign = -1; - result.negSelf(); - } - else { - result.sign = isNonZero != 0 ? 1 : 0; - } + else if(a instanceof BigNum32) { + return BigNum32.max((BigNum32) a, (BigNum32) b); } else { - result.sign = isNonZero != 0 ? sign : 0; + return BigNum64.max((BigNum64) a, (BigNum64) b); } - - return result; } - public BigNum add(int a) { - - BigNum result = new BigNum(); - - int otherSign; - if(a == 0) { - otherSign = 0; - } - else if(a < 0) { - otherSign = -1; - } - else { - otherSign = 1; - } - - int otherDigits = a; - - boolean aIsOne = a == 1 || a == -1; + public abstract BigNum negate(); + public abstract BigNum abs(); + public abstract BigNum abs_mutable(); - int[] resDigits = result.digits; + public abstract BigNum square(); - int[] digits = this.digits; - int sign = this.sign; + public abstract BigNum squareFull(); + public abstract BigNum mult(int value); - if(sign == 0 || otherSign == 0) { - if(sign == 0 && otherSign == 0){ - return result; - } - else if(sign == 0) { - result.sign = otherSign; - result.isOne = aIsOne; + public abstract BigNum mult2(); + public abstract BigNum mult4(); + public abstract BigNum divide2(); + public abstract BigNum divide4(); + public abstract BigNum mult(BigNum b); + public abstract int compare(BigNum other); + public abstract int compareBothPositive(BigNum other); - if(otherSign < 0) { - a = ~a + 1; - } + public abstract void negSelf(); - resDigits[0] = a; - } - else { - result.sign = sign; - result.isOne = isOne; - System.arraycopy(digits, 0, resDigits, 0, digits.length); - } - return result; - } + public abstract BigNum sub(BigNum a); + public abstract BigNum sub(int a); + public abstract BigNum add(BigNum a); + public abstract BigNum add(int a); - if(sign != otherSign) { - if(sign == -1) { - BigNum copy = getNegative(this); - digits = copy.digits; - } - } - else { - if(otherSign < 0) { - otherDigits = ~otherDigits + 1; - } - } + public abstract BigNum squareFullGolden(); + public abstract long getScale(); - int isNonZero = 0; - int temp; - for(int i=fracDigits; i>0; i--) { - temp = resDigits[i] = digits[i]; - isNonZero |= temp; - } + public abstract double doubleValueOld(); + public abstract double doubleValue(); - temp = digits[0] + otherDigits; - result.isOne = (temp == 1 || temp == -1) && isNonZero == 0; - isNonZero |= temp; - resDigits[0] = temp; + public abstract MantExp getMantExp(); - if(sign != otherSign) { - if(resDigits[0] < 0) { - result.sign = -1; - result.negSelf(); - } - else { - result.sign = isNonZero != 0 ? 1 : 0; - } - } - else { - result.sign = isNonZero != 0 ? sign : 0; - } + public abstract BigNum mult2toi(long power); + public abstract BigNum div2toi(long power); + public abstract BigNum shift2toi(long power); - return result; + public abstract BigNum sqrt(); + public boolean isPositive() { + //return digits[0] > 0; + return sign == 1; } - /* When sign was not an extra field - public BigNum sub(BigNum a) { - BigNum result = new BigNum(); - - int[] otherDigits = a.digits; - int[] resDigits = result.digits; - long s = 0; - for(int i=fracDigits; i>0; i--) { - s += ((long)digits[i])-((long)otherDigits[i]); resDigits[i] = (int)(s&MASK); s >>= SHIFT; - } - resDigits[0] = (int)(digits[0]-otherDigits[0]+s); - return result; + public boolean isZero() { + return sign == 0; } - public BigNum add(BigNum a) { - BigNum result = new BigNum(); - - int[] otherDigits = a.digits; - int[] resDigits = result.digits; - long s = 0; - for(int i=fracDigits; i>0; i--) { - s += ((long)digits[i])+((long)otherDigits[i]); resDigits[i] = (int)(s&MASK); s >>>= SHIFT; - } - resDigits[0] = (int)(digits[0]+otherDigits[0]+s); - return result; - }*/ - - public BigNum sub(BigNum a) { - - BigNum result = new BigNum(); - - int[] otherDigits = a.digits; - int otherSign = a.sign; - - int[] resDigits = result.digits; - - int[] digits = this.digits; - int sign = this.sign; - - if(sign == 0 || otherSign == 0) { - if(sign == 0 && otherSign == 0){ - return result; - } - else if(sign == 0) { - result.sign = -otherSign; - result.isOne = a.isOne; - System.arraycopy(otherDigits, 0, resDigits, 0, otherDigits.length); - } - else { - result.sign = sign; - result.isOne = isOne; - System.arraycopy(digits, 0, resDigits, 0, digits.length); - } - return result; - } - - if(sign == otherSign) { - // + + -> + - - // - - -> - + - if(sign == -1) { - BigNum copy = getNegative(this); - digits = copy.digits; - } - else { - BigNum copy = getNegative(a); - otherDigits = copy.digits; - } - } - - int s = 0; - int isNonZero = 0; - int temp; - for(int i=fracDigits; i>0; i--) { - s += digits[i] + otherDigits[i]; - temp = s & MASKINT; - isNonZero |= temp; - resDigits[i] = temp; - s >>>= SHIFT; - } - temp = digits[0] + otherDigits[0] + s; - result.isOne = (temp == 1 || temp == -1) && isNonZero == 0; - isNonZero |= temp; - resDigits[0] = temp; - - if(sign == otherSign) { - if(resDigits[0] < 0) { - result.sign = -1; - result.negSelf(); - } - else { - result.sign = isNonZero != 0 ? 1 : 0; - } - } - else { - result.sign = isNonZero != 0 ? sign : 0; - } - - return result; + public boolean isOne() { + return sign == 1 && isOne; } - public BigNum sub(int a) { - - BigNum result = new BigNum(); - - int otherSign; - if(a == 0) { - otherSign = 0; - } - else if(a < 0) { - otherSign = -1; - } - else { - otherSign = 1; - } - - int otherDigits = a; - - boolean aIsOne = a == 1 || a == -1; - - int[] resDigits = result.digits; - - int[] digits = this.digits; - int sign = this.sign; - - if(sign == 0 || otherSign == 0) { - if(sign == 0 && otherSign == 0){ - return result; - } - else if(sign == 0) { - result.sign = -otherSign; - result.isOne = aIsOne; - - if(otherSign < 0) { - a = ~a + 1; - } - - resDigits[0] = a; - } - else { - result.sign = sign; - result.isOne = isOne; - System.arraycopy(digits, 0, resDigits, 0, digits.length); - } - return result; - } - - if(sign == otherSign) { - // + + -> + - - // - - -> - + - if(sign == -1) { - BigNum copy = getNegative(this); - digits = copy.digits; - - if(otherSign < 0) { - otherDigits = ~otherDigits + 1; - } - } - else { - otherDigits = ~otherDigits + 1; - } - } - else { - if(otherSign < 0) { - otherDigits = ~otherDigits + 1; - } - } - - - int isNonZero = 0; - int temp; - for(int i=fracDigits; i>0; i--) { - temp = resDigits[i] = digits[i]; - isNonZero |= temp; - } + public boolean isNegative() { + return sign == -1; + //return digits[0] < 0; + } - temp = digits[0] + otherDigits; - result.isOne = (temp == 1 || temp == -1) && isNonZero == 0; - isNonZero |= temp; - resDigits[0] = temp; + public abstract String bits(); - if(sign == otherSign) { - if(resDigits[0] < 0) { - result.sign = -1; - result.negSelf(); - } - else { - result.sign = isNonZero != 0 ? 1 : 0; - } - } - else { - result.sign = isNonZero != 0 ? sign : 0; - } - - return result; - } - - public BigNum square() { - if(offset <= 15) { - return squareFull(); - } - else { - return squareWithZeroSkip(); - } - } - - public BigNum squareWithZeroSkip() { - - - BigNum result = new BigNum(); - - if(sign == 0) { - return result; - } - - int[] resDigits = result.digits; - - if(isOne) { - resDigits[0] = 1; - result.isOne = true; - result.sign = 1; - return result; - } - - if ((offset << 1) > fracDigits) { - return result; // zero - } - - long old_sum = 0; - - long sum = 0; - - int length = initialLength; - - int j; - int k; - long carry = 0; - long bj; - long ak; - - for (j = 1, k = fracDigits; j <= length; j++, k--) { - bj = digits[j]; - ak = digits[k]; - - sum += bj * ak; - carry += sum >>> SHIFT; - sum &= MASK; - } - - carry <<= 1; - - if(j == k) { - bj = digits[j]; - sum <<= 1; - sum += bj * bj; - } - else { - bj = digits[j]; - ak = digits[k]; - sum += bj * ak; - sum <<= 1; - } - - carry += sum >>> SHIFT; - sum &= MASK; - - - - old_sum = carry + (sum >>> (SHIFTM1)); // Roundish - - int newJStart = offset != -1 ? offset : 0; //To avoid multiplication on zeros - - for(int i = fracDigits; i > 0; i--) { - - sum = old_sum; - - length = (i >> 1) - 1; - - long temp_sum = 0; - carry = 0; - - for(j = newJStart, k = i - newJStart; j <= length; j++, k--) { - bj = digits[j]; - ak = digits[k]; - temp_sum += bj * ak; - carry += temp_sum >>> SHIFT; - temp_sum &= MASK; - } - - carry <<= 1; - - if(j == k) { - bj = digits[j]; - temp_sum <<= 1; - temp_sum += bj * bj; - } - else { - bj = digits[j]; - ak = digits[k]; - temp_sum += bj * ak; - temp_sum <<= 1; - } - - sum += temp_sum; - carry += sum >>> SHIFT; - sum &= MASK; - - - resDigits[i] = (int) (sum); - old_sum = carry; - - if(k <= offset && carry == 0) { - result.sign = 1; - return result; - } - } - - sum = old_sum; - - bj = digits[0]; - sum += bj * bj; - - resDigits[0] = (int) (sum); - result.sign = 1; - - return result; - } - @Deprecated - public BigNum squareFullOLD() { - - - BigNum result = new BigNum(); - - if(sign == 0) { - return result; - } - - int[] resDigits = result.digits; - - if(isOne) { - resDigits[0] = 1; - result.isOne = true; - result.sign = 1; - return result; - } - - long old_sum = 0; - - long sum = 0; - - int length = initialLength; - - int j; - int k; - long carry = 0; - long bj; - long ak; - - for (j = 1, k = fracDigits; j <= length; j++, k--) { - bj = digits[j]; - ak = digits[k]; - - sum += bj * ak; - carry += sum >>> SHIFT; - sum &= MASK; - } - - carry <<= 1; - - if(j == k) { - bj = digits[j]; - sum <<= 1; - sum += bj * bj; - } - else { - bj = digits[j]; - ak = digits[k]; - sum += bj * ak; - sum <<= 1; - } - - carry += sum >>> SHIFT; - sum &= MASK; - - old_sum = carry + (sum >>> (SHIFTM1)); // Roundish - - - for(int i = fracDigits; i > 0; i--) { - - sum = old_sum; - - length = (i >> 1) - 1; - - long temp_sum = 0; - carry = 0; - for(j = 0, k = i; j <= length; j++, k--) { - bj = digits[j]; - ak = digits[k]; - temp_sum += bj * ak; - carry += temp_sum >>> SHIFT; - temp_sum &= MASK; - } - - carry <<= 1; - - if(j == k) { - bj = digits[j]; - temp_sum <<= 1; - temp_sum += bj * bj; - } - else { - bj = digits[j]; - ak = digits[k]; - temp_sum += bj * ak; - temp_sum <<= 1; - } - - sum += temp_sum; - carry += sum >>> SHIFT; - sum &= MASK; - - - resDigits[i] = (int) (sum); - old_sum = carry; - } - - sum = old_sum; - - bj = digits[0]; - sum += bj * bj; - - resDigits[0] = (int) (sum); - result.sign = 1; - - return result; - } - - - public BigNum squareFull() { - - - BigNum result = new BigNum(); - - if(sign == 0) { - return result; - } - - int[] resDigits = result.digits; - - if(isOne) { - resDigits[0] = 1; - result.isOne = true; - result.sign = 1; - return result; - } - - long old_sum = 0; - - long sum = 0; - - int length = initialLength; - - int j; - int k; - long carry = 0; - - long bj; - long ak; - - for (j = 1, k = fracDigits; j <= length; j++, k--) { - bj = digits[j]; - ak = digits[k]; - - sum += bj * ak; - carry += sum >>> SHIFT; - sum &= MASK; - } - - carry <<= 1; - - if(j == k) { - bj = digits[j]; - sum <<= 1; - sum += bj * bj; - } - else { - bj = digits[j]; - ak = digits[k]; - sum += bj * ak; - sum <<= 1; - } - - carry += sum >>> SHIFT; - sum &= MASK; - - old_sum = carry + (sum >>> (SHIFTM1)); // Roundish - - length = fracDigitsHalf; - - for(int i = fracDigits; i > 0; i-=2, length--) { - - long sum1 = old_sum; - long sum2 = 0; - long carry1 = 0; - long carry2 = 0; - long temp_sum1 = 0; - long temp_sum2 = 0; - - k = i; - long prevDigit = digits[k]; - - for(j = 0; j < length; j++) { - bj = digits[j]; - - temp_sum1 += prevDigit * bj; - carry1 += temp_sum1 >>> SHIFT; - temp_sum1 &= MASK; - - k--; - - prevDigit = digits[k]; //ak - - temp_sum2 += prevDigit * bj; - carry2 += temp_sum2 >>> SHIFT; - temp_sum2 &= MASK; - } - - if(evenFracDigits) { - temp_sum1 <<= 1; - temp_sum1 += prevDigit * prevDigit; - - temp_sum2 <<= 1; - } - else { - bj = digits[length]; - - temp_sum1 += prevDigit * bj; - carry1 += temp_sum1 >>> SHIFT; - temp_sum1 &= MASK; - - temp_sum2 <<= 1; - temp_sum2 += bj * bj; - - temp_sum1 <<= 1; - } - - carry1 <<= 1; - carry2 <<= 1; - - sum1 += temp_sum1; - carry1 += sum1 >>> SHIFT; - sum1 &= MASK; - - sum2 += temp_sum2 + carry1; - - - if(i > 1) { - carry2 += sum2 >>> SHIFT; - sum2 &= MASK; - old_sum = carry2; - } - - resDigits[i] = (int) (sum1); - resDigits[i - 1] = (int) (sum2); - - } - - if(evenFracDigits) { - sum = old_sum; - - bj = digits[0]; - sum += bj * bj; - - resDigits[0] = (int) (sum); - } - result.sign = 1; - - return result; - } - - @Deprecated - public BigNum squareKaratsubaOLD() { - - BigNum result = new BigNum(); - - if(sign == 0) { - return result; - } - - int[] resDigits = result.digits; - - if(isOne) { - resDigits[0] = 1; - result.isOne = true; - result.sign = 1; - return result; - } - - long[] partials = new long[fracDigitsp1]; - long[] partialSums = new long[fracDigitsp1]; - long[] partialCarries = new long[fracDigitsp1]; - - long PartialSum = 0; - long PartialCarry = 0; - for(int i = 0; i < fracDigitsp1; i++) { - long temp = digits[i]; - long p = temp * temp; - - partials[i] = p; - PartialSum += p; - - PartialCarry += PartialSum >>> SHIFT; - PartialSum &= MASK; - - partialSums[i] = PartialSum; - partialCarries[i] = PartialCarry; - } - - long old_sum = 0; - - //for(int i = MAX_FRAC_DIGITS; i > 0; i--) { - //long sum += (int)(old_sum >>> SHIFT30); - - //long sum = (old_sum >>> SHIFT31); - - long p0 = partials[0]; - long sum = p0; - - int length = initialLength; - - long aj; - long ak; - - int j; - int k; - long carry = 0; - for (j = 1, k = fracDigits; j <= length; j++, k--) { - aj = digits[j]; - ak = digits[k]; - - - long temp = aj + ak; - - sum += temp * temp; - carry += sum >>> SHIFT; - sum &= MASK; - - //System.out.println("a" + j + " * " + "a " + k); - } - - //System.out.println("OUT"); - //System.out.println("a" + j + " * " + "a " + k); - long temp = 0; - //int diff = k - j; - //int branchlessCheck = (diff >> 31) - (-diff >> 31); - - if(j == k) { - sum += (partials[k] << 1); - } - else { - aj = digits[j]; - ak = digits[k]; - temp = ak + aj; - sum += temp * temp; - } - - carry += sum >>> SHIFT; - sum &= MASK; - - sum -= PartialSum; - carry -= ((sum & MASK31) >>> SHIFT) + PartialCarry; - sum &= MASK; - - old_sum = carry + (sum >>> (SHIFTM1)); // Roundish - - - for(int i = fracDigits; i > 0; i--) { - - sum = old_sum; - - length = (i >> 1) - 1; - - carry = 0; - for(j = 0, k = i; j <= length; j++, k--) { - aj = digits[j]; - ak = digits[k]; - - temp = aj + ak; - - sum += temp * temp; - carry += sum >>> SHIFT; - sum &= MASK; - //System.out.println("a" + j + " * " + "a " + k); - } - - //System.out.println("OUT"); - //System.out.println("a" + j + " * " + "a " + k); - - //System.out.println("NEXT"); - - //diff = k - j; - //branchlessCheck = (diff >> 31) - (-diff >> 31); - - if(j == k) { - sum += (partials[k] << 1); - } - else { - aj = digits[j]; - ak = digits[k]; - temp = ak + aj; - sum += temp * temp; - } - - carry += sum >>> SHIFT; - sum &= MASK; - - sum -= PartialSum; - carry -= ((sum & MASK31) >>> SHIFT) + PartialCarry; - sum &= MASK; - - if(i > 1) { -// long partialI = partials[i]; -// PartialSum -= partialI & MASK; -// PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFT; -// //PartialCarry -= (PartialSum & MASK31)>>> SHIFT; -// //PartialCarry -= partialI >>> SHIFT; -// PartialSum &= MASK; - int im1 = i - 1; - PartialSum = partialSums[im1]; - PartialCarry = partialCarries[im1]; - } - - resDigits[i] = (int) (sum); - //System.out.println(result.digits[i] ); - old_sum = carry; - //System.out.println("NEXT"); - } - - sum = old_sum; - - sum += p0; - - resDigits[0] = (int) (sum); - result.sign = 1; - - return result; - } - - public BigNum squareKaratsuba() { - - BigNum result = new BigNum(); - - if(sign == 0) { - return result; - } - - int[] resDigits = result.digits; - - if(isOne) { - resDigits[0] = 1; - result.isOne = true; - result.sign = 1; - return result; - } - - long[] partials = new long[fracDigitsp1]; - - long PartialSum = 0; - long PartialCarry = 0; - for(int i = 0; i < partials.length; i++) { - long temp = digits[i]; - long p = temp * temp; - - partials[i] = p; - PartialSum += p; - - PartialCarry += PartialSum >>> SHIFT; - PartialSum &= MASK; - } - - long old_sum = 0; - - //for(int i = MAX_FRAC_DIGITS; i > 0; i--) { - //long sum += (int)(old_sum >>> SHIFT30); - - //long sum = (old_sum >>> SHIFT31); - - long p0 = partials[0]; - long sum = p0; - - int length = initialLength; - - long aj; - long ak; - - int j; - int k; - long carry = 0; - for (j = 1, k = fracDigits; j <= length; j++, k--) { - aj = digits[j]; - ak = digits[k]; - - - long temp = aj + ak; - - sum += temp * temp; - carry += sum >>> SHIFT; - sum &= MASK; - - //System.out.println("a" + j + " * " + "a " + k); - } - - //System.out.println("OUT"); - //System.out.println("a" + j + " * " + "a " + k); - long temp = 0; - //int diff = k - j; - //int branchlessCheck = (diff >> 31) - (-diff >> 31); - - if(j == k) { - sum += (partials[k] << 1); - } - else { - aj = digits[j]; - ak = digits[k]; - temp = ak + aj; - sum += temp * temp; - } - - carry += sum >>> SHIFT; - sum &= MASK; - - sum -= PartialSum; - carry -= ((sum & MASK31) >>> SHIFT) + PartialCarry; - sum &= MASK; - - old_sum = carry + (sum >>> (SHIFTM1)); // Roundish - - length = fracDigitsHalf; - - for(int i = fracDigits; i > 0; i-=2, length--) { - - long sum1 = old_sum; - long sum2 = 0; - long carry1 = 0; - long carry2 = 0; - - k = i; - long prevDigit = digits[k]; - - for(j = 0; j < length; j++) { - aj = digits[j]; - - //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); - - temp = prevDigit + aj; - - sum1 += temp * temp; - carry1 += sum1 >>> SHIFT; - sum1 &= MASK; - - k--; - - prevDigit = digits[k]; // ak - - //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); - - temp = prevDigit + aj; - sum2 += temp * temp; - carry2 += sum2 >>> SHIFT; - sum2 &= MASK; - } - - if(evenFracDigits) { - sum1 += (partials[length] << 1); - } - else { - aj = digits[length]; - - temp = prevDigit + aj; - - sum1 += temp * temp; - - //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); - - sum2 += (partials[length] << 1); - carry2 += sum2 >>> SHIFT; - sum2 &= MASK; - } - - carry1 += sum1 >>> SHIFT; - sum1 &= MASK; - - sum1 -= PartialSum; - carry1 -= ((sum1 & MASK31) >>> SHIFT) + PartialCarry; - sum1 &= MASK; - - long partialI = partials[i]; - - PartialSum -= partialI & MASK; - PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFT; - PartialSum &= MASK; - - sum2 += carry1; - carry2 += sum2 >>> SHIFT; - sum2 &= MASK; - - - sum2 -= PartialSum; - - resDigits[i] = (int) (sum1); - - if(i > 1) { - - int im1 = i - 1; - carry2 -= ((sum2 & MASK31) >>> SHIFT) + PartialCarry; - sum2 &= MASK; - - partialI = partials[im1]; - - PartialSum -= partialI & MASK; - PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFT; - PartialSum &= MASK; - - old_sum = carry2; - - resDigits[im1] = (int) (sum2); - } - else { - sum2 &= MASK; - resDigits[0] = (int) (sum2); - } - } - - if(evenFracDigits) { - sum = old_sum; - - sum += p0; - - resDigits[0] = (int) (sum); - } - - result.sign = 1; - - return result; - } - - /* This function has better performance than the normal one after about 3333 digits */ - public BigNum squareFullBackwards() { - - - BigNum result = new BigNum(); - - if(sign == 0) { - return result; - } - - int[] resDigits = result.digits; - - if(isOne) { - resDigits[0] = 1; - result.isOne = true; - result.sign = 1; - return result; - } - - long old_sum = 0; - - long sum = 0; - - int length = initialLength; - - int j; - int k; - long carry = 0; - - long bj; - long ak; - - for (j = 1, k = fracDigits; j <= length; j++, k--) { - bj = digits[j]; - ak = digits[k]; - - sum += bj * ak; - carry += sum >>> SHIFT; - sum &= MASK; - } - - carry <<= 1; - - if(j == k) { - bj = digits[j]; - sum <<= 1; - sum += bj * bj; - } - else { - bj = digits[j]; - ak = digits[k]; - sum += bj * ak; - sum <<= 1; - } - - carry += sum >>> SHIFT; - sum &= MASK; - - old_sum = carry + (sum >>> (SHIFTM1)); // Roundish - - length = fracDigitsHalf; - int length2 = evenFracDigits ? length : length + 1; - - for(int i = fracDigits; i > 0; i-=2, length--, length2--) { - - long sum1 = old_sum; - long sum2 = 0; - long carry1 = 0; - long carry2 = 0; - long temp_sum1 = 0; - long temp_sum2 = 0; - - k = length2; - long prevDigit = digits[k]; - long startDigit = prevDigit; - - for(j = length - 1; j >= 0; j--) { - bj = digits[j]; - - temp_sum2 += prevDigit * bj; - carry2 += temp_sum2 >>> SHIFT; - temp_sum2 &= MASK; - - k++; - - prevDigit = digits[k]; //ak - - temp_sum1 += prevDigit * bj; - carry1 += temp_sum1 >>> SHIFT; - temp_sum1 &= MASK; - } - - if(evenFracDigits) { - temp_sum1 <<= 1; - temp_sum1 += startDigit * startDigit; - - temp_sum2 <<= 1; - } - else { - bj = digits[length]; - - temp_sum1 += startDigit * bj; - carry1 += temp_sum1 >>> SHIFT; - temp_sum1 &= MASK; - - temp_sum2 <<= 1; - temp_sum2 += bj * bj; - - temp_sum1 <<= 1; - } - - carry1 <<= 1; - carry2 <<= 1; - - sum1 += temp_sum1; - carry1 += sum1 >>> SHIFT; - sum1 &= MASK; - - sum2 += temp_sum2 + carry1; - - - if(i > 1) { - carry2 += sum2 >>> SHIFT; - sum2 &= MASK; - old_sum = carry2; - } - - resDigits[i] = (int) (sum1); - resDigits[i - 1] = (int) (sum2); - - } - - if(evenFracDigits) { - sum = old_sum; - - bj = digits[0]; - sum += bj * bj; - - resDigits[0] = (int) (sum); - } - result.sign = 1; - - return result; - } - - /* This function has better performance than the normal one after about 3333 digits */ - public BigNum squareKaratsubaBackwards() { - - BigNum result = new BigNum(); - - if(sign == 0) { - return result; - } - - int[] resDigits = result.digits; - - if(isOne) { - resDigits[0] = 1; - result.isOne = true; - result.sign = 1; - return result; - } - - long[] partials = new long[fracDigitsp1]; - - long PartialSum = 0; - long PartialCarry = 0; - for(int i = 0; i < partials.length; i++) { - long temp = digits[i]; - long p = temp * temp; - - partials[i] = p; - PartialSum += p; - - PartialCarry += PartialSum >>> SHIFT; - PartialSum &= MASK; - } - - long old_sum = 0; - - //for(int i = MAX_FRAC_DIGITS; i > 0; i--) { - //long sum += (int)(old_sum >>> SHIFT30); - - //long sum = (old_sum >>> SHIFT31); - - long p0 = partials[0]; - long sum = p0; - - int length = initialLength; - - long aj; - long ak; - - int j; - int k; - long carry = 0; - for (j = 1, k = fracDigits; j <= length; j++, k--) { - aj = digits[j]; - ak = digits[k]; - - - long temp = aj + ak; - - sum += temp * temp; - carry += sum >>> SHIFT; - sum &= MASK; - - //System.out.println("a" + j + " * " + "a " + k); - } - - //System.out.println("OUT"); - //System.out.println("a" + j + " * " + "a " + k); - long temp = 0; - //int diff = k - j; - //int branchlessCheck = (diff >> 31) - (-diff >> 31); - - if(j == k) { - sum += (partials[k] << 1); - } - else { - aj = digits[j]; - ak = digits[k]; - temp = ak + aj; - sum += temp * temp; - } - - carry += sum >>> SHIFT; - sum &= MASK; - - sum -= PartialSum; - carry -= ((sum & MASK31) >>> SHIFT) + PartialCarry; - sum &= MASK; - - old_sum = carry + (sum >>> (SHIFTM1)); // Roundish - - length = fracDigitsHalf; - int length2 = evenFracDigits ? length : length + 1; - - for(int i = fracDigits; i > 0; i-=2, length--, length2--) { - - long sum1 = old_sum; - long sum2 = 0; - long carry1 = 0; - long carry2 = 0; - - k = length2; - long prevDigit = digits[k]; - long firstDigit = prevDigit; - - for(j = length - 1; j >= 0; j--) { - aj = digits[j]; - - //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); - - temp = prevDigit + aj; - sum2 += temp * temp; - carry2 += sum2 >>> SHIFT; - sum2 &= MASK; - - k++; - - prevDigit = digits[k]; // ak - - //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); - - temp = prevDigit + aj; - sum1 += temp * temp; - carry1 += sum1 >>> SHIFT; - sum1 &= MASK; - } - - if(evenFracDigits) { - sum1 += (partials[length] << 1); - } - else { - aj = digits[length]; - - temp = firstDigit + aj; - - sum1 += temp * temp; - - //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); - - sum2 += (partials[length] << 1); - carry2 += sum2 >>> SHIFT; - sum2 &= MASK; - } - - carry1 += sum1 >>> SHIFT; - sum1 &= MASK; - - sum1 -= PartialSum; - carry1 -= ((sum1 & MASK31) >>> SHIFT) + PartialCarry; - sum1 &= MASK; - - long partialI = partials[i]; - - PartialSum -= partialI & MASK; - PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFT; - PartialSum &= MASK; - - sum2 += carry1; - carry2 += sum2 >>> SHIFT; - sum2 &= MASK; - - - sum2 -= PartialSum; - - resDigits[i] = (int) (sum1); - - if(i > 1) { - - int im1 = i - 1; - carry2 -= ((sum2 & MASK31) >>> SHIFT) + PartialCarry; - sum2 &= MASK; - - partialI = partials[im1]; - - PartialSum -= partialI & MASK; - PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFT; - PartialSum &= MASK; - - old_sum = carry2; - - resDigits[im1] = (int) (sum2); - } - else { - sum2 &= MASK; - resDigits[0] = (int) (sum2); - } - } - - if(evenFracDigits) { - sum = old_sum; - - sum += p0; - - resDigits[0] = (int) (sum); - } - - result.sign = 1; - - return result; - } - - public BigNum mult(BigNum b) { - if(useKaratsuba) { - return multKaratsuba(b); - } - else { - return multFull(b); - } - } - - /* Sign is positive */ - public BigNum mult(int value) { - BigNum result = new BigNum(); - - if(sign == 0 || value == 0) { - return result; - } - - int[] resDigits = result.digits; - - boolean bIsOne = value == 1 || value == -1; - - int bsign; - - if(value < 0) { - bsign = -1; - value = ~value + 1; - } - else { - bsign = 1; - } - - if(isOne || bIsOne) { - if (isOne && bIsOne) { - resDigits[0] = 1; - result.isOne = true; - result.sign = sign * bsign; - } - else if(isOne) { - resDigits[0] = value; - result.sign = sign * bsign; - } - else { - System.arraycopy(digits, 0, resDigits, 0, digits.length); - result.sign = sign * bsign; - } - return result; - } - - long old_sum = 0; - long sum; - long carry; - - int isNonZero = 0; - for(int i = fracDigits; i > 0; i--) { - sum = old_sum; //carry from prev - carry = 0; - - sum += (long)digits[i] * (long)value; - carry += sum >>> SHIFT; - sum &= MASK; - - int di = (int) (sum); - resDigits[i] = di; - isNonZero |= di; - old_sum = carry; - } - - sum = old_sum; - - sum += (long)digits[0] * (long)value; - - int d0 = (int) (sum); - resDigits[0] = d0; - - result.isOne = d0 == 1 && isNonZero == 0; - - result.sign = sign * bsign; - - return result; - } - - @Deprecated - public BigNum multFullOLD(BigNum b) { - - BigNum result = new BigNum(); - - if(sign == 0 || b.sign == 0) { - return result; - } - - int[] bdigits = b.digits; - - int[] resDigits = result.digits; - - if(isOne || b.isOne) { - if (isOne && b.isOne) { - resDigits[0] = 1; - result.isOne = true; - result.sign = sign * b.sign; - } - else if(isOne) { - System.arraycopy(bdigits, 0, resDigits, 0, bdigits.length); - result.sign = sign * b.sign; - } - else { - System.arraycopy(digits, 0, resDigits, 0, digits.length); - result.sign = sign * b.sign; - } - return result; - } - - long old_sum = 0; - - //for(int i = MAX_FRAC_DIGITS; i > 0; i--) { - - //long sum = (old_sum >>> SHIFT31); - // - long sum = 0; - long carry = 0; - long bj; - long ak; - for (int j = 1, k = fracDigits; j <= fracDigits; j++, k--) { - bj = bdigits[j]; - ak = digits[k]; - - sum += bj * ak; - carry += sum >>> SHIFT; - sum &= MASK; - - } - - old_sum = carry + (sum >>> (SHIFTM1)); // Roundish - - //System.out.println(); - //} - - int isNonZero = 0; - for(int i = fracDigits; i > 0; i--) { - - sum = old_sum; //carry from prev - carry = 0; - for(int j = 0, k = i; j <= i; j++, k--) { - bj = bdigits[j]; - ak = digits[k]; - - sum += bj * ak; - carry += sum >>> SHIFT; - sum &= MASK; - - // System.out.println("b" + j + " * " + "a " + k); - } - - int di = (int) (sum); - resDigits[i] = di; - isNonZero |= di; - //System.out.println(result.digits[i] ); - old_sum = carry; - //System.out.println("NEXT"); - } - - sum = old_sum; - - bj = bdigits[0]; - ak = digits[0]; - - sum += bj * ak; - - int d0 = (int) (sum); - resDigits[0] = d0; - - result.isOne = d0 == 1 && isNonZero == 0; - - result.sign = sign * b.sign; - - return result; - - } - - /* A backwards function might have better performance after 3333 digits */ - //Todo: test it - public BigNum multFull(BigNum b) { - - BigNum result = new BigNum(); - - if(sign == 0 || b.sign == 0) { - return result; - } - - int[] bdigits = b.digits; - - int[] resDigits = result.digits; - - if(isOne || b.isOne) { - if (isOne && b.isOne) { - resDigits[0] = 1; - result.isOne = true; - result.sign = sign * b.sign; - } - else if(isOne) { - System.arraycopy(bdigits, 0, resDigits, 0, bdigits.length); - result.sign = sign * b.sign; - } - else { - System.arraycopy(digits, 0, resDigits, 0, digits.length); - result.sign = sign * b.sign; - } - return result; - } - - long old_sum = 0; - - //for(int i = MAX_FRAC_DIGITS; i > 0; i--) { - - //long sum = (old_sum >>> SHIFT31); - // - long sum = 0; - long carry = 0; - long bj; - long ak; - for (int j = 1, k = fracDigits; j <= fracDigits; j++, k--) { - bj = bdigits[j]; - ak = digits[k]; - - sum += bj * ak; - carry += sum >>> SHIFT; - sum &= MASK; - - } - - old_sum = carry + (sum >>> (SHIFTM1)); // Roundish - - //System.out.println(); - //} - - long a0 = digits[0]; - - int isNonZero = 0; - for(int i = fracDigits; i > 0; i-=2) { - int im1 = i - 1; - long sum1 = old_sum; - long sum2 = 0; - long carry1 = 0; - long carry2 = 0; - long temp_sum1 = 0; - long temp_sum2 = 0; - - int k = i; - long prevDigit = digits[k]; - int j; - for(j = 0; j < im1; j++) { - bj = bdigits[j]; - - temp_sum1 += prevDigit * bj; - carry1 += temp_sum1 >>> SHIFT; - temp_sum1 &= MASK; - - k--; - - prevDigit = digits[k]; //ak - - temp_sum2 += prevDigit * bj; - carry2 += temp_sum2 >>> SHIFT; - temp_sum2 &= MASK; - } - - - //Unrolling to fix d0 - bj = bdigits[j]; - - temp_sum1 += prevDigit * bj; - carry1 += temp_sum1 >>> SHIFT; - temp_sum1 &= MASK; - - prevDigit = a0; //ak - - temp_sum2 += prevDigit * bj; - - j++; - - ///// - - bj = bdigits[j]; - - temp_sum1 += prevDigit * bj; - carry1 += temp_sum1 >>> SHIFT; - temp_sum1 &= MASK; - - sum1 += temp_sum1; - carry1 += sum1 >>> SHIFT; - sum1 &= MASK; - - - int di = (int) (sum1); - isNonZero |= di; - resDigits[i] = di; - - - if(i > 1) { - carry2 += temp_sum2 >>> SHIFT; - temp_sum2 &= MASK; - - sum2 += temp_sum2 + carry1; - - carry2 += sum2 >>> SHIFT; - sum2 &= MASK; - old_sum = carry2; - - di = (int) (sum2); - isNonZero |= di; - resDigits[im1] = di; - } - else { - sum2 += temp_sum2 + carry1; - int d0 = (int) (sum2); - resDigits[0] = d0; - result.isOne = d0 == 1 && isNonZero == 0; - } - - } - - if(evenFracDigits) { - sum = old_sum; - - bj = bdigits[0]; - - sum += bj * a0; - - int d0 = (int) (sum); - resDigits[0] = d0; - - result.isOne = d0 == 1 && isNonZero == 0; - } - - result.sign = sign * b.sign; - - return result; - - } - - @Deprecated - public BigNum multKaratsubaOLD(BigNum b) { - - BigNum result = new BigNum(); - - if(sign == 0 || b.sign == 0) { - return result; - } - - int[] bdigits = b.digits; - int[] resDigits = result.digits; - - if(isOne || b.isOne) { - if (isOne && b.isOne) { - resDigits[0] = 1; - result.isOne = true; - result.sign = sign * b.sign; - } - else if(isOne) { - System.arraycopy(bdigits, 0, resDigits, 0, bdigits.length); - result.sign = sign * b.sign; - } - else { - System.arraycopy(digits, 0, resDigits, 0, digits.length); - result.sign = sign * b.sign; - } - return result; - } - - long[] partials = new long[fracDigitsp1]; - long[] partialSums = new long[fracDigitsp1]; - long[] partialCarries = new long[fracDigitsp1]; - - long PartialSum = 0; - long PartialCarry = 0; - for (int i = 0; i < fracDigitsp1; i++) { - long p = ((long) digits[i]) * ((long) bdigits[i]); - partials[i] = p; - PartialSum += p; - - PartialCarry += PartialSum >>> SHIFT; - PartialSum &= MASK; - - partialSums[i] = PartialSum; - partialCarries[i] = PartialCarry; - } - - - long old_sum = 0; - - long p0 = partials[0]; - - long sum = p0; - - int length = initialLength; - - int j; - int k; - long carry = 0; - long bj, bk, aj, ak; - for (j = 1, k = fracDigits; j <= length; j++, k--) { - bj = bdigits[j]; - bk = bdigits[k]; - aj = digits[j]; - ak = digits[k]; - - sum += (bk + bj) * (ak + aj); - carry += sum >>> SHIFT; - sum &= MASK; - - //System.out.println("partials " + k + " partials " + j); - - } - - //System.out.println("partials " + k + " partials " + j); - - //System.out.println("Next"); - - //int diff = k - j; - //int branchlessCheck = (diff >> 31) - (-diff >> 31); - - - //System.out.println("partials " + k + " partials " + j); - - //System.out.println("NEXT"); - - //System.out.println("OUT"); - //System.out.println("b" + j + " * " + "a " + k); - - if(j == k) { - sum += (partials[k] << 1); - } - else { - bj = bdigits[j]; - bk = bdigits[k]; - aj = digits[j]; - ak = digits[k]; - sum += (bk + bj) * (ak + aj); - } - - carry += sum >>> SHIFT; - sum &= MASK; - - sum -= PartialSum; - carry -= ((sum & MASK31) >>> SHIFT) + PartialCarry; - sum &= MASK; - - //sum += (1 - branchlessCheck) * partials[k] + branchlessCheck * ((bk + bj) * (ak + aj) - partials[k] - partials[j]); - - old_sum = carry + (sum >>> (SHIFTM1)); // Roundish, adds bias because 10000 is always shifted upwards - - - int isNonZero = 0; - for(int i = fracDigits; i > 0; i--) { - - length = (i >> 1) - 1; - - sum = old_sum; //carry from prev - - carry = 0; - for(j = 0, k = i; j <= length; j++, k--) { - bj = bdigits[j]; - bk = bdigits[k]; - aj = digits[j]; - ak = digits[k]; - - sum += (bk + bj) * (ak + aj); - - carry += sum >>> SHIFT; - sum &= MASK; - //System.out.println("partials " + k + " partials " + j); - //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); - - } - - if(j == k) { - sum += (partials[k] << 1); - } - else { - bj = bdigits[j]; - bk = bdigits[k]; - aj = digits[j]; - ak = digits[k]; - //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); - sum += (bk + bj) * (ak + aj); - } - - //System.out.println("NEXT"); - - carry += sum >>> SHIFT; - sum &= MASK; - - sum -= PartialSum; - carry -= ((sum & MASK31) >>> SHIFT) + PartialCarry; - sum &= MASK; - - if(i > 1) { - int im1 = i - 1; - PartialSum = partialSums[im1]; - PartialCarry = partialCarries[im1]; - - //long partialI = partials[i]; - - //PartialSum -= partialI & MASK; - //PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFT; - //PartialSum &= MASK; - } - - - //System.out.println("partials " + k + " partials " + j); - //System.out.println("NEXT"); - - - int di = (int) (sum); - isNonZero |= di; - resDigits[i] = di; - //System.out.println(result.digits[i] ); - old_sum = carry; - //System.out.println("NEXT"); - } - - sum = old_sum; - - sum += p0; - - int d0 = (int) (sum); - resDigits[0] = d0; - - result.sign = sign * b.sign; - - result.isOne = d0 == 1 && isNonZero == 0; - - return result; - - } - - public BigNum multKaratsuba(BigNum b) { - - BigNum result = new BigNum(); - - if(sign == 0 || b.sign == 0) { - return result; - } - - int[] bdigits = b.digits; - int[] resDigits = result.digits; - - if(isOne || b.isOne) { - if (isOne && b.isOne) { - resDigits[0] = 1; - result.isOne = true; - result.sign = sign * b.sign; - } - else if(isOne) { - System.arraycopy(bdigits, 0, resDigits, 0, bdigits.length); - result.sign = sign * b.sign; - } - else { - System.arraycopy(digits, 0, resDigits, 0, digits.length); - result.sign = sign * b.sign; - } - return result; - } - - long[] partials = new long[fracDigitsp1]; - - long PartialSum = 0; - long PartialCarry = 0; - for(int i = 0; i < partials.length; i++) { - long p = ((long)digits[i]) * ((long)bdigits[i]); - partials[i] = p; - PartialSum += p; - - PartialCarry += PartialSum >>> SHIFT; - PartialSum &= MASK; - } - - long old_sum = 0; - - long p0 = partials[0]; - - long sum = p0; - - int length = initialLength; - - int j; - int k; - long carry = 0; - long bj, bk, aj, ak; - for (j = 1, k = fracDigits; j <= length; j++, k--) { - bj = bdigits[j]; - bk = bdigits[k]; - aj = digits[j]; - ak = digits[k]; - - sum += (bk + bj) * (ak + aj); - carry += sum >>> SHIFT; - sum &= MASK; - - //System.out.println("partials " + k + " partials " + j); - - } - - if(j == k) { - sum += (partials[k] << 1); - } - else { - bj = bdigits[j]; - bk = bdigits[k]; - aj = digits[j]; - ak = digits[k]; - sum += (bk + bj) * (ak + aj); - } - - carry += sum >>> SHIFT; - sum &= MASK; - - sum -= PartialSum; - carry -= ((sum & MASK31) >>> SHIFT) + PartialCarry; - sum &= MASK; - - old_sum = carry + (sum >>> (SHIFTM1)); // Roundish, adds bias because 10000 is always shifted upwards - - - int isNonZero = 0; - - length = fracDigitsHalf; - int length2 = evenFracDigits ? length : length + 1; - - for(int i = fracDigits; i > 0; i-=2, length--, length2--) { - - long sum1 = old_sum; - long sum2 = 0; - long carry1 = 0; - long carry2 = 0; - - k = length2; - long prevDigit = digits[k]; - long prevDigit2 = bdigits[k]; - long startDigit = prevDigit; - long startDigit2 = prevDigit2; - - for(j = length - 1; j >= 0; j--) { - aj = digits[j]; - bj = bdigits[j]; - - //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); - - sum2 += (prevDigit2 + bj) * (prevDigit + aj); - carry2 += sum2 >>> SHIFT; - sum2 &= MASK; - - k++; - - prevDigit = digits[k]; //ak - prevDigit2 = bdigits[k]; //bk - - //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); - - sum1 += (prevDigit2 + bj) * (prevDigit + aj); - carry1 += sum1 >>> SHIFT; - sum1 &= MASK; - - } - - if(evenFracDigits) { - sum1 += (partials[length] << 1); - } - else { - aj = digits[length]; - bj = bdigits[length]; - - sum1 += (startDigit2 + bj) * (startDigit + aj); - - //System.out.println("b " + length + " b " + length2 + " a " + length + " a " + length2); - - sum2 += (partials[length] << 1); - carry2 += sum2 >>> SHIFT; - sum2 &= MASK; - } - - //System.out.println("NEXT"); - - carry1 += sum1 >>> SHIFT; - sum1 &= MASK; - - sum1 -= PartialSum; - carry1 -= ((sum1 & MASK31) >>> SHIFT) + PartialCarry; - sum1 &= MASK; - - long partialI = partials[i]; - - PartialSum -= partialI & MASK; - PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFT; - PartialSum &= MASK; - - sum2 += carry1; - carry2 += sum2 >>> SHIFT; - sum2 &= MASK; - - - sum2 -= PartialSum; - - int di = (int) (sum1); - isNonZero |= di; - resDigits[i] = di; - - if(i > 1) { - - int im1 = i - 1; - carry2 -= ((sum2 & MASK31) >>> SHIFT) + PartialCarry; - sum2 &= MASK; - - partialI = partials[im1]; - - PartialSum -= partialI & MASK; - PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFT; - PartialSum &= MASK; - - old_sum = carry2; - - di = (int) (sum2); - isNonZero |= di; - resDigits[im1] = di; - } - else { - sum2 &= MASK; - int d0 = (int) (sum2); - resDigits[0] = d0; - result.isOne = d0 == 1 && isNonZero == 0; - } - } - - if(evenFracDigits) { - sum = old_sum; - - sum += p0; - - int d0 = (int) (sum); - resDigits[0] = d0; - - //result.isOne = ( (((d0 ^ isNonZero) | d0) & ~(isNonZero & 0x1)) ) == 1 - result.isOne = d0 == 1 && isNonZero == 0; - } - - result.sign = sign * b.sign; - - return result; - - } - - /*mult2, mult4, divide2, divide4, multFull, multKaratsuba, square and squareKaratsuba - might overflow or underflow leading to zero but the sign will not be set to 0 - */ - - public BigNum mult2() { - - BigNum res = new BigNum(); - - if(sign == 0) { - return res; - } - - int [] resDigits = res.digits; - - if(isOne) { - resDigits[0] = 2; - res.sign = sign; - return res; - } - - int isNonZero = 0; - - int temp = digits[fracDigits] << 1; - int val = temp & MASKINT; - resDigits[fracDigits] = val; - isNonZero |= val; - - for(int i = fracDigitsm1; i > 0; i--) { - temp = (digits[i] << 1) | (temp >>> SHIFT); - val = temp & MASKINT; - resDigits[i] = val; - isNonZero |= val; - } - - temp = (digits[0] << 1) | (temp >>> SHIFT); - resDigits[0] = (int)(temp & MASKD0); - res.sign = sign; - res.isOne = temp == 1 && isNonZero == 0; - return res; - - } - - public BigNum divide2() { - - BigNum res = new BigNum(); - - if(sign == 0) { - return res; - } - - int [] resDigits = res.digits; - - if(isOne) { - resDigits[1] = 0x20000000; - res.sign = sign; - return res; - } - - int isNonZero = 0; - - int d0 = digits[0]; - int temp = d0; - int val = temp >>> 1; - - int bit = temp & 0x1; - - resDigits[0] = val; - isNonZero |= val; - - for(int i=1; i < fracDigits; i++) { - temp = digits[i]; - temp |= (bit << SHIFT); - bit = temp & 0x1; - temp >>>= 1; - val = temp & MASKINT; - resDigits[i] = val; - isNonZero |= val; - } - - temp = digits[fracDigits]; - temp |= (bit << SHIFT); - temp >>>= 1; - resDigits[fracDigits] = temp & MASKINT; - res.sign = sign; - res.isOne = d0 == 1 && isNonZero == 0; - return res; - - } - - public BigNum divide4() { - - BigNum res = new BigNum(); - - if(sign == 0) { - return res; - } - - int [] resDigits = res.digits; - - if(isOne) { - resDigits[1] = 0x10000000; - res.sign = sign; - return res; - } - - int isNonZero = 0; - - int d0 = digits[0]; - int temp = d0; - int val = temp >>> 2; - - int bits = temp & 0x3; - - resDigits[0] = val; - isNonZero |= val; - - for(int i=1; i < fracDigits; i++) { - temp = digits[i]; - temp |= (bits << SHIFT); - bits = temp & 0x3; - temp >>>= 2; - val = temp & MASKINT; - resDigits[i] = val; - isNonZero |= val; - } - - temp = digits[fracDigits]; - temp |= (bits << SHIFT); - temp >>>= 2; - resDigits[fracDigits] = temp & MASKINT; - res.sign = sign; - res.isOne = d0 == 1 && isNonZero == 0; - return res; - - } - - public BigNum mult4() { - - BigNum res = new BigNum(); - - if(sign == 0) { - return res; - } - - int [] resDigits = res.digits; - - if(isOne) { - resDigits[0] = 4; - res.sign = sign; - return res; - } - - int isNonZero = 0; - - int temp = digits[fracDigits] << 2; - int val = temp & MASKINT; - resDigits[fracDigits] = val; - isNonZero |= val; - - for(int i=fracDigitsm1; i > 0; i--) { - temp = (digits[i] << 2) | (temp >>> SHIFT); - val = temp & MASKINT; - resDigits[i] = val; - isNonZero |= val; - } - - temp = (digits[0] << 2) | (temp >>> SHIFT); - resDigits[0] = (int)(temp & MASKD0); - res.sign = sign; - res.isOne = temp == 1 && isNonZero == 0; - return res; - - } - - public boolean isPositive() { - //return digits[0] > 0; - return sign == 1; - } - public boolean isZero() { - return sign == 0; - } - - public boolean isOne() { - return sign == 1 && isOne; - } - - public boolean isNegative() { - return sign == -1; - //return digits[0] < 0; - } - - private static final String ZEROS = "0000000000000000000000000000000000000000000000000000000000000000"; - - public static String toHexString(int i) { - String s = Integer.toHexString(i).toUpperCase(); - return ZEROS.substring(0,8-s.length())+s; - } - - /* - Too slow - */ - public BigNum divide(BigNum b) { - - if(b.sign == 0) { - BigNum result = getMax(); - result.sign = sign; - } - - BigNum result = new BigNum(); - - if(sign == 0) { - return result; - } - - if (isOne && b.isOne) { - result.digits[0] = 1; - result.isOne = true; - result.sign = sign * b.sign; - return result; - } - else if (b.isOne){ - System.arraycopy(digits, 0, result.digits, 0, digits.length); - result.sign = sign * b.sign; - return result; - } - - BigNum low = new BigNum(); - BigNum high = this.compare(b) < 0 ? new BigNum(1) : new BigNum(0x7fffffff); - - BigNum oldVal = null; - - //int iterations = 0; - - while (true) { - BigNum mid = low.add(high.sub(low).divide2()); - - BigNum temp = b.mult(mid); - - BigNum val = temp.sub(this); - - if(oldVal != null && val.compare(oldVal) == 0) { - result.digits = mid.digits; - result.sign = sign * b.sign; - result.isOne = result.digits[0] == 1 && isFractionalPartZero(result.digits); - return result; - } - - oldVal = val; - - if(temp.compare(this) < 0) { - low = mid; - } - else { - high = mid; - } - //iterations++; - } - - - } - - /* - Too slow - */ - public BigNum reciprocal() { - - if(sign == 0) { - BigNum result = getMax(); - result.sign = sign; - } - - BigNum result = new BigNum(); - - if (isOne) { - result.digits[0] = 1; - result.isOne = true; - result.sign = sign; - return result; - } - - BigNum low = new BigNum(); - BigNum high = digits[0] != 0 ? new BigNum(1) : new BigNum(0x7fffffff); - - BigNum oldVal = null; - - BigNum one = new BigNum(1); - - while (true) { - BigNum mid = low.add(high.sub(low).divide2()); - - BigNum temp = this.mult(mid); - - BigNum val = temp.sub(one); - - if(oldVal != null && val.compare(oldVal) == 0) { - result.digits = mid.digits; - result.sign = sign; - result.isOne = result.digits[0] == 1 && isFractionalPartZero(result.digits); - return result; - } - - oldVal = val; - - if(temp.compare(one) < 0) { - low = mid; - } - else { - high = mid; - } - } - - - } - - public MantExp getMantExp() { - - if (sign == 0) { - return new MantExp(); - } - - if(isOne) { - return new MantExp(sign); - } - - int[] digits = this.digits; - - if(offset == -1) { - int i; - int digit = 0; - for (i = 0; i < digits.length; i++) { - digit = digits[i]; - if (digit != 0) { - break; - } - } - - if (i == digits.length) { - return new MantExp(); - } - - /*int r; - for(r = i == 0 ? SHIFT : SHIFTM1; r >= 0; r--) { - if(digits[i] >>> r != 0) { - break; - } - }*/ - - offset = i; - long v = digit; - double d = v & ~(v >>> 1); - //int r = (int)(((Double.doubleToRawLongBits(d) >> 52) & 0x7ff) - 1023); //Fix for the 64 bit, not needed here - bitOffset = (int) ((Double.doubleToRawLongBits(d) >> 52) - 1023); - //r |= (r >> 31); //Fix for zero, not needed here - - //bitOffset = 31 - Integer.numberOfLeadingZeros(digit); - - scale = i == 0 ? bitOffset : -(((long) i) * SHIFT) + bitOffset; - } - - int i = offset; - long mantissa = 0; - - int temp = 52 - bitOffset; - mantissa |= ((long)digits[i]) << temp; //Will always be positive - mantissa &= 0xFFFFFFFFFFFFFL; - - //System.out.println(digits[i]); - - i++; - - int k; - for(k = bitOffset ; k < 52 && i < digits.length; k+=SHIFT, i++) { - long val = digits[i]; - temp = 52 - k; - - if(temp > SHIFT) { - mantissa |= val << (temp - SHIFT); - mantissa &= 0xFFFFFFFFFFFFFL; - } - else { - int temp2 = k + SHIFTM52; - mantissa |= val >>> temp2; - mantissa &= 0xFFFFFFFFFFFFFL; - - if(temp2 == 0 && i + 1 < digits.length) { - long val2 = digits[i + 1]; - mantissa += (val2 >>> (SHIFTM1)) & 0x1; //Rounding - } - else { - mantissa += (val >>> (temp2 - 1)) & 0x1; //Rounding - } - } - } - - // Bit 63 (the bit that is selected by the mask 0x8000000000000000L) represents the sign of the floating-point number. - // Bits 62-52 (the bits that are selected by the mask 0x7ff0000000000000L) represent the exponent. - // Bits 51-0 (the bits that are selected by the mask 0x000fffffffffffffL) represent the significand (sometimes called the mantissa) of the floating-point number. - - int exp = (int)(scale + (mantissa >>> 52)); - double mantissaDouble; - - if(sign == -1) { - mantissaDouble = Double.longBitsToDouble( (0x8000000000000000L) | (mantissa & 0xFFFFFFFFFFFFFL) | (0x3FF0000000000000L)); - } - else { - mantissaDouble = Double.longBitsToDouble((mantissa & 0xFFFFFFFFFFFFFL) | (0x3FF0000000000000L)); - } - - return new MantExp(exp, mantissaDouble); - - - - } - - public static boolean isFractionalPartZero(int[] digits) { - - for(int i = 1; i < digits.length; i++) { - if(digits[i] != 0) { - return false; - } - } - - return true; - } - - public static BigNum max(BigNum a, BigNum b) { - return a.compare(b) > 0 ? a : b; - } - - public static BigNum min(BigNum a, BigNum b) { - return a.compare(b) < 0 ? a : b; - } - - public BigNum mult2to30(int times) { - - BigNum result = new BigNum(this); - - if(times <= 0) { - return result; - } - - int[] digits = result.digits; - int total = digits.length + times; - int isNonZero = 0; - - for(int i = times, location = 0; i < total; i++, location++) { - if(i < digits.length) { - if(location == 0) { - int value = digits[i - 1]; - int finalValue = digits[i]; - finalValue |= (value & 0x1) << SHIFT; - digits[location] = finalValue; - } - else { - digits[location] = digits[i]; - } - } - else { - int im1 = i - 1; - if(location == 0 && im1 < digits.length) { - int value = digits[im1]; - int finalValue = (value & 0x1) << SHIFT; - digits[location] = finalValue; - } - else { - digits[location] = 0; - } - } - - if(location != 0) { - isNonZero |= digits[location]; - } - } - - result.isOne = digits[0] == 1 && isNonZero == 0; - return result; - } - - public BigNum div2toi(long power) { - BigNum result = new BigNum(this); - - if(power <= 0) { - return result; - } - - int times = (int)(power / SHIFT); - - int internalShift = (int)(power % SHIFT); - - int[] digits = result.digits; - int total = -times; - int isNonZero = 0; - - for(int i = digits.length - 1 - times, location = digits.length - 1; i >= total; i--, location--) { - if(i >= 0) { - int value = digits[i] >>> internalShift; - - if(value > MASKINT) { - if(location != 0) { - digits[location] = value & MASKINT; - } - else { - digits[location] = value; - } - - i--; - location--; - if(location >= 0) { - digits[location] = 0x1; - } - } - else { - int finalValue = value; - int im1 = i - 1; - if(im1 >= 0) { - int diff = SHIFT - internalShift; - finalValue |= (digits[im1] & (0xFFFFFFFF >>> diff)) << diff; - } - if(location == 0) { - digits[location] = (int) (finalValue & MASKD0); - } - else { - digits[location] = finalValue & MASKINT; - } - } - } - else { - int ip1 = i + 1; - if(ip1 == 0 && (digits[ip1] >>> internalShift) > MASKINT) { - digits[location] = 0x1; - } - else { - digits[location] = 0; - } - } - - if(location != 0) { - isNonZero |= digits[location]; - } - } - - result.isOne = digits[0] == 1 && isNonZero == 0; - return result; - } - - public BigNum mult2toi(long power) { - - BigNum result = new BigNum(this); - - if(power <= 0) { - return result; - } - - int times = (int)(power / SHIFT); - - int internalShift = (int)(power % SHIFT); - - int[] digits = result.digits; - int total = digits.length + times; - int isNonZero = 0; - - for(int i = times, location = 0; i < total; i++, location++) { - if(i < digits.length) { - - int value = digits[i] << internalShift; - - int im1 = i - 1; - if(location == 0 && im1 >= 0 && internalShift == 0) { - value |= (digits[im1] & 0x1) << SHIFT; - } - - int ip1 = i + 1; - if(ip1 < digits.length) { - value |= digits[ip1] >>> (SHIFT - internalShift); - } - if(location == 0) { - digits[location] = (int)(value & MASKD0); - } - else { - digits[location] = value & MASKINT; - } - - } - else { - int im1 = i - 1; - if(location == 0 && im1 < digits.length && internalShift == 0) { - int value = (digits[im1] & 0x1) << SHIFT; - digits[location] = (int)(value & MASKD0); - } - else { - digits[location] = 0; - } - } - - if(location != 0) { - isNonZero |= digits[location]; - } - } - - result.isOne = digits[0] == 1 && isNonZero == 0; - return result; - } - - public BigNum divide2to30(int times) { - - BigNum result = new BigNum(this); - - if(times <= 0) { - return result; - } - - int[] digits = result.digits; - int total = -times; - int isNonZero = 0; - - for(int i = digits.length - 1 - times, location = digits.length - 1; i >= total; i--, location--) { - if(i >= 0) { - int value = digits[i]; - - if(value > MASKINT) { - digits[location] = value & MASKINT; - i--; - location--; - digits[location] = 0x1; - } - else { - digits[location] = value; - } - } - else { - int ip1 = i + 1; - if(ip1 == 0 && digits[ip1] > MASKINT) { - digits[location] = 0x1; - } - else { - digits[location] = 0; - } - } - - if(location != 0) { - isNonZero |= digits[location]; - } - } - - result.isOne = digits[0] == 1 && isNonZero == 0; - return result; - } - - public BigNum shift2to30(int times) { - if(times > 0) { - return mult2to30(times); - } - else if(times < 0) { - return divide2to30(-times); - } - - return new BigNum(this); - } - - public BigNum shift2toi(long power) { - if(power > 0) { - return mult2toi(power); - } - else if(power < 0) { - return div2toi(-power); - } - - return new BigNum(this); - } - - public BigNum sqrt() { - if(sign == 0 || isOne) { - return new BigNum(this); - } - if(sign < 0) { - return new BigNum(); - } - BigNum one = new BigNum(1); - BigNum oneFourth = new BigNum(0.25); - - BigNum a = new BigNum(this); - long divisions = 0; - long multiplications = 0; - if(a.compareBothPositive(one) > 0) { //scale it down between 1 and 1/4 - do { - a = a.divide4(); - divisions++; - } while (a.compareBothPositive(one) > 0); - } - else if(a.compareBothPositive(oneFourth) < 0) { - - int i; - - int[] digits = a.digits; - for(i = 2; i < digits.length; i++) { - if(digits[i] != 0) { - break; - } - } - - int numberOfLimbs = i - 2; - int multiplesOfTwo = numberOfLimbs >>> 1; - - if(multiplesOfTwo > 0) { - int temp = multiplesOfTwo << 1; - multiplications += ((long)temp * SHIFT) >>> 1; - a = a.mult2to30(temp); - } - - do { - a = a.mult4(); - multiplications++; - } while (a.compareBothPositive(oneFourth) < 0); - } - - BigNum oneHalf = new BigNum(1.5); - BigNum aHalf = a.divide2(); // a / 2 - - BigNum x = new BigNum(1 / Math.sqrt(a.doubleValue())); // set the initial value to an approximation of 1 /sqrt(a) - - //Newton steps - BigNum newX = x.mult(oneHalf.sub(aHalf.mult(x.squareFull()))); // x = (3/2 - (a/2)*x^2)*x - - BigNum epsilon = new BigNum(1); - epsilon.digits[epsilon.digits.length - 1] = 0x1F; - epsilon.digits[0] = 0; - - int iter = 0; - while (newX.sub(x).abs_mutable().compareBothPositive(epsilon) >= 0 && iter < SQRT_MAX_ITERATIONS) { - x = newX; - newX = x.mult(oneHalf.sub(aHalf.mult(x.squareFull()))); - iter++; - } - - BigNum sqrta = newX.mult(a); //sqrt(a) = a * (1 /sqrt(a)); - if(multiplications > 0) { //scale it up again - sqrta = sqrta.div2toi(multiplications); - } - else if(divisions > 0) { - sqrta = sqrta.mult2toi(divisions); - } - - return sqrta; - } + public Apfloat toApfloat() { return new MyApfloat(bits(), 2).toRadix(10);} } diff --git a/src/fractalzoomer/core/BigNum30.java b/src/fractalzoomer/core/BigNum30.java new file mode 100644 index 000000000..8dd380b33 --- /dev/null +++ b/src/fractalzoomer/core/BigNum30.java @@ -0,0 +1,4727 @@ +package fractalzoomer.core; + +import org.apfloat.Apfloat; +import org.apfloat.internal.LongMemoryDataStorage; + +import java.util.Arrays; + +import static fractalzoomer.core.MyApfloat.TWO; +import static org.apfloat.internal.LongRadixConstants.BASE_DIGITS; + +public class BigNum30 extends BigNum { + + public static long getPrecision() { + return (long)fracDigits * SHIFT; + } + public static String getName() { + return "Built-in (30)"; + } + + public int[] digits; + + protected static int fracDigits; + private static int fracDigitsm1; + private static int fracDigitsp1; + private static int fracDigitsHalf; + private static boolean useToDouble2; + private static boolean useKaratsuba; + private static int initialLength; + private static boolean evenFracDigits; + + protected static boolean use_threads; + + public static final long MASK = 0x3FFFFFFFL; + public static final int MASKINT = 0x3FFFFFFF; + public static final int SHIFT = 30; + public static final long MASKD0 = 0x7FFFFFFFL; + public static final long MASK31 = 0x40000000L; + public static final int SHIFTM1 = SHIFT - 1; + public static final int SHIFTM52 = SHIFT - 52; + public static final int MSHIFTP52 = 52 - SHIFT; + private static final double TWO_TO_SHIFT = Math.pow(2,-SHIFT); + public static int THREADS_THRESHOLD = 275; + + public static void reinitialize(double digits) { + + double res = digits / SHIFT; + int temp = (int) (res); + + if (temp == 0) { + temp = 1; + } else if (digits % SHIFT != 0) { + //0 is floor + if(TaskDraw.BIGNUM_INITIALIZATION_ALGORITHM == 1) { //always + temp++; + } + else if (TaskDraw.BIGNUM_INITIALIZATION_ALGORITHM == 2) { //round + temp = (int)(res + 0.5); + } + } + + //Lets always have even fracDigits +// if((temp & 1) == 0) { +// fracDigits = temp * TaskDraw.BIGNUM_PRECISION_FACTOR; +// } +// else { +// fracDigits = (temp + 1) * TaskDraw.BIGNUM_PRECISION_FACTOR; +// } + //Lets always have odd fracDigits + if((temp & 1) == 1) { + fracDigits = temp * TaskDraw.BIGNUM_PRECISION_FACTOR; + } + else { + fracDigits = (temp + 1) * TaskDraw.BIGNUM_PRECISION_FACTOR; + } + + initializeInternal(); + } + + public static void reinitializeTest(double digits) { + fracDigits = ((int)(digits / SHIFT) + 1) * TaskDraw.BIGNUM_PRECISION_FACTOR; + initializeInternal(); + } + + private static void initializeInternal() { + fracDigitsm1 = fracDigits - 1; + fracDigitsp1 = fracDigits + 1; + //useToDouble2 = fracDigits > 160; + useKaratsuba = fracDigits > 40; + fracDigitsHalf = fracDigits >> 1; + initialLength = fracDigitsHalf - ((fracDigitsp1) % 2); + evenFracDigits = (fracDigits & 1) == 0; + + use_threads = TaskDraw.USE_THREADS_IN_BIGNUM_LIBS && fracDigits >= THREADS_THRESHOLD && Runtime.getRuntime().availableProcessors() >= 2; + //use_threads2 = TaskDraw.USE_THREADS_IN_BIGNUM_LIBS && fracDigits >= THREADS_THRESHOLD && Runtime.getRuntime().availableProcessors() >= 3; + } + + private static BigNum30 getMax() { + BigNum30 n = new BigNum30(); + n.digits[0] = (int)MASKD0; + n.sign = 1; + return n; + } + + protected BigNum30() { + digits = new int[fracDigitsp1]; + sign = 0; + isOne = false; + scale = 0; + offset = -1; + bitOffset = -1; + } + + protected BigNum30(BigNum30 other) { + digits = Arrays.copyOf(other.digits, other.digits.length); + sign = other.sign; + isOne = other.isOne; + scale = 0; + offset = -1; + bitOffset = -1; + } + + protected BigNum30(int val) { + digits = new int[fracDigitsp1]; + digits[0] = Math.abs(val); + isOne = val == 1 || val == -1; + sign = (int)Math.signum(val); + scale = 0; + offset = -1; + bitOffset = -1; + } + + protected BigNum30(double val) { + + digits = new int[fracDigitsp1]; + + scale = 0; + offset = -1; + bitOffset = -1; + + if(val == 0 ) { + sign = 0; + isOne = false; + return; + } + else if(Math.abs(val) == 1) { + isOne = true; + sign = (int)val; + digits[0] = 1; + return; + } + + sign = (int)Math.signum(val); + val = Math.abs(val); + digits[0] = (int)(val); + double fractionalPart = val - (int) val; + + if(fractionalPart != 0) { + + long bits = Double.doubleToRawLongBits(fractionalPart); + long f_exp = ((bits & 0x7FF0000000000000L) >>> 52) - Double.MAX_EXPONENT; + long mantissa = (bits & 0xFFFFFFFFFFFFFL) | (0x10000000000000L); + + if(f_exp < 0) { + + long posExp = -f_exp; + + int index = (int) (posExp / SHIFT) + 1; + int bitOffset = (int) (posExp % SHIFT); + + if (bitOffset == 0) { + index--; + bitOffset = SHIFT; + } + + int k; + int i = index; + for (k = 53; k > 0 && i < digits.length; i++) { + int r; + + if (k > SHIFT) { + + if (k == 53) { + r = MSHIFTP52 + bitOffset; + k -= 53 - r; + } else { + r = k - SHIFT; + k -= SHIFT; + } + + digits[i] = (int) ((mantissa >>> r) & MASK); + } else { + + r = SHIFT - k; + k -= k; + + + //if(r >= 0) { + digits[i] = (int) ((mantissa << r) & MASK); + //} + //else { + // digits[i] = (int) ((mantissa >>> (-r)) & MASK); + // } + } + + } + } + + } + + boolean isZero = true; + for(int i = 0; i < digits.length; i++) { + if(digits[i] != 0) { + isZero = false; + break; + } + } + + if(isZero) { + sign = 0; + } + + } + + //Has similarities with the double constructor + private BigNum30(MantExp inputVal) { + + digits = new int[fracDigitsp1]; + + scale = 0; + offset = -1; + bitOffset = -1; + + inputVal.Normalize(); + double doubleMantissa = inputVal.getMantissa(); + long inputExp = inputVal.getExp(); + + if(doubleMantissa == 0) { + sign = 0; + isOne = false; + return; + } + else if(Math.abs(doubleMantissa) == 1 && inputExp == 0) { + isOne = true; + sign = (int)doubleMantissa; + digits[0] = 1; + return; + } + + sign = (int)Math.signum(doubleMantissa); + double val = Math.abs(doubleMantissa); + + + long bits = Double.doubleToRawLongBits(val); + long f_exp = ((bits & 0x7FF0000000000000L) >>> 52) - Double.MAX_EXPONENT; + long mantissa = (bits & 0xFFFFFFFFFFFFFL) | (0x10000000000000L); + + + long totalExp = f_exp + inputExp; + + int index; + int bitOffset; + if(totalExp < 0) { + long posExp = Math.abs(totalExp); + index = (int) (posExp / SHIFT) + 1; + bitOffset = (int) (posExp % SHIFT); + } + else { + index = (int) (-totalExp / SHIFT); + bitOffset = (int) (totalExp % SHIFT); + } + + + int k; + int i = index; + for (k = 53; k > 0 && i < digits.length; i++) { + int r; + + if (k > SHIFT) { + + if(i == -1) { + i = 0; + r = MSHIFTP52; + k -= 53 - r; + digits[i] = (int) ((mantissa >>> r) & MASKD0); + } + else if(i == 0) { + r = 52 - bitOffset; + k -= 53 - r; + digits[i] = (int) ((mantissa >>> r) & MASKD0); + } + else if (i > 0) { + if (k == 53) { + r = MSHIFTP52 + bitOffset; + k -= 53 - r; + } else { + r = k - SHIFT; + k -= SHIFT; + } + + digits[i] = (int) ((mantissa >>> r) & MASK); + } + } else { + + r = SHIFT - k; + k -= k; + + + //if(r >= 0) { + digits[i] = (int) ((mantissa << r) & MASK); + //} + //else { + // digits[i] = (int) ((mantissa >>> (-r)) & MASK); + // } + } + + } + + boolean isZero = true; + for(i = 0; i < digits.length; i++) { + if(digits[i] != 0) { + isZero = false; + break; + } + } + + if(isZero) { + sign = 0; + } + } + + protected BigNum30(String val) { + this(new MyApfloat(val)); + } + + protected BigNum30(Apfloat val) { + + scale = 0; + this.offset = -1; + bitOffset = -1; + + Apfloat baseTwo = val.toRadix(2); + + sign = baseTwo.getImpl().signum(); + + isOne = false; + + digits = new int[fracDigitsp1]; + + LongMemoryDataStorage str = (LongMemoryDataStorage)baseTwo.getImpl().getDataStorage(); + + if(str == null || sign == 0) { //for zero + return; + } + + long[] data = str.getData(); + + if(data.length == 1 && data[0] == 1) { + isOne = true; + } + + int base_digits = BASE_DIGITS[2]; + + int offset = (int)str.getOffset(); + + int exponent = (int)baseTwo.getImpl().getExponent(); + + if(exponent == 1) { + int index = data.length >= 2 ? 1 : 0; + digits[0] = (int)(MASKD0 & data[index]); + offset++; + } + + int dataOffset = exponent < 0 ? Math.abs(exponent) * base_digits : 0; + + for(int i = dataOffset, j = 0; ; i++, j++) { + + int index2 = (i / SHIFT) + 1; + int index = j / base_digits + offset; + + if(index2 >= digits.length || index >= data.length) { + break; + } + + int shift = base_digits - (j % base_digits) - 1; + int bit = (int) ((data[index] >>> shift) & 0x1); + + digits[index2] |= bit << (SHIFT - (i % SHIFT) - 1); + } + + boolean isZero = true; + for(int i = 0; i < digits.length; i++) { + if(digits[i] != 0) { + isZero = false; + break; + } + } + + if(isZero) { + sign = 0; + } + + } + + @Override + public long getScale() { + + if(sign == 0) { + return Long.MIN_VALUE; + } + + if(offset != -1) { + return scale; + } + + int i; + int digit = 0; + for(i = 0; i < digits.length; i++) { + digit = digits[i]; + if(digit != 0) { + break; + } + } + + if(i == digits.length) { + return Long.MIN_VALUE; + } + + /*int r; + for(r = i == 0 ? SHIFT : SHIFTM1; r >= 0; r--) { + if(digits[i] >>> r != 0) { + break; + } + }*/ + + offset = i; + long v = digit; + double d = v & ~(v >>> 1); + //int r = (int)(((Double.doubleToRawLongBits(d) >> 52) & 0x7ff) - 1023); //Fix for the 64 bit, not needed here + bitOffset = (int)((Double.doubleToRawLongBits(d) >> 52) - 1023); + //r |= (r >> 31); //Fix for zero, not needed here + + //bitOffset = 31 - Integer.numberOfLeadingZeros(digit); + + scale = i == 0 ? bitOffset : -(((long)i) * SHIFT) + bitOffset; + + return scale; + + } + + public static BigNum30 getNegative(BigNum30 other) { + + BigNum30 copy = new BigNum30(); + copy.sign = other.sign; + copy.isOne = other.isOne; + + int[] otherDigits = other.digits; + int[] digits = copy.digits; + + int s = (~otherDigits[fracDigits] & MASKINT) + 1; + digits[fracDigits] = s & MASKINT; + for (int i = fracDigitsm1; i > 0 ; i--) { + s = (~otherDigits[i] & MASKINT) + (s>>>SHIFT); + digits[i] = s & MASKINT; + } + + s = (~otherDigits[0]) + (s>>>SHIFT); + digits[0] = s; + + return copy; + } + + @Override + public void negSelf() { + + if(sign == 0) { + return; + } + /*if(digits[fracDigits]>0) { + digits[fracDigits] = (int)((digits[fracDigits]-1)^MASK); + for(int i=fracDigits-1; i>0; i--) digits[i] ^= MASK; + digits[0] = ~digits[0]; + } else { + long s = digits[fracDigits-1]-1; digits[fracDigits-1] = (int)(~s&MASK); + for(int i=fracDigits-2; i>0; i--) { + s = digits[i]+(s>>SHIFT); digits[i] = (int)(~s&MASK); + } + digits[0] = (int)(~(digits[0]+(s>>SHIFT))); + }*/ + + int s = (~digits[fracDigits] & MASKINT) + 1; + digits[fracDigits] = s & MASKINT; + for (int i = fracDigitsm1; i > 0 ; i--) { + s = (~digits[i] & MASKINT) + (s>>>SHIFT); + digits[i] = s & MASKINT; + } + + s = (~digits[0]) + (s>>>SHIFT); + digits[0] = s; + + } + + @Override + public BigNum30 negate() { + + BigNum30 res = new BigNum30(this); + + res.sign *= -1; + + return res; + + } + + @Override + public BigNum30 abs() { + + BigNum30 res = new BigNum30(this); + + if(sign == -1) { + res.sign = 1; + } + + return res; + } + + @Override + public BigNum30 abs_mutable() { + + if(sign == -1) { + sign = 1; + } + + return this; + } + + @Override + public String toString() { + StringBuilder ret = new StringBuilder((sign == -1 ? "-" : "") + toHexString(digits[0])); + for(int i=1; i<=fracDigits; i++) { + ret.append(i==1 ? "." : " "); + ret.append(toHexString(digits[i])); + } + return doubleValueOld() + " " + ret.toString(); + } + + + @Override + public String bits() { + + String value = ""; + if(sign == -1) { + value = "-"; + } + for (int i = 0; i < digits.length; i++) { + + if (i == 0) { + boolean zero = true; + for (int j = SHIFTM1; j >= 0; j--) { + if (((digits[i] >>> j) & 0x1) == 1) { + zero = false; + } + + if (!zero) { + value += "" + ((digits[i] >>> j) & 0x1); + } + } + if(zero) { + value += "0"; + } + value += "."; + } else { + for (int j = SHIFTM1; j >= 0; j--) { + value += "" + ((digits[i] >>> j) & 0x1); + } + } + } + + return value; + + } + + @Override + public int compare(BigNum otherr) { + BigNum30 other = (BigNum30) otherr; + + int signA = sign; + + int[] otherDigits = other.digits; + + int signB = other.sign; + + int digit, otherDigit; + + if(signA < signB) { + return -1; + } + else if(signA > signB) { + return 1; + } + else {//if(signA == signB) + if (signA == 0) { + return 0; + } + + if(signA < 0) { + for (int i = 0; i < digits.length; i++) { + digit = digits[i]; + otherDigit = otherDigits[i]; + if (digit < otherDigit) { + return 1; + } else if (digit > otherDigit) { + return -1; + } + } + } + else { + for (int i = 0; i < digits.length; i++) { + digit = digits[i]; + otherDigit = otherDigits[i]; + if (digit < otherDigit) { + return -1; + } else if (digit > otherDigit) { + return 1; + } + } + } + } + + return 0; + + } + + @Override + public int compareBothPositive(BigNum otherr) { + BigNum30 other = (BigNum30) otherr; + + int signA = sign; + int signB = other.sign; + + if(signA == 0 && signB == 0) { + return 0; + } + + int[] otherDigits = other.digits; + + int digit, otherDigit; + + for (int i = 0; i < digits.length; i++) { + digit = digits[i]; + otherDigit = otherDigits[i]; + if (digit < otherDigit) { + return -1; + } else if (digit > otherDigit) { + return 1; + } + } + + return 0; + + } + + @Override + public double doubleValue() { + + int[] digits = this.digits; + + int i; + int digit = 0; + if(offset == -1) { + for (i = 0; i < digits.length; i++) { + digit = digits[i]; + if (digit != 0) { + break; + } + } + + if (i == digits.length) { + return 0; + } + + /*int r; + for(r = i == 0 ? SHIFT : SHIFTM1; r >= 0; r--) { + if(digits[i] >>> r != 0) { + break; + } + }*/ + + offset = i; + long v = digit; + double d = v & ~(v >>> 1); + //int r = (int)(((Double.doubleToRawLongBits(d) >> 52) & 0x7ff) - 1023); //Fix for the 64 bit, not needed here + bitOffset = (int) ((Double.doubleToRawLongBits(d) >> 52) - 1023); + //r |= (r >> 31); //Fix for zero, not needed here + //bitOffset = 31 - Integer.numberOfLeadingZeros(digit); + + scale = i == 0 ? bitOffset : -(((long) i) * SHIFT) + bitOffset; + + } + else { + i = offset; + digit = digits[i]; + } + + if (scale < Double.MIN_EXPONENT) { //accounting for +1 + return 0.0; + } + else if (scale >= Double.MAX_EXPONENT) { + return sign == -1 ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; + } + + long mantissa = 0; + long v = digit; + + mantissa |= v << (52 - bitOffset); + i++; + + int k; + for(k = bitOffset ; k < 52 && i < digits.length; k+=SHIFT, i++) { + long val = digits[i]; + int temp = 52 - k; + + if(temp > SHIFT) { + mantissa |= val << (temp - SHIFT); + mantissa &= 0xFFFFFFFFFFFFFL; + } + else { + int temp2 = k + SHIFTM52; + mantissa |= val >>> temp2; + mantissa &= 0xFFFFFFFFFFFFFL; + + if(temp2 == 0 && i + 1 < digits.length) { + long val2 = digits[i + 1]; + mantissa += (val2 >>> (SHIFTM1)) & 0x1; + } + else { + mantissa += (val >>> (temp2 - 1)) & 0x1; + } + } + } + + long finalScale = scale + (mantissa >>> 52); + if (finalScale <= Double.MIN_EXPONENT) { + return 0.0; + } + else if (finalScale >= Double.MAX_EXPONENT) { + return sign == -1 ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; + } + + // Bit 63 (the bit that is selected by the mask 0x8000000000000000L) represents the sign of the floating-point number. + // Bits 62-52 (the bits that are selected by the mask 0x7ff0000000000000L) represent the exponent. + // Bits 51-0 (the bits that are selected by the mask 0x000fffffffffffffL) represent the significand (sometimes called the mantissa) of the floating-point number. + + if(sign == -1) { + return Double.longBitsToDouble( (0x8000000000000000L) | (mantissa & 0xFFFFFFFFFFFFFL) | ((finalScale + Double.MAX_EXPONENT) << 52)); + } + else { + return Double.longBitsToDouble((mantissa & 0xFFFFFFFFFFFFFL) | ((finalScale + Double.MAX_EXPONENT) << 52)); + } + + } + + @Override + public double doubleValueOld() { + + if (sign == 0) { + return 0; + } + + if(isOne) { + return sign; + } + + if(useToDouble2) { + return doubleValue(); + } + + double ret = 0; + + + /*if(digits[0]>=0) { + for(int i=fracDigits; i>=0; i--) { + ret *= TWO_TO_SHIFT; + ret += digits[i]; + } + } else { + ret--; + for(int i=fracDigits; i>0; i--) { + ret += digits[i] - MASK; + ret *= TWO_TO_SHIFT; + } + ret += digits[0]+1; + }*/ + + for(int i=fracDigits; i>=0; i--) { + ret *= TWO_TO_SHIFT; + ret += digits[i]; + } + + ret *= sign; + return ret; + } + + @Override + public BigNum30 add(BigNum aa) { + BigNum30 a = (BigNum30) aa; + + BigNum30 result = new BigNum30(); + + int[] otherDigits = a.digits; + int otherSign = a.sign; + + int[] resDigits = result.digits; + + int[] digits = this.digits; + int sign = this.sign; + + if(sign == 0 || otherSign == 0) { + if(sign == 0 && otherSign == 0){ + return result; + } + else if(sign == 0) { + result.sign = otherSign; + result.isOne = a.isOne; + System.arraycopy(otherDigits, 0, resDigits, 0, otherDigits.length); + } + else { + result.sign = sign; + result.isOne = isOne; + System.arraycopy(digits, 0, resDigits, 0, digits.length); + } + return result; + } + + if(sign != otherSign) { + if(sign == -1) { + BigNum30 copy = getNegative(this); + digits = copy.digits; + } + else + { + BigNum30 copy = getNegative(a); + otherDigits = copy.digits; + } + } + + int s = 0; + int isNonZero = 0; + int temp; + for(int i=fracDigits; i>0; i--) { + s += digits[i] + otherDigits[i]; + temp = s & MASKINT; + isNonZero |= temp; + resDigits[i] = temp; + s >>>= SHIFT; + } + temp = digits[0] + otherDigits[0] + s; + result.isOne = (temp == 1 || temp == -1) && isNonZero == 0; + isNonZero |= temp; + resDigits[0] = temp; + + if(sign != otherSign) { + if(resDigits[0] < 0) { + result.sign = -1; + result.negSelf(); + } + else { + result.sign = isNonZero != 0 ? 1 : 0; + } + } + else { + result.sign = isNonZero != 0 ? sign : 0; + } + + return result; + } + + @Override + public BigNum30 add(int a) { + + BigNum30 result = new BigNum30(); + + int otherSign; + if(a == 0) { + otherSign = 0; + } + else if(a < 0) { + otherSign = -1; + } + else { + otherSign = 1; + } + + int otherDigits = a; + + boolean aIsOne = a == 1 || a == -1; + + int[] resDigits = result.digits; + + int[] digits = this.digits; + int sign = this.sign; + + if(sign == 0 || otherSign == 0) { + if(sign == 0 && otherSign == 0){ + return result; + } + else if(sign == 0) { + result.sign = otherSign; + result.isOne = aIsOne; + + if(otherSign < 0) { + a = ~a + 1; + } + + resDigits[0] = a; + } + else { + result.sign = sign; + result.isOne = isOne; + System.arraycopy(digits, 0, resDigits, 0, digits.length); + } + return result; + } + + if(sign != otherSign) { + if(sign == -1) { + BigNum30 copy = getNegative(this); + digits = copy.digits; + } + } + else { + if(otherSign < 0) { + otherDigits = ~otherDigits + 1; + } + } + + int isNonZero = 0; + int temp; + for(int i=fracDigits; i>0; i--) { + temp = resDigits[i] = digits[i]; + isNonZero |= temp; + } + + temp = digits[0] + otherDigits; + result.isOne = (temp == 1 || temp == -1) && isNonZero == 0; + isNonZero |= temp; + resDigits[0] = temp; + + if(sign != otherSign) { + if(resDigits[0] < 0) { + result.sign = -1; + result.negSelf(); + } + else { + result.sign = isNonZero != 0 ? 1 : 0; + } + } + else { + result.sign = isNonZero != 0 ? sign : 0; + } + + return result; + } + + /* When sign was not an extra field + public BigNum30 sub(BigNum30 a) { + BigNum30 result = new BigNum30(); + + int[] otherDigits = a.digits; + int[] resDigits = result.digits; + long s = 0; + for(int i=fracDigits; i>0; i--) { + s += ((long)digits[i])-((long)otherDigits[i]); resDigits[i] = (int)(s&MASK); s >>= SHIFT; + } + resDigits[0] = (int)(digits[0]-otherDigits[0]+s); + return result; + } + + public BigNum30 add(BigNum30 a) { + BigNum30 result = new BigNum30(); + + int[] otherDigits = a.digits; + int[] resDigits = result.digits; + long s = 0; + for(int i=fracDigits; i>0; i--) { + s += ((long)digits[i])+((long)otherDigits[i]); resDigits[i] = (int)(s&MASK); s >>>= SHIFT; + } + resDigits[0] = (int)(digits[0]+otherDigits[0]+s); + return result; + }*/ + + @Override + public BigNum30 sub(BigNum aa) { + BigNum30 a = (BigNum30) aa; + + BigNum30 result = new BigNum30(); + + int[] otherDigits = a.digits; + int otherSign = a.sign; + + int[] resDigits = result.digits; + + int[] digits = this.digits; + int sign = this.sign; + + if(sign == 0 || otherSign == 0) { + if(sign == 0 && otherSign == 0){ + return result; + } + else if(sign == 0) { + result.sign = -otherSign; + result.isOne = a.isOne; + System.arraycopy(otherDigits, 0, resDigits, 0, otherDigits.length); + } + else { + result.sign = sign; + result.isOne = isOne; + System.arraycopy(digits, 0, resDigits, 0, digits.length); + } + return result; + } + + if(sign == otherSign) { + // + + -> + - + // - - -> - + + if(sign == -1) { + BigNum30 copy = getNegative(this); + digits = copy.digits; + } + else { + BigNum30 copy = getNegative(a); + otherDigits = copy.digits; + } + } + + int s = 0; + int isNonZero = 0; + int temp; + for(int i=fracDigits; i>0; i--) { + s += digits[i] + otherDigits[i]; + temp = s & MASKINT; + isNonZero |= temp; + resDigits[i] = temp; + s >>>= SHIFT; + } + temp = digits[0] + otherDigits[0] + s; + result.isOne = (temp == 1 || temp == -1) && isNonZero == 0; + isNonZero |= temp; + resDigits[0] = temp; + + if(sign == otherSign) { + if(resDigits[0] < 0) { + result.sign = -1; + result.negSelf(); + } + else { + result.sign = isNonZero != 0 ? 1 : 0; + } + } + else { + result.sign = isNonZero != 0 ? sign : 0; + } + + return result; + } + + @Override + public BigNum30 sub(int a) { + + BigNum30 result = new BigNum30(); + + int otherSign; + if(a == 0) { + otherSign = 0; + } + else if(a < 0) { + otherSign = -1; + } + else { + otherSign = 1; + } + + int otherDigits = a; + + boolean aIsOne = a == 1 || a == -1; + + int[] resDigits = result.digits; + + int[] digits = this.digits; + int sign = this.sign; + + if(sign == 0 || otherSign == 0) { + if(sign == 0 && otherSign == 0){ + return result; + } + else if(sign == 0) { + result.sign = -otherSign; + result.isOne = aIsOne; + + if(otherSign < 0) { + a = ~a + 1; + } + + resDigits[0] = a; + } + else { + result.sign = sign; + result.isOne = isOne; + System.arraycopy(digits, 0, resDigits, 0, digits.length); + } + return result; + } + + if(sign == otherSign) { + // + + -> + - + // - - -> - + + if(sign == -1) { + BigNum30 copy = getNegative(this); + digits = copy.digits; + } + + otherDigits = ~otherDigits + 1; + } + else { + if(otherSign < 0) { + otherDigits = ~otherDigits + 1; + } + } + + + int isNonZero = 0; + int temp; + for(int i=fracDigits; i>0; i--) { + temp = resDigits[i] = digits[i]; + isNonZero |= temp; + } + + temp = digits[0] + otherDigits; + result.isOne = (temp == 1 || temp == -1) && isNonZero == 0; + isNonZero |= temp; + resDigits[0] = temp; + + if(sign == otherSign) { + if(resDigits[0] < 0) { + result.sign = -1; + result.negSelf(); + } + else { + result.sign = isNonZero != 0 ? 1 : 0; + } + } + else { + result.sign = isNonZero != 0 ? sign : 0; + } + + return result; + } + + @Override + public BigNum30 square() { + if(offset <= 15) { + return squareFull(); + } + else { + return squareWithZeroSkip(); + } + } + + public BigNum30 squareWithZeroSkip() { + + + BigNum30 result = new BigNum30(); + + if(sign == 0) { + return result; + } + + int[] resDigits = result.digits; + + if(isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = 1; + return result; + } + + if ((offset << 1) > fracDigits) { + return result; // zero + } + + long old_sum; + + long sum = 0; + + int length = initialLength; + + int j; + int k; + long carry = 0; + long bj; + long ak; + + int newLength = (length >>> 1) << 1; + boolean isOdd = (length & 1) == 1; + + for (j = 1, k = fracDigits; j <= newLength;) { + bj = digits[j]; + ak = digits[k]; + + sum += bj * ak; + + j++;k--; + + bj = digits[j]; + ak = digits[k]; + + sum += bj * ak; + + j++;k--; + + carry += sum >>> SHIFT; + sum &= MASK; + } + + if(isOdd) { + bj = digits[j]; + ak = digits[k]; + sum += bj * ak; + carry += sum >>> SHIFT; + sum &= MASK; + j++;k--; + } + + carry <<= 1; + + if(j == k) { + bj = digits[j]; + sum <<= 1; + sum += bj * bj; + } + else { + bj = digits[j]; + ak = digits[k]; + sum += bj * ak; + sum <<= 1; + } + + carry += sum >>> SHIFT; + sum &= MASK; + + + + old_sum = carry + (sum >>> (SHIFTM1)); // Roundish + + int newJStart = offset != -1 ? offset : 0; //To avoid multiplication on zeros + + for(int i = fracDigits; i > 0; i--) { + + sum = 0; + + length = (i >> 1) - 1; + + carry = 0; + + for(j = newJStart, k = i - newJStart; j <= length; j++, k--) { + bj = digits[j]; + ak = digits[k]; + sum += bj * ak; + carry += sum >>> SHIFT; + sum &= MASK; + } + + carry <<= 1; + + if(j == k) { + bj = digits[j]; + sum <<= 1; + sum += bj * bj; + } + else { + bj = digits[j]; + ak = digits[k]; + sum += bj * ak; + sum <<= 1; + } + + sum += old_sum; + carry += sum >>> SHIFT; + sum &= MASK; + + + resDigits[i] = (int) (sum); + old_sum = carry; + + if(k <= offset && carry == 0) { + result.sign = 1; + return result; + } + } + + sum = old_sum; + + bj = digits[0]; + sum += bj * bj; + + resDigits[0] = (int) (sum & MASKD0); + result.sign = 1; + + return result; + } + @Deprecated + @Override + public BigNum30 squareFullGolden() { + + + BigNum30 result = new BigNum30(); + + if(sign == 0) { + return result; + } + + int[] resDigits = result.digits; + + if(isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = 1; + return result; + } + + long old_sum; + + long sum = 0; + + int length = initialLength; + + int j; + int k; + long carry = 0; + long bj; + long ak; + + for (j = 1, k = fracDigits; j <= length; j++, k--) { + bj = digits[j]; + ak = digits[k]; + + sum += bj * ak; + carry += sum >>> SHIFT; + sum &= MASK; + } + + carry <<= 1; + + if(j == k) { + bj = digits[j]; + sum <<= 1; + sum += bj * bj; + } + else { + bj = digits[j]; + ak = digits[k]; + sum += bj * ak; + sum <<= 1; + } + + carry += sum >>> SHIFT; + sum &= MASK; + + old_sum = carry + (sum >>> (SHIFTM1)); // Roundish + + + for(int i = fracDigits; i > 0; i--) { + + sum = 0; + + length = (i >> 1) - 1; + + carry = 0; + for(j = 0, k = i; j <= length; j++, k--) { + bj = digits[j]; + ak = digits[k]; + sum += bj * ak; + carry += sum >>> SHIFT; + sum &= MASK; + } + + + + if(j == k) { + bj = digits[j]; + sum <<= 1; + carry <<= 1; + sum += bj * bj; + carry += sum >>> SHIFT; + sum &= MASK; + } + else { + bj = digits[j]; + ak = digits[k]; + sum += bj * ak; + carry += sum >>> SHIFT; + sum &= MASK; + sum <<= 1; + carry <<= 1; + } + + sum += old_sum; + carry += sum >>> SHIFT; + sum &= MASK; + + + resDigits[i] = (int) (sum); + old_sum = carry; + } + + sum = old_sum; + + bj = digits[0]; + sum += bj * bj; + + resDigits[0] = (int) (sum & MASKD0); + result.sign = 1; + + return result; + } + + + @Override + public BigNum30 squareFull() { + + + BigNum30 result = new BigNum30(); + + if(sign == 0) { + return result; + } + + int[] resDigits = result.digits; + + if(isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = 1; + return result; + } + + long old_sum; + + long sum = 0; + + int length = initialLength; + + int j; + int k; + long carry = 0; + + long bj; + long ak; + + int newLength = (length >>> 1) << 1; + boolean isOdd = (length & 1) == 1; + + for (j = 1, k = fracDigits; j <= newLength;) { + bj = digits[j]; + ak = digits[k]; + + sum += bj * ak; + + j++;k--; + + bj = digits[j]; + ak = digits[k]; + + sum += bj * ak; + + j++;k--; + + carry += sum >>> SHIFT; + sum &= MASK; + } + + if(isOdd) { + bj = digits[j]; + ak = digits[k]; + sum += bj * ak; + //carry += sum >>> SHIFT; + //sum &= MASK; + j++;k--; + } + + carry <<= 1; + + if(j == k) { + bj = digits[j]; + sum <<= 1; + sum += bj * bj; + } + else { + bj = digits[j]; + ak = digits[k]; + sum += bj * ak; + sum <<= 1; + } + + carry += sum >>> SHIFT; + sum &= MASK; + + old_sum = carry + (sum >>> (SHIFTM1)); // Roundish + + length = fracDigitsHalf; + + for(int i = fracDigits; i > 0; i-=2, length--) { + + sum = 0; + long sum2 = 0; + carry = 0; + long carry2 = 0; + + k = i; + long prevDigit = digits[k]; + + newLength = (length >>> 1) << 1; + isOdd = (length & 1) == 1; + + for(j = 0; j < newLength;) { + //1st + bj = digits[j]; + sum += prevDigit * bj; + + k--; + + prevDigit = digits[k]; //ak + sum2 += prevDigit * bj; + + j++; + + //2nd + bj = digits[j]; + sum += prevDigit * bj; + + k--; + + prevDigit = digits[k]; //ak + sum2 += prevDigit * bj; + + carry += sum >>> SHIFT; + sum &= MASK; + carry2 += sum2 >>> SHIFT; + sum2 &= MASK; + j++; + } + + if(isOdd) { + bj = digits[j]; + sum += prevDigit * bj; + + k--; + + prevDigit = digits[k]; //ak + + sum2 += prevDigit * bj; + +// carry1 += temp_sum1 >>> SHIFT; +// temp_sum1 &= MASK; +// carry2 += temp_sum2 >>> SHIFT; +// temp_sum2 &= MASK; + } + + if(evenFracDigits) { + sum <<= 1; + sum += prevDigit * prevDigit; + + sum2 <<= 1; + } + else { + bj = digits[length]; + + sum += prevDigit * bj; + //carry1 += temp_sum1 >>> SHIFT; + //temp_sum1 &= MASK; + + sum2 <<= 1; + sum2 += bj * bj; + + sum <<= 1; + } + + carry <<= 1; + carry2 <<= 1; + + sum += old_sum; + carry += sum >>> SHIFT; + sum &= MASK; + + sum2 += carry; + + + if(i > 1) { + carry2 += sum2 >>> SHIFT; + sum2 &= MASK; + old_sum = carry2; + } + + resDigits[i] = (int) (sum); + resDigits[i - 1] = (int) (sum2); + + } + + if(evenFracDigits) { + sum = old_sum; + + bj = digits[0]; + sum += bj * bj; + + resDigits[0] = (int) (sum & MASKD0); + } + result.sign = 1; + + return result; + } + + @Deprecated + public BigNum30 squareKaratsubaOLD() { + + BigNum30 result = new BigNum30(); + + if(sign == 0) { + return result; + } + + int[] resDigits = result.digits; + + if(isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = 1; + return result; + } + + long[] partials = new long[fracDigitsp1]; + long[] partialSums = new long[fracDigitsp1]; + long[] partialCarries = new long[fracDigitsp1]; + + long PartialSum = 0; + long PartialCarry = 0; + for(int i = 0; i < fracDigitsp1; i++) { + long temp = digits[i]; + long p = temp * temp; + + partials[i] = p; + PartialSum += p; + + PartialCarry += PartialSum >>> SHIFT; + PartialSum &= MASK; + + partialSums[i] = PartialSum; + partialCarries[i] = PartialCarry; + } + + long old_sum; + + //for(int i = MAX_FRAC_DIGITS; i > 0; i--) { + //long sum += (int)(old_sum >>> SHIFT30); + + //long sum = (old_sum >>> SHIFT31); + + long p0 = partials[0]; + long sum = p0; + + int length = initialLength; + + long aj; + long ak; + + int j; + int k; + long carry = 0; + long temp; + for (j = 1, k = fracDigits; j <= length; j++, k--) { + aj = digits[j]; + ak = digits[k]; + + + temp = aj + ak; + + sum += temp * temp; + carry += sum >>> SHIFT; + sum &= MASK; + + //System.out.println("a" + j + " * " + "a " + k); + } + + //System.out.println("OUT"); + //System.out.println("a" + j + " * " + "a " + k); + //int diff = k - j; + //int branchlessCheck = (diff >> 31) - (-diff >> 31); + + if(j == k) { + sum += (partials[k] << 1); + } + else { + aj = digits[j]; + ak = digits[k]; + temp = ak + aj; + sum += temp * temp; + } + + carry += sum >>> SHIFT; + sum &= MASK; + + sum -= PartialSum; + carry -= ((sum & MASK31) >>> SHIFT) + PartialCarry; + sum &= MASK; + + old_sum = carry + (sum >>> (SHIFTM1)); // Roundish + + + for(int i = fracDigits; i > 0; i--) { + + sum = old_sum; + + length = (i >> 1) - 1; + + carry = 0; + for(j = 0, k = i; j <= length; j++, k--) { + aj = digits[j]; + ak = digits[k]; + + temp = aj + ak; + + sum += temp * temp; + carry += sum >>> SHIFT; + sum &= MASK; + //System.out.println("a" + j + " * " + "a " + k); + } + + //System.out.println("OUT"); + //System.out.println("a" + j + " * " + "a " + k); + + //System.out.println("NEXT"); + + //diff = k - j; + //branchlessCheck = (diff >> 31) - (-diff >> 31); + + if(j == k) { + sum += (partials[k] << 1); + } + else { + aj = digits[j]; + ak = digits[k]; + temp = ak + aj; + sum += temp * temp; + } + + carry += sum >>> SHIFT; + sum &= MASK; + + sum -= PartialSum; + carry -= ((sum & MASK31) >>> SHIFT) + PartialCarry; + sum &= MASK; + + if(i > 1) { +// long partialI = partials[i]; +// PartialSum -= partialI & MASK; +// PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFT; +// //PartialCarry -= (PartialSum & MASK31)>>> SHIFT; +// //PartialCarry -= partialI >>> SHIFT; +// PartialSum &= MASK; + int im1 = i - 1; + PartialSum = partialSums[im1]; + PartialCarry = partialCarries[im1]; + } + + resDigits[i] = (int) (sum); + //System.out.println(result.digits[i] ); + old_sum = carry; + //System.out.println("NEXT"); + } + + sum = old_sum; + + sum += p0; + + resDigits[0] = (int) (sum & MASKD0); + result.sign = 1; + + return result; + } + + public BigNum30 squareKaratsuba() { + + BigNum30 result = new BigNum30(); + + if(sign == 0) { + return result; + } + + int[] resDigits = result.digits; + + if(isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = 1; + return result; + } + + long[] partials = new long[fracDigitsp1]; + + long PartialSum = 0; + long PartialCarry = 0; + + int newLength = (fracDigitsp1 >>> 1) << 1; + boolean isOdd = (fracDigitsp1 & 1) == 1; + long temp, p; + + int i; + for(i = 0; i < newLength;) { + temp = digits[i]; + p = temp * temp; + + partials[i] = p; + PartialSum += p; + + i++; + + temp = digits[i]; + p = temp * temp; + + partials[i] = p; + PartialSum += p; + + i++; + + PartialCarry += PartialSum >>> SHIFT; + PartialSum &= MASK; + } + + if(isOdd) { + temp = digits[i]; + p = temp * temp; + + partials[i] = p; + PartialSum += p; + + PartialCarry += PartialSum >>> SHIFT; + PartialSum &= MASK; + } + + long old_sum; + + //for(int i = MAX_FRAC_DIGITS; i > 0; i--) { + //long sum += (int)(old_sum >>> SHIFT30); + + //long sum = (old_sum >>> SHIFT31); + + long p0 = partials[0]; + long sum = p0; + + int length = initialLength; + + long aj; + long ak; + + int j; + int k; + long carry = sum >>> SHIFT; + sum &= MASK; + + newLength = (length >>> 1) << 1; + isOdd = (length & 1) == 1; + + for (j = 1, k = fracDigits; j <= newLength;) { + aj = digits[j]; + ak = digits[k]; + + + temp = aj + ak; + + sum += temp * temp; + j++;k--; + + aj = digits[j]; + ak = digits[k]; + + + temp = aj + ak; + + sum += temp * temp; + j++;k--; + + carry += sum >>> SHIFT; + sum &= MASK; + + //System.out.println("a" + j + " * " + "a " + k); + } + + if(isOdd) { + aj = digits[j]; + ak = digits[k]; + + temp = aj + ak; + + sum += temp * temp; + //carry += sum >>> SHIFT; + //sum &= MASK; + j++;k--; + } + + //System.out.println("OUT"); + //System.out.println("a" + j + " * " + "a " + k); + //int diff = k - j; + //int branchlessCheck = (diff >> 31) - (-diff >> 31); + + if(j == k) { + sum += (partials[k] << 1); + } + else { + aj = digits[j]; + ak = digits[k]; + temp = ak + aj; + sum += temp * temp; + } + + carry += sum >>> SHIFT; + sum &= MASK; + + sum -= PartialSum; + carry -= ((sum & MASK31) >>> SHIFT) + PartialCarry; + sum &= MASK; + + old_sum = carry + (sum >>> (SHIFTM1)); // Roundish + + length = fracDigitsHalf; + + for(i = fracDigits; i > 0; i-=2, length--) { + + carry = old_sum >>> SHIFT; + old_sum &= MASK; + + sum = old_sum; + long sum2 = 0; + long carry2 = 0; + + k = i; + long prevDigit = digits[k]; + + newLength = (length >>> 1) << 1; + isOdd = (length & 1) == 1; + + for(j = 0; j < newLength;) { + aj = digits[j]; + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + temp = prevDigit + aj; + + sum += temp * temp; + + k--; + + prevDigit = digits[k]; // ak + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + temp = prevDigit + aj; + sum2 += temp * temp; + j++; + + aj = digits[j]; + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + temp = prevDigit + aj; + + sum += temp * temp; + + k--; + + prevDigit = digits[k]; // ak + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + temp = prevDigit + aj; + sum2 += temp * temp; + j++; + + carry += sum >>> SHIFT; + sum &= MASK; + carry2 += sum2 >>> SHIFT; + sum2 &= MASK; + } + + if(isOdd) { + aj = digits[j]; + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + temp = prevDigit + aj; + + sum += temp * temp; + + k--; + + prevDigit = digits[k]; // ak + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + temp = prevDigit + aj; + sum2 += temp * temp; + +// carry1 += sum1 >>> SHIFT; +// sum1 &= MASK; +// carry2 += sum2 >>> SHIFT; +// sum2 &= MASK; + } + + if(evenFracDigits) { + sum += (partials[length] << 1); + } + else { + aj = digits[length]; + + temp = prevDigit + aj; + + sum += temp * temp; + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + sum2 += (partials[length] << 1); +// carry2 += sum2 >>> SHIFT; +// sum2 &= MASK; + } + + carry += sum >>> SHIFT; + sum &= MASK; + + sum -= PartialSum; + carry -= ((sum & MASK31) >>> SHIFT) + PartialCarry; + sum &= MASK; + + long partialI = partials[i]; + + PartialSum -= partialI & MASK; + PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFT; + PartialSum &= MASK; + + sum2 += carry; + carry2 += sum2 >>> SHIFT; + sum2 &= MASK; + + + sum2 -= PartialSum; + + resDigits[i] = (int) (sum); + + if(i > 1) { + + int im1 = i - 1; + carry2 -= ((sum2 & MASK31) >>> SHIFT) + PartialCarry; + sum2 &= MASK; + + partialI = partials[im1]; + + PartialSum -= partialI & MASK; + PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFT; + PartialSum &= MASK; + + old_sum = carry2; + + resDigits[im1] = (int) (sum2); + } + else { + sum2 &= MASK; + resDigits[0] = (int) (sum2); + } + } + + if(evenFracDigits) { + sum = p0 + old_sum; + + resDigits[0] = (int) (sum & MASKD0); + } + + result.sign = 1; + + return result; + } + + /* This function has better performance than the normal one after about 3333 digits */ + public BigNum30 squareFullBackwards() { + + + BigNum30 result = new BigNum30(); + + if(sign == 0) { + return result; + } + + int[] resDigits = result.digits; + + if(isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = 1; + return result; + } + + long old_sum; + + long sum = 0; + + int length = initialLength; + + int j; + int k; + long carry = 0; + + long bj; + long ak; + + int newLength = (length >>> 1) << 1; + boolean isOdd = (length & 1) == 1; + + for (j = 1, k = fracDigits; j <= newLength;) { + bj = digits[j]; + ak = digits[k]; + + sum += bj * ak; + + j++; k--; + + bj = digits[j]; + ak = digits[k]; + + sum += bj * ak; + + j++; k--; + + carry += sum >>> SHIFT; + sum &= MASK; + } + + if(isOdd) { + bj = digits[j]; + ak = digits[k]; + + sum += bj * ak; + + j++; k--; + //carry += sum >>> SHIFT; + //sum &= MASK; + } + + carry <<= 1; + + if(j == k) { + bj = digits[j]; + sum <<= 1; + sum += bj * bj; + } + else { + bj = digits[j]; + ak = digits[k]; + sum += bj * ak; + sum <<= 1; + } + + carry += sum >>> SHIFT; + sum &= MASK; + + old_sum = carry + (sum >>> (SHIFTM1)); // Roundish + + length = fracDigitsHalf; + int length2 = evenFracDigits ? length : length + 1; + + for(int i = fracDigits; i > 0; i-=2, length--, length2--) { + + sum = 0; + long sum2 = 0; + carry = 0; + long carry2 = 0; + + k = length2; + long prevDigit = digits[k]; + long startDigit = prevDigit; + + int range = length - ((length >>> 1) << 1); + isOdd = (length & 1) == 1; + + for(j = length - 1; j >= range;) { + bj = digits[j]; + + sum2 += prevDigit * bj; + + k++; + + prevDigit = digits[k]; //ak + + sum += prevDigit * bj; + + j--; + + bj = digits[j]; + + sum2 += prevDigit * bj; + + k++; + + prevDigit = digits[k]; //ak + + sum += prevDigit * bj; + + j--; + + carry += sum >>> SHIFT; + sum &= MASK; + carry2 += sum2 >>> SHIFT; + sum2 &= MASK; + } + + if(isOdd) { + bj = digits[j]; + + sum2 += prevDigit * bj; + + k++; + + prevDigit = digits[k]; //ak + + sum += prevDigit * bj; + +// carry1 += temp_sum1 >>> SHIFT; +// temp_sum1 &= MASK; +// carry2 += temp_sum2 >>> SHIFT; +// temp_sum2 &= MASK; + } + + if(evenFracDigits) { + sum <<= 1; + sum += startDigit * startDigit; + + sum2 <<= 1; + } + else { + bj = digits[length]; + + sum += startDigit * bj; + //carry1 += temp_sum1 >>> SHIFT; + //temp_sum1 &= MASK; + + sum2 <<= 1; + sum2 += bj * bj; + + sum <<= 1; + } + + carry <<= 1; + carry2 <<= 1; + + sum += old_sum; + carry += sum >>> SHIFT; + sum &= MASK; + + sum2 += carry; + + + if(i > 1) { + carry2 += sum2 >>> SHIFT; + sum2 &= MASK; + old_sum = carry2; + } + + resDigits[i] = (int) (sum); + resDigits[i - 1] = (int) (sum2); + + } + + if(evenFracDigits) { + bj = digits[0]; + sum = bj * bj + old_sum; + + resDigits[0] = (int) (sum & MASKD0); + } + result.sign = 1; + + return result; + } + + /* This function has better performance than the normal one after about 3333 digits */ + public BigNum30 squareKaratsubaBackwards() { + + BigNum30 result = new BigNum30(); + + if(sign == 0) { + return result; + } + + int[] resDigits = result.digits; + + if(isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = 1; + return result; + } + + long[] partials = new long[fracDigitsp1]; + + long PartialSum = 0; + long PartialCarry = 0; + + int newLength = (fracDigitsp1 >>> 1) << 1; + boolean isOdd = (fracDigitsp1 & 1) == 1; + int i; + long temp, p; + + for(i = 0; i < newLength;) { + temp = digits[i]; + p = temp * temp; + + partials[i] = p; + PartialSum += p; + i++; + + temp = digits[i]; + p = temp * temp; + + partials[i] = p; + PartialSum += p; + i++; + + PartialCarry += PartialSum >>> SHIFT; + PartialSum &= MASK; + } + + if(isOdd) { + temp = digits[i]; + p = temp * temp; + + partials[i] = p; + PartialSum += p; + + PartialCarry += PartialSum >>> SHIFT; + PartialSum &= MASK; + } + + long old_sum; + + //for(int i = MAX_FRAC_DIGITS; i > 0; i--) { + //long sum += (int)(old_sum >>> SHIFT30); + + //long sum = (old_sum >>> SHIFT31); + + long p0 = partials[0]; + long sum = p0; + + int length = initialLength; + + long aj; + long ak; + + int j; + int k; + long carry = sum >>> SHIFT; + sum &= MASK; + + newLength = (length >>> 1) << 1; + isOdd = (length & 1) == 1; + + for (j = 1, k = fracDigits; j <= newLength; ) { + aj = digits[j]; + ak = digits[k]; + + + temp = aj + ak; + + sum += temp * temp; + + j++; k--; + + aj = digits[j]; + ak = digits[k]; + + + temp = aj + ak; + + sum += temp * temp; + + j++; k--; + + carry += sum >>> SHIFT; + sum &= MASK; + + //System.out.println("a" + j + " * " + "a " + k); + } + + if(isOdd) { + aj = digits[j]; + ak = digits[k]; + + temp = aj + ak; + + sum += temp * temp; + + j++; k--; + + //carry += sum >>> SHIFT; + //sum &= MASK; + } + + //System.out.println("OUT"); + //System.out.println("a" + j + " * " + "a " + k); + //int diff = k - j; + //int branchlessCheck = (diff >> 31) - (-diff >> 31); + + if(j == k) { + sum += (partials[k] << 1); + } + else { + aj = digits[j]; + ak = digits[k]; + temp = ak + aj; + sum += temp * temp; + } + + carry += sum >>> SHIFT; + sum &= MASK; + + sum -= PartialSum; + carry -= ((sum & MASK31) >>> SHIFT) + PartialCarry; + sum &= MASK; + + old_sum = carry + (sum >>> (SHIFTM1)); // Roundish + + length = fracDigitsHalf; + int length2 = evenFracDigits ? length : length + 1; + + for(i = fracDigits; i > 0; i-=2, length--, length2--) { + + carry = old_sum >>> SHIFT; + old_sum &= MASK; + sum = old_sum; + long sum2 = 0; + long carry2 = 0; + + k = length2; + long prevDigit = digits[k]; + long firstDigit = prevDigit; + + int range = length - ((length >>> 1) << 1); + isOdd = (length & 1) == 1; + + for(j = length - 1; j >= range;) { + aj = digits[j]; + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + temp = prevDigit + aj; + sum2 += temp * temp; + + k++; + + prevDigit = digits[k]; // ak + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + temp = prevDigit + aj; + sum += temp * temp; + + j--; + + aj = digits[j]; + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + temp = prevDigit + aj; + sum2 += temp * temp; + + k++; + + prevDigit = digits[k]; // ak + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + temp = prevDigit + aj; + sum += temp * temp; + + j--; + + carry += sum >>> SHIFT; + sum &= MASK; + carry2 += sum2 >>> SHIFT; + sum2 &= MASK; + } + + if(isOdd) { + aj = digits[j]; + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + temp = prevDigit + aj; + sum2 += temp * temp; + + k++; + + prevDigit = digits[k]; // ak + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + temp = prevDigit + aj; + sum += temp * temp; + +// carry1 += sum1 >>> SHIFT; +// sum1 &= MASK; +// carry2 += sum2 >>> SHIFT; +// sum2 &= MASK; + } + + if(evenFracDigits) { + sum += (partials[length] << 1); + } + else { + aj = digits[length]; + + temp = firstDigit + aj; + + sum += temp * temp; + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + sum2 += (partials[length] << 1); +// carry2 += sum2 >>> SHIFT; +// sum2 &= MASK; + } + + carry += sum >>> SHIFT; + sum &= MASK; + + sum -= PartialSum; + carry -= ((sum & MASK31) >>> SHIFT) + PartialCarry; + sum &= MASK; + + long partialI = partials[i]; + + PartialSum -= partialI & MASK; + PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFT; + PartialSum &= MASK; + + sum2 += carry; + carry2 += sum2 >>> SHIFT; + sum2 &= MASK; + + + sum2 -= PartialSum; + + resDigits[i] = (int) (sum); + + if(i > 1) { + + int im1 = i - 1; + carry2 -= ((sum2 & MASK31) >>> SHIFT) + PartialCarry; + sum2 &= MASK; + + partialI = partials[im1]; + + PartialSum -= partialI & MASK; + PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFT; + PartialSum &= MASK; + + old_sum = carry2; + + resDigits[im1] = (int) (sum2); + } + else { + sum2 &= MASK; + resDigits[0] = (int) (sum2); + } + } + + if(evenFracDigits) { + sum = p0 + old_sum; + + resDigits[0] = (int) (sum & MASKD0); + } + + result.sign = 1; + + return result; + } + + @Override + public BigNum30 mult(BigNum bb) { + BigNum30 b = (BigNum30) bb; + if(useKaratsuba) { + return multKaratsuba(b); + } + else { + return multFull(b); + } + } + + /* Sign is positive */ + @Override + public BigNum30 mult(int value) { + BigNum30 result = new BigNum30(); + + if(sign == 0 || value == 0) { + return result; + } + + int[] resDigits = result.digits; + + boolean bIsOne = value == 1 || value == -1; + + int bsign; + + if(value < 0) { + bsign = -1; + value = ~value + 1; + } + else { + bsign = 1; + } + + if(isOne || bIsOne) { + if (isOne && bIsOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = sign * bsign; + } + else if(isOne) { + resDigits[0] = value; + result.sign = sign * bsign; + } + else { + System.arraycopy(digits, 0, resDigits, 0, digits.length); + result.sign = sign * bsign; + } + return result; + } + + long old_sum = 0; + long sum; + long carry; + + int isNonZero = 0; + for(int i = fracDigits; i > 0; i--) { + sum = (long)digits[i] * value + old_sum; + carry = sum >>> SHIFT; + sum &= MASK; + + int di = (int) (sum); + resDigits[i] = di; + isNonZero |= di; + old_sum = carry; + } + + sum = (long)digits[0] * value + old_sum; + + int d0 = (int) (sum & MASKD0); + resDigits[0] = d0; + + result.isOne = d0 == 1 && isNonZero == 0; + + result.sign = sign * bsign; + + return result; + } + + @Deprecated + public BigNum30 multFullGolden(BigNum30 b) { + + BigNum30 result = new BigNum30(); + + if(sign == 0 || b.sign == 0) { + return result; + } + + int[] bdigits = b.digits; + + int[] resDigits = result.digits; + + if(isOne || b.isOne) { + if (isOne && b.isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = sign * b.sign; + } + else if(isOne) { + System.arraycopy(bdigits, 0, resDigits, 0, bdigits.length); + result.sign = sign * b.sign; + } + else { + System.arraycopy(digits, 0, resDigits, 0, digits.length); + result.sign = sign * b.sign; + } + return result; + } + + long old_sum; + + //for(int i = MAX_FRAC_DIGITS; i > 0; i--) { + + //long sum = (old_sum >>> SHIFT31); + // + long sum = 0; + long carry = 0; + long bj; + long ak; + for (int j = 1, k = fracDigits; j <= fracDigits; j++, k--) { + bj = bdigits[j]; + ak = digits[k]; + + sum += bj * ak; + carry += sum >>> SHIFT; + sum &= MASK; + + } + + old_sum = carry + (sum >>> (SHIFTM1)); // Roundish + + //System.out.println(); + //} + + int isNonZero = 0; + for(int i = fracDigits; i > 0; i--) { + + sum = old_sum; //carry from prev + carry = 0; + for(int j = 0, k = i; j <= i; j++, k--) { + bj = bdigits[j]; + ak = digits[k]; + + sum += bj * ak; + carry += sum >>> SHIFT; + sum &= MASK; + + //System.out.println("b" + j + " * " + "a " + k); + } + + int di = (int) (sum); + resDigits[i] = di; + isNonZero |= di; + //System.out.println(result.digits[i] ); + old_sum = carry; + //System.out.println("NEXT"); + } + + sum = old_sum; + + bj = bdigits[0]; + ak = digits[0]; + + sum += bj * ak; + + int d0 = (int) (sum & MASKD0); + resDigits[0] = d0; + + result.isOne = d0 == 1 && isNonZero == 0; + + result.sign = sign * b.sign; + + return result; + + } + + /* A backwards function might have better performance after 3333 digits */ + //Todo: test it + public BigNum30 multFull(BigNum30 b) { + + BigNum30 result = new BigNum30(); + + if(sign == 0 || b.sign == 0) { + return result; + } + + int[] bdigits = b.digits; + + int[] resDigits = result.digits; + + if(isOne || b.isOne) { + if (isOne && b.isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = sign * b.sign; + } + else if(isOne) { + System.arraycopy(bdigits, 0, resDigits, 0, bdigits.length); + result.sign = sign * b.sign; + } + else { + System.arraycopy(digits, 0, resDigits, 0, digits.length); + result.sign = sign * b.sign; + } + return result; + } + + long old_sum; + + //for(int i = MAX_FRAC_DIGITS; i > 0; i--) { + + //long sum = (old_sum >>> SHIFT31); + // + long sum = 0; + long carry = 0; + long bj; + long ak; + + int newLength = fracDigitsHalf << 1; + + int j, k; + + for (j = 1, k = fracDigits; j <= newLength;) { + bj = bdigits[j]; + ak = digits[k]; + + sum += bj * ak; + + j++;k--; + + bj = bdigits[j]; + ak = digits[k]; + + sum += bj * ak; + + j++;k--; + + carry += sum >>> SHIFT; + sum &= MASK; + } + + if(!evenFracDigits) { + bj = bdigits[j]; + ak = digits[k]; + sum += bj * ak; + carry += sum >>> SHIFT; + sum &= MASK; + } + + old_sum = carry + (sum >>> (SHIFTM1)); // Roundish + + //System.out.println(); + //} + + long a0 = digits[0]; + + int isNonZero = 0; + for(int i = fracDigits; i > 0; i-=2) { + sum = 0; + long sum2 = 0; + carry = old_sum >>> SHIFT; + old_sum &= MASK; + long carry2 = 0; + + k = i; + long prevDigit = digits[k]; + + newLength = (i >>> 1) << 1; + boolean isOdd = (i & 1) == 1; + + for(j = 0; j < newLength;) { + bj = bdigits[j]; + sum += prevDigit * bj; + + //System.out.println("b" + j + " * " + "a " + k); + + k--; + + prevDigit = digits[k]; //ak + sum2 += prevDigit * bj; + //System.out.println("b" + j + " * " + "a " + k); + + j++; + + bj = bdigits[j]; + sum += prevDigit * bj; + //System.out.println("b" + j + " * " + "a " + k); + + k--; + + prevDigit = digits[k]; //ak + sum2 += prevDigit * bj; + //System.out.println("b" + j + " * " + "a " + k); + + j++; + + carry += sum >>> SHIFT; + sum &= MASK; + + carry2 += sum2 >>> SHIFT; + sum2 &= MASK; + } + + if(isOdd) { + bj = bdigits[j]; + sum += prevDigit * bj; + //System.out.println("b" + j + " * " + "a " + k); + + k--; + + prevDigit = digits[k]; //ak + sum2 += prevDigit * bj; + //System.out.println("b" + j + " * " + "a " + k); + +// carry1 += temp_sum1 >>> SHIFT; +// temp_sum1 &= MASK; +// +// carry2 += temp_sum2 >>> SHIFT; +// temp_sum2 &= MASK; + j++; + } + + bj = bdigits[j]; + + sum += prevDigit * bj + old_sum; + //System.out.println("b" + j + " * " + "a " + k); + //carry1 += temp_sum1 >>> SHIFT; + //temp_sum1 &= MASK; + + carry += sum >>> SHIFT; + sum &= MASK; + + //System.out.println("NEXT"); + + int di = (int) (sum); + isNonZero |= di; + resDigits[i] = di; + + + if(i > 1) { + int im1 = i - 1; + sum2 += carry; + + carry2 += sum2 >>> SHIFT; + sum2 &= MASK; + old_sum = carry2; + + di = (int) (sum2); + isNonZero |= di; + resDigits[im1] = di; + } + else { + sum2 += carry; + int d0 = (int) (sum2 & MASKD0); + resDigits[0] = d0; + result.isOne = d0 == 1 && isNonZero == 0; + } + + } + + if(evenFracDigits) { + bj = bdigits[0]; + + sum = bj * a0 + old_sum; + + int d0 = (int) (sum & MASKD0); + resDigits[0] = d0; + + result.isOne = d0 == 1 && isNonZero == 0; + } + + result.sign = sign * b.sign; + + return result; + + } + + public BigNum30 multFullBackwards(BigNum30 b) { + + BigNum30 result = new BigNum30(); + + if(sign == 0 || b.sign == 0) { + return result; + } + + int[] bdigits = b.digits; + + int[] resDigits = result.digits; + + if(isOne || b.isOne) { + if (isOne && b.isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = sign * b.sign; + } + else if(isOne) { + System.arraycopy(bdigits, 0, resDigits, 0, bdigits.length); + result.sign = sign * b.sign; + } + else { + System.arraycopy(digits, 0, resDigits, 0, digits.length); + result.sign = sign * b.sign; + } + return result; + } + + long old_sum; + + //for(int i = MAX_FRAC_DIGITS; i > 0; i--) { + + //long sum = (old_sum >>> SHIFT31); + // + long sum = 0; + long carry = 0; + long bj; + long ak; + + int newLength = fracDigitsHalf << 1; + + int j, k; + + for (j = 1, k = fracDigits; j <= newLength;) { + bj = bdigits[j]; + ak = digits[k]; + + sum += bj * ak; + + j++;k--; + + bj = bdigits[j]; + ak = digits[k]; + + sum += bj * ak; + + j++;k--; + + carry += sum >>> SHIFT; + sum &= MASK; + } + + if(!evenFracDigits) { + bj = bdigits[j]; + ak = digits[k]; + sum += bj * ak; + carry += sum >>> SHIFT; + sum &= MASK; + } + + old_sum = carry + (sum >>> (SHIFTM1)); // Roundish + + //System.out.println(); + //} + + long a0 = digits[0]; + + int isNonZero = 0; + for(int i = fracDigits; i > 0; i-=2) { + int im1 = i - 1; + carry = old_sum >>> SHIFT; + old_sum &= MASK; + sum = 0; + long sum2 = 0; + long carry2 = 0; + + k = 0; + + long prevDigit = bdigits[i]; + + int range = i - ((i >>> 1) << 1); + boolean isOdd = (i & 1) == 1; + + for(j = i; j > range;) { + ak = digits[k]; + sum += prevDigit * ak; + + //System.out.println("b" + j + " * " + "a " + k); + j--; + + prevDigit = bdigits[j]; + sum2 += prevDigit * ak; + //System.out.println("b" + j + " * " + "a " + k); + k++; + + ak = digits[k]; + sum += prevDigit * ak; + + //System.out.println("b" + j + " * " + "a " + k); + j--; + + prevDigit = bdigits[j]; + sum2 += prevDigit * ak; + //System.out.println("b" + j + " * " + "a " + k); + k++; + + carry += sum >>> SHIFT; + sum &= MASK; + + carry2 += sum2 >>> SHIFT; + sum2 &= MASK; + } + + if(isOdd) { + ak = digits[k]; + sum += prevDigit * ak; + + //System.out.println("b" + j + " * " + "a " + k); + j--; + + prevDigit = bdigits[j]; + sum2 += prevDigit * ak; + //System.out.println("b" + j + " * " + "a " + k); + k++; + +// carry1 += temp_sum1 >>> SHIFT; +// temp_sum1 &= MASK; +// +// carry2 += temp_sum2 >>> SHIFT; +// temp_sum2 &= MASK; + } + + + //System.out.println("b" + j + " * " + "a " + k); + ak = digits[k]; + sum += prevDigit * ak + old_sum; + //carry1 += temp_sum1 >>> SHIFT; + //temp_sum1 &= MASK; + + //System.out.println("b" + i + " * " + "a " + startIndex); + + carry += sum >>> SHIFT; + sum &= MASK; + + //System.out.println("NEXT"); + + int di = (int) (sum); + isNonZero |= di; + resDigits[i] = di; + + + if(i > 1) { + sum2 += carry; + + carry2 += sum2 >>> SHIFT; + sum2 &= MASK; + old_sum = carry2; + + di = (int) (sum2); + isNonZero |= di; + resDigits[im1] = di; + } + else { + sum2 += carry; + int d0 = (int) (sum2 & MASKD0); + resDigits[0] = d0; + result.isOne = d0 == 1 && isNonZero == 0; + } + + } + + if(evenFracDigits) { + bj = bdigits[0]; + + sum = bj * a0 + old_sum; + + int d0 = (int) (sum & MASKD0); + resDigits[0] = d0; + + result.isOne = d0 == 1 && isNonZero == 0; + } + + result.sign = sign * b.sign; + + return result; + + } + + @Deprecated + public BigNum30 multKaratsubaGolden(BigNum30 b) { + + BigNum30 result = new BigNum30(); + + if(sign == 0 || b.sign == 0) { + return result; + } + + int[] bdigits = b.digits; + int[] resDigits = result.digits; + + if(isOne || b.isOne) { + if (isOne && b.isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = sign * b.sign; + } + else if(isOne) { + System.arraycopy(bdigits, 0, resDigits, 0, bdigits.length); + result.sign = sign * b.sign; + } + else { + System.arraycopy(digits, 0, resDigits, 0, digits.length); + result.sign = sign * b.sign; + } + return result; + } + + long[] partials = new long[fracDigitsp1]; + long[] partialSums = new long[fracDigitsp1]; + long[] partialCarries = new long[fracDigitsp1]; + + long PartialSum = 0; + long PartialCarry = 0; + for (int i = 0; i < fracDigitsp1; i++) { + long p = ((long) digits[i]) * ((long) bdigits[i]); + partials[i] = p; + PartialSum += p; + + PartialCarry += PartialSum >>> SHIFT; + PartialSum &= MASK; + + partialSums[i] = PartialSum; + partialCarries[i] = PartialCarry; + } + + + long old_sum; + + long p0 = partials[0]; + + long sum = p0; + + int length = initialLength; + + int j; + int k; + long carry = 0; + long bj, bk, aj, ak; + for (j = 1, k = fracDigits; j <= length; j++, k--) { + bj = bdigits[j]; + bk = bdigits[k]; + aj = digits[j]; + ak = digits[k]; + + sum += (bk + bj) * (ak + aj); + carry += sum >>> SHIFT; + sum &= MASK; + + //System.out.println("partials " + k + " partials " + j); + + } + + //System.out.println("partials " + k + " partials " + j); + + //System.out.println("Next"); + + //int diff = k - j; + //int branchlessCheck = (diff >> 31) - (-diff >> 31); + + + //System.out.println("partials " + k + " partials " + j); + + //System.out.println("NEXT"); + + //System.out.println("OUT"); + //System.out.println("b" + j + " * " + "a " + k); + + if(j == k) { + sum += (partials[k] << 1); + } + else { + bj = bdigits[j]; + bk = bdigits[k]; + aj = digits[j]; + ak = digits[k]; + sum += (bk + bj) * (ak + aj); + } + + carry += sum >>> SHIFT; + sum &= MASK; + + sum -= PartialSum; + carry -= ((sum & MASK31) >>> SHIFT) + PartialCarry; + sum &= MASK; + + //sum += (1 - branchlessCheck) * partials[k] + branchlessCheck * ((bk + bj) * (ak + aj) - partials[k] - partials[j]); + + old_sum = carry + (sum >>> (SHIFTM1)); // Roundish, adds bias because 10000 is always shifted upwards + + + int isNonZero = 0; + for(int i = fracDigits; i > 0; i--) { + + length = (i >> 1) - 1; + + sum = old_sum; //carry from prev + + carry = 0; + for(j = 0, k = i; j <= length; j++, k--) { + bj = bdigits[j]; + bk = bdigits[k]; + aj = digits[j]; + ak = digits[k]; + + sum += (bk + bj) * (ak + aj); + + carry += sum >>> SHIFT; + sum &= MASK; + //System.out.println("partials " + k + " partials " + j); + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + } + + if(j == k) { + sum += (partials[k] << 1); + } + else { + bj = bdigits[j]; + bk = bdigits[k]; + aj = digits[j]; + ak = digits[k]; + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + sum += (bk + bj) * (ak + aj); + } + + //System.out.println("NEXT"); + + carry += sum >>> SHIFT; + sum &= MASK; + + sum -= PartialSum; + carry -= ((sum & MASK31) >>> SHIFT) + PartialCarry; + sum &= MASK; + + if(i > 1) { + int im1 = i - 1; + PartialSum = partialSums[im1]; + PartialCarry = partialCarries[im1]; + + //long partialI = partials[i]; + + //PartialSum -= partialI & MASK; + //PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFT; + //PartialSum &= MASK; + } + + + //System.out.println("partials " + k + " partials " + j); + //System.out.println("NEXT"); + + + int di = (int) (sum); + isNonZero |= di; + resDigits[i] = di; + //System.out.println(result.digits[i] ); + old_sum = carry; + //System.out.println("NEXT"); + } + + sum = old_sum; + + sum += p0; + + int d0 = (int) (sum & MASKD0); + resDigits[0] = d0; + + result.sign = sign * b.sign; + + result.isOne = d0 == 1 && isNonZero == 0; + + return result; + + } + + public BigNum30 multKaratsubaBackwards(BigNum30 b) { + + BigNum30 result = new BigNum30(); + + if(sign == 0 || b.sign == 0) { + return result; + } + + int[] bdigits = b.digits; + int[] resDigits = result.digits; + + if(isOne || b.isOne) { + if (isOne && b.isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = sign * b.sign; + } + else if(isOne) { + System.arraycopy(bdigits, 0, resDigits, 0, bdigits.length); + result.sign = sign * b.sign; + } + else { + System.arraycopy(digits, 0, resDigits, 0, digits.length); + result.sign = sign * b.sign; + } + return result; + } + + long[] partials = new long[fracDigitsp1]; + + long PartialSum = 0; + long PartialCarry = 0; + + int newLength = (fracDigitsp1 >>> 1) << 1; + boolean isOdd = (fracDigitsp1 & 1) == 1; + long p; + int i; + for(i = 0; i < newLength;) { + p = ((long)digits[i]) * ((long)bdigits[i]); + partials[i] = p; + PartialSum += p; + + i++; + + p = ((long)digits[i]) * ((long)bdigits[i]); + partials[i] = p; + PartialSum += p; + + i++; + + PartialCarry += PartialSum >>> SHIFT; + PartialSum &= MASK; + } + + if(isOdd) { + p = ((long)digits[i]) * ((long)bdigits[i]); + partials[i] = p; + PartialSum += p; + PartialCarry += PartialSum >>> SHIFT; + PartialSum &= MASK; + } + + long old_sum; + + long p0 = partials[0]; + + long sum = p0; + + int length = initialLength; + + int j; + int k; + // long carry = sum >>> SHIFT; + // sum &= MASK; + long carry = 0; + + long bj, bk, aj, ak; + + newLength = (length >>> 1) << 1; + isOdd = (length & 1) == 1; + + for (j = 1, k = fracDigits; j <= newLength;) { + bj = bdigits[j]; + bk = bdigits[k]; + aj = digits[j]; + ak = digits[k]; + + sum += (bk + bj) * (ak + aj); + + j++; k--; + + bj = bdigits[j]; + bk = bdigits[k]; + aj = digits[j]; + ak = digits[k]; + + sum += (bk + bj) * (ak + aj); + + j++; k--; + + carry += sum >>> SHIFT; + sum &= MASK; + + //System.out.println("partials " + k + " partials " + j); + + } + + if(isOdd) { + bj = bdigits[j]; + bk = bdigits[k]; + aj = digits[j]; + ak = digits[k]; + + sum += (bk + bj) * (ak + aj); + + j++; k--; + + //carry += sum >>> SHIFT; + //sum &= MASK; + } + + if(j == k) { + sum += (partials[k] << 1); + } + else { + bj = bdigits[j]; + bk = bdigits[k]; + aj = digits[j]; + ak = digits[k]; + sum += (bk + bj) * (ak + aj); + } + + carry += sum >>> SHIFT; + sum &= MASK; + + sum -= PartialSum; + carry -= ((sum & MASK31) >>> SHIFT) + PartialCarry; + sum &= MASK; + + old_sum = carry + (sum >>> (SHIFTM1)); // Roundish, adds bias because 10000 is always shifted upwards + + + int isNonZero = 0; + + length = fracDigitsHalf; + int length2 = evenFracDigits ? length : length + 1; + + for(i = fracDigits; i > 0; i-=2, length--, length2--) { + + //carry = old_sum >>> SHIFT; + //old_sum &= MASK; + carry = 0; + sum = old_sum; + long sum2 = 0; + long carry2 = 0; + + k = length2; + long prevDigit = digits[k]; + long prevDigit2 = bdigits[k]; + long startDigit = prevDigit; + long startDigit2 = prevDigit2; + + int range = length - ((length >>> 1) << 1); + isOdd = (length & 1) == 1; + + for(j = length - 1; j >= range;) { + aj = digits[j]; + bj = bdigits[j]; + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + sum2 += (prevDigit2 + bj) * (prevDigit + aj); + + k++; + + prevDigit = digits[k]; //ak + prevDigit2 = bdigits[k]; //bk + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + sum += (prevDigit2 + bj) * (prevDigit + aj); + j--; + + aj = digits[j]; + bj = bdigits[j]; + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + sum2 += (prevDigit2 + bj) * (prevDigit + aj); + + k++; + + prevDigit = digits[k]; //ak + prevDigit2 = bdigits[k]; //bk + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + sum += (prevDigit2 + bj) * (prevDigit + aj); + j--; + + carry += sum >>> SHIFT; + sum &= MASK; + carry2 += sum2 >>> SHIFT; + sum2 &= MASK; + + } + + if(isOdd) { + aj = digits[j]; + bj = bdigits[j]; + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + sum2 += (prevDigit2 + bj) * (prevDigit + aj); + + k++; + + prevDigit = digits[k]; //ak + prevDigit2 = bdigits[k]; //bk + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + sum += (prevDigit2 + bj) * (prevDigit + aj); + +// carry1 += sum1 >>> SHIFT; +// sum1 &= MASK; +// carry2 += sum2 >>> SHIFT; +// sum2 &= MASK; + } + + if(evenFracDigits) { + sum += (partials[length] << 1); + } + else { + aj = digits[length]; + bj = bdigits[length]; + + sum += (startDigit2 + bj) * (startDigit + aj); + + //System.out.println("b " + length + " b " + length2 + " a " + length + " a " + length2); + + sum2 += (partials[length] << 1); +// carry2 += sum2 >>> SHIFT; +// sum2 &= MASK; + } + + //System.out.println("NEXT"); + + carry += sum >>> SHIFT; + sum &= MASK; + + sum -= PartialSum; + carry -= ((sum & MASK31) >>> SHIFT) + PartialCarry; + sum &= MASK; + + long partialI = partials[i]; + + PartialSum -= partialI & MASK; + PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFT; + PartialSum &= MASK; + + sum2 += carry; + carry2 += sum2 >>> SHIFT; + sum2 &= MASK; + + + sum2 -= PartialSum; + + int di = (int) (sum); + isNonZero |= di; + resDigits[i] = di; + + if(i > 1) { + + int im1 = i - 1; + carry2 -= ((sum2 & MASK31) >>> SHIFT) + PartialCarry; + sum2 &= MASK; + + partialI = partials[im1]; + + PartialSum -= partialI & MASK; + PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFT; + PartialSum &= MASK; + + old_sum = carry2; + + di = (int) (sum2); + isNonZero |= di; + resDigits[im1] = di; + } + else { + sum2 &= MASK; + int d0 = (int) (sum2 & MASKD0); + resDigits[0] = d0; + result.isOne = d0 == 1 && isNonZero == 0; + } + } + + if(evenFracDigits) { + sum = p0 + old_sum; + + int d0 = (int) (sum & MASKD0); + resDigits[0] = d0; + + //result.isOne = ( (((d0 ^ isNonZero) | d0) & ~(isNonZero & 0x1)) ) == 1 + result.isOne = d0 == 1 && isNonZero == 0; + } + + result.sign = sign * b.sign; + + return result; + + } + + public BigNum30 multKaratsuba(BigNum30 b) { + + BigNum30 result = new BigNum30(); + + if(sign == 0 || b.sign == 0) { + return result; + } + + int[] bdigits = b.digits; + int[] resDigits = result.digits; + + if(isOne || b.isOne) { + if (isOne && b.isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = sign * b.sign; + } + else if(isOne) { + System.arraycopy(bdigits, 0, resDigits, 0, bdigits.length); + result.sign = sign * b.sign; + } + else { + System.arraycopy(digits, 0, resDigits, 0, digits.length); + result.sign = sign * b.sign; + } + return result; + } + + long[] partials = new long[fracDigitsp1]; + + long PartialSum = 0; + long PartialCarry = 0; + + int newLength = (fracDigitsp1 >>> 1) << 1; + boolean isOdd = (fracDigitsp1 & 1) == 1; + long p; + int i; + for(i = 0; i < newLength;) { + p = ((long)digits[i]) * ((long)bdigits[i]); + partials[i] = p; + PartialSum += p; + + i++; + + p = ((long)digits[i]) * ((long)bdigits[i]); + partials[i] = p; + PartialSum += p; + + i++; + + PartialCarry += PartialSum >>> SHIFT; + PartialSum &= MASK; + } + + if(isOdd) { + p = ((long)digits[i]) * ((long)bdigits[i]); + partials[i] = p; + PartialSum += p; + PartialCarry += PartialSum >>> SHIFT; + PartialSum &= MASK; + } + + long old_sum; + + long p0 = partials[0]; + + long sum = p0; + + int length = initialLength; + + int j; + int k; + // long carry = sum >>> SHIFT; + // sum &= MASK; + long carry = 0; + long bj, bk, aj, ak; + + newLength = (length >>> 1) << 1; + isOdd = (length & 1) == 1; + + for (j = 1, k = fracDigits; j <= newLength;) { + bj = bdigits[j]; + bk = bdigits[k]; + aj = digits[j]; + ak = digits[k]; + + sum += (bk + bj) * (ak + aj); + + j++; k--; + + bj = bdigits[j]; + bk = bdigits[k]; + aj = digits[j]; + ak = digits[k]; + + sum += (bk + bj) * (ak + aj); + + j++; k--; + + carry += sum >>> SHIFT; + sum &= MASK; + + //System.out.println("partials " + k + " partials " + j); + + } + + if(isOdd) { + bj = bdigits[j]; + bk = bdigits[k]; + aj = digits[j]; + ak = digits[k]; + + sum += (bk + bj) * (ak + aj); + + j++; k--; + + //carry += sum >>> SHIFT; + //sum &= MASK; + } + + if(j == k) { + sum += (partials[k] << 1); + } + else { + bj = bdigits[j]; + bk = bdigits[k]; + aj = digits[j]; + ak = digits[k]; + sum += (bk + bj) * (ak + aj); + } + + carry += sum >>> SHIFT; + sum &= MASK; + + sum -= PartialSum; + carry -= ((sum & MASK31) >>> SHIFT) + PartialCarry; + sum &= MASK; + + old_sum = carry + (sum >>> (SHIFTM1)); // Roundish, adds bias because 10000 is always shifted upwards + + + int isNonZero = 0; + + length = fracDigitsHalf; + + for(i = fracDigits; i > 0; i-=2, length--) { + + //carry = old_sum >>> SHIFT; + //old_sum &= MASK; + carry = 0; + sum = old_sum; + long sum2 = 0; + long carry2 = 0; + + k = i; + + long prevDigit = digits[k]; + long prevDigit2 = bdigits[k]; + + newLength = (length >>> 1) << 1; + isOdd = (length & 1) == 1; + + for(j = 0; j < newLength;) { + aj = digits[j]; + bj = bdigits[j]; + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + + sum += (prevDigit2 + bj) * (prevDigit + aj); + + k--; + + prevDigit = digits[k]; // ak + prevDigit2 = bdigits[k]; + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + sum2 += (prevDigit2 + bj) * (prevDigit + aj); + j++; + + aj = digits[j]; + bj = bdigits[j]; + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + + sum += (prevDigit2 + bj) * (prevDigit + aj); + + k--; + + prevDigit = digits[k]; // ak + prevDigit2 = bdigits[k]; + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + sum2 += (prevDigit2 + bj) * (prevDigit + aj); + j++; + + carry += sum >>> SHIFT; + sum &= MASK; + carry2 += sum2 >>> SHIFT; + sum2 &= MASK; + } + + if(isOdd) { + aj = digits[j]; + bj = bdigits[j]; + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + sum += (prevDigit2 + bj) * (prevDigit + aj); + + k--; + + prevDigit = digits[k]; // ak + prevDigit2 = bdigits[k]; + + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + sum2 += (prevDigit2 + bj) * (prevDigit + aj); + +// carry1 += sum1 >>> SHIFT; +// sum1 &= MASK; +// carry2 += sum2 >>> SHIFT; +// sum2 &= MASK; + } + + if(evenFracDigits) { + sum += (partials[length] << 1); + } + else { + aj = digits[length]; + bj = bdigits[length]; + + sum += (prevDigit2 + bj) * (prevDigit + aj); + + //System.out.println("b " + length + " b " + length2 + " a " + length + " a " + length2); + + sum2 += (partials[length] << 1); + +// carry2 += sum2 >>> SHIFT; +// sum2 &= MASK; + } + + //System.out.println("NEXT"); + + carry += sum >>> SHIFT; + sum &= MASK; + + sum -= PartialSum; + carry -= ((sum & MASK31) >>> SHIFT) + PartialCarry; + sum &= MASK; + + long partialI = partials[i]; + + PartialSum -= partialI & MASK; + PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFT; + PartialSum &= MASK; + + sum2 += carry; + carry2 += sum2 >>> SHIFT; + sum2 &= MASK; + + + sum2 -= PartialSum; + + int di = (int) (sum); + isNonZero |= di; + resDigits[i] = di; + + if(i > 1) { + + int im1 = i - 1; + carry2 -= ((sum2 & MASK31) >>> SHIFT) + PartialCarry; + sum2 &= MASK; + + partialI = partials[im1]; + + PartialSum -= partialI & MASK; + PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFT; + PartialSum &= MASK; + + old_sum = carry2; + + di = (int) (sum2); + isNonZero |= di; + resDigits[im1] = di; + } + else { + sum2 &= MASK; + int d0 = (int) (sum2 & MASKD0); + resDigits[0] = d0; + result.isOne = d0 == 1 && isNonZero == 0; + } + } + + if(evenFracDigits) { + sum = p0 + old_sum; + + int d0 = (int) (sum & MASKD0); + resDigits[0] = d0; + + //result.isOne = ( (((d0 ^ isNonZero) | d0) & ~(isNonZero & 0x1)) ) == 1 + result.isOne = d0 == 1 && isNonZero == 0; + } + + result.sign = sign * b.sign; + + return result; + + } + + /*mult2, mult4, divide2, divide4, multFull, multKaratsuba, square and squareKaratsuba + might overflow or underflow leading to zero but the sign will not be set to 0 + */ + + @Override + public BigNum30 mult2() { + + BigNum30 res = new BigNum30(); + + if(sign == 0) { + return res; + } + + int [] resDigits = res.digits; + + if(isOne) { + resDigits[0] = 2; + res.sign = sign; + return res; + } + + int isNonZero = 0; + + int temp = digits[fracDigits] << 1; + int val = temp & MASKINT; + resDigits[fracDigits] = val; + isNonZero |= val; + + for(int i = fracDigitsm1; i > 0; i--) { + temp = (digits[i] << 1) | (temp >>> SHIFT); + val = temp & MASKINT; + resDigits[i] = val; + isNonZero |= val; + } + + temp = (digits[0] << 1) | (temp >>> SHIFT); + int d0 = (int)(temp & MASKD0); + resDigits[0] = d0; + res.sign = sign; + res.isOne = d0 == 1 && isNonZero == 0; + return res; + + } + + @Override + public BigNum30 divide2() { + + BigNum30 res = new BigNum30(); + + if(sign == 0) { + return res; + } + + int [] resDigits = res.digits; + + if(isOne) { + resDigits[1] = 0x20000000; + res.sign = sign; + return res; + } + + int isNonZero = 0; + + int d0 = digits[0]; + int temp = d0; + int val = temp >>> 1; + + int bit = temp & 0x1; + + resDigits[0] = val; + isNonZero |= val; + + for(int i=1; i < fracDigits; i++) { + temp = digits[i]; + temp |= (bit << SHIFT); + bit = temp & 0x1; + temp >>>= 1; + val = temp & MASKINT; + resDigits[i] = val; + isNonZero |= val; + } + + temp = digits[fracDigits]; + temp |= (bit << SHIFT); + temp >>>= 1; + val = temp & MASKINT; + resDigits[fracDigits] = val; + isNonZero |= val; + res.sign = sign; + res.isOne = d0 == 1 && isNonZero == 0; + return res; + + } + + @Override + public BigNum30 divide4() { + + BigNum30 res = new BigNum30(); + + if(sign == 0) { + return res; + } + + int [] resDigits = res.digits; + + if(isOne) { + resDigits[1] = 0x10000000; + res.sign = sign; + return res; + } + + int isNonZero = 0; + + int d0 = digits[0]; + int temp = d0; + int val = temp >>> 2; + + int bits = temp & 0x3; + + resDigits[0] = val; + isNonZero |= val; + + for(int i=1; i < fracDigits; i++) { + temp = digits[i]; + temp |= (bits << SHIFT); + bits = temp & 0x3; + temp >>>= 2; + val = temp & MASKINT; + resDigits[i] = val; + isNonZero |= val; + } + + temp = digits[fracDigits]; + temp |= (bits << SHIFT); + temp >>>= 2; + val = temp & MASKINT; + resDigits[fracDigits] = val; + isNonZero |= val; + res.sign = sign; + res.isOne = d0 == 1 && isNonZero == 0; + return res; + + } + + @Override + public BigNum30 mult4() { + + BigNum30 res = new BigNum30(); + + if(sign == 0) { + return res; + } + + int [] resDigits = res.digits; + + if(isOne) { + resDigits[0] = 4; + res.sign = sign; + return res; + } + + int isNonZero = 0; + + int temp = digits[fracDigits] << 2; + int val = temp & MASKINT; + resDigits[fracDigits] = val; + isNonZero |= val; + + for(int i=fracDigitsm1; i > 0; i--) { + temp = (digits[i] << 2) | (temp >>> SHIFT); + val = temp & MASKINT; + resDigits[i] = val; + isNonZero |= val; + } + + temp = (digits[0] << 2) | (temp >>> SHIFT); + int d0 = (int)(temp & MASKD0); + resDigits[0] = d0; + res.sign = sign; + res.isOne = d0 == 1 && isNonZero == 0; + return res; + + } + + /* + Too slow + */ + public BigNum30 divide(BigNum30 b) { + + if(b.sign == 0) { + BigNum30 result = getMax(); + result.sign = sign; + } + + BigNum30 result = new BigNum30(); + + if(sign == 0) { + return result; + } + + if (isOne && b.isOne) { + result.digits[0] = 1; + result.isOne = true; + result.sign = sign * b.sign; + return result; + } + else if (b.isOne){ + System.arraycopy(digits, 0, result.digits, 0, digits.length); + result.sign = sign * b.sign; + return result; + } + + BigNum30 low = new BigNum30(); + BigNum30 high = this.compare(b) < 0 ? new BigNum30(1) : new BigNum30(0x7fffffff); + + BigNum30 oldVal = null; + + //int iterations = 0; + + while (true) { + BigNum30 mid = low.add(high.sub(low).divide2()); + + BigNum30 temp = b.mult(mid); + + BigNum30 val = temp.sub(this); + + if(oldVal != null && val.compare(oldVal) == 0) { + result.digits = mid.digits; + result.sign = sign * b.sign; + result.isOne = result.digits[0] == 1 && isFractionalPartZero(result.digits); + return result; + } + + oldVal = val; + + if(temp.compare(this) < 0) { + low = mid; + } + else { + high = mid; + } + //iterations++; + } + + + } + + /* + Too slow + */ + public BigNum30 reciprocal() { + + if(sign == 0) { + BigNum30 result = getMax(); + result.sign = sign; + } + + BigNum30 result = new BigNum30(); + + if (isOne) { + result.digits[0] = 1; + result.isOne = true; + result.sign = sign; + return result; + } + + BigNum30 low = new BigNum30(); + BigNum30 high = digits[0] != 0 ? new BigNum30(1) : new BigNum30(0x7fffffff); + + BigNum30 oldVal = null; + + BigNum30 one = new BigNum30(1); + + while (true) { + BigNum30 mid = low.add(high.sub(low).divide2()); + + BigNum30 temp = this.mult(mid); + + BigNum30 val = temp.sub(one); + + if(oldVal != null && val.compare(oldVal) == 0) { + result.digits = mid.digits; + result.sign = sign; + result.isOne = result.digits[0] == 1 && isFractionalPartZero(result.digits); + return result; + } + + oldVal = val; + + if(temp.compare(one) < 0) { + low = mid; + } + else { + high = mid; + } + } + + + } + + @Override + public MantExp getMantExp() { + + if (sign == 0) { + return new MantExp(); + } + + if(isOne) { + return new MantExp(sign); + } + + int[] digits = this.digits; + + int i; + int digit = 0; + if(offset == -1) { + for (i = 0; i < digits.length; i++) { + digit = digits[i]; + if (digit != 0) { + break; + } + } + + if (i == digits.length) { + return new MantExp(); + } + + /*int r; + for(r = i == 0 ? SHIFT : SHIFTM1; r >= 0; r--) { + if(digits[i] >>> r != 0) { + break; + } + }*/ + + offset = i; + long v = digit; + double d = v & ~(v >>> 1); + //int r = (int)(((Double.doubleToRawLongBits(d) >> 52) & 0x7ff) - 1023); //Fix for the 64 bit, not needed here + bitOffset = (int) ((Double.doubleToRawLongBits(d) >> 52) - 1023); + //r |= (r >> 31); //Fix for zero, not needed here + + //bitOffset = 31 - Integer.numberOfLeadingZeros(digit); + + scale = i == 0 ? bitOffset : -(((long) i) * SHIFT) + bitOffset; + } + else { + i = offset; + digit = digits[i]; + } + + long mantissa = 0; + + int temp = 52 - bitOffset; + mantissa |= ((long)digit) << temp; //Will always be positive + mantissa &= 0xFFFFFFFFFFFFFL; + + //System.out.println(digits[i]); + + i++; + + int k; + for(k = bitOffset ; k < 52 && i < digits.length; k+=SHIFT, i++) { + long val = digits[i]; + temp = 52 - k; + + if(temp > SHIFT) { + mantissa |= val << (temp - SHIFT); + mantissa &= 0xFFFFFFFFFFFFFL; + } + else { + int temp2 = k + SHIFTM52; + mantissa |= val >>> temp2; + mantissa &= 0xFFFFFFFFFFFFFL; + + if(temp2 == 0 && i + 1 < digits.length) { + long val2 = digits[i + 1]; + mantissa += (val2 >>> (SHIFTM1)) & 0x1; //Rounding + } + else { + mantissa += (val >>> (temp2 - 1)) & 0x1; //Rounding + } + } + } + + // Bit 63 (the bit that is selected by the mask 0x8000000000000000L) represents the sign of the floating-point number. + // Bits 62-52 (the bits that are selected by the mask 0x7ff0000000000000L) represent the exponent. + // Bits 51-0 (the bits that are selected by the mask 0x000fffffffffffffL) represent the significand (sometimes called the mantissa) of the floating-point number. + + int exp = (int)(scale + (mantissa >>> 52)); + double mantissaDouble; + + if(sign == -1) { + mantissaDouble = Double.longBitsToDouble( (0x8000000000000000L) | (mantissa & 0xFFFFFFFFFFFFFL) | (0x3FF0000000000000L)); + } + else { + mantissaDouble = Double.longBitsToDouble((mantissa & 0xFFFFFFFFFFFFFL) | (0x3FF0000000000000L)); + } + + return new MantExp(exp, mantissaDouble); + + + + } + + public static boolean isFractionalPartZero(int[] digits) { + + for(int i = 1; i < digits.length; i++) { + if(digits[i] != 0) { + return false; + } + } + + return true; + } + + public static BigNum30 max(BigNum30 a, BigNum30 b) { + return a.compare(b) > 0 ? a : b; + } + + public static BigNum30 min(BigNum30 a, BigNum30 b) { + return a.compare(b) < 0 ? a : b; + } + + public BigNum30 mult2to30(int times) { + + BigNum30 result = new BigNum30(this); + + if(times <= 0) { + return result; + } + + int[] digits = result.digits; + int total = digits.length + times; + int isNonZero = 0; + + for(int i = times, location = 0; i < total; i++, location++) { + if(i < digits.length) { + if(location == 0) { + int value = digits[i - 1]; + int finalValue = digits[i]; + finalValue |= (value & 0x1) << SHIFT; + digits[location] = finalValue; + } + else { + digits[location] = digits[i]; + } + } + else { + int im1 = i - 1; + if(location == 0 && im1 < digits.length) { + int value = digits[im1]; + int finalValue = (value & 0x1) << SHIFT; + digits[location] = finalValue; + } + else { + digits[location] = 0; + } + } + + if(location != 0) { + isNonZero |= digits[location]; + } + } + + result.isOne = digits[0] == 1 && isNonZero == 0; + return result; + } + + @Override + public BigNum30 div2toi(long power) { + BigNum30 result = new BigNum30(this); + + if(power <= 0) { + return result; + } + + int times = (int)(power / SHIFT); + + int internalShift = (int)(power % SHIFT); + + int[] digits = result.digits; + int total = -times; + int isNonZero = 0; + + for(int i = digits.length - 1 - times, location = digits.length - 1; i >= total; i--, location--) { + if(i >= 0) { + int value = digits[i] >>> internalShift; + + if(value > MASKINT) { + if(location != 0) { + digits[location] = value & MASKINT; + } + else { + digits[location] = value; + } + + i--; + location--; + if(location >= 0) { + digits[location] = 0x1; + } + } + else { + int finalValue = value; + int im1 = i - 1; + if(im1 >= 0) { + int diff = SHIFT - internalShift; + finalValue |= (digits[im1] & (0xFFFFFFFF >>> diff)) << diff; + } + if(location == 0) { + digits[location] = (int) (finalValue & MASKD0); + } + else { + digits[location] = finalValue & MASKINT; + } + } + } + else { + int ip1 = i + 1; + if(ip1 == 0 && (digits[ip1] >>> internalShift) > MASKINT) { + digits[location] = 0x1; + } + else { + digits[location] = 0; + } + } + + if(location != 0) { + isNonZero |= digits[location]; + } + } + + result.isOne = digits[0] == 1 && isNonZero == 0; + return result; + } + + @Override + public BigNum30 mult2toi(long power) { + + BigNum30 result = new BigNum30(this); + + if(power <= 0) { + return result; + } + + int times = (int)(power / SHIFT); + + int internalShift = (int)(power % SHIFT); + + int[] digits = result.digits; + int total = digits.length + times; + int isNonZero = 0; + + for(int i = times, location = 0; i < total; i++, location++) { + if(i < digits.length) { + + int value = digits[i] << internalShift; + + int im1 = i - 1; + if(location == 0 && im1 >= 0 && internalShift == 0) { + value |= (digits[im1] & 0x1) << SHIFT; + } + + int ip1 = i + 1; + if(ip1 < digits.length) { + value |= digits[ip1] >>> (SHIFT - internalShift); + } + if(location == 0) { + digits[location] = (int)(value & MASKD0); + } + else { + digits[location] = value & MASKINT; + } + + } + else { + int im1 = i - 1; + if(location == 0 && im1 < digits.length && internalShift == 0) { + int value = (digits[im1] & 0x1) << SHIFT; + digits[location] = (int)(value & MASKD0); + } + else { + digits[location] = 0; + } + } + + if(location != 0) { + isNonZero |= digits[location]; + } + } + + result.isOne = digits[0] == 1 && isNonZero == 0; + return result; + } + + public BigNum30 divide2to30(int times) { + + BigNum30 result = new BigNum30(this); + + if(times <= 0) { + return result; + } + + int[] digits = result.digits; + int total = -times; + int isNonZero = 0; + + for(int i = digits.length - 1 - times, location = digits.length - 1; i >= total; i--, location--) { + if(i >= 0) { + int value = digits[i]; + + if(value > MASKINT) { + digits[location] = value & MASKINT; + i--; + location--; + digits[location] = 0x1; + } + else { + digits[location] = value; + } + } + else { + int ip1 = i + 1; + if(ip1 == 0 && digits[ip1] > MASKINT) { + digits[location] = 0x1; + } + else { + digits[location] = 0; + } + } + + if(location != 0) { + isNonZero |= digits[location]; + } + } + + result.isOne = digits[0] == 1 && isNonZero == 0; + return result; + } + + public BigNum30 shift2to30(int times) { + if(times > 0) { + return mult2to30(times); + } + else if(times < 0) { + return divide2to30(-times); + } + + return new BigNum30(this); + } + + @Override + public BigNum30 shift2toi(long power) { + if(power > 0) { + return mult2toi(power); + } + else if(power < 0) { + return div2toi(-power); + } + + return new BigNum30(this); + } + + @Override + public BigNum30 sqrt() { + if(sign == 0 || isOne) { + return new BigNum30(this); + } + if(sign < 0) { + return new BigNum30(); + } + BigNum30 one = new BigNum30(1); + BigNum30 oneFourth = new BigNum30(0.25); + + BigNum30 a = new BigNum30(this); + long divisions = 0; + long multiplications = 0; + if(a.compareBothPositive(one) > 0) { //scale it down between 1 and 1/4 + do { + a = a.divide4(); + divisions++; + } while (a.compareBothPositive(one) > 0); + } + else if(a.compareBothPositive(oneFourth) < 0) { + + int i; + + int[] digits = a.digits; + for(i = 2; i < digits.length; i++) { + if(digits[i] != 0) { + break; + } + } + + int numberOfLimbs = i - 2; + int multiplesOfTwo = numberOfLimbs >>> 1; + + if(multiplesOfTwo > 0) { + int temp = multiplesOfTwo << 1; + multiplications += ((long)temp * SHIFT) >>> 1; + a = a.mult2to30(temp); + } + + do { + a = a.mult4(); + multiplications++; + } while (a.compareBothPositive(oneFourth) < 0); + } + + BigNum30 oneHalf = new BigNum30(1.5); + BigNum30 aHalf = a.divide2(); // a / 2 + + BigNum30 x = new BigNum30(1 / Math.sqrt(a.doubleValue())); // set the initial value to an approximation of 1 /sqrt(a) + + //Newton steps + BigNum30 newX = x.mult(oneHalf.sub(aHalf.mult(x.squareFull()))); // x = (3/2 - (a/2)*x^2)*x + + BigNum30 epsilon = new BigNum30(1); + epsilon.digits[epsilon.digits.length - 1] = 0x3; + epsilon.digits[0] = 0; + + int iter = 0; + while (newX.sub(x).abs_mutable().compareBothPositive(epsilon) >= 0 && iter < SQRT_MAX_ITERATIONS) { + x = newX; + newX = x.mult(oneHalf.sub(aHalf.mult(x.squareFull()))); + iter++; + } + + BigNum30 sqrta = newX.mult(a); //sqrt(a) = a * (1 /sqrt(a)); + + if(multiplications > 0) { //scale it up again + sqrta = sqrta.div2toi(multiplications); + } + else if(divisions > 0) { + sqrta = sqrta.mult2toi(divisions); + } + + return sqrta; + } +} diff --git a/src/fractalzoomer/core/BigNum32.java b/src/fractalzoomer/core/BigNum32.java new file mode 100644 index 000000000..8a96b723f --- /dev/null +++ b/src/fractalzoomer/core/BigNum32.java @@ -0,0 +1,2497 @@ +package fractalzoomer.core; + +import org.apfloat.Apfloat; +import org.apfloat.internal.LongMemoryDataStorage; + +import java.util.Arrays; + +import static fractalzoomer.core.MyApfloat.TWO; +import static org.apfloat.internal.LongRadixConstants.BASE_DIGITS; + +public class BigNum32 extends BigNum { + + public static long getPrecision() { + + return (long)fracDigits * SHIFT; + + } + + public static String getName() { + return "Built-in (32)"; + } + + public int[] digits; + + private static int fracDigits; + private static int fracDigitsm1; + private static int fracDigitsp1; + private static int fracDigitsHalf; + private static boolean useToDouble2; + private static boolean useKaratsuba; + private static int initialLength; + private static boolean evenFracDigits; + + protected static boolean use_threads; + public static final long MASK = 0xFFFFFFFFL; + public static final int SHIFT = 32; + public static final long MASKD0 = 0x7FFFFFFFL; + public static final long MASK33 = 0x100000000L; + public static final int SHIFTM1 = SHIFT - 1; + public static final int SHIFTM52 = SHIFT - 52; + public static final int MSHIFTP52 = 52 - SHIFT; + private static final double TWO_TO_SHIFT = Math.pow(2,-SHIFT); + + public static void reinitialize(double digits) { + + double res = digits / SHIFT; + int temp = (int) (res); + + if (temp == 0) { + temp = 1; + } else if (digits % SHIFT != 0) { + //0 is floor + if(TaskDraw.BIGNUM_INITIALIZATION_ALGORITHM == 1) { //always + temp++; + } + else if (TaskDraw.BIGNUM_INITIALIZATION_ALGORITHM == 2) { //round + temp = (int)(res + 0.5); + } + } + + //Lets always have even fracDigits +// if((temp & 1) == 0) { +// fracDigits = temp * TaskDraw.BIGNUM_PRECISION_FACTOR; +// } +// else { +// fracDigits = (temp + 1) * TaskDraw.BIGNUM_PRECISION_FACTOR; +// } + fracDigits = temp * TaskDraw.BIGNUM_PRECISION_FACTOR; + + initializeInternal(); + } + + public static void reinitializeTest(double digits) { + fracDigits = ((int)(digits / SHIFT) + 1) * TaskDraw.BIGNUM_PRECISION_FACTOR; + initializeInternal(); + } + + private static void initializeInternal() { + fracDigitsm1 = fracDigits - 1; + fracDigitsp1 = fracDigits + 1; + //useToDouble2 = fracDigits > 120; + //useToDouble2 = false; + //useKaratsuba = fracDigits > 60; + useKaratsuba = false; + fracDigitsHalf = fracDigits >> 1; + initialLength = fracDigitsHalf - ((fracDigitsp1) % 2); + evenFracDigits = (fracDigits & 1) == 0; + + use_threads = false; + } + + private static BigNum32 getMax() { + BigNum32 n = new BigNum32(); + n.digits[0] = (int)MASKD0; + n.sign = 1; + return n; + } + + protected BigNum32() { + digits = new int[fracDigitsp1]; + sign = 0; + isOne = false; + scale = 0; + offset = -1; + bitOffset = -1; + } + + protected BigNum32(BigNum32 other) { + digits = Arrays.copyOf(other.digits, other.digits.length); + sign = other.sign; + isOne = other.isOne; + scale = 0; + offset = -1; + bitOffset = -1; + } + + protected BigNum32(int val) { + digits = new int[fracDigitsp1]; + digits[0] = Math.abs(val); + isOne = val == 1 || val == -1; + sign = (int)Math.signum(val); + scale = 0; + offset = -1; + bitOffset = -1; + } + + protected BigNum32(double val) { + + digits = new int[fracDigitsp1]; + + scale = 0; + offset = -1; + bitOffset = -1; + + if(val == 0 ) { + sign = 0; + isOne = false; + return; + } + else if(Math.abs(val) == 1) { + isOne = true; + sign = (int)val; + digits[0] = 1; + return; + } + + sign = (int)Math.signum(val); + val = Math.abs(val); + digits[0] = (int)(val); + double fractionalPart = val - (int) val; + + if(fractionalPart != 0) { + + long bits = Double.doubleToRawLongBits(fractionalPart); + long f_exp = ((bits & 0x7FF0000000000000L) >>> 52) - Double.MAX_EXPONENT; + long mantissa = (bits & 0xFFFFFFFFFFFFFL) | (0x10000000000000L); + + if(f_exp < 0) { + + long posExp = -f_exp; + + int index = (int) (posExp / SHIFT) + 1; + int bitOffset = (int) (posExp % SHIFT); + + if (bitOffset == 0) { + index--; + bitOffset = SHIFT; + } + + int k; + int i = index; + for (k = 53; k > 0 && i < digits.length; i++) { + int r; + + if (k > SHIFT) { + + if (k == 53) { + r = MSHIFTP52 + bitOffset; + k -= 53 - r; + } else { + r = k - SHIFT; + k -= SHIFT; + } + + digits[i] = (int) ((mantissa >>> r) & MASK); + } else { + + r = SHIFT - k; + k -= k; + + + //if(r >= 0) { + digits[i] = (int) ((mantissa << r) & MASK); + //} + //else { + // digits[i] = (int) ((mantissa >>> (-r)) & MASK); + // } + } + + } + } + + } + + boolean isZero = true; + for(int i = 0; i < digits.length; i++) { + if(digits[i] != 0) { + isZero = false; + break; + } + } + + if(isZero) { + sign = 0; + } + + } + + protected BigNum32(String val) { + this(new MyApfloat(val)); + } + + protected BigNum32(Apfloat val) { + + scale = 0; + this.offset = -1; + bitOffset = -1; + + Apfloat baseTwo = val.toRadix(2); + + sign = baseTwo.getImpl().signum(); + + isOne = false; + + digits = new int[fracDigitsp1]; + + LongMemoryDataStorage str = (LongMemoryDataStorage)baseTwo.getImpl().getDataStorage(); + + if(str == null || sign == 0) { //for zero + return; + } + + long[] data = str.getData(); + + if(data.length == 1 && data[0] == 1) { + isOne = true; + } + + int base_digits = BASE_DIGITS[2]; + + int offset = (int)str.getOffset(); + + int exponent = (int)baseTwo.getImpl().getExponent(); + + if(exponent == 1) { + int index = data.length >= 2 ? 1 : 0; + digits[0] = (int)(MASKD0 & data[index]); + offset++; + } + + int dataOffset = exponent < 0 ? Math.abs(exponent) * base_digits : 0; + + for(int i = dataOffset, j = 0; ; i++, j++) { + + int index2 = (i / SHIFT) + 1; + int index = j / base_digits + offset; + + if(index2 >= digits.length || index >= data.length) { + break; + } + + int shift = base_digits - (j % base_digits) - 1; + int bit = (int) ((data[index] >>> shift) & 0x1); + + digits[index2] |= bit << (SHIFT - (i % SHIFT) - 1); + } + + boolean isZero = true; + for(int i = 0; i < digits.length; i++) { + if(digits[i] != 0) { + isZero = false; + break; + } + } + + if(isZero) { + sign = 0; + } + + } + + @Override + public long getScale() { + + if(sign == 0) { + return Long.MIN_VALUE; + } + + if(offset != -1) { + return scale; + } + + int i; + int digit = 0; + for(i = 0; i < digits.length; i++) { + digit = digits[i]; + if(digit != 0) { + break; + } + } + + if(i == digits.length) { + return Long.MIN_VALUE; + } + + /*int r; + for(r = i == 0 ? SHIFT : SHIFTM1; r >= 0; r--) { + if(digits[i] >>> r != 0) { + break; + } + }*/ + + offset = i; + long v = digit & MASK; + double d = v & ~(v >>> 1); + //int r = (int)(((Double.doubleToRawLongBits(d) >> 52) & 0x7ff) - 1023); //Fix for the 64 bit, not needed here + bitOffset = (int)((Double.doubleToRawLongBits(d) >> 52) - 1023); + //r |= (r >> 31); //Fix for zero, not needed here + + //bitOffset = 31 - Integer.numberOfLeadingZeros(digit); + + scale = i == 0 ? bitOffset : -(((long)i) * SHIFT) + bitOffset; + + return scale; + + } + + public static BigNum32 getNegative(BigNum32 other) { + + BigNum32 copy = new BigNum32(); + copy.sign = other.sign; + copy.isOne = other.isOne; + + int[] otherDigits = other.digits; + int[] digits = copy.digits; + + long s = (~otherDigits[fracDigits]) & MASK + 1; + digits[fracDigits] = (int)s; + for (int i = fracDigitsm1; i >= 0 ; i--) { + s = (~(otherDigits[i]) & MASK) + (s>>>SHIFT); + digits[i] = (int)s; + } + + return copy; + } + + @Override + public void negSelf() { + + if(sign == 0) { + return; + } + + long s = (~digits[fracDigits]) & MASK + 1; + digits[fracDigits] = (int)s; + for (int i = fracDigitsm1; i >= 0 ; i--) { + s = (~(digits[i]) & MASK) + (s>>>SHIFT); + digits[i] = (int)s; + } + + } + + @Override + public BigNum32 negate() { + + BigNum32 res = new BigNum32(this); + + res.sign *= -1; + + return res; + + } + + @Override + public BigNum32 abs() { + + BigNum32 res = new BigNum32(this); + + if(sign == -1) { + res.sign = 1; + } + + return res; + } + + @Override + public BigNum32 abs_mutable() { + + if(sign == -1) { + sign = 1; + } + + return this; + } + + @Override + public String toString() { + StringBuilder ret = new StringBuilder((sign == -1 ? "-" : "") + toHexString(digits[0])); + for(int i=1; i<=fracDigits; i++) { + ret.append(i==1 ? "." : " "); + ret.append(toHexString(digits[i])); + } + return doubleValueOld() + " " + ret.toString(); + } + + @Override + public String bits() { + + String value = ""; + if(sign == -1) { + value = "-"; + } + for (int i = 0; i < digits.length; i++) { + + if (i == 0) { + boolean zero = true; + for (int j = SHIFTM1; j >= 0; j--) { + if (((digits[i] >>> j) & 0x1) == 1) { + zero = false; + } + + if (!zero) { + value += "" + ((digits[i] >>> j) & 0x1); + } + } + if(zero) { + value += "0"; + } + value += "."; + } else { + for (int j = SHIFTM1; j >= 0; j--) { + value += "" + ((digits[i] >>> j) & 0x1); + } + } + } + + return value; + + } + + @Override + public int compare(BigNum otherr) { + BigNum32 other = (BigNum32) otherr; + + int signA = sign; + + int[] otherDigits = other.digits; + + int signB = other.sign; + + long digit, otherDigit; + + if(signA < signB) { + return -1; + } + else if(signA > signB) { + return 1; + } + else {//if(signA == signB) + if (signA == 0) { + return 0; + } + + if(signA < 0) { + for (int i = 0; i < digits.length; i++) { + digit = digits[i] & MASK; + otherDigit = otherDigits[i] & MASK; + if (digit < otherDigit) { + return 1; + } else if (digit > otherDigit) { + return -1; + } + } + } + else { + for (int i = 0; i < digits.length; i++) { + digit = digits[i] & MASK; + otherDigit = otherDigits[i] & MASK; + if (digit < otherDigit) { + return -1; + } else if (digit > otherDigit) { + return 1; + } + } + } + } + + return 0; + + } + + @Override + public int compareBothPositive(BigNum otherr) { + + BigNum32 other = (BigNum32) otherr; + + int signA = sign; + int signB = other.sign; + + if(signA == 0 && signB == 0) { + return 0; + } + + int[] otherDigits = other.digits; + long digit, otherDigit; + + for (int i = 0; i < digits.length; i++) { + digit = digits[i] & MASK; + otherDigit = otherDigits[i] & MASK; + if (digit < otherDigit) { + return -1; + } else if (digit > otherDigit) { + return 1; + } + } + + return 0; + + } + + @Override + public double doubleValue() { + + int[] digits = this.digits; + + int i; + long v; + + if(offset == -1) { + int digit = 0; + for (i = 0; i < digits.length; i++) { + digit = digits[i]; + if (digit != 0) { + break; + } + } + + if (i == digits.length) { + return 0; + } + + /*int r; + for(r = i == 0 ? SHIFT : SHIFTM1; r >= 0; r--) { + if(digits[i] >>> r != 0) { + break; + } + }*/ + + offset = i; + v = digit & MASK; + double d = v & ~(v >>> 1); + //int r = (int)(((Double.doubleToRawLongBits(d) >> 52) & 0x7ff) - 1023); //Fix for the 64 bit, not needed here + bitOffset = (int) ((Double.doubleToRawLongBits(d) >> 52) - 1023); + //r |= (r >> 31); //Fix for zero, not needed here + //bitOffset = 31 - Integer.numberOfLeadingZeros(digit); + + scale = i == 0 ? bitOffset : -(((long) i) * SHIFT) + bitOffset; + } + else { + i = offset; + v = digits[i] & MASK; + } + + if (scale < Double.MIN_EXPONENT) { //accounting for +1 + return 0.0; + } + else if (scale >= Double.MAX_EXPONENT) { + return sign == -1 ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; + } + + long mantissa = 0; + + mantissa |= v << (52 - bitOffset); + i++; + + int k; + for(k = bitOffset ; k < 52 && i < digits.length; k+=SHIFT, i++) { + long val = digits[i] & MASK; + int temp = 52 - k; + + if(temp > SHIFT) { + mantissa |= val << (temp - SHIFT); + mantissa &= 0xFFFFFFFFFFFFFL; + } + else { + int temp2 = k + SHIFTM52; + mantissa |= val >>> temp2; + mantissa &= 0xFFFFFFFFFFFFFL; + + if(temp2 == 0 && i + 1 < digits.length) { + long val2 = digits[i + 1] & MASK; + mantissa += (val2 >>> (SHIFTM1)) & 0x1; + } + else { + mantissa += (val >>> (temp2 - 1)) & 0x1; + } + } + } + + long finalScale = scale + (mantissa >>> 52); + if (finalScale <= Double.MIN_EXPONENT) { + return 0.0; + } + else if (finalScale >= Double.MAX_EXPONENT) { + return sign == -1 ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; + } + + // Bit 63 (the bit that is selected by the mask 0x8000000000000000L) represents the sign of the floating-point number. + // Bits 62-52 (the bits that are selected by the mask 0x7ff0000000000000L) represent the exponent. + // Bits 51-0 (the bits that are selected by the mask 0x000fffffffffffffL) represent the significand (sometimes called the mantissa) of the floating-point number. + + if(sign == -1) { + return Double.longBitsToDouble( (0x8000000000000000L) | (mantissa & 0xFFFFFFFFFFFFFL) | ((finalScale + Double.MAX_EXPONENT) << 52)); + } + else { + return Double.longBitsToDouble((mantissa & 0xFFFFFFFFFFFFFL) | ((finalScale + Double.MAX_EXPONENT) << 52)); + } + + } + + @Override + public double doubleValueOld() { + + if (sign == 0) { + return 0; + } + + if(isOne) { + return sign; + } + + if(useToDouble2) { + return doubleValue(); + } + + double ret = 0; + + + /*if(digits[0]>=0) { + for(int i=fracDigits; i>=0; i--) { + ret *= TWO_TO_SHIFT; + ret += digits[i]; + } + } else { + ret--; + for(int i=fracDigits; i>0; i--) { + ret += digits[i] - MASK; + ret *= TWO_TO_SHIFT; + } + ret += digits[0]+1; + }*/ + + for(int i=fracDigits; i>=0; i--) { + ret *= TWO_TO_SHIFT; + ret += digits[i] & MASK; + } + + ret *= sign; + return ret; + } + + @Override + public BigNum32 add(BigNum aa) { + BigNum32 a = (BigNum32)aa; + + BigNum32 result = new BigNum32(); + + int[] otherDigits = a.digits; + int otherSign = a.sign; + + int[] resDigits = result.digits; + + int[] digits = this.digits; + int sign = this.sign; + + if(sign == 0 || otherSign == 0) { + if(sign == 0 && otherSign == 0){ + return result; + } + else if(sign == 0) { + result.sign = otherSign; + result.isOne = a.isOne; + System.arraycopy(otherDigits, 0, resDigits, 0, otherDigits.length); + } + else { + result.sign = sign; + result.isOne = isOne; + System.arraycopy(digits, 0, resDigits, 0, digits.length); + } + return result; + } + + if(sign != otherSign) { + if(sign == -1) { + BigNum32 copy = getNegative(this); + digits = copy.digits; + } + else + { + BigNum32 copy = getNegative(a); + otherDigits = copy.digits; + } + } + + long s = 0; + int isNonZero = 0; + long temp; + for(int i=fracDigits; i>0; i--) { + s += (digits[i] & MASK) + (otherDigits[i] & MASK); + temp = s & MASK; + isNonZero |= temp; + resDigits[i] = (int)temp; + s >>>= SHIFT; + } + temp = (digits[0] & MASK) + (otherDigits[0] & MASK) + s; + + int temp2 = (int) temp; + result.isOne = (temp2 == 1 || temp2 == -1) && isNonZero == 0; + isNonZero |= temp2; + resDigits[0] = temp2; + + if(sign != otherSign) { + if(resDigits[0] < 0) { + result.sign = -1; + result.negSelf(); + } + else { + result.sign = isNonZero != 0 ? 1 : 0; + } + } + else { + result.sign = isNonZero != 0 ? sign : 0; + } + + return result; + } + + + @Override + public BigNum32 add(int a) { + + BigNum32 result = new BigNum32(); + + int otherSign; + if(a == 0) { + otherSign = 0; + } + else if(a < 0) { + otherSign = -1; + } + else { + otherSign = 1; + } + + int otherDigits = a; + + boolean aIsOne = a == 1 || a == -1; + + int[] resDigits = result.digits; + + int[] digits = this.digits; + int sign = this.sign; + + if(sign == 0 || otherSign == 0) { + if(sign == 0 && otherSign == 0){ + return result; + } + else if(sign == 0) { + result.sign = otherSign; + result.isOne = aIsOne; + + if(otherSign < 0) { + a = ~a + 1; + } + + resDigits[0] = a; + } + else { + result.sign = sign; + result.isOne = isOne; + System.arraycopy(digits, 0, resDigits, 0, digits.length); + } + return result; + } + + if(sign != otherSign) { + if(sign == -1) { + BigNum32 copy = getNegative(this); + digits = copy.digits; + } + } + else { + if(otherSign < 0) { + otherDigits = ~otherDigits + 1; + } + } + + int isNonZero = 0; + long temp; + for(int i=fracDigits; i>0; i--) { + temp = resDigits[i] = digits[i]; + isNonZero |= temp; + } + + temp = (digits[0] & MASK) + otherDigits; + result.isOne = (temp == 1 || temp == -1) && isNonZero == 0; + isNonZero |= temp; + resDigits[0] = (int)temp; + + if(sign != otherSign) { + if(resDigits[0] < 0) { + result.sign = -1; + result.negSelf(); + } + else { + result.sign = isNonZero != 0 ? 1 : 0; + } + } + else { + result.sign = isNonZero != 0 ? sign : 0; + } + + return result; + } + + @Override + public BigNum32 sub(BigNum aa) { + BigNum32 a = (BigNum32)aa; + + BigNum32 result = new BigNum32(); + + int[] otherDigits = a.digits; + int otherSign = a.sign; + + int[] resDigits = result.digits; + + int[] digits = this.digits; + int sign = this.sign; + + if(sign == 0 || otherSign == 0) { + if(sign == 0 && otherSign == 0){ + return result; + } + else if(sign == 0) { + result.sign = -otherSign; + result.isOne = a.isOne; + System.arraycopy(otherDigits, 0, resDigits, 0, otherDigits.length); + } + else { + result.sign = sign; + result.isOne = isOne; + System.arraycopy(digits, 0, resDigits, 0, digits.length); + } + return result; + } + + if(sign == otherSign) { + // + + -> + - + // - - -> - + + if(sign == -1) { + BigNum32 copy = getNegative(this); + digits = copy.digits; + } + else { + BigNum32 copy = getNegative(a); + otherDigits = copy.digits; + } + } + + long s = 0; + int isNonZero = 0; + long temp; + for(int i=fracDigits; i>0; i--) { + s += (digits[i] & MASK) + (otherDigits[i] & MASK); + temp = s & MASK; + isNonZero |= temp; + resDigits[i] = (int)temp; + s >>>= SHIFT; + } + temp = (digits[0] & MASK) + (otherDigits[0] & MASK) + s; + + int temp2 = (int) temp; + result.isOne = (temp2 == 1 || temp2 == -1) && isNonZero == 0; + isNonZero |= temp2; + resDigits[0] = temp2; + + if(sign == otherSign) { + if(resDigits[0] < 0) { + result.sign = -1; + result.negSelf(); + } + else { + result.sign = isNonZero != 0 ? 1 : 0; + } + } + else { + result.sign = isNonZero != 0 ? sign : 0; + } + + return result; + } + + @Override + public BigNum32 sub(int a) { + + BigNum32 result = new BigNum32(); + + int otherSign; + if(a == 0) { + otherSign = 0; + } + else if(a < 0) { + otherSign = -1; + } + else { + otherSign = 1; + } + + int otherDigits = a; + + boolean aIsOne = a == 1 || a == -1; + + int[] resDigits = result.digits; + + int[] digits = this.digits; + int sign = this.sign; + + if(sign == 0 || otherSign == 0) { + if(sign == 0 && otherSign == 0){ + return result; + } + else if(sign == 0) { + result.sign = -otherSign; + result.isOne = aIsOne; + + if(otherSign < 0) { + a = ~a + 1; + } + + resDigits[0] = a; + } + else { + result.sign = sign; + result.isOne = isOne; + System.arraycopy(digits, 0, resDigits, 0, digits.length); + } + return result; + } + + if(sign == otherSign) { + // + + -> + - + // - - -> - + + if(sign == -1) { + BigNum32 copy = getNegative(this); + digits = copy.digits; + } + otherDigits = ~otherDigits + 1; + } + else { + if(otherSign < 0) { + otherDigits = ~otherDigits + 1; + } + } + + + int isNonZero = 0; + long temp; + for(int i=fracDigits; i>0; i--) { + temp = resDigits[i] = digits[i]; + isNonZero |= temp; + } + + temp = (digits[0] & MASK) + otherDigits; + result.isOne = (temp == 1 || temp == -1) && isNonZero == 0; + isNonZero |= temp; + resDigits[0] = (int)temp; + + if(sign == otherSign) { + if(resDigits[0] < 0) { + result.sign = -1; + result.negSelf(); + } + else { + result.sign = isNonZero != 0 ? 1 : 0; + } + } + else { + result.sign = isNonZero != 0 ? sign : 0; + } + + return result; + } + + @Override + public BigNum32 square() { + if(offset <= 15) { + return squareFull(); + } + else { + return squareWithZeroSkip(); + } + } + + public BigNum32 squareWithZeroSkip() { + + + BigNum32 result = new BigNum32(); + + if(sign == 0) { + return result; + } + + int[] resDigits = result.digits; + + if(isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = 1; + return result; + } + + if ((offset << 1) > fracDigits) { + return result; // zero + } + + long old_sum; + + long sum = 0; + + int length = initialLength; + + int j; + int k; + long carry = 0; + long bj; + long ak; + + + for (j = 1, k = fracDigits; j <= length;) { + bj = digits[j] & MASK; + ak = digits[k] & MASK; + + sum += bj * ak; + + j++;k--; + + carry += sum >>> SHIFT; + sum &= MASK; + } + + if(j == k) { + bj = digits[j] & MASK; + sum <<= 1; + //carry += sum >>> SHIFT; + //sum &= MASK; + carry <<= 1; + sum += bj * bj; + } + else { + bj = digits[j] & MASK; + ak = digits[k] & MASK; + sum += bj * ak; + carry += sum >>> SHIFT; + sum &= MASK; + sum <<= 1; + carry <<= 1; + } + + carry += sum >>> SHIFT; + sum &= MASK; + + + + old_sum = carry + (sum >>> (SHIFTM1)); // Roundish + + int newJStart = offset != -1 ? offset : 0; //To avoid multiplication on zeros + + for(int i = fracDigits; i > 0; i--) { + + sum = 0; + + length = (i >> 1) - 1; + + carry = 0; + + for(j = newJStart, k = i - newJStart; j <= length; j++, k--) { + bj = digits[j] & MASK; + ak = digits[k] & MASK; + sum += bj * ak; + carry += sum >>> SHIFT; + sum &= MASK; + } + + + if(j == k) { + bj = digits[j] & MASK; + sum <<= 1; + carry <<= 1; + carry += sum >>> SHIFT; + sum &= MASK; + sum += bj * bj; + carry += sum >>> SHIFT; + sum &= MASK; + } + else { + bj = digits[j] & MASK; + ak = digits[k] & MASK; + sum += bj * ak; + carry += sum >>> SHIFT; + sum &= MASK; + sum <<= 1; + carry <<= 1; + //carry += sum >>> SHIFT; + //sum &= MASK; + } + + sum += old_sum; + carry += sum >>> SHIFT; + sum &= MASK; + + + resDigits[i] = (int) (sum); + old_sum = carry; + + if(k <= offset && carry == 0) { + result.sign = 1; + return result; + } + } + + sum = old_sum; + + bj = digits[0] & MASK; + sum += bj * bj; + + resDigits[0] = (int) (sum & MASKD0); + result.sign = 1; + + return result; + } + @Deprecated + @Override + public BigNum32 squareFullGolden() { + + + BigNum32 result = new BigNum32(); + + if(sign == 0) { + return result; + } + + int[] resDigits = result.digits; + + if(isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = 1; + return result; + } + + long old_sum; + + long sum = 0; + + int length = initialLength; + + int j; + int k; + long carry = 0; + long bj; + long ak; + + for (j = 1, k = fracDigits; j <= length; j++, k--) { + bj = digits[j] & MASK; + ak = digits[k] & MASK; + + sum += bj * ak; + carry += sum >>> SHIFT; + sum &= MASK; + } + + + if(j == k) { + bj = digits[j] & MASK; + sum <<= 1; + carry <<= 1; + sum += bj * bj; + } + else { + bj = digits[j] & MASK; + ak = digits[k] & MASK; + sum += bj * ak; + carry += sum >>> SHIFT; + sum &= MASK; + sum <<= 1; + carry <<= 1; + } + + carry += sum >>> SHIFT; + sum &= MASK; + + old_sum = carry + (sum >>> (SHIFTM1)); // Roundish + + + for(int i = fracDigits; i > 0; i--) { + + sum = old_sum; + + length = (i >> 1) - 1; + + long temp_sum = 0; + carry = 0; + for(j = 0, k = i; j <= length; j++, k--) { + bj = digits[j] & MASK; + ak = digits[k] & MASK; + temp_sum += bj * ak; + carry += temp_sum >>> SHIFT; + temp_sum &= MASK; + } + + + if(j == k) { + bj = digits[j] & MASK; + temp_sum <<= 1; + carry <<= 1; + carry += temp_sum >>> SHIFT; + temp_sum &= MASK; + temp_sum += bj * bj; + carry += temp_sum >>> SHIFT; + temp_sum &= MASK; + } + else { + bj = digits[j] & MASK; + ak = digits[k] & MASK; + temp_sum += bj * ak; + carry += temp_sum >>> SHIFT; + temp_sum &= MASK; + temp_sum <<= 1; + carry <<= 1; + carry += temp_sum >>> SHIFT; + temp_sum &= MASK; + } + + sum += temp_sum; + carry += sum >>> SHIFT; + sum &= MASK; + + + resDigits[i] = (int) (sum); + old_sum = carry; + } + + sum = old_sum; + + bj = digits[0] & MASK; + sum += bj * bj; + + resDigits[0] = (int) (sum & MASKD0); + result.sign = 1; + + return result; + } + + + //Todo check 32 impl for overflows + @Override + public BigNum32 squareFull() { + + + BigNum32 result = new BigNum32(); + + if(sign == 0) { + return result; + } + + int[] resDigits = result.digits; + + if(isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = 1; + return result; + } + + long old_sum; + + long sum = 0; + + int length = initialLength; + + int j; + int k; + long carry = 0; + + long bj; + long ak; + + for (j = 1, k = fracDigits; j <= length;) { + bj = digits[j] & MASK; + ak = digits[k] & MASK; + + sum += bj * ak; + + j++;k--; + + carry += sum >>> SHIFT; + sum &= MASK; + } + + if(j == k) { + bj = digits[j] & MASK; + sum <<= 1; + carry <<= 1; + //carry += sum >>> SHIFT; + //sum &= MASK; + sum += bj * bj; + } + else { + bj = digits[j] & MASK; + ak = digits[k] & MASK; + sum += bj * ak; + carry += sum >>> SHIFT; + sum &= MASK; + sum <<= 1; + carry <<= 1; + } + + carry += sum >>> SHIFT; + sum &= MASK; + + old_sum = carry + (sum >>> (SHIFTM1)); // Roundish + + // System.out.println(old_sum); + + length = fracDigitsHalf; + + for(int i = fracDigits; i > 0; i-=2, length--) { + + sum = 0; + long sum2 = 0; + carry = 0; + long carry2 = 0; + + k = i; + long prevDigit = digits[k] & MASK; + + for(j = 0; j < length;) { + bj = digits[j] & MASK; + sum += prevDigit * bj; + + k--; + + prevDigit = digits[k] & MASK; //ak + sum2 += prevDigit * bj; + + j++; + + carry += sum >>> SHIFT; + sum &= MASK; + carry2 += sum2 >>> SHIFT; + sum2 &= MASK; + } + + if(evenFracDigits) { + sum <<= 1; + carry <<= 1; + carry += sum >>> SHIFT; + sum &= MASK; + sum += prevDigit * prevDigit; + + sum2 <<= 1; + carry2 <<= 1; + //carry2 += sum2 >>> SHIFT; + //sum2 &= MASK; + } + else { + bj = digits[length] & MASK; + + sum += prevDigit * bj; + carry += sum >>> SHIFT; + sum &= MASK; + //carry1 += temp_sum1 >>> SHIFT; + //temp_sum1 &= MASK; + + sum2 <<= 1; + carry2 <<= 1; + sum2 += bj * bj; + carry2 += sum2 >>> SHIFT; + sum2 &= MASK; + + sum <<= 1; + carry <<= 1; + } + + + carry += sum >>> SHIFT; + sum &= MASK; + + sum += old_sum; + carry += sum >>> SHIFT; + sum &= MASK; + + sum2 += carry; + + + if(i > 1) { + carry2 += sum2 >>> SHIFT; + sum2 &= MASK; + old_sum = carry2; + } + + resDigits[i] = (int) (sum); + resDigits[i - 1] = (int) (sum2); + + } + + if(evenFracDigits) { + sum = old_sum; + + bj = digits[0] & MASK; + sum += bj * bj; + + resDigits[0] = (int) (sum & MASKD0); + } + result.sign = 1; + + return result; + } + + + @Override + public BigNum32 mult(BigNum bb) { + BigNum32 b = (BigNum32) bb; + return multFull(b); + } + + /* Sign is positive */ + @Override + public BigNum32 mult(int value) { + BigNum32 result = new BigNum32(); + + if(sign == 0 || value == 0) { + return result; + } + + int[] resDigits = result.digits; + + boolean bIsOne = value == 1 || value == -1; + + int bsign; + + if(value < 0) { + bsign = -1; + value = ~value + 1; + } + else { + bsign = 1; + } + + if(isOne || bIsOne) { + if (isOne && bIsOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = sign * bsign; + } + else if(isOne) { + resDigits[0] = value; + result.sign = sign * bsign; + } + else { + System.arraycopy(digits, 0, resDigits, 0, digits.length); + result.sign = sign * bsign; + } + return result; + } + + long old_sum = 0; + long sum; + long carry; + + int isNonZero = 0; + for(int i = fracDigits; i > 0; i--) { + sum = (digits[i] & MASK) * value + old_sum; + carry = sum >>> SHIFT; + sum &= MASK; + + int di = (int) (sum); + resDigits[i] = di; + isNonZero |= di; + old_sum = carry; + } + + sum = (digits[0] & MASK) * value + old_sum; + + int d0 = (int) (sum & MASKD0); + resDigits[0] = d0; + + result.isOne = d0 == 1 && isNonZero == 0; + + result.sign = sign * bsign; + + return result; + } + + @Deprecated + public BigNum32 multFullGolden(BigNum32 b) { + + BigNum32 result = new BigNum32(); + + if(sign == 0 || b.sign == 0) { + return result; + } + + int[] bdigits = b.digits; + + int[] resDigits = result.digits; + + if(isOne || b.isOne) { + if (isOne && b.isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = sign * b.sign; + } + else if(isOne) { + System.arraycopy(bdigits, 0, resDigits, 0, bdigits.length); + result.sign = sign * b.sign; + } + else { + System.arraycopy(digits, 0, resDigits, 0, digits.length); + result.sign = sign * b.sign; + } + return result; + } + + long old_sum; + + //for(int i = MAX_FRAC_DIGITS; i > 0; i--) { + + //long sum = (old_sum >>> SHIFT31); + // + long sum = 0; + long carry = 0; + long bj; + long ak; + for (int j = 1, k = fracDigits; j <= fracDigits; j++, k--) { + bj = bdigits[j] & MASK; + ak = digits[k] & MASK; + + sum += bj * ak; + carry += sum >>> SHIFT; + sum &= MASK; + + } + + old_sum = carry + (sum >>> (SHIFTM1)); // Roundish + + //System.out.println(); + //} + + int isNonZero = 0; + for(int i = fracDigits; i > 0; i--) { + + sum = old_sum; //carry from prev + carry = 0; + for(int j = 0, k = i; j <= i; j++, k--) { + bj = bdigits[j] & MASK; + ak = digits[k] & MASK; + + sum += bj * ak; + carry += sum >>> SHIFT; + sum &= MASK; + + //System.out.println("b" + j + " * " + "a " + k); + } + + int di = (int) (sum); + resDigits[i] = di; + isNonZero |= di; + //System.out.println(result.digits[i] ); + old_sum = carry; + //System.out.println("NEXT"); + } + + sum = old_sum; + + bj = bdigits[0] & MASK; + ak = digits[0] & MASK; + + sum += bj * ak; + + int d0 = (int) (sum & MASKD0); + resDigits[0] = d0; + + result.isOne = d0 == 1 && isNonZero == 0; + + result.sign = sign * b.sign; + + return result; + + } + + public BigNum32 multFull(BigNum32 b) { + + BigNum32 result = new BigNum32(); + + if(sign == 0 || b.sign == 0) { + return result; + } + + int[] bdigits = b.digits; + + int[] resDigits = result.digits; + + if(isOne || b.isOne) { + if (isOne && b.isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = sign * b.sign; + } + else if(isOne) { + System.arraycopy(bdigits, 0, resDigits, 0, bdigits.length); + result.sign = sign * b.sign; + } + else { + System.arraycopy(digits, 0, resDigits, 0, digits.length); + result.sign = sign * b.sign; + } + return result; + } + + long old_sum; + + //for(int i = MAX_FRAC_DIGITS; i > 0; i--) { + + //long sum = (old_sum >>> SHIFT31); + // + long sum = 0; + long carry = 0; + long bj; + long ak; + + int j, k; + + for (j = 1, k = fracDigits; j <= fracDigits;) { + bj = bdigits[j] & MASK; + ak = digits[k] & MASK; + + sum += bj * ak; + + j++;k--; + + + carry += sum >>> SHIFT; + sum &= MASK; + } + + old_sum = carry + (sum >>> (SHIFTM1)); // Roundish + + //System.out.println(); + //} + + + long a0 = digits[0] & MASK; + + int isNonZero = 0; + for(int i = fracDigits; i > 0; i-=2) { + sum = 0; + long sum2 = 0; + carry = old_sum >>> SHIFT; + old_sum &= MASK; + long carry2 = 0; + + k = i; + long prevDigit = digits[k] & MASK; + + for(j = 0; j < i;) { + bj = bdigits[j] & MASK; + sum += prevDigit * bj; + + //System.out.println("b" + j + " * " + "a " + k); + + k--; + + prevDigit = digits[k] & MASK; //ak + sum2 += prevDigit * bj; + //System.out.println("b" + j + " * " + "a " + k); + + j++; + + carry += sum >>> SHIFT; + sum &= MASK; + + carry2 += sum2 >>> SHIFT; + sum2 &= MASK; + } + + bj = bdigits[j] & MASK; + + sum += prevDigit * bj + old_sum; + //System.out.println("b" + j + " * " + "a " + k); + //carry1 += temp_sum1 >>> SHIFT; + //temp_sum1 &= MASK; + + carry += sum >>> SHIFT; + sum &= MASK; + + //System.out.println("NEXT"); + + int di = (int) (sum); + isNonZero |= di; + resDigits[i] = di; + + + if(i > 1) { + int im1 = i - 1; + sum2 += carry; + + carry2 += sum2 >>> SHIFT; + sum2 &= MASK; + old_sum = carry2; + + di = (int) (sum2); + isNonZero |= di; + resDigits[im1] = di; + } + else { + sum2 += carry; + int d0 = (int) (sum2 & MASKD0); + resDigits[0] = d0; + result.isOne = d0 == 1 && isNonZero == 0; + } + + } + + if(evenFracDigits) { + bj = bdigits[0] & MASK; + + sum = bj * a0 + old_sum; + + int d0 = (int) (sum & MASKD0); + resDigits[0] = d0; + + result.isOne = d0 == 1 && isNonZero == 0; + } + + result.sign = sign * b.sign; + + return result; + + } + + @Deprecated + public BigNum32 multKaratsubaGolden(BigNum32 b) { + + BigNum32 result = new BigNum32(); + + if(sign == 0 || b.sign == 0) { + return result; + } + + int[] bdigits = b.digits; + int[] resDigits = result.digits; + + if(isOne || b.isOne) { + if (isOne && b.isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = sign * b.sign; + } + else if(isOne) { + System.arraycopy(bdigits, 0, resDigits, 0, bdigits.length); + result.sign = sign * b.sign; + } + else { + System.arraycopy(digits, 0, resDigits, 0, digits.length); + result.sign = sign * b.sign; + } + return result; + } + + long[] partials = new long[fracDigitsp1]; + long[] partialSums = new long[fracDigitsp1]; + long[] partialCarries = new long[fracDigitsp1]; + + long PartialSum = 0; + long PartialCarry = 0; + for (int i = 0; i < fracDigitsp1; i++) { + long p = (digits[i] & MASK) * (bdigits[i] & MASK); + partials[i] = p; + PartialSum += p; + + PartialCarry += PartialSum >>> SHIFT; + PartialSum &= MASK; + + partialSums[i] = PartialSum; + partialCarries[i] = PartialCarry; + } + + + long old_sum; + + long p0 = partials[0]; + + long sum = p0; + + int length = initialLength; + + int j; + int k; + long carry = 0; + long bj, bk, aj, ak; + for (j = 1, k = fracDigits; j <= length; j++, k--) { + bj = bdigits[j] & MASK; + bk = bdigits[k] & MASK; + aj = digits[j] & MASK; + ak = digits[k] & MASK; + + sum += (bk + bj) * (ak + aj); + carry += sum >>> SHIFT; + sum &= MASK; + + //System.out.println("partials " + k + " partials " + j); + + } + + //System.out.println("partials " + k + " partials " + j); + + //System.out.println("Next"); + + //int diff = k - j; + //int branchlessCheck = (diff >> 31) - (-diff >> 31); + + + //System.out.println("partials " + k + " partials " + j); + + //System.out.println("NEXT"); + + //System.out.println("OUT"); + //System.out.println("b" + j + " * " + "a " + k); + + if(j == k) { + sum += (partials[k] << 1); + } + else { + bj = bdigits[j] & MASK; + bk = bdigits[k] & MASK; + aj = digits[j] & MASK; + ak = digits[k] & MASK; + sum += (bk + bj) * (ak + aj); + } + + carry += sum >>> SHIFT; + sum &= MASK; + + sum -= PartialSum; + carry -= ((sum & MASK33) >>> SHIFT) + PartialCarry; + sum &= MASK; + + //sum += (1 - branchlessCheck) * partials[k] + branchlessCheck * ((bk + bj) * (ak + aj) - partials[k] - partials[j]); + + old_sum = carry + (sum >>> (SHIFTM1)); // Roundish, adds bias because 10000 is always shifted upwards + + int isNonZero = 0; + for(int i = fracDigits; i > 0; i--) { + + length = (i >> 1) - 1; + + sum = old_sum; //carry from prev + + carry = 0; + for(j = 0, k = i; j <= length; j++, k--) { + bj = bdigits[j] & MASK; + bk = bdigits[k] & MASK; + aj = digits[j] & MASK; + ak = digits[k] & MASK; + + sum += (bk + bj) * (ak + aj); //Overflows + + carry += sum >>> SHIFT; + sum &= MASK; + //System.out.println("partials " + k + " partials " + j); + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + + } + + if(j == k) { + sum += (partials[k] << 1); + } + else { + bj = bdigits[j] & MASK; + bk = bdigits[k] & MASK; + aj = digits[j] & MASK; + ak = digits[k] & MASK; + //System.out.println("b " + j + " b " + k + " a " + j + " a " + k); + sum += (bk + bj) * (ak + aj); + } + + //System.out.println("NEXT"); + + carry += sum >>> SHIFT; + sum &= MASK; + + sum -= PartialSum; + carry -= ((sum & MASK33) >>> SHIFT) + PartialCarry; + sum &= MASK; + + if(i > 1) { + int im1 = i - 1; + PartialSum = partialSums[im1]; + PartialCarry = partialCarries[im1]; + + //long partialI = partials[i]; + + //PartialSum -= partialI & MASK; + //PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFT; + //PartialSum &= MASK; + } + + + //System.out.println("partials " + k + " partials " + j); + //System.out.println("NEXT"); + + + int di = (int) (sum); + isNonZero |= di; + resDigits[i] = di; + //System.out.println(result.digits[i] ); + old_sum = carry; + // System.out.println(old_sum); + //System.out.println("NEXT"); + } + + sum = old_sum; + + sum += p0; + + int d0 = (int) (sum & MASKD0); + resDigits[0] = d0; + + result.sign = sign * b.sign; + + result.isOne = d0 == 1 && isNonZero == 0; + + return result; + + } + + /*mult2, mult4, divide2, divide4, multFull, multKaratsuba, square and squareKaratsuba + might overflow or underflow leading to zero but the sign will not be set to 0 + */ + + @Override + public BigNum32 mult2() { + + BigNum32 res = new BigNum32(); + + if(sign == 0) { + return res; + } + + int [] resDigits = res.digits; + + if(isOne) { + resDigits[0] = 2; + res.sign = sign; + return res; + } + + int isNonZero = 0; + + long temp = (digits[fracDigits] & MASK) << 1; + long val = temp & MASK; + resDigits[fracDigits] = (int) val; + isNonZero |= val; + + for(int i = fracDigitsm1; i > 0; i--) { + temp = ((digits[i] & MASK) << 1) | (temp >>> SHIFT); + val = temp & MASK; + resDigits[i] = (int)val; + isNonZero |= val; + } + + temp = ((digits[0] & MASK) << 1) | (temp >>> SHIFT); + int d0 = (int)(temp & MASKD0); + resDigits[0] = d0; + res.sign = sign; + res.isOne = d0 == 1 && isNonZero == 0; + return res; + + } + + @Override + public BigNum32 divide2() { + + BigNum32 res = new BigNum32(); + + if(sign == 0) { + return res; + } + + int [] resDigits = res.digits; + + if(isOne) { + resDigits[1] = 0x80000000; + res.sign = sign; + return res; + } + + int isNonZero = 0; + + long d0 = digits[0] & MASK; + long temp = d0; + long val = temp >>> 1; + + long bit = temp & 0x1; + + resDigits[0] = (int)val; + isNonZero |= val; + + for(int i=1; i < fracDigits; i++) { + temp = digits[i] & MASK; + temp |= (bit << SHIFT); + bit = temp & 0x1; + temp >>>= 1; + val = temp & MASK; + resDigits[i] = (int)val; + isNonZero |= val; + } + + temp = digits[fracDigits] & MASK; + temp |= (bit << SHIFT); + temp >>>= 1; + val = temp & MASK; + resDigits[fracDigits] = (int)val; + isNonZero |= val; + + res.sign = sign; + res.isOne = d0 == 1 && isNonZero == 0; + return res; + + } + + @Override + public BigNum32 divide4() { + + BigNum32 res = new BigNum32(); + + if(sign == 0) { + return res; + } + + int [] resDigits = res.digits; + + if(isOne) { + resDigits[1] = 0x40000000; + res.sign = sign; + return res; + } + + int isNonZero = 0; + + long d0 = digits[0] & MASK; + long temp = d0; + long val = temp >>> 2; + + long bits = temp & 0x3; + + resDigits[0] = (int)val; + isNonZero |= val; + + for(int i=1; i < fracDigits; i++) { + temp = digits[i] & MASK; + temp |= (bits << SHIFT); + bits = temp & 0x3; + temp >>>= 2; + val = temp & MASK; + resDigits[i] = (int)val; + isNonZero |= val; + } + + temp = digits[fracDigits] & MASK; + temp |= (bits << SHIFT); + temp >>>= 2; + val = temp & MASK; + resDigits[fracDigits] = (int)val; + isNonZero |= val; + res.sign = sign; + res.isOne = d0 == 1 && isNonZero == 0; + return res; + + } + + @Override + public BigNum32 mult4() { + + BigNum32 res = new BigNum32(); + + if(sign == 0) { + return res; + } + + int [] resDigits = res.digits; + + if(isOne) { + resDigits[0] = 4; + res.sign = sign; + return res; + } + + int isNonZero = 0; + + long temp = (digits[fracDigits] & MASK) << 2; + long val = temp & MASK; + resDigits[fracDigits] = (int)val; + isNonZero |= val; + + for(int i=fracDigitsm1; i > 0; i--) { + temp = ((digits[i] & MASK) << 2) | (temp >>> SHIFT); + val = temp & MASK; + resDigits[i] = (int)val; + isNonZero |= val; + } + + temp = ((digits[0] & MASK) << 2) | (temp >>> SHIFT); + int d0 = (int)(temp & MASKD0); + resDigits[0] = d0; + res.sign = sign; + res.isOne = d0 == 1 && isNonZero == 0; + return res; + + } + + @Override + public MantExp getMantExp() { + + if (sign == 0) { + return new MantExp(); + } + + if(isOne) { + return new MantExp(sign); + } + + int[] digits = this.digits; + + int i; + int digit = 0; + if(offset == -1) { + for (i = 0; i < digits.length; i++) { + digit = digits[i]; + if (digit != 0) { + break; + } + } + + if (i == digits.length) { + return new MantExp(); + } + + /*int r; + for(r = i == 0 ? SHIFT : SHIFTM1; r >= 0; r--) { + if(digits[i] >>> r != 0) { + break; + } + }*/ + + offset = i; + long v = digit & MASK; + double d = v & ~(v >>> 1); + //int r = (int)(((Double.doubleToRawLongBits(d) >> 52) & 0x7ff) - 1023); //Fix for the 64 bit, not needed here + bitOffset = (int) ((Double.doubleToRawLongBits(d) >> 52) - 1023); + //r |= (r >> 31); //Fix for zero, not needed here + + //bitOffset = 31 - Integer.numberOfLeadingZeros(digit); + + scale = i == 0 ? bitOffset : -(((long) i) * SHIFT) + bitOffset; + } + else { + i = offset; + digit = digits[i]; + } + + long mantissa = 0; + + int temp = 52 - bitOffset; + mantissa |= (digit & MASK) << temp; //Will always be positive + mantissa &= 0xFFFFFFFFFFFFFL; + + //System.out.println(digits[i]); + + i++; + + int k; + for(k = bitOffset ; k < 52 && i < digits.length; k+=SHIFT, i++) { + long val = digits[i] & MASK; + temp = 52 - k; + + if(temp > SHIFT) { + mantissa |= val << (temp - SHIFT); + mantissa &= 0xFFFFFFFFFFFFFL; + } + else { + int temp2 = k + SHIFTM52; + mantissa |= val >>> temp2; + mantissa &= 0xFFFFFFFFFFFFFL; + + if(temp2 == 0 && i + 1 < digits.length) { + long val2 = digits[i + 1] & MASK; + mantissa += (val2 >>> (SHIFTM1)) & 0x1; //Rounding + } + else { + mantissa += (val >>> (temp2 - 1)) & 0x1; //Rounding + } + } + } + + // Bit 63 (the bit that is selected by the mask 0x8000000000000000L) represents the sign of the floating-point number. + // Bits 62-52 (the bits that are selected by the mask 0x7ff0000000000000L) represent the exponent. + // Bits 51-0 (the bits that are selected by the mask 0x000fffffffffffffL) represent the significand (sometimes called the mantissa) of the floating-point number. + + int exp = (int)(scale + (mantissa >>> 52)); + double mantissaDouble; + + if(sign == -1) { + mantissaDouble = Double.longBitsToDouble( (0x8000000000000000L) | (mantissa & 0xFFFFFFFFFFFFFL) | (0x3FF0000000000000L)); + } + else { + mantissaDouble = Double.longBitsToDouble((mantissa & 0xFFFFFFFFFFFFFL) | (0x3FF0000000000000L)); + } + + return new MantExp(exp, mantissaDouble); + + + + } + + public static BigNum32 max(BigNum32 a, BigNum32 b) { + return a.compare(b) > 0 ? a : b; + } + + public static BigNum32 min(BigNum32 a, BigNum32 b) { + return a.compare(b) < 0 ? a : b; + } + + public BigNum32 mult2to32(int times) { + + BigNum32 result = new BigNum32(this); + + if(times <= 0) { + return result; + } + + int[] digits = result.digits; + int total = digits.length + times; + int isNonZero = 0; + + for(int i = times, location = 0; i < total; i++, location++) { + if(i < digits.length) { + digits[location] = digits[i]; + } + else { + digits[location] = 0; + } + + if(location != 0) { + isNonZero |= digits[location]; + } + } + + result.isOne = digits[0] == 1 && isNonZero == 0; + return result; + } + + @Override + public BigNum32 div2toi(long power) { + BigNum32 result = new BigNum32(this); + + if(power <= 0) { + return result; + } + + int times = (int)(power / SHIFT); + + int internalShift = (int)(power % SHIFT); + + int[] digits = result.digits; + int total = -times; + int isNonZero = 0; + int val; + + for(int i = digits.length - 1 - times, location = digits.length - 1; i >= total; i--, location--) { + if(i == 0) { + digits[location] = val = digits[i] >>> internalShift; + } + else if (i > 0) { + digits[location] = val = ((int)(((digits[i - 1] & MASK) << (SHIFT - internalShift)))) | (digits[i] >>> internalShift); + } + else { + digits[location] = val = 0; + } + + if(location != 0) { + isNonZero |= val; + } + } + + result.isOne = digits[0] == 1 && isNonZero == 0; + return result; + } + + @Override + public BigNum32 mult2toi(long power) { + + BigNum32 result = new BigNum32(this); + + if(power <= 0) { + return result; + } + + int times = (int)(power / SHIFT); + + int internalShift = (int)(power % SHIFT); + + int[] digits = result.digits; + int total = digits.length + times; + int isNonZero = 0; + int val; + + for(int i = times, location = 0; i < total; i++, location++) { + if(i < digits.length - 1) { + digits[location] = val = (digits[i] << internalShift) | ((int)((digits[i + 1] & MASK) >>> (SHIFT - internalShift))); + } + else if(i < digits.length) { + digits[location] = val = (digits[i] << internalShift); + } + else { + digits[location] = val = 0; + } + + if(location != 0) { + isNonZero |= val; + } + } + + result.isOne = digits[0] == 1 && isNonZero == 0; + return result; + } + + public BigNum32 divide2to32(int times) { + + BigNum32 result = new BigNum32(this); + + if(times <= 0) { + return result; + } + + int[] digits = result.digits; + int total = -times; + int isNonZero = 0; + + for(int i = digits.length - 1 - times, location = digits.length - 1; i >= total; i--, location--) { + if(i >= 0) { + digits[location] = digits[i]; + } + else { + digits[location] = 0; + } + + if(location != 0) { + isNonZero |= digits[location]; + } + } + + result.isOne = digits[0] == 1 && isNonZero == 0; + return result; + } + + public BigNum32 shift2to32(int times) { + if(times > 0) { + return mult2to32(times); + } + else if(times < 0) { + return divide2to32(-times); + } + + return new BigNum32(this); + } + + @Override + public BigNum32 shift2toi(long power) { + if(power > 0) { + return mult2toi(power); + } + else if(power < 0) { + return div2toi(-power); + } + + return new BigNum32(this); + } + + @Override + public BigNum32 sqrt() { + if(sign == 0 || isOne) { + return new BigNum32(this); + } + if(sign < 0) { + return new BigNum32(); + } + BigNum32 one = new BigNum32(1); + BigNum32 oneFourth = new BigNum32(0.25); + + BigNum32 a = new BigNum32(this); + long divisions = 0; + long multiplications = 0; + if(a.compareBothPositive(one) > 0) { //scale it down between 1 and 1/4 + do { + a = a.divide4(); + divisions++; + } while (a.compareBothPositive(one) > 0); + } + else if(a.compareBothPositive(oneFourth) < 0) { + + int i; + + int[] digits = a.digits; + for(i = 2; i < digits.length; i++) { + if(digits[i] != 0) { + break; + } + } + + int numberOfLimbs = i - 2; + + if(numberOfLimbs > 0) { + multiplications += ((long)numberOfLimbs * SHIFT) >>> 1; + a = a.mult2to32(numberOfLimbs); + } + + do { + a = a.mult4(); + multiplications++; + } while (a.compareBothPositive(oneFourth) < 0); + } + + BigNum32 oneHalf = new BigNum32(1.5); + BigNum32 aHalf = a.divide2(); // a / 2 + + BigNum32 x = new BigNum32(1 / Math.sqrt(a.doubleValue())); // set the initial value to an approximation of 1 /sqrt(a) + + //Newton steps + BigNum32 newX = x.mult(oneHalf.sub(aHalf.mult(x.squareFull()))); // x = (3/2 - (a/2)*x^2)*x + + BigNum32 epsilon = new BigNum32(1); + epsilon.digits[epsilon.digits.length - 1] = 0x3; + epsilon.digits[0] = 0; + + int iter = 0; + while (newX.sub(x).abs_mutable().compareBothPositive(epsilon) >= 0 && iter < SQRT_MAX_ITERATIONS) { + x = newX; + newX = x.mult(oneHalf.sub(aHalf.mult(x.squareFull()))); + iter++; + } + + BigNum32 sqrta = newX.mult(a); //sqrt(a) = a * (1 /sqrt(a)); + + if(multiplications > 0) { //scale it up again + sqrta = sqrta.div2toi(multiplications); + } + else if(divisions > 0) { + sqrta = sqrta.mult2toi(divisions); + } + + return sqrta; + } + + public static void main(String[] args) { + MyApfloat a = new MyApfloat("-2"); + BigNum32.reinitializeTest(2000); + BigNum30.reinitializeTest(2000); + BigNum64.reinitializeTest(2000); + BigNum60.reinitializeTest(2000); + BigNum32 b = new BigNum32(0.999949292246963); + + + System.out.println(b.mult2toi(1)); + } +} diff --git a/src/fractalzoomer/core/BigNum60.java b/src/fractalzoomer/core/BigNum60.java new file mode 100644 index 000000000..bb508d664 --- /dev/null +++ b/src/fractalzoomer/core/BigNum60.java @@ -0,0 +1,3626 @@ +package fractalzoomer.core; + +import org.apfloat.Apfloat; +import org.apfloat.internal.LongMemoryDataStorage; + +import java.util.Arrays; + +import static fractalzoomer.core.MyApfloat.TWO; +import static org.apfloat.internal.LongRadixConstants.BASE_DIGITS; + +public class BigNum60 extends BigNum { + + public static long getPrecision() { + return (long)fracDigits * SHIFT; + } + public static String getName() { + return "Built-in (60)"; + } + + public long[] digits; + + private static int fracDigits; + private static int fracDigitsm1; + private static int fracDigitsp1; + private static int fracDigitsHalf; + + private static int fracDigits2; + private static boolean useToDouble2; + private static boolean useKaratsuba; + private static int initialLength; + private static boolean evenFracDigits; + + protected static boolean use_threads; + public static final long MASK = 0x0FFFFFFFFFFFFFFFL; + public static final int SHIFT = 60; + public static final long MASKD0 = 0x7FFFFFFFFFFFFFFFL; + + public static final long MASKI = 0x3FFFFFFFL; + public static final int SHIFTI = 30; + public static final int SHIFTIM1 = SHIFTI - 1; + public static final long MASK31 = 0x40000000L; + public static final int SHIFTM1 = SHIFT - 1; + public static final int SHIFTM52 = SHIFT - 52; + + private static final double TWO_TO_SHIFT = Math.pow(2,-SHIFT); + + //Todo change this + public static int THREADS_THRESHOLD = 141; + + public static void reinitialize(double digits) { + + double res = digits / SHIFT; + int temp = (int) (res); + + if (temp == 0) { + temp = 1; + } else if (digits % SHIFT != 0) { + //0 is floor + if(TaskDraw.BIGNUM_INITIALIZATION_ALGORITHM == 1) { //always + temp++; + } + else if (TaskDraw.BIGNUM_INITIALIZATION_ALGORITHM == 2) { //round + temp = (int)(res + 0.5); + } + } + + fracDigits = temp * TaskDraw.BIGNUM_PRECISION_FACTOR; + + initializeInternal(); + } + + public static void reinitializeTest(double digits) { + fracDigits = ((int)(digits / SHIFT) + 1) * TaskDraw.BIGNUM_PRECISION_FACTOR; + initializeInternal(); + } + + private static void initializeInternal() { + fracDigitsm1 = fracDigits - 1; + fracDigitsp1 = fracDigits + 1; + //useToDouble2 = fracDigits > 80; + useKaratsuba = fracDigits > 20; + fracDigitsHalf = fracDigits >> 1; + fracDigits2 = fracDigits << 1; + initialLength = fracDigitsHalf - ((fracDigitsp1) % 2); + evenFracDigits = (fracDigits & 1) == 0; + + use_threads = TaskDraw.USE_THREADS_IN_BIGNUM_LIBS && fracDigits >= THREADS_THRESHOLD && Runtime.getRuntime().availableProcessors() >= 2; + } + + private static BigNum60 getMax() { + BigNum60 n = new BigNum60(); + n.digits[0] = MASKD0; + n.sign = 1; + return n; + } + + protected BigNum60() { + digits = new long[fracDigitsp1]; + sign = 0; + isOne = false; + scale = 0; + offset = -1; + bitOffset = -1; + } + + protected BigNum60(BigNum60 other) { + digits = Arrays.copyOf(other.digits, other.digits.length); + sign = other.sign; + isOne = other.isOne; + scale = 0; + offset = -1; + bitOffset = -1; + } + + protected BigNum60(String val) { + this(new MyApfloat(val)); + } + + protected BigNum60(int val) { + digits = new long[fracDigitsp1]; + digits[0] = Math.abs(val); + isOne = val == 1 || val == -1; + sign = (int)Math.signum(val); + scale = 0; + offset = -1; + bitOffset = -1; + } + protected BigNum60(double val) { + + digits = new long[fracDigitsp1]; + + scale = 0; + offset = -1; + bitOffset = -1; + + if (val == 0) { + sign = 0; + isOne = false; + return; + } else if (Math.abs(val) == 1) { + isOne = true; + sign = (int) val; + digits[0] = 1; + return; + } + + sign = (int) Math.signum(val); + val = Math.abs(val); + digits[0] = (long) (val); + double fractionalPart = val - (long) val; + + if (fractionalPart != 0) { + + long bits = Double.doubleToRawLongBits(fractionalPart); + long f_exp = ((bits & 0x7FF0000000000000L) >>> 52) - Double.MAX_EXPONENT; + long mantissa = (bits & 0xFFFFFFFFFFFFFL) | (0x10000000000000L); + + if(f_exp < 0) { + long posExp = -f_exp; + + int index = (int) (posExp / SHIFT) + 1; + int bitOffset = (int) (posExp % SHIFT); + + if (bitOffset == 0) { + index--; + bitOffset = SHIFT; + } + + int k; + int i = index; + for (k = 53; k > 0 && i < digits.length; i++) { + int r; + + if (k == 53) { + r = SHIFT - k - bitOffset + 1; + k -= r < 0 ? 53 + r : 53 - r; + } else { + r = SHIFT - k; + k -= k; + } + + if (r >= 0) { + digits[i] = (mantissa << r) & MASK; + } else { + digits[i] = (mantissa >>> (-r)) & MASK; + } + + } + } + + } + + boolean isZero = true; + for(int i = 0; i < digits.length; i++) { + if(digits[i] != 0) { + isZero = false; + break; + } + } + + if(isZero) { + sign = 0; + } + } + + protected BigNum60(Apfloat val) { + + scale = 0; + this.offset = -1; + bitOffset = -1; + + Apfloat baseTwo = val.toRadix(2); + + sign = baseTwo.getImpl().signum(); + + isOne = false; + + digits = new long[fracDigitsp1]; + + LongMemoryDataStorage str = (LongMemoryDataStorage)baseTwo.getImpl().getDataStorage(); + + if(str == null || sign == 0) { //for zero + return; + } + + long[] data = str.getData(); + + if(data.length == 1 && data[0] == 1) { + isOne = true; + } + + int base_digits = BASE_DIGITS[2]; + + int offset = (int)str.getOffset(); + + int exponent = (int)baseTwo.getImpl().getExponent(); + + if(exponent == 1) { + int index = data.length >= 2 ? 1 : 0; + digits[0] = MASKD0 & data[index]; + offset++; + } + + int dataOffset = exponent < 0 ? Math.abs(exponent) * base_digits : 0; + + for(int i = dataOffset, j = 0; ; i++, j++) { + + int index2 = (i / SHIFT) + 1; + int index = j / base_digits + offset; + + if(index2 >= digits.length || index >= data.length) { + break; + } + + int shift = base_digits - (j % base_digits) - 1; + long bit = ((data[index] >>> shift) & 0x1); + + digits[index2] |= bit << (SHIFT - (i % SHIFT) - 1); + } + + boolean isZero = true; + for(int i = 0; i < digits.length; i++) { + if(digits[i] != 0) { + isZero = false; + break; + } + } + + if(isZero) { + sign = 0; + } + + } + + @Override + public long getScale() { + + if(sign == 0) { + return Long.MIN_VALUE; + } + + if(offset != -1) { + return scale; + } + + int i; + long digit = 0; + for(i = 0; i < digits.length; i++) { + digit = digits[i]; + if(digit != 0) { + break; + } + } + + if(i == digits.length) { + return Long.MIN_VALUE; + } + + /*int r; + for(r = i == 0 ? SHIFT : SHIFTM1; r >= 0; r--) { + if(digits[i] >>> r != 0) { + break; + } + }*/ + + offset = i; + long v = digit; + double d = v & ~(v >>> 1); + //int r = (int)(((Double.doubleToRawLongBits(d) >> 52) & 0x7ff) - 1023); //Fix for the 64 bit, not needed here + bitOffset = (int)((Double.doubleToRawLongBits(d) >> 52) - 1023); + //r |= (r >> 31); //Fix for zero, not needed here + + scale = i == 0 ? bitOffset : -(((long)i) * SHIFT) + bitOffset; + + return scale; + } + + public static BigNum60 getNegative(BigNum60 other) { + + BigNum60 copy = new BigNum60(); + copy.sign = other.sign; + copy.isOne = other.isOne; + + long[] otherDigits = other.digits; + long[] digits = copy.digits; + + long s = (~otherDigits[fracDigits] & MASK) + 1; + digits[fracDigits] = s & MASK; + for (int i = fracDigitsm1; i > 0 ; i--) { + s = (~otherDigits[i] & MASK) + (s>>>SHIFT); + digits[i] = s & MASK; + } + + s = (~otherDigits[0]) + (s>>>SHIFT); + digits[0] = s; + + return copy; + } + + @Override + public void negSelf() { + + if(sign == 0) { + return; + } + /*if(digits[fracDigits]>0) { + digits[fracDigits] = (int)((digits[fracDigits]-1)^MASK); + for(int i=fracDigits-1; i>0; i--) digits[i] ^= MASK; + digits[0] = ~digits[0]; + } else { + long s = digits[fracDigits-1]-1; digits[fracDigits-1] = (int)(~s&MASK); + for(int i=fracDigits-2; i>0; i--) { + s = digits[i]+(s>>SHIFT); digits[i] = (int)(~s&MASK); + } + digits[0] = (int)(~(digits[0]+(s>>SHIFT))); + }*/ + + long s = (~digits[fracDigits] & MASK) + 1; + digits[fracDigits] = s & MASK; + for (int i = fracDigitsm1; i > 0 ; i--) { + s = (~digits[i] & MASK) + (s>>>SHIFT); + digits[i] = s & MASK; + } + + s = (~digits[0]) + (s>>>SHIFT); + digits[0] = s; + + } + + @Override + public BigNum60 negate() { + + BigNum60 res = new BigNum60(this); + + res.sign *= -1; + + return res; + + } + + @Override + public BigNum60 abs() { + + BigNum60 res = new BigNum60(this); + + if(sign == -1) { + res.sign = 1; + } + + return res; + } + + @Override + public BigNum60 abs_mutable() { + + if(sign == -1) { + sign = 1; + } + + return this; + } + + @Override + public String toString() { + StringBuilder ret = new StringBuilder((sign == -1 ? "-" : "") + toHexString(digits[0])); + for(int i=1; i<=fracDigits; i++) { + ret.append(i==1 ? "." : " "); + ret.append(toHexString(digits[i])); + } + return doubleValueOld() + " " + ret.toString(); + } + + + @Override + public String bits() { + + String value = ""; + if(sign == -1) { + value = "-"; + } + for (int i = 0; i < digits.length; i++) { + + if (i == 0) { + boolean zero = true; + for (int j = SHIFTM1; j >= 0; j--) { + if (((digits[i] >>> j) & 0x1) == 1) { + zero = false; + } + + if (!zero) { + value += "" + ((digits[i] >>> j) & 0x1); + } + } + if(zero) { + value += "0"; + } + value += "."; + } else { + for (int j = SHIFTM1; j >= 0; j--) { + value += "" + ((digits[i] >>> j) & 0x1); + } + } + } + + return value; + + } + + @Override + public int compare(BigNum otherb) { + BigNum60 other = (BigNum60) otherb; + + int signA = sign; + + long[] otherDigits = other.digits; + + int signB = other.sign; + + long digit, otherDigit; + + if(signA < signB) { + return -1; + } + else if(signA > signB) { + return 1; + } + else { + if (signA == 0) { + return 0; + } + + if(signA < 0) { + for (int i = 0; i < digits.length; i++) { + digit = digits[i]; + otherDigit = otherDigits[i]; + if (digit < otherDigit) { + return 1; + } else if (digit > otherDigit) { + return -1; + } + } + } + else { + for (int i = 0; i < digits.length; i++) { + digit = digits[i]; + otherDigit = otherDigits[i]; + if (digit < otherDigit) { + return -1; + } else if (digit > otherDigit) { + return 1; + } + } + } + } + + return 0; + + } + + @Override + public int compareBothPositive(BigNum otherb) { + BigNum60 other = (BigNum60) otherb; + + int signA = sign; + int signB = other.sign; + + if(signA == 0 && signB == 0) { + return 0; + } + + long[] otherDigits = other.digits; + long digit, otherDigit; + + for (int i = 0; i < digits.length; i++) { + digit = digits[i]; + otherDigit = otherDigits[i]; + if (digit < otherDigit) { + return -1; + } else if (digit > otherDigit) { + return 1; + } + } + + return 0; + + } + +// static long binarySearch64(long v) { +// +// int shift = 32; +// +// long res = v >>> shift; +// +// if(res == 1) { +// return shift; +// } +// else if (res > 1) { +// shift += 16; //+16 +// } +// else { +// shift -= 16; // -16 +// } +// +// res = v >>> shift; +// +// if(res == 1) { +// return shift; +// } +// else if (res > 1) { +// shift += 8; //+8 +// } +// else { +// shift -= 8; // -8 +// } +// +// res = v >>> shift; +// +// if(res == 1) { +// return shift; +// } +// else if (res > 1) { +// shift += 4; // +4 +// } +// else { +// shift -= 4; // -4 +// } +// +// res = v >>> shift; +// +// if(res == 1) { +// return shift; +// } +// else if (res > 1) { +// shift += 2; // + 2 +// } +// else { +// shift -= 2; // -2 +// } +// +// res = v >>> shift; +// +// if(res == 1) { +// return shift; +// } +// else if (res > 1) { +// shift += 1; // + 1 +// } +// else { +// +// shift -= 1; // -1 +// } +// +// return shift; +// } +// +// +// static int debruijn64[] = +// { +// 0, 58, 1, 59, 47, 53, 2, 60, 39, 48, 27, 54, 33, 42, 3, 61, 51, 37, 40, 49, +// 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4, 62, 57, 46, 52, 38, 26, 32, 41, +// 50, 36, 17, 19, 29, 10, 13, 21, 56, 45, 25, 31, 35, 16, 9, 12, 44, 24, 15, +// 8, 23, 7, 6, 5, 63 +// }; +// +// static long msbDeBruijn64(long v) { +// +// +// /* Round down to one less than a power of 2. */ +// v |= v >>> 1; +// v |= v >>> 2; +// v |= v >>> 4; +// v |= v >>> 8; +// v |= v >>> 16; +// v |= v >>> 32; +// +// /* 0x03f6eaf2cd271461 is a hexadecimal representation of a De Bruijn +// * sequence for binary words of length 6. The binary representation +// * starts with 000000111111. This is required to make it work with one less +// * than a power of 2 instead of an actual power of 2. +// */ +// +// return debruijn64[(int)((v * 0x03f6eaf2cd271461L) >>> 58)]; +// } + + @Override + public double doubleValue() { + + long[] digits = this.digits; + + int i; + long digit = 0; + if(offset == -1) { + for (i = 0; i < digits.length; i++) { + digit = digits[i]; + if (digit != 0) { + break; + } + } + + if (i == digits.length) { + return 0; + } + + /*int r; + for(r = i == 0 ? SHIFT : SHIFTM1; r >= 0; r--) { + if(digits[i] >>> r != 0) { + break; + } + }*/ + offset = i; + long v = digit; + double d = v & ~(v >>> 1); + //int r = (int)(((Double.doubleToRawLongBits(d) >> 52) & 0x7ff) - 1023); //Fix for the 64 bit, not needed here + bitOffset = (int) ((Double.doubleToRawLongBits(d) >> 52) - 1023); + //r |= (r >> 31); //Fix for zero, not needed here + + scale = i == 0 ? bitOffset : -(((long)i) * SHIFT) + bitOffset; + } + else { + i = offset; + digit = digits[i]; + } + + + if (scale < Double.MIN_EXPONENT) { //accounting for +1 + return 0.0; + } + else if (scale >= Double.MAX_EXPONENT) { + return sign == -1 ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; + } + + long mantissa = 0; + + int temp = 52 - bitOffset; + + long val = digit; + if(temp >= 0) { + mantissa |= val << temp; + mantissa &= 0xFFFFFFFFFFFFFL; + if(temp == 0 && i + 1 < digits.length) { + mantissa += (digits[i + 1] >>> (SHIFTM1)) & 0x1; + } + } + else { + int shift = -temp; + mantissa |= val >>> shift; + mantissa &= 0xFFFFFFFFFFFFFL; + mantissa += (val >>> (shift - 1)) & 0x1; + } + + i++; + + int k; + for(k = bitOffset ; k < 52 && i < digits.length; k+=SHIFT, i++) { + val = digits[i]; + temp = 52 - k; + + if(temp > SHIFT) { + mantissa |= val << (temp - SHIFT); + mantissa &= 0xFFFFFFFFFFFFFL; + } + else { + int temp2 = k + SHIFTM52; + mantissa |= val >>> temp2; + mantissa &= 0xFFFFFFFFFFFFFL; + + if(temp2 == 0 && i + 1 < digits.length) { + mantissa += (digits[i + 1] >>> (SHIFTM1)) & 0x1; + } + else { + mantissa += (val >>> (temp2 - 1)) & 0x1; + } + } + } + + long finalScale = scale + (mantissa >>> 52); + if (finalScale <= Double.MIN_EXPONENT) { + return 0.0; + } + else if (finalScale >= Double.MAX_EXPONENT) { + return sign == -1 ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; + } + + // Bit 63 (the bit that is selected by the mask 0x8000000000000000L) represents the sign of the floating-point number. + // Bits 62-52 (the bits that are selected by the mask 0x7ff0000000000000L) represent the exponent. + // Bits 51-0 (the bits that are selected by the mask 0x000fffffffffffffL) represent the significand (sometimes called the mantissa) of the floating-point number. + + if(sign == -1) { + return Double.longBitsToDouble( (0x8000000000000000L) | (mantissa & 0xFFFFFFFFFFFFFL) | ((finalScale + Double.MAX_EXPONENT) << 52)); + } + else { + return Double.longBitsToDouble((mantissa & 0xFFFFFFFFFFFFFL) | ((finalScale + Double.MAX_EXPONENT) << 52)); + } + + } + + @Override + public double doubleValueOld() { + + if (sign == 0) { + return 0; + } + + if(isOne) { + return sign; + } + + if(useToDouble2) { + return doubleValue(); + } + + double ret = 0; + + + /*if(digits[0]>=0) { + for(int i=fracDigits; i>=0; i--) { + ret *= TWO_TO_SHIFT; + ret += digits[i]; + } + } else { + ret--; + for(int i=fracDigits; i>0; i--) { + ret += digits[i] - MASK; + ret *= TWO_TO_SHIFT; + } + ret += digits[0]+1; + }*/ + + for(int i=fracDigits; i>=0; i--) { + ret *= TWO_TO_SHIFT; + ret += digits[i]; + } + + ret *= sign; + return ret; + } + + @Override + public BigNum60 add(BigNum aa) { + BigNum60 a = (BigNum60) aa; + + BigNum60 result = new BigNum60(); + + long[] otherDigits = a.digits; + int otherSign = a.sign; + + long[] resDigits = result.digits; + + long[] digits = this.digits; + int sign = this.sign; + + if(sign == 0 || otherSign == 0) { + if(sign == 0 && otherSign == 0){ + return result; + } + else if(sign == 0) { + result.sign = otherSign; + result.isOne = a.isOne; + System.arraycopy(otherDigits, 0, resDigits, 0, otherDigits.length); + } + else { + result.sign = sign; + result.isOne = isOne; + System.arraycopy(digits, 0, resDigits, 0, digits.length); + } + return result; + } + + if(sign != otherSign) { + if(sign == -1) { + BigNum60 copy = getNegative(this); + digits = copy.digits; + } + else + { + BigNum60 copy = getNegative(a); + otherDigits = copy.digits; + } + } + + long s = 0; + long isNonZero = 0; + long temp; + for(int i=fracDigits; i>0; i--) { + s += digits[i]+otherDigits[i]; + temp = s&MASK; + isNonZero |= temp; + resDigits[i] = temp; + s >>>= SHIFT; + } + temp = digits[0]+otherDigits[0]+s; + result.isOne = (temp == 1 || temp == -1) && isNonZero == 0; + isNonZero |= temp; + resDigits[0] = temp; + + if(sign != otherSign) { + if(resDigits[0] < 0) { + result.sign = -1; + result.negSelf(); + } + else { + result.sign = isNonZero != 0 ? 1 : 0; + } + } + else { + result.sign = isNonZero != 0 ? sign : 0; + } + + return result; + } + + @Override + public BigNum60 add(int a) { + + BigNum60 result = new BigNum60(); + + int otherSign; + if(a == 0) { + otherSign = 0; + } + else if(a < 0) { + otherSign = -1; + } + else { + otherSign = 1; + } + + int otherDigits = a; + + boolean aIsOne = a == 1 || a == -1; + + long[] resDigits = result.digits; + + long[] digits = this.digits; + int sign = this.sign; + + if(sign == 0 || otherSign == 0) { + if(sign == 0 && otherSign == 0){ + return result; + } + else if(sign == 0) { + result.sign = otherSign; + result.isOne = aIsOne; + + if(otherSign < 0) { + a = ~a + 1; + } + + resDigits[0] = a; + } + else { + result.sign = sign; + result.isOne = isOne; + System.arraycopy(digits, 0, resDigits, 0, digits.length); + } + return result; + } + + if(sign != otherSign) { + if(sign == -1) { + BigNum60 copy = getNegative(this); + digits = copy.digits; + } + } + else { + if(otherSign < 0) { + otherDigits = ~otherDigits + 1; + } + } + + long isNonZero = 0; + long temp; + for(int i=fracDigits; i>0; i--) { + temp = resDigits[i] = digits[i]; + isNonZero |= temp; + } + + temp = digits[0] + otherDigits; + result.isOne = (temp == 1 || temp == -1) && isNonZero == 0; + isNonZero |= temp; + resDigits[0] = temp; + + if(sign != otherSign) { + if(resDigits[0] < 0) { + result.sign = -1; + result.negSelf(); + } + else { + result.sign = isNonZero != 0 ? 1 : 0; + } + } + else { + result.sign = isNonZero != 0 ? sign : 0; + } + + return result; + } + + @Override + public BigNum60 sub(BigNum aa) { + BigNum60 a = (BigNum60) aa; + + BigNum60 result = new BigNum60(); + + long[] otherDigits = a.digits; + int otherSign = a.sign; + + long[] resDigits = result.digits; + + long[] digits = this.digits; + int sign = this.sign; + + if(sign == 0 || otherSign == 0) { + if(sign == 0 && otherSign == 0){ + return result; + } + else if(sign == 0) { + result.sign = -otherSign; + result.isOne = a.isOne; + System.arraycopy(otherDigits, 0, resDigits, 0, otherDigits.length); + } + else { + result.sign = sign; + result.isOne = isOne; + System.arraycopy(digits, 0, resDigits, 0, digits.length); + } + return result; + } + + if(sign == otherSign) { + // + + -> + - + // - - -> - + + if(sign == -1) { + BigNum60 copy = getNegative(this); + digits = copy.digits; + } + else { + BigNum60 copy = getNegative(a); + otherDigits = copy.digits; + } + } + + long s = 0; + long isNonZero = 0; + long temp; + for(int i=fracDigits; i>0; i--) { + s += digits[i]+otherDigits[i]; + temp = s&MASK; + isNonZero |= temp; + resDigits[i] = temp; + s >>>= SHIFT; + } + temp = digits[0]+otherDigits[0]+s; + result.isOne = (temp == 1 || temp == -1) && isNonZero == 0; + isNonZero |= temp; + resDigits[0] = temp; + + if(sign == otherSign) { + if(resDigits[0] < 0) { + result.sign = -1; + result.negSelf(); + } + else { + result.sign = isNonZero != 0 ? 1 : 0; + } + } + else { + result.sign = isNonZero != 0 ? sign : 0; + } + + return result; + } + + @Override + public BigNum60 sub(int a) { + + BigNum60 result = new BigNum60(); + + int otherSign; + if(a == 0) { + otherSign = 0; + } + else if(a < 0) { + otherSign = -1; + } + else { + otherSign = 1; + } + + int otherDigits = a; + + boolean aIsOne = a == 1 || a == -1; + + long[] resDigits = result.digits; + + long[] digits = this.digits; + int sign = this.sign; + + if(sign == 0 || otherSign == 0) { + if(sign == 0 && otherSign == 0){ + return result; + } + else if(sign == 0) { + result.sign = -otherSign; + result.isOne = aIsOne; + + if(otherSign < 0) { + a = ~a + 1; + } + + resDigits[0] = a; + } + else { + result.sign = sign; + result.isOne = isOne; + System.arraycopy(digits, 0, resDigits, 0, digits.length); + } + return result; + } + + if(sign == otherSign) { + // + + -> + - + // - - -> - + + if(sign == -1) { + BigNum60 copy = getNegative(this); + digits = copy.digits; + } + otherDigits = ~otherDigits + 1; + } + else { + if(otherSign < 0) { + otherDigits = ~otherDigits + 1; + } + } + + + long isNonZero = 0; + long temp; + for(int i=fracDigits; i>0; i--) { + temp = resDigits[i] = digits[i]; + isNonZero |= temp; + } + + temp = digits[0] + otherDigits; + result.isOne = (temp == 1 || temp == -1) && isNonZero == 0; + isNonZero |= temp; + resDigits[0] = temp; + + if(sign == otherSign) { + if(resDigits[0] < 0) { + result.sign = -1; + result.negSelf(); + } + else { + result.sign = isNonZero != 0 ? 1 : 0; + } + } + else { + result.sign = isNonZero != 0 ? sign : 0; + } + + return result; + } + + @Override + public BigNum60 square() { + return squareFull(); + } + + @Override + public BigNum60 squareFull() { + BigNum60 result = new BigNum60(); + + if(sign == 0) { + return result; + } + + long[] resDigits = result.digits; + + if(isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = 1; + return result; + } + + long old_sum; + + long sum = 0; + + int length = initialLength; + + int j; + int k; + long carry = 0; + + long bdigit; + long adigit; + long bjhi, akhi, bjlo, aklo; + + int newLength = (length >>> 1) << 1; + boolean isOdd = (length & 1) == 1; + + for (j = 1, k = fracDigits; j <= newLength;) { + bdigit = digits[j]; + adigit = digits[k]; + + bjlo = bdigit & MASKI; + aklo = adigit & MASKI; + + bjhi = bdigit >>> SHIFTI; + akhi = adigit >>> SHIFTI; + + sum += bjhi * aklo; + //System.out.println("1: a" + j + "hi * a"+k+"lo"); + sum += bjlo * akhi; + //System.out.println("1: a" + j + "lo * a"+k+"hi"); + + j++;k--; + + bdigit = digits[j]; + adigit = digits[k]; + + bjlo = bdigit & MASKI; + aklo = adigit & MASKI; + + bjhi = bdigit >>> SHIFTI; + akhi = adigit >>> SHIFTI; + + sum += bjhi * aklo; + //System.out.println("1: a" + j + "hi * a"+k+"lo"); + sum += bjlo * akhi; + //System.out.println("1: a" + j + "lo * a"+k+"hi"); + + j++;k--; + + carry += sum >>> SHIFTI; + sum &= MASKI; + } + + if(isOdd) { + bdigit = digits[j]; + adigit = digits[k]; + + bjlo = bdigit & MASKI; + aklo = adigit & MASKI; + + bjhi = bdigit >>> SHIFTI; + akhi = adigit >>> SHIFTI; + + sum += bjhi * aklo; + //System.out.println("1: a" + j + "hi * a"+k+"lo"); + sum += bjlo * akhi; + //System.out.println("1: a" + j + "lo * a"+k+"hi"); + carry += sum >>> SHIFTI; + sum &= MASKI; + j++;k--; + } + + carry <<= 1; + + if(j == k) { + bdigit = digits[j]; + bjhi = bdigit >>> SHIFTI; + bjlo = bdigit & MASKI; + sum += (bjhi * bjlo); + sum <<= 1; + //System.out.println("1: a" + j + "lo * a"+j+"lo"); + } + else { + bdigit = digits[j]; + adigit = digits[k]; + + bjlo = bdigit & MASKI; + aklo = adigit & MASKI; + + bjhi = bdigit >>> SHIFTI; + akhi = adigit >>> SHIFTI; + + sum += bjhi * aklo; + //System.out.println("1: a" + j + "hi * a"+k+"lo"); + sum += bjlo * akhi; + //System.out.println("1: a" + j + "lo * a"+k+"hi"); + + sum <<= 1; + } + + carry += sum >>> SHIFTI; + sum &= MASKI; + + old_sum = carry + (sum >>> SHIFTIM1); // Roundish + + long d0 = digits[0]; + long d0lo = (int)d0; + + length = fracDigitsHalf; + + int toggle = evenFracDigits ? 0 : 1; + + for(int i = fracDigits; i > 0; i--, length -= toggle, toggle ^= 1) { + + sum = old_sum >>> 1; + carry = 0; + long sum2 = 0; + long carry2 = 0; + long extra = old_sum & 0x1; //For some reason this is better than adding old_sum in the end + + k = i; + + adigit = digits[k]; + + aklo = adigit & MASKI; + akhi = adigit >>> SHIFTI; + + bjlo = d0lo; + + int length2 = evenFracDigits ? length : length + 1; + int length2m1 = length2 - 1; + + newLength = (length2m1 >>> 1) << 1; + isOdd = (length2m1 & 1) == 1; + + sum += bjlo * aklo; + sum2 += bjlo * akhi; + carry += sum >>> SHIFTI; + sum &= MASKI; + + carry2 += sum2 >>> SHIFTI; + sum2 &= MASKI; + + for(j = 1; j < newLength;) { + bdigit = digits[j]; + bjlo = bdigit & MASKI; + bjhi = bdigit >>> SHIFTI; + + sum += bjhi * akhi; + //System.out.println("1: b" + j + "hi * a"+k+"hi"); + + k--; + + adigit = digits[k]; + + aklo = adigit & MASKI; + akhi = adigit >>> SHIFTI; + + //System.out.println("2: b" + j + "hi * a"+k+"lo"); + sum += bjlo * aklo; + sum2 += bjhi * aklo + bjlo * akhi; + + j++; + + bdigit = digits[j]; + bjlo = bdigit & MASKI; + bjhi = bdigit >>> SHIFTI; + + sum += bjhi * akhi; + //System.out.println("1: b" + j + "hi * a"+k+"hi"); + + k--; + + adigit = digits[k]; + + aklo = adigit & MASKI; + akhi = adigit >>> SHIFTI; + + //System.out.println("2: b" + j + "hi * a"+k+"lo"); + sum += bjlo * aklo; + sum2 += bjhi * aklo + bjlo * akhi; + + j++; + + carry += sum >>> SHIFTI; + sum &= MASKI; + + carry2 += sum2 >>> SHIFTI; + sum2 &= MASKI; + } + + if(isOdd) { + bdigit = digits[j]; + bjlo = bdigit & MASKI; + bjhi = bdigit >>> SHIFTI; + + sum += bjhi * akhi; + //System.out.println("1: b" + j + "hi * a"+k+"hi"); + + k--; + + adigit = digits[k]; + + aklo = adigit & MASKI; + akhi = adigit >>> SHIFTI; + + //System.out.println("2: b" + j + "hi * a"+k+"lo"); + sum += bjlo * aklo; + sum2 += bjhi * aklo + bjlo * akhi; + + j++; + } + + if(j == k) { + sum <<= 1; + sum += akhi * akhi + extra; + } + else { + bdigit = digits[j]; + bjhi = bdigit >>> SHIFTI; + + sum += bjhi * akhi; + + k--; + + adigit = digits[k]; + + aklo = adigit & MASKI; + + sum2 += bjhi * aklo; + + sum <<= 1; + sum += aklo * aklo + extra; + } + + sum2 <<= 1; + carry <<= 1; + carry2 <<= 1; + + /*newLength = (length >>> 1) << 1; + isOdd = (length & 1) == 1; + + for(j = 0; j < newLength;) { + + sum += bjlo * aklo; + //System.out.println("1: b" + j + "lo * a"+k+"lo"); + + sum2 += bjlo * akhi; + //System.out.println("2: b" + j + "lo * a"+k+"hi"); + + j++; + + bdigit = digits[j]; + bjlo = bdigit & MASKI; + bjhi = bdigit >>> SHIFTI; + + sum += bjhi * akhi; + //System.out.println("1: b" + j + "hi * a"+k+"hi"); + + k--; + + adigit = digits[k]; + + aklo = adigit & MASKI; + akhi = adigit >>> SHIFTI; + + //System.out.println("2: b" + j + "hi * a"+k+"lo"); + + //2nd + sum += bjlo * aklo; + //System.out.println("1: b" + j + "lo * a"+k+"lo"); + + sum2 += bjhi * aklo + bjlo * akhi; + //System.out.println("2: b" + j + "lo * a"+k+"hi"); + + j++; + + bdigit = digits[j]; + bjlo = bdigit & MASKI; + bjhi = bdigit >>> SHIFTI; + + sum += bjhi * akhi; + //System.out.println("1: b" + j + "hi * a"+k+"hi"); + + k--; + + adigit = digits[k]; + + aklo = adigit & MASKI; + akhi = adigit >>> SHIFTI; + + sum2 += bjhi * aklo; + //System.out.println("2: b" + j + "hi * a"+k+"lo"); + + + carry += sum >>> SHIFTI; + sum &= MASKI; + + carry2 += sum2 >>> SHIFTI; + sum2 &= MASKI; + } + + if(isOdd) { + sum += bjlo * aklo; + //System.out.println("1: b" + j + "lo * a"+k+"lo"); + + sum2 += bjlo * akhi; + //System.out.println("2: b" + j + "lo * a"+k+"hi"); + + j++; + + bdigit = digits[j]; + bjlo = bdigit & MASKI; + bjhi = bdigit >>> SHIFTI; + + sum += bjhi * akhi; + //System.out.println("1: b" + j + "hi * a"+k+"hi"); + + k--; + + adigit = digits[k]; + + aklo = adigit & MASKI; + akhi = adigit >>> SHIFTI; + + //System.out.println("2: b" + j + "hi * a"+k+"lo"); + + sum2 += bjhi * aklo; + + } + + if(j == k) { + sum <<= 1; + sum += aklo * aklo; + //System.out.println("1: a" + j + "lo * a"+j+"lo"); + } + else { + sum += bjlo * aklo; + sum2 += bjlo * akhi; + //System.out.println("1: a" + j + "lo * a"+k+"lo"); + sum <<= 1; + sum += akhi * akhi; + //System.out.println("1: a" + k + "hi * a"+k+"hi"); + +// carry1 += temp_sum1 >>> SHIFT; +// temp_sum1 &= MASK; + + + + //System.out.println("2: a" + j + "lo * a"+k+"hi"); + + } + + + + sum2 <<= 1; + carry += carry; // <<= 1 is slower for some reason + carry2 <<= 1; + + */ + + carry += sum >>> SHIFTI; + sum &= MASKI; + + sum2 += carry; + carry2 += sum2 >>> SHIFTI; + sum2 &= MASKI; + + //System.out.println("NEXT"); + + long di = (sum2 << SHIFTI) | sum; + resDigits[i] = di; + old_sum = carry2; + } + + sum = old_sum; + + sum += d0 * d0; + + resDigits[0] = sum & MASKD0; + result.sign = 1; + + return result; + } + + @Deprecated + @Override + public BigNum60 squareFullGolden() { + + + BigNum60 result = new BigNum60(); + + if(sign == 0) { + return result; + } + + long[] resDigits = result.digits; + long[] origDigitsA = this.digits; + + if(isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = 1; + return result; + } + + int newFracDigits = fracDigits2; + int newLength = newFracDigits + 1; + int[] digits = new int[newLength]; + + long old_sum; + + long sum = 0; + + int length = fracDigitsHalf; + + long carry = 0; + + digits[0] = (int)origDigitsA[0]; + int j = 1, k = fracDigits; + int base = (j << 1) - 1, base2 = (k << 1); + for (; j <= length; j++, k--) { + long bdigit = origDigitsA[j]; + long adigit = origDigitsA[k]; + + long bjlo = bdigit & MASKI; + long aklo = adigit & MASKI; + + long bjhi = bdigit >>> SHIFTI; + long akhi = adigit >>> SHIFTI; + + digits[base2] = (int)(aklo); + digits[base] = (int)(bjhi); + base++; + base2--; + digits[base2] = (int)(akhi); + digits[base] = (int)(bjlo); + base++; + base2--; + + sum += bjlo * akhi; + carry += sum >>> SHIFTI; + sum &= MASKI; + + sum += bjhi * aklo; + carry += sum >>> SHIFTI; + sum &= MASKI; + + } + + if(j == k) { + long bdigit = origDigitsA[j]; + long aklo = bdigit & MASKI; + long bjhi = bdigit >>> SHIFTI; + + digits[base2] = (int)(aklo); + digits[base] = (int)(bjhi); + + sum += bjhi * aklo; + carry += sum >>> SHIFTI; + sum &= MASKI; + } + + carry <<= 1; + sum <<= 1; + carry += sum >>> SHIFTI; + sum &= MASKI; + + + old_sum = carry + (sum >>> SHIFTIM1); // Roundish + + int m = fracDigits; + for(int i = newFracDigits; i > 0; i--, m--) { + + sum = old_sum; + + length = (i >> 1) - 1; + + long temp_sum = 0; + carry = 0; + + long bj, ak; + + for(j = 0, k = i; j <= length; j++, k--) { + bj = digits[j]; + ak = digits[k]; + temp_sum += bj * ak; + carry += temp_sum >>> SHIFTI; + temp_sum &= MASKI; + } + + carry <<= 1; + + bj = digits[j]; + ak = digits[k]; + temp_sum = (temp_sum << 1) + bj * ak; + + //carry += temp_sum >>> SHIFT; //Maybe its ok + //temp_sum &= MASK; + + sum += temp_sum; + carry += sum >>> SHIFTI; + sum &= MASKI; + + long finalVal = sum; + + i--;//Unrolling + + sum = carry; + + length = i >> 1; + + temp_sum = 0; + carry = 0; + + for(j = 0, k = i; j <= length; j++, k--) { + bj = digits[j]; + ak = digits[k]; + temp_sum += bj * ak; + carry += temp_sum >>> SHIFTI; + temp_sum &= MASKI; + } + + carry <<= 1; + temp_sum <<= 1; + + //carry += temp_sum >>> SHIFT; //Maybe its ok + //temp_sum &= MASK; + + sum += temp_sum; + carry += sum >>> SHIFTI; + sum &= MASKI; + + finalVal |= sum << SHIFTI; + + resDigits[m] = finalVal; + old_sum = carry; + } + + sum = old_sum; + + long bj = digits[0]; + long ak = digits[0]; + sum += bj * ak; + + result.sign = 1; + + result.digits[0] = sum; + + return result; + } + + @Override + public BigNum60 mult(BigNum bb) { + BigNum60 b = (BigNum60) bb; + if(useKaratsuba) { + return multKaratsuba(b); + } + else { + return multFull(b); + } + } + + @Deprecated + public BigNum60 multFullGolden(BigNum60 b) { + + BigNum60 result = new BigNum60(); + + if(sign == 0 || b.sign == 0) { + return result; + } + + long[] resDigits = result.digits; + long[] origDigitsA = this.digits; + long[] origDigitsB = b.digits; + + if(isOne || b.isOne) { + if (isOne && b.isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = sign * b.sign; + } + else if(isOne) { + System.arraycopy(origDigitsB, 0, resDigits, 0, origDigitsB.length); + result.sign = sign * b.sign; + } + else { + System.arraycopy(origDigitsA, 0, resDigits, 0, origDigitsA.length); + result.sign = sign * b.sign; + } + return result; + } + + int newFracDigits = fracDigits2; + int newLength = newFracDigits + 1; + int[] digits = new int[newLength]; + int[] bdigits = new int[newLength]; + + long old_sum; + + long sum = 0; + long carry = 0; + digits[0] = (int)origDigitsA[0]; + bdigits[0] = (int)origDigitsB[0]; + + for (int j = 1, base = (j << 1) - 1, k = fracDigits, base2 = (k << 1); j <= fracDigits; j++, k--) { + + long bdigit = origDigitsB[j]; + long adigit = origDigitsA[k]; + + long bjlo = bdigit & MASKI; + long aklo = adigit & MASKI; + + long bjhi = bdigit >>> SHIFTI; + long akhi = adigit >>> SHIFTI; + + digits[base2] = (int)(aklo); + bdigits[base] = (int)(bjhi); + base++; + base2--; + digits[base2] = (int)(akhi); + bdigits[base] = (int)(bjlo); + base++; + base2--; + + sum += bjlo * akhi; + carry += sum >>> SHIFTI; + sum &= MASKI; + + sum += bjhi * aklo; + carry += sum >>> SHIFTI; + sum &= MASKI; + + } + + old_sum = carry + (sum >>> SHIFTIM1); // Roundish + + long isNonZero = 0; + for(int i = newFracDigits, m = fracDigits; i > 0; i--, m--) { + + sum = old_sum; //carry from prev + carry = 0; + for(int j = 0, k = i; j <= i; j++, k--) { + long bj = bdigits[j]; + long ak = digits[k]; + + sum += bj * ak; + carry += sum >>> SHIFTI; + sum &= MASKI; + + } + + long finalVal = sum; + + i--;//Unrolling + + sum = carry; //carry from prev + carry = 0; + for(int j = 0, k = i; j <= i; j++, k--) { + long bj = bdigits[j]; + long ak = digits[k]; + + sum += bj * ak; + carry += sum >>> SHIFTI; + sum &= MASKI; + + } + + finalVal |= sum << SHIFTI; + resDigits[m] = finalVal; + + isNonZero |= finalVal; + old_sum = carry; + } + + sum = old_sum; + + long bj = bdigits[0]; + long ak = digits[0]; + + sum += bj * ak; + + long d0 = sum & MASKD0; + result.digits[0] = sum; + result.isOne = d0 == 1 && isNonZero == 0; + result.sign = sign * b.sign; + + return result; + + } + + public BigNum60 multFull(BigNum60 b) { + + BigNum60 result = new BigNum60(); + + if(sign == 0 || b.sign == 0) { + return result; + } + + long[] bdigits = b.digits; + + long[] resDigits = result.digits; + + if(isOne || b.isOne) { + if (isOne && b.isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = sign * b.sign; + } + else if(isOne) { + System.arraycopy(bdigits, 0, resDigits, 0, bdigits.length); + result.sign = sign * b.sign; + } + else { + System.arraycopy(digits, 0, resDigits, 0, digits.length); + result.sign = sign * b.sign; + } + return result; + } + + + long old_sum; + + long sum = 0; + long carry = 0; + long bdigit; + long adigit; + long bjhi, akhi, bjlo, aklo; + + int newLength = fracDigitsHalf << 1; + int j, k; + + for (j = 1, k = fracDigits; j <= newLength;) { + + bdigit = bdigits[j]; + adigit = digits[k]; + + bjlo = bdigit & MASKI; + aklo = adigit & MASKI; + + bjhi = bdigit >>> SHIFTI; + akhi = adigit >>> SHIFTI; + + sum += bjhi * aklo; + sum += bjlo * akhi; + + j++;k--; + + bdigit = bdigits[j]; + adigit = digits[k]; + + bjlo = bdigit & MASKI; + aklo = adigit & MASKI; + + bjhi = bdigit >>> SHIFTI; + akhi = adigit >>> SHIFTI; + + sum += bjhi * aklo; + sum += bjlo * akhi; + + carry += sum >>> SHIFTI; + sum &= MASKI; + + j++;k--; + } + + if(!evenFracDigits) { + bdigit = bdigits[j]; + adigit = digits[k]; + + bjlo = bdigit & MASKI; + aklo = adigit & MASKI; + + bjhi = bdigit >>> SHIFTI; + akhi = adigit >>> SHIFTI; + + sum += bjhi * aklo; + sum += bjlo * akhi; + + carry += sum >>> SHIFTI; + sum &= MASKI; + } + + old_sum = carry + (sum >>> SHIFTIM1); // Roundish + + long carry2; + long sum2; + + long isNonZero = 0; + + long bd0 = bdigits[0]; + long bd0lo = (int)bd0; + + for(int i = fracDigits; i > 0; i--) { + + sum = old_sum; //carry from prev + carry = 0; + carry2 = 0; + sum2 = 0; + k = i; + adigit = digits[k]; + + aklo = adigit & MASKI; + akhi = adigit >>> SHIFTI; + + newLength = (i >>> 1) << 1; + boolean isOdd = (i & 1) == 1; + + bjlo = bd0lo; + + for(j = 0; j < newLength;) { + + sum += bjlo * aklo; + //System.out.println("1: b" + j + "lo * a"+k+"lo"); + + sum2 += bjlo * akhi; + //System.out.println("2: b" + j + "lo * a"+k+"hi"); + + j++; + + bdigit = bdigits[j]; + bjlo = bdigit & MASKI; + bjhi = bdigit >>> SHIFTI; + + sum += bjhi * akhi; + //System.out.println("1: b" + j + "hi * a"+k+"hi"); + + k--; + + adigit = digits[k]; + + aklo = adigit & MASKI; + akhi = adigit >>> SHIFTI; + + //System.out.println("2: b" + j + "hi * a"+k+"lo"); + + //2nd + sum += bjlo * aklo; + //System.out.println("1: b" + j + "lo * a"+k+"lo"); + + sum2 += bjhi * aklo + bjlo * akhi; + //System.out.println("2: b" + j + "lo * a"+k+"hi"); + + j++; + + bdigit = bdigits[j]; + bjlo = bdigit & MASKI; + bjhi = bdigit >>> SHIFTI; + + sum += bjhi * akhi; + //System.out.println("1: b" + j + "hi * a"+k+"hi"); + + k--; + + adigit = digits[k]; + + aklo = adigit & MASKI; + akhi = adigit >>> SHIFTI; + + sum2 += bjhi * aklo; + //System.out.println("2: b" + j + "hi * a"+k+"lo"); + + + carry += sum >>> SHIFTI; + sum &= MASKI; + + carry2 += sum2 >>> SHIFTI; + sum2 &= MASKI; + } + + if(isOdd) { + sum += bjlo * aklo; + //System.out.println("1: b" + j + "lo * a"+k+"lo"); + + sum2 += bjlo * akhi; + //System.out.println("2: b" + j + "lo * a"+k+"hi"); + + j++; + + bdigit = bdigits[j]; + bjlo = bdigit & MASKI; + bjhi = bdigit >>> SHIFTI; + + sum += bjhi * akhi; + //System.out.println("1: b" + j + "hi * a"+k+"hi"); + + k--; + + adigit = digits[k]; + + aklo = adigit & MASKI; + + sum2 += bjhi * aklo; + //System.out.println("2: b" + j + "hi * a"+k+"lo"); + + +// carry += sum >>> SHIFTI; +// sum &= MASKI; +// +// carry2 += sum2 >>> SHIFTI; +// sum2 &= MASKI; + } + + sum += bjlo * aklo; + //System.out.println("1: b" + j + "lo * a"+k+"lo"); + carry += sum >>> SHIFTI; + sum &= MASKI; + + sum2 += carry; + carry2 += sum2 >>> SHIFTI; + sum2 &= MASKI; + + //System.out.println("Next"); + + long di = (sum2 << SHIFTI) | sum; + resDigits[i] = di; + isNonZero |= di; + //System.out.println(result.digits[i] ); + old_sum = carry2; + //System.out.println("NEXT"); + } + + long d0 = (bd0 * digits[0] + old_sum) & MASKD0; + resDigits[0] = d0; + + result.isOne = d0 == 1 && isNonZero == 0; + + result.sign = sign * b.sign; + + return result; + + } + + + public BigNum60 multKaratsuba(BigNum60 b) { + + BigNum60 result = new BigNum60(); + + if(sign == 0 || b.sign == 0) { + return result; + } + + long[] bdigits = b.digits; + long[] resDigits = result.digits; + + if(isOne || b.isOne) { + if (isOne && b.isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = sign * b.sign; + } + else if(isOne) { + System.arraycopy(bdigits, 0, resDigits, 0, bdigits.length); + result.sign = sign * b.sign; + } + else { + System.arraycopy(digits, 0, resDigits, 0, digits.length); + result.sign = sign * b.sign; + } + return result; + } + + long[] partialshi = new long[fracDigitsp1]; + long[] partialslo = new long[fracDigitsp1]; + + long PartialSum = 0; + long PartialCarry = 0; + + int newLength = fracDigitsHalf << 1; + boolean isOdd = (fracDigits & 1) == 1; + long p; + int i; + long bdigit; + long adigit; + long bhi, ahi, blo, alo; + + long bd0 = bdigits[0]; + long bd0lo = (int)bd0; + long ad0 = digits[0]; + long ad0lo = (int)ad0; + + p = ad0lo * bd0lo; + partialslo[0] = p; + PartialSum += p; + + PartialCarry += PartialSum >>> SHIFTI; + PartialSum &= MASKI; + + for(i = 1; i < newLength;) { + adigit = digits[i]; + bdigit = bdigits[i]; + + ahi = adigit >>> SHIFTI; + alo = adigit & MASKI; + + bhi = bdigit >>> SHIFTI; + blo = bdigit & MASKI; + + p = ahi * bhi; + partialshi[i] = p; + PartialSum += p; + + p = alo * blo; + partialslo[i] = p; + PartialSum += p; + + i++; + + adigit = digits[i]; + bdigit = bdigits[i]; + + ahi = adigit >>> SHIFTI; + alo = adigit & MASKI; + + bhi = bdigit >>> SHIFTI; + blo = bdigit & MASKI; + + p = ahi * bhi; + partialshi[i] = p; + PartialSum += p; + + p = alo * blo; + partialslo[i] = p; + PartialSum += p; + + i++; + + PartialCarry += PartialSum >>> SHIFTI; + PartialSum &= MASKI; + } + + if(isOdd) { + adigit = digits[i]; + bdigit = bdigits[i]; + + ahi = adigit >>> SHIFTI; + alo = adigit & MASKI; + + bhi = bdigit >>> SHIFTI; + blo = bdigit & MASKI; + + p = ahi * bhi; + partialshi[i] = p; + PartialSum += p; + + p = alo * blo; + partialslo[i] = p; + PartialSum += p; + + PartialCarry += PartialSum >>> SHIFTI; + PartialSum &= MASKI; + } + + long old_sum; + + long p0 = partialslo[0]; + + long sum = p0; + + int length = initialLength; + + int j; + int k; + long carry = sum >>> SHIFTI; + sum &= MASKI; + + long bj, bk, aj, ak; + + newLength = (length >>> 1) << 1; + isOdd = (length & 1) == 1; + long bklo, ajhi, bjhi, aklo; + long bjlo, akhi, bkhi, ajlo; + + for (j = 1, k = fracDigits; j <= newLength;) { + bj = bdigits[j]; + bk = bdigits[k]; + aj = digits[j]; + ak = digits[k]; + + bjhi = bj >>> SHIFTI; + bjlo = bj & MASKI; + + ajhi = aj >>> SHIFTI; + ajlo = aj & MASKI; + + bkhi = bk >>> SHIFTI; + bklo = bk & MASKI; + + akhi = ak >>> SHIFTI; + aklo = ak & MASKI; + + sum += (bjhi + bklo) * (aklo + ajhi) + (bjlo + bkhi) * (akhi + ajlo); + + + j++; k--; + + bj = bdigits[j]; + bk = bdigits[k]; + aj = digits[j]; + ak = digits[k]; + + bjhi = bj >>> SHIFTI; + bjlo = bj & MASKI; + + ajhi = aj >>> SHIFTI; + ajlo = aj & MASKI; + + bkhi = bk >>> SHIFTI; + bklo = bk & MASKI; + + akhi = ak >>> SHIFTI; + aklo = ak & MASKI; + + sum += (bjhi + bklo) * (aklo + ajhi) + (bjlo + bkhi) * (akhi + ajlo); + + j++; k--; + + carry += sum >>> SHIFTI; + sum &= MASKI; + + //System.out.println("partials " + k + " partials " + j); + + } + + if(isOdd) { + bj = bdigits[j]; + bk = bdigits[k]; + aj = digits[j]; + ak = digits[k]; + + bjhi = bj >>> SHIFTI; + bjlo = bj & MASKI; + + ajhi = aj >>> SHIFTI; + ajlo = aj & MASKI; + + bkhi = bk >>> SHIFTI; + bklo = bk & MASKI; + + akhi = ak >>> SHIFTI; + aklo = ak & MASKI; + + sum += (bjhi + bklo) * (aklo + ajhi) + (bjlo + bkhi) * (akhi + ajlo); + + j++; k--; + + //carry += sum >>> SHIFTI; + //sum &= MASKI; + } + + if(j == k) { + bj = bdigits[j]; + aj = digits[j]; + + bjhi = bj >>> SHIFTI; + bjlo = bj & MASKI; + + ajhi = aj >>> SHIFTI; + ajlo = aj & MASKI; + + sum += (bjhi + bjlo) * (ajlo + ajhi); + } + else { + bj = bdigits[j]; + bk = bdigits[k]; + aj = digits[j]; + ak = digits[k]; + + bjhi = bj >>> SHIFTI; + bjlo = bj & MASKI; + + ajhi = aj >>> SHIFTI; + ajlo = aj & MASKI; + + bkhi = bk >>> SHIFTI; + bklo = bk & MASKI; + + akhi = ak >>> SHIFTI; + aklo = ak & MASKI; + + sum += (bjhi + bklo) * (aklo + ajhi) + (bjlo + bkhi) * (akhi + ajlo); + } + + carry += sum >>> SHIFTI; + sum &= MASKI; + + sum -= PartialSum; + carry -= ((sum & MASK31) >>> SHIFTI) + PartialCarry; + sum &= MASKI; + + old_sum = carry + (sum >>> SHIFTIM1); // Roundish, adds bias because 10000 is always shifted upwards + + + long isNonZero = 0; + + length = fracDigitsHalf; + + int toggle = evenFracDigits ? 0 : 1; + + for(i = fracDigits; i > 0; i--, length -= toggle, toggle ^= 1) { + + sum = old_sum; + long sum2 = 0; + carry = 0; + long carry2 = 0; + + k = i; + + ak = digits[k]; + bk = bdigits[k]; + + bkhi = bk >>> SHIFTI; + bklo = bk & MASKI; + akhi = ak >>> SHIFTI; + aklo = ak & MASKI; + +// bjlo = bd0lo; +// ajlo = ad0lo; + //newLength = (length >>> 1) << 1; + //isOdd = (length & 1) == 1; + + /* for(j = 0; j < newLength;) { + sum += (bjlo + bklo) * (aklo + ajlo); + sum2 += (bjlo + bkhi) * (akhi + ajlo); + + j++; + aj = digits[j]; + bj = bdigits[j]; + + bjhi = bj >>> SHIFTI; + bjlo = bj & MASKI; + ajhi = aj >>> SHIFTI; + ajlo = aj & MASKI; + + sum += (bjhi + bkhi) * (akhi + ajhi); + + k--; + ak = digits[k]; + bk = bdigits[k]; + + bkhi = bk >>> SHIFTI; + bklo = bk & MASKI; + akhi = ak >>> SHIFTI; + aklo = ak & MASKI; + + //2nd + + sum += (bjlo + bklo) * (aklo + ajlo); + sum2 += (bjhi + bklo) * (aklo + ajhi) + (bjlo + bkhi) * (akhi + ajlo); + + j++; + aj = digits[j]; + bj = bdigits[j]; + + bjhi = bj >>> SHIFTI; + bjlo = bj & MASKI; + ajhi = aj >>> SHIFTI; + ajlo = aj & MASKI; + + sum += (bjhi + bkhi) * (akhi + ajhi); + + k--; + ak = digits[k]; + bk = bdigits[k]; + + bkhi = bk >>> SHIFTI; + bklo = bk & MASKI; + akhi = ak >>> SHIFTI; + aklo = ak & MASKI; + + sum2 += (bjhi + bklo) * (aklo + ajhi); + + carry += sum >>> SHIFTI; + sum &= MASKI; + carry2 += sum2 >>> SHIFTI; + sum2 &= MASKI; + } + + if(isOdd) { + sum += (bjlo + bklo) * (aklo + ajlo); + sum2 += (bjlo + bkhi) * (akhi + ajlo); + + j++; + aj = digits[j]; + bj = bdigits[j]; + + bjhi = bj >>> SHIFTI; + bjlo = bj & MASKI; + ajhi = aj >>> SHIFTI; + ajlo = aj & MASKI; + + sum += (bjhi + bkhi) * (akhi + ajhi); + + k--; + ak = digits[k]; + bk = bdigits[k]; + + bkhi = bk >>> SHIFTI; + bklo = bk & MASKI; + akhi = ak >>> SHIFTI; + aklo = ak & MASKI; + + sum2 += (bjhi + bklo) * (aklo + ajhi); + + +// carry1 += sum1 >>> SHIFT; +// sum1 &= MASK; +// carry2 += sum2 >>> SHIFT; +// sum2 &= MASK; + } + + if(j == k) { + sum += (partialslo[length] << 1); + } + else { + sum += (bjlo + bklo) * (aklo + ajlo) + (partialshi[length + 1] << 1); + sum2 += (bjlo + bkhi) * (akhi + ajlo); + }*/ + + sum += (bd0lo + bklo) * (aklo + ad0lo); + sum2 += (bd0lo + bkhi) * (akhi + ad0lo); + carry += sum >>> SHIFTI; + sum &= MASKI; + carry2 += sum2 >>> SHIFTI; + sum2 &= MASKI; + + int length2 = evenFracDigits ? length : length + 1; + int length2m1 = length2 - 1; + + newLength = (length2m1 >>> 1) << 1; + isOdd = (length2m1 & 1) == 1; + + for(j = 1; j < newLength;) { + aj = digits[j]; + bj = bdigits[j]; + + bjhi = bj >>> SHIFTI; + bjlo = bj & MASKI; + ajhi = aj >>> SHIFTI; + ajlo = aj & MASKI; + + sum += (bjhi + bkhi) * (akhi + ajhi); + + k--; + + ak = digits[k]; + bk = bdigits[k]; + + bkhi = bk >>> SHIFTI; + bklo = bk & MASKI; + akhi = ak >>> SHIFTI; + aklo = ak & MASKI; + + sum += (bjlo + bklo) * (aklo + ajlo); + sum2 += (bjhi + bklo) * (aklo + ajhi) + (bjlo + bkhi) * (akhi + ajlo); + + j++; + //2nd + + aj = digits[j]; + bj = bdigits[j]; + + bjhi = bj >>> SHIFTI; + bjlo = bj & MASKI; + ajhi = aj >>> SHIFTI; + ajlo = aj & MASKI; + + sum += (bjhi + bkhi) * (akhi + ajhi); + + k--; + + ak = digits[k]; + bk = bdigits[k]; + + bkhi = bk >>> SHIFTI; + bklo = bk & MASKI; + akhi = ak >>> SHIFTI; + aklo = ak & MASKI; + + sum += (bjlo + bklo) * (aklo + ajlo); + sum2 += (bjhi + bklo) * (aklo + ajhi) + (bjlo + bkhi) * (akhi + ajlo); + j++; + + carry += sum >>> SHIFTI; + sum &= MASKI; + carry2 += sum2 >>> SHIFTI; + sum2 &= MASKI; + } + + if(isOdd) { + aj = digits[j]; + bj = bdigits[j]; + + bjhi = bj >>> SHIFTI; + bjlo = bj & MASKI; + ajhi = aj >>> SHIFTI; + ajlo = aj & MASKI; + + sum += (bjhi + bkhi) * (akhi + ajhi); + + k--; + + ak = digits[k]; + bk = bdigits[k]; + + bkhi = bk >>> SHIFTI; + bklo = bk & MASKI; + akhi = ak >>> SHIFTI; + aklo = ak & MASKI; + + sum += (bjlo + bklo) * (aklo + ajlo); + sum2 += (bjhi + bklo) * (aklo + ajhi) + (bjlo + bkhi) * (akhi + ajlo); + j++; + +// carry += sum >>> SHIFTI; +// sum &= MASKI; +// carry2 += sum2 >>> SHIFTI; +// sum2 &= MASKI; + } + + + if(j == k) { + sum += (partialshi[length2] << 1); + } + else { + aj = digits[j]; + bj = bdigits[j]; + + bjhi = bj >>> SHIFTI; + //bjlo = bj & MASKI; + ajhi = aj >>> SHIFTI; + //ajlo = aj & MASKI; + + sum += (bjhi + bkhi) * (akhi + ajhi); + + k--; + + ak = digits[k]; + bk = bdigits[k]; + + //bkhi = bk >>> SHIFTI; + bklo = bk & MASKI; + //akhi = ak >>> SHIFTI; + aklo = ak & MASKI; + + sum2 += (bjhi + bklo) * (aklo + ajhi); + + + sum += (partialslo[length2] << 1); + } + + //System.out.println("NEXT"); + + carry += sum >>> SHIFTI; + sum &= MASKI; + + sum -= PartialSum; + carry -= ((sum & MASK31) >>> SHIFTI) + PartialCarry; + sum &= MASKI; + + long partialI = partialslo[i]; + + PartialSum -= partialI & MASKI; + PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFTI; + PartialSum &= MASKI; + + sum2 += carry; + carry2 += sum2 >>> SHIFTI; + sum2 &= MASKI; + + + sum2 -= PartialSum; + + carry2 -= ((sum2 & MASK31) >>> SHIFTI) + PartialCarry; + sum2 &= MASKI; + + partialI = partialshi[i]; + + PartialSum -= partialI & MASKI; + PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFTI; + PartialSum &= MASKI; + + long di = (sum2 << SHIFTI) | sum; + isNonZero |= di; + resDigits[i] = di; + + old_sum = carry2; + } + + sum = p0 + old_sum; + + long d0 = sum & MASKD0; + resDigits[0] = d0; + + //result.isOne = ( (((d0 ^ isNonZero) | d0) & ~(isNonZero & 0x1)) ) == 1 + result.isOne = d0 == 1 && isNonZero == 0; + + result.sign = sign * b.sign; + + return result; + + } + + @Deprecated + public BigNum60 multKaratsubaGolden(BigNum60 b) { + + BigNum60 result = new BigNum60(); + + if(sign == 0 || b.sign == 0) { + return result; + } + + long[] resDigits = result.digits; + long[] origDigitsA = this.digits; + long[] origDigitsB = b.digits; + + if(isOne || b.isOne) { + if (isOne && b.isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = sign * b.sign; + } + else if(isOne) { + System.arraycopy(origDigitsB, 0, resDigits, 0, origDigitsB.length); + result.sign = sign * b.sign; + } + else { + System.arraycopy(origDigitsA, 0, resDigits, 0, origDigitsA.length); + result.sign = sign * b.sign; + } + return result; + } + + int newFracDigits = fracDigits2; + int newLength = newFracDigits + 1; + int[] digits = new int[newLength]; + int[] bdigits = new int[newLength]; + + long[] partials = new long[newLength]; + + + long PartialSum = 0; + long PartialCarry = 0; + + long adigit = (int)origDigitsA[0]; + long bdigit = (int)origDigitsB[0]; + digits[0] = (int)adigit; + bdigits[0] = (int)bdigit; + + long p = adigit * bdigit; + long p0 = p; + partials[0] = p; + PartialSum += p; + + PartialCarry += PartialSum >>> SHIFTI; + PartialSum &= MASKI; + + for(int i = 1, base = (i << 1) - 1; i <=fracDigits; i++) { + + bdigit = origDigitsB[i]; + adigit = origDigitsA[i]; + + long bjlo = bdigit & MASKI; + long aklo = adigit & MASKI; + + long bjhi = bdigit >>> SHIFTI; + long akhi = adigit >>> SHIFTI; + + digits[base] = (int)(akhi); + bdigits[base] = (int)(bjhi); + p = akhi * bjhi; + partials[base] = p; + PartialSum += p; + PartialCarry += PartialSum >>> SHIFTI; + PartialSum &= MASKI; + + base++; + digits[base] = (int)(aklo); + bdigits[base] = (int)(bjlo); + p = aklo * bjlo; + partials[base] = p; + PartialSum += p; + + PartialCarry += PartialSum >>> SHIFTI; + PartialSum &= MASKI; + base++; + + + } + + long old_sum; + + long sum = p0; + + int length = fracDigits;//newFracDigits >> 1; + + int j; + int k; + long carry = 0; + for (j = 1, k = newFracDigits; j <= length; j++, k--) { + long bj = bdigits[j]; + long bk = bdigits[k]; + long aj = digits[j]; + long ak = digits[k]; + + sum += (bk + bj) * (ak + aj); + carry += sum >>> SHIFTI; + sum &= MASKI; + + //System.out.println("partials " + k + " partials " + j); + + } + + long bj, bk, aj, ak; + + sum -= PartialSum; + carry -= ((sum & MASK31) >>> SHIFTI) + PartialCarry; + sum &= MASKI; + + old_sum = carry + (sum >>> SHIFTIM1); // Roundish + + + long isNonZero = 0; + int m = fracDigits; + for(int i = newFracDigits; i > 0; i--, m--) { + + length = (i >> 1) - 1; + + sum = old_sum; //carry from prev + + carry = 0; + for(j = 0, k = i; j <= length; j++, k--) { + bj = bdigits[j]; + bk = bdigits[k]; + aj = digits[j]; + ak = digits[k]; + + sum += (bk + bj) * (ak + aj); + + carry += sum >>> SHIFTI; + sum &= MASKI; + //System.out.println("b " + k + " + b " + j + " * a " + k + " + a " + j); + //System.out.println("partials " + k + " partials " + j); + + } + + + // System.out.println("partials " + k); + //System.out.println("NEXT"); + sum += partials[k] << 1; + + carry += sum >>> SHIFTI; + sum &= MASKI; + + sum -= PartialSum; + carry -= ((sum & MASK31) >>> SHIFTI) + PartialCarry; + sum &= MASKI; + + long partialI = partials[i]; + PartialSum -= partialI & MASKI; + PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFTI; + //PartialCarry -= ((PartialSum & MASK31) >>> SHIFTI); + PartialSum &= MASKI; + //PartialCarry -= partialI >>> SHIFTI; + + long finalVal = sum; + + i--;//Unrolling + + length = i >> 1; + + sum = carry; + + carry = 0; + for(j = 0, k = i; j <= length; j++, k--) { + bj = bdigits[j]; + bk = bdigits[k]; + aj = digits[j]; + ak = digits[k]; + + sum += (bk + bj) * (ak + aj); + + carry += sum >>> SHIFTI; + sum &= MASKI; + + //System.out.println("b " + k + " + b " + j + " * a " + k + " + a " + j); + } + + sum -= PartialSum; + carry -= ((sum & MASK31) >>> SHIFTI) + PartialCarry; + finalVal |= (sum & MASKI) << SHIFTI; + + partialI = partials[i]; + PartialSum -= partialI & MASKI; + PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFTI; + //PartialCarry -= ((PartialSum & MASK31) >>> SHIFTI); + PartialSum &= PartialSum & MASKI; + //PartialCarry -= partialI >>> SHIFTI; + + isNonZero |= finalVal; + resDigits[m] = finalVal; + old_sum = carry; + } + + sum = old_sum; + + sum += p0; + + long d0 = sum & MASKD0; + result.digits[0] = sum; + result.isOne = d0 == 1 && isNonZero == 0; + result.sign = sign * b.sign; + + return result; + + } + + @Override + /* Sign is positive */ + public BigNum60 mult(int value) { + BigNum60 result = new BigNum60(); + + if(sign == 0 || value == 0) { + return result; + } + + long[] resDigits = result.digits; + + boolean bIsOne = value == 1 || value == -1; + + int bsign; + + if(value < 0) { + bsign = -1; + value = ~value + 1; + } + else { + bsign = 1; + } + + if(isOne || bIsOne) { + if (isOne && bIsOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = sign * bsign; + } + else if(isOne) { + resDigits[0] = value; + result.sign = sign * bsign; + } + else { + System.arraycopy(digits, 0, resDigits, 0, digits.length); + result.sign = sign * bsign; + } + return result; + } + + long old_sum = 0; + long sum, sum2; + long carry, carry2; + + long isNonZero = 0; + long digit, digitlo, digithi; + for(int i = fracDigits; i > 0; i--) { + digit = digits[i]; + digithi = digit >>> SHIFTI; + digitlo = digit & MASKI; + + sum = digitlo * value + old_sum; + carry = sum >>> SHIFTI; + sum &= MASKI; + + sum2 = digithi * value + carry; + carry2 = sum2 >>> SHIFTI; + sum2 &= MASKI; + + + long di = (sum2 << SHIFTI) | sum; + resDigits[i] = di; + isNonZero |= di; + old_sum = carry2; + } + + sum = digits[0] * value + old_sum; + + long d0 = sum & MASKD0; + resDigits[0] = d0 & MASKD0; + + result.isOne = d0 == 1 && isNonZero == 0; + + result.sign = sign * bsign; + + return result; + } + + @Override + public BigNum60 mult2() { + + BigNum60 res = new BigNum60(); + + if(sign == 0) { + return res; + } + + long [] resDigits = res.digits; + + if(isOne) { + resDigits[0] = 2; + res.sign = sign; + return res; + } + + long isNonZero = 0; + + long temp = (digits[fracDigits] << 1); + long val = temp & MASK; + resDigits[fracDigits] = val; + isNonZero |= val; + + for(int i=fracDigits - 1; i > 0; i--) { + temp = (digits[i] << 1) | ((temp >>> (SHIFT))); + val = temp & MASK; + isNonZero |= val; + resDigits[i] = val; + } + + temp = ((digits[0]) << 1) | ((temp >>> (SHIFT))); + long d0 = temp & MASKD0; + resDigits[0] = d0; + res.sign = sign; + res.isOne = d0 == 1 && isNonZero == 0; + return res; + + } + + @Override + public BigNum60 mult4() { + + BigNum60 res = new BigNum60(); + + if(sign == 0) { + return res; + } + + long [] resDigits = res.digits; + + if(isOne) { + resDigits[0] = 4; + res.sign = sign; + return res; + } + + long isNonZero = 0; + + long temp = (digits[fracDigits] << 2); + long val = temp & MASK; + resDigits[fracDigits] = val; + isNonZero |= val; + + for(int i=fracDigits - 1; i > 0; i--) { + temp = (digits[i] << 2) | ((temp >>> (SHIFT))); + val = temp & MASK; + isNonZero |= val; + resDigits[i] = val; + } + + temp = ((digits[0]) << 2) | ((temp >>> (SHIFT))); + long d0 = temp & MASKD0; + resDigits[0] = d0; + res.sign = sign; + res.isOne = d0 == 1 && isNonZero == 0; + return res; + + } + + @Override + public BigNum60 divide2() { + + BigNum60 res = new BigNum60(); + + if(sign == 0) { + return res; + } + + long [] resDigits = res.digits; + + if(isOne) { + resDigits[1] = 0x800000000000000L; + res.sign = sign; + return res; + } + + long isNonZero = 0; + + long d0 = digits[0]; + long temp = d0; + long val = temp >>> 1; + + long bit = temp & 0x1; + + resDigits[0] = val; + isNonZero |= val; + + for(int i=1; i < fracDigits; i++) { + temp = digits[i]; + temp |= (bit << SHIFT); + bit = temp & 0x1; + temp = temp >>> 1; + val = temp & MASK; + resDigits[i] = val; + isNonZero |= val; + } + + temp = digits[fracDigits]; + temp |= (bit << SHIFT); + temp = temp >>> 1; + val = temp & MASK; + resDigits[fracDigits] = val; + isNonZero |= val; + res.sign = sign; + res.isOne = d0 == 1 && isNonZero == 0; + return res; + + } + + @Override + public BigNum60 divide4() { + + BigNum60 res = new BigNum60(); + + if(sign == 0) { + return res; + } + + long [] resDigits = res.digits; + + if(isOne) { + resDigits[1] = 0x400000000000000L; + res.sign = sign; + return res; + } + + long isNonZero = 0; + + + long d0 = digits[0]; + long temp = d0; + long val = temp >>> 2; + + long bits = temp & 0x3; + + resDigits[0] = val; + isNonZero |= val; + + for(int i=1; i < fracDigits; i++) { + temp = digits[i]; + temp |= (bits << SHIFT); + bits = temp & 0x3; + temp = temp >>> 2; + val = temp & MASK; + resDigits[i] = val; + isNonZero |= val; + } + + temp = digits[fracDigits]; + temp |= (bits << SHIFT); + temp = temp >>> 2; + val = temp & MASK; + resDigits[fracDigits] = val; + isNonZero |= val; + res.sign = sign; + res.isOne = d0 == 1 && isNonZero == 0; + return res; + + } + + @Override + public MantExp getMantExp() { + + if (sign == 0) { + return new MantExp(); + } + + if(isOne) { + return new MantExp(sign); + } + + long[] digits = this.digits; + + int i; + long digit = 0; + if(offset == -1) { + for (i = 0; i < digits.length; i++) { + digit = digits[i]; + if (digit != 0) { + break; + } + } + + if (i == digits.length) { + return new MantExp(); + } + + /*int r; + for(r = i == 0 ? SHIFT : SHIFTM1; r >= 0; r--) { + if(digits[i] >>> r != 0) { + break; + } + }*/ + + offset = i; + long v = digit; + double d = v & ~(v >>> 1); + //int r = (int)(((Double.doubleToRawLongBits(d) >> 52) & 0x7ff) - 1023); //Fix for the 64 bit, not needed here + bitOffset = (int) (((Double.doubleToRawLongBits(d) >> 52)) - 1023); + //r |= (r >> 31); //Fix for zero, not needed here + + scale = i == 0 ? bitOffset : -(((long) i) * SHIFT) + bitOffset; + } + else { + i = offset; + digit = digits[i]; + } + + long mantissa = 0; + + int temp = 52 - bitOffset; + + long val = digit; + if(temp >= 0) { + mantissa |= val << temp; + mantissa &= 0xFFFFFFFFFFFFFL; + if(temp == 0 && i + 1 < digits.length) { + mantissa += (digits[i + 1] >>> (SHIFTM1)) & 0x1; + } + } + else { + int shift = -temp; + mantissa |= val >>> shift; + mantissa &= 0xFFFFFFFFFFFFFL; + mantissa += (val >>> (shift - 1)) & 0x1; + } + + //System.out.println(digits[i]); + + i++; + + int k; + for(k = bitOffset ; k < 52 && i < digits.length; k+=SHIFT, i++) { + val = digits[i]; + temp = 52 - k; + + if(temp > SHIFT) { + mantissa |= val << (temp - SHIFT); + mantissa &= 0xFFFFFFFFFFFFFL; + } + else { + long temp2 = k + SHIFTM52; + mantissa |= val >>> temp2; + mantissa &= 0xFFFFFFFFFFFFFL; + + if(temp2 == 0 && i + 1 < digits.length) { + mantissa += (digits[i + 1] >>> (SHIFTM1)) & 0x1; + } + else { + mantissa += (val >>> (temp2 - 1)) & 0x1; + } + } + } + + // Bit 63 (the bit that is selected by the mask 0x8000000000000000L) represents the sign of the floating-point number. + // Bits 62-52 (the bits that are selected by the mask 0x7ff0000000000000L) represent the exponent. + // Bits 51-0 (the bits that are selected by the mask 0x000fffffffffffffL) represent the significand (sometimes called the mantissa) of the floating-point number. + + long exp = scale + (mantissa >>> 52); + double mantissaDouble; + + if(sign == -1) { + mantissaDouble = Double.longBitsToDouble( (0x8000000000000000L) | (mantissa & 0xFFFFFFFFFFFFFL) | (0x3FF0000000000000L)); + } + else { + mantissaDouble = Double.longBitsToDouble((mantissa & 0xFFFFFFFFFFFFFL) | (0x3FF0000000000000L)); + } + + return new MantExp(exp, mantissaDouble); + + + + } + + public static BigNum60 max(BigNum60 a, BigNum60 b) { + return a.compare(b) > 0 ? a : b; + } + + public static BigNum60 min(BigNum60 a, BigNum60 b) { + return a.compare(b) < 0 ? a : b; + } + + public BigNum60 mult2to60(int times) { + + BigNum60 result = new BigNum60(this); + + if(times <= 0) { + return result; + } + + long[] digits = result.digits; + int total = digits.length + times; + long isNonZero = 0; + + for(int i = times, location = 0; i < total; i++, location++) { + if(i < digits.length) { + if(location == 0) { + long value = digits[i - 1]; + long finalValue = digits[i]; + finalValue |= (value & 0x1) << SHIFT; + digits[location] = finalValue; + } + else { + digits[location] = digits[i]; + } + } + else { + int im1 = i - 1; + if(location == 0 && im1 < digits.length) { + long value = digits[im1]; + long finalValue = (value & 0x1) << SHIFT; + digits[location] = finalValue; + } + else { + digits[location] = 0; + } + } + + if(location != 0) { + isNonZero |= digits[location]; + } + } + + result.isOne = digits[0] == 1 && isNonZero == 0; + return result; + } + + @Override + public BigNum60 div2toi(long power) { + BigNum60 result = new BigNum60(this); + + if(power <= 0) { + return result; + } + + int times = (int)(power / SHIFT); + + int internalShift = (int)(power % SHIFT); + + long[] digits = result.digits; + int total = -times; + long isNonZero = 0; + + for(int i = digits.length - 1 - times, location = digits.length - 1; i >= total; i--, location--) { + if(i >= 0) { + long value = digits[i] >>> internalShift; + + if(value > MASK) { + if(location != 0) { + digits[location] = value & MASK; + } + else { + digits[location] = value; + } + + i--; + location--; + if(location >= 0) { + digits[location] = 0x1; + } + } + else { + long finalValue = value; + int im1 = i - 1; + if(im1 >= 0) { + int diff = SHIFT - internalShift; + finalValue |= (digits[im1] & (0xFFFFFFFFFFFFFFFFL >>> diff)) << diff; + } + if(location == 0) { + digits[location] = finalValue & MASKD0; + } + else { + digits[location] = finalValue & MASK; + } + } + } + else { + int ip1 = i + 1; + if(ip1 == 0 && (digits[ip1] >>> internalShift) > MASK) { + digits[location] = 0x1; + } + else { + digits[location] = 0; + } + } + + if(location != 0) { + isNonZero |= digits[location]; + } + } + + result.isOne = digits[0] == 1 && isNonZero == 0; + return result; + } + + @Override + public BigNum60 mult2toi(long power) { + + BigNum60 result = new BigNum60(this); + + if(power <= 0) { + return result; + } + + int times = (int)(power / SHIFT); + + int internalShift = (int)(power % SHIFT); + + long[] digits = result.digits; + int total = digits.length + times; + long isNonZero = 0; + + for(int i = times, location = 0; i < total; i++, location++) { + if(i < digits.length) { + + long value = digits[i] << internalShift; + + int im1 = i - 1; + if(location == 0 && im1 >= 0 && internalShift == 0) { + value |= (digits[im1] & 0x1) << SHIFT; + } + + int ip1 = i + 1; + if(ip1 < digits.length) { + value |= digits[ip1] >>> (SHIFT - internalShift); + } + if(location == 0) { + digits[location] = value & MASKD0; + } + else { + digits[location] = value & MASK; + } + + } + else { + int im1 = i - 1; + if(location == 0 && im1 < digits.length && internalShift == 0) { + long value = (digits[im1] & 0x1) << SHIFT; + digits[location] = value & MASKD0; + } + else { + digits[location] = 0; + } + } + + if(location != 0) { + isNonZero |= digits[location]; + } + } + + result.isOne = digits[0] == 1 && isNonZero == 0; + return result; + } + + public BigNum60 divide2to60(int times) { + + BigNum60 result = new BigNum60(this); + + if(times <= 0) { + return result; + } + + long[] digits = result.digits; + int total = -times; + long isNonZero = 0; + + for(int i = digits.length - 1 - times, location = digits.length - 1; i >= total; i--, location--) { + if(i >= 0) { + long value = digits[i]; + + if(value > MASK) { + digits[location] = value & MASK; + i--; + location--; + digits[location] = 0x1; + } + else { + digits[location] = value; + } + } + else { + int ip1 = i + 1; + if(ip1 == 0 && digits[ip1] > MASK) { + digits[location] = 0x1; + } + else { + digits[location] = 0; + } + } + + if(location != 0) { + isNonZero |= digits[location]; + } + } + + result.isOne = digits[0] == 1 && isNonZero == 0; + return result; + } + + public BigNum60 shift2to60(int times) { + if(times > 0) { + return mult2to60(times); + } + else if(times < 0) { + return divide2to60(-times); + } + + return new BigNum60(this); + } + + @Override + public BigNum60 shift2toi(long power) { + if(power > 0) { + return mult2toi(power); + } + else if(power < 0) { + return div2toi(-power); + } + + return new BigNum60(this); + } + + @Override + public BigNum60 sqrt() { + if(sign == 0 || isOne) { + return new BigNum60(this); + } + if(sign < 0) { + return new BigNum60(); + } + BigNum60 one = new BigNum60(1); + BigNum60 oneFourth = new BigNum60(0.25); + + BigNum60 a = new BigNum60(this); + long divisions = 0; + long multiplications = 0; + if(a.compareBothPositive(one) > 0) { //scale it down between 1 and 1/4 + do { + a = a.divide4(); + divisions++; + } while (a.compareBothPositive(one) > 0); + } + else if(a.compareBothPositive(oneFourth) < 0) { + + int i; + + long[] digits = a.digits; + for(i = 2; i < digits.length; i++) { + if(digits[i] != 0) { + break; + } + } + + int numberOfLimbs = i - 2; + + if(numberOfLimbs > 0) { + multiplications += ((long)numberOfLimbs * SHIFT) >>> 1; + a = a.mult2to60(numberOfLimbs); + } + + do { + a = a.mult4(); + multiplications++; + } while (a.compareBothPositive(oneFourth) < 0); + } + + BigNum60 oneHalf = new BigNum60(1.5); + BigNum60 aHalf = a.divide2(); // a / 2 + + BigNum60 x = new BigNum60(1 / Math.sqrt(a.doubleValue())); // set the initial value to an approximation of 1 /sqrt(a) + + //Newton steps + BigNum60 newX = x.mult(oneHalf.sub(aHalf.mult(x.squareFull()))); // x = (3/2 - (a/2)*x^2)*x + + BigNum60 epsilon = new BigNum60(1); + epsilon.digits[epsilon.digits.length - 1] = 0x3; + epsilon.digits[0] = 0; + + int iter = 0; + while (newX.sub(x).abs_mutable().compareBothPositive(epsilon) >= 0 && iter < SQRT_MAX_ITERATIONS) { + x = newX; + newX = x.mult(oneHalf.sub(aHalf.mult(x.squareFull()))); + iter++; + } + + BigNum60 sqrta = newX.mult(a); //sqrt(a) = a * (1 /sqrt(a)); + if(multiplications > 0) { //scale it up again + sqrta = sqrta.div2toi(multiplications); + } + else if(divisions > 0) { + sqrta = sqrta.mult2toi(divisions); + } + + return sqrta; + } + + public static void main(String[] args) { + MyApfloat.setPrecision(141); + + MyApfloat re = new MyApfloat("-0.74836379425363001495034832147870348765915884117169331481867446308835696434466935951547711102992018544177150733728857158059944201760589035"); + MyApfloat im = new MyApfloat("-0.06744780927701335119415722995059170914204410549488939856276708324527235898639356887734291279309469373068713442093807553848565543917545272"); + + BigNum60 zreb = new BigNum60(); + BigNum60 zimb = new BigNum60(); + BigNum60 creb = new BigNum60(re); + BigNum60 cimb = new BigNum60(im); + + int max_iterations = 16125356; + + long time = System.currentTimeMillis(); + int i; + for(i = 0; i < max_iterations; i++) { + double dre = zreb.doubleValue(); + double dim = zimb.doubleValue(); + if(dre * dre + dim * dim >= 4) { + break; + } + + BigNum60 temp = zreb.add(zimb).mult(zreb.sub(zimb)).add(creb); + zimb = zreb.mult(zimb).mult2().add(cimb); + zreb = temp; + } + + System.out.println("BigNum60"); + System.out.println(i); + System.out.println(System.currentTimeMillis() - time); + System.out.println((BigNum60.fracDigits + 1) * 60); + + + BigNum30 zreb30 = new BigNum30(); + BigNum30 zimb30 = new BigNum30(); + BigNum30 creb30 = new BigNum30(re); + BigNum30 cimb30 = new BigNum30(im); + + + time = System.currentTimeMillis(); + for(i = 0; i < max_iterations; i++) { + double dre = zreb30.doubleValue(); + double dim = zimb30.doubleValue(); + if(dre * dre + dim * dim >= 4) { + break; + } + + BigNum30 temp = zreb30.add(zimb30).mult(zreb30.sub(zimb30)).add(creb30); + zimb30 = zreb30.mult(zimb30).mult2().add(cimb30); + zreb30 = temp; + } + + System.out.println("BigNum30"); + System.out.println(i); + System.out.println(System.currentTimeMillis() - time); + + + BigIntNum zrebi = new BigIntNum(); + BigIntNum zimbi = new BigIntNum(); + BigIntNum crebi = new BigIntNum(re); + BigIntNum cimbi = new BigIntNum(im); + + +// double bitCount1 = 0; +// double bitCount2 = 0; + time = System.currentTimeMillis(); + for(i = 0; i < max_iterations; i++) { + double dre = zrebi.doubleValue(); + double dim = zimbi.doubleValue(); + if(dre * dre + dim * dim >= 4) { + break; + } + + BigIntNum temp = zrebi.add(zimbi).mult(zrebi.sub(zimbi)).add(crebi); +// bitCount2 += (zrebi.add(zimbi).getBitLength() + zrebi.sub(zimbi).getBitLength()) / 2.0; +// bitCount1 += (zrebi.getBitLength() + zimbi.getBitLength()) / 2.0; + zimbi = zrebi.mult(zimbi).mult2().add(cimbi); + zrebi = temp; + + } + + System.out.println("BigIntNum"); + System.out.println(i); + System.out.println(System.currentTimeMillis() - time); + //System.out.println(bitCount1 /i + " " + bitCount2 / i); + } +} diff --git a/src/fractalzoomer/core/BigNum64.java b/src/fractalzoomer/core/BigNum64.java new file mode 100644 index 000000000..bba7546d3 --- /dev/null +++ b/src/fractalzoomer/core/BigNum64.java @@ -0,0 +1,2733 @@ +package fractalzoomer.core; + +import org.apfloat.Apfloat; +import org.apfloat.internal.LongMemoryDataStorage; + +import java.util.Arrays; + +import static fractalzoomer.core.MyApfloat.TWO; +import static org.apfloat.internal.LongRadixConstants.BASE_DIGITS; + +public class BigNum64 extends BigNum { + + public static long getPrecision() { + return (long)fracDigits * SHIFT; + } + public static String getName() { + return "Built-in (64)"; + } + + public long[] digits; + + private static int fracDigits; + private static int fracDigitsm1; + private static int fracDigitsp1; + private static int fracDigitsHalf; + + private static int fracDigits2; + private static boolean useToDouble2; + private static boolean useKaratsuba; + private static int initialLength; + private static boolean evenFracDigits; + + protected static boolean use_threads; + public static final int SHIFT = 64; + public static final long MASKD0 = 0x7FFFFFFFFFFFFFFFL; + public static final long MASKI = 0xFFFFFFFFL; + public static final int SHIFTI = 32; + public static final int SHIFTIM1 = SHIFTI - 1; + public static final int SHIFTM1 = SHIFT - 1; + public static final int SHIFTM2 = SHIFT - 2; + public static final int SHIFTM52 = SHIFT - 52; + private static final double TWO_TO_SHIFT2 = Math.pow(2,-(SHIFT >>> 1)); + + + public static void reinitialize(double digits) { + + double res = digits / SHIFT; + int temp = (int) (res); + + if (temp == 0) { + temp = 1; + } else if (digits % SHIFT != 0) { + //0 is floor + if(TaskDraw.BIGNUM_INITIALIZATION_ALGORITHM == 1) { //always + temp++; + } + else if (TaskDraw.BIGNUM_INITIALIZATION_ALGORITHM == 2) { //round + temp = (int)(res + 0.5); + } + } + + fracDigits = temp * TaskDraw.BIGNUM_PRECISION_FACTOR; + + initializeInternal(); + } + + public static void reinitializeTest(double digits) { + fracDigits = ((int)(digits / SHIFT) + 1) * TaskDraw.BIGNUM_PRECISION_FACTOR; + initializeInternal(); + } + + private static void initializeInternal() { + fracDigitsm1 = fracDigits - 1; + fracDigitsp1 = fracDigits + 1; + //useToDouble2 = fracDigits > 80; + useKaratsuba = false; + fracDigitsHalf = fracDigits >> 1; + fracDigits2 = fracDigits << 1; + initialLength = fracDigitsHalf - ((fracDigitsp1) % 2); + evenFracDigits = (fracDigits & 1) == 0; + + use_threads = false; + } + + private static BigNum64 getMax() { + BigNum64 n = new BigNum64(); + n.digits[0] = MASKD0; + n.sign = 1; + return n; + } + + protected BigNum64() { + digits = new long[fracDigitsp1]; + sign = 0; + isOne = false; + scale = 0; + offset = -1; + bitOffset = -1; + } + + protected BigNum64(BigNum64 other) { + digits = Arrays.copyOf(other.digits, other.digits.length); + sign = other.sign; + isOne = other.isOne; + scale = 0; + offset = -1; + bitOffset = -1; + } + + protected BigNum64(String val) { + this(new MyApfloat(val)); + } + + protected BigNum64(int val) { + digits = new long[fracDigitsp1]; + digits[0] = Math.abs(val); + isOne = val == 1 || val == -1; + sign = (int)Math.signum(val); + scale = 0; + offset = -1; + bitOffset = -1; + } + protected BigNum64(double val) { + + digits = new long[fracDigitsp1]; + + scale = 0; + offset = -1; + bitOffset = -1; + + if (val == 0) { + sign = 0; + isOne = false; + return; + } else if (Math.abs(val) == 1) { + isOne = true; + sign = (int) val; + digits[0] = 1; + return; + } + + sign = (int) Math.signum(val); + val = Math.abs(val); + digits[0] = (long) (val); + double fractionalPart = val - (long) val; + + if (fractionalPart != 0) { + + long bits = Double.doubleToRawLongBits(fractionalPart); + long f_exp = ((bits & 0x7FF0000000000000L) >>> 52) - Double.MAX_EXPONENT; + long mantissa = (bits & 0xFFFFFFFFFFFFFL) | (0x10000000000000L); + + if(f_exp < 0) { + long posExp = -f_exp; + + int index = (int) (posExp / SHIFT) + 1; + int bitOffset = (int) (posExp % SHIFT); + + if (bitOffset == 0) { + index--; + bitOffset = SHIFT; + } + + int k; + int i = index; + for (k = 53; k > 0 && i < digits.length; i++) { + int r; + + if (k == 53) { + r = SHIFT - k - bitOffset + 1; + k -= r < 0 ? 53 + r : 53 - r; + } else { + r = SHIFT - k; + k -= k; + } + + if (r >= 0) { + digits[i] = (mantissa << r); + } else { + digits[i] = (mantissa >>> (-r)); + } + + } + } + + } + + boolean isZero = true; + for(int i = 0; i < digits.length; i++) { + if(digits[i] != 0) { + isZero = false; + break; + } + } + + if(isZero) { + sign = 0; + } + } + + public BigNum64(Apfloat val) { + + scale = 0; + this.offset = -1; + bitOffset = -1; + + Apfloat baseTwo = val.toRadix(2); + + sign = baseTwo.getImpl().signum(); + + isOne = false; + + digits = new long[fracDigitsp1]; + + LongMemoryDataStorage str = (LongMemoryDataStorage)baseTwo.getImpl().getDataStorage(); + + if(str == null || sign == 0) { //for zero + return; + } + + long[] data = str.getData(); + + if(data.length == 1 && data[0] == 1) { + isOne = true; + } + + int base_digits = BASE_DIGITS[2]; + + int offset = (int)str.getOffset(); + + int exponent = (int)baseTwo.getImpl().getExponent(); + + if(exponent == 1) { + int index = data.length >= 2 ? 1 : 0; + digits[0] = MASKD0 & data[index]; + offset++; + } + + int dataOffset = exponent < 0 ? Math.abs(exponent) * base_digits : 0; + + for(int i = dataOffset, j = 0; ; i++, j++) { + + int index2 = (i / SHIFT) + 1; + int index = j / base_digits + offset; + + if(index2 >= digits.length || index >= data.length) { + break; + } + + int shift = base_digits - (j % base_digits) - 1; + long bit = ((data[index] >>> shift) & 0x1); + + digits[index2] |= bit << (SHIFT - (i % SHIFT) - 1); + } + + boolean isZero = true; + for(int i = 0; i < digits.length; i++) { + if(digits[i] != 0) { + isZero = false; + break; + } + } + + if(isZero) { + sign = 0; + } + + } + + @Override + public long getScale() { + + if(sign == 0) { + return Long.MIN_VALUE; + } + + if(offset != -1) { + return scale; + } + + int i; + long digit = 0; + for(i = 0; i < digits.length; i++) { + digit = digits[i]; + if(digit != 0) { + break; + } + } + + if(i == digits.length) { + return Long.MIN_VALUE; + } + + /*int r; + for(r = i == 0 ? SHIFT : SHIFTM1; r >= 0; r--) { + if(digits[i] >>> r != 0) { + break; + } + }*/ + + offset = i; + bitOffset = (int)msbDeBruijn64(digit); + scale = i == 0 ? bitOffset : -(((long) i) * SHIFT) + bitOffset; + + return scale; + } + + public static BigNum64 getNegative(BigNum64 other) { + + BigNum64 copy = new BigNum64(); + copy.sign = other.sign; + copy.isOne = other.isOne; + + long[] otherDigits = other.digits; + long[] digits = copy.digits; + +// long digit = otherDigits[fracDigits]; +// long digitlo = digit & MASKI; +// long digithi = digit >>> SHIFTI; +// long slo = ((~digitlo) & MASKI) + 1; +// long shi = ((~digithi) & MASKI) + (slo >>> SHIFTI); +// digits[fracDigits] = (shi << SHIFTI) | (slo & MASKI); +// for (int i = fracDigitsm1; i >= 0 ; i--) { +// digit = otherDigits[i]; +// digitlo = digit & MASKI; +// digithi = digit >>> SHIFTI; +// slo = ((~digitlo) & MASKI) + (shi >>> SHIFTI); +// shi = ((~digithi) & MASKI) + (slo >>> SHIFTI); +// digits[i] = (shi << SHIFTI) | (slo & MASKI); +// } + + long digit = otherDigits[fracDigits]; + long temp = ~digit; + long bit = temp >>> SHIFTM1; + temp++; + digits[fracDigits] = temp; + long carry = bit & ((~(temp >>> SHIFTM1)) & 0x1); + + for (int i = fracDigitsm1; i >= 0 ; i--) { + digit = otherDigits[i]; + temp = ~digit; + bit = temp >>> SHIFTM1; + temp += carry; + digits[i] = temp; + carry = bit & ((~(temp >>> SHIFTM1)) & 0x1); + } + + return copy; + } + + @Override + public void negSelf() { + + if(sign == 0) { + return; + } + /*if(digits[fracDigits]>0) { + digits[fracDigits] = (int)((digits[fracDigits]-1)^MASK); + for(int i=fracDigits-1; i>0; i--) digits[i] ^= MASK; + digits[0] = ~digits[0]; + } else { + long s = digits[fracDigits-1]-1; digits[fracDigits-1] = (int)(~s&MASK); + for(int i=fracDigits-2; i>0; i--) { + s = digits[i]+(s>>SHIFT); digits[i] = (int)(~s&MASK); + } + digits[0] = (int)(~(digits[0]+(s>>SHIFT))); + }*/ + +// long digit = digits[fracDigits]; +// long digitlo = digit & MASKI; +// long digithi = digit >>> SHIFTI; +// long slo = ((~digitlo) & MASKI) + 1; +// long shi = ((~digithi) & MASKI) + (slo >>> SHIFTI); +// digits[fracDigits] = (shi << SHIFTI) | (slo & MASKI); +// for (int i = fracDigitsm1; i >= 0 ; i--) { +// digit = digits[i]; +// digitlo = digit & MASKI; +// digithi = digit >>> SHIFTI; +// slo = ((~digitlo) & MASKI) + (shi >>> SHIFTI); +// shi = ((~digithi) & MASKI) + (slo >>> SHIFTI); +// digits[i] = (shi << SHIFTI) | (slo & MASKI); +// } + + long digit = digits[fracDigits]; + long temp = ~digit; + long bit = temp >>> SHIFTM1; + temp++; + digits[fracDigits] = temp; + long carry = bit & ((~(temp >>> SHIFTM1)) & 0x1); + + for (int i = fracDigitsm1; i >= 0 ; i--) { + digit = digits[i]; + temp = ~digit; + bit = temp >>> SHIFTM1; + temp += carry; + digits[i] = temp; + carry = bit & ((~(temp >>> SHIFTM1)) & 0x1); + } + + } + + @Override + public BigNum64 negate() { + + BigNum64 res = new BigNum64(this); + + res.sign *= -1; + + return res; + + } + + @Override + public BigNum64 abs() { + + BigNum64 res = new BigNum64(this); + + if(sign == -1) { + res.sign = 1; + } + + return res; + } + + @Override + public BigNum64 abs_mutable() { + + if(sign == -1) { + sign = 1; + } + + return this; + } + + @Override + public String toString() { + StringBuilder ret = new StringBuilder((sign == -1 ? "-" : "") + toHexString(digits[0])); + for(int i=1; i<=fracDigits; i++) { + ret.append(i==1 ? "." : " "); + ret.append(toHexString(digits[i])); + } + return doubleValueOld() + " " + ret.toString(); + } + + @Override + public String bits() { + + String value = ""; + if(sign == -1) { + value = "-"; + } + for (int i = 0; i < digits.length; i++) { + + if (i == 0) { + boolean zero = true; + for (int j = SHIFTM1; j >= 0; j--) { + if (((digits[i] >>> j) & 0x1) == 1) { + zero = false; + } + + if (!zero) { + value += "" + ((digits[i] >>> j) & 0x1); + } + } + if(zero) { + value += "0"; + } + value += "."; + } else { + for (int j = SHIFTM1; j >= 0; j--) { + value += "" + ((digits[i] >>> j) & 0x1); + } + } + } + + return value; + + } + + @Override + public int compare(BigNum otherb) { + BigNum64 other = (BigNum64) otherb; + + int signA = sign; + + long[] otherDigits = other.digits; + + int signB = other.sign; + + long digit, otherDigit; + long digitHi, digitLo, otherDigitHi, otherDigitLo; + + if(signA < signB) { + return -1; + } + else if(signA > signB) { + return 1; + } + else { + if (signA == 0) { + return 0; + } + + if(signA < 0) { + for (int i = 0; i < digits.length; i++) { + digit = digits[i]; + otherDigit = otherDigits[i]; + digitHi = digit >>> SHIFTI; + otherDigitHi = otherDigit >>> SHIFTI; + + if (digitHi < otherDigitHi) { + return 1; + } else if (digitHi > otherDigitHi) { + return -1; + } + digitLo = digit & MASKI; + otherDigitLo = otherDigit & MASKI; + + if (digitLo < otherDigitLo) { + return 1; + } else if (digitLo > otherDigitLo) { + return -1; + } + } + } + else { + for (int i = 0; i < digits.length; i++) { + digit = digits[i]; + otherDigit = otherDigits[i]; + + digitHi = digit >>> SHIFTI; + otherDigitHi = otherDigit >>> SHIFTI; + + if (digitHi < otherDigitHi) { + return -1; + } else if (digitHi > otherDigitHi) { + return 1; + } + + digitLo = digit & MASKI; + otherDigitLo = otherDigit & MASKI; + + if (digitLo < otherDigitLo) { + return -1; + } else if (digitLo > otherDigitLo) { + return 1; + } + } + } + } + + return 0; + + } + + @Override + public int compareBothPositive(BigNum otherb) { + BigNum64 other = (BigNum64) otherb; + + int signA = sign; + int signB = other.sign; + + if(signA == 0 && signB == 0) { + return 0; + } + + long[] otherDigits = other.digits; + + long digit, otherDigit; + long digitHi, digitLo, otherDigitHi, otherDigitLo; + + for (int i = 0; i < digits.length; i++) { + digit = digits[i]; + otherDigit = otherDigits[i]; + + digitHi = digit >>> SHIFTI; + otherDigitHi = otherDigit >>> SHIFTI; + + if (digitHi < otherDigitHi) { + return -1; + } else if (digitHi > otherDigitHi) { + return 1; + } + + digitLo = digit & MASKI; + otherDigitLo = otherDigit & MASKI; + + if (digitLo < otherDigitLo) { + return -1; + } else if (digitLo > otherDigitLo) { + return 1; + } + } + + return 0; + + } + +// static long binarySearch64(long v) { +// +// int shift = 32; +// +// long res = v >>> shift; +// +// if(res == 1) { +// return shift; +// } +// else if (res > 1) { +// shift += 16; //+16 +// } +// else { +// shift -= 16; // -16 +// } +// +// res = v >>> shift; +// +// if(res == 1) { +// return shift; +// } +// else if (res > 1) { +// shift += 8; //+8 +// } +// else { +// shift -= 8; // -8 +// } +// +// res = v >>> shift; +// +// if(res == 1) { +// return shift; +// } +// else if (res > 1) { +// shift += 4; // +4 +// } +// else { +// shift -= 4; // -4 +// } +// +// res = v >>> shift; +// +// if(res == 1) { +// return shift; +// } +// else if (res > 1) { +// shift += 2; // + 2 +// } +// else { +// shift -= 2; // -2 +// } +// +// res = v >>> shift; +// +// if(res == 1) { +// return shift; +// } +// else if (res > 1) { +// shift += 1; // + 1 +// } +// else { +// +// shift -= 1; // -1 +// } +// +// return shift; +// } +// +// + static int[] debruijn64 = + { + 0, 58, 1, 59, 47, 53, 2, 60, 39, 48, 27, 54, 33, 42, 3, 61, 51, 37, 40, 49, + 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4, 62, 57, 46, 52, 38, 26, 32, 41, + 50, 36, 17, 19, 29, 10, 13, 21, 56, 45, 25, 31, 35, 16, 9, 12, 44, 24, 15, + 8, 23, 7, 6, 5, 63 + }; + + static long msbDeBruijn64(long v) { + + + /* Round down to one less than a power of 2. */ + v |= v >>> 1; + v |= v >>> 2; + v |= v >>> 4; + v |= v >>> 8; + v |= v >>> 16; + v |= v >>> 32; + + /* 0x03f6eaf2cd271461 is a hexadecimal representation of a De Bruijn + * sequence for binary words of length 6. The binary representation + * starts with 000000111111. This is required to make it work with one less + * than a power of 2 instead of an actual power of 2. + */ + + return debruijn64[(int)((v * 0x03f6eaf2cd271461L) >>> 58)]; + } + + @Override + public double doubleValue() { + + long[] digits = this.digits; + + int i; + long digit = 0; + if(offset == -1) { + for (i = 0; i < digits.length; i++) { + digit = digits[i]; + if (digit != 0) { + break; + } + } + + if (i == digits.length) { + return 0; + } + + /*int r; + for(r = i == 0 ? SHIFT : SHIFTM1; r >= 0; r--) { + if(digits[i] >>> r != 0) { + break; + } + }*/ + offset = i; + bitOffset = (int)msbDeBruijn64(digit); + scale = i == 0 ? bitOffset : -(((long) i) * SHIFT) + bitOffset; + } + else { + i = offset; + digit = digits[i]; + } + + if (scale < Double.MIN_EXPONENT) { //accounting for +1 + return 0.0; + } + else if (scale >= Double.MAX_EXPONENT) { + return sign == -1 ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; + } + + long mantissa = 0; + + int temp = 52 - bitOffset; + + long val = digit; + if(temp >= 0) { + mantissa |= val << temp; + mantissa &= 0xFFFFFFFFFFFFFL; + if(temp == 0 && i + 1 < digits.length) { + mantissa += (digits[i + 1] >>> (SHIFTM1)) & 0x1; + } + } + else { + int shift = -temp; + mantissa |= val >>> shift; + mantissa &= 0xFFFFFFFFFFFFFL; + mantissa += (val >>> (shift - 1)) & 0x1; + } + + i++; + + int k; + for(k = bitOffset ; k < 52 && i < digits.length; k+=SHIFT, i++) { + val = digits[i]; + temp = 52 - k; + + if(temp > SHIFT) { + mantissa |= val << (temp - SHIFT); + mantissa &= 0xFFFFFFFFFFFFFL; + } + else { + int temp2 = k + SHIFTM52; + mantissa |= val >>> temp2; + mantissa &= 0xFFFFFFFFFFFFFL; + + if(temp2 == 0 && i + 1 < digits.length) { + mantissa += (digits[i + 1] >>> (SHIFTM1)) & 0x1; + } + else { + mantissa += (val >>> (temp2 - 1)) & 0x1; + } + } + } + + long finalScale = scale + (mantissa >>> 52); + if (finalScale <= Double.MIN_EXPONENT) { + return 0.0; + } + else if (finalScale >= Double.MAX_EXPONENT) { + return sign == -1 ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; + } + + // Bit 63 (the bit that is selected by the mask 0x8000000000000000L) represents the sign of the floating-point number. + // Bits 62-52 (the bits that are selected by the mask 0x7ff0000000000000L) represent the exponent. + // Bits 51-0 (the bits that are selected by the mask 0x000fffffffffffffL) represent the significand (sometimes called the mantissa) of the floating-point number. + + double res; + if(sign == -1) { + return Double.longBitsToDouble( (0x8000000000000000L) | (mantissa & 0xFFFFFFFFFFFFFL) | ((finalScale + Double.MAX_EXPONENT) << 52)); + } + else { + return Double.longBitsToDouble((mantissa & 0xFFFFFFFFFFFFFL) | ((finalScale + Double.MAX_EXPONENT) << 52)); + } + + } + + @Override + public double doubleValueOld() { + + if (sign == 0) { + return 0; + } + + if(isOne) { + return sign; + } + + if(useToDouble2) { + return doubleValue(); + } + + double ret = 0; + + + /*if(digits[0]>=0) { + for(int i=fracDigits; i>=0; i--) { + ret *= TWO_TO_SHIFT; + ret += digits[i]; + } + } else { + ret--; + for(int i=fracDigits; i>0; i--) { + ret += digits[i] - MASK; + ret *= TWO_TO_SHIFT; + } + ret += digits[0]+1; + }*/ + + for(int i=fracDigits; i > 0; i--) { + long v = digits[i]; + long v1 = v & MASKI; + ret *= TWO_TO_SHIFT2; + ret += v1; + long v2 = v >>> SHIFTI; + ret *= TWO_TO_SHIFT2; + ret += v2; + } + + long v = digits[0] & MASKD0; + ret *= TWO_TO_SHIFT2; + ret += v; + + ret *= sign; + return ret; + } + + @Override + public BigNum64 add(BigNum aa) { + BigNum64 a = (BigNum64) aa; + + BigNum64 result = new BigNum64(); + + long[] otherDigits = a.digits; + int otherSign = a.sign; + + long[] resDigits = result.digits; + + long[] digits = this.digits; + int sign = this.sign; + + if(sign == 0 || otherSign == 0) { + if(sign == 0 && otherSign == 0){ + return result; + } + else if(sign == 0) { + result.sign = otherSign; + result.isOne = a.isOne; + System.arraycopy(otherDigits, 0, resDigits, 0, otherDigits.length); + } + else { + result.sign = sign; + result.isOne = isOne; + System.arraycopy(digits, 0, resDigits, 0, digits.length); + } + return result; + } + + if(sign != otherSign) { + if(sign == -1) { + BigNum64 copy = getNegative(this); + digits = copy.digits; + } + else + { + BigNum64 copy = getNegative(a); + otherDigits = copy.digits; + } + } + + long s = 0; + long isNonZero = 0; + long digitA, digitB, bitA, bitB, notBitC; + for(int i=fracDigits; i>0; i--) { + digitA = digits[i]; + digitB = otherDigits[i]; + bitA = digitA >>> SHIFTM1; + bitB = digitB >>> SHIFTM1; + s += digitA + digitB; + isNonZero |= s; + resDigits[i] = s; + notBitC = (~(s >>> SHIFTM1)) & 0x1; + + s = (bitA & bitB) | (bitA & notBitC) | (bitB & notBitC); + } + s += digits[0] + otherDigits[0]; + + result.isOne = (s == 1 || s == -1) && isNonZero == 0; + isNonZero |= s; + resDigits[0] = s; + + + + /*long s = 0; + long s2; + + long isNonZero = 0; + long temp, carry2; + long digitA, digitB, Alo, Ahi, Blo, Bhi; + for(int i=fracDigits; i>0; i--) { + digitA = digits[i]; + digitB = otherDigits[i]; + Alo = digitA & MASKI; + Ahi = digitA >>> SHIFTI; + Blo = digitB & MASKI; + Bhi = digitB >>> SHIFTI; + + s += Alo + Blo; + + s2 = Ahi + Bhi + (s >>> SHIFTI); + + s &= MASKI; + carry2 = s2 >>> SHIFTI; + s2 &= MASKI; + + + temp = (s2 << SHIFTI) | s; + isNonZero |= temp; + resDigits[i] = temp; + + s = carry2; + } + + digitA = digits[0]; + digitB = otherDigits[0]; + Alo = digitA & MASKI; + Ahi = digitA >>> SHIFTI; + Blo = digitB & MASKI; + Bhi = digitB >>> SHIFTI; + + s += Alo + Blo; + + s2 = Ahi + Bhi + (s >>> SHIFTI); + + s &= MASKI; + s2 &= MASKI; + + temp = (s2 << SHIFTI) | s; + + + result.isOne = (temp == 1 || temp == -1) && isNonZero == 0; + isNonZero |= s; + resDigits[0] = s;*/ + + if(sign != otherSign) { + if(resDigits[0] < 0) { + result.sign = -1; + result.negSelf(); + } + else { + result.sign = isNonZero != 0 ? 1 : 0; + } + } + else { + result.sign = isNonZero != 0 ? sign : 0; + } + + return result; + } + + @Override + public BigNum64 add(int a) { + + BigNum64 result = new BigNum64(); + + int otherSign; + if(a == 0) { + otherSign = 0; + } + else if(a < 0) { + otherSign = -1; + } + else { + otherSign = 1; + } + + int otherDigits = a; + + boolean aIsOne = a == 1 || a == -1; + + long[] resDigits = result.digits; + + long[] digits = this.digits; + int sign = this.sign; + + if(sign == 0 || otherSign == 0) { + if(sign == 0 && otherSign == 0){ + return result; + } + else if(sign == 0) { + result.sign = otherSign; + result.isOne = aIsOne; + + if(otherSign < 0) { + a = ~a + 1; + } + + resDigits[0] = a; + } + else { + result.sign = sign; + result.isOne = isOne; + System.arraycopy(digits, 0, resDigits, 0, digits.length); + } + return result; + } + + if(sign != otherSign) { + if(sign == -1) { + BigNum64 copy = getNegative(this); + digits = copy.digits; + } + } + else { + if(otherSign < 0) { + otherDigits = ~otherDigits + 1; + } + } + + long isNonZero = 0; + long temp; + for(int i=fracDigits; i>0; i--) { + temp = resDigits[i] = digits[i]; + isNonZero |= temp; + } + + temp = digits[0] + otherDigits; + result.isOne = (temp == 1 || temp == -1) && isNonZero == 0; + isNonZero |= temp; + resDigits[0] = temp; + + if(sign != otherSign) { + if(resDigits[0] < 0) { + result.sign = -1; + result.negSelf(); + } + else { + result.sign = isNonZero != 0 ? 1 : 0; + } + } + else { + result.sign = isNonZero != 0 ? sign : 0; + } + + return result; + } + + @Override + public BigNum64 sub(BigNum aa) { + BigNum64 a = (BigNum64) aa; + + BigNum64 result = new BigNum64(); + + long[] otherDigits = a.digits; + int otherSign = a.sign; + + long[] resDigits = result.digits; + + long[] digits = this.digits; + int sign = this.sign; + + if(sign == 0 || otherSign == 0) { + if(sign == 0 && otherSign == 0){ + return result; + } + else if(sign == 0) { + result.sign = -otherSign; + result.isOne = a.isOne; + System.arraycopy(otherDigits, 0, resDigits, 0, otherDigits.length); + } + else { + result.sign = sign; + result.isOne = isOne; + System.arraycopy(digits, 0, resDigits, 0, digits.length); + } + return result; + } + + if(sign == otherSign) { + // + + -> + - + // - - -> - + + if(sign == -1) { + BigNum64 copy = getNegative(this); + digits = copy.digits; + } + else { + BigNum64 copy = getNegative(a); + otherDigits = copy.digits; + } + } + + /*long s = 0; + long s2; + + long isNonZero = 0; + long temp, carry2; + long digitA, digitB, Alo, Ahi, Blo, Bhi; + for(int i=fracDigits; i>0; i--) { + digitA = digits[i]; + digitB = otherDigits[i]; + Alo = digitA & MASKI; + Ahi = digitA >>> SHIFTI; + Blo = digitB & MASKI; + Bhi = digitB >>> SHIFTI; + + s += Alo + Blo; + + s2 = Ahi + Bhi + (s >>> SHIFTI); + + s &= MASKI; + carry2 = s2 >>> SHIFTI; + s2 &= MASKI; + + + temp = (s2 << SHIFTI) | s; + isNonZero |= temp; + resDigits[i] = temp; + + s = carry2; + } + + digitA = digits[0]; + digitB = otherDigits[0]; + Alo = digitA & MASKI; + Ahi = digitA >>> SHIFTI; + Blo = digitB & MASKI; + Bhi = digitB >>> SHIFTI; + + s += Alo + Blo; + + s2 = Ahi + Bhi + (s >>> SHIFTI); + + s &= MASKI; + s2 &= MASKI; + + temp = (s2 << SHIFTI) | s; + + result.isOne = (temp == 1 || temp == -1) && isNonZero == 0; + isNonZero |= temp; + resDigits[0] = temp;*/ + + long s = 0; + long isNonZero = 0; + long digitA, digitB, bitA, bitB, notBitC; + for(int i=fracDigits; i>0; i--) { + digitA = digits[i]; + digitB = otherDigits[i]; + bitA = digitA >>> SHIFTM1; + bitB = digitB >>> SHIFTM1; + s += digitA + digitB; + isNonZero |= s; + resDigits[i] = s; + notBitC = (~(s >>> SHIFTM1)) & 0x1; + + s = (bitA & bitB) | (bitA & notBitC) | (bitB & notBitC); + } + s += digits[0] + otherDigits[0]; + + result.isOne = (s == 1 || s == -1) && isNonZero == 0; + isNonZero |= s; + resDigits[0] = s; + + if(sign == otherSign) { + if(resDigits[0] < 0) { + result.sign = -1; + result.negSelf(); + } + else { + result.sign = isNonZero != 0 ? 1 : 0; + } + } + else { + result.sign = isNonZero != 0 ? sign : 0; + } + + return result; + } + + @Override + public BigNum64 sub(int a) { + + BigNum64 result = new BigNum64(); + + int otherSign; + if(a == 0) { + otherSign = 0; + } + else if(a < 0) { + otherSign = -1; + } + else { + otherSign = 1; + } + + int otherDigits = a; + + boolean aIsOne = a == 1 || a == -1; + + long[] resDigits = result.digits; + + long[] digits = this.digits; + int sign = this.sign; + + if(sign == 0 || otherSign == 0) { + if(sign == 0 && otherSign == 0){ + return result; + } + else if(sign == 0) { + result.sign = -otherSign; + result.isOne = aIsOne; + + if(otherSign < 0) { + a = ~a + 1; + } + + resDigits[0] = a; + } + else { + result.sign = sign; + result.isOne = isOne; + System.arraycopy(digits, 0, resDigits, 0, digits.length); + } + return result; + } + + if(sign == otherSign) { + // + + -> + - + // - - -> - + + if(sign == -1) { + BigNum64 copy = getNegative(this); + digits = copy.digits; + } + otherDigits = ~otherDigits + 1; + } + else { + if(otherSign < 0) { + otherDigits = ~otherDigits + 1; + } + } + + + long isNonZero = 0; + long temp; + for(int i=fracDigits; i>0; i--) { + temp = resDigits[i] = digits[i]; + isNonZero |= temp; + } + + temp = digits[0] + otherDigits; + result.isOne = (temp == 1 || temp == -1) && isNonZero == 0; + isNonZero |= temp; + resDigits[0] = temp; + + if(sign == otherSign) { + if(resDigits[0] < 0) { + result.sign = -1; + result.negSelf(); + } + else { + result.sign = isNonZero != 0 ? 1 : 0; + } + } + else { + result.sign = isNonZero != 0 ? sign : 0; + } + + return result; + } + + @Override + public BigNum64 square() { + return squareFull(); + } + + @Override + public BigNum64 squareFull() { + BigNum64 result = new BigNum64(); + + if(sign == 0) { + return result; + } + + long[] resDigits = result.digits; + + if(isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = 1; + return result; + } + + long old_sum; + + long sum = 0; + + int length = initialLength; + + int j; + int k; + long carry = 0; + + long bdigit; + long adigit; + long bjhi, akhi, bjlo, aklo; + + for (j = 1, k = fracDigits; j <= length;) { + bdigit = digits[j]; + adigit = digits[k]; + + bjlo = bdigit & MASKI; + aklo = adigit & MASKI; + + bjhi = bdigit >>> SHIFTI; + akhi = adigit >>> SHIFTI; + + sum += bjhi * aklo; + carry += sum >>> SHIFTI; + sum &= MASKI; + //System.out.println("1: a" + j + "hi * a"+k+"lo"); + sum += bjlo * akhi; + carry += sum >>> SHIFTI; + sum &= MASKI; + //System.out.println("1: a" + j + "lo * a"+k+"hi"); + + j++;k--; + } + + if(j == k) { + bdigit = digits[j]; + bjhi = bdigit >>> SHIFTI; + bjlo = bdigit & MASKI; + sum += (bjhi * bjlo); + carry += sum >>> SHIFTI; + sum &= MASKI; + + sum <<= 1; + carry <<= 1; + //System.out.println("1: a" + j + "lo * a"+j+"lo"); + } + else { + bdigit = digits[j]; + adigit = digits[k]; + + bjlo = bdigit & MASKI; + aklo = adigit & MASKI; + + bjhi = bdigit >>> SHIFTI; + akhi = adigit >>> SHIFTI; + + sum += bjhi * aklo; + carry += sum >>> SHIFTI; + sum &= MASKI; + //System.out.println("1: a" + j + "hi * a"+k+"lo"); + sum += bjlo * akhi; + carry += sum >>> SHIFTI; + sum &= MASKI; + //System.out.println("1: a" + j + "lo * a"+k+"hi"); + + sum <<= 1; + carry <<= 1; + } + + carry += sum >>> SHIFTI; + sum &= MASKI; + + old_sum = carry + (sum >>> SHIFTIM1); // Roundish + + long d0 = digits[0]; + long d0lo = d0 & MASKI; + + length = fracDigitsHalf; + + int toggle = evenFracDigits ? 0 : 1; + + for(int i = fracDigits; i > 0; i--, length -= toggle, toggle ^= 1) { + + sum = 0; + carry = 0; + long sum2 = 0; + long carry2 = 0; + + k = i; + + adigit = digits[k]; + + aklo = adigit & MASKI; + akhi = adigit >>> SHIFTI; + + bjlo = d0lo; + + int length2 = evenFracDigits ? length : length + 1; + + sum += bjlo * aklo; + sum2 += bjlo * akhi; + carry += sum >>> SHIFTI; + sum &= MASKI; + + carry2 += sum2 >>> SHIFTI; + sum2 &= MASKI; + + for(j = 1; j < length2;) { + bdigit = digits[j]; + bjlo = bdigit & MASKI; + bjhi = bdigit >>> SHIFTI; + + sum += bjhi * akhi; + carry += sum >>> SHIFTI; + sum &= MASKI; + //System.out.println("1: b" + j + "hi * a"+k+"hi"); + + k--; + + adigit = digits[k]; + + aklo = adigit & MASKI; + akhi = adigit >>> SHIFTI; + + //System.out.println("2: b" + j + "hi * a"+k+"lo"); + sum += bjlo * aklo; + carry += sum >>> SHIFTI; + sum &= MASKI; + + sum2 += bjhi * aklo; + carry2 += sum2 >>> SHIFTI; + sum2 &= MASKI; + + sum2 += bjlo * akhi; + carry2 += sum2 >>> SHIFTI; + sum2 &= MASKI; + + j++; + + } + + if(j == k) { + sum <<= 1; + carry <<= 1; + carry += sum >>> SHIFTI; + sum &= MASKI; + sum += akhi * akhi; + } + else { + bdigit = digits[j]; + bjhi = bdigit >>> SHIFTI; + + sum += bjhi * akhi; + carry += sum >>> SHIFTI; + sum &= MASKI; + + k--; + + adigit = digits[k]; + + aklo = adigit & MASKI; + + sum2 += bjhi * aklo; + carry2 += sum2 >>> SHIFTI; + sum2 &= MASKI; + + sum <<= 1; + carry <<= 1; + carry += sum >>> SHIFTI; + sum &= MASKI; + sum += aklo * aklo; + } + + sum2 <<= 1; + carry2 <<= 1; + + carry += sum >>> SHIFTI; + sum &= MASKI; + + sum += old_sum; + carry += sum >>> SHIFTI; + sum &= MASKI; + + sum2 += carry; + carry2 += sum2 >>> SHIFTI; + sum2 &= MASKI; + + //System.out.println("NEXT"); + + long di = (sum2 << SHIFTI) | sum; + resDigits[i] = di; + old_sum = carry2; + } + + sum = old_sum; + + sum += d0 * d0; + + resDigits[0] = sum & MASKD0; + result.sign = 1; + + return result; + } + + @Deprecated + @Override + public BigNum64 squareFullGolden() { + + + BigNum64 result = new BigNum64(); + + if(sign == 0) { + return result; + } + + long[] resDigits = result.digits; + long[] origDigitsA = this.digits; + + if(isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = 1; + return result; + } + + int newFracDigits = fracDigits2; + int newLength = newFracDigits + 1; + int[] digits = new int[newLength]; + + long old_sum; + + long sum = 0; + + int length = fracDigitsHalf; + + long carry = 0; + + digits[0] = (int)(origDigitsA[0] & MASKI); + int j = 1, k = fracDigits; + int base = (j << 1) - 1, base2 = (k << 1); + for (; j <= length; j++, k--) { + long bdigit = origDigitsA[j]; + long adigit = origDigitsA[k]; + + long bjlo = bdigit & MASKI; + long aklo = adigit & MASKI; + + long bjhi = bdigit >>> SHIFTI; + long akhi = adigit >>> SHIFTI; + + digits[base2] = (int)(aklo); + digits[base] = (int)(bjhi); + base++; + base2--; + digits[base2] = (int)(akhi); + digits[base] = (int)(bjlo); + base++; + base2--; + + sum += bjlo * akhi; + carry += sum >>> SHIFTI; + sum &= MASKI; + + sum += bjhi * aklo; + carry += sum >>> SHIFTI; + sum &= MASKI; + + } + + if(j == k) { + long bdigit = origDigitsA[j]; + long aklo = bdigit & MASKI; + long bjhi = bdigit >>> SHIFTI; + + digits[base2] = (int)(aklo); + digits[base] = (int)(bjhi); + + sum += bjhi * aklo; + carry += sum >>> SHIFTI; + sum &= MASKI; + } + + carry <<= 1; + sum <<= 1; + carry += sum >>> SHIFTI; + sum &= MASKI; + + old_sum = carry + (sum >>> SHIFTIM1); // Roundish + + int m = fracDigits; + for(int i = newFracDigits; i > 0; i--, m--) { + + sum = old_sum; + + length = (i >> 1) - 1; + + long temp_sum = 0; + carry = 0; + + long bj, ak; + + for(j = 0, k = i; j <= length; j++, k--) { + bj = digits[j] & MASKI; + ak = digits[k] & MASKI; + temp_sum += bj * ak; + carry += temp_sum >>> SHIFTI; + temp_sum &= MASKI; + } + + carry <<= 1; + temp_sum <<= 1; + + carry += temp_sum >>> SHIFTI; + temp_sum &= MASKI; + + bj = digits[j] & MASKI; + ak = digits[k] & MASKI; + temp_sum += bj * ak; + + carry += temp_sum >>> SHIFTI; + temp_sum &= MASKI; + + sum += temp_sum; + carry += sum >>> SHIFTI; + sum &= MASKI; + + long finalVal = sum; + + i--;//Unrolling + + sum = carry; + + length = i >> 1; + + temp_sum = 0; + carry = 0; + + for(j = 0, k = i; j <= length; j++, k--) { + bj = digits[j] & MASKI; + ak = digits[k] & MASKI; + temp_sum += bj * ak; + carry += temp_sum >>> SHIFTI; + temp_sum &= MASKI; + } + + carry <<= 1; + temp_sum <<= 1; + + carry += temp_sum >>> SHIFTI; + temp_sum &= MASKI; + + sum += temp_sum; + carry += sum >>> SHIFTI; + sum &= MASKI; + + finalVal |= sum << SHIFTI; + + resDigits[m] = finalVal; + old_sum = carry; + } + + sum = old_sum; + + long bj = digits[0] & MASKI; + long ak = digits[0] & MASKI; + sum += bj * ak; + + result.sign = 1; + + result.digits[0] = sum; + + return result; + } + + @Override + public BigNum64 mult(BigNum bb) { + BigNum64 b = (BigNum64) bb; + return multFull(b); + } + + @Deprecated + public BigNum64 multFullGolden(BigNum64 b) { + + BigNum64 result = new BigNum64(); + + if(sign == 0 || b.sign == 0) { + return result; + } + + long[] resDigits = result.digits; + long[] origDigitsA = this.digits; + long[] origDigitsB = b.digits; + + if(isOne || b.isOne) { + if (isOne && b.isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = sign * b.sign; + } + else if(isOne) { + System.arraycopy(origDigitsB, 0, resDigits, 0, origDigitsB.length); + result.sign = sign * b.sign; + } + else { + System.arraycopy(origDigitsA, 0, resDigits, 0, origDigitsA.length); + result.sign = sign * b.sign; + } + return result; + } + + int newFracDigits = fracDigits2; + int newLength = newFracDigits + 1; + int[] digits = new int[newLength]; + int[] bdigits = new int[newLength]; + + long old_sum; + + long sum = 0; + long carry = 0; + digits[0] = (int)(origDigitsA[0] & MASKI); + bdigits[0] = (int)(origDigitsB[0] & MASKI); + + for (int j = 1, base = (j << 1) - 1, k = fracDigits, base2 = (k << 1); j <= fracDigits; j++, k--) { + + long bdigit = origDigitsB[j]; + long adigit = origDigitsA[k]; + + long bjlo = bdigit & MASKI; + long aklo = adigit & MASKI; + + long bjhi = bdigit >>> SHIFTI; + long akhi = adigit >>> SHIFTI; + + digits[base2] = (int)(aklo); + bdigits[base] = (int)(bjhi); + base++; + base2--; + digits[base2] = (int)(akhi); + bdigits[base] = (int)(bjlo); + base++; + base2--; + + sum += bjlo * akhi; + carry += sum >>> SHIFTI; + sum &= MASKI; + + sum += bjhi * aklo; + carry += sum >>> SHIFTI; + sum &= MASKI; + + } + + old_sum = carry + (sum >>> SHIFTIM1); // Roundish + + long isNonZero = 0; + for(int i = newFracDigits, m = fracDigits; i > 0; i--, m--) { + + sum = old_sum; //carry from prev + carry = sum >>> SHIFTI; + sum &= MASKI; + + for(int j = 0, k = i; j <= i; j++, k--) { + long bj = bdigits[j] & MASKI; + long ak = digits[k] & MASKI; + + sum += bj * ak; + carry += sum >>> SHIFTI; + sum &= MASKI; + + } + + long finalVal = sum; + + i--;//Unrolling + + sum = carry; //carry from prev + carry = sum >>> SHIFTI; + sum &= MASKI; + + for(int j = 0, k = i; j <= i; j++, k--) { + long bj = bdigits[j] & MASKI; + long ak = digits[k] & MASKI; + + sum += bj * ak; + carry += sum >>> SHIFTI; + sum &= MASKI; + + } + + finalVal |= sum << SHIFTI; + resDigits[m] = finalVal; + + isNonZero |= finalVal; + old_sum = carry; + } + + sum = old_sum; + + long bj = bdigits[0] & MASKI; + long ak = digits[0] & MASKI; + + sum += bj * ak; + + long d0 = sum & MASKD0; + result.digits[0] = sum; + result.isOne = d0 == 1 && isNonZero == 0; + result.sign = sign * b.sign; + + return result; + + } + + public BigNum64 multFull(BigNum64 b) { + + BigNum64 result = new BigNum64(); + + if(sign == 0 || b.sign == 0) { + return result; + } + + long[] bdigits = b.digits; + + long[] resDigits = result.digits; + + if(isOne || b.isOne) { + if (isOne && b.isOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = sign * b.sign; + } + else if(isOne) { + System.arraycopy(bdigits, 0, resDigits, 0, bdigits.length); + result.sign = sign * b.sign; + } + else { + System.arraycopy(digits, 0, resDigits, 0, digits.length); + result.sign = sign * b.sign; + } + return result; + } + + + long old_sum; + + long sum = 0; + long carry = 0; + long bdigit; + long adigit; + long bjhi, akhi, bjlo, aklo; + + int j, k; + + for (j = 1, k = fracDigits; j <= fracDigits;) { + + bdigit = bdigits[j]; + adigit = digits[k]; + + bjlo = bdigit & MASKI; + aklo = adigit & MASKI; + + bjhi = bdigit >>> SHIFTI; + akhi = adigit >>> SHIFTI; + + sum += bjhi * aklo; + carry += sum >>> SHIFTI; + sum &= MASKI; + + sum += bjlo * akhi; + carry += sum >>> SHIFTI; + sum &= MASKI; + + j++;k--; + } + + old_sum = carry + (sum >>> SHIFTIM1); // Roundish + + long carry2; + long sum2; + + long isNonZero = 0; + + long bd0 = bdigits[0]; + long bd0lo = bd0 & MASKI; + + for(int i = fracDigits; i > 0; i--) { + + sum = old_sum; //carry from prev + carry = sum >>> SHIFTI; + sum &= MASKI; + + carry2 = 0; + sum2 = 0; + k = i; + adigit = digits[k]; + + aklo = adigit & MASKI; + akhi = adigit >>> SHIFTI; + + bjlo = bd0lo; + + for(j = 0; j < i;) { + + sum += bjlo * aklo; + carry += sum >>> SHIFTI; + sum &= MASKI; + //System.out.println("1: b" + j + "lo * a"+k+"lo"); + + sum2 += bjlo * akhi; + carry2 += sum2 >>> SHIFTI; + sum2 &= MASKI; + //System.out.println("2: b" + j + "lo * a"+k+"hi"); + + j++; + + bdigit = bdigits[j]; + bjlo = bdigit & MASKI; + bjhi = bdigit >>> SHIFTI; + + sum += bjhi * akhi; + carry += sum >>> SHIFTI; + sum &= MASKI; + //System.out.println("1: b" + j + "hi * a"+k+"hi"); + + k--; + + adigit = digits[k]; + + aklo = adigit & MASKI; + akhi = adigit >>> SHIFTI; + + sum2 += bjhi * aklo; + carry2 += sum2 >>> SHIFTI; + sum2 &= MASKI; + + } + + sum += bjlo * aklo; + //System.out.println("1: b" + j + "lo * a"+k+"lo"); + carry += sum >>> SHIFTI; + sum &= MASKI; + + sum2 += carry; + carry2 += sum2 >>> SHIFTI; + sum2 &= MASKI; + + //System.out.println("Next"); + + long di = (sum2 << SHIFTI) | sum; + resDigits[i] = di; + isNonZero |= di; + //System.out.println(result.digits[i] ); + old_sum = carry2; + //System.out.println("NEXT"); + } + + long d0 = (bd0 * digits[0] + old_sum) & MASKD0; + resDigits[0] = d0; + + result.isOne = d0 == 1 && isNonZero == 0; + + result.sign = sign * b.sign; + + return result; + + } + + @Override + /* Sign is positive */ + public BigNum64 mult(int value) { + BigNum64 result = new BigNum64(); + + if(sign == 0 || value == 0) { + return result; + } + + long[] resDigits = result.digits; + + boolean bIsOne = value == 1 || value == -1; + + int bsign; + + if(value < 0) { + bsign = -1; + value = ~value + 1; + } + else { + bsign = 1; + } + + if(isOne || bIsOne) { + if (isOne && bIsOne) { + resDigits[0] = 1; + result.isOne = true; + result.sign = sign * bsign; + } + else if(isOne) { + resDigits[0] = value; + result.sign = sign * bsign; + } + else { + System.arraycopy(digits, 0, resDigits, 0, digits.length); + result.sign = sign * bsign; + } + return result; + } + + long old_sum = 0; + long sum, sum2; + long carry, carry2; + long digit, digitlo, digithi; + + long isNonZero = 0; + for(int i = fracDigits; i > 0; i--) { + digit = digits[i]; + digithi = digit >>> SHIFTI; + digitlo = digit & MASKI; + + sum = digitlo * value + old_sum; + carry = sum >>> SHIFTI; + sum &= MASKI; + + sum2 = digithi * value + carry; + carry2 = sum2 >>> SHIFTI; + sum2 &= MASKI; + + long di = (sum2 << SHIFTI) | sum; + resDigits[i] = di; + isNonZero |= di; + old_sum = carry2; + } + + sum = digits[0] * value + old_sum; + + long d0 = sum & MASKD0; + resDigits[0] = d0 & MASKD0; + + result.isOne = d0 == 1 && isNonZero == 0; + + result.sign = sign * bsign; + + return result; + } + + @Override + public BigNum64 mult2() { + + BigNum64 res = new BigNum64(); + + if(sign == 0) { + return res; + } + + long [] resDigits = res.digits; + + if(isOne) { + resDigits[0] = 2; + res.sign = sign; + return res; + } + + long isNonZero = 0; + + long digit = digits[fracDigits]; + long bit = digit >>> (SHIFTM1); + long temp = digit << 1; + resDigits[fracDigits] = temp; + isNonZero |= temp; + + for(int i=fracDigits - 1; i > 0; i--) { + digit = digits[i]; + temp = (digit << 1) | bit; + bit = digit >>> (SHIFTM1); + isNonZero |= temp; + resDigits[i] = temp; + } + + digit = digits[0]; + temp = (digit << 1) | bit; + + long d0 = temp & MASKD0; + resDigits[0] = d0; + res.sign = sign; + res.isOne = d0 == 1 && isNonZero == 0; + return res; + + } + + @Override + public BigNum64 mult4() { + + BigNum64 res = new BigNum64(); + + if(sign == 0) { + return res; + } + + long [] resDigits = res.digits; + + if(isOne) { + resDigits[0] = 4; + res.sign = sign; + return res; + } + + long isNonZero = 0; + + long digit = digits[fracDigits]; + long bit = digit >>> (SHIFTM2); + long temp = digit << 2; + resDigits[fracDigits] = temp; + isNonZero |= temp; + + for(int i=fracDigits - 1; i > 0; i--) { + digit = digits[i]; + temp = (digit << 2) | bit; + bit = digit >>> (SHIFTM2); + isNonZero |= temp; + resDigits[i] = temp; + } + + digit = digits[0]; + temp = (digit << 2) | bit; + + long d0 = temp & MASKD0; + resDigits[0] = d0; + res.sign = sign; + res.isOne = d0 == 1 && isNonZero == 0; + return res; + + } + + @Override + public BigNum64 divide2() { + + BigNum64 res = new BigNum64(); + + if(sign == 0) { + return res; + } + + long [] resDigits = res.digits; + + if(isOne) { + resDigits[1] = 0x8000000000000000L; + res.sign = sign; + return res; + } + + long isNonZero = 0; + + long d0 = digits[0]; + long temp = d0; + long val = temp >>> 1; + + long bit = temp & 0x1; + + resDigits[0] = val; + isNonZero |= val; + + for(int i=1; i < fracDigits; i++) { + temp = digits[i]; + val = (bit << SHIFTM1) | (temp >>> 1); + bit = temp & 0x1; + resDigits[i] = val; + isNonZero |= val; + } + + temp = digits[fracDigits]; + val = (bit << SHIFTM1) | (temp >>> 1); + resDigits[fracDigits] = val; + isNonZero |= val; + res.sign = sign; + res.isOne = d0 == 1 && isNonZero == 0; + return res; + + } + + @Override + public BigNum64 divide4() { + + BigNum64 res = new BigNum64(); + + if(sign == 0) { + return res; + } + + long [] resDigits = res.digits; + + if(isOne) { + resDigits[1] = 0x4000000000000000L; + res.sign = sign; + return res; + } + + long isNonZero = 0; + + + long d0 = digits[0]; + long temp = d0; + long val = temp >>> 2; + + long bits = temp & 0x3; + + resDigits[0] = val; + isNonZero |= val; + + for(int i=1; i < fracDigits; i++) { + temp = digits[i]; + val = (temp >>> 2) | (bits << SHIFTM2); + bits = temp & 0x3; + resDigits[i] = val; + isNonZero |= val; + } + + temp = digits[fracDigits]; + val = (temp >>> 2) | (bits << SHIFTM2); + resDigits[fracDigits] = val; + isNonZero |= val; + res.sign = sign; + res.isOne = d0 == 1 && isNonZero == 0; + return res; + + } + + @Override + public MantExp getMantExp() { + + if (sign == 0) { + return new MantExp(); + } + + if(isOne) { + return new MantExp(sign); + } + + long[] digits = this.digits; + + int i; + long digit = 0; + if(offset == -1) { + for (i = 0; i < digits.length; i++) { + digit = digits[i]; + if (digit != 0) { + break; + } + } + + if (i == digits.length) { + return new MantExp(); + } + + /*int r; + for(r = i == 0 ? SHIFT : SHIFTM1; r >= 0; r--) { + if(digits[i] >>> r != 0) { + break; + } + }*/ + + offset = i; + bitOffset = (int)msbDeBruijn64(digit); + scale = i == 0 ? bitOffset : -(((long) i) * SHIFT) + bitOffset; + } + else { + i = offset; + digit = digits[i]; + } + + long mantissa = 0; + + int temp = 52 - bitOffset; + + long val = digit; + if(temp >= 0) { + mantissa |= val << temp; + mantissa &= 0xFFFFFFFFFFFFFL; + if(temp == 0 && i + 1 < digits.length) { + mantissa += (digits[i + 1] >>> (SHIFTM1)) & 0x1; + } + } + else { + int shift = -temp; + mantissa |= val >>> shift; + mantissa &= 0xFFFFFFFFFFFFFL; + mantissa += (val >>> (shift - 1)) & 0x1; + } + + //System.out.println(digits[i]); + + i++; + + int k; + for(k = bitOffset ; k < 52 && i < digits.length; k+=SHIFT, i++) { + val = digits[i]; + temp = 52 - k; + + if(temp > SHIFT) { + mantissa |= val << (temp - SHIFT); + mantissa &= 0xFFFFFFFFFFFFFL; + } + else { + long temp2 = k + SHIFTM52; + mantissa |= val >>> temp2; + mantissa &= 0xFFFFFFFFFFFFFL; + + if(temp2 == 0 && i + 1 < digits.length) { + mantissa += (digits[i + 1] >>> (SHIFTM1)) & 0x1; + } + else { + mantissa += (val >>> (temp2 - 1)) & 0x1; + } + } + } + + // Bit 63 (the bit that is selected by the mask 0x8000000000000000L) represents the sign of the floating-point number. + // Bits 62-52 (the bits that are selected by the mask 0x7ff0000000000000L) represent the exponent. + // Bits 51-0 (the bits that are selected by the mask 0x000fffffffffffffL) represent the significand (sometimes called the mantissa) of the floating-point number. + + long exp = scale + (mantissa >>> 52); + double mantissaDouble; + + if(sign == -1) { + mantissaDouble = Double.longBitsToDouble( (0x8000000000000000L) | (mantissa & 0xFFFFFFFFFFFFFL) | (0x3FF0000000000000L)); + } + else { + mantissaDouble = Double.longBitsToDouble((mantissa & 0xFFFFFFFFFFFFFL) | (0x3FF0000000000000L)); + } + + return new MantExp(exp, mantissaDouble); + + + + } + + public static BigNum64 max(BigNum64 a, BigNum64 b) { + return a.compare(b) > 0 ? a : b; + } + + public static BigNum64 min(BigNum64 a, BigNum64 b) { + return a.compare(b) < 0 ? a : b; + } + + public BigNum64 mult2to64(int times) { + + BigNum64 result = new BigNum64(this); + + if(times <= 0) { + return result; + } + + long[] digits = result.digits; + int total = digits.length + times; + long isNonZero = 0; + + for(int i = times, location = 0; i < total; i++, location++) { + if(i < digits.length) { + digits[location] = digits[i]; + } + else { + digits[location] = 0; + } + + if(location != 0) { + isNonZero |= digits[location]; + } + } + + result.isOne = digits[0] == 1 && isNonZero == 0; + return result; + } + + @Override + public BigNum64 div2toi(long power) { + BigNum64 result = new BigNum64(this); + + if(power <= 0) { + return result; + } + + int times = (int)(power / SHIFT); + + int internalShift = (int)(power % SHIFT); + + long[] digits = result.digits; + int total = -times; + long isNonZero = 0; + long val; + + for(int i = digits.length - 1 - times, location = digits.length - 1; i >= total; i--, location--) { + if(i == 0) { + digits[location] = val = digits[i] >>> internalShift; + } + else if (i > 0) { + digits[location] = val = (digits[i - 1] << (SHIFT - internalShift)) | (digits[i] >>> internalShift); + } + else { + digits[location] = val = 0; + } + + if(location != 0) { + isNonZero |= val; + } + } + + result.isOne = digits[0] == 1 && isNonZero == 0; + return result; + } + + @Override + public BigNum64 mult2toi(long power) { + + BigNum64 result = new BigNum64(this); + + if(power <= 0) { + return result; + } + + int times = (int)(power / SHIFT); + + int internalShift = (int)(power % SHIFT); + + long[] digits = result.digits; + int total = digits.length + times; + long isNonZero = 0; + long val; + + for(int i = times, location = 0; i < total; i++, location++) { + if(i < digits.length - 1) { + digits[location] = val = (digits[i] << internalShift) | (digits[i + 1] >>> (SHIFT - internalShift)); + } + else if(i < digits.length) { + digits[location] = val = (digits[i] << internalShift); + } + else { + digits[location] = val = 0; + } + + if(location != 0) { + isNonZero |= val; + } + } + + result.isOne = digits[0] == 1 && isNonZero == 0; + return result; + } + + public BigNum64 divide2to64(int times) { + + BigNum64 result = new BigNum64(this); + + if(times <= 0) { + return result; + } + + long[] digits = result.digits; + int total = -times; + long isNonZero = 0; + + for(int i = digits.length - 1 - times, location = digits.length - 1; i >= total; i--, location--) { + if(i >= 0) { + digits[location] = digits[i]; + } + else { + digits[location] = 0; + } + + if(location != 0) { + isNonZero |= digits[location]; + } + } + + result.isOne = digits[0] == 1 && isNonZero == 0; + return result; + } + + public BigNum64 shift2to64(int times) { + if(times > 0) { + return mult2to64(times); + } + else if(times < 0) { + return divide2to64(-times); + } + + return new BigNum64(this); + } + + @Override + public BigNum64 shift2toi(long power) { + if(power > 0) { + return mult2toi(power); + } + else if(power < 0) { + return div2toi(-power); + } + + return new BigNum64(this); + } + + @Override + public BigNum64 sqrt() { + if(sign == 0 || isOne) { + return new BigNum64(this); + } + if(sign < 0) { + return new BigNum64(); + } + BigNum64 one = new BigNum64(1); + BigNum64 oneFourth = new BigNum64(0.25); + + BigNum64 a = new BigNum64(this); + long divisions = 0; + long multiplications = 0; + if(a.compareBothPositive(one) > 0) { //scale it down between 1 and 1/4 + do { + a = a.divide4(); + divisions++; + } while (a.compareBothPositive(one) > 0); + } + else if(a.compareBothPositive(oneFourth) < 0) { + + int i; + + long[] digits = a.digits; + for(i = 2; i < digits.length; i++) { + if(digits[i] != 0) { + break; + } + } + + int numberOfLimbs = i - 2; + + if(numberOfLimbs > 0) { + multiplications += ((long)numberOfLimbs * SHIFT) >>> 1; + a = a.mult2to64(numberOfLimbs); + } + + do { + a = a.mult4(); + multiplications++; + } while (a.compareBothPositive(oneFourth) < 0); + } + + BigNum64 oneHalf = new BigNum64(1.5); + BigNum64 aHalf = a.divide2(); // a / 2 + + BigNum64 x = new BigNum64(1 / Math.sqrt(a.doubleValue())); // set the initial value to an approximation of 1 /sqrt(a) + + //Newton steps + BigNum64 newX = x.mult(oneHalf.sub(aHalf.mult(x.squareFull()))); // x = (3/2 - (a/2)*x^2)*x + + BigNum64 epsilon = new BigNum64(1); + epsilon.digits[epsilon.digits.length - 1] = 0x3; + epsilon.digits[0] = 0; + + int iter = 0; + while (newX.sub(x).abs_mutable().compareBothPositive(epsilon) >= 0 && iter < SQRT_MAX_ITERATIONS) { + x = newX; + newX = x.mult(oneHalf.sub(aHalf.mult(x.squareFull()))); + iter++; + } + + BigNum64 sqrta = newX.mult(a); //sqrt(a) = a * (1 /sqrt(a)); + if(multiplications > 0) { //scale it up again + sqrta = sqrta.div2toi(multiplications); + } + else if(divisions > 0) { + sqrta = sqrta.mult2toi(divisions); + } + + return sqrta; + } + + public static void main(String[] args) { + MyApfloat a = new MyApfloat("1.999999999999"); + BigNum64.reinitializeTest(64);//180 + BigNum64 b = new BigNum64(a); + +// MyApfloat.precision = 2000000; +// BigNum64.reinitializeTest(240); +// +// Apfloat a = new MyApfloat("1.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); +// BigNum64 k = new BigNum64(a); + +// BigNum.reinitializeTest(110); +// BigNum c = new BigNum(a); +// c.multKaratsuba(c); + + //System.out.println(b); + //System.out.println(b.multFull(b)); + //System.out.println(b.multFull(b).doubleValue()); + //System.out.println(b.doubleValue()); + //System.out.println(b.doubleValue2()); + + double p = 1312.4325345; + +// BigNum64 r = new BigNum64(p); +// System.out.println(r); +// System.out.println(r.mult2()); +// r = r.mult4(); +// System.out.println(r); +// //r = r.divide2(); +// r = r.divide2(); +// System.out.println(r); + + + //System.out.println(Math.sqrt(p)); + + //System.out.println(b); + + //System.out.println(b.div2toi(2)); + + //System.out.println(b.multFullGolden(b)); + //System.out.println(b.squareFullGolden()); + + //BigNum.reinitializeTest(110); + //BigNum c = new BigNum(a); + +// System.out.println(c.sqrt()); +// System.out.println(b.sqrt()); + + //System.out.println(c.squareFull()); + //System.out.println(b.squareFull()); + //System.out.println(b.squareFullGolden()); + //System.out.println(b.multFull(b)); +// System.out.println(k.multKaratsuba(k)); +// System.out.println(k.multFullGolden(k)); + //System.out.println(b.multKaratsubaGolden(b)); + //System.out.println(c.multKaratsuba(c)); + //System.out.println(b.squareFullGolden()); + +// for(int i = -300; i <= 300; i++) { +// if(b.shift2toi(i).doubleValue() != c.shift2toi(i).doubleValue()) { +// System.out.println(i); +// } +// } + + /*long init = (1073741823L << 5) + 15; + System.out.println(init); + long sum = init; + + sum += (1073741823L + 1073741823L) * (1073741823L + 1073741823L); + sum += (1073741823L + 1073741823L) * (1073741823L + 1073741823L); + sum += (1073741823L + 1073741823L) * (1073741823L + 1073741823L); + sum += (1073741823L + 1073741823L) * (1073741823L + 1073741823L); + + long carry = sum >>> 30; + sum &= 0x3FFFFFFFL; + + System.out.println(sum); + System.out.println(carry); + + + sum = init; + carry = 0; + + sum += (1073741823L + 1073741823L) * (1073741823L + 1073741823L); + carry += sum >>> 30; + sum &= 0x3FFFFFFFL; + sum += (1073741823L + 1073741823L) * (1073741823L + 1073741823L); + carry += sum >>> 30; + sum &= 0x3FFFFFFFL; + sum += (1073741823L + 1073741823L) * (1073741823L + 1073741823L); + carry += sum >>> 30; + sum &= 0x3FFFFFFFL; + sum += (1073741823L + 1073741823L) * (1073741823L + 1073741823L); + carry += sum >>> 30; + sum &= 0x3FFFFFFFL; + + + System.out.println(sum); + System.out.println(carry); + + + System.out.println("NEXT"); + + init = 0; + System.out.println(init); + sum = init; + + long val = 1073741823L + 7; + + sum += (val + 1073741823L) * (1073741823L + val); + sum += (1073741823L + 1073741823L) * (1073741823L + 1073741823L); + sum += (1073741823L + 1073741823L) * (1073741823L + 1073741823L); + sum += (1073741823L + 1073741823L) * (1073741823L + 1073741823L); + + carry = sum >>> 30; + sum &= 0x3FFFFFFFL; + + System.out.println(sum); + System.out.println(carry); + + + sum = init; + carry = 0; + + sum += (val + 1073741823L) * (1073741823L + val); + carry += sum >>> 30; + sum &= 0x3FFFFFFFL; + sum += (1073741823L + 1073741823L) * (1073741823L + 1073741823L); + carry += sum >>> 30; + sum &= 0x3FFFFFFFL; + sum += (1073741823L + 1073741823L) * (1073741823L + 1073741823L); + carry += sum >>> 30; + sum &= 0x3FFFFFFFL; + sum += (1073741823L + 1073741823L) * (1073741823L + 1073741823L); + carry += sum >>> 30; + sum &= 0x3FFFFFFFL; + + + System.out.println(sum); + System.out.println(carry);*/ + + + } +} diff --git a/src/fractalzoomer/core/BigNumComplex.java b/src/fractalzoomer/core/BigNumComplex.java index 8864cf71d..40c026b82 100644 --- a/src/fractalzoomer/core/BigNumComplex.java +++ b/src/fractalzoomer/core/BigNumComplex.java @@ -10,23 +10,23 @@ public class BigNumComplex extends GenericComplex { private BigNum im; public BigNumComplex(BigComplex c) { - re = new BigNum(c.getRe()); - im = new BigNum(c.getIm()); + re = BigNum.create(c.getRe()); + im = BigNum.create(c.getIm()); } public BigNumComplex(double re, double im) { - this.re = new BigNum(re); - this.im = new BigNum(im); + this.re = BigNum.create(re); + this.im = BigNum.create(im); } public BigNumComplex(BigNumComplex c) { - re = new BigNum(c.getRe()); - im = new BigNum(c.getIm()); + re = BigNum.copy(c.getRe()); + im = BigNum.copy(c.getIm()); } public BigNumComplex(Complex c) { - re = new BigNum(c.getRe()); - im = new BigNum(c.getIm()); + re = BigNum.create(c.getRe()); + im = BigNum.create(c.getIm()); } public BigNumComplex(BigNum re, BigNum im) { @@ -35,19 +35,19 @@ public BigNumComplex(BigNum re, BigNum im) { } public BigNumComplex(Apfloat re, Apfloat im) { - this.re = new BigNum(re); - this.im = new BigNum(im); + this.re = BigNum.create(re); + this.im = BigNum.create(im); } public BigNumComplex(String re, String im) { - this.re = new BigNum(re); - this.im = new BigNum(im); + this.re = BigNum.create(re); + this.im = BigNum.create(im); } public BigNumComplex() { - re = new BigNum(); - im = new BigNum(); + re = BigNum.create(); + im = BigNum.create(); } @@ -166,7 +166,7 @@ public final BigNumComplex r_sub(BigNum number) { @Override public final BigNumComplex r_sub(int number) { - return new BigNumComplex(new BigNum(number).sub(re), im.negate()); + return new BigNumComplex(BigNum.create(number).sub(re), im.negate()); } @@ -297,7 +297,7 @@ public NormComponents normSquaredWithComponents(NormComponents n) { */ public final BigNum norm_squared() { - if(BigNum.use_threads) { + if(BigNum.useThreads()) { Future temp1 = TaskDraw.reference_thread_executor.submit(() -> re.square()); Future temp2 = TaskDraw.reference_thread_executor.submit(() -> im.square()); @@ -305,7 +305,7 @@ public final BigNum norm_squared() { return temp1.get().add(temp2.get()); } catch (Exception ex) { - return new BigNum(); + return BigNum.create(); } } else { @@ -507,7 +507,31 @@ public final BigNumComplex square_plus_c(GenericComplex cn) { BigNumComplex c = (BigNumComplex)cn; - if(BigNum.use_threads) { + /*if(BigNum.useThreads2()) { + Future temp1 = TaskDraw.reference_thread_executor2.submit(() -> re.squareFull()); + Future temp2 = TaskDraw.reference_thread_executor2.submit(() -> im.squareFull()); + Future temp3 = TaskDraw.reference_thread_executor2.submit(() -> re.add(im).squareFull()); + + try { + BigNum resqr = temp1.get(); + BigNum imsqr = temp2.get(); + BigNum resqrpimsqr = temp3.get(); + + return new BigNumComplex(resqr.sub(imsqr).add(c.re), resqrpimsqr.sub(resqr).sub(imsqr).add(c.im)); + } + catch (Exception ex) { + return new BigNumComplex(); + } + } + else { + BigNum resqr = re.squareFull(); + BigNum imsqr = im.squareFull(); + BigNum resqrpimsqr = re.add(im).squareFull(); + + return new BigNumComplex(resqr.sub(imsqr).add(c.re), resqrpimsqr.sub(resqr).sub(imsqr).add(c.im)); + }*/ +// else + if(BigNum.useThreads()) { Future temp1 = TaskDraw.reference_thread_executor.submit(() -> re.add(im).mult(re.sub(im)).add(c.re)); Future temp2 = TaskDraw.reference_thread_executor.submit(() -> re.mult(im).mult2().add(c.im)); @@ -852,6 +876,9 @@ public BigNumComplex absNegateIm_mutable() { @Override public BigNumComplex absre_mutable() { return absre(); } + @Override + public BigComplex toBigComplex() {return new BigComplex(re.toApfloat(), im.toApfloat());} + public static void main(String[] args) { MyApfloat.setPrecision(3000); diff --git a/src/fractalzoomer/core/Complex.java b/src/fractalzoomer/core/Complex.java index 510cc09ea..2c66ef17b 100644 --- a/src/fractalzoomer/core/Complex.java +++ b/src/fractalzoomer/core/Complex.java @@ -752,6 +752,7 @@ public final Complex i_remainder_mutable(double imaginary) { /* * 1 / z */ + @Override public final Complex reciprocal() { double temp = 1.0 / (re * re + im * im); @@ -3097,7 +3098,7 @@ public static int sign(double value) { return 0; } - public double chebychevNorm() { + public double chebyshevNorm() { return Math.max(Math.abs(re), Math.abs(im)); } @@ -3120,4 +3121,7 @@ public Complex absNegateIm_mutable() { return this; } + @Override + public BigComplex toBigComplex() {return new BigComplex(re, im);} + } diff --git a/src/fractalzoomer/core/CompressedDeepReference.java b/src/fractalzoomer/core/CompressedDeepReference.java new file mode 100644 index 000000000..cb43cdc21 --- /dev/null +++ b/src/fractalzoomer/core/CompressedDeepReference.java @@ -0,0 +1,337 @@ +package fractalzoomer.core; + +import java.util.ArrayList; +import java.util.Arrays; + +public class CompressedDeepReference extends DeepReference { + private ArrayList wayPointsList; + + private ArrayList rebasesList; + + private int[] rebases; + private boolean[] rebase; + private double[] wayPointMantissaRe; + private double[] wayPointMantissaIm; + + private long[] wayPointExpRe; + private long[] wayPointExpIm; + private int[] wayPointIteration; + + private boolean compressed_extended; + + public CompressedDeepReference(int length) { + super(); + wayPointsList = new ArrayList<>(); + rebasesList = new ArrayList<>(); + rebases = new int[0]; + rebase = new boolean[0]; + wayPointMantissaRe = new double[0]; + wayPointMantissaIm = new double[0]; + wayPointExpRe = new long[0]; + wayPointExpIm = new long[0]; + wayPointIteration = new int[0]; + this.length = length; + compressed = true; + compressed_extended = false; + } + + public CompressedDeepReference(int length, int lengthOverride) { + wayPointsList = new ArrayList<>(); + rebasesList = new ArrayList<>(); + rebases = new int[0]; + rebase = new boolean[0]; + wayPointMantissaRe = new double[0]; + wayPointMantissaIm = new double[0]; + wayPointExpRe = new long[0]; + wayPointExpIm = new long[0]; + wayPointIteration = new int[0]; + this.length = length; + this.lengthOverride = lengthOverride; + compressed = true; + compressed_extended = false; + } + + public void setCompressedExtended(boolean value) { + compressed_extended = value; + } + + public boolean isCompressedExtended() { + return compressed_extended; + } + + public void addWaypoint(Waypoint w) { + wayPointsList.add(w); + } + + public void compact() { + if(wayPointIteration.length == 0 && !wayPointsList.isEmpty()) { + int length = wayPointsList.size(); + wayPointMantissaRe = new double[length]; + wayPointMantissaIm = new double[length]; + wayPointExpRe = new long[length]; + if(TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { + wayPointExpIm = new long[length]; + } + wayPointIteration = new int[length]; + for(int i = 0; i < length; i++) { + Waypoint w = wayPointsList.get(i); + MantExpComplex mz = w.mz; + wayPointMantissaRe[i] = mz.getMantissaReal(); + wayPointMantissaIm[i] = mz.getMantissaImag(); + wayPointExpRe[i] = mz.getExp(); + if(TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { + wayPointExpIm[i] = mz.getExpImag(); + } + wayPointIteration[i] = w.iteration; + } + } + else if (!wayPointsList.isEmpty()){ + int oldLength = wayPointIteration.length; + int newLength = oldLength + wayPointsList.size(); + wayPointMantissaRe = Arrays.copyOf(wayPointMantissaRe, newLength); + wayPointMantissaIm = Arrays.copyOf(wayPointMantissaIm, newLength); + wayPointExpRe = Arrays.copyOf(wayPointExpRe, newLength); + if(TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { + wayPointExpIm = Arrays.copyOf(wayPointExpIm, newLength); + } + wayPointIteration = Arrays.copyOf(wayPointIteration, newLength); + + for(int i = 0, j = oldLength; i < wayPointsList.size(); i++, j++) { + Waypoint w = wayPointsList.get(i); + MantExpComplex mz = w.mz; + wayPointMantissaRe[j] = mz.getMantissaReal(); + wayPointMantissaIm[j] = mz.getMantissaImag(); + wayPointExpRe[j] = mz.getExp(); + if(TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { + wayPointExpIm[j] = mz.getExpImag(); + } + wayPointIteration[j] = w.iteration; + } + } + + wayPointsList.clear(); + } + + public void compactExtended() { + if(wayPointIteration.length == 0 && !wayPointsList.isEmpty()) { + int length = wayPointsList.size(); + wayPointMantissaRe = new double[length]; + wayPointMantissaIm = new double[length]; + wayPointExpRe = new long[length]; + rebase = new boolean[length]; + if(TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { + wayPointExpIm = new long[length]; + } + wayPointIteration = new int[length]; + for(int i = 0; i < length; i++) { + Waypoint w = wayPointsList.get(i); + MantExpComplex mz = w.mz; + wayPointMantissaRe[i] = mz.getMantissaReal(); + wayPointMantissaIm[i] = mz.getMantissaImag(); + wayPointExpRe[i] = mz.getExp(); + if(TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { + wayPointExpIm[i] = mz.getExpImag(); + } + wayPointIteration[i] = w.iteration; + rebase[i] = w.rebase; + } + } + else if (!wayPointsList.isEmpty()){ + int oldLength = wayPointIteration.length; + int newLength = oldLength + wayPointsList.size(); + wayPointMantissaRe = Arrays.copyOf(wayPointMantissaRe, newLength); + wayPointMantissaIm = Arrays.copyOf(wayPointMantissaIm, newLength); + wayPointExpRe = Arrays.copyOf(wayPointExpRe, newLength); + rebase = Arrays.copyOf(rebase, newLength); + if(TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { + wayPointExpIm = Arrays.copyOf(wayPointExpIm, newLength); + } + wayPointIteration = Arrays.copyOf(wayPointIteration, newLength); + + for(int i = 0, j = oldLength; i < wayPointsList.size(); i++, j++) { + Waypoint w = wayPointsList.get(i); + MantExpComplex mz = w.mz; + wayPointMantissaRe[j] = mz.getMantissaReal(); + wayPointMantissaIm[j] = mz.getMantissaImag(); + wayPointExpRe[j] = mz.getExp(); + if(TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { + wayPointExpIm[j] = mz.getExpImag(); + } + wayPointIteration[j] = w.iteration; + rebase[j] = w.rebase; + } + } + + wayPointsList.clear(); + + if(rebases.length == 0 && !rebasesList.isEmpty()) { + int length = rebasesList.size(); + rebases = new int[length]; + + for(int i = 0; i < length; i++) { + rebases[i] = rebasesList.get(i); + } + } + else if (!rebasesList.isEmpty()){ + int oldLength = rebases.length; + int newLength = oldLength + rebasesList.size(); + rebases = Arrays.copyOf(rebases, newLength); + + for(int i = 0, j = oldLength; i < rebasesList.size(); i++, j++) { + rebases[j] = rebasesList.get(i); + } + } + + rebasesList.clear(); + } + + public int compressedLength() { + return wayPointIteration.length; + } + + public int getWaypointIteration(int compressed_index) { + return wayPointIteration[compressed_index]; + } + + public boolean useWaypoint(int compressed_index, int iteration) { + return compressed_index < wayPointIteration.length && wayPointIteration[compressed_index] == iteration; + } + + public MantExpComplex getWaypointData(int compressed_index) { + if(TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { + return new MantExpComplexFull(wayPointExpRe[compressed_index], wayPointExpIm[compressed_index], wayPointMantissaRe[compressed_index], wayPointMantissaIm[compressed_index]); + } + return new MantExpComplex(wayPointExpRe[compressed_index], wayPointMantissaRe[compressed_index], wayPointMantissaIm[compressed_index]); + } + + public Waypoint getWaypoint(int compressed_index) { + + MantExpComplex z; + if(TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { + z = new MantExpComplexFull(wayPointExpRe[compressed_index], wayPointExpIm[compressed_index], wayPointMantissaRe[compressed_index], wayPointMantissaIm[compressed_index]); + } + else { + z = new MantExpComplex(wayPointExpRe[compressed_index], wayPointMantissaRe[compressed_index], wayPointMantissaIm[compressed_index]); + } + return new Waypoint(z, wayPointIteration[compressed_index]); + + } + + public Waypoint getWaypointExtended(int compressed_index) { + MantExpComplex z; + if(TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { + z = new MantExpComplexFull(wayPointExpRe[compressed_index], wayPointExpIm[compressed_index], wayPointMantissaRe[compressed_index], wayPointMantissaIm[compressed_index]); + } + else { + z = new MantExpComplex(wayPointExpRe[compressed_index], wayPointMantissaRe[compressed_index], wayPointMantissaIm[compressed_index]); + } + return new Waypoint(z, wayPointIteration[compressed_index], rebase[compressed_index]); + } + + @Override + public void reset() { + + } + + @Override + public void resize(int length) { + + } + + public Waypoint getClosestWaypoint(int iteration) { + + if(iteration == 0) { + if(wayPointIteration.length > 0 && wayPointIteration[0] == iteration) { + if(TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { + return new Waypoint(new MantExpComplexFull(wayPointExpRe[0], wayPointExpIm[0], wayPointMantissaRe[0], wayPointMantissaIm[0]), wayPointIteration[0], 0); + } + return new Waypoint(new MantExpComplex(wayPointExpRe[0], wayPointMantissaRe[0], wayPointMantissaIm[0]), wayPointIteration[0], 0); + + } + return new Waypoint(0, -1); + } + + int left = 0; + int right = wayPointIteration.length - 1; + + while (left <= right) { + int mid = (int)(((long)left + right) >>> 1); + + if (wayPointIteration[mid] == iteration) { + if(TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { + return new Waypoint(new MantExpComplexFull(wayPointExpRe[mid], wayPointExpIm[mid], wayPointMantissaRe[mid], wayPointMantissaIm[mid]), iteration, mid); + } + return new Waypoint(new MantExpComplex(wayPointExpRe[mid], wayPointMantissaRe[mid], wayPointMantissaIm[mid]), iteration, mid); + } else if (wayPointIteration[mid] < iteration) { + left = mid + 1; + } else { + right = mid - 1; + } + } + + if(right < 0) { + return new Waypoint(0, -1); + } + + if(TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { + return new Waypoint(new MantExpComplexFull(wayPointExpRe[right], wayPointExpIm[right], wayPointMantissaRe[right], wayPointMantissaIm[right]), wayPointIteration[right], right); + } + return new Waypoint(new MantExpComplex(wayPointExpRe[right], wayPointMantissaRe[right], wayPointMantissaIm[right]), wayPointIteration[right], right); + + } + + public Waypoint findWaypoint(int iteration) { + + int left = 0; + int right = wayPointIteration.length - 1; + + while (left <= right) { + int mid = (int)(((long)left + right) >>> 1); + + if (wayPointIteration[mid] == iteration) { + if(TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { + return new Waypoint(new MantExpComplexFull(wayPointExpRe[mid], wayPointExpIm[mid], wayPointMantissaRe[mid], wayPointMantissaIm[mid]), iteration, mid); + } + return new Waypoint(new MantExpComplex(wayPointExpRe[mid], wayPointMantissaRe[mid], wayPointMantissaIm[mid]), iteration, mid); + } else if (wayPointIteration[mid] < iteration) { + left = mid + 1; + } else { + right = mid - 1; + } + } + + return null; + } + + public int rebasesListLength() { + return rebasesList.size(); + } + + public int getRebaseFromListAtIndex(int index) { + return rebasesList.get(index); + } + + public int rebasesLength() { + return rebases.length; + } + + public int getRebaseAtIndex(int index) { + return rebases[index]; + } + + public void addRebase(int index) { + rebasesList.add(index); + } + + public void setRebaseAt(int index, int value) { + rebasesList.set(index, value); + } + + public int compressedListLength() { + return wayPointsList.size(); + } + + public int getWaypointListIteration(int compressed_index) { + return wayPointsList.get(compressed_index).iteration; + } +} diff --git a/src/fractalzoomer/core/CompressedDoubleReference.java b/src/fractalzoomer/core/CompressedDoubleReference.java new file mode 100644 index 000000000..bee191d9c --- /dev/null +++ b/src/fractalzoomer/core/CompressedDoubleReference.java @@ -0,0 +1,270 @@ +package fractalzoomer.core; + +import java.util.ArrayList; +import java.util.Arrays; + +public class CompressedDoubleReference extends DoubleReference { + private ArrayList wayPointsList; + private ArrayList rebasesList; + + private int[] rebases; + + private boolean[] rebase; + private double[] wayPointRe; + private double[] wayPointIm; + private int[] wayPointIteration; + + private boolean compressed_extended; + + public CompressedDoubleReference(int length) { + super(); + wayPointsList = new ArrayList<>(); + rebasesList = new ArrayList<>(); + wayPointRe = new double[0]; + wayPointIm = new double[0]; + wayPointIteration = new int[0]; + rebases = new int[0]; + rebase = new boolean[0]; + this.length = length; + compressed = true; + compressed_extended = false; + } + + public CompressedDoubleReference(int length, int lengthOverride) { + super(); + wayPointsList = new ArrayList<>(); + rebasesList = new ArrayList<>(); + wayPointRe = new double[0]; + wayPointIm = new double[0]; + wayPointIteration = new int[0]; + rebases = new int[0]; + rebase = new boolean[0]; + this.length = length; + this.lengthOverride = lengthOverride; + compressed = true; + compressed_extended = false; + } + + public void setCompressedExtended(boolean value) { + compressed_extended = value; + } + + public boolean isCompressedExtended() { + return compressed_extended; + } + + public void addWaypoint(Waypoint w) { + wayPointsList.add(w); + } + + public void addRebase(int index) { + rebasesList.add(index); + } + + public void setRebaseAt(int index, int value) { + rebasesList.set(index, value); + } + + public void compact() { + if(wayPointIteration.length == 0 && !wayPointsList.isEmpty()) { + int length = wayPointsList.size(); + wayPointRe = new double[length]; + wayPointIm = new double[length]; + wayPointIteration = new int[length]; + for(int i = 0; i < length; i++) { + Waypoint w = wayPointsList.get(i); + Complex z = w.z; + wayPointRe[i] = z.getRe(); + wayPointIm[i] = z.getIm(); + wayPointIteration[i] = w.iteration; + } + } + else if (!wayPointsList.isEmpty()){ + int oldLength = wayPointIteration.length; + int newLength = oldLength + wayPointsList.size(); + wayPointRe = Arrays.copyOf(wayPointRe, newLength); + wayPointIm = Arrays.copyOf(wayPointIm, newLength); + wayPointIteration = Arrays.copyOf(wayPointIteration, newLength); + + for(int i = 0, j = oldLength; i < wayPointsList.size(); i++, j++) { + Waypoint w = wayPointsList.get(i); + Complex z = w.z; + wayPointRe[j] = z.getRe(); + wayPointIm[j] = z.getIm(); + wayPointIteration[j] = w.iteration; + } + } + + wayPointsList.clear(); + } + + + public void compactExtended() { + + if(wayPointIteration.length == 0 && !wayPointsList.isEmpty()) { + int length = wayPointsList.size(); + wayPointRe = new double[length]; + wayPointIm = new double[length]; + wayPointIteration = new int[length]; + rebase = new boolean[length]; + for(int i = 0; i < length; i++) { + Waypoint w = wayPointsList.get(i); + Complex z = w.z; + wayPointRe[i] = z.getRe(); + wayPointIm[i] = z.getIm(); + wayPointIteration[i] = w.iteration; + rebase[i] = w.rebase; + } + } + else if (!wayPointsList.isEmpty()){ + int oldLength = wayPointIteration.length; + int newLength = oldLength + wayPointsList.size(); + wayPointRe = Arrays.copyOf(wayPointRe, newLength); + wayPointIm = Arrays.copyOf(wayPointIm, newLength); + wayPointIteration = Arrays.copyOf(wayPointIteration, newLength); + rebase = Arrays.copyOf(rebase, newLength); + + for(int i = 0, j = oldLength; i < wayPointsList.size(); i++, j++) { + Waypoint w = wayPointsList.get(i); + Complex z = w.z; + wayPointRe[j] = z.getRe(); + wayPointIm[j] = z.getIm(); + wayPointIteration[j] = w.iteration; + rebase[j] = w.rebase; + } + } + + wayPointsList.clear(); + + if(rebases.length == 0 && !rebasesList.isEmpty()) { + int length = rebasesList.size(); + rebases = new int[length]; + + for(int i = 0; i < length; i++) { + rebases[i] = rebasesList.get(i); + } + } + else if (!rebasesList.isEmpty()){ + int oldLength = rebases.length; + int newLength = oldLength + rebasesList.size(); + rebases = Arrays.copyOf(rebases, newLength); + + for(int i = 0, j = oldLength; i < rebasesList.size(); i++, j++) { + rebases[j] = rebasesList.get(i); + } + } + + rebasesList.clear(); + } + + public int compressedLength() { + return wayPointIteration.length; + } + + public int getWaypointIteration(int compressed_index) { + return wayPointIteration[compressed_index]; + } + + public int compressedListLength() { + return wayPointsList.size(); + } + + public int getWaypointListIteration(int compressed_index) { + return wayPointsList.get(compressed_index).iteration; + } + + public boolean useWaypoint(int compressed_index, int iteration) { + return compressed_index < wayPointIteration.length && wayPointIteration[compressed_index] == iteration; + } + + public Complex getWaypointData(int compressed_index) { + return new Complex(wayPointRe[compressed_index], wayPointIm[compressed_index]); + } + + public Waypoint getWaypoint(int compressed_index) { + return new Waypoint(new Complex(wayPointRe[compressed_index], wayPointIm[compressed_index]), wayPointIteration[compressed_index]); + } + + public Waypoint getWaypointExtended(int compressed_index) { + return new Waypoint(new Complex(wayPointRe[compressed_index], wayPointIm[compressed_index]), wayPointIteration[compressed_index], rebase[compressed_index]); + } + + @Override + public void reset() { + + } + + @Override + public void resize(int length) { + + } + + public Waypoint getClosestWaypoint(int iteration) { + + if(iteration == 0) { + if(wayPointIteration.length > 0 && wayPointIteration[0] == iteration) { + return new Waypoint(new Complex(wayPointRe[0], wayPointIm[0]), iteration, 0); + } + return new Waypoint(0, -1); + } + + int left = 0; + int right = wayPointIteration.length - 1; + + while (left <= right) { + int mid = (int)(((long)left + right) >>> 1); + + if (wayPointIteration[mid] == iteration) { + return new Waypoint(new Complex(wayPointRe[mid], wayPointIm[mid]), iteration, mid); + } else if (wayPointIteration[mid] < iteration) { + left = mid + 1; + } else { + right = mid - 1; + } + } + + if(right < 0) { + return new Waypoint(0, -1); + } + + return new Waypoint(new Complex(wayPointRe[right], wayPointIm[right]), wayPointIteration[right], right); + + } + + public Waypoint findWaypoint(int iteration) { + + int left = 0; + int right = wayPointIteration.length - 1; + + while (left <= right) { + int mid = (int)(((long)left + right) >>> 1); + + if (wayPointIteration[mid] == iteration) { + return new Waypoint(new Complex(wayPointRe[mid], wayPointIm[mid]), iteration, mid); + } else if (wayPointIteration[mid] < iteration) { + left = mid + 1; + } else { + right = mid - 1; + } + } + + return null; + } + + public int rebasesListLength() { + return rebasesList.size(); + } + + public int getRebaseFromListAtIndex(int index) { + return rebasesList.get(index); + } + + public int rebasesLength() { + return rebases.length; + } + + public int getRebaseAtIndex(int index) { + return rebases[index]; + } + +} diff --git a/src/fractalzoomer/core/DDComplex.java b/src/fractalzoomer/core/DDComplex.java index 3afa986a8..65739f217 100644 --- a/src/fractalzoomer/core/DDComplex.java +++ b/src/fractalzoomer/core/DDComplex.java @@ -616,6 +616,7 @@ public final int compare(DDComplex z2) { /* * 1 / z */ + @Override public final DDComplex reciprocal() { DoubleDouble temp = new DoubleDouble(1.0).divide(re.sqr().add(im.sqr())); @@ -1652,4 +1653,17 @@ public DDComplex absNegateIm_mutable() { @Override public DDComplex absre_mutable() { return absre(); } + + public final boolean isNaN() { + return re.isNaN() || im.isNaN(); + } + + public final boolean isInfinite() { + return re.isInfinite() || im.isInfinite(); + } + + @Override + public BigComplex toBigComplex() { + return new BigComplex(re.toApfloat(), im.toApfloat()); + } } diff --git a/src/fractalzoomer/core/DeepReference.java b/src/fractalzoomer/core/DeepReference.java index 5aeb1d060..256758df3 100644 --- a/src/fractalzoomer/core/DeepReference.java +++ b/src/fractalzoomer/core/DeepReference.java @@ -11,10 +11,17 @@ public class DeepReference { public long[] expsIm; - private int lengthOverride; - public int length; + protected int lengthOverride; + protected int length; public boolean saveMemory; + public int id; + public boolean compressed; + + public DeepReference() { + id = -1; + compressed = false; + } public DeepReference(int length) { int actualLength = getCreationLength(length); @@ -28,6 +35,8 @@ public DeepReference(int length) { saveMemory = length != actualLength; this.length = length; + id = -1; + compressed = false; } @@ -42,6 +51,8 @@ public DeepReference(int length, int lengthOverride) { saveMemory = false; this.lengthOverride = lengthOverride; this.length = length; + id = -1; + compressed = false; } private int getCreationLength(int length) { diff --git a/src/fractalzoomer/core/DoubleDouble.java b/src/fractalzoomer/core/DoubleDouble.java index 992cdc75f..016a539c3 100644 --- a/src/fractalzoomer/core/DoubleDouble.java +++ b/src/fractalzoomer/core/DoubleDouble.java @@ -2187,4 +2187,6 @@ public DoubleDouble toDegrees() { public MantExp getMantExp() { return new MantExp(doubleValue()); } + + public Apfloat toApfloat() { return new MyApfloat(toString());} } diff --git a/src/fractalzoomer/core/DoubleReference.java b/src/fractalzoomer/core/DoubleReference.java index a6cf8075b..5e257281a 100644 --- a/src/fractalzoomer/core/DoubleReference.java +++ b/src/fractalzoomer/core/DoubleReference.java @@ -5,12 +5,19 @@ public class DoubleReference { public double[] re; public double[] im; - public int length; - private int lengthOverride; + protected int length; + protected int lengthOverride; public boolean saveMemory; public static final int SAVE_MEMORY_THRESHOLD = 100_000_000; public static final int SAVE_MEMORY_THRESHOLD2 = 50_000_000; public static boolean SHOULD_SAVE_MEMORY = false; + public int id; + public boolean compressed; + + public DoubleReference() { + id = -1; + compressed = false; + } public DoubleReference(int length) { @@ -22,6 +29,9 @@ public DoubleReference(int length) { saveMemory = length != actualLength; this.length = length; + + id = -1; + compressed = false; } private int getCreationLength(int length) { @@ -45,6 +55,8 @@ public DoubleReference(int length, int lengthOverride) { im = new double[length]; saveMemory = false; this.length = length; + id = -1; + compressed = false; } public void setLengthOverride(int lengthOverride) { diff --git a/src/fractalzoomer/core/DrawOrbit.java b/src/fractalzoomer/core/DrawOrbit.java index 88a9a8ed5..8c4e95f59 100644 --- a/src/fractalzoomer/core/DrawOrbit.java +++ b/src/fractalzoomer/core/DrawOrbit.java @@ -310,9 +310,68 @@ protected void draw() { ptr.getMainPanel().repaint(); } - - public void drawLine(Graphics2D full_image_g) { - int x0, y0, x1 = 0, y1 = 0, list_size; + + static final double EPSILON = 1e-6; + + static boolean liangBarskyClip(double x0, double y0, double x1, double y1, + double xmin, double ymin, double xmax, double ymax, double[] result) { + double dx = x1 - x0; + double dy = y1 - y0; + + double p1 = -dx; + double p2 = dx; + double p3 = -dy; + double p4 = dy; + + double q1 = x0 - xmin; + double q2 = xmax - x0; + double q3 = y0 - ymin; + double q4 = ymax - y0; + + double[] p = {p1, p2, p3, p4}; + double[] q = {q1, q2, q3, q4}; + + double t_enter = 0, t_exit = 1; + + for (int i = 0; i < p.length; i++) { + if (Math.abs(p[i]) < EPSILON) { + if (q[i] < 0) { + return false; // Line is parallel and outside the clipping window + } + } else { + double t = q[i] / p[i]; + + if (p[i] < 0 && t > t_enter) { + t_enter = t; + } else if (p[i] > 0 && t < t_exit) { + t_exit = t; + } + } + } + + if (t_enter > t_exit) { + return false; // Line is outside the clipping window + } + + // Compute the intersection points + double xIntersection1 = x0 + t_enter * dx; + double yIntersection1 = y0 + t_enter * dy; + + double xIntersection2 = x0 + t_exit * dx; + double yIntersection2 = y0 + t_exit * dy; + + // Print the intersection points + result[0] = xIntersection1; + result[1] = yIntersection1; + result[2] = xIntersection2; + result[3] = yIntersection2; + + return true; + } + + public void drawLine(Graphics2D full_image_g, boolean drawDot) { + double x0, y0, x1 = 0, y1 = 0; + int list_size; full_image_g.setColor(orbit_color); @@ -353,6 +412,10 @@ public void drawLine(Graphics2D full_image_g) { Rectangle2D rect = metrics.getStringBounds("*", full_image_g); int width = (int)rect.getWidth(); int height = (int)rect.getHeight(); + + int x0_ = 0, x1_ = 0, y0_ = 0, y1_ = 0; + double[] result = new double[4]; + boolean drawLine = true; for(int i = 0; i < list_size; i++) { @@ -362,54 +425,77 @@ public void drawLine(Graphics2D full_image_g) { f0 = n0.arg(); f0 = f0 < 0 ? f0 + 2 * Math.PI : f0; - x0 = (int)((Math.log(r0) - start) / mulx + 0.5); - y0 = (int)(f0 / muly + 0.5); + x0 = (Math.log(r0) - start) / mulx; + y0 = f0 / muly; Complex n1 = complex_orbit.get(i + 1).sub(new Complex(xcenter, ycenter)); r1 = n1.norm(); f1 = n1.arg(); f1 = f1 < 0 ? f1 + 2 * Math.PI : f1; - x1 = (int)((Math.log(r1) - start) / mulx + 0.5); - y1 = (int)(f1 / muly + 0.5); + x1 = (Math.log(r1) - start) / mulx; + y1 = f1 / muly; } else { - x0 = (int)((complex_orbit.get(i).getRe() - temp_xcenter_size) / temp_size_image_size_x + 0.5); - y0 = (int)((-complex_orbit.get(i).getIm() + temp_ycenter_size) / temp_size_image_size_y + 0.5); - x1 = (int)((complex_orbit.get(i + 1).getRe() - temp_xcenter_size) / temp_size_image_size_x + 0.5); - y1 = (int)((-complex_orbit.get(i + 1).getIm() + temp_ycenter_size) / temp_size_image_size_y + 0.5); - } - - if(x0 == Integer.MIN_VALUE || x0 == Integer.MAX_VALUE || x1 == Integer.MIN_VALUE || x1 == Integer.MAX_VALUE || y0 == Integer.MIN_VALUE || y0 == Integer.MAX_VALUE || y1 == Integer.MIN_VALUE || y1 == Integer.MAX_VALUE) { - return; + x0 = (complex_orbit.get(i).getRe() - temp_xcenter_size) / temp_size_image_size_x; + y0 = (-complex_orbit.get(i).getIm() + temp_ycenter_size) / temp_size_image_size_y; + x1 = (complex_orbit.get(i + 1).getRe() - temp_xcenter_size) / temp_size_image_size_x; + y1 = (-complex_orbit.get(i + 1).getIm() + temp_ycenter_size) / temp_size_image_size_y; } - - full_image_g.drawLine(x0, y0, x1, y1); - if(i == 0) { - if(polar_projection && circle_period > 1 && pixel_x != -1 && pixel_y != -1 && Math.abs(y0 - pixel_y) != 0) { - full_image_g.drawLine(pixel_x, pixel_y, x0, y0); - full_image_g.drawString("*", pixel_x - width / 2, pixel_y + height / 2); - full_image_g.fillOval(x0 - 2, y0 - 2, 5, 5); + + drawLine = true; + if(x0 < 0 || x0 >= image_size || y0 < 0 || y0 >= image_size || + x1 < 0 || x1 >= image_size || y1 < 0 || y1 >= image_size) { + + int limit = 1000000; + if(!liangBarskyClip(x0, y0, x1, y1, -limit, -limit, image_size + limit, image_size + limit, result)) { + drawLine = false; } else { - full_image_g.drawString("*", x0 - width / 2, y0 + height / 2); + x0_ = (int) (result[0] + 0.5); + y0_ = (int) (result[1] + 0.5); + x1_ = (int) (result[2] + 0.5); + y1_ = (int) (result[3] + 0.5); } } else { - full_image_g.fillOval(x0 - 2, y0 - 2, 5, 5); + x0_ = (int)(x0 + 0.5); + y0_ = (int)(y0 + 0.5); + x1_ = (int)(x1 + 0.5); + y1_ = (int)(y1 + 0.5); + } + + if(drawLine) { + full_image_g.drawLine(x0_, y0_, x1_, y1_); + + if(drawDot) { + if (i == 0) { + if (polar_projection && circle_period > 1 && pixel_x != -1 && pixel_y != -1 && Math.abs(y0_ - pixel_y) != 0) { + full_image_g.drawLine(pixel_x, pixel_y, x0_, y0_); + full_image_g.drawString("*", pixel_x - width / 2, pixel_y + height / 2); + full_image_g.fillOval(x0_ - 2, y0_ - 2, 5, 5); + } else { + full_image_g.drawString("*", x0_ - width / 2, y0_ + height / 2); + } + } else { + full_image_g.fillOval(x0_ - 2, y0_ - 2, 5, 5); + } + } } } - if(list_size > 0) { - full_image_g.fillOval(x1 - 2, y1 - 2, 5, 5); + if(list_size > 0 && drawLine) { + if(drawDot) { + full_image_g.fillOval(x1_ - 2, y1_ - 2, 5, 5); + } if(show_converging_point) { - if(complex_orbit.get(complex_orbit.size() - 1).distance(complex_orbit.get(complex_orbit.size() - 2)) < 1e-6) { + if(complex_orbit.get(complex_orbit.size() - 1).distance(complex_orbit.get(complex_orbit.size() - 2)) < EPSILON) { Complex last = complex_orbit.get(complex_orbit.size() - 1); Rotation rot = new Rotation(rotation_vals[0], rotation_vals[1], rotation_center[0], rotation_center[1]); - full_image_g.drawString(rot.rotate(last).toStringTruncated(), x1 + 15, y1 + 15); + full_image_g.drawString(rot.rotate(last).toStringTruncated(), x1_ + 15, y1_ + 15); } } } @@ -417,7 +503,8 @@ public void drawLine(Graphics2D full_image_g) { } public void drawDot(Graphics2D full_image_g) { - int x0 = 0, y0 = 0, list_size; + double x0 = 0, y0 = 0; + int list_size; full_image_g.setColor(orbit_color); @@ -460,6 +547,8 @@ public void drawDot(Graphics2D full_image_g) { Rectangle2D rect = metrics.getStringBounds("*", full_image_g); int width = (int)rect.getWidth(); int height = (int)rect.getHeight(); + int x0_ = 0, y0_ = 0; + boolean draw = true; for(int i = 0; i < list_size; i++) { if(polar_projection) { @@ -468,42 +557,43 @@ public void drawDot(Graphics2D full_image_g) { f0 = n0.arg(); f0 = f0 < 0 ? f0 + 2 * Math.PI : f0; - x0 = (int)((Math.log(r0) - start) / mulx + 0.5); - y0 = (int)(f0 / muly + 0.5); + x0 = (Math.log(r0) - start) / mulx; + y0 = f0 / muly; } else { - x0 = (int)((complex_orbit.get(i).getRe() - temp_xcenter_size) / temp_size_image_size_x + 0.5); - y0 = (int)((-complex_orbit.get(i).getIm() + temp_ycenter_size) / temp_size_image_size_y + 0.5); + x0 = (complex_orbit.get(i).getRe() - temp_xcenter_size) / temp_size_image_size_x; + y0 = (-complex_orbit.get(i).getIm() + temp_ycenter_size) / temp_size_image_size_y; } - - if(x0 == Integer.MIN_VALUE || x0 == Integer.MAX_VALUE || y0 == Integer.MIN_VALUE || y0 == Integer.MAX_VALUE) { - return; - } - - if(i == 0) { - if(polar_projection && circle_period > 1 && pixel_x != -1 && pixel_y != -1 && Math.abs(y0 - pixel_y) != 0) { - full_image_g.drawString("*", pixel_x - width / 2, pixel_y + height / 2); - full_image_g.fillOval(x0 - 2, y0 - 2, 5, 5); - } - else { - full_image_g.drawString("*", x0 - width / 2, y0 + height / 2); - } + + draw = true; + if(x0 < 0 || x0 >= image_size || y0 < 0 || y0 >= image_size) { + draw = false; } else { - full_image_g.fillOval(x0 - 2, y0 - 2, 5, 5); + x0_ = (int)(x0 + 0.5); + y0_ = (int)(y0 + 0.5); } - } - - if(list_size > 1) { - if(show_converging_point) { - if(complex_orbit.get(complex_orbit.size() - 1).distance(complex_orbit.get(complex_orbit.size() - 2)) < 1e-6) { - Complex last = complex_orbit.get(complex_orbit.size() - 1); - Rotation rot = new Rotation(rotation_vals[0], rotation_vals[1], rotation_center[0], rotation_center[1]); - - full_image_g.drawString(rot.rotate(last).toStringTruncated(), x0 + 15, y0 + 15); + + if(draw) { + if (i == 0) { + if (polar_projection && circle_period > 1 && pixel_x != -1 && pixel_y != -1 && Math.abs(y0_ - pixel_y) != 0) { + full_image_g.drawString("*", pixel_x - width / 2, pixel_y + height / 2); + full_image_g.fillOval(x0_ - 2, y0_ - 2, 5, 5); + } else { + full_image_g.drawString("*", x0_ - width / 2, y0_ + height / 2); + } + } else { + full_image_g.fillOval(x0_ - 2, y0_ - 2, 5, 5); } } } + + if(draw && list_size > 1 && show_converging_point && complex_orbit.get(complex_orbit.size() - 1).distance(complex_orbit.get(complex_orbit.size() - 2)) < EPSILON) { + Complex last = complex_orbit.get(complex_orbit.size() - 1); + Rotation rot = new Rotation(rotation_vals[0], rotation_vals[1], rotation_center[0], rotation_center[1]); + + full_image_g.drawString(rot.rotate(last).toStringTruncated(), x0_ + 15, y0_ + 15); + } } @@ -772,6 +862,9 @@ private void orbitJuliaFactory(int function, double xCenter, double yCenter, dou case MainWindow.FORMULA47: pixel_orbit = new Formula47(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); break; + case MainWindow.FORMULA48: + pixel_orbit = new Formula48(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); + break; case MainWindow.PERPENDICULAR_MANDELBROT: pixel_orbit = new PerpendicularMandelbrot(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); break; @@ -1312,6 +1405,9 @@ private void orbitFractalFactory(int function, double xCenter, double yCenter, d case MainWindow.FORMULA47: pixel_orbit = new Formula47(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, rotation_vals, rotation_center, perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, user_perturbation_conditions, user_perturbation_condition_formula, perturbation_user_formula, init_val, initial_vals, variable_init_value, user_initial_value_algorithm, user_initial_value_conditions, user_initial_value_condition_formula, initial_value_user_formula, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower); break; + case MainWindow.FORMULA48: + pixel_orbit = new Formula48(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, rotation_vals, rotation_center, perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, user_perturbation_conditions, user_perturbation_condition_formula, perturbation_user_formula, init_val, initial_vals, variable_init_value, user_initial_value_algorithm, user_initial_value_conditions, user_initial_value_condition_formula, initial_value_user_formula, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower); + break; case MainWindow.PERPENDICULAR_MANDELBROT: pixel_orbit = new PerpendicularMandelbrot(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, rotation_vals, rotation_center, perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, user_perturbation_conditions, user_perturbation_condition_formula, perturbation_user_formula, init_val, initial_vals, variable_init_value, user_initial_value_algorithm, user_initial_value_conditions, user_initial_value_condition_formula, initial_value_user_formula, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower); break; diff --git a/src/fractalzoomer/core/GenericComplex.java b/src/fractalzoomer/core/GenericComplex.java index 9910ea919..09a861eac 100644 --- a/src/fractalzoomer/core/GenericComplex.java +++ b/src/fractalzoomer/core/GenericComplex.java @@ -6,9 +6,10 @@ import fractalzoomer.utils.NormComponents; import org.apfloat.Apfloat; -public class GenericComplex { +public abstract class GenericComplex { public Complex toComplex() {return null;} + public BigComplex toBigComplex() {return null;} public MantExpComplex toMantExpComplex() {return null;} @@ -20,12 +21,16 @@ public class GenericComplex { public GenericComplex square_plus_c_mutable(GenericComplex c, MpfrBigNum temp, MpfrBigNum temp2) {return null;} + public GenericComplex square_plus_c_mutable_with_reduction(GenericComplex c, MpfrBigNum temp, MpfrBigNum temp2, boolean deepZoom, Complex cz, MantExpComplex mcz) {return null;} + public GenericComplex square_mutable(MpfrBigNum temp1, MpfrBigNum temp2) { return null; } public GenericComplex square_mutable(MpirBigNum temp1, MpirBigNum temp2) { return null; } public GenericComplex square_plus_c_mutable(GenericComplex c, MpirBigNum temp, MpirBigNum temp2, MpirBigNum temp3) {return null;} + public GenericComplex square_plus_c_mutable_with_reduction(GenericComplex c, MpirBigNum temp, MpirBigNum temp2, MpirBigNum temp3, boolean deepZoom, Complex cz, MantExpComplex mcz) {return null;} + public GenericComplex square_plus_c_mutable_no_threads(GenericComplex c, MpirBigNum temp, MpirBigNum temp2, MpirBigNum temp3) {return null;} public GenericComplex sub(GenericComplex v, MpfrBigNum temp, MpfrBigNum temp2) {return null;} @@ -55,6 +60,8 @@ public class GenericComplex { public GenericComplex square_mutable() {return null;} + public GenericComplex reciprocal() {return null;} + public GenericComplex cube() {return null;} public GenericComplex fourth() {return null;} @@ -136,4 +143,6 @@ public void assign(GenericComplex z) {} public GenericComplex absre_mutable() { return null; } + public abstract boolean isZero(); + } diff --git a/src/fractalzoomer/core/MantExpComplex.java b/src/fractalzoomer/core/MantExpComplex.java index b9ac9f203..f8927ec8f 100644 --- a/src/fractalzoomer/core/MantExpComplex.java +++ b/src/fractalzoomer/core/MantExpComplex.java @@ -985,6 +985,7 @@ public MantExpComplex divide_mutable(MantExpComplex factor) { return this; } + @Override public MantExpComplex reciprocal() { double temp = 1.0 / (mantissaReal * mantissaReal + mantissaImag * mantissaImag); @@ -1066,6 +1067,27 @@ public MantExpComplex abs_mutable() { } + @Override + public MantExpComplex absre_mutable() { + + mantissaReal = Math.abs(mantissaReal); + + return this; + + } + + @Override + public MantExpComplex absNegateRe_mutable() { + mantissaReal = - Math.abs(mantissaReal); + return this; + } + + @Override + public MantExpComplex absNegateIm_mutable() { + mantissaImag = - Math.abs(mantissaImag); + return this; + } + public MantExpComplex conjugate() { return new MantExpComplex(exp, mantissaReal, -mantissaImag); @@ -1210,7 +1232,7 @@ public MantExpComplex plus_mutable(GenericComplex v) { } - public MantExp chebychevNorm() { + public MantExp chebyshevNorm() { return MantExp.maxBothPositive(getRe().abs(), getIm().abs()); } @@ -1226,5 +1248,36 @@ public void assign(long exp1, double mantissaReal1, double mantissaImag1) { public void assign(long exp1, long expIm1, double mantissaReal1, double mantissaImag1) { } + + public void set(long expRe, long expIm, double valRe, double valIm) { + + if(valRe == 0 && valIm == 0) { + expRe = MantExp.MIN_BIG_EXPONENT; + expIm = MantExp.MIN_BIG_EXPONENT; + } + else if(valRe == 0) { + expRe = MantExp.MIN_BIG_EXPONENT; + } + else if(valIm == 0) { + expIm = MantExp.MIN_BIG_EXPONENT; + } + + exp = Math.max(expRe, expIm); + mantissaReal = valRe * MantExp.getMultiplier(expRe-exp); + mantissaImag = valIm * MantExp.getMultiplier(expIm-exp); + } + + public boolean isInfinite() { + return Double.isInfinite(mantissaReal) || Double.isInfinite(mantissaImag); + } + + public boolean isNaN() { + return Double.isNaN(mantissaReal) || Double.isNaN(mantissaImag); + } + + @Override + public boolean isZero() { + return mantissaReal == 0 && mantissaImag == 0; + } } diff --git a/src/fractalzoomer/core/MantExpComplexFull.java b/src/fractalzoomer/core/MantExpComplexFull.java index ba2ffd019..765f26a6d 100644 --- a/src/fractalzoomer/core/MantExpComplexFull.java +++ b/src/fractalzoomer/core/MantExpComplexFull.java @@ -505,6 +505,26 @@ public MantExpComplexFull abs_mutable() { } + @Override + public MantExpComplexFull absre_mutable() { + + re.abs_mutable(); + return this; + + } + + @Override + public MantExpComplexFull absNegateRe_mutable() { + re.abs_mutable().negate_mutable(); + return this; + } + + @Override + public MantExpComplexFull absNegateIm_mutable() { + im.abs_mutable().negate_mutable(); + return this; + } + @Override public MantExpComplexFull conjugate() { @@ -652,5 +672,40 @@ public void assign(long exp1, long expIm1, double mantissaReal1, double mantissa re.exp = exp1; im.exp = expIm1; } + + @Override + public void set(long expRe, long expIm, double valRe, double valIm) { + + if(valRe == 0 && valIm == 0) { + expRe = MantExp.MIN_BIG_EXPONENT; + expIm = MantExp.MIN_BIG_EXPONENT; + } + else if(valRe == 0) { + expRe = MantExp.MIN_BIG_EXPONENT; + } + else if(valIm == 0) { + expIm = MantExp.MIN_BIG_EXPONENT; + } + + re.exp = expRe; + im.exp = expIm; + re.mantissa = valRe; + im.mantissa = valIm; + } + + @Override + public boolean isInfinite() { + return Double.isInfinite(re.mantissa) || Double.isInfinite(im.mantissa); + } + + @Override + public boolean isNaN() { + return Double.isNaN(re.mantissa) || Double.isNaN(im.mantissa); + } + + @Override + public boolean isZero() { + return re.mantissa == 0 && im.mantissa == 0; + } } diff --git a/src/fractalzoomer/core/MpfrBigNumComplex.java b/src/fractalzoomer/core/MpfrBigNumComplex.java index bb2ef7998..d2a3791cd 100644 --- a/src/fractalzoomer/core/MpfrBigNumComplex.java +++ b/src/fractalzoomer/core/MpfrBigNumComplex.java @@ -1455,6 +1455,14 @@ public final MpfrBigNumComplex square_plus_c_mutable(GenericComplex ca, MpfrBigN } + @Override + public MpfrBigNumComplex square_plus_c_mutable_with_reduction(GenericComplex ca, MpfrBigNum temp1, MpfrBigNum temp2, boolean deepZoom, Complex cz, MantExpComplex mcz) { + MpfrBigNumComplex c = (MpfrBigNumComplex)ca; + MpfrBigNum.z_sqr_p_c_with_reduction(re, im, temp1, temp2, c.re, c.im, deepZoom, cz, mcz); + return this; + + } + /* * z1 * z2 */ @@ -2225,6 +2233,7 @@ public final MpfrBigNumComplex log_mutable() { /* * 1 / z */ + @Override public final MpfrBigNumComplex reciprocal() { MpfrBigNum tempRe = re.square(); MpfrBigNum tempIm = im.square(); @@ -3123,5 +3132,10 @@ public MpfrBigNumComplex absNegateIm_mutable() { return this; } + @Override + public BigComplex toBigComplex() { + return new BigComplex(re.toApfloat(), im.toApfloat()); + } + } diff --git a/src/fractalzoomer/core/MpirBigNumComplex.java b/src/fractalzoomer/core/MpirBigNumComplex.java index 0bd4481e4..718be2ec2 100644 --- a/src/fractalzoomer/core/MpirBigNumComplex.java +++ b/src/fractalzoomer/core/MpirBigNumComplex.java @@ -1347,6 +1347,13 @@ public final MpirBigNumComplex square_plus_c_mutable(GenericComplex ca, MpirBigN } + @Override + public final MpirBigNumComplex square_plus_c_mutable_with_reduction(GenericComplex ca, MpirBigNum temp1, MpirBigNum temp2, MpirBigNum temp3, boolean deepZoom, Complex cz, MantExpComplex mcz) { + MpirBigNumComplex c = (MpirBigNumComplex)ca; + MpirBigNum.z_sqr_p_c_with_reduction(re, im, temp1, temp2, temp3, c.re, c.im, deepZoom, cz, mcz); + return this; + } + @Override public final MpirBigNumComplex square_plus_c_mutable_no_threads(GenericComplex ca, MpirBigNum temp1, MpirBigNum temp2, MpirBigNum temp3) { MpirBigNumComplex c = (MpirBigNumComplex)ca; @@ -1912,6 +1919,7 @@ public MpirBigNumComplex divide4_mutable() { /* * 1 / z */ + @Override public final MpirBigNumComplex reciprocal() { MpirBigNum tempRe = re.square(); MpirBigNum tempIm = im.square(); @@ -2197,4 +2205,9 @@ public MpirBigNumComplex absNegateIm_mutable() { return this; } + @Override + public BigComplex toBigComplex() { + return new BigComplex(re.toApfloat(), im.toApfloat()); + } + } diff --git a/src/fractalzoomer/core/MyApfloat.java b/src/fractalzoomer/core/MyApfloat.java index 8b2c183e4..4977e311a 100644 --- a/src/fractalzoomer/core/MyApfloat.java +++ b/src/fractalzoomer/core/MyApfloat.java @@ -40,8 +40,9 @@ public class MyApfloat extends Apfloat { public static Apfloat SA_START_SIZE; public static Apfloat NEGATIVE_INFINITY = new Apfloat("-1e5000000000"); public static FixedPrecisionApfloatHelper fp; - public static long precHeadRoom = 30; - public static long precHeadRoomSmall = 4; + public static long precHeadRoom = 25; + public static long precHeadRoom2 = 50; + public static long precHeadRoomSmall = 5; public static boolean setAutomaticPrecision = true; public static boolean alwaysCheckForDecrease = true; @@ -58,13 +59,13 @@ public static long getAutomaticPrecision(double value) { Apfloat val = new Apfloat(new BigDecimal(value), 10000); //Hopefully that is enough return Math.abs(val.scale()) + precHeadRoom + 1; // + 30 for some headroom }*/ - - public static long getAutomaticPrecision(String[] values, boolean[] preferExponent) { - long prec = getAutomaticPrecisionInternal(values, preferExponent); - return Math.max(prec, precHeadRoom); + public static long getAutomaticPrecision(String[] values, boolean[] preferExponent, int function) { + long precHeadRoomToUse = Settings.usesPerturbationWithDivision(function) ? precHeadRoom2 : precHeadRoom; + long prec = getAutomaticPrecisionInternal(values, preferExponent, precHeadRoomToUse); + return Math.max(prec, precHeadRoomToUse); } - private static long getAutomaticPrecisionInternal(String[] values, boolean[] preferExponent) { + private static long getAutomaticPrecisionInternal(String[] values, boolean[] preferExponent, long precHeadRoom) { long maxValue = Long.MIN_VALUE; long maxValueForExponentPreferal = Long.MIN_VALUE; @@ -154,11 +155,12 @@ else if (Character.isDigit(value.charAt(i))) { } } - public static boolean shouldSetPrecision(long newPrecision, boolean checkForDecrease) { + public static boolean shouldSetPrecision(long newPrecision, boolean checkForDecrease, int function) { + long precHeadRoomToUse = Settings.usesPerturbationWithDivision(function) ? precHeadRoom2 : precHeadRoom; return (newPrecision > precision) || (checkForDecrease - && newPrecision < (precision - (precHeadRoom << 1)) - && newPrecision > precHeadRoom + && newPrecision < (precision - (precHeadRoomToUse << 1)) + && newPrecision > precHeadRoomToUse ); } @@ -167,7 +169,8 @@ public static boolean shouldIncreasePrecision(Apfloat val) { } public static void increasePrecision(Settings s) { - setPrecision(precision + precHeadRoom, s); + long precHeadRoomToUse = Settings.usesPerturbationWithDivision(s.fns.function) ? precHeadRoom2 : precHeadRoom; + setPrecision(precision + precHeadRoomToUse, s); } static { @@ -189,7 +192,7 @@ public static void increasePrecision(Settings s) { SIXTEEN = new Apint(16); TWENTYFOUR = new Apint(24); THIRTYTWO = new Apint(32); - E = fp.exp(ONE); + E = fp.e(); TWO_PI = fp.multiply(PI, TWO); SQRT_TWO = fp.sqrt(TWO); LOG_TWO = fp.log(TWO); @@ -222,7 +225,7 @@ public static void setPrecision(long prec) { precision = prec; fp = new FixedPrecisionApfloatHelper(precision); PI = fp.pi(); - E = fp.exp(ONE); + E = fp.e(); TWO_PI = fp.multiply(PI, TWO); SQRT_TWO = fp.sqrt(TWO); LOG_TWO = fp.log(TWO); @@ -286,6 +289,10 @@ public MyApfloat(String value) { super(value.trim(), precision); } + public MyApfloat(String value, int radix) { + super(value.trim(), precision, radix); + } + public static Apfloat getPi() { return PI; } @@ -637,7 +644,7 @@ public static void main(String[] args) { MyApfloat.precision = 50; MyApfloat.fp = new FixedPrecisionApfloatHelper(MyApfloat.precision); - System.out.println(getAutomaticPrecision(new String[]{"0.003236469856558749616219364295756151228386738578675", "-0.8421534199886435385336059377278168189344067258883", "6.82121026329696178436279296875e-13" }, new boolean[] {false, false, true})); + //System.out.println(getAutomaticPrecision(new String[]{"0.003236469856558749616219364295756151228386738578675", "-0.8421534199886435385336059377278168189344067258883", "6.82121026329696178436279296875e-13" }, new boolean[] {false, false, true})); //Apfloat a = new MyApfloat("-1.99996619445037030418434688506350579675531241540724851511761922944801584242342684381376129778868913812287046406560949864353810575744772166485672496092803920095332"); //Apfloat b = new MyApfloat("+0.00000000000000000000000000000000030013824367909383240724973039775924987346831190773335270174257280120474975614823581185647299288414075519224186504978181625478529"); diff --git a/src/fractalzoomer/core/ReferenceCompressor.java b/src/fractalzoomer/core/ReferenceCompressor.java new file mode 100644 index 000000000..809a6c72c --- /dev/null +++ b/src/fractalzoomer/core/ReferenceCompressor.java @@ -0,0 +1,659 @@ +package fractalzoomer.core; + +import fractalzoomer.functions.Fractal; + +import java.util.function.Function; + +public class ReferenceCompressor { + public static double CompressionError = Math.pow(10, -9); + private static double CompressionErrorInverted = 1 / CompressionError; + private static MantExp CompressionErrorInvertedm = new MantExp(CompressionErrorInverted); + + + private static double limit1 = 0x1.0p-4; + private static MantExp limit1m = new MantExp(limit1); + + private static double limit2 = 0x1.000001p0; + private static MantExp limit2m = new MantExp(limit2); + + public static void setCompressionError() { + CompressionErrorInverted = 1 / CompressionError; + CompressionErrorInvertedm = new MantExp(CompressionErrorInverted); + } + private Complex z; + private Complex c; + + private Complex initVal; + + private MantExpComplex mz; + private MantExpComplex mc; + + private MantExpComplex initValm; + + private Function function; + private Function functionm; + + private Fractal f; + + public ReferenceCompressor( Fractal f, Complex z, Complex c, Complex initVal) { + this.z = z; + this.c = c; + this.f = f; + this.initVal = initVal; + } + + public ReferenceCompressor( Fractal f, MantExpComplex mz, MantExpComplex mc, MantExpComplex initValm) { + this.f = f; + this.mz = mz; + this.mc = mc; + this.initValm = initValm; + } + + public ReferenceCompressor(Function function) { + this.function = function; + } + + public ReferenceCompressor(Function function, boolean deep) { + this.functionm = function; + } + + //maxRefIteration should be +1 + public static CompressedDeepReference compressReferenceWithExpression(CompressedDeepReference reference, DeepReference expressionReference, Function function, Fractal f, MantExpComplex z, MantExpComplex c, int maxRefIteration) { + + if(expressionReference.compressed) { + throw new UnsupportedOperationException("This reference is already compressed."); + } + + if(reference.length != expressionReference.length) { + throw new UnsupportedOperationException("Invalid length"); + } + + CompressedDeepReference cref = new CompressedDeepReference(reference.length, reference.lengthOverride); + + MantExpComplex CorrectVal, CalculatedVal; + + //Do the compression + + int length = Math.min(maxRefIteration, reference.length - 1); + boolean twoExponents = TaskDraw.MANTEXPCOMPLEX_FORMAT == 1; + + + int compressed_index = 0; + for (int i = 0; i <= length; i++) { + if(reference.useWaypoint(compressed_index, i)) { + z = reference.getWaypointData(compressed_index); + compressed_index++; + } + else if (i > 0) { + z = f.function(z, c); + } + + if (twoExponents) { + CorrectVal = new MantExpComplexFull(expressionReference.exps[i], expressionReference.expsIm[i], expressionReference.mantsRe[i], expressionReference.mantsIm[i]); + } else { + CorrectVal = new MantExpComplex(expressionReference.exps[i], expressionReference.mantsRe[i], expressionReference.mantsIm[i]); + } + CalculatedVal = function.apply(z); + CalculatedVal.Normalize(); + + if (CalculatedVal.sub(CorrectVal).times_mutable(CompressionErrorInvertedm).chebyshevNorm().compareToBothPositiveReduced(CorrectVal.chebyshevNorm()) > 0) { + cref.addWaypoint(new Waypoint(MantExpComplex.copy(CorrectVal), i)); + } + + } + + cref.compact(); + + return cref; + + } + + @Deprecated + public static CompressedDeepReference compressReferenceWithExpression(DeepReference reference, DeepReference expressionReference, Function function, int maxRefIteration) { + + if(reference.compressed) { + throw new UnsupportedOperationException("This reference is already compressed."); + } + + if(expressionReference.compressed) { + throw new UnsupportedOperationException("This reference is already compressed."); + } + + if(reference.length != expressionReference.length) { + throw new UnsupportedOperationException("Invalid length"); + } + + CompressedDeepReference cref = new CompressedDeepReference(reference.length, reference.lengthOverride); + + MantExpComplex CorrectVal, CalculatedVal; + + //Do the compression + + int length = Math.min(maxRefIteration, reference.length - 1); + boolean twoExponents = TaskDraw.MANTEXPCOMPLEX_FORMAT == 1; + + for (int i = 0; i <= length; i++) { + + if (twoExponents) { + CorrectVal = new MantExpComplexFull(expressionReference.exps[i], expressionReference.expsIm[i], expressionReference.mantsRe[i], expressionReference.mantsIm[i]); + CalculatedVal = function.apply(new MantExpComplexFull(reference.exps[i], reference.expsIm[i], reference.mantsRe[i], reference.mantsIm[i])); + } else { + CorrectVal = new MantExpComplex(expressionReference.exps[i], expressionReference.mantsRe[i], expressionReference.mantsIm[i]); + CalculatedVal = function.apply(new MantExpComplex(reference.exps[i], reference.mantsRe[i], reference.mantsIm[i])); + } + + CalculatedVal.Normalize(); + + if (CalculatedVal.sub(CorrectVal).times_mutable(CompressionErrorInvertedm).chebyshevNorm().compareToBothPositiveReduced(CorrectVal.chebyshevNorm()) > 0) { + cref.addWaypoint(new Waypoint(MantExpComplex.copy(CorrectVal), i)); + } + + } + + cref.compact(); + + return cref; + + } + + //maxRefIteration should be +1 + public static CompressedDoubleReference compressReferenceWithExpression(CompressedDoubleReference reference, DoubleReference expressionReference, Function function, Fractal f, Complex z, Complex c, int maxRefIteration) { + + if(expressionReference.compressed) { + throw new UnsupportedOperationException("This reference is already compressed."); + } + + if(reference.length != expressionReference.length) { + throw new UnsupportedOperationException("Invalid length"); + } + + CompressedDoubleReference cref = new CompressedDoubleReference(reference.length, reference.lengthOverride); + + Complex CorrectVal, CalculatedVal; + + //Do the compression + + int length = Math.min(maxRefIteration, reference.length - 1); + + + + int compressed_index = 0; + for (int i = 0; i <= length; i++) { + if(reference.useWaypoint(compressed_index, i)) { + z = reference.getWaypointData(compressed_index); + compressed_index++; + } + else if (i > 0){ + z = f.function(z, c); + } + + CorrectVal = new Complex(expressionReference.re[i], expressionReference.im[i]); + CalculatedVal = function.apply(z); + + if (CalculatedVal.sub(CorrectVal).chebyshevNorm() * CompressionErrorInverted > CorrectVal.chebyshevNorm()) { + cref.addWaypoint(new Waypoint(new Complex(CorrectVal), i)); + } + + } + + cref.compact(); + + return cref; + + } + + //maxRefIteration should be +1 + @Deprecated + public static CompressedDoubleReference compressReferenceWithExpression(DoubleReference reference, DoubleReference expressionReference, Function function, int maxRefIteration) { + + if(reference.compressed) { + throw new UnsupportedOperationException("This reference is already compressed."); + } + + if(expressionReference.compressed) { + throw new UnsupportedOperationException("This reference is already compressed."); + } + + if(reference.length != expressionReference.length) { + throw new UnsupportedOperationException("The references must have the same length."); + } + + CompressedDoubleReference cref = new CompressedDoubleReference(reference.length, reference.lengthOverride); + + Complex CorrectVal, CalculatedVal; + + //Do the compression + + int length = Math.min(maxRefIteration, reference.length - 1); + + for (int i = 0; i <= length; i++) { + CorrectVal = new Complex(expressionReference.re[i], expressionReference.im[i]); + CalculatedVal = function.apply(new Complex(reference.re[i], reference.im[i])); + + if (CalculatedVal.sub(CorrectVal).chebyshevNorm() * CompressionErrorInverted > CorrectVal.chebyshevNorm()) { + cref.addWaypoint(new Waypoint(new Complex(CorrectVal), i)); + } + + } + + cref.compact(); + + return cref; + + } + + + //maxRefIteration should be +1 + public static CompressedDoubleReference compressReferenceSimple(Fractal f, DoubleReference reference, Complex z, Complex c, int maxRefIteration) { + + if(reference.compressed) { + throw new UnsupportedOperationException("This reference is already compressed."); + } + + CompressedDoubleReference cref = new CompressedDoubleReference(reference.length, reference.lengthOverride); + + Complex Z; + + int length = Math.min(maxRefIteration, reference.length - 1); + + //Do the compression + + for (int i = 0; i <= length; i++) { + Z = new Complex(reference.re[i], reference.im[i]); + + if (z.sub(Z).chebyshevNorm() * CompressionErrorInverted > Z.chebyshevNorm()) { + z = Z; + cref.addWaypoint(new Waypoint(new Complex(Z), i)); + } + + z = f.function(z, c); + } + + cref.compact(); + + return cref; + + } + + public static CompressedDeepReference compressReferenceExtended(Fractal f, DeepReference reference, MantExpComplex c, int maxRefIteration) { + + if(!f.supportsExtendedReferenceCompression()) { + throw new UnsupportedOperationException("This compression only works for mandelbrot."); + } + + if(reference.compressed) { + throw new UnsupportedOperationException("This reference is already compressed."); + } + + CompressedDeepReference cref = new CompressedDeepReference(reference.length, reference.lengthOverride); + cref.setCompressedExtended(true); + + MantExpComplex Z; + + int i = 1; + MantExpComplex z = MantExpComplex.copy(c); + + boolean twoExponents = TaskDraw.MANTEXPCOMPLEX_FORMAT == 1; + + int length = Math.min(maxRefIteration, reference.length - 1); + + for (; i <= length; i++) { + if(twoExponents) { + Z = new MantExpComplexFull(reference.exps[i], reference.expsIm[i], reference.mantsRe[i], reference.mantsIm[i]); + } + else { + Z = new MantExpComplex(reference.exps[i], reference.mantsRe[i], reference.mantsIm[i]); + } + + MantExp norm = Z.chebyshevNorm(); + + if(norm.compareToBothPositiveReduced(limit1m) < 0) { + z = Z; + cref.addWaypoint(new Waypoint(MantExpComplex.copy(Z), i, true)); + break; + } + else if (z.sub(Z).times_mutable(CompressionErrorInvertedm).chebyshevNorm().compareToBothPositiveReduced(norm) > 0) { + z = Z; + cref.addWaypoint(new Waypoint(MantExpComplex.copy(Z), i, false)); + } + + z = f.function(z, c); + z.Normalize(); + } + + MantExpComplex dz = MantExpComplex.copy(z); + int PrevWayPointIteration = i; + dz = f.perturbationFunction(dz, reference, 0); + dz.Normalize(); + i++; + int j = 1; + + MantExpComplex Zi, Zj; + for (; i <= length; i++, j++) { + + if(twoExponents) { + Zj = new MantExpComplexFull(reference.exps[j], reference.expsIm[j], reference.mantsRe[j], reference.mantsIm[j]); + } + else { + Zj = new MantExpComplex(reference.exps[j], reference.mantsRe[j], reference.mantsIm[j]); + } + + z = dz.plus(Zj); + z.Normalize(); + + if(twoExponents) { + Zi = new MantExpComplexFull(reference.exps[i], reference.expsIm[i], reference.mantsRe[i], reference.mantsIm[i]); + } + else { + Zi = new MantExpComplex(reference.exps[i], reference.mantsRe[i], reference.mantsIm[i]); + } + + if(j >= PrevWayPointIteration || z.sub(Zi).times_mutable(CompressionErrorInvertedm).chebyshevNorm().compareToBothPositiveReduced(Zi.chebyshevNorm()) > 0) { // TODO: Use a different threshold for uncorrectable parts of the orbit. + PrevWayPointIteration = i; + z = Zi; + dz = z.sub(Zj); + dz.Normalize(); + + if(z.chebyshevNorm().compareToBothPositiveReduced(dz.chebyshevNorm()) < 0 || (i - j) * 4 < i) {// TODO: Improve second condition + dz = z; + j = 0; + cref.addWaypoint(new Waypoint(MantExpComplex.copy(dz), i, true)); + } + else { + cref.addWaypoint(new Waypoint(MantExpComplex.copy(dz), i, false)); + } + } + else if(z.chebyshevNorm().compareToBothPositiveReduced(dz.times(limit2m).chebyshevNorm()) < 0 ) { + dz = z; + j = 0; + + int rebasesLength = cref.rebasesListLength(); + if(rebasesLength > 0 && cref.getRebaseFromListAtIndex(rebasesLength - 1) > cref.getWaypointListIteration(cref.compressedListLength() - 1)) { + cref.setRebaseAt(rebasesLength - 1, i); + } + else { + cref.addRebase(i); + } + } + + dz = f.perturbationFunction(dz, reference, j); + dz.Normalize(); + } + + cref.addWaypoint(new Waypoint(MantExpComplex.create(), Integer.MAX_VALUE, false)); + cref.addRebase(Integer.MAX_VALUE); + + cref.compactExtended(); + + return cref; + + } + + public static CompressedDoubleReference compressReferenceExtended(Fractal f, DoubleReference reference, Complex c, int maxRefIteration) { + + if(!f.supportsExtendedReferenceCompression()) { + throw new UnsupportedOperationException("This compression only works for mandelbrot."); + } + + if(reference.compressed) { + throw new UnsupportedOperationException("This reference is already compressed."); + } + + CompressedDoubleReference cref = new CompressedDoubleReference(reference.length, reference.lengthOverride); + cref.setCompressedExtended(true); + + Complex Z; + + int i = 1; + Complex z = new Complex(c); + + int length = Math.min(maxRefIteration, reference.length - 1); + + for (; i <= length; i++) { + Z = new Complex(reference.re[i], reference.im[i]); + + double norm = Z.chebyshevNorm(); + + if(norm < limit1) { + z = Z; + cref.addWaypoint(new Waypoint(new Complex(Z), i, true)); + break; + } + else if (z.sub(Z).chebyshevNorm() * CompressionErrorInverted > norm) { + z = Z; + cref.addWaypoint(new Waypoint(new Complex(Z), i, false)); + } + + z = f.function(z, c); + } + + Complex dz = new Complex(z); + int PrevWayPointIteration = i; + dz = f.perturbationFunction(dz, reference, 0); + i++; + int j = 1; + + Complex Zi, Zj; + for (; i <= length; i++, j++) { + Zj = new Complex(reference.re[j], reference.im[j]); + z = dz.plus(Zj); + Zi = new Complex(reference.re[i], reference.im[i]); + if(j >= PrevWayPointIteration || z.sub(Zi).chebyshevNorm() * CompressionErrorInverted > Zi.chebyshevNorm()) { // TODO: Use a different threshold for uncorrectable parts of the orbit. + PrevWayPointIteration = i; + z = Zi; + dz = z.sub(Zj); + + if(z.chebyshevNorm() < dz.chebyshevNorm() || (i - j) * 4 < i) {// TODO: Improve second condition + dz = z; + j = 0; + cref.addWaypoint(new Waypoint(new Complex(dz), i, true)); + } + else { + cref.addWaypoint(new Waypoint(new Complex(dz), i, false)); + } + } + else if(z.chebyshevNorm() < dz.chebyshevNorm() * limit2) { + dz = z; + j = 0; + + int rebasesLength = cref.rebasesListLength(); + if(rebasesLength > 0 && cref.getRebaseFromListAtIndex(rebasesLength - 1) > cref.getWaypointListIteration(cref.compressedListLength() - 1)) { + cref.setRebaseAt(rebasesLength - 1, i); + } + else { + cref.addRebase(i); + } + } + + dz = f.perturbationFunction(dz, reference, j); + } + + cref.addWaypoint(new Waypoint(new Complex(), Integer.MAX_VALUE, false)); + cref.addRebase(Integer.MAX_VALUE); + + cref.compactExtended(); + + return cref; + + } + + public static CompressedDeepReference compressReferenceSimple(Fractal f, DeepReference reference, MantExpComplex z, MantExpComplex c, int maxRefIteration) { + + if(reference.compressed) { + throw new UnsupportedOperationException("This reference is already compressed."); + } + + CompressedDeepReference cref = new CompressedDeepReference(reference.length, reference.lengthOverride); + + MantExpComplex Z; + + //Do the compression + + boolean twoExponents = TaskDraw.MANTEXPCOMPLEX_FORMAT == 1; + + int length = Math.min(maxRefIteration, reference.length - 1); + + for (int i = 0; i <= length; i++) { + if(twoExponents) { + Z = new MantExpComplexFull(reference.exps[i], reference.expsIm[i], reference.mantsRe[i], reference.mantsIm[i]); + } + else { + Z = new MantExpComplex(reference.exps[i], reference.mantsRe[i], reference.mantsIm[i]); + } + + if (z.sub(Z).times_mutable(CompressionErrorInvertedm).chebyshevNorm().compareToBothPositiveReduced(Z.chebyshevNorm()) > 0) { + z = Z; + cref.addWaypoint(new Waypoint(MantExpComplex.copy(Z), i)); + } + + z = f.function(z, c); + z.Normalize(); + } + + cref.compact(); + + return cref; + + } + + public Complex setArrayValue(DoubleReference ref, int iteration, Complex Z) { + CompressedDoubleReference cref = (CompressedDoubleReference) ref; + if (z.sub(Z).chebyshevNorm() * CompressionErrorInverted > Z.chebyshevNorm()) { + z.assign(Z); + cref.addWaypoint(new Waypoint(new Complex(Z), iteration)); + } + + Complex result = new Complex(z); + z = f.function(z, c); + + return result; + } + + public MantExpComplex setArrayDeepValue(DeepReference ref, int iteration, MantExpComplex Z) { + CompressedDeepReference cref = (CompressedDeepReference) ref; + if (mz.sub(Z).times_mutable(CompressionErrorInvertedm).chebyshevNorm().compareToBothPositiveReduced(Z.chebyshevNorm()) > 0) { + mz.assign(Z); + cref.addWaypoint(new Waypoint(MantExpComplex.copy(Z), iteration)); + } + + MantExpComplex result = MantExpComplex.copy(mz); + mz = f.function(mz, mc); + mz.Normalize(); + + return result; + } + + public void setArrayValue(DoubleReference ref, int iteration, Complex CorrectVal, Complex refZ) { + CompressedDoubleReference cref = (CompressedDoubleReference) ref; + Complex CalculatedVal = function.apply(refZ); + if (CalculatedVal.sub(CorrectVal).chebyshevNorm() * CompressionErrorInverted > CorrectVal.chebyshevNorm()) { + cref.addWaypoint(new Waypoint(new Complex(CorrectVal), iteration)); + } + } + + public void setArrayDeepValue(DeepReference ref, int iteration, MantExpComplex CorrectVal, MantExpComplex refZ) { + CompressedDeepReference cref = (CompressedDeepReference) ref; + + MantExpComplex CalculatedVal = functionm.apply(refZ); + CalculatedVal.Normalize(); + + if (CalculatedVal.sub(CorrectVal).times_mutable(CompressionErrorInvertedm).chebyshevNorm().compareToBothPositiveReduced(CorrectVal.chebyshevNorm()) > 0) { + cref.addWaypoint(new Waypoint(MantExpComplex.copy(CorrectVal), iteration)); + } + } + + public Complex getZ() { + return z; + } + + public MantExpComplex getZDeep() { + return mz; + } + + public void compact(DoubleReference ref) { + CompressedDoubleReference cref = (CompressedDoubleReference) ref; + cref.compact(); + } + + public void compact(DeepReference ref) { + CompressedDeepReference cref = (CompressedDeepReference) ref; + cref.compact(); + } + + public static void createLowPrecisionOrbit(CompressedDoubleReference ref, CompressedDeepReference cref) { + int length = cref.compressedLength(); + for(int i = 0; i < length; i++) { + Waypoint w = cref.getWaypoint(i); + ref.addWaypoint(new Waypoint(w.mz.toComplex(), w.iteration)); + } + ref.compact(); + } + + public void reset() { + if(initVal != null) { + z = new Complex(initVal); + } + + if(initValm != null) { + mz = MantExpComplex.copy(initValm); + } + } + + /* + if(deepZoom) { + CompressedDeepReference test = ReferenceCompressor.compressExtended(this, referenceDeep, refPointSmallDeep, referenceData.MaxRefIteration + 1); + CompressedDeepReference test2 = ReferenceCompressor.compressSimple(this, referenceDeep, MantExpComplex.create(), refPointSmallDeep, referenceData.MaxRefIteration + 1); + + DeepReference test3 = ReferenceDecompressor.uncompressSimple(this, test2, MantExpComplex.create(), refPointSmallDeep, referenceData.MaxRefIteration + 1); + DeepReference test4 = ReferenceDecompressor.uncompressExtended(this, test, MantExpComplex.create(), refPointSmallDeep, referenceData.MaxRefIteration + 1); + + MantExp maxError1 = new MantExp(-Double.MAX_VALUE); + int index1 = -1; + MantExpComplex origRef; + MantExpComplex newRef; + boolean twoExponents = TaskDraw.MANTEXPCOMPLEX_FORMAT == 1; + for (int i = 0; i <= referenceData.MaxRefIteration + 1; i++) { + + if(twoExponents) { + origRef = new MantExpComplexFull(referenceDeep.exps[i], referenceDeep.expsIm[i], referenceDeep.mantsRe[i], referenceDeep.mantsIm[i]); + newRef = new MantExpComplexFull(test3.exps[i], test3.expsIm[i], test3.mantsRe[i], test3.mantsIm[i]); + } + else { + origRef = new MantExpComplex(referenceDeep.exps[i], referenceDeep.mantsRe[i], referenceDeep.mantsIm[i]); + newRef = new MantExpComplex(test3.exps[i], test3.mantsRe[i], test3.mantsIm[i]); + } + + MantExp error = origRef.distance(newRef); + error.Normalize(); + if (error.compareTo(maxError1) > 0) { + maxError1 = error; + index1 = i; + } + } + + MantExp maxError2 = new MantExp(-Double.MAX_VALUE); + int index2 = -1; + for (int i = 0; i <= referenceData.MaxRefIteration + 1; i++) { + if(twoExponents) { + origRef = new MantExpComplexFull(referenceDeep.exps[i], referenceDeep.expsIm[i], referenceDeep.mantsRe[i], referenceDeep.mantsIm[i]); + newRef = new MantExpComplexFull(test4.exps[i], test4.expsIm[i], test4.mantsRe[i], test4.mantsIm[i]); + } + else { + origRef = new MantExpComplex(referenceDeep.exps[i], referenceDeep.mantsRe[i], referenceDeep.mantsIm[i]); + newRef = new MantExpComplex(test4.exps[i], test4.mantsRe[i], test4.mantsIm[i]); + } + + MantExp error = origRef.distance(newRef); + error.Normalize(); + + if (error.compareTo(maxError2) > 0) { + maxError2 = error; + index2 = i; + } + } + + System.out.println(maxError1 + " " + index1); + System.out.println(maxError2 + " " + index2); + } + */ +} diff --git a/src/fractalzoomer/core/ReferenceData.java b/src/fractalzoomer/core/ReferenceData.java index 7b3217157..4284100b4 100644 --- a/src/fractalzoomer/core/ReferenceData.java +++ b/src/fractalzoomer/core/ReferenceData.java @@ -2,10 +2,13 @@ import fractalzoomer.functions.Fractal; +import java.util.ArrayList; import java.util.stream.IntStream; public class ReferenceData { + public static int REFERENCE_DATA_COUNT = 4; public static final int MAX_PRECALCULATED_TERMS = 10; + public static final int SUBEXPRESSION_LENGTH = (1 + MAX_PRECALCULATED_TERMS); public DoubleReference Reference; public DoubleReference ReferenceSubCp; @@ -22,11 +25,17 @@ public class ReferenceData { public Complex dzdc; public MantExpComplex mdzdc; + public Complex compressorZ; + public MantExpComplex compressorZm; + public Complex period_dzdc; public MantExpComplex period_mdzdc; - public ReferenceData() { + public int id; + + public ReferenceData(int id) { PrecalculatedTerms = new DoubleReference[MAX_PRECALCULATED_TERMS]; + this.id = id; } public void clear() { @@ -73,79 +82,101 @@ public void deallocate() { Fractal.reference = null; } - public void createAndSetShortcut(int max_iterations, boolean needsRefSubCp, int precalCount) { - create(max_iterations, needsRefSubCp, precalCount); + public void createAndSetShortcut(int max_iterations, boolean needsRefSubCp, int precalCount, boolean compression) { + create(max_iterations, needsRefSubCp, precalCount, compression); Fractal.reference = Reference; } - public void createAndSetShortcut(int max_iterations, int cps, int precalCount) { - create(max_iterations, cps, precalCount); + /*public void createAndSetShortcut(int max_iterations, int cps, int precalCount, boolean compression) { + create(max_iterations, cps, precalCount, compression); Fractal.reference = Reference; } - public void createAndSetShortcut(int max_iterations, int cps, int[] indexes) { - create(max_iterations, cps, indexes); + public void createAndSetShortcut(int max_iterations, int cps, int[] indexes, boolean compression) { + create(max_iterations, cps, indexes, compression); Fractal.reference = Reference; - } + }*/ - public void createAndSetShortcut(int max_iterations, boolean needsRefSubCp, int[] indexes) { - create(max_iterations, needsRefSubCp, indexes); + public void createAndSetShortcut(int max_iterations, boolean needsRefSubCp, int[] indexes, boolean compression) { + create(max_iterations, needsRefSubCp, indexes, compression); Fractal.reference = Reference; } //Use this on julia ref - public void create(int max_iterations, boolean needsRefSubCp, int precalCount) { + public void create(int max_iterations, boolean needsRefSubCp, int precalCount, boolean compression) { int[] indexes = new int[0]; if(precalCount > 0) { indexes = IntStream.range(0, precalCount).toArray(); } - create(max_iterations, needsRefSubCp, indexes); + create(max_iterations, needsRefSubCp, indexes, compression); } - public void create(int max_iterations, int cps, int precalCount) { + /*public void create(int max_iterations, int cps, int precalCount, boolean compression) { int[] indexes = new int[0]; if(precalCount > 0) { indexes = IntStream.range(0, precalCount).toArray(); } - create(max_iterations, cps, indexes); - } + create(max_iterations, cps, indexes, compression); + }*/ - public void create(int max_iterations, boolean needsRefSubCp, int[] indexes) { - if(Reference == null || Reference.shouldCreateNew(max_iterations)) { - Reference = new DoubleReference(max_iterations); + public void create(int max_iterations, boolean needsRefSubCp, int[] indexes, boolean compression) { + if(compression) { + Reference = new CompressedDoubleReference(max_iterations); + Reference.id = id; } else { - Reference.reset(); + if (Reference == null || Reference.shouldCreateNew(max_iterations)) { + Reference = new DoubleReference(max_iterations); + Reference.id = id; + } else { + Reference.reset(); + } } if(needsRefSubCp) { - if(ReferenceSubCp == null || ReferenceSubCp.shouldCreateNew(max_iterations)) { - ReferenceSubCp = new DoubleReference(max_iterations); + if(compression) { + ReferenceSubCp = new CompressedDoubleReference(max_iterations); + ReferenceSubCp.id = id * SUBEXPRESSION_LENGTH; } else { - ReferenceSubCp.reset(); + if (ReferenceSubCp == null || ReferenceSubCp.shouldCreateNew(max_iterations)) { + ReferenceSubCp = new DoubleReference(max_iterations); + } else { + ReferenceSubCp.reset(); + } } } for(int i = 0; i < indexes.length; i++) { int index = indexes[i]; if(index < PrecalculatedTerms.length) { - if( PrecalculatedTerms[index] == null || PrecalculatedTerms[index].shouldCreateNew(max_iterations)) { - PrecalculatedTerms[index] = new DoubleReference(max_iterations); + if(compression) { + PrecalculatedTerms[index] = new CompressedDoubleReference(max_iterations); + PrecalculatedTerms[index].id = id * SUBEXPRESSION_LENGTH + (index + 1); } else { - PrecalculatedTerms[index].reset(); + if (PrecalculatedTerms[index] == null || PrecalculatedTerms[index].shouldCreateNew(max_iterations)) { + PrecalculatedTerms[index] = new DoubleReference(max_iterations); + } else { + PrecalculatedTerms[index].reset(); + } } } } } - public void create(int max_iterations, int cpsCount, int[] indexes) { - if(Reference == null || Reference.shouldCreateNew(max_iterations)) { - Reference = new DoubleReference(max_iterations); + /*public void create(int max_iterations, int cpsCount, int[] indexes, boolean compression) { + if(compression) { + Reference = new CompressedDoubleReference(max_iterations); + Reference.id = id; } else { - Reference.reset(); + if (Reference == null || Reference.shouldCreateNew(max_iterations)) { + Reference = new DoubleReference(max_iterations); + Reference.id = id; + } else { + Reference.reset(); + } } for(int i = 0; i < indexes.length; i++) { @@ -178,10 +209,11 @@ public void create(int max_iterations, int cpsCount, int[] indexes) { } } - } + }*/ public void setReference(DoubleReference Reference) { this.Reference = Reference; + Reference.id = id; Fractal.reference = Reference; } @@ -208,4 +240,28 @@ public void resize(int max_iterations) { } } } + + public ArrayList getWaypointsLength() { + ArrayList waypoints = new ArrayList<>(); + + if(Reference != null && Reference.compressed) { + waypoints.add(((CompressedDoubleReference)Reference).compressedLength()); + } + + if(ReferenceSubCp != null && ReferenceSubCp.compressed) { + waypoints.add(((CompressedDoubleReference)ReferenceSubCp).compressedLength()); + } + + for(int i = 0; i < PrecalculatedTerms.length; i++) { + if(PrecalculatedTerms[i] != null && PrecalculatedTerms[i].compressed) { + waypoints.add(((CompressedDoubleReference)PrecalculatedTerms[i]).compressedLength()); + } + } + + return waypoints; + } + + public boolean exists() { + return Reference != null; + } } diff --git a/src/fractalzoomer/core/ReferenceDecompressor.java b/src/fractalzoomer/core/ReferenceDecompressor.java new file mode 100644 index 000000000..11ad276fd --- /dev/null +++ b/src/fractalzoomer/core/ReferenceDecompressor.java @@ -0,0 +1,944 @@ +package fractalzoomer.core; + +import fractalzoomer.functions.Fractal; + +import java.util.function.Function; + +public class ReferenceDecompressor { + private Complex c; + private MantExpComplex mc; + + private Complex initVal; + private MantExpComplex initValm; + private Fractal f; + + private int prevIteration; + private Complex prevZ; + private MantExpComplex prevZm; + private long nextWaypointIteration; + private int currentWaypointIteration; + private int nextCompressedIndex; + + private int currentCompressIndex; + + private Waypoint currentWaypoint; + + private Function function; + private Function functionm; + + public ReferenceDecompressor(Function function) { + this.function = function; + prevIteration = Integer.MIN_VALUE; + nextWaypointIteration = Long.MIN_VALUE; + nextCompressedIndex = Integer.MIN_VALUE; + currentWaypointIteration = Integer.MIN_VALUE; + currentCompressIndex = Integer.MIN_VALUE; + currentWaypoint = null; + prevZ = new Complex(); + } + + public ReferenceDecompressor(Function function, boolean deep) { + this.functionm = function; + prevIteration = Integer.MIN_VALUE; + nextWaypointIteration = Long.MIN_VALUE; + nextCompressedIndex = Integer.MIN_VALUE; + currentWaypointIteration = Integer.MIN_VALUE; + currentCompressIndex = Integer.MIN_VALUE; + currentWaypoint = null; + prevZm = MantExpComplex.create(); + } + + public ReferenceDecompressor(ReferenceDecompressor other) { + if(other.c != null) { + this.c = new Complex(other.c); + } + if(other.initVal != null) { + this.initVal = new Complex(other.initVal); + } + if(other.mc != null) { + this.mc = MantExpComplex.copy(other.mc); + } + if(other.initValm != null) { + this.initValm = MantExpComplex.copy(other.initValm); + } + this.f = other.f; + this.functionm = other.functionm; + this.function = other.function; + + prevIteration = Integer.MIN_VALUE; + nextWaypointIteration = Long.MIN_VALUE; + nextCompressedIndex = Integer.MIN_VALUE; + currentWaypointIteration = Integer.MIN_VALUE; + currentCompressIndex = Integer.MIN_VALUE; + currentWaypoint = null; + prevZm = MantExpComplex.create(); + prevZ = new Complex(); + } + + public ReferenceDecompressor(Fractal f, Complex c, Complex initVal) { + this.c = c; + this.initVal = initVal; + this.f = f; + prevIteration = Integer.MIN_VALUE; + nextWaypointIteration = Long.MIN_VALUE; + nextCompressedIndex = Integer.MIN_VALUE; + currentWaypointIteration = Integer.MIN_VALUE; + currentCompressIndex = Integer.MIN_VALUE; + currentWaypoint = null; + prevZ = new Complex(); + } + + public ReferenceDecompressor(Fractal f, MantExpComplex mc, MantExpComplex initValm) { + this.f = f; + this.mc = mc; + this.initValm = initValm; + prevIteration = Integer.MIN_VALUE; + nextWaypointIteration = Long.MIN_VALUE; + nextCompressedIndex = Integer.MIN_VALUE; + currentWaypointIteration = Integer.MIN_VALUE; + currentCompressIndex = Integer.MIN_VALUE; + currentWaypoint = null; + prevZm = MantExpComplex.create(); + } + + //maxRefIteration should be +1 + public static DoubleReference uncompressReferenceSimple(Fractal f, CompressedDoubleReference cref, Complex z, Complex c, int maxRefIteration) { + + if(cref.isCompressedExtended()) { + throw new UnsupportedOperationException("Cannot uncompress due to different compression algorithm."); + } + + if(cref.length <= 0) { + throw new UnsupportedOperationException("Invalid length"); + } + + DoubleReference ref = new DoubleReference(cref.length, cref.lengthOverride); + + ref.re[0] = z.getRe(); + ref.im[0] = z.getIm(); + + int compressed_index = 0; + + int length = Math.min(maxRefIteration, ref.length - 1); + + for(int i = 1; i <= length; i++) { + if(cref.useWaypoint(compressed_index, i)) { + z = cref.getWaypointData(compressed_index); + compressed_index++; + } + else { + z = f.function(z, c); + } + + ref.re[i] = z.getRe(); + ref.im[i] = z.getIm(); + } + + return ref; + } + + //maxRefIteration should be +1 + @Deprecated + public static DoubleReference uncompressReferenceWithExpression(DoubleReference reference, CompressedDoubleReference cexprref, Function function, int maxRefIteration) { + + if(reference.compressed) { + throw new UnsupportedOperationException("This reference is compressed."); + } + + if(cexprref.isCompressedExtended()) { + throw new UnsupportedOperationException("Cannot uncompress due to different compression algorithm."); + } + + if(cexprref.length <= 0) { + throw new UnsupportedOperationException("Invalid length"); + } + + if(reference.length != cexprref.length) { + throw new UnsupportedOperationException("Invalid length"); + } + + DoubleReference output = new DoubleReference(cexprref.length, cexprref.lengthOverride); + + int compressed_index = 0; + + int length = Math.min(maxRefIteration, output.length - 1); + + Complex z; + + for(int i = 0; i <= length; i++) { + if(cexprref.useWaypoint(compressed_index, i)) { + z = cexprref.getWaypointData(compressed_index); + compressed_index++; + } + else { + z = function.apply(new Complex(reference.re[i], reference.im[i])); + } + + output.re[i] = z.getRe(); + output.im[i] = z.getIm(); + } + + return output; + } + + public static DoubleReference uncompressReferenceWithExpression(CompressedDoubleReference reference, CompressedDoubleReference cexprref, Function function, Fractal f, Complex z, Complex c, int maxRefIteration) { + + + if(reference.isCompressedExtended() || cexprref.isCompressedExtended()) { + throw new UnsupportedOperationException("Cannot uncompress due to different compression algorithm."); + } + + if(cexprref.length <= 0) { + throw new UnsupportedOperationException("Invalid length"); + } + + if(reference.length != cexprref.length) { + throw new UnsupportedOperationException("Invalid length"); + } + + DoubleReference output = new DoubleReference(cexprref.length, cexprref.lengthOverride); + + int compressed_index = 0; + int compressed_index2 = 0; + + int length = Math.min(maxRefIteration, output.length - 1); + + Complex exprz; + + for(int i = 0; i <= length; i++) { + if(reference.useWaypoint(compressed_index2, i)) { + z = reference.getWaypointData(compressed_index2); + compressed_index2++; + } + else if (i > 0) { + z = f.function(z, c); + } + + if(cexprref.useWaypoint(compressed_index, i)) { + exprz = cexprref.getWaypointData(compressed_index); + compressed_index++; + } + else { + exprz = function.apply(z); + } + + output.re[i] = exprz.getRe(); + output.im[i] = exprz.getIm(); + } + + return output; + } + + + //maxRefIteration should be +1 + @Deprecated + public static DeepReference uncompressReferenceWithExpression(DeepReference reference, CompressedDeepReference cexprref, Function function, int maxRefIteration) { + + if(reference.compressed) { + throw new UnsupportedOperationException("This reference is compressed."); + } + + if(cexprref.isCompressedExtended()) { + throw new UnsupportedOperationException("Cannot uncompress due to different compression algorithm."); + } + + if(cexprref.length <= 0) { + throw new UnsupportedOperationException("Invalid length"); + } + + if(reference.length != cexprref.length) { + throw new UnsupportedOperationException("Invalid length"); + } + + DeepReference output = new DeepReference(cexprref.length, cexprref.lengthOverride); + + int compressed_index = 0; + + int length = Math.min(maxRefIteration, output.length - 1); + + MantExpComplex z; + + boolean twoExponents = TaskDraw.MANTEXPCOMPLEX_FORMAT == 1; + + for(int i = 0; i <= length; i++) { + if(cexprref.useWaypoint(compressed_index, i)) { + z = cexprref.getWaypointData(compressed_index); + compressed_index++; + } + else { + if(twoExponents) { + z = function.apply(new MantExpComplexFull(reference.exps[i], reference.expsIm[i], reference.mantsRe[i], reference.mantsIm[i])); + } + else { + z = function.apply(new MantExpComplex(reference.exps[i], reference.mantsRe[i], reference.mantsIm[i])); + } + + z.Normalize(); + } + + output.exps[i] = z.getExp(); + output.mantsRe[i] = z.getMantissaReal(); + output.mantsIm[i] = z.getMantissaImag(); + if(twoExponents) { + output.expsIm[i] = z.getExpImag(); + } + } + + return output; + } + + public static DeepReference uncompressReferenceWithExpression(CompressedDeepReference reference, CompressedDeepReference cexprref, Function function, Fractal f, MantExpComplex z, MantExpComplex c, int maxRefIteration) { + + if(cexprref.isCompressedExtended() || reference.isCompressedExtended()) { + throw new UnsupportedOperationException("Cannot uncompress due to different compression algorithm."); + } + + if(cexprref.length <= 0) { + throw new UnsupportedOperationException("Invalid length"); + } + + if(reference.length != cexprref.length) { + throw new UnsupportedOperationException("Invalid length"); + } + + DeepReference output = new DeepReference(cexprref.length, cexprref.lengthOverride); + + int compressed_index = 0; + int compressed_index2 = 0; + + int length = Math.min(maxRefIteration, output.length - 1); + + MantExpComplex exprz; + + boolean twoExponents = TaskDraw.MANTEXPCOMPLEX_FORMAT == 1; + + for(int i = 0; i <= length; i++) { + if(reference.useWaypoint(compressed_index2, i)) { + z = reference.getWaypointData(compressed_index2); + compressed_index2++; + } + else if(i > 0) { + z = f.function(z, c); + z.Normalize(); + } + + if(cexprref.useWaypoint(compressed_index, i)) { + exprz = cexprref.getWaypointData(compressed_index); + compressed_index++; + } + else { + exprz = function.apply(z); + exprz.Normalize(); + } + + output.exps[i] = exprz.getExp(); + output.mantsRe[i] = exprz.getMantissaReal(); + output.mantsIm[i] = exprz.getMantissaImag(); + if(twoExponents) { + output.expsIm[i] = exprz.getExpImag(); + } + } + + return output; + } + private static double ScalingFactor = 0x1.0p-384; + private static void CorrectOrbit(DoubleReference ref, int Begin, int End, Complex diff) { + + Complex dzdc = new Complex(ScalingFactor, 0); + for (int i = End; i > Begin; ) { + i--; + dzdc.times_mutable(new Complex(ref.re[i], ref.im[i]).times2_mutable()); + Complex temp = diff.times(dzdc.conjugate().times_mutable(ScalingFactor / dzdc.norm_squared())); + ref.re[i] += temp.getRe(); + ref.im[i] += temp.getIm(); + } + } + + private static MantExp ScalingFactorm = new MantExp(ScalingFactor); + + private static void CorrectOrbit(DeepReference ref, int Begin, int End, MantExpComplex diff) { + MantExpComplex dzdc = MantExpComplex.create(ScalingFactorm, new MantExp()); + boolean twoExponents = TaskDraw.MANTEXPCOMPLEX_FORMAT == 1; + MantExpComplex Z; + for (int i = End; i > Begin; ) { + i--; + + if(twoExponents) { + Z = new MantExpComplexFull(ref.exps[i], ref.expsIm[i], ref.mantsRe[i], ref.mantsIm[i]); + } + else { + Z = new MantExpComplex(ref.exps[i], ref.mantsRe[i], ref.mantsIm[i]); + } + + dzdc.times_mutable(Z.times2()); + dzdc.Normalize(); + MantExpComplex temp = diff.times(dzdc.conjugate().times_mutable(ScalingFactorm.divide(dzdc.norm_squared()))); + temp.Normalize(); + Z.plus_mutable(temp); + Z.Normalize(); + + ref.mantsRe[i] = Z.getMantissaReal(); + ref.mantsIm[i] = Z.getMantissaImag(); + ref.exps[i] = Z.getExp(); + if(twoExponents) { + ref.expsIm[i] = Z.getExpImag(); + } + } + } + + public static DoubleReference uncompressReferenceExtended(Fractal f, CompressedDoubleReference cref, Complex z, Complex c, int maxRefIteration) { + + if(!f.supportsExtendedReferenceCompression()) { + throw new UnsupportedOperationException("This compression only works for mandelbrot"); + } + + if(!cref.isCompressedExtended()) { + throw new UnsupportedOperationException("Cannot uncompress due to different compression algorithm."); + } + + DoubleReference ref = new DoubleReference(cref.length, cref.lengthOverride); + + if(cref.compressedLength() == 0) { + throw new UnsupportedOperationException("Cannot uncompress due to corrupted compressed data."); + } + + int length = Math.min(maxRefIteration, ref.length - 1); + + int WayPointIndex = 0; + int RebaseIndex = 0; + Waypoint NextWayPoint = cref.getWaypointExtended(WayPointIndex); + int NextRebase = cref.getRebaseAtIndex(RebaseIndex); + + int i = 0; + int UncorrectedOrbitBegin = 1; + for (; i <= length; i++) + { + if (i == NextWayPoint.iteration) { + CorrectOrbit(ref, UncorrectedOrbitBegin, i, NextWayPoint.z.sub(z)); + UncorrectedOrbitBegin = i + 1; + z = NextWayPoint.z; + boolean Rebase = NextWayPoint.rebase; + WayPointIndex++; + NextWayPoint = cref.getWaypointExtended(WayPointIndex); + if (Rebase) { + break; + } + } + ref.re[i] = z.getRe(); + ref.im[i] = z.getIm(); + + z = f.function(z, c); + } + + int j = 0; + Complex dz = z; + for (; i <= length; i++, j++) { + z = dz.plus(new Complex(ref.re[j], ref.im[j])); + if(i == NextWayPoint.iteration) { + if (NextWayPoint.rebase) { + dz = z; + j = 0; + } + CorrectOrbit(ref, UncorrectedOrbitBegin, i, NextWayPoint.z.sub(dz)); + UncorrectedOrbitBegin = i + 1; + dz = NextWayPoint.z; + z = dz.plus(new Complex(ref.re[j], ref.im[j])); //Zj + WayPointIndex++; + NextWayPoint = cref.getWaypointExtended(WayPointIndex); + } + else if(i == NextRebase) { + RebaseIndex++; + NextRebase = cref.getRebaseAtIndex(RebaseIndex); + dz = z; + j = 0; + } + else if(z.chebyshevNorm() < dz.chebyshevNorm()) { + dz = z; + j = 0; + } + + ref.re[i] = z.getRe(); + ref.im[i] = z.getIm(); + + dz = f.perturbationFunction(dz, ref, j); + } + + return ref; + } + + public static DeepReference uncompressReferenceExtended(Fractal f, CompressedDeepReference cref, MantExpComplex z, MantExpComplex c, int maxRefIteration) { + + if(!f.supportsExtendedReferenceCompression()) { + throw new UnsupportedOperationException("This compression only works for mandelbrot"); + } + + if(!cref.isCompressedExtended()) { + throw new UnsupportedOperationException("Cannot uncompress due to different compression algorithm."); + } + + DeepReference ref = new DeepReference(cref.length, cref.lengthOverride); + + if(cref.compressedLength() == 0) { + throw new UnsupportedOperationException("Cannot uncompress due to corrupted compressed data."); + } + + int length = Math.min(maxRefIteration, ref.length - 1); + + int WayPointIndex = 0; + int RebaseIndex = 0; + Waypoint NextWayPoint = cref.getWaypointExtended(WayPointIndex); + int NextRebase = cref.getRebaseAtIndex(RebaseIndex); + + boolean twoExponents = TaskDraw.MANTEXPCOMPLEX_FORMAT == 1; + + int i = 0; + int UncorrectedOrbitBegin = 1; + for (; i <= length; i++) + { + if (i == NextWayPoint.iteration) { + CorrectOrbit(ref, UncorrectedOrbitBegin, i, NextWayPoint.mz.sub(z)); + UncorrectedOrbitBegin = i + 1; + z = NextWayPoint.mz; + boolean Rebase = NextWayPoint.rebase; + WayPointIndex++; + NextWayPoint = cref.getWaypointExtended(WayPointIndex); + if (Rebase) { + break; + } + } + + ref.mantsRe[i] = z.getMantissaReal(); + ref.mantsIm[i] = z.getMantissaImag(); + ref.exps[i] = z.getExp(); + if(twoExponents) { + ref.expsIm[i] = z.getExpImag(); + } + + z = f.function(z, c); + z.Normalize(); + } + + int j = 0; + MantExpComplex dz = z; + MantExpComplex Z; + for (; i <= length; i++, j++) { + if(twoExponents) { + Z = new MantExpComplexFull(ref.exps[j], ref.expsIm[j], ref.mantsRe[j], ref.mantsIm[j]); + } + else { + Z = new MantExpComplex(ref.exps[j], ref.mantsRe[j], ref.mantsIm[j]); + } + + z = dz.plus(Z); + z.Normalize(); + if(i == NextWayPoint.iteration) { + if (NextWayPoint.rebase) { + dz = z; + j = 0; + } + CorrectOrbit(ref, UncorrectedOrbitBegin, i, NextWayPoint.mz.sub(dz)); + UncorrectedOrbitBegin = i + 1; + dz = NextWayPoint.mz; + + if(twoExponents) { + Z = new MantExpComplexFull(ref.exps[j], ref.expsIm[j], ref.mantsRe[j], ref.mantsIm[j]); + } + else { + Z = new MantExpComplex(ref.exps[j], ref.mantsRe[j], ref.mantsIm[j]); + } + + z = dz.plus(Z); + z.Normalize(); + WayPointIndex++; + NextWayPoint = cref.getWaypointExtended(WayPointIndex); + } + else if(i == NextRebase) { + RebaseIndex++; + NextRebase = cref.getRebaseAtIndex(RebaseIndex); + dz = z; + j = 0; + } + else if(z.chebyshevNorm().compareToBothPositiveReduced(dz.chebyshevNorm()) < 0) { + dz = z; + j = 0; + } + + ref.mantsRe[i] = z.getMantissaReal(); + ref.mantsIm[i] = z.getMantissaImag(); + ref.exps[i] = z.getExp(); + if(twoExponents) { + ref.expsIm[i] = z.getExpImag(); + } + + dz = f.perturbationFunction(dz, ref, j); + dz.Normalize(); + } + + return ref; + } + + public static DeepReference uncompressReferenceSimple(Fractal f, CompressedDeepReference cref, MantExpComplex z, MantExpComplex c, int maxRefIteration) { + + if(cref.isCompressedExtended()) { + throw new UnsupportedOperationException("Cannot uncompress due to different compression algorithm."); + } + + if(cref.length <= 0) { + throw new UnsupportedOperationException("Invalid length"); + } + + DeepReference ref = new DeepReference(cref.length, cref.lengthOverride); + + boolean twoExponents = TaskDraw.MANTEXPCOMPLEX_FORMAT == 1; + + ref.exps[0] = z.getExp(); + ref.mantsRe[0] = z.getMantissaReal(); + ref.mantsIm[0] = z.getMantissaImag(); + + if(twoExponents) { + ref.expsIm[0] = z.getExpImag(); + } + + int compressed_index = 0; + + int length = Math.min(maxRefIteration, ref.length - 1); + + for(int i = 1; i <= length; i++) { + if(cref.useWaypoint(compressed_index, i)) { + z = cref.getWaypointData(compressed_index); + compressed_index++; + } + else { + z = f.function(z, c); + z.Normalize(); + } + + ref.exps[i] = z.getExp(); + ref.mantsRe[i] = z.getMantissaReal(); + ref.mantsIm[i] = z.getMantissaImag(); + + if(twoExponents) { + ref.expsIm[i] = z.getExpImag(); + } + } + + return ref; + } + + public MantExpComplex getArrayDeepValue(DeepReference array, int iteration) { + CompressedDeepReference cref = (CompressedDeepReference) array; + MantExpComplex z; + + if(iteration == prevIteration) { + z = MantExpComplex.copy(prevZm); + } + else if(iteration == nextWaypointIteration) { + currentCompressIndex = nextCompressedIndex; + currentWaypoint = cref.getWaypoint(currentCompressIndex); + nextCompressedIndex++; + + currentWaypointIteration = currentWaypoint.iteration; + + if(nextCompressedIndex < cref.compressedLength()) { + nextWaypointIteration = cref.getWaypointIteration(nextCompressedIndex); + } + else { + nextWaypointIteration = Long.MAX_VALUE; + } + + z = MantExpComplex.copy(currentWaypoint.mz); + } + else if(prevIteration >= 0 && iteration < nextWaypointIteration && iteration > prevIteration) { //sequential + int length = iteration - prevIteration; + z = MantExpComplex.copy(prevZm); + for(int i = 0; i < length; i++) { + z = f.function(z, mc); + z.Normalize(); + } + } + else { + if(iteration < currentWaypointIteration || iteration >= nextWaypointIteration) { + currentWaypoint = cref.getClosestWaypoint(iteration); //binary search + currentCompressIndex = currentWaypoint.index; + nextCompressedIndex = currentCompressIndex + 1; + + currentWaypointIteration = currentWaypoint.iteration; + + if (nextCompressedIndex < cref.compressedLength()) { + nextWaypointIteration = cref.getWaypointIteration(nextCompressedIndex); + } else { + nextWaypointIteration = Long.MAX_VALUE; + } + } + + if(currentWaypoint.mz == null) { + z = MantExpComplex.copy(initValm); + } + else { + z = MantExpComplex.copy(currentWaypoint.mz); + } + + for (int i = currentWaypointIteration; i < iteration; i++) { + z = f.function(z, mc); + z.Normalize(); + } + } + + prevZm.assign(z); + prevIteration = iteration; + + return z; + } + + public Complex getArrayValue(DoubleReference array, int iteration) { + + Complex z; + CompressedDoubleReference cref = (CompressedDoubleReference) array; + + if(iteration == prevIteration) { + z = new Complex(prevZ); + } + else if(iteration == nextWaypointIteration) { + currentCompressIndex = nextCompressedIndex; + currentWaypoint = cref.getWaypoint(currentCompressIndex); + nextCompressedIndex++; + + currentWaypointIteration = currentWaypoint.iteration; + + if (nextCompressedIndex < cref.compressedLength()) { + nextWaypointIteration = cref.getWaypointIteration(nextCompressedIndex); + } else { + nextWaypointIteration = Long.MAX_VALUE; + } + + z = new Complex(currentWaypoint.z); + } + else if(prevIteration >= 0 && iteration < nextWaypointIteration && iteration > prevIteration) { //sequential + int length = iteration - prevIteration; + z = new Complex(prevZ); + for(int i = 0; i < length; i++) { + z = f.function(z, c); + } + } + else { + + if(iteration < currentWaypointIteration || iteration >= nextWaypointIteration) { + currentWaypoint = cref.getClosestWaypoint(iteration); //binary search + currentCompressIndex = currentWaypoint.index; + nextCompressedIndex = currentCompressIndex + 1; + + currentWaypointIteration = currentWaypoint.iteration; + + if (nextCompressedIndex < cref.compressedLength()) { + nextWaypointIteration = cref.getWaypointIteration(nextCompressedIndex); + } else { + nextWaypointIteration = Long.MAX_VALUE; + } + } + + if(currentWaypoint.z == null) { + z = new Complex(initVal); + } + else { + z = new Complex(currentWaypoint.z); + } + + for (int i = currentWaypointIteration; i < iteration; i++) { + z = f.function(z, c); + } + } + + prevZ.assign(z); + prevIteration = iteration; + + return z; + + } + + public Complex getArrayValue(DoubleReference array, int iteration, Complex refZ) { + + Complex z; + CompressedDoubleReference cref = (CompressedDoubleReference) array; + + if(iteration == prevIteration) { + z = new Complex(prevZ); + } + else if(iteration == nextWaypointIteration) { + currentCompressIndex = nextCompressedIndex; + currentWaypoint = cref.getWaypoint(currentCompressIndex); + nextCompressedIndex++; + + currentWaypointIteration = currentWaypoint.iteration; + + if (nextCompressedIndex < cref.compressedLength()) { + nextWaypointIteration = cref.getWaypointIteration(nextCompressedIndex); + } else { + nextWaypointIteration = Long.MAX_VALUE; + } + + z = new Complex(currentWaypoint.z); + } + else { + + if(iteration < currentWaypointIteration || iteration >= nextWaypointIteration) { + currentWaypoint = cref.getClosestWaypoint(iteration); //binary search + currentCompressIndex = currentWaypoint.index; + nextCompressedIndex = currentCompressIndex + 1; + + currentWaypointIteration = currentWaypoint.iteration; + + if (nextCompressedIndex < cref.compressedLength()) { + nextWaypointIteration = cref.getWaypointIteration(nextCompressedIndex); + } else { + nextWaypointIteration = Long.MAX_VALUE; + } + } + + if(iteration != currentWaypointIteration || currentWaypoint.z == null) { + z = function.apply(refZ); + } + else { + z = new Complex(currentWaypoint.z); + } + } + + prevZ.assign(z); + prevIteration = iteration; + + return z; + + } + + public MantExpComplex getArrayDeepValue(DeepReference array, int iteration, MantExpComplex refZ) { + + MantExpComplex z; + CompressedDeepReference cref = (CompressedDeepReference) array; + + if(iteration == prevIteration) { + z = MantExpComplex.copy(prevZm); + } + else if(iteration == nextWaypointIteration) { + currentCompressIndex = nextCompressedIndex; + currentWaypoint = cref.getWaypoint(currentCompressIndex); + nextCompressedIndex++; + + currentWaypointIteration = currentWaypoint.iteration; + + if (nextCompressedIndex < cref.compressedLength()) { + nextWaypointIteration = cref.getWaypointIteration(nextCompressedIndex); + } else { + nextWaypointIteration = Long.MAX_VALUE; + } + + z = MantExpComplex.copy(currentWaypoint.mz); + } + else { + + if(iteration < currentWaypointIteration || iteration >= nextWaypointIteration) { + currentWaypoint = cref.getClosestWaypoint(iteration); //binary search + currentCompressIndex = currentWaypoint.index; + nextCompressedIndex = currentCompressIndex + 1; + + currentWaypointIteration = currentWaypoint.iteration; + + if (nextCompressedIndex < cref.compressedLength()) { + nextWaypointIteration = cref.getWaypointIteration(nextCompressedIndex); + } else { + nextWaypointIteration = Long.MAX_VALUE; + } + } + + if(iteration != currentWaypointIteration || currentWaypoint.z == null) { + z = functionm.apply(refZ); + z.Normalize(); + } + else { + z = MantExpComplex.copy(currentWaypoint.mz); + } + } + + prevZm.assign(z); + prevIteration = iteration; + + return z; + + } + + + //when using a single decompressor on a multithreaded level + public MantExpComplex getArrayDeepValueRandomAccess(DeepReference array, int iteration) { + CompressedDeepReference cref = (CompressedDeepReference) array; + Waypoint waypoint = cref.getClosestWaypoint(iteration); //binary search + MantExpComplex z; + + if(waypoint.mz == null) { + z = MantExpComplex.copy(initValm); + } + else { + z = waypoint.mz; + } + + for (int i = waypoint.iteration; i < iteration; i++) { + z = f.function(z, mc); + z.Normalize(); + } + + return z; + } + + //when using a single decompressor on a multithreaded level + public Complex getArrayValueRandomAccess(DoubleReference array, int iteration) { + CompressedDoubleReference cref = (CompressedDoubleReference) array; + Waypoint waypoint = cref.getClosestWaypoint(iteration); //binary search + Complex z; + + if(waypoint.z == null) { + z = new Complex(initVal); + } + else { + z = waypoint.z; + } + + for (int i = waypoint.iteration; i < iteration; i++) { + z = f.function(z, c); + } + + return z; + } + + public MantExpComplex getArrayDeepValueRandomAccess(DeepReference array, int iteration, MantExpComplex refZ) { + + CompressedDeepReference cref = (CompressedDeepReference) array; + + Waypoint waypoint = cref.findWaypoint(iteration); + + MantExpComplex z; + if(waypoint == null) { + z = functionm.apply(refZ); + } + else { + z = waypoint.mz; + } + + return z; + + } + + public Complex getArrayValueRandomAccess(DoubleReference array, int iteration, Complex refZ) { + + CompressedDoubleReference cref = (CompressedDoubleReference) array; + + Waypoint waypoint = cref.findWaypoint(iteration); + + Complex z; + if(waypoint == null) { + z = function.apply(refZ); + } + else { + z = waypoint.z; + } + + return z; + + } +} diff --git a/src/fractalzoomer/core/ReferenceDeepData.java b/src/fractalzoomer/core/ReferenceDeepData.java index 258ca1d34..60aa74235 100644 --- a/src/fractalzoomer/core/ReferenceDeepData.java +++ b/src/fractalzoomer/core/ReferenceDeepData.java @@ -2,9 +2,10 @@ import fractalzoomer.functions.Fractal; +import java.util.ArrayList; import java.util.stream.IntStream; -import static fractalzoomer.core.ReferenceData.MAX_PRECALCULATED_TERMS; +import static fractalzoomer.core.ReferenceData.*; public class ReferenceDeepData { @@ -12,10 +13,12 @@ public class ReferenceDeepData { public DeepReference ReferenceSubCp; public DeepReference[] PrecalculatedTerms; public DeepReference[] ReferenceSubCps; + public int id; - public ReferenceDeepData() { + public ReferenceDeepData(int id) { PrecalculatedTerms = new DeepReference[MAX_PRECALCULATED_TERMS]; + this.id = id; } public void clear() { @@ -39,79 +42,102 @@ public void deallocate() { Fractal.referenceDeep = null; } - public void createAndSetShortcut(int max_iterations, boolean needsRefSubCp, int precalCount) { - create(max_iterations, needsRefSubCp, precalCount); + public void createAndSetShortcut(int max_iterations, boolean needsRefSubCp, int precalCount, boolean compress) { + create(max_iterations, needsRefSubCp, precalCount, compress); Fractal.referenceDeep = Reference; } - public void createAndSetShortcut(int max_iterations, boolean needsRefSubCp, int[] indexes) { - create(max_iterations, needsRefSubCp, indexes); + public void createAndSetShortcut(int max_iterations, boolean needsRefSubCp, int[] indexes, boolean compress) { + create(max_iterations, needsRefSubCp, indexes, compress); Fractal.referenceDeep = Reference; } - public void createAndSetShortcut(int max_iterations, int cps, int precalCount) { - create(max_iterations, cps, precalCount); + /*public void createAndSetShortcut(int max_iterations, int cps, int precalCount, boolean compression) { + create(max_iterations, cps, precalCount, compression); Fractal.referenceDeep = Reference; } - public void createAndSetShortcut(int max_iterations, int cps, int[] indexes) { - create(max_iterations, cps, indexes); + public void createAndSetShortcut(int max_iterations, int cps, int[] indexes, boolean compression) { + create(max_iterations, cps, indexes, compression); Fractal.referenceDeep = Reference; - } + }*/ - public void create(int max_iterations, boolean needsRefSubCp, int precalCount) { + public void create(int max_iterations, boolean needsRefSubCp, int precalCount, boolean compress) { int[] indexes = new int[0]; if(precalCount > 0) { indexes = IntStream.range(0, precalCount).toArray(); } - create(max_iterations, needsRefSubCp, indexes); + create(max_iterations, needsRefSubCp, indexes, compress); } - public void create(int max_iterations, int cps, int precalCount) { + /*public void create(int max_iterations, int cps, int precalCount, boolean compression) { int[] indexes = new int[0]; if(precalCount > 0) { indexes = IntStream.range(0, precalCount).toArray(); } - create(max_iterations, cps, indexes); - } + create(max_iterations, cps, indexes, compression); + }*/ //Use this on julia ref - public void create(int max_iterations, boolean needsRefSubCp, int[] indexes) { - if(Reference == null || Reference.shouldCreateNew(max_iterations)) { - Reference = new DeepReference(max_iterations); + public void create(int max_iterations, boolean needsRefSubCp, int[] indexes, boolean compression) { + + if(compression) { + Reference = new CompressedDeepReference(max_iterations); + Reference.id = id; } else { - Reference.reset(); + if (Reference == null || Reference.shouldCreateNew(max_iterations)) { + Reference = new DeepReference(max_iterations); + Reference.id = id; + } else { + Reference.reset(); + } } if(needsRefSubCp) { - if(ReferenceSubCp == null || ReferenceSubCp.shouldCreateNew(max_iterations)) { - ReferenceSubCp = new DeepReference(max_iterations); + if(compression) { + ReferenceSubCp = new CompressedDeepReference(max_iterations); + ReferenceSubCp.id = id * SUBEXPRESSION_LENGTH; } else { - ReferenceSubCp.reset(); + if (ReferenceSubCp == null || ReferenceSubCp.shouldCreateNew(max_iterations)) { + ReferenceSubCp = new DeepReference(max_iterations); + } else { + ReferenceSubCp.reset(); + } } } for(int i = 0; i < indexes.length; i++) { int index = indexes[i]; if(index < PrecalculatedTerms.length) { - if( PrecalculatedTerms[index] == null || PrecalculatedTerms[index].shouldCreateNew(max_iterations)) { - PrecalculatedTerms[index] = new DeepReference(max_iterations); + if(compression) { + PrecalculatedTerms[index] = new CompressedDeepReference(max_iterations); + PrecalculatedTerms[index].id = id * SUBEXPRESSION_LENGTH + (index + 1); } else { - PrecalculatedTerms[index].reset(); + if (PrecalculatedTerms[index] == null || PrecalculatedTerms[index].shouldCreateNew(max_iterations)) { + PrecalculatedTerms[index] = new DeepReference(max_iterations); + } else { + PrecalculatedTerms[index].reset(); + } } } } } - public void create(int max_iterations, int cpsCount, int[] indexes) { - if(Reference == null || Reference.shouldCreateNew(max_iterations)) { - Reference = new DeepReference(max_iterations); + /*public void create(int max_iterations, int cpsCount, int[] indexes, boolean compression) { + if(compression) { + Reference = new CompressedDeepReference(max_iterations); + Reference.id = id; } else { - Reference.reset(); + if (Reference == null || Reference.shouldCreateNew(max_iterations)) { + Reference = new DeepReference(max_iterations); + Reference.id = id; + } else { + Reference.reset(); + } } for(int i = 0; i < indexes.length; i++) { @@ -143,10 +169,11 @@ public void create(int max_iterations, int cpsCount, int[] indexes) { } } } - } + }*/ public void setReference(DeepReference Reference) { this.Reference = Reference; + Reference.id = id; Fractal.referenceDeep = Reference; } @@ -173,4 +200,28 @@ public void resize(int max_iterations) { } } } + + public ArrayList getWaypointsLength() { + ArrayList waypoints = new ArrayList<>(); + + if(Reference != null && Reference.compressed) { + waypoints.add(((CompressedDeepReference)Reference).compressedLength()); + } + + if(ReferenceSubCp != null && ReferenceSubCp.compressed) { + waypoints.add(((CompressedDeepReference)ReferenceSubCp).compressedLength()); + } + + for(int i = 0; i < PrecalculatedTerms.length; i++) { + if(PrecalculatedTerms[i] != null && PrecalculatedTerms[i].compressed) { + waypoints.add(((CompressedDeepReference)PrecalculatedTerms[i]).compressedLength()); + } + } + + return waypoints; + } + + public boolean exists() { + return Reference != null; + } } diff --git a/src/fractalzoomer/core/TaskDraw.java b/src/fractalzoomer/core/TaskDraw.java index fc8a131d2..59c69b157 100644 --- a/src/fractalzoomer/core/TaskDraw.java +++ b/src/fractalzoomer/core/TaskDraw.java @@ -111,6 +111,7 @@ import fractalzoomer.functions.szegedi_butterfly.SzegediButterfly1; import fractalzoomer.functions.szegedi_butterfly.SzegediButterfly2; import fractalzoomer.functions.user_formulas.*; +import fractalzoomer.main.CommonFunctions; import fractalzoomer.main.Constants; import fractalzoomer.main.ImageExpanderWindow; import fractalzoomer.main.MainWindow; @@ -138,6 +139,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.LongAccumulator; import java.util.concurrent.atomic.LongAdder; +import java.util.stream.Collectors; /** * @@ -188,16 +190,58 @@ public abstract class TaskDraw implements Runnable { public static float HSB_CONSTANT_S = 1; public static float HSB_CONSTANT_B = 1; + public static double USER_CONVERGENT_BAILOUT; + + public static boolean CHUNK_SIZE_PER_ROW = false; + protected static final int THREAD_CHUNK_SIZE = 500; protected static final int SUCCESSIVE_REFINEMENT_EXPONENT = 7; protected static final int SUCCESSIVE_REFINEMENT_MAX_SIZE = 2 << (SUCCESSIVE_REFINEMENT_EXPONENT - 1); protected static final int[] THREAD_CHUNK_SIZE_PER_LEVEL = {2, 4, 8, 16, 32, 64, 128, 256}; + protected static final int[] THREAD_CHUNK_SIZE_PER_LEVEL2 = {2, 4, 4, 8, 8, 16, 16, 32, 32, 64, 64, 128, 128, 256, 256}; + + protected static final int[] SUCCESSIVE_REFINEMENT_SPLIT1 = {SUCCESSIVE_REFINEMENT_MAX_SIZE, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 1, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 1, + SUCCESSIVE_REFINEMENT_MAX_SIZE >> 2, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 2, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 3, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 3, + SUCCESSIVE_REFINEMENT_MAX_SIZE >> 4, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 4, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 5, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 5, + SUCCESSIVE_REFINEMENT_MAX_SIZE >> 6, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 6, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 7, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 7}; + + protected static final int[] SUCCESSIVE_REFINEMENT_SPLIT2 = {SUCCESSIVE_REFINEMENT_MAX_SIZE, SUCCESSIVE_REFINEMENT_MAX_SIZE, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 1, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 1, + SUCCESSIVE_REFINEMENT_MAX_SIZE >> 2, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 2, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 3, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 3, + SUCCESSIVE_REFINEMENT_MAX_SIZE >> 4, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 4, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 5, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 5, + SUCCESSIVE_REFINEMENT_MAX_SIZE >> 6, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 6, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 7}; + + + protected static final int[] SUCCESSIVE_REFINEMENT_SPLIT3 = {SUCCESSIVE_REFINEMENT_MAX_SIZE, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 1, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 1, + SUCCESSIVE_REFINEMENT_MAX_SIZE >> 1, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 2, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 3, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 3, + SUCCESSIVE_REFINEMENT_MAX_SIZE >> 3, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 4, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 5, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 5, + SUCCESSIVE_REFINEMENT_MAX_SIZE >> 5, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 6, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 7, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 7}; + + protected static final int[] SUCCESSIVE_REFINEMENT_SPLIT4 = {SUCCESSIVE_REFINEMENT_MAX_SIZE, SUCCESSIVE_REFINEMENT_MAX_SIZE, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 1, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 2, + SUCCESSIVE_REFINEMENT_MAX_SIZE >> 2, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 2, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 3, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 4, + SUCCESSIVE_REFINEMENT_MAX_SIZE >> 4, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 4, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 5, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 6, + SUCCESSIVE_REFINEMENT_MAX_SIZE >> 6, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 6, SUCCESSIVE_REFINEMENT_MAX_SIZE >> 7}; + + + public static int SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM = 0; + + public static boolean COMPRESS_REFERENCE_IF_POSSIBLE = false; + + public static boolean TWO_PASS_SUCCESSIVE_REFINEMENT = false; + public static int SQUARE_RECT_CHUNK_AGGERAGATION = 0; + + protected static int[] SUCCESSIVE_REFINEMENT_CHUNK_X; + protected static int[] SUCCESSIVE_REFINEMENT_CHUNK_Y; public static boolean QUICKDRAW_SUCCESSIVE_REFINEMENT = false; public static boolean USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT = true; public static boolean ALWAYS_SAVE_EXTRA_PIXEL_DATA_ON_AA = true; + public static boolean ALWAYS_SAVE_EXTRA_PIXEL_DATA_ON_AA_WITH_PP = true; + public static boolean USE_RI_ON_BLA2 = false; + public static boolean DISABLE_RI_ON_BLA2 = false; public static boolean USE_FAST_DELTA_LOCATION = true; + public static int BUILT_IT_BIGNUM_IMPLEMENTATION = 0; + public static int BIGNUM_INITIALIZATION_ALGORITHM = 0; public static int FAST_JULIA_IMAGE_SIZE = 252; protected static int randomNumber; @@ -232,8 +276,7 @@ public abstract class TaskDraw implements Runnable { private static CyclicBarrier normalize_sync; private static CyclicBarrier normalize_sync2; private static CyclicBarrier normalize_find_ranges_sync_3d; - private static CyclicBarrier normalize_sync_3d; - private static CyclicBarrier normalize_sync2_3d; + protected static CyclicBarrier initialize_jobs_sync; private static CyclicBarrier post_processing_sync; private static CyclicBarrier calculate_vectors_sync; @@ -258,13 +301,17 @@ public abstract class TaskDraw implements Runnable { public static LongAccumulator max_pixel_calculation_time; private static LongAdder total_calculated_extra; protected static AtomicInteger normal_drawing_algorithm_pixel; + protected static AtomicInteger normal_drawing_algorithm_pixel2; protected static AtomicInteger[] quick_draw_drawing_algorithm_pixel; protected static AtomicInteger[] successive_refinement_drawing_algorithm_pixel; + protected static AtomicInteger[] successive_refinement_drawing_algorithm2_pixel; protected static AtomicInteger draw_squares_pixel; protected static CyclicBarrier quick_draw_drawing_algorithm_barrier; protected static CyclicBarrier successive_refinement_drawing_algorithm_barrier; protected static AtomicInteger normal_drawing_algorithm_apply_palette; + protected static AtomicInteger normal_drawing_algorithm_apply_palette2; protected static AtomicInteger normal_drawing_algorithm_post_processing; + protected static AtomicInteger normal_drawing_algorithm_post_processing2; protected static AtomicInteger apply_skipped_color_pixel; protected static AtomicInteger normal_drawing_algorithm_histogram; private static CyclicBarrier color_cycling_filters_sync; @@ -288,6 +335,42 @@ public static void stopSuccessiveRefinement() { successive_refinement_lock.unlockWrite(); } + protected static int getThreadChunkSize(int width, boolean per_row) { + if (per_row) { + return width; + } + return THREAD_CHUNK_SIZE; + } + + static { + setSuccessiveRefinementChunks(); + } + + public static void setSuccessiveRefinementChunks() { + + if(SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM == 1) { + SUCCESSIVE_REFINEMENT_CHUNK_X = SUCCESSIVE_REFINEMENT_SPLIT1; + SUCCESSIVE_REFINEMENT_CHUNK_Y = SUCCESSIVE_REFINEMENT_SPLIT2; + } + else if(SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM == 2) { + SUCCESSIVE_REFINEMENT_CHUNK_X = SUCCESSIVE_REFINEMENT_SPLIT2; + SUCCESSIVE_REFINEMENT_CHUNK_Y = SUCCESSIVE_REFINEMENT_SPLIT1; + } + else if(SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM == 3) { + SUCCESSIVE_REFINEMENT_CHUNK_X = SUCCESSIVE_REFINEMENT_SPLIT3; + SUCCESSIVE_REFINEMENT_CHUNK_Y = SUCCESSIVE_REFINEMENT_SPLIT4; + } + else if(SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM == 4) { + SUCCESSIVE_REFINEMENT_CHUNK_X = SUCCESSIVE_REFINEMENT_SPLIT4; + SUCCESSIVE_REFINEMENT_CHUNK_Y = SUCCESSIVE_REFINEMENT_SPLIT3; + } + else { + SUCCESSIVE_REFINEMENT_CHUNK_X = null; + SUCCESSIVE_REFINEMENT_CHUNK_Y = null; + } + + } + private static BufferedImage window_image; public static void loadWindowImage(int id) { @@ -371,14 +454,6 @@ else if (id == 9){ private static double lowerFence; private static double upperFence; - private static double maxIterations3d; - private static double minIterations3d; - private static double histogramDenominator = 1; - private static int[] histogramCounts; - private static int totalCounts; - private boolean histogramHeight; - private int histogram_granularity; - private double histogram_density; private boolean preHeightScaling; /** @@ -492,12 +567,9 @@ else if (id == 9){ private int color_cycling_location_outcoloring; private int color_cycling_location_incoloring; private int gradient_offset; - private int color_cycling_speed; - private boolean cycle_colors; - private boolean cycle_lights; - private boolean cycle_gradient; - private int color_cycling_adjusting_value; + private ColorCyclingSettings ccs; + /** * ******************** */ @@ -566,6 +638,7 @@ else if (id == 9){ public static boolean USE_THREADS_FOR_SA = false; public static int BLA_BITS = ApproximationDefaultSettings.BLA_BITS; public static boolean USE_THREADS_FOR_BLA = true; + public static boolean USE_THREADS_FOR_BLA2 = true; public static boolean DETECT_PERIOD = true; public static int PERIOD_DETECTION_ALGORITHM = 2; public static boolean STOP_REFERENCE_CALCULATION_AFTER_DETECTED_PERIOD = true; @@ -574,6 +647,7 @@ else if (id == 9){ public static int NANOMB1_N = ApproximationDefaultSettings.NANOMB1_N; public static int NANOMB1_M = ApproximationDefaultSettings.NANOMB1_M; public static boolean GATHER_PERTURBATION_STATISTICS = false; + public static boolean GATHER_HIGHPRECISION_STATISTICS = false; public static boolean CHECK_BAILOUT_DURING_DEEP_NOT_FULL_FLOATEXP_MODE = false; public static boolean GREEDY_ALGORITHM = true; public static boolean GREEDY_ALGORITHM_CHECK_ITER_DATA = true; @@ -598,7 +672,9 @@ else if (id == 9){ public static int MANTEXPCOMPLEX_FORMAT = 0; public static boolean SMOOTH_DATA = false; + public static ThreadPoolExecutor la_thread_executor; public static ThreadPoolExecutor reference_thread_executor; + //public static ThreadPoolExecutor reference_thread_executor2; public static ThreadPoolExecutor thread_calculation_executor; public static ThreadPoolExecutor julia_map_thread_calculation_executor; public static ExecutorService single_thread_executor; @@ -608,6 +684,9 @@ public static void shutdownThreadPools() { if(reference_thread_executor != null) { reference_thread_executor.shutdownNow(); } +// if(reference_thread_executor2 != null) { +// reference_thread_executor2.shutdown(); +// } if(thread_calculation_executor != null) { thread_calculation_executor.shutdownNow(); } @@ -620,6 +699,9 @@ public static void shutdownThreadPools() { if(action_thread_executor != null) { action_thread_executor.shutdownNow(); } + if(la_thread_executor != null) { + la_thread_executor.shutdownNow(); + } } @@ -637,10 +719,13 @@ public static void shutdownThreadPools() { algorithm_colors2 = new int[200]; setAlgorithmColors(); - if(Runtime.getRuntime().availableProcessors() >= 2) { - reference_thread_executor = (ThreadPoolExecutor)Executors.newFixedThreadPool(2); + if (Runtime.getRuntime().availableProcessors() >= 2) { + reference_thread_executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2); } +// if (Runtime.getRuntime().availableProcessors() >= 3) { +// reference_thread_executor2 = (ThreadPoolExecutor) Executors.newFixedThreadPool(3); +// } } public static void setAlgorithmColors() { @@ -778,9 +863,6 @@ private void settingsFractal(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCe this.shade_algorithm = d3s.shade_algorithm; this.shade_invert = d3s.shade_invert; this.d3_color_type = d3s.d3_color_type; - this.histogramHeight = d3s.histogram_equalization; - this.histogram_granularity = d3s.histogram_granularity; - this.histogram_density = d3s.histogram_density; this.preHeightScaling = d3s.preHeightScaling; this.d3s = d3s; @@ -1001,9 +1083,6 @@ private void settingsJulia(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCent this.shade_algorithm = d3s.shade_algorithm; this.shade_invert = d3s.shade_invert; this.d3_color_type = d3s.d3_color_type; - this.histogramHeight = d3s.histogram_equalization; - this.histogram_granularity = d3s.histogram_granularity; - this.histogram_density = d3s.histogram_density; this.preHeightScaling = d3s.preHeightScaling; this.d3s = d3s; @@ -1367,7 +1446,7 @@ private void settingsJuliaPreview(int FROMx, int TOx, int FROMy, int TOy, Apfloa } //Color Cycling - public TaskDraw(int FROMx, int TOx, int FROMy, int TOy, int max_iterations, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, int color_cycling_location, int color_cycling_location2, int color_cycling_speed, FiltersSettings fs, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, boolean cycle_colors, boolean cycle_lights, boolean cycle_gradient, int color_cycling_adjusting_value, DomainColoringSettings ds, int gradient_offset, double contourFactor, boolean smoothing, GeneratedPaletteSettings gps, PostProcessSettings pps) { + public TaskDraw(int FROMx, int TOx, int FROMy, int TOy, int max_iterations, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, int color_cycling_location, int color_cycling_location2, FiltersSettings fs, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, DomainColoringSettings ds, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, PostProcessSettings pps, ColorCyclingSettings ccs) { this.FROMx = FROMx; this.TOx = TOx; @@ -1393,11 +1472,7 @@ public TaskDraw(int FROMx, int TOx, int FROMy, int TOy, int max_iterations, Main action = COLOR_CYCLING; - this.color_cycling_speed = color_cycling_speed; - this.cycle_colors = cycle_colors; - this.cycle_lights = cycle_lights; - this.cycle_gradient = cycle_gradient; - this.color_cycling_adjusting_value = color_cycling_adjusting_value; + this.ccs = ccs; this.color_blending = color_blending; @@ -1702,7 +1777,11 @@ public void run() { System.exit(-1); } DONE = true; - number_of_tasks.decrementAndGet(); + int number = number_of_tasks.decrementAndGet(); + + if(ptr != null && number == 0) { + ptr.getMainPanel().stopTimer(); + } } @@ -1798,10 +1877,10 @@ private String getBigNumString(int bigNumLib, int arbitraryLib) { if(!domain_coloring && HIGH_PRECISION_CALCULATION && fractal.supportsPerturbationTheory()) { if(arbitraryLib == Constants.ARBITRARY_BUILT_IN && fractal.supportsBignum()) { - return _getBigNumLibString("Built-in") + _getBigNumLibPrecString(BigNum.fracDigits * BigNum.SHIFT); + return _getBigNumLibString(BigNum.getName()) + _getBigNumLibPrecString(BigNum.getPrecision()); } else if(arbitraryLib == Constants.ARBITRARY_BIGINT && fractal.supportsBigIntnum()) { - return _getBigNumLibString("Fixed Point BigInteger") + _getBigNumLibPrecString(BigIntNum.fracDigits * BigIntNum.SHIFT32); + return _getBigNumLibString("Fixed Point BigInteger") + _getBigNumLibPrecString(BigIntNum.getPrecision()); } else if(arbitraryLib == Constants.ARBITRARY_MPFR && fractal.supportsMpfrBignum()) { return _getBigNumLibString("MPFR " + LibMpfr.mpfr_version) + _getBigNumLibPrecString(MpfrBigNum.precision); @@ -1818,10 +1897,10 @@ else if(arbitraryLib == Constants.ARBITRARY_APFLOAT) { } else if(!domain_coloring && PERTURBATION_THEORY && fractal.supportsPerturbationTheory()) { if(bigNumLib == Constants.BIGNUM_BUILT_IN && fractal.supportsBignum()) { - return _getBigNumLibString("Built-in") + _getBigNumLibPrecString(BigNum.fracDigits * BigNum.SHIFT); + return _getBigNumLibString(BigNum.getName()) + _getBigNumLibPrecString(BigNum.getPrecision()); } else if(bigNumLib == Constants.BIGNUM_BIGINT && fractal.supportsBigIntnum()) { - return _getBigNumLibString("Fixed Point BigInteger") + _getBigNumLibPrecString(BigIntNum.fracDigits * BigIntNum.SHIFT32); + return _getBigNumLibString("Fixed Point BigInteger") + _getBigNumLibPrecString(BigIntNum.getPrecision()); } else if(bigNumLib == Constants.BIGNUM_MPFR && fractal.supportsMpfrBignum()) { return _getBigNumLibString("MPFR " + LibMpfr.mpfr_version) + _getBigNumLibPrecString(MpfrBigNum.precision); @@ -1946,6 +2025,94 @@ else if(!domain_coloring && HIGH_PRECISION_CALCULATION && fractal.supportsPertur } } + private String getCompressionInfo(int refPointIterations, int secondRefPointIterations) { + + int waypoints = 0; + int waypoints2 = 0; + + String referenceDataWaypoints = "" + waypoints; + if(Fractal.referenceDeepData != null && Fractal.referenceDeepData.exists()) { + ArrayList waypointsList = Fractal.referenceDeepData.getWaypointsLength(); + waypoints = waypointsList.stream().mapToInt(v -> v).max().orElse(0); + if(waypointsList.size() == 1) { + referenceDataWaypoints = "" + waypointsList.get(0); + } + else { + referenceDataWaypoints = "[" + String.join(", ", waypointsList.stream().map(i -> "" + i).collect(Collectors.toList())) + "]"; + } + } + else if(Fractal.referenceData != null && Fractal.referenceData.exists()) { + ArrayList waypointsList = Fractal.referenceData.getWaypointsLength(); + waypoints = waypointsList.stream().mapToInt(v -> v).max().orElse(0); + if(waypointsList.size() == 1) { + referenceDataWaypoints = "" + waypointsList.get(0); + } + else { + referenceDataWaypoints = "[" + String.join(", ", waypointsList.stream().map(i -> "" + i).collect(Collectors.toList())) + "]"; + } + } + + String result = "
  • Reference Compression Waypoints: " + referenceDataWaypoints + "
    "; + result += "
  • Reference Compression Ratio: " + (waypoints > 0 ? (refPointIterations) + " / " + (waypoints) + " (" + String.format("%.4f", refPointIterations / ((double)waypoints)) + "x)" : "N/A") + "
    "; + + if(fractal.needsSecondReference()) { + + String referenceDataWaypoints2 = "" + waypoints2; + if(Fractal.secondReferenceDeepData != null && Fractal.secondReferenceDeepData.exists()) { + ArrayList waypointsList = Fractal.secondReferenceDeepData.getWaypointsLength(); + waypoints2 = waypointsList.stream().mapToInt(v -> v).max().orElse(0); + if(waypointsList.size() == 1) { + referenceDataWaypoints2 = "" + waypointsList.get(0); + } + else { + referenceDataWaypoints2 = "[" + String.join(", ", waypointsList.stream().map(i -> "" + i).collect(Collectors.toList())) + "]"; + } + } + else if(Fractal.secondReferenceData != null && Fractal.secondReferenceData.exists()) { + ArrayList waypointsList = Fractal.secondReferenceData.getWaypointsLength(); + waypoints2 = waypointsList.stream().mapToInt(v -> v).max().orElse(0); + if(waypointsList.size() == 1) { + referenceDataWaypoints2 = "" + waypointsList.get(0); + } + else { + referenceDataWaypoints2 = "[" + String.join(", ", waypointsList.stream().map(i -> "" + i).collect(Collectors.toList())) + "]"; + } + } + + result += "
  • Julia Extra Reference Compression Waypoints: " + referenceDataWaypoints2 + "
    "; + result += "
  • Julia Extra Reference Compression Ratio: " + (waypoints2 > 0 ? (secondRefPointIterations) + " / " + (waypoints2) + " (" + String.format("%.4f", secondRefPointIterations / ((double)waypoints2)) + "x)" : "N/A") + "
    "; + + } + + return result; + } + + private String getApproximationString(boolean supportsPerturbation) { + + if(!(!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation)) { + return ""; + } + + String approximation = "
  • Approximation: "; + if(APPROXIMATION_ALGORITHM == 1 && fractal.supportsSeriesApproximation()) { + approximation += "Series Approximation
    "; + } + else if(APPROXIMATION_ALGORITHM == 2 && fractal.supportsBilinearApproximation()) { + approximation += "Bilinear Approximation (claude)
    "; + } + else if(APPROXIMATION_ALGORITHM == 3 && fractal.supportsNanomb1()) { + approximation += "Nanomb1
    "; + } + else if(APPROXIMATION_ALGORITHM == 4 && fractal.supportsBilinearApproximation2()) { + approximation += "Bilinear Approximation (Zhuoran)
    "; + } + else { + approximation += "No Approximation
    "; + } + + return approximation; + } + public void setFullToolTipMessage(int total) { long time = ptr != null ? ptr.getCalculationTime() : ptrExpander.getCalculationTime(); @@ -2010,14 +2177,16 @@ public void setFullToolTipMessage(int total) { (d3 && D3RenderingCalculationTime > 0? "
  • 3D Rendering Elapsed Time: " + D3RenderingCalculationTime + " ms
    " : "") + (!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation && Fractal.ReferenceCalculationTime > 0 ? "
  • Reference Calculation Elapsed Time: " + Fractal.ReferenceCalculationTime + " ms
    " : "") + (!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation ? "
  • Reference Point Iterations: " + refPointIterations + "
    " : "") + - (!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation && Fractal.ReferenceCalculationTime > 0 && Fractal.calculatedReferenceIterations > 0 ? "
  • Reference Point Iterations per second: " + String.format("%.2f", Fractal.calculatedReferenceIterations / ((double)Fractal.ReferenceCalculationTime / 1000.0)) + "
    " : "") + + (!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation && Fractal.ReferenceCalculationTime > 0 && Fractal.calculatedReferenceIterations > 0 ? "
  • Reference Point Iterations per second: " + String.format("%.4f", Fractal.calculatedReferenceIterations / ((double)Fractal.ReferenceCalculationTime / 1000.0)) + "
    " : "") + (!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation && fractal.needsSecondReference() && Fractal.SecondReferenceCalculationTime > 0 ? "
  • Julia Extra Reference Calculation Elapsed Time: " + Fractal.SecondReferenceCalculationTime + " ms
    " : "") + (!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation && fractal.needsSecondReference() ? "
  • Julia Extra Reference Point Iterations: " + secondRefPointIterations + "
    " : "") + - (!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation && fractal.needsSecondReference() && Fractal.SecondReferenceCalculationTime > 0 && Fractal.calculatedSecondReferenceIterations > 0 ? "
  • Julia Extra Reference Point Iterations per second: " + String.format("%.2f", Fractal.calculatedSecondReferenceIterations / ((double)Fractal.SecondReferenceCalculationTime / 1000.0)) + "
    " : "") + + (!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation && fractal.needsSecondReference() && Fractal.SecondReferenceCalculationTime > 0 && Fractal.calculatedSecondReferenceIterations > 0 ? "
  • Julia Extra Reference Point Iterations per second: " + String.format("%.4f", Fractal.calculatedSecondReferenceIterations / ((double)Fractal.SecondReferenceCalculationTime / 1000.0)) + "
    " : "") + + (!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation && COMPRESS_REFERENCE_IF_POSSIBLE && fractal.supportsReferenceCompression() ? getCompressionInfo(refPointIterations, secondRefPointIterations) : "") + (!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation && DETECT_PERIOD && fractal.supportsPeriod() ? "
  • Detected Period: " + (Fractal.DetectedPeriod != 0 ? Fractal.DetectedPeriod : "N/A") + "
    " : "") + //&& Fractal.DetectedPeriod != 0 //(!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation && DETECT_PERIOD && fractal.supportsPeriod() && Fractal.DetectedPeriod != Fractal.DetectedAtomPeriod ? "
  • Detected Atom Period: " + Fractal.DetectedAtomPeriod + "
    " : "") + (!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation && fractal.supportsPeriod() && fractal.getPeriod() != 0 && Fractal.SAskippedIterations == 0 ? "
  • Used Period: " + fractal.getPeriod() + "
    " : "") + + getApproximationString(supportsPerturbation) + (!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation && APPROXIMATION_ALGORITHM == 1 && fractal.supportsSeriesApproximation() && Fractal.SAskippedIterations != 0 && Fractal.SATerms != 0 && Fractal.SACalculationTime > 0? "
  • SA Calculation Elapsed Time: " + Fractal.SACalculationTime + " ms
    " : "") + (!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation && APPROXIMATION_ALGORITHM == 1 && fractal.supportsSeriesApproximation() && Fractal.SAskippedIterations != 0 && Fractal.SATerms != 0 ? "
  • SA Terms Used: " + Fractal.SATerms + "
    " : "") + (!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation && APPROXIMATION_ALGORITHM == 1 && fractal.supportsSeriesApproximation() && Fractal.SAskippedIterations != 0 && Fractal.SATerms != 0 ? "
  • SA Skipped Iterations: " + Fractal.SAskippedIterations + "
    ": "") + @@ -2025,26 +2194,28 @@ public void setFullToolTipMessage(int total) { (!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation && APPROXIMATION_ALGORITHM == 3 && fractal.supportsNanomb1() && Fractal.Nanomb1CalculationTime > 0 ? "
  • Nanomb1 Calculation Elapsed Time: " + Fractal.Nanomb1CalculationTime + " ms
    " : "") + (!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation && APPROXIMATION_ALGORITHM == 3 && fractal.supportsNanomb1() ? "
  • Nanomb1 M: " + NANOMB1_M + "
    " : "") + (!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation && APPROXIMATION_ALGORITHM == 3 && fractal.supportsNanomb1() ? "
  • Nanomb1 N: " + NANOMB1_N + "
    " : "") + - (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && APPROXIMATION_ALGORITHM == 3 && fractal.supportsNanomb1() ? "
  • Nanomb1 Skipped Iterations Per Pixel: " + String.format("%.2f", Fractal.total_nanomb1_skipped_iterations.sum() / ((double) total_calculated_pixels * (supersampling_num))) + "
    ": "") + + (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && APPROXIMATION_ALGORITHM == 3 && fractal.supportsNanomb1() ? "
  • Nanomb1 Skipped Iterations Per Pixel: " + String.format("%.4f", Fractal.total_nanomb1_skipped_iterations.sum() / ((double) total_calculated_pixels * (supersampling_num))) + "
    ": "") + (!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM == 2 && fractal.supportsBilinearApproximation() || APPROXIMATION_ALGORITHM == 4 && fractal.supportsBilinearApproximation2() && Fractal.BLACalculationTime > 0) ? "
  • BLA Calculation Elapsed Time: " + Fractal.BLACalculationTime + " ms
    " : "") + (!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation && APPROXIMATION_ALGORITHM == 2 && fractal.supportsBilinearApproximation() ? "
  • BLA Precision: " + TaskDraw.BLA_BITS + " bits
    " : "") + (!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation && APPROXIMATION_ALGORITHM == 2 && fractal.supportsBilinearApproximation() ? "
  • BLA Starting Level: " + TaskDraw.BLA_STARTING_LEVEL + "
    " : "") + - (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM == 2 && fractal.supportsBilinearApproximation() || APPROXIMATION_ALGORITHM == 4 && fractal.supportsBilinearApproximation2()) ? "
  • BLA Iterations Per Pixel: " + String.format("%.2f", Fractal.total_bla_iterations.sum() / ((double) total_calculated_pixels * (supersampling_num))) + "
    " : "") + - (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM == 2 && fractal.supportsBilinearApproximation() || APPROXIMATION_ALGORITHM == 4 && fractal.supportsBilinearApproximation2()) ? "
  • BLA Iterations Per BLA Step: " + (Fractal.total_bla_steps.sum() == 0 ? "N/A" : String.format("%.2f", Fractal.total_bla_iterations.sum() / ((double)Fractal.total_bla_steps.sum()))) + "
    " : "") + - (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM == 2 && fractal.supportsBilinearApproximation() || APPROXIMATION_ALGORITHM == 4 && fractal.supportsBilinearApproximation2()) ? "
  • Perturbation Iterations Per Pixel: " + String.format("%.2f", Fractal.total_perturb_iterations.sum() / ((double) total_calculated_pixels * (supersampling_num))) + "
    " : "") + - (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM == 2 && fractal.supportsBilinearApproximation() || APPROXIMATION_ALGORITHM == 4 && fractal.supportsBilinearApproximation2()) ? "
  • BLA Steps Per Pixel: " + String.format("%.2f", Fractal.total_bla_steps.sum() / ((double) total_calculated_pixels * (supersampling_num))) + "
    " : "") + - (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM == 2 && fractal.supportsBilinearApproximation() || APPROXIMATION_ALGORITHM == 4 && fractal.supportsBilinearApproximation2()) ? "
  • Total Steps Per Pixel: " + String.format("%.2f", (Fractal.total_bla_steps.sum() + Fractal.total_perturb_iterations.sum()) / ((double) total_calculated_pixels * (supersampling_num))) + "
    " : "") + - (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM != 2 || !fractal.supportsBilinearApproximation()) && (APPROXIMATION_ALGORITHM != 4 || !fractal.supportsBilinearApproximation2()) && TaskDraw.PERTUBATION_PIXEL_ALGORITHM == 1 && fractal.supportsScaledIterations() && isDeep ? "
  • Extended Range Iterations Per Pixel: " + (String.format("%.2f", Fractal.total_float_exp_iterations.sum() / ((double) total_calculated_pixels * (supersampling_num)))) + "
    " : "") + - (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM != 2 || !fractal.supportsBilinearApproximation()) && (APPROXIMATION_ALGORITHM != 4 || !fractal.supportsBilinearApproximation2()) && TaskDraw.PERTUBATION_PIXEL_ALGORITHM == 1 && fractal.supportsScaledIterations() && isDeep ? "
  • Scaled Double Iterations Per Pixel: " + (String.format("%.2f", Fractal.total_scaled_iterations.sum() / ((double) total_calculated_pixels * (supersampling_num)))) + "
    " : "") + - (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM != 2 || !fractal.supportsBilinearApproximation()) && (APPROXIMATION_ALGORITHM != 4 || !fractal.supportsBilinearApproximation2()) && TaskDraw.PERTUBATION_PIXEL_ALGORITHM == 1 && fractal.supportsScaledIterations() && isDeep ? "
  • Normal Double Iterations Per Pixel: " + (String.format("%.2f", Fractal.total_double_iterations.sum() / ((double) total_calculated_pixels * (supersampling_num)))) + "
    " : "") + - (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM != 2 || !fractal.supportsBilinearApproximation()) && (APPROXIMATION_ALGORITHM != 4 || !fractal.supportsBilinearApproximation2()) && (TaskDraw.PERTUBATION_PIXEL_ALGORITHM == 0 || !fractal.supportsScaledIterations()) && isDeep ? "
  • Extended Range Iterations Per Pixel: " + (String.format("%.2f", Fractal.total_float_exp_iterations.sum() / ((double) total_calculated_pixels * (supersampling_num)))) + "
    " : "") + - (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM != 2 || !fractal.supportsBilinearApproximation()) && (APPROXIMATION_ALGORITHM != 4 || !fractal.supportsBilinearApproximation2()) && (TaskDraw.PERTUBATION_PIXEL_ALGORITHM == 0 || !fractal.supportsScaledIterations()) && isDeep ? "
  • Normal Double Iterations Per Pixel: " + (String.format("%.2f", Fractal.total_double_iterations.sum() / ((double) total_calculated_pixels * (supersampling_num)))) + "
    " : "") + - (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM != 2 || !fractal.supportsBilinearApproximation()) && (APPROXIMATION_ALGORITHM != 4 || !fractal.supportsBilinearApproximation2()) && !isDeep ? "
  • Normal Double Iterations Per Pixel: " + (String.format("%.2f", Fractal.total_double_iterations.sum() / ((double) total_calculated_pixels * (supersampling_num)))) + "
    " : "") + - (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM != 2 || !fractal.supportsBilinearApproximation()) && (APPROXIMATION_ALGORITHM != 4 || !fractal.supportsBilinearApproximation2()) && TaskDraw.PERTUBATION_PIXEL_ALGORITHM == 1 && fractal.supportsScaledIterations() && isDeep ? "
  • Re-Aligns Per Pixel: " + (String.format("%.2f", Fractal.total_realigns.sum() / ((double) total_calculated_pixels * (supersampling_num)))) + "
    " : "") + - (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation ? "
  • Rebases Per Pixel: " + String.format("%.2f", Fractal.total_rebases.sum() / ((double) total_calculated_pixels * (supersampling_num))) + "
    " : "") + - (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation ? "
  • Average Iterations Per Pixel: " + String.format("%.2f", ( Fractal.total_double_iterations.sum() + Fractal.total_scaled_iterations.sum() + Fractal.total_float_exp_iterations.sum() + Fractal.total_perturb_iterations.sum() + Fractal.total_bla_iterations.sum())/ ((double) total_calculated_pixels * (supersampling_num))) + "
    " : "") + - (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation ? "
  • Minimum Iterations: " + Fractal.total_min_iterations.get() + "
    " : "") + - (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation? "
  • Maximum Iterations: " + Fractal.total_max_iterations.get() + "
    " : "") + + (!HIGH_PRECISION_CALCULATION && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM == 2 && fractal.supportsBilinearApproximation() || APPROXIMATION_ALGORITHM == 4 && fractal.supportsBilinearApproximation2()) ? "
  • BLA Entries: " + fractal.getBLAEntries() + "
    " : "") + + (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM == 2 && fractal.supportsBilinearApproximation() || APPROXIMATION_ALGORITHM == 4 && fractal.supportsBilinearApproximation2()) ? "
  • BLA Iterations Per Pixel: " + String.format("%.4f", Fractal.total_bla_iterations.sum() / ((double) total_calculated_pixels * (supersampling_num))) + "
    " : "") + + (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM == 2 && fractal.supportsBilinearApproximation() || APPROXIMATION_ALGORITHM == 4 && fractal.supportsBilinearApproximation2()) ? "
  • BLA Iterations Per BLA Step: " + (Fractal.total_bla_steps.sum() == 0 ? "N/A" : String.format("%.4f", Fractal.total_bla_iterations.sum() / ((double)Fractal.total_bla_steps.sum()))) + "
    " : "") + + (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM == 2 && fractal.supportsBilinearApproximation() || APPROXIMATION_ALGORITHM == 4 && fractal.supportsBilinearApproximation2()) ? "
  • Perturbation Iterations Per Pixel: " + String.format("%.4f", Fractal.total_perturb_iterations.sum() / ((double) total_calculated_pixels * (supersampling_num))) + "
    " : "") + + (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM == 2 && fractal.supportsBilinearApproximation() || APPROXIMATION_ALGORITHM == 4 && fractal.supportsBilinearApproximation2()) ? "
  • BLA Steps Per Pixel: " + String.format("%.4f", Fractal.total_bla_steps.sum() / ((double) total_calculated_pixels * (supersampling_num))) + "
    " : "") + + (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM == 2 && fractal.supportsBilinearApproximation() || APPROXIMATION_ALGORITHM == 4 && fractal.supportsBilinearApproximation2()) ? "
  • Total Steps Per Pixel: " + String.format("%.4f", (Fractal.total_bla_steps.sum() + Fractal.total_perturb_iterations.sum()) / ((double) total_calculated_pixels * (supersampling_num))) + "
    " : "") + + (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM != 2 || !fractal.supportsBilinearApproximation()) && (APPROXIMATION_ALGORITHM != 4 || !fractal.supportsBilinearApproximation2()) && TaskDraw.PERTUBATION_PIXEL_ALGORITHM == 1 && fractal.supportsScaledIterations() && isDeep ? "
  • Extended Range Iterations Per Pixel: " + (String.format("%.4f", Fractal.total_float_exp_iterations.sum() / ((double) total_calculated_pixels * (supersampling_num)))) + "
    " : "") + + (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM != 2 || !fractal.supportsBilinearApproximation()) && (APPROXIMATION_ALGORITHM != 4 || !fractal.supportsBilinearApproximation2()) && TaskDraw.PERTUBATION_PIXEL_ALGORITHM == 1 && fractal.supportsScaledIterations() && isDeep ? "
  • Scaled Double Iterations Per Pixel: " + (String.format("%.4f", Fractal.total_scaled_iterations.sum() / ((double) total_calculated_pixels * (supersampling_num)))) + "
    " : "") + + (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM != 2 || !fractal.supportsBilinearApproximation()) && (APPROXIMATION_ALGORITHM != 4 || !fractal.supportsBilinearApproximation2()) && TaskDraw.PERTUBATION_PIXEL_ALGORITHM == 1 && fractal.supportsScaledIterations() && isDeep ? "
  • Normal Double Iterations Per Pixel: " + (String.format("%.4f", Fractal.total_double_iterations.sum() / ((double) total_calculated_pixels * (supersampling_num)))) + "
    " : "") + + (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM != 2 || !fractal.supportsBilinearApproximation()) && (APPROXIMATION_ALGORITHM != 4 || !fractal.supportsBilinearApproximation2()) && (TaskDraw.PERTUBATION_PIXEL_ALGORITHM == 0 || !fractal.supportsScaledIterations()) && isDeep ? "
  • Extended Range Iterations Per Pixel: " + (String.format("%.4f", Fractal.total_float_exp_iterations.sum() / ((double) total_calculated_pixels * (supersampling_num)))) + "
    " : "") + + (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM != 2 || !fractal.supportsBilinearApproximation()) && (APPROXIMATION_ALGORITHM != 4 || !fractal.supportsBilinearApproximation2()) && (TaskDraw.PERTUBATION_PIXEL_ALGORITHM == 0 || !fractal.supportsScaledIterations()) && isDeep ? "
  • Normal Double Iterations Per Pixel: " + (String.format("%.4f", Fractal.total_double_iterations.sum() / ((double) total_calculated_pixels * (supersampling_num)))) + "
    " : "") + + (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM != 2 || !fractal.supportsBilinearApproximation()) && (APPROXIMATION_ALGORITHM != 4 || !fractal.supportsBilinearApproximation2()) && !isDeep ? "
  • Normal Double Iterations Per Pixel: " + (String.format("%.4f", Fractal.total_double_iterations.sum() / ((double) total_calculated_pixels * (supersampling_num)))) + "
    " : "") + + (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation && (APPROXIMATION_ALGORITHM != 2 || !fractal.supportsBilinearApproximation()) && (APPROXIMATION_ALGORITHM != 4 || !fractal.supportsBilinearApproximation2()) && TaskDraw.PERTUBATION_PIXEL_ALGORITHM == 1 && fractal.supportsScaledIterations() && isDeep ? "
  • Re-Aligns Per Pixel: " + (String.format("%.4f", Fractal.total_realigns.sum() / ((double) total_calculated_pixels * (supersampling_num)))) + "
    " : "") + + (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY && supportsPerturbation ? "
  • Rebases Per Pixel: " + String.format("%.4f", Fractal.total_rebases.sum() / ((double) total_calculated_pixels * (supersampling_num))) + "
    " : "") + + (((HIGH_PRECISION_CALCULATION && GATHER_HIGHPRECISION_STATISTICS) || (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY)) && supportsPerturbation ? "
  • Average Iterations Per Pixel: " + String.format("%.4f", (Fractal.total_iterations.sum())/ ((double) total_calculated_pixels * (supersampling_num))) + "
    " : "") + + (((HIGH_PRECISION_CALCULATION && GATHER_HIGHPRECISION_STATISTICS) || (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY)) && supportsPerturbation ? "
  • Minimum Iterations: " + Fractal.total_min_iterations.get() + "
    " : "") + + (((HIGH_PRECISION_CALCULATION && GATHER_HIGHPRECISION_STATISTICS) || (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY)) && supportsPerturbation ? "
  • Maximum Iterations: " + Fractal.total_max_iterations.get() + "
    " : "") + + (((HIGH_PRECISION_CALCULATION && GATHER_HIGHPRECISION_STATISTICS) || (!HIGH_PRECISION_CALCULATION && GATHER_PERTURBATION_STATISTICS && PERTURBATION_THEORY)) && supportsPerturbation ? "
  • Maximum Iterations (Ignore Not Escaped Points): " + Fractal.total_max_iterations_ignore_max_iter.get() + "
    " : "") + @@ -3394,10 +3565,7 @@ protected int prevPowerOf2 (int x) return x - (x >>> 1); } - protected void quickDrawIterations(int image_size, boolean polar) { - - Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (PERTURBATION_THEORY || HIGH_PRECISION_CALCULATION) && fractal.supportsPerturbationTheory()); - + protected void initialize(Location location) { if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { if (reference_calc_sync.getAndIncrement() == 0) { calculateReference(location); @@ -3412,6 +3580,26 @@ protected void quickDrawIterations(int image_size, boolean polar) { } location.setReference(Fractal.refPoint); } + else if(HIGH_PRECISION_CALCULATION && fractal.supportsPerturbationTheory()) { + if (reference_calc_sync.getAndIncrement() == 0) { + initializeHighPrecision(); + } + + try { + reference_sync.await(); + } catch (InterruptedException ex) { + + } catch (BrokenBarrierException ex) { + + } + } + } + + protected void quickDrawIterations(int image_size, boolean polar) { + + Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (PERTURBATION_THEORY || HIGH_PRECISION_CALCULATION) && fractal.supportsPerturbationTheory()); + + initialize(location); int color, loc2, loc, x, y; int tempx, tempy; @@ -3713,20 +3901,7 @@ private void drawIterations3D(int image_size, boolean polar) { Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, detail, circle_period, rotation_center, rotation_vals, fractal, js, polar, (PERTURBATION_THEORY || HIGH_PRECISION_CALCULATION) && fractal.supportsPerturbationTheory()); - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); int pixel_percent = detail * detail / 100; @@ -3738,6 +3913,8 @@ private void drawIterations3D(int image_size, boolean polar) { int x, y, loc; + int thread_chunk_size = getThreadChunkSize(detail, CHUNK_SIZE_PER_ROW); + int condition = detail * detail; boolean escaped_val; @@ -3747,13 +3924,13 @@ private void drawIterations3D(int image_size, boolean polar) { do { - loc = THREAD_CHUNK_SIZE * normal_drawing_algorithm_pixel.getAndIncrement(); + loc = thread_chunk_size * normal_drawing_algorithm_pixel.getAndIncrement(); if (loc >= condition) { break; } - for (int count = 0; count < THREAD_CHUNK_SIZE && loc < condition; count++, loc++) { + for (int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { x = loc % detail; y = loc / detail; @@ -3806,17 +3983,19 @@ private void drawIterationsDomain3D(int image_size, boolean polar) { int condition = detail * detail; + int thread_chunk_size = getThreadChunkSize(detail, CHUNK_SIZE_PER_ROW); + long time = System.currentTimeMillis(); do { - loc = THREAD_CHUNK_SIZE * normal_drawing_algorithm_pixel.getAndIncrement(); + loc = thread_chunk_size * normal_drawing_algorithm_pixel.getAndIncrement(); if (loc >= condition) { break; } - for (int count = 0; count < THREAD_CHUNK_SIZE && loc < condition; count++, loc++) { + for (int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { x = loc % detail; y = loc / detail; @@ -3865,20 +4044,7 @@ private void drawIterations3DAntialiased(int image_size, boolean polar) { int supersampling_num = getExtraSamples(aaSamplesIndex, aaMethod); location.createAntialiasingSteps(aaMethod == 5, useJitter, supersampling_num); - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); int pixel_percent = detail * detail / 100; @@ -3907,17 +4073,19 @@ private void drawIterations3DAntialiased(int image_size, boolean polar) { double f_val; boolean storeExtraData = pixelData != null; + int thread_chunk_size = getThreadChunkSize(detail, CHUNK_SIZE_PER_ROW); + long time = System.currentTimeMillis(); do { - loc = THREAD_CHUNK_SIZE * normal_drawing_algorithm_pixel.getAndIncrement(); + loc = thread_chunk_size * normal_drawing_algorithm_pixel.getAndIncrement(); if (loc >= condition) { break; } - for (int count = 0; count < THREAD_CHUNK_SIZE && loc < condition; count++, loc++) { + for (int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { x = loc % detail; y = loc / detail; @@ -4018,17 +4186,19 @@ private void drawIterationsDomain3DAntialiased(int image_size, boolean polar) { boolean storeExtraData = pixelData != null; + int thread_chunk_size = getThreadChunkSize(detail, CHUNK_SIZE_PER_ROW); + long time = System.currentTimeMillis(); do { - loc = THREAD_CHUNK_SIZE * normal_drawing_algorithm_pixel.getAndIncrement(); + loc = thread_chunk_size * normal_drawing_algorithm_pixel.getAndIncrement(); if (loc >= condition) { break; } - for (int count = 0; count < THREAD_CHUNK_SIZE && loc < condition; count++, loc++) { + for (int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { x = loc % detail; y = loc / detail; @@ -4958,7 +5128,7 @@ private int[] pseudoDistanceEstimation(double[] image_iterations, PixelExtraData protected void applyPostProcessingOnPixel(int index, int x, int y, int image_size, double[] image_iterations, boolean[] escaped, PixelExtraData[] pixelData, AntialiasingAlgorithm aa, int[] modified, double sizeCorr, double lightx, double lighty, Location location) { - if(aa != null) { + if(aa != null && pixelData != null) { modified = pixelData[index].rgb_values; } else if (d3) { @@ -5049,7 +5219,7 @@ else if (d3) { } - if(aa != null) { + if(aa != null && pixelData != null) { aa.initialize(modified[0]); @@ -5106,7 +5276,7 @@ protected void applyPostProcessingPointFilter(int image_size, double[] image_ite protected void applyPostProcessing(int image_size, double[] image_iterations, boolean[] escaped, PixelExtraData[] pixelData, AntialiasingAlgorithm aa, Location location) { if (hss.histogramColoring && !domain_coloring) { - if(aa != null) { + if(aa != null && pixelData != null) { initializeHistogramColoring(pixelData); }else { initializeHistogramColoring(image_iterations, escaped); @@ -5129,11 +5299,14 @@ private boolean isInt(double val) { private void colorCycling() { + int outPaletteLength = CommonFunctions.getOutPaletteLength(domain_coloring, domain_color != null ? domain_color.getColoringMode() : -1); + int inPaletteLength = CommonFunctions.getInPaletteLength(domain_coloring); + do { try { color_cycling_toggle_lock.lockRead(); + } catch (InterruptedException e) { } - catch (InterruptedException e) {} try { @@ -5156,44 +5329,25 @@ private void colorCycling() { int image_size = image.getWidth(); - if (cycle_gradient) { - gradient_offset += color_cycling_adjusting_value; - gradient_offset = gradient_offset > Integer.MAX_VALUE - 40000 ? 0 : gradient_offset; + if (ccs.gradient_cycling_adjusting_value != 0) { + gradient_offset = CommonFunctions.adjustPaletteOffset(gradient_offset, ccs.gradient_cycling_adjusting_value, Constants.GRADIENT_LENGTH); } - if (cycle_colors) { - color_cycling_location_outcoloring += color_cycling_adjusting_value; - - color_cycling_location_outcoloring = color_cycling_location_outcoloring > Integer.MAX_VALUE - 40000 ? 0 : color_cycling_location_outcoloring; - - color_cycling_location_incoloring += color_cycling_adjusting_value; - - color_cycling_location_incoloring = color_cycling_location_incoloring > Integer.MAX_VALUE - 40000 ? 0 : color_cycling_location_incoloring; + if (ccs.color_cycling_adjusting_value != 0) { + color_cycling_location_outcoloring = CommonFunctions.adjustPaletteOffset(color_cycling_location_outcoloring, ccs.color_cycling_adjusting_value, outPaletteLength); + color_cycling_location_incoloring = CommonFunctions.adjustPaletteOffset(color_cycling_location_incoloring, ccs.color_cycling_adjusting_value, inPaletteLength); } - if (cycle_lights) { - if (bms.bump_map) { - bms.lightDirectionDegrees += color_cycling_adjusting_value; - bms.lightDirectionDegrees = bms.lightDirectionDegrees % 360.0; - } - - if (ls.lighting) { - ls.light_direction += color_cycling_adjusting_value; - ls.light_direction = ls.light_direction % 360.0; - - double lightAngleRadians = Math.toRadians(ls.light_direction); - ls.lightVector[0] = Math.cos(lightAngleRadians) * ls.light_magnitude; - ls.lightVector[1] = Math.sin(lightAngleRadians) * ls.light_magnitude; - } + if (ccs.bump_cycling_adjusting_value != 0 && bms.bump_map) { + CommonFunctions.adjustBumpOffset(bms, ccs.bump_cycling_adjusting_value); + } - if(ss.slopes) { - ss.SlopeAngle += color_cycling_adjusting_value; - ss.SlopeAngle = ss.SlopeAngle % 360.0; + if (ccs.light_cycling_adjusting_value != 0 && ls.lighting) { + CommonFunctions.adjustLightOffset(ls, ccs.light_cycling_adjusting_value); + } - double lightAngleRadians = Math.toRadians(ss.SlopeAngle); - ss.lightVector[0] = Math.cos(lightAngleRadians); - ss.lightVector[1] = Math.sin(lightAngleRadians); - } + if(ccs.slope_cycling_adjusting_value != 0 && ss.slopes) { + CommonFunctions.adjustSlopeOffset(ss, ccs.slope_cycling_adjusting_value); } for (int y = FROMy; y < TOy; y++) { @@ -5218,11 +5372,11 @@ private void colorCycling() { ptr.getMainPanel().repaint(); - if (cycle_colors) { + if (ccs.color_cycling_adjusting_value != 0) { ptr.updatePalettePreview(color_cycling_location_outcoloring, color_cycling_location_incoloring); } - if (cycle_gradient) { + if (ccs.gradient_cycling_adjusting_value != 0) { ptr.updateGradientPreview(gradient_offset); } //progress.setForeground(new Color(palette.getPaletteColor(color_cycling_location))); @@ -5234,7 +5388,7 @@ private void colorCycling() { } try { - Thread.sleep(color_cycling_speed + 35); + Thread.sleep(ccs.color_cycling_speed + 35); } catch (InterruptedException ex) { } @@ -6430,10 +6584,6 @@ private void heightProcessing() { applyHeightFunction(); - if (histogramHeight) { - histogramHeight(); - } - if (remove_outliers_post) { if (remove_outliers_sync3.incrementAndGet() == ptr.getNumberOfThreads()) { @@ -8694,12 +8844,12 @@ protected int[] applyScalingToPixel(int index, int[] colors, PixelExtraData[] da return output; } - private int binarySearch(double[] array, double target) { + private int closestPoint(double[] array, double target) { int left = 0; int right = array.length - 1; while (left <= right) { - int mid = left + (right - left) / 2; + int mid = (int)(((long)left + right) >>> 1); if (array[mid] == target) { return mid; @@ -8710,10 +8860,10 @@ private int binarySearch(double[] array, double target) { } } - return -1; // Target value not found + return right; } - protected int[] applyHistogramToPixel(int index, int[] colors, PixelExtraData[] data, int maxCount, int histogramGranularity, double histogramDensity, double[] image_iterations, boolean[] escaped) { + protected int[] applyHistogramToPixel(int index, int[] colors, PixelExtraData[] data, int histogramGranularity, double histogramDensity, double[] image_iterations, boolean[] escaped) { int[] output = new int[colors.length]; @@ -8740,26 +8890,26 @@ protected int[] applyHistogramToPixel(int index, int[] colors, PixelExtraData[] double tempVal = Math.abs(ColorAlgorithm.transformResultToHeight(val, max_iterations)); double diff = 0; - int valIndex = 0; + long valIndex = 0; if (esc) { tempVal = capValue(tempVal, upperFenceEscaped, lowerFenceEscaped); diff = tempVal - minIterationsEscaped; - diff = diff > maxCount ? maxCount : diff; - valIndex = (int) ((diff) / denominatorEscaped * histogramGranularity); + valIndex = (long) ((diff) / denominatorEscaped * histogramGranularity); } else { tempVal = capValue(tempVal, upperFenceNotEscaped, lowerFenceNotEscaped); diff = tempVal - minIterationsNotEscaped; - diff = diff > maxCount ? maxCount : diff; - valIndex = (int) ((diff) / denominatorNotEscaped * histogramGranularity); + valIndex = (long) ((diff) / denominatorNotEscaped * histogramGranularity); } int[] array = esc ? escapedCounts : notEscapedCounts; - double sum = array[valIndex]; + + int valIndexInt = valIndex >= array.length ? array.length - 1 : (int)valIndex; + double sum = array[valIndexInt]; double sumNext = sum; //Find the next cdf val that is greater from the old - for (int i = valIndex + 1; i < array.length; i++) { + for (int i = valIndexInt + 1; i < array.length; i++) { if (array[i] > sum) { sumNext = array[i]; break; @@ -8848,25 +8998,44 @@ protected int[] applyRankOrderMappingToPixel(int index, int[] colors, PixelExtra tempVal = capValue(tempVal, upperFenceNotEscaped, lowerFenceNotEscaped); } + double originalVal = tempVal; tempVal = roundForRankOrder(tempVal); double g1; if (esc) { - int i = binarySearch(arrayEscaped, tempVal); + int i = closestPoint(arrayEscaped, tempVal); if(i != -1) { - g1 = (double)i / arrayEscaped.length; + if(arrayEscaped[i] == tempVal) { + g1 = (double) i / (arrayEscaped.length - 1); + } + else if(i + 1 >= arrayEscaped.length) { + g1 = 1.0; + } + else { + double in = i + ((originalVal - arrayEscaped[i])/(arrayEscaped[i + 1] - arrayEscaped[i])); + g1 = in / (arrayEscaped.length - 1); + } } else { g1 = 0; } } else { - int i = binarySearch(arraynotEscaped, tempVal); + int i = closestPoint(arraynotEscaped, tempVal); if(i != -1) { - g1 = (double)i / arraynotEscaped.length; + if(arraynotEscaped[i] == tempVal) { + g1 = (double)i / (arraynotEscaped.length - 1); + } + else if(i + 1 >= arraynotEscaped.length) { + g1 = 1.0; + } + else { + double in = i + ((originalVal - arraynotEscaped[i])/(arraynotEscaped[i + 1] - arraynotEscaped[i])); + g1 = in / (arraynotEscaped.length - 1); + } } else { g1 = 0; @@ -8974,13 +9143,36 @@ private double[] getFences(ArrayList data) { } } + public static boolean INCLUDE_AA_DATA_ON_RANK_ORDER = false; + private double roundForRankOrder(double val) { - return Math.floor(100 * val + 0.5) / 100; + if(hss.rank_order_digits_grouping == 0) { + return Math.floor(val + 0.5); + } + else if(hss.rank_order_digits_grouping == 1) { + return Math.floor(10 * val + 0.5) / 10; + } + else if(hss.rank_order_digits_grouping == 2) { + return Math.floor(100 * val + 0.5) / 100; + } + else if(hss.rank_order_digits_grouping == 3) { + return Math.floor(1000 * val + 0.5) / 1000; + } + else if(hss.rank_order_digits_grouping == 4) { + return Math.floor(10000 * val + 0.5) / 10000; + } + else if(hss.rank_order_digits_grouping == 5) { + return Math.floor(100000 * val + 0.5) / 100000; + } + else if(hss.rank_order_digits_grouping == 6) { + return Math.floor(1000000 * val + 0.5) / 1000000; + } + + return Math.floor(10000000 * val + 0.5) / 10000000; } private void initializeHistogramColoring(double[] image_iterations, boolean[] escaped) { - int maxCount = 1000000; int mapping = hss.hmapping; int histogramGranularity = hss.histogramBinGranularity; @@ -9122,14 +9314,16 @@ private void initializeHistogramColoring(double[] image_iterations, boolean[] es if(mapping == 0) { if (maxIterationEscaped != -Double.MAX_VALUE && minIterationsEscaped != Double.MAX_VALUE) { double diff = maxIterationEscaped - minIterationsEscaped; - diff = diff > maxCount ? maxCount : diff; - escapedCounts = new int[((int) ((diff + 1) * histogramGranularity))]; + long total = ((long)((diff + 1) * histogramGranularity)); + total = total > Integer.MAX_VALUE ? Integer.MAX_VALUE : total; + escapedCounts = new int[(int)total]; } if (maxIterationNotEscaped != -Double.MAX_VALUE && minIterationsNotEscaped != Double.MAX_VALUE) { double diff = maxIterationNotEscaped - minIterationsNotEscaped; - diff = diff > maxCount ? maxCount : diff; - notEscapedCounts = new int[((int) ((diff + 1) * histogramGranularity))]; + long total = ((long)((diff + 1) * histogramGranularity)); + total = total > Integer.MAX_VALUE ? Integer.MAX_VALUE : total; + notEscapedCounts = new int[(int)total]; } if (maxIterationEscaped < 1 && minIterationsEscaped < 1) { @@ -9168,8 +9362,9 @@ private void initializeHistogramColoring(double[] image_iterations, boolean[] es } else { double diff = val - minIterationsEscaped; - diff = diff > maxCount ? maxCount : diff; - escapedCounts[(int) ((diff) / denominatorEscaped * histogramGranularity)]++; + long id = (long) ((diff) / denominatorEscaped * histogramGranularity); + id = id >= escapedCounts.length ? escapedCounts.length - 1 : id; + escapedCounts[(int)id]++; } totalEscaped++; } else { @@ -9180,8 +9375,9 @@ private void initializeHistogramColoring(double[] image_iterations, boolean[] es } else { double diff = val - minIterationsNotEscaped; - diff = diff > maxCount ? maxCount : diff; - notEscapedCounts[(int) ((diff) / denominatorNotEscaped * histogramGranularity)]++; + long id = (long) ((diff) / denominatorNotEscaped * histogramGranularity); + id = id >= notEscapedCounts.length ? notEscapedCounts.length - 1 : id; + notEscapedCounts[(int)id]++; } totalNotEscaped++; } @@ -9238,7 +9434,6 @@ else if(mapping == 6) { private void initializeHistogramColoring(PixelExtraData[] data) { - int maxCount = 1000000; int mapping = hss.hmapping; int histogramGranularity = hss.histogramBinGranularity; @@ -9383,14 +9578,16 @@ private void initializeHistogramColoring(PixelExtraData[] data) { if(mapping == 0) { if (maxIterationEscaped != -Double.MAX_VALUE && minIterationsEscaped != Double.MAX_VALUE) { double diff = maxIterationEscaped - minIterationsEscaped; - diff = diff > maxCount ? maxCount : diff; - escapedCounts = new int[((int) ((diff + 1) * histogramGranularity))]; + long total = ((long)((diff + 1) * histogramGranularity)); + total = total > Integer.MAX_VALUE ? Integer.MAX_VALUE : total; + escapedCounts = new int[(int)total]; } if (maxIterationNotEscaped != -Double.MAX_VALUE && minIterationsNotEscaped != Double.MAX_VALUE) { double diff = maxIterationNotEscaped - minIterationsNotEscaped; - diff = diff > maxCount ? maxCount : diff; - notEscapedCounts = new int[((int) ((diff + 1) * histogramGranularity))]; + long total = ((long)((diff + 1) * histogramGranularity)); + total = total > Integer.MAX_VALUE ? Integer.MAX_VALUE : total; + notEscapedCounts = new int[(int)total]; } if (maxIterationEscaped < 1 && minIterationsEscaped < 1) { @@ -9408,7 +9605,14 @@ private void initializeHistogramColoring(PixelExtraData[] data) { ArrayList listnotEscaped; for(int j = 0; j < data.length; j++) { - for (int i = 0; i < data[j].values.length; i++) { + int length; + if(mapping == 6 && INCLUDE_AA_DATA_ON_RANK_ORDER) { + length = data[j].values.length; + } + else { + length = mapping == 6 ? Math.min(1, data[j].values.length) : data[j].values.length; + } + for (int i = 0; i < length; i++) { double val = data[j].values[i]; if (isMaximumIterations(val)) { @@ -9429,8 +9633,9 @@ private void initializeHistogramColoring(PixelExtraData[] data) { } else { double diff = val - minIterationsEscaped; - diff = diff > maxCount ? maxCount : diff; - escapedCounts[(int) ((diff) / denominatorEscaped * histogramGranularity)]++; + long id = (long) ((diff) / denominatorEscaped * histogramGranularity); + id = id >= escapedCounts.length ? escapedCounts.length - 1 : id; + escapedCounts[(int)id]++; } totalEscaped++; } else { @@ -9440,8 +9645,9 @@ private void initializeHistogramColoring(PixelExtraData[] data) { } else { double diff = val - minIterationsNotEscaped; - diff = diff > maxCount ? maxCount : diff; - notEscapedCounts[(int) ((diff) / denominatorNotEscaped * histogramGranularity)]++; + long id = (long) ((diff) / denominatorNotEscaped * histogramGranularity); + id = id >= notEscapedCounts.length ? notEscapedCounts.length - 1 : id; + notEscapedCounts[(int)id]++; } totalNotEscaped++; @@ -9501,11 +9707,10 @@ else if(mapping == 6) { private int[] finalizeHistogramColoring(double[] image_iterations, PixelExtraData[] data, int[] colors, int i, int j, int image_size, boolean[] escaped) { double histogramDensity = hss.histogramDensity; - int maxCount = 1000000; int mapping = hss.hmapping; int histogramGranularity = hss.histogramBinGranularity; if(mapping == 0) { - return applyHistogramToPixel(i * image_size + j, colors, data, maxCount, histogramGranularity, histogramDensity, image_iterations, escaped); + return applyHistogramToPixel(i * image_size + j, colors, data, histogramGranularity, histogramDensity, image_iterations, escaped); } else if(mapping == 6) { return applyRankOrderMappingToPixel(i * image_size + j, colors, data, image_iterations, escaped); @@ -9516,138 +9721,6 @@ else if(mapping == 6) { } - private void histogramHeight() { - - int maxCount = 1000000; - int HIST_MULT = histogram_granularity; - - histogramDenominator = 1; - - try { - if (normalize_find_ranges_sync_3d.await() == 0) { - maxIterations3d = -Double.MAX_VALUE; - minIterations3d = Double.MAX_VALUE; - totalCounts = 0; - - for (int x = 0; x < detail; x++) { - for (int y = 0; y < detail; y++) { - double val = Math.abs(vert[x][y]); - - if (Double.isNaN(val) || Double.isInfinite(val)) { - continue; - } - - maxIterations3d = val > maxIterations3d ? val : maxIterations3d; - minIterations3d = val < minIterations3d ? val : minIterations3d; - } - } - - if (maxIterations3d != -Double.MAX_VALUE && minIterations3d != Double.MAX_VALUE) { - double diff = maxIterations3d - minIterations3d; - diff = diff > maxCount ? maxCount : diff; - histogramCounts = new int[((int) ((diff + 1) * HIST_MULT))]; - } - - - if(minIterations3d < 1 && maxIterations3d < 1) { - histogramDenominator = maxIterations3d - minIterations3d + 1e-12; - } - - for (int x = 0; x < detail; x++) { - for (int y = 0; y < detail; y++) { - double val = Math.abs(vert[x][y]); - - if (Double.isNaN(val) || Double.isInfinite(val)) { - continue; - } - - double diff = val - minIterations3d; - diff = diff > maxCount ? maxCount : diff; - - histogramCounts[(int) ((diff) / histogramDenominator * HIST_MULT)]++; - totalCounts++; - } - } - - if (histogramCounts != null) { - double sum = 0; - for (int i = 0; i < histogramCounts.length; i++) { - histogramCounts[i] += sum; - sum = histogramCounts[i]; - } - } - } - } catch (InterruptedException e) { - - } catch (BrokenBarrierException e) { - - } - - try { - normalize_sync_3d.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - - for (int x = FROMx; x < TOx; x++) { - for (int y = FROMy; y < TOy; y++) { - - double val = vert[x][y]; - - if (Double.isNaN(val) || Double.isInfinite(val)) { - continue; - } - - double tempVal = Math.abs(val); - - double diff = tempVal - minIterations3d; - diff = diff > maxCount ? maxCount : diff; - - int valIndex = (int) ((diff) / histogramDenominator * HIST_MULT); - - double sum = histogramCounts[valIndex]; - - double sumNext = sum; - - //Find the next cdf val that is greater from the old - for (int i = valIndex + 1; i < histogramCounts.length; i++) { - if (histogramCounts[i] > sum) { - sumNext = histogramCounts[i]; - break; - } - } - - double cdfMin = histogramCounts[0]; - double g = 1.0 - Math.pow(1.0 - ((sum - cdfMin) / (totalCounts - cdfMin)), 1.0 / histogram_density); - double g2 = 1.0 - Math.pow(1.0 - ((sumNext - cdfMin) / (totalCounts - cdfMin)), 1.0 / histogram_density); - - double fractionalPart = MathUtils.fract((diff) / histogramDenominator * HIST_MULT); - - g = method.interpolate(g, g2, fractionalPart); - val = g; - - if (Double.isNaN(val) || Double.isInfinite(val)) { - continue; - } - - vert[x][y] = val; - } - } - - try { - if (normalize_sync2_3d.await() == 0) { - histogramCounts = null; - } - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - - } - public static String getDefaultInitialValue() { return default_init_val; @@ -9841,6 +9914,7 @@ public static void resetTaskData(int num_tasks, boolean createFullImageAfterPrev remove_outliers_sync2 = new CyclicBarrier(num_tasks); remove_outliers_sync4 = new CyclicBarrier(num_tasks); normal_drawing_algorithm_pixel = new AtomicInteger(0); + normal_drawing_algorithm_pixel2 = new AtomicInteger(0); apply_skipped_color_pixel = new AtomicInteger(0); draw_squares_pixel = new AtomicInteger(0); quick_draw_drawing_algorithm_pixel = new AtomicInteger[SUCCESSIVE_REFINEMENT_EXPONENT]; @@ -9848,15 +9922,22 @@ public static void resetTaskData(int num_tasks, boolean createFullImageAfterPrev quick_draw_drawing_algorithm_pixel[i] = new AtomicInteger(0); } - successive_refinement_drawing_algorithm_pixel = new AtomicInteger[SUCCESSIVE_REFINEMENT_EXPONENT + 1]; + successive_refinement_drawing_algorithm_pixel = new AtomicInteger[2 * (SUCCESSIVE_REFINEMENT_EXPONENT + 1)]; for(int i = 0; i < successive_refinement_drawing_algorithm_pixel.length; i++) { successive_refinement_drawing_algorithm_pixel[i] = new AtomicInteger(0); } + successive_refinement_drawing_algorithm2_pixel = new AtomicInteger[2 * (2 * SUCCESSIVE_REFINEMENT_EXPONENT + 1)]; + for(int i = 0; i < successive_refinement_drawing_algorithm2_pixel.length; i++) { + successive_refinement_drawing_algorithm2_pixel[i] = new AtomicInteger(0); + } + quick_draw_drawing_algorithm_barrier = new CyclicBarrier(num_tasks); successive_refinement_drawing_algorithm_barrier = new CyclicBarrier(num_tasks); normal_drawing_algorithm_post_processing = new AtomicInteger(0); + normal_drawing_algorithm_post_processing2 = new AtomicInteger(0); normal_drawing_algorithm_apply_palette = new AtomicInteger(0); + normal_drawing_algorithm_apply_palette2 = new AtomicInteger(0); normal_drawing_algorithm_histogram = new AtomicInteger(0); color_cycling_filters_sync = new CyclicBarrier(num_tasks); color_cycling_restart_sync = new CyclicBarrier(num_tasks); @@ -9866,8 +9947,6 @@ public static void resetTaskData(int num_tasks, boolean createFullImageAfterPrev normalize_sync = new CyclicBarrier(num_tasks); normalize_sync2 = new CyclicBarrier(num_tasks); normalize_find_ranges_sync_3d = new CyclicBarrier(num_tasks); - normalize_sync_3d = new CyclicBarrier(num_tasks); - normalize_sync2_3d = new CyclicBarrier(num_tasks); color_cycling_toggle_lock = new ReadWriteLock(); successive_refinement_lock = new ReadWriteLock(); @@ -10439,6 +10518,9 @@ private Fractal fractalFactory(int function, double xCenter, double yCenter, Apf case MainWindow.FORMULA47: fractal = new Formula47(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, out_coloring_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, smoothing, periodicity_checking, plane_type, rotation_vals, rotation_center, perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, user_perturbation_conditions, user_perturbation_condition_formula, perturbation_user_formula, init_val, initial_vals, variable_init_value, user_initial_value_algorithm, user_initial_value_conditions, user_initial_value_condition_formula, initial_value_user_formula, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, escaping_smooth_algorithm, ots, sts); break; + case MainWindow.FORMULA48: + fractal = new Formula48(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, out_coloring_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, smoothing, periodicity_checking, plane_type, rotation_vals, rotation_center, perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, user_perturbation_conditions, user_perturbation_condition_formula, perturbation_user_formula, init_val, initial_vals, variable_init_value, user_initial_value_algorithm, user_initial_value_conditions, user_initial_value_condition_formula, initial_value_user_formula, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, escaping_smooth_algorithm, ots, sts); + break; case MainWindow.PERPENDICULAR_MANDELBROT: fractal = new PerpendicularMandelbrot(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, out_coloring_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, smoothing, periodicity_checking, plane_type, rotation_vals, rotation_center, perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, user_perturbation_conditions, user_perturbation_condition_formula, perturbation_user_formula, init_val, initial_vals, variable_init_value, user_initial_value_algorithm, user_initial_value_conditions, user_initial_value_condition_formula, initial_value_user_formula, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, escaping_smooth_algorithm, ots, sts); break; @@ -11615,12 +11697,12 @@ private Fractal fractalFactory(int function, double xCenter, double yCenter, Apf fractal.setFunctionId(function); if(ptr != null) { - if(ptr.getSettings().hasConvergentBailoutCondition()) { + if(ptr.getSettings().hasConvergentBailout()) { fractal.ConvergentBailoutConditionFactory(cbs.convergent_bailout_test_algorithm, fractal.getConvergentBailout(), cbs.convergent_bailout_test_user_formula, cbs.convergent_bailout_test_user_formula2, cbs.convergent_bailout_test_comparison, cbs.convergent_n_norm, plane_transform_center); } } else if(ptrExpander != null) { - if(ptrExpander.getSettings().hasConvergentBailoutCondition()) { + if(ptrExpander.getSettings().hasConvergentBailout()) { fractal.ConvergentBailoutConditionFactory(cbs.convergent_bailout_test_algorithm, fractal.getConvergentBailout(), cbs.convergent_bailout_test_user_formula, cbs.convergent_bailout_test_user_formula2, cbs.convergent_bailout_test_comparison, cbs.convergent_n_norm, plane_transform_center); } } @@ -11922,6 +12004,9 @@ private Fractal juliaFactory(int function, double xCenter, double yCenter, Apfl case MainWindow.FORMULA47: fractal = new Formula47(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, out_coloring_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, smoothing, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, escaping_smooth_algorithm, ots, sts, xJuliaCenter, yJuliaCenter); break; + case MainWindow.FORMULA48: + fractal = new Formula48(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, out_coloring_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, smoothing, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, escaping_smooth_algorithm, ots, sts, xJuliaCenter, yJuliaCenter); + break; case MainWindow.PERPENDICULAR_MANDELBROT: fractal = new PerpendicularMandelbrot(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, out_coloring_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, smoothing, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, escaping_smooth_algorithm, ots, sts, xJuliaCenter, yJuliaCenter); break; @@ -12048,12 +12133,12 @@ private Fractal juliaFactory(int function, double xCenter, double yCenter, Apfl fractal.influencePlaneFactory(ips); if(ptr != null) { - if(ptr.getSettings().hasConvergentBailoutCondition()) { + if(ptr.getSettings().hasConvergentBailout()) { fractal.ConvergentBailoutConditionFactory(cbs.convergent_bailout_test_algorithm, fractal.getConvergentBailout(), cbs.convergent_bailout_test_user_formula, cbs.convergent_bailout_test_user_formula2, cbs.convergent_bailout_test_comparison, cbs.convergent_n_norm, plane_transform_center); } } else if(ptrExpander != null) { - if(ptrExpander.getSettings().hasConvergentBailoutCondition()) { + if(ptrExpander.getSettings().hasConvergentBailout()) { fractal.ConvergentBailoutConditionFactory(cbs.convergent_bailout_test_algorithm, fractal.getConvergentBailout(), cbs.convergent_bailout_test_user_formula, cbs.convergent_bailout_test_user_formula2, cbs.convergent_bailout_test_comparison, cbs.convergent_n_norm, plane_transform_center); } } @@ -12175,14 +12260,14 @@ else if(TaskDraw.HIGH_PRECISION_LIB == Constants.ARBITRARY_MPFR && LibMpfr.hasEr return Constants.ARBITRARY_DOUBLEDOUBLE; } - if(f.supportsBigIntnum()) { - return Constants.ARBITRARY_BIGINT; - } - if(f.supportsBignum()) { return Constants.ARBITRARY_BUILT_IN; } + if(f.supportsBigIntnum()) { + return Constants.ARBITRARY_BIGINT; + } + return Constants.ARBITRARY_APFLOAT; } else if(TaskDraw.HIGH_PRECISION_LIB == Constants.ARBITRARY_MPIR && !LibMpir.hasError()) { @@ -12202,14 +12287,14 @@ else if(TaskDraw.HIGH_PRECISION_LIB == Constants.ARBITRARY_MPIR && LibMpir.hasEr return Constants.ARBITRARY_DOUBLEDOUBLE; } - if(f.supportsBigIntnum()) { - return Constants.ARBITRARY_BIGINT; - } - if(f.supportsBignum()) { return Constants.ARBITRARY_BUILT_IN; } + if(f.supportsBigIntnum()) { + return Constants.ARBITRARY_BIGINT; + } + return Constants.ARBITRARY_APFLOAT; } else if(TaskDraw.HIGH_PRECISION_LIB == Constants.ARBITRARY_AUTOMATIC) { @@ -12218,22 +12303,22 @@ else if(TaskDraw.HIGH_PRECISION_LIB == Constants.ARBITRARY_AUTOMATIC) { return Constants.ARBITRARY_DOUBLEDOUBLE; } - if(!LibMpir.hasError() && f.supportsMpirBignum() && (MpirBigNum.precision >= 1500 || (!f.supportsBigIntnum() && !f.supportsBignum()))) { + if(!LibMpir.hasError() && f.supportsMpirBignum() && (MpirBigNum.precision >= 1200 || (!f.supportsBigIntnum() && !f.supportsBignum()))) { return Constants.ARBITRARY_MPIR; } - if(!LibMpfr.hasError() && f.supportsMpfrBignum() && (MpfrBigNum.precision >= 1800 || (!f.supportsBigIntnum() && !f.supportsBignum()))) { + if(!LibMpfr.hasError() && f.supportsMpfrBignum() && (MpfrBigNum.precision >= 1350 || (!f.supportsBigIntnum() && !f.supportsBignum()))) { return Constants.ARBITRARY_MPFR; } - if(f.supportsBigIntnum()) { - return Constants.ARBITRARY_BIGINT; - } - if(f.supportsBignum()) { return Constants.ARBITRARY_BUILT_IN; } + if(f.supportsBigIntnum()) { + return Constants.ARBITRARY_BIGINT; + } + return Constants.ARBITRARY_APFLOAT; } @@ -12303,6 +12388,10 @@ else if(TaskDraw.BIGNUM_LIBRARY == Constants.BIGNUM_MPFR && LibMpfr.hasError()) return Constants.BIGNUM_DOUBLEDOUBLE; } + if(f.supportsBignum()) { + return Constants.BIGNUM_BUILT_IN; + } + if(f.supportsBigIntnum()) { return Constants.BIGNUM_BIGINT; } @@ -12333,6 +12422,10 @@ else if(TaskDraw.BIGNUM_LIBRARY == Constants.BIGNUM_MPIR && LibMpir.hasError()) return Constants.BIGNUM_DOUBLEDOUBLE; } + if(f.supportsBignum()) { + return Constants.BIGNUM_BUILT_IN; + } + if(f.supportsBigIntnum()) { return Constants.BIGNUM_BIGINT; } @@ -12348,41 +12441,41 @@ else if(TaskDraw.BIGNUM_LIBRARY == Constants.BIGNUM_AUTOMATIC) { return Constants.BIGNUM_DOUBLEDOUBLE; } - if(!LibMpir.hasError() && f.supportsMpirBignum() && (MpirBigNum.precision >= 1500 || (!f.supportsBigIntnum() && !f.supportsBignum()))) { //(f.supportsPeriod() && DETECT_PERIOD && MpfrBigNum.precision >= 450) + if(!LibMpir.hasError() && f.supportsMpirBignum() && (MpirBigNum.precision >= 1200 || (!f.supportsBigIntnum() && !f.supportsBignum()))) { //(f.supportsPeriod() && DETECT_PERIOD && MpfrBigNum.precision >= 450) return Constants.BIGNUM_MPIR; } - if(!LibMpfr.hasError() && f.supportsMpfrBignum() && (MpfrBigNum.precision >= 1800 || (!f.supportsBigIntnum() && !f.supportsBignum()))) { //(f.supportsPeriod() && DETECT_PERIOD && MpfrBigNum.precision >= 450) + if(!LibMpfr.hasError() && f.supportsMpfrBignum() && (MpfrBigNum.precision >= 1350 || (!f.supportsBigIntnum() && !f.supportsBignum()))) { //(f.supportsPeriod() && DETECT_PERIOD && MpfrBigNum.precision >= 450) return Constants.BIGNUM_MPFR; } - if(f.supportsBigIntnum()) { - return Constants.BIGNUM_BIGINT; - } - if(f.supportsBignum()) { return Constants.BIGNUM_BUILT_IN; } + if(f.supportsBigIntnum()) { + return Constants.BIGNUM_BIGINT; + } + return Constants.BIGNUM_APFLOAT; } else if(TaskDraw.BIGNUM_LIBRARY == Constants.BIGNUM_AUTOMATIC_ONLY_BIGNUM) { - if(!LibMpir.hasError() && f.supportsMpirBignum() && (MpirBigNum.precision >= 1500 || (!f.supportsBigIntnum() && !f.supportsBignum()))) { //(f.supportsPeriod() && DETECT_PERIOD && MpfrBigNum.precision >= 450) + if(!LibMpir.hasError() && f.supportsMpirBignum() && (MpirBigNum.precision >= 1200 || (!f.supportsBigIntnum() && !f.supportsBignum()))) { //(f.supportsPeriod() && DETECT_PERIOD && MpfrBigNum.precision >= 450) return Constants.BIGNUM_MPIR; } - if(!LibMpfr.hasError() && f.supportsMpfrBignum() && (MpfrBigNum.precision >= 1800 || (!f.supportsBigIntnum() && !f.supportsBignum()))) { //(f.supportsPeriod() && DETECT_PERIOD && MpfrBigNum.precision >= 450) + if(!LibMpfr.hasError() && f.supportsMpfrBignum() && (MpfrBigNum.precision >= 1350 || (!f.supportsBigIntnum() && !f.supportsBignum()))) { //(f.supportsPeriod() && DETECT_PERIOD && MpfrBigNum.precision >= 450) return Constants.BIGNUM_MPFR; } - if(f.supportsBigIntnum()) { - return Constants.BIGNUM_BIGINT; - } - if(f.supportsBignum()) { return Constants.BIGNUM_BUILT_IN; } + if(f.supportsBigIntnum()) { + return Constants.BIGNUM_BIGINT; + } + return Constants.BIGNUM_APFLOAT; } @@ -12438,8 +12531,8 @@ public static boolean useExtendedRange(Apfloat size, Fractal f) { if(RefIteration == nextBigDataIter) { DeltaSubN.Normalize(); DeltaSub0.Normalize(); - GenericComplex p = new BigNumComplex(new BigNum(DeltaSubN.getRe()), new BigNum(DeltaSubN.getIm())); - GenericComplex c = new BigNumComplex(new BigNum(DeltaSub0.getRe()), new BigNum(DeltaSub0.getIm())); + GenericComplex p = new BigNumComplex(BigNum.create(DeltaSubN.getRe()), BigNum.create(DeltaSubN.getIm())); + GenericComplex c = new BigNumComplex(BigNum.create(DeltaSub0.getRe()), BigNum.create(DeltaSub0.getIm())); DeltaSubN = Mandelbrot.BigData.get(nextBigDataIndex).times2().plus_mutable(p).times_mutable(p).plus_mutable(c).toMantExpComplex(); //return getArrayDeepValue(referenceDeep, RefIteration).times2_mutable().plus_mutable(DeltaSubN).times_mutable(DeltaSubN).plus_mutable(DeltaSub0); } @@ -12452,7 +12545,7 @@ public static boolean useExtendedRange(Apfloat size, Fractal f) { if (max_iterations > 1) { if(RefIteration == nextBigDataIter) { DeltaSubN.Normalize(); - GenericComplex p = new BigNumComplex(new BigNum(DeltaSubN.getRe()), new BigNum(DeltaSubN.getIm())); + GenericComplex p = new BigNumComplex(BigNum.create(DeltaSubN.getRe()), BigNum.create(DeltaSubN.getIm())); z = Mandelbrot.BigData.get(nextBigDataIndex).plus(p).toMantExpComplex(); } else { @@ -12495,6 +12588,13 @@ public static boolean useExtendedRange(Apfloat size, Fractal f) { }*/ + public void initializeHighPrecision() { + Fractal.total_iterations = new LongAdder(); + Fractal.total_min_iterations = new LongAccumulator(Math::min, Long.MAX_VALUE); + Fractal.total_max_iterations = new LongAccumulator(Math::max, Long.MIN_VALUE); + Fractal.total_max_iterations_ignore_max_iter = new LongAccumulator(Math::max, Long.MIN_VALUE); + } + public void calculateReference(Location loc) { Fractal.ReferenceCalculationTime = 0; @@ -12512,8 +12612,10 @@ public void calculateReference(Location loc) { Fractal.total_float_exp_iterations = new LongAdder(); Fractal.total_rebases = new LongAdder(); Fractal.total_realigns = new LongAdder(); + Fractal.total_iterations = new LongAdder(); Fractal.total_min_iterations = new LongAccumulator(Math::min, Long.MAX_VALUE); Fractal.total_max_iterations = new LongAccumulator(Math::max, Long.MIN_VALUE); + Fractal.total_max_iterations_ignore_max_iter = new LongAccumulator(Math::max, Long.MIN_VALUE); int old_max = progress.getMaximum(); int cur_val = progress.getValue(); @@ -12583,10 +12685,12 @@ else if(APPROXIMATION_ALGORITHM == 2 && fractal.supportsBilinearApproximation() else if(APPROXIMATION_ALGORITHM == 4 && fractal.supportsBilinearApproximation2() && (loc.getSize().compareToBothPositive(Fractal.BLA2Size) != 0 || fractal.BLA2ParamsDiffer() - || (isDeep && fractal.useFullFloatExp() != Fractal.BLA2UsedFullFloatExp))) { + || (isDeep && fractal.useFullFloatExp() != Fractal.BLA2UsedFullFloatExp) + || Fractal.laReference == null || !Fractal.laReference.isValid)) { if(Fractal.laReference == null || - fractal.BLA2ParamsDiffer() + !Fractal.laReference.isValid + || fractal.BLA2ParamsDiffer() || (isDeep && fractal.useFullFloatExp() != Fractal.BLA2UsedFullFloatExp) //|| (isDeep && !fractal.useFullFloatExp()) || (isDeep && fractal.useFullFloatExp() && LAReference.CONVERT_TO_DOUBLE_WHEN_POSSIBLE) diff --git a/src/fractalzoomer/core/Waypoint.java b/src/fractalzoomer/core/Waypoint.java new file mode 100644 index 000000000..acb991e96 --- /dev/null +++ b/src/fractalzoomer/core/Waypoint.java @@ -0,0 +1,53 @@ +package fractalzoomer.core; + +public class Waypoint { + public int iteration; + public Complex z; + public MantExpComplex mz; + + public int index; + public boolean rebase; + + public Waypoint() { + + } + + public Waypoint(int iterationIn, int indexIn) { + iteration = iterationIn; + index = indexIn; + } + + public Waypoint(Complex zIn, int iterationIn, int indexIn) { + z = zIn; + iteration = iterationIn; + index = indexIn; + } + + public Waypoint(Complex zIn, int iterationIn) { + z = zIn; + iteration = iterationIn; + } + + public Waypoint(Complex zIn, int iterationIn, boolean rebase) { + z = zIn; + iteration = iterationIn; + this.rebase = rebase; + } + + public Waypoint(MantExpComplex zIn, int iterationIn) { + mz = zIn; + iteration = iterationIn; + } + + public Waypoint(MantExpComplex zIn, int iterationIn, boolean rebase) { + mz = zIn; + iteration = iterationIn; + this.rebase = rebase; + } + + public Waypoint(MantExpComplex zIn, int iterationIn, int indexIn) { + mz = zIn; + iteration = iterationIn; + index = indexIn; + } +} diff --git a/src/fractalzoomer/core/antialiasing/MeanNoOutliersAntialiasingAlgorithm.java b/src/fractalzoomer/core/antialiasing/MeanNoOutliersAntialiasingAlgorithm.java index 57938a85c..b09d3fd00 100644 --- a/src/fractalzoomer/core/antialiasing/MeanNoOutliersAntialiasingAlgorithm.java +++ b/src/fractalzoomer/core/antialiasing/MeanNoOutliersAntialiasingAlgorithm.java @@ -72,26 +72,28 @@ private Object[] getSumAndSamples(double[] vals) { double upper_quartile = calculateMedian(vals, (vals.length + 1) / 2, vals.length); double iqr = upper_quartile - lower_quartile; - if (iqr == 0) { - double mean = 0; - double variance = 0; - int samples = 0; - for (int i = 0; i < vals.length; i++) { - samples++; - double delta = vals[i] - mean; - mean += delta / samples; - double delta2 = vals[i] - mean; - variance += delta * delta2; - } - double sigma = Math.sqrt(variance / samples); - double temp = 3 * sigma; - lower_fence = mean - temp; - upper_fence = mean + temp; - } else { - double temp = 1.5 * iqr; - lower_fence = lower_quartile - temp; - upper_fence = upper_quartile + temp; + double temp = 1.5 * iqr; + double lower_fence2 = lower_quartile - temp; + double upper_fence2 = upper_quartile + temp; + + double mean = 0; + double variance = 0; + int samples = 0; + for (int i = 0; i < vals.length; i++) { + samples++; + double delta = vals[i] - mean; + mean += delta / samples; + double delta2 = vals[i] - mean; + variance += delta * delta2; } + double sigma = Math.sqrt(variance / samples); + double temp2 = 3 * sigma; + double lower_fence1 = mean - temp2; + double upper_fence1 = mean + temp2; + + lower_fence = Math.max(lower_fence1, lower_fence2); + upper_fence = Math.min(upper_fence1, upper_fence2); + } double sum = 0; diff --git a/src/fractalzoomer/core/bla/BLAS.java b/src/fractalzoomer/core/bla/BLAS.java index c059ef3c6..eb5ba0271 100644 --- a/src/fractalzoomer/core/bla/BLAS.java +++ b/src/fractalzoomer/core/bla/BLAS.java @@ -6,6 +6,7 @@ import javax.swing.*; import java.util.ArrayList; +import java.util.concurrent.Future; import java.util.stream.IntStream; import static fractalzoomer.main.Constants.BLA_CALCULATION_STR; @@ -24,12 +25,17 @@ public class BLAS { private int firstLevel; private boolean returnL1; + private long finalTotal; + + private ReferenceDecompressor[] referenceDecompressors; + private ReferenceDecompressor referenceDecompressor; + public BLAS(Fractal fractal) { this.fractal = fractal; } - private BLADeep createOneStep(DeepReference Ref, int m, MantExp epsilon) { - MantExpComplex Z = Fractal.getArrayDeepValue(Ref, m); + private BLADeep createOneStep(DeepReference Ref, int m, MantExp epsilon, ReferenceDecompressor referenceDecompressor) { + MantExpComplex Z = fractal.getArrayDeepValue(referenceDecompressor, Ref, m); MantExpComplex A = fractal.getBlaA(Z); MantExp mA = A.hypot(); @@ -44,15 +50,15 @@ private BLADeep createOneStep(DeepReference Ref, int m, MantExp epsilon) { return BLADeep1Step.create(r2, A); } - private void initLStep(int level, int m, DoubleReference Ref, double blaSize, double epsilon) { + private void initLStep(int level, int m, DoubleReference Ref, double blaSize, double epsilon, ReferenceDecompressor referenceDecompressor) { - b[level][m - 1] = createLStep(level, m, Ref, blaSize, epsilon); + b[level][m - 1] = createLStep(level, m, Ref, blaSize, epsilon, referenceDecompressor); } - private void initLStep(int level, int m, DeepReference Ref, MantExp blaSize, MantExp epsilon) { + private void initLStep(int level, int m, DeepReference Ref, MantExp blaSize, MantExp epsilon, ReferenceDecompressor referenceDecompressor) { - bdeep[level][m - 1] = createLStep(level, m, Ref, blaSize, epsilon); + bdeep[level][m - 1] = createLStep(level, m, Ref, blaSize, epsilon, referenceDecompressor); } @@ -93,10 +99,10 @@ private BLADeep mergeTwoBlas(BLADeep x, BLADeep y, MantExp blaSize) { return BLADeepLStep.create(r2, A, B, l); } - private BLA createLStep(int level, int m, DoubleReference Ref, double blaSize, double epsilon) { + private BLA createLStep(int level, int m, DoubleReference Ref, double blaSize, double epsilon, ReferenceDecompressor referenceDecompressor) { if(level == 0) { - return createOneStep(Ref, m, epsilon); + return createOneStep(Ref, m, epsilon, referenceDecompressor); } int m2 = m << 1; @@ -105,21 +111,21 @@ private BLA createLStep(int level, int m, DoubleReference Ref, double blaSize, d int levelm1 = level - 1; if (my <= elementsPerLevel[levelm1]) { - BLA x = createLStep(levelm1, mx, Ref, blaSize, epsilon); + BLA x = createLStep(levelm1, mx, Ref, blaSize, epsilon, referenceDecompressor); - BLA y = createLStep(levelm1, my, Ref, blaSize, epsilon); + BLA y = createLStep(levelm1, my, Ref, blaSize, epsilon, referenceDecompressor); return mergeTwoBlas(x, y, blaSize); } else { - return createLStep(levelm1, mx, Ref, blaSize, epsilon); + return createLStep(levelm1, mx, Ref, blaSize, epsilon, referenceDecompressor); } } - private BLADeep createLStep(int level, int m, DeepReference Ref, MantExp blaSize, MantExp epsilon) { + private BLADeep createLStep(int level, int m, DeepReference Ref, MantExp blaSize, MantExp epsilon, ReferenceDecompressor referenceDecompressor) { if(level == 0) { - return createOneStep(Ref, m, epsilon); + return createOneStep(Ref, m, epsilon, referenceDecompressor); } int m2 = m << 1; @@ -127,18 +133,18 @@ private BLADeep createLStep(int level, int m, DeepReference Ref, MantExp blaSize int my = m2; int levelm1 = level - 1; if (my <= elementsPerLevel[levelm1]) { - BLADeep x = createLStep(levelm1, mx, Ref, blaSize, epsilon); + BLADeep x = createLStep(levelm1, mx, Ref, blaSize, epsilon, referenceDecompressor); - BLADeep y = createLStep(levelm1, my, Ref, blaSize, epsilon); + BLADeep y = createLStep(levelm1, my, Ref, blaSize, epsilon, referenceDecompressor); return mergeTwoBlas(x, y, blaSize); } else { - return createLStep(levelm1, mx, Ref, blaSize, epsilon); + return createLStep(levelm1, mx, Ref, blaSize, epsilon, referenceDecompressor); } } - private BLA createOneStep(DoubleReference Ref, int m, double epsilon) { - Complex Z = Fractal.getArrayValue(Ref, m); + private BLA createOneStep(DoubleReference Ref, int m, double epsilon, ReferenceDecompressor referenceDecompressor) { + Complex Z = fractal.getArrayValue(referenceDecompressor, Ref, m); Complex A = fractal.getBlaA(Z); double mA = A.hypot(); @@ -157,30 +163,61 @@ private void init(DoubleReference Ref, double blaSize, double epsilon, JProgress int elements = elementsPerLevel[firstLevel] + 1; if(TaskDraw.USE_THREADS_FOR_BLA) { done = 0; //we dont care fore race condition - long mainId = Thread.currentThread().getId(); - long expectedVal = done + elements; + ArrayList> futures = new ArrayList<>(); + final int ThreadCount = TaskDraw.la_thread_executor.getCorePoolSize(); + Runnable[] Tasks = new Runnable[ThreadCount]; + long expectedVal = done + elements; old_chunk = 0; - IntStream.range(1, elements). - parallel().forEach(m -> { - initLStep(firstLevel, m, Ref, blaSize, epsilon); - if (progress != null) { - if (Thread.currentThread().getId() == mainId) { - done++; - long val = done; - - long new_chunk = val / 1000; - - if(old_chunk != new_chunk) { - setProgress(progress, val, divisor); - old_chunk = new_chunk; + + try { + for (int i = 0; i < Tasks.length; i++) { + final int k = i; + Tasks[i] = new Runnable() { + int ThreadID = k; + @Override + public void run() { + int Start = (int)((long)elements * ThreadID / ThreadCount); + int End = (int)((long)elements * (ThreadID + 1) / ThreadCount); + + Start = ThreadID == 0 ? Start + 1 : Start; + + ReferenceDecompressor referenceDecompressor = referenceDecompressors[ThreadID]; + + for(int m = Start; m < End; m++) { + initLStep(firstLevel, m, Ref, blaSize, epsilon, referenceDecompressor); + + if (progress != null) { + if (ThreadID == 0) { + done++; + long val = done; + + long new_chunk = val / 1000; + + if(old_chunk != new_chunk) { + setProgress(progress, val, divisor); + old_chunk = new_chunk; + } + } else { + done++; + } } - } else { - done++; } + } - }); + }; + } + + for (int i = 0; i < Tasks.length; i++) { + futures.add(TaskDraw.la_thread_executor.submit(Tasks[i])); + } + + for (int i = 0; i < futures.size(); i++) { + futures.get(i).get(); + } + } + catch (Exception ex) {} //Fix for thread race condition if (progress != null && expectedVal > done) { @@ -192,7 +229,7 @@ private void init(DoubleReference Ref, double blaSize, double epsilon, JProgress else { done = 0; for(int m = 1; m < elements; m++) { - initLStep(firstLevel, m, Ref, blaSize, epsilon); + initLStep(firstLevel, m, Ref, blaSize, epsilon, referenceDecompressor); if (progress != null) { done++; long val = done; @@ -224,31 +261,58 @@ private void init(DeepReference Ref, MantExp blaSize, MantExp epsilon, JProgress if(TaskDraw.USE_THREADS_FOR_BLA) { done = 0; //we dont care for race conditions - long mainId = Thread.currentThread().getId(); - old_chunk = 0; + ArrayList> futures = new ArrayList<>(); + final int ThreadCount = TaskDraw.la_thread_executor.getCorePoolSize(); + Runnable[] Tasks = new Runnable[ThreadCount]; long expectedVal = done + elements; + old_chunk = 0; - IntStream.range(1, elements). - parallel().forEach(m -> { - initLStep(firstLevel, m , Ref, blaSize, epsilon); - if (progress != null) { - if (Thread.currentThread().getId() == mainId) { - done++; - long val = done; - long new_chunk = val / 1000; - - if(old_chunk != new_chunk) { - setProgress(progress, val, divisor); - old_chunk = new_chunk; + try { + for (int i = 0; i < Tasks.length; i++) { + final int k = i; + Tasks[i] = new Runnable() { + int ThreadID = k; + @Override + public void run() { + int Start = (int)((long)elements * ThreadID / ThreadCount); + int End = (int)((long)elements * (ThreadID + 1) / ThreadCount); + ReferenceDecompressor referenceDecompressor = referenceDecompressors[ThreadID]; + + Start = ThreadID == 0 ? Start + 1 : Start; + + for(int m = Start; m < End; m++) { + initLStep(firstLevel, m , Ref, blaSize, epsilon, referenceDecompressor); + if (progress != null) { + if (ThreadID == 0) { + done++; + long val = done; + long new_chunk = val / 1000; + + if(old_chunk != new_chunk) { + setProgress(progress, val, divisor); + old_chunk = new_chunk; + } + } else { + done++; + } } - } else { - done++; } + } - } - ); + }; + } + + for (int i = 0; i < Tasks.length; i++) { + futures.add(TaskDraw.la_thread_executor.submit(Tasks[i])); + } + + for (int i = 0; i < futures.size(); i++) { + futures.get(i).get(); + } + } + catch (Exception ex) {} //Fix for thread race condition if (progress != null && expectedVal > done) { @@ -260,7 +324,7 @@ private void init(DeepReference Ref, MantExp blaSize, MantExp epsilon, JProgress else { done = 0; for(int m = 1; m < elements; m++) { - initLStep(firstLevel, m , Ref, blaSize, epsilon); + initLStep(firstLevel, m , Ref, blaSize, epsilon, referenceDecompressor); if (progress != null) { done++; long val = done; @@ -309,8 +373,6 @@ private void merge(double blaSize, JProgressBar progress, long divisor) { boolean useThreadsForBla = TaskDraw.USE_THREADS_FOR_BLA; - long mainId = Thread.currentThread().getId(); - int elementsDst = 0; int src = firstLevel; int maxLevel = elementsPerLevel.length - 1; @@ -326,28 +388,55 @@ private void merge(double blaSize, JProgressBar progress, long divisor) { if(useThreadsForBla) { - long expectedVal = done + elementsDst; - - IntStream.range(0, elementsDst). - parallel().forEach(m -> { - mergeOneStep(m, elementsSrcFinal, srcFinal, destFinal, blaSize); + ArrayList> futures = new ArrayList<>(); + final int ThreadCount = TaskDraw.la_thread_executor.getCorePoolSize(); + Runnable[] Tasks = new Runnable[ThreadCount]; - if (progress != null) { - if (Thread.currentThread().getId() == mainId) { - done++; - long val = done; - long new_chunk = val / 1000; + long expectedVal = done + elementsDst; - if(old_chunk != new_chunk) { - setProgress(progress, val, divisor); - old_chunk = new_chunk; + try { + for (int i = 0; i < Tasks.length; i++) { + final int k = i; + final int elementsDstFinal = elementsDst; + Tasks[i] = new Runnable() { + int ThreadID = k; + @Override + public void run() { + int Start = (int)((long)elementsDstFinal * ThreadID / ThreadCount); + int End = (int)((long)elementsDstFinal * (ThreadID + 1) / ThreadCount); + + for(int m = Start; m < End; m++) { + mergeOneStep(m, elementsSrcFinal, srcFinal, destFinal, blaSize); + + if (progress != null) { + if (ThreadID == 0) { + done++; + long val = done; + long new_chunk = val / 1000; + + if(old_chunk != new_chunk) { + setProgress(progress, val, divisor); + old_chunk = new_chunk; + } + } else { + done++; + } } - } else { - done++; } + } + }; } - ); + + for (int i = 0; i < Tasks.length; i++) { + futures.add(TaskDraw.la_thread_executor.submit(Tasks[i])); + } + + for (int i = 0; i < futures.size(); i++) { + futures.get(i).get(); + } + } + catch (Exception ex) {} //Fix for thread race condition if (progress != null && expectedVal > done) { @@ -385,8 +474,6 @@ private void merge(MantExp blaSize, JProgressBar progress, long divisor) { boolean useThreadsForBla = TaskDraw.USE_THREADS_FOR_BLA; - long mainId = Thread.currentThread().getId(); - int elementsDst = 0; int src = firstLevel; int maxLevel = elementsPerLevel.length - 1; @@ -402,28 +489,55 @@ private void merge(MantExp blaSize, JProgressBar progress, long divisor) { if(useThreadsForBla) { - long expectedVal = done + elementsDst; + ArrayList> futures = new ArrayList<>(); + final int ThreadCount = TaskDraw.la_thread_executor.getCorePoolSize(); + Runnable[] Tasks = new Runnable[ThreadCount]; - IntStream.range(0, elementsDst). - parallel().forEach(m -> { - mergeOneStep(m, elementsSrcFinal, srcFinal, destFinal, blaSize); - - if (progress != null) { - if (Thread.currentThread().getId() == mainId) { - done++; - long val = done; - long new_chunk = val / 1000; + long expectedVal = done + elementsDst; - if(old_chunk != new_chunk) { - setProgress(progress, val, divisor); - old_chunk = new_chunk; + try { + for (int i = 0; i < Tasks.length; i++) { + final int k = i; + final int elementsDstFinal = elementsDst; + Tasks[i] = new Runnable() { + int ThreadID = k; + @Override + public void run() { + int Start = (int)((long)elementsDstFinal * ThreadID / ThreadCount); + int End = (int)((long)elementsDstFinal * (ThreadID + 1) / ThreadCount); + + for(int m = Start; m < End; m++) { + mergeOneStep(m, elementsSrcFinal, srcFinal, destFinal, blaSize); + + if (progress != null) { + if (ThreadID == 0) { + done++; + long val = done; + long new_chunk = val / 1000; + + if(old_chunk != new_chunk) { + setProgress(progress, val, divisor); + old_chunk = new_chunk; + } + } else { + done++; + } } - } else { - done++; } + } + }; + } + + for (int i = 0; i < Tasks.length; i++) { + futures.add(TaskDraw.la_thread_executor.submit(Tasks[i])); + } + + for (int i = 0; i < futures.size(); i++) { + futures.get(i).get(); } - ); + } + catch (Exception ex) {} //Fix for thread race condition if (progress != null && expectedVal > done) { @@ -485,7 +599,7 @@ public void init(int M, DoubleReference Ref, double blaSize, JProgressBar progre elementsPerLevel = elemPerLevel.stream().mapToInt(i -> i).toArray(); - long finalTotal = total; + finalTotal = total; long removedTotal = 0; if(firstLevel > 0) { @@ -515,6 +629,19 @@ public void init(int M, DoubleReference Ref, double blaSize, JProgressBar progre b[l] = new BLA[elementsPerLevel[l]]; } + if(Ref.compressed) { + referenceDecompressor = fractal.getReferenceDecompressors()[Ref.id]; + } + + if(TaskDraw.USE_THREADS_FOR_BLA) { + referenceDecompressors = new ReferenceDecompressor[TaskDraw.la_thread_executor.getCorePoolSize()]; + if (referenceDecompressor != null) { + for (int i = 0; i < referenceDecompressors.length; i++) { + referenceDecompressors[i] = new ReferenceDecompressor(referenceDecompressor); + } + } + } + init(Ref, blaSize, precision, progress, divisor); merge(blaSize, progress, divisor); @@ -555,7 +682,7 @@ public void init(int M, DeepReference Ref, MantExp blaSize, JProgressBar progres elementsPerLevel = elemPerLevel.stream().mapToInt(i -> i).toArray(); - long finalTotal = total; + finalTotal = total; long removedTotal = 0; if(firstLevel > 0) { @@ -584,6 +711,19 @@ public void init(int M, DeepReference Ref, MantExp blaSize, JProgressBar progres bdeep[l] = new BLADeep[elementsPerLevel[l]]; } + if(Ref.compressed) { + referenceDecompressor = fractal.getReferenceDecompressors()[Ref.id]; + } + + if(TaskDraw.USE_THREADS_FOR_BLA) { + referenceDecompressors = new ReferenceDecompressor[TaskDraw.la_thread_executor.getCorePoolSize()]; + if (referenceDecompressor != null) { + for (int i = 0; i < referenceDecompressors.length; i++) { + referenceDecompressors[i] = new ReferenceDecompressor(referenceDecompressor); + } + } + } + init(Ref, blaSize, precision, progress, divisor); merge(blaSize, progress, divisor); @@ -596,6 +736,10 @@ public void init(int M, DeepReference Ref, MantExp blaSize, JProgressBar progres isValid = true; } + public long getTotalElements() { + return finalTotal; + } + public BLA lookup(int m, double z2, int iterations, int max_iterations) { if (m == 0) { return null; diff --git a/src/fractalzoomer/core/domain_coloring/DomainColoring.java b/src/fractalzoomer/core/domain_coloring/DomainColoring.java index 9973edc1c..06e70b7cf 100644 --- a/src/fractalzoomer/core/domain_coloring/DomainColoring.java +++ b/src/fractalzoomer/core/domain_coloring/DomainColoring.java @@ -183,23 +183,32 @@ else if (coloring_mode == 5){ return 0; } - + + public int getColoringMode() { + return coloring_mode; + } + + public static final int HSB_COLOR_LENGTH = 100; + private static double HSB_COLOR_FACTOR = 1.0 / HSB_COLOR_LENGTH; public static int HSBcolor(double h, int color_cycling_location) { - return Color.HSBtoRGB((float) ((h + color_cycling_location * 0.01) % 1.0), TaskDraw.HSB_CONSTANT_S, TaskDraw.HSB_CONSTANT_B); + return Color.HSBtoRGB((float) ((h + color_cycling_location * HSB_COLOR_FACTOR) % 1.0), TaskDraw.HSB_CONSTANT_S, TaskDraw.HSB_CONSTANT_B); } + + public static final int LCH_COLOR_LENGTH = 100; + private static double LCH_COLOR_FACTOR = 1.0 / LCH_COLOR_LENGTH; public static int LCHabcolor(double h, int color_cycling_location) { - int [] res = ColorSpaceConverter.LCH_abtoRGB(TaskDraw.LCHab_CONSTANT_L, TaskDraw.LCHab_CONSTANT_C, ((h + color_cycling_location * 0.01) % 1.0) * 360); + int [] res = ColorSpaceConverter.LCH_abtoRGB(TaskDraw.LCHab_CONSTANT_L, TaskDraw.LCHab_CONSTANT_C, ((h + color_cycling_location * LCH_COLOR_FACTOR) % 1.0) * 360); return 0xFF000000 | res[0] << 16 | res[1] << 8 | res[2]; } public static int LCHuvcolor(double h, int color_cycling_location) { - int [] res = ColorSpaceConverter.LCH_uvtoRGB(TaskDraw.LCHuv_CONSTANT_L, TaskDraw.LCHuv_CONSTANT_C, ((h + color_cycling_location * 0.01) % 1.0) * 360); + int [] res = ColorSpaceConverter.LCH_uvtoRGB(TaskDraw.LCHuv_CONSTANT_L, TaskDraw.LCHuv_CONSTANT_C, ((h + color_cycling_location * 0.01) % LCH_COLOR_FACTOR) * 360); return 0xFF000000 | res[0] << 16 | res[1] << 8 | res[2]; } @@ -216,6 +225,22 @@ public static int Cubehelix3(double h, int color_cycling_location) { } + public static int getDomainColoringPaletteLength(int domain_coloring_mode) { + if(domain_coloring_mode == 4) { + return Cubehelix.cubehelix3.length; + } + else if(domain_coloring_mode == 3) { + return Cubehelix.defaultMap.length; + } + else if(domain_coloring_mode == 0) { + return HSB_COLOR_LENGTH; + } + else if(domain_coloring_mode == 2 || domain_coloring_mode == 5) { + return LCH_COLOR_LENGTH; + } + return 0; + } + protected int applyArgColor(double arg) { double h = (arg + Math.PI) / ( Math.PI * 2); @@ -225,7 +250,7 @@ protected int applyArgColor(double arg) { } // private double fract(double x) { -// return x - (int)x; +// return x - (long)x; // } /*protected int applyArgColor2(double arg, double r) { diff --git a/src/fractalzoomer/core/drawing_algorithms/BoundaryTracing2Draw.java b/src/fractalzoomer/core/drawing_algorithms/BoundaryTracing2Draw.java index 65a2bda31..4a64bc983 100644 --- a/src/fractalzoomer/core/drawing_algorithms/BoundaryTracing2Draw.java +++ b/src/fractalzoomer/core/drawing_algorithms/BoundaryTracing2Draw.java @@ -99,20 +99,7 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (PERTURBATION_THEORY || HIGH_PRECISION_CALCULATION) && fractal.supportsPerturbationTheory()); - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); int pixel_percent = (image_size * image_size) / 100; diff --git a/src/fractalzoomer/core/drawing_algorithms/BoundaryTracing3Draw.java b/src/fractalzoomer/core/drawing_algorithms/BoundaryTracing3Draw.java index d0651af41..1eafea255 100644 --- a/src/fractalzoomer/core/drawing_algorithms/BoundaryTracing3Draw.java +++ b/src/fractalzoomer/core/drawing_algorithms/BoundaryTracing3Draw.java @@ -427,20 +427,7 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (PERTURBATION_THEORY || HIGH_PRECISION_CALCULATION) && fractal.supportsPerturbationTheory()); - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); int pixel_percent = (image_size * image_size) / 100; diff --git a/src/fractalzoomer/core/drawing_algorithms/BoundaryTracingColorsAndIterationDataDraw.java b/src/fractalzoomer/core/drawing_algorithms/BoundaryTracingColorsAndIterationDataDraw.java index 94981171f..3efdc1638 100644 --- a/src/fractalzoomer/core/drawing_algorithms/BoundaryTracingColorsAndIterationDataDraw.java +++ b/src/fractalzoomer/core/drawing_algorithms/BoundaryTracingColorsAndIterationDataDraw.java @@ -88,20 +88,7 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi int last_drawing_done = 0; int totalPixels = (TOx - FROMx) * (TOy - FROMy); - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); Location location2 = Location.getCopy(location); @@ -579,21 +566,7 @@ protected void drawIterationsAntialiased(int image_size, boolean polar) throws S PixelExtraData temp_starting_pixel_extra_data = null; - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - - location.setReference(Fractal.refPoint); - } + initialize(location); Location location2 = Location.getCopy(location); diff --git a/src/fractalzoomer/core/drawing_algorithms/BoundaryTracingDraw.java b/src/fractalzoomer/core/drawing_algorithms/BoundaryTracingDraw.java index 58a85fc75..5bd2f9b40 100644 --- a/src/fractalzoomer/core/drawing_algorithms/BoundaryTracingDraw.java +++ b/src/fractalzoomer/core/drawing_algorithms/BoundaryTracingDraw.java @@ -89,20 +89,7 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi int last_drawing_done = 0; int totalPixels = (TOx - FROMx) * (TOy - FROMy); - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); Location location2 = Location.getCopy(location); @@ -574,21 +561,7 @@ protected void drawIterationsAntialiased(int image_size, boolean polar) throws S PixelExtraData temp_starting_pixel_extra_data = null; - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - - location.setReference(Fractal.refPoint); - } + initialize(location); Location location2 = Location.getCopy(location); diff --git a/src/fractalzoomer/core/drawing_algorithms/BruteForce2Draw.java b/src/fractalzoomer/core/drawing_algorithms/BruteForce2Draw.java index 98dc6ff1b..1080dd94c 100644 --- a/src/fractalzoomer/core/drawing_algorithms/BruteForce2Draw.java +++ b/src/fractalzoomer/core/drawing_algorithms/BruteForce2Draw.java @@ -79,20 +79,7 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi int x, y, loc; - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); long time = System.currentTimeMillis(); @@ -146,20 +133,7 @@ protected void drawIterationsAntialiased(int image_size, boolean polar) throws S AntialiasingAlgorithm aa = AntialiasingAlgorithm.getAntialiasingAlgorithm(totalSamples, aaMethod, aaAvgWithMean, colorSpace, fs.aaSigmaR, fs.aaSigmaS); - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); aa.setNeedsPostProcessing(needsPostProcessing()); diff --git a/src/fractalzoomer/core/drawing_algorithms/BruteForceDraw.java b/src/fractalzoomer/core/drawing_algorithms/BruteForceDraw.java index ab59134a4..dc65a426b 100644 --- a/src/fractalzoomer/core/drawing_algorithms/BruteForceDraw.java +++ b/src/fractalzoomer/core/drawing_algorithms/BruteForceDraw.java @@ -63,8 +63,8 @@ public BruteForceDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, A super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, fast_julia_filters, image, periodicity_checking, fs, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); } - public BruteForceDraw(int FROMx, int TOx, int FROMy, int TOy, int max_iterations, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, int color_cycling_location, int color_cycling_location2, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, int color_cycling_speed, FiltersSettings fs, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, boolean cycle_colors, boolean cycle_lights, boolean cycle_gradient, int color_cycling_adjusting_value, DomainColoringSettings ds, int gradient_offset, double contourFactor, boolean smoothing, GeneratedPaletteSettings gps, PostProcessSettings pps) { - super(FROMx, TOx, FROMy, TOy, max_iterations, ptr, fractal_color, dem_color, image, color_cycling_location, color_cycling_location2, color_cycling_speed, fs, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, cycle_colors, cycle_lights, cycle_gradient, color_cycling_adjusting_value, ds, gradient_offset, contourFactor, smoothing, gps, pps); + public BruteForceDraw(int FROMx, int TOx, int FROMy, int TOy, int max_iterations, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, int color_cycling_location, int color_cycling_location2, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, FiltersSettings fs, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, DomainColoringSettings ds, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, PostProcessSettings pps, ColorCyclingSettings ccs) { + super(FROMx, TOx, FROMy, TOy, max_iterations, ptr, fractal_color, dem_color, image, color_cycling_location, color_cycling_location2, fs, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, ds, gradient_offset, contourFactor, gps, pps, ccs); } public BruteForceDraw(int FROMx, int TOx, int FROMy, int TOy, int max_iterations, MainWindow ptr, BufferedImage image, Color fractal_color, Color dem_color, int color_cycling_location, int color_cycling_location2, FiltersSettings fs, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, DomainColoringSettings ds, int gradient_offset, double contourFactor, boolean smoothing, GeneratedPaletteSettings gps, PostProcessSettings pps) { @@ -91,37 +91,23 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi int condition = image_size * image_size; - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - - location.setReference(Fractal.refPoint); - } + initialize(location); boolean escaped_val; double f_val; + int thread_chunk_size = getThreadChunkSize(image_size, CHUNK_SIZE_PER_ROW); long time = System.currentTimeMillis(); do { - loc = THREAD_CHUNK_SIZE * normal_drawing_algorithm_pixel.getAndIncrement(); + loc = thread_chunk_size * normal_drawing_algorithm_pixel.getAndIncrement(); if(loc >= condition) { break; } - for(int count = 0; count < THREAD_CHUNK_SIZE && loc < condition; count++, loc++) { + for(int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { x = loc % image_size; y = loc / image_size; @@ -173,20 +159,7 @@ protected void drawIterationsAntialiased(int image_size, boolean polar) throws S int totalSamples = supersampling_num + 1; AntialiasingAlgorithm aa = AntialiasingAlgorithm.getAntialiasingAlgorithm(totalSamples, aaMethod, aaAvgWithMean, colorSpace, fs.aaSigmaR, fs.aaSigmaS); - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); boolean escaped_val; double f_val; @@ -195,17 +168,19 @@ protected void drawIterationsAntialiased(int image_size, boolean polar) throws S boolean storeExtraData = pixelData != null; + int thread_chunk_size = getThreadChunkSize(image_size, CHUNK_SIZE_PER_ROW); + long time = System.currentTimeMillis(); do { - loc = THREAD_CHUNK_SIZE * normal_drawing_algorithm_pixel.getAndIncrement(); + loc = thread_chunk_size * normal_drawing_algorithm_pixel.getAndIncrement(); if(loc >= condition) { break; } - for(int count = 0; count < THREAD_CHUNK_SIZE && loc < condition; count++, loc++) { + for(int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { x = loc % image_size; y = loc / image_size; @@ -237,18 +212,16 @@ protected void drawIterationsAntialiased(int image_size, boolean polar) throws S rgbs[loc] = aa.getColor(); drawing_done++; + task_calculated++; } if(drawing_done / pixel_percent >= 1) { update(drawing_done); - task_calculated += drawing_done; drawing_done = 0; } } while(true); - task_calculated += drawing_done; - pixel_calculation_time_per_task = System.currentTimeMillis() - time; postProcess(image_size, aa, location); @@ -279,18 +252,20 @@ protected void drawFastJulia(int image_size, boolean polar) { int condition = image_size * image_size; + int thread_chunk_size = getThreadChunkSize(image_size, CHUNK_SIZE_PER_ROW); + boolean escaped_val; double f_val; do { - loc = THREAD_CHUNK_SIZE * normal_drawing_algorithm_pixel.getAndIncrement(); + loc = thread_chunk_size * normal_drawing_algorithm_pixel.getAndIncrement(); if(loc >= condition) { break; } - for(int count = 0; count < THREAD_CHUNK_SIZE && loc < condition; count++, loc++) { + for(int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { x = loc % image_size; y = loc / image_size; @@ -351,15 +326,17 @@ protected void drawFastJuliaAntialiased(int image_size, boolean polar) { boolean storeExtraData = pixelData_fast_julia != null; + int thread_chunk_size = getThreadChunkSize(image_size, CHUNK_SIZE_PER_ROW); + do { - loc = THREAD_CHUNK_SIZE * normal_drawing_algorithm_pixel.getAndIncrement(); + loc = thread_chunk_size * normal_drawing_algorithm_pixel.getAndIncrement(); if(loc >= condition) { break; } - for(int count = 0; count < THREAD_CHUNK_SIZE && loc < condition; count++, loc++) { + for(int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { x = loc % image_size; y = loc / image_size; @@ -424,15 +401,17 @@ protected void applyPostProcessingPointFilter(int image_size, double[] image_ite int x, y, loc; int condition = image_size * image_size; + int thread_chunk_size = getThreadChunkSize(image_size, CHUNK_SIZE_PER_ROW); + do { - loc = THREAD_CHUNK_SIZE * normal_drawing_algorithm_post_processing.getAndIncrement(); + loc = thread_chunk_size * normal_drawing_algorithm_post_processing.getAndIncrement(); if(loc >= condition) { break; } - for(int count = 0; count < THREAD_CHUNK_SIZE && loc < condition; count++, loc++) { + for(int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { x = loc % image_size; y = loc / image_size; @@ -465,17 +444,19 @@ protected void changePaletteWithAA(int image_size) throws StopSuccessiveRefineme PixelExtraData data; task_completed = 0; + int thread_chunk_size = getThreadChunkSize(image_size, CHUNK_SIZE_PER_ROW); + long time = System.currentTimeMillis(); do { - loc = THREAD_CHUNK_SIZE * normal_drawing_algorithm_apply_palette.getAndIncrement(); + loc = thread_chunk_size * normal_drawing_algorithm_apply_palette.getAndIncrement(); if(loc >= condition) { break; } - for(int count = 0; count < THREAD_CHUNK_SIZE && loc < condition; count++, loc++) { + for(int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { data = pixelData[loc]; data.update_rgb(0, color = getStandardColor(data.values[0], data.escaped[0])); @@ -519,17 +500,19 @@ protected void changePalette(int image_size) throws StopSuccessiveRefinementExce int condition = image_size * image_size; task_completed = 0; + int thread_chunk_size = getThreadChunkSize(image_size, CHUNK_SIZE_PER_ROW); + long time = System.currentTimeMillis(); do { - loc = THREAD_CHUNK_SIZE * normal_drawing_algorithm_apply_palette.getAndIncrement(); + loc = thread_chunk_size * normal_drawing_algorithm_apply_palette.getAndIncrement(); if(loc >= condition) { break; } - for(int count = 0; count < THREAD_CHUNK_SIZE && loc < condition; count++, loc++) { + for(int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { if (domain_coloring) { rgbs[loc] = domain_color.getDomainColor(new Complex(domain_image_data_re[loc], domain_image_data_im[loc])); } else { @@ -565,17 +548,19 @@ protected void drawIterationsDomain(int image_size, boolean polar) { int condition = image_size * image_size; + int thread_chunk_size = getThreadChunkSize(image_size, CHUNK_SIZE_PER_ROW); + long time = System.currentTimeMillis(); do { - loc = THREAD_CHUNK_SIZE * normal_drawing_algorithm_pixel.getAndIncrement(); + loc = thread_chunk_size * normal_drawing_algorithm_pixel.getAndIncrement(); if (loc >= condition) { break; } - for (int count = 0; count < THREAD_CHUNK_SIZE && loc < condition; count++, loc++) { + for (int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { x = loc % image_size; y = loc / image_size; @@ -640,17 +625,19 @@ protected void drawIterationsDomainAntialiased(int image_size, boolean polar) { double f_val; + int thread_chunk_size = getThreadChunkSize(image_size, CHUNK_SIZE_PER_ROW); + long time = System.currentTimeMillis(); do { - loc = THREAD_CHUNK_SIZE * normal_drawing_algorithm_pixel.getAndIncrement(); + loc = thread_chunk_size * normal_drawing_algorithm_pixel.getAndIncrement(); if (loc >= condition) { break; } - for (int count = 0; count < THREAD_CHUNK_SIZE && loc < condition; count++, loc++) { + for (int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { x = loc % image_size; y = loc / image_size; @@ -687,18 +674,16 @@ protected void drawIterationsDomainAntialiased(int image_size, boolean polar) { rgbs[loc] = aa.getColor(); drawing_done++; + task_calculated++; } if (drawing_done / pixel_percent >= 1) { update(drawing_done); - task_calculated += drawing_done; drawing_done = 0; } } while (true); - task_calculated += drawing_done; - pixel_calculation_time_per_task = System.currentTimeMillis() - time; try { diff --git a/src/fractalzoomer/core/drawing_algorithms/BruteForceInterleavedDraw.java b/src/fractalzoomer/core/drawing_algorithms/BruteForceInterleavedDraw.java new file mode 100644 index 000000000..dd34a7fa1 --- /dev/null +++ b/src/fractalzoomer/core/drawing_algorithms/BruteForceInterleavedDraw.java @@ -0,0 +1,719 @@ +/* + * Fractal Zoomer, Copyright (C) 2020 hrkalona2 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package fractalzoomer.core.drawing_algorithms; + +import fractalzoomer.core.Complex; +import fractalzoomer.core.PixelExtraData; +import fractalzoomer.core.TaskDraw; +import fractalzoomer.core.antialiasing.AntialiasingAlgorithm; +import fractalzoomer.core.location.Location; +import fractalzoomer.functions.Fractal; +import fractalzoomer.main.Constants; +import fractalzoomer.main.ImageExpanderWindow; +import fractalzoomer.main.MainWindow; +import fractalzoomer.main.app_settings.*; +import fractalzoomer.utils.StopSuccessiveRefinementException; +import org.apfloat.Apfloat; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * + * @author kaloch + */ +public class BruteForceInterleavedDraw extends TaskDraw { + + public BruteForceInterleavedDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, D3Settings d3s, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, boolean quickDraw, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, d3s, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, quickDraw, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps); + } + + public BruteForceInterleavedDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, ImageExpanderWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps); + } + + public BruteForceInterleavedDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, D3Settings d3s, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, boolean quickDraw, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps, Apfloat xJuliaCenter, Apfloat yJuliaCenter) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, d3s, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, quickDraw, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); + } + + public BruteForceInterleavedDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, ImageExpanderWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps, Apfloat xJuliaCenter, Apfloat yJuliaCenter) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); + } + + public BruteForceInterleavedDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps); + } + + public BruteForceInterleavedDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, MainWindow ptr, Color fractal_color, Color dem_color, boolean fast_julia_filters, BufferedImage image, boolean periodicity_checking, FiltersSettings fs, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps, Apfloat xJuliaCenter, Apfloat yJuliaCenter) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, fast_julia_filters, image, periodicity_checking, fs, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); + } + + public BruteForceInterleavedDraw(int FROMx, int TOx, int FROMy, int TOy, int max_iterations, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, int color_cycling_location, int color_cycling_location2, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, FiltersSettings fs, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, DomainColoringSettings ds, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, PostProcessSettings pps, ColorCyclingSettings ccs) { + super(FROMx, TOx, FROMy, TOy, max_iterations, ptr, fractal_color, dem_color, image, color_cycling_location, color_cycling_location2, fs, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, ds, gradient_offset, contourFactor, gps, pps, ccs); + } + + public BruteForceInterleavedDraw(int FROMx, int TOx, int FROMy, int TOy, int max_iterations, MainWindow ptr, BufferedImage image, Color fractal_color, Color dem_color, int color_cycling_location, int color_cycling_location2, FiltersSettings fs, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, DomainColoringSettings ds, int gradient_offset, double contourFactor, boolean smoothing, GeneratedPaletteSettings gps, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, max_iterations, ptr, image, fractal_color, dem_color, color_cycling_location, color_cycling_location2, fs, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, ds, gradient_offset, contourFactor, smoothing, gps, pps); + } + + public BruteForceInterleavedDraw(int FROMx, int TOx, int FROMy, int TOy, D3Settings d3s, boolean draw_action, MainWindow ptr, BufferedImage image, FiltersSettings fs, BlendingSettings color_blending, double contourFactor, boolean smoothing, GeneratedPaletteSettings gps) { + super(FROMx, TOx, FROMy, TOy, d3s, draw_action, ptr, image, fs, color_blending, contourFactor, smoothing, gps); + } + + public BruteForceInterleavedDraw(int action, int FROMx, int TOx, int FROMy, int TOy, int max_iterations, MainWindow ptr, BufferedImage image, Color fractal_color, Color dem_color, int color_cycling_location, int color_cycling_location2, FiltersSettings fs, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, PostProcessSettings pps, DomainColoringSettings ds) { + super(action, FROMx, TOx, FROMy, TOy, max_iterations, ptr, image, fractal_color, dem_color, color_cycling_location, color_cycling_location2, fs, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, pps, ds); + } + + private void drawIterationsInternal(int condition, int thread_chunk_size, int image_size, int pixel_percent, AtomicInteger dCount, Location location, int a, int b) { + int x, y, loc; + double f_val; + boolean escaped_val; + do { + + loc = thread_chunk_size * (a * dCount.getAndIncrement() + b); + + if(loc >= condition) { + break; + } + + for(int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { + + x = loc % image_size; + y = loc / image_size; + + if(rgbs[loc] >>> 24 != Constants.NORMAL_ALPHA) { + image_iterations[loc] = f_val = iteration_algorithm.calculate(location.getComplex(x, y)); + escaped[loc] = escaped_val = iteration_algorithm.escaped(); + rgbs[loc] = getFinalColor(f_val, escaped_val); + task_calculated++; + } + + drawing_done++; + } + + if(drawing_done / pixel_percent >= 1) { + update(drawing_done); + drawing_done = 0; + } + + } while(true); + } + + @Override + protected void drawIterations(int image_size, boolean polar) throws StopSuccessiveRefinementException { + + Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (PERTURBATION_THEORY || HIGH_PRECISION_CALCULATION) && fractal.supportsPerturbationTheory()); + + int pixel_percent = (image_size * image_size) / 100; + + int condition = image_size * image_size; + + initialize(location); + + int thread_chunk_size = getThreadChunkSize(image_size, true); + + long time = System.currentTimeMillis(); + drawIterationsInternal(condition, thread_chunk_size, image_size, pixel_percent, normal_drawing_algorithm_pixel, location, 2, 0); + drawIterationsInternal(condition, thread_chunk_size, image_size, pixel_percent, normal_drawing_algorithm_pixel2, location, 2, 1); + pixel_calculation_time_per_task = System.currentTimeMillis() - time; + + postProcess(image_size, null, location); + } + + private void drawIterationsAntialiasedInternal(int condition, int thread_chunk_size, int image_size, int pixel_percent, boolean storeExtraData, AntialiasingAlgorithm aa, int supersampling_num, int totalSamples, AtomicInteger dCount, Location location, int a, int b) { + int x, y, loc; + double f_val, temp_result; + boolean escaped_val; + int color; + + do { + + loc = thread_chunk_size * (a * dCount.getAndIncrement() + b); + + if(loc >= condition) { + break; + } + + for(int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { + x = loc % image_size; + y = loc / image_size; + + image_iterations[loc] = f_val = iteration_algorithm.calculate(location.getComplex(x, y)); + escaped[loc] = escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(f_val, escaped_val); + + if(storeExtraData) { + pixelData[loc].set(0, color, f_val, escaped_val, totalSamples); + } + + aa.initialize(color); + + //Supersampling + for(int i = 0; i < supersampling_num; i++) { + temp_result = iteration_algorithm.calculate(location.getAntialiasingComplex(i, loc)); + escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(temp_result, escaped_val); + + if(storeExtraData) { + pixelData[loc].set(i + 1, color, temp_result, escaped_val, totalSamples); + } + + if(!aa.addSample(color)) { + break; + } + } + + rgbs[loc] = aa.getColor(); + + drawing_done++; + task_calculated++; + } + + if(drawing_done / pixel_percent >= 1) { + update(drawing_done); + drawing_done = 0; + } + + } while(true); + } + + @Override + protected void drawIterationsAntialiased(int image_size, boolean polar) throws StopSuccessiveRefinementException { + + int aaMethod = (filters_options_vals[MainWindow.ANTIALIASING] % 100) / 10; + boolean useJitter = aaMethod != 6 && ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x4) == 4; + Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (PERTURBATION_THEORY || HIGH_PRECISION_CALCULATION) && fractal.supportsPerturbationTheory()); + int aaSamplesIndex = (filters_options_vals[MainWindow.ANTIALIASING] % 100) % 10; + int supersampling_num = getExtraSamples(aaSamplesIndex, aaMethod); + location.createAntialiasingSteps(aaMethod == 5, useJitter, supersampling_num); + + int pixel_percent = (image_size * image_size) / 100; + + int condition = image_size * image_size; + + boolean aaAvgWithMean = ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x1) == 1; + int colorSpace = filters_options_extra_vals[0][MainWindow.ANTIALIASING]; + int totalSamples = supersampling_num + 1; + AntialiasingAlgorithm aa = AntialiasingAlgorithm.getAntialiasingAlgorithm(totalSamples, aaMethod, aaAvgWithMean, colorSpace, fs.aaSigmaR, fs.aaSigmaS); + + initialize(location); + + aa.setNeedsPostProcessing(needsPostProcessing()); + + boolean storeExtraData = pixelData != null; + + int thread_chunk_size = getThreadChunkSize(image_size, true); + + long time = System.currentTimeMillis(); + drawIterationsAntialiasedInternal(condition, thread_chunk_size, image_size, pixel_percent, storeExtraData, aa, supersampling_num, totalSamples, normal_drawing_algorithm_pixel, location, 2, 0); + drawIterationsAntialiasedInternal(condition, thread_chunk_size, image_size, pixel_percent, storeExtraData, aa, supersampling_num, totalSamples, normal_drawing_algorithm_pixel2, location, 2, 1); + pixel_calculation_time_per_task = System.currentTimeMillis() - time; + + postProcess(image_size, aa, location); + } + + private void drawFastJuliaInternal(int condition, int thread_chunk_size, int image_size, AtomicInteger dCount, Location location, int a, int b) { + boolean escaped_val; + double f_val; + int loc, x, y; + + do { + + loc = thread_chunk_size * (a * dCount.getAndIncrement() + b); + + if(loc >= condition) { + break; + } + + for(int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { + x = loc % image_size; + y = loc / image_size; + + image_iterations_fast_julia[loc] = f_val = iteration_algorithm.calculate(location.getComplex(x, y)); + escaped_fast_julia[loc] = escaped_val = iteration_algorithm.escaped(); + rgbs[loc] = getFinalColor(f_val, escaped_val); + } + + } while(true); + } + + @Override + protected void drawFastJulia(int image_size, boolean polar) { + + Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (PERTURBATION_THEORY || HIGH_PRECISION_CALCULATION) && fractal.supportsPerturbationTheory()); + + if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { + + if (reference_calc_sync.getAndIncrement() == 0) { + calculateReferenceFastJulia(location); + } + + try { + reference_sync.await(); + } catch (InterruptedException ex) { + + } catch (BrokenBarrierException ex) { + + } + location.setReference(Fractal.refPoint); + } + + int condition = image_size * image_size; + + int thread_chunk_size = getThreadChunkSize(image_size, true); + + drawFastJuliaInternal(condition, thread_chunk_size, image_size, normal_drawing_algorithm_pixel, location, 2, 0); + drawFastJuliaInternal(condition, thread_chunk_size, image_size, normal_drawing_algorithm_pixel2, location, 2, 1); + + postProcessFastJulia(image_size, null, location); + + } + + private void drawFastJuliaAntialiasedInternal(int condition, int thread_chunk_size, int image_size, boolean storeExtraData, AntialiasingAlgorithm aa, int supersampling_num, int totalSamples, AtomicInteger dCount, Location location, int a, int b) { + int loc, x, y, color; + double f_val, temp_result; + boolean escaped_val; + do { + + loc = thread_chunk_size * (a * dCount.getAndIncrement() + b); + + if(loc >= condition) { + break; + } + + for(int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { + x = loc % image_size; + y = loc / image_size; + + image_iterations_fast_julia[loc] = f_val = iteration_algorithm.calculate(location.getComplex(x, y)); + escaped_fast_julia[loc] = escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(f_val, escaped_val); + + if(storeExtraData) { + pixelData_fast_julia[loc].set(0, color, f_val, escaped_val, totalSamples); + } + + aa.initialize(color); + + //Supersampling + for(int i = 0; i < supersampling_num; i++) { + temp_result = iteration_algorithm.calculate(location.getAntialiasingComplex(i, loc)); + escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(temp_result, escaped_val); + + if(storeExtraData) { + pixelData_fast_julia[loc].set(i + 1, color, temp_result, escaped_val, totalSamples); + } + + if(!aa.addSample(color)) { + break; + } + } + + rgbs[loc] = aa.getColor(); + } + } while(true); + } + + @Override + protected void drawFastJuliaAntialiased(int image_size, boolean polar) { + + int aaMethod = (filters_options_vals[MainWindow.ANTIALIASING] % 100) / 10; + boolean useJitter = aaMethod != 6 && ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x4) == 4; + Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (PERTURBATION_THEORY || HIGH_PRECISION_CALCULATION) && fractal.supportsPerturbationTheory()); + int aaSamplesIndex = (filters_options_vals[MainWindow.ANTIALIASING] % 100) % 10; + int supersampling_num = getExtraSamples(aaSamplesIndex, aaMethod); + location.createAntialiasingSteps(aaMethod == 5, useJitter, supersampling_num); + + if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { + + if (reference_calc_sync.getAndIncrement() == 0) { + calculateReferenceFastJulia(location); + } + + try { + reference_sync.await(); + } catch (InterruptedException ex) { + + } catch (BrokenBarrierException ex) { + + } + location.setReference(Fractal.refPoint); + } + + int condition = image_size * image_size; + + boolean aaAvgWithMean = ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x1) == 1; + int colorSpace = filters_options_extra_vals[0][MainWindow.ANTIALIASING]; + int totalSamples = supersampling_num + 1; + + AntialiasingAlgorithm aa = AntialiasingAlgorithm.getAntialiasingAlgorithm(totalSamples, aaMethod, aaAvgWithMean, colorSpace, fs.aaSigmaR, fs.aaSigmaS); + + aa.setNeedsPostProcessing(needsPostProcessing()); + + boolean storeExtraData = pixelData_fast_julia != null; + + int thread_chunk_size = getThreadChunkSize(image_size, true); + + drawFastJuliaAntialiasedInternal(condition, thread_chunk_size, image_size, storeExtraData, aa, supersampling_num, totalSamples, normal_drawing_algorithm_pixel, location, 2, 0); + drawFastJuliaAntialiasedInternal(condition, thread_chunk_size, image_size, storeExtraData, aa, supersampling_num, totalSamples, normal_drawing_algorithm_pixel2, location, 2, 1); + + postProcessFastJulia(image_size, aa, location); + } + + private void applyPostProcessingPointFilterInternal(double[] image_iterations, boolean[] escaped, PixelExtraData[] pixelData, int condition, int thread_chunk_size, int image_size, AtomicInteger dCount, Location location, double sizeCorr, double lightx, double lighty, AntialiasingAlgorithm aa, int[] modified, int a, int b) { + int loc, x, y; + do { + + loc = thread_chunk_size * (a * dCount.getAndIncrement() + b); + + if(loc >= condition) { + break; + } + + for(int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { + x = loc % image_size; + y = loc / image_size; + + applyPostProcessingOnPixel(loc, x, y, image_size, image_iterations, escaped, pixelData, aa, modified, sizeCorr, lightx, lighty, location); + + } + + } while(true); + } + + @Override + protected void applyPostProcessingPointFilter(int image_size, double[] image_iterations, boolean[] escaped, PixelExtraData[] pixelData, AntialiasingAlgorithm aa, Location location) { + + if(d3 || action == COLOR_CYCLING) { + super.applyPostProcessingPointFilter(image_size, image_iterations, escaped, pixelData, aa, location); + return; + } + + double sizeCorr = 0, lightx = 0, lighty = 0; + + if (bms.bump_map) { + double gradCorr = Math.pow(2, (bms.bumpMappingStrength - DEFAULT_BUMP_MAPPING_STRENGTH) * 0.05); + sizeCorr = image_size / Math.pow(2, (MAX_BUMP_MAPPING_DEPTH - bms.bumpMappingDepth) * 0.16); + double lightAngleRadians = Math.toRadians(bms.lightDirectionDegrees); + lightx = Math.cos(lightAngleRadians) * gradCorr; + lighty = Math.sin(lightAngleRadians) * gradCorr; + } + + + int[] modified = new int[1]; + + if(aa != null) { + modified = new int[aa.getTotalSamples()]; + aa.setNeedsPostProcessing(false); + } + + int condition = image_size * image_size; + + int thread_chunk_size = getThreadChunkSize(image_size, true); + + applyPostProcessingPointFilterInternal(image_iterations, escaped, pixelData, condition, thread_chunk_size, image_size, normal_drawing_algorithm_post_processing, location, sizeCorr, lightx, lighty, aa, modified, 2, 0); + applyPostProcessingPointFilterInternal(image_iterations, escaped, pixelData, condition, thread_chunk_size, image_size, normal_drawing_algorithm_post_processing2, location, sizeCorr, lightx, lighty, aa, modified, 2, 1); + + } + + private void changePaletteWithAAInternal(int condition, int thread_chunk_size, int pixel_percent, AntialiasingAlgorithm aa, AtomicInteger dCount, int a, int b) { + int loc, color; + PixelExtraData data; + do { + + loc = thread_chunk_size * (a * dCount.getAndIncrement() + b); + + if(loc >= condition) { + break; + } + + for(int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { + data = pixelData[loc]; + data.update_rgb(0, color = getStandardColor(data.values[0], data.escaped[0])); + + aa.initialize(color); + + //Supersampling + int length = data.getActualLength() - 1; + for(int i = 0; i < length; i++) { + data.update_rgb(i + 1, color = getFinalColor(data.values[i + 1], data.escaped[i + 1])); + + if(!aa.addSample(color)) { + break; + } + } + + rgbs[loc] = aa.getColor(); + + drawing_done++; + task_completed++; + } + + if (drawing_done / pixel_percent >= 1) { + update(drawing_done); + drawing_done = 0; + } + + } while(true); + } + + @Override + protected void changePaletteWithAA(int image_size) throws StopSuccessiveRefinementException { + + int aaMethod = (filters_options_vals[MainWindow.ANTIALIASING] % 100) / 10; + int aaSamplesIndex = (filters_options_vals[MainWindow.ANTIALIASING] % 100) % 10; + boolean aaAvgWithMean = ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x1) == 1; + int colorSpace = filters_options_extra_vals[0][MainWindow.ANTIALIASING]; + int supersampling_num = getExtraSamples(aaSamplesIndex, aaMethod); + int totalSamples = supersampling_num + 1; + AntialiasingAlgorithm aa = AntialiasingAlgorithm.getAntialiasingAlgorithm(totalSamples, aaMethod, aaAvgWithMean, colorSpace, fs.aaSigmaR, fs.aaSigmaS); + + aa.setNeedsPostProcessing(true); + + int condition = image_size * image_size; + + int pixel_percent = (image_size * image_size) / 100; + + task_completed = 0; + + int thread_chunk_size = getThreadChunkSize(image_size, true); + + long time = System.currentTimeMillis(); + + changePaletteWithAAInternal(condition, thread_chunk_size, pixel_percent, aa, normal_drawing_algorithm_apply_palette, 2, 0); + changePaletteWithAAInternal(condition, thread_chunk_size, pixel_percent, aa, normal_drawing_algorithm_apply_palette2, 2, 1); + + pixel_calculation_time_per_task = System.currentTimeMillis() - time; + + postProcess(image_size, aa, null); + + } + + private void changePaletteInternal(int condition, int thread_chunk_size, int pixel_percent, AtomicInteger dCount, int a, int b) { + int loc; + do { + + loc = thread_chunk_size * (a * dCount.getAndIncrement() + b); + + if(loc >= condition) { + break; + } + + for(int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { + if (domain_coloring) { + rgbs[loc] = domain_color.getDomainColor(new Complex(domain_image_data_re[loc], domain_image_data_im[loc])); + } else { + rgbs[loc] = getStandardColor(image_iterations[loc], escaped[loc]); + } + + drawing_done++; + task_completed++; + } + + if (drawing_done / pixel_percent >= 1) { + update(drawing_done); + drawing_done = 0; + } + + } while(true); + } + + @Override + protected void changePalette(int image_size) throws StopSuccessiveRefinementException { + + int pixel_percent = (image_size * image_size) / 100; + + int condition = image_size * image_size; + task_completed = 0; + + int thread_chunk_size = getThreadChunkSize(image_size, true); + + long time = System.currentTimeMillis(); + + changePaletteInternal(condition, thread_chunk_size, pixel_percent, normal_drawing_algorithm_apply_palette, 2, 0); + changePaletteInternal(condition, thread_chunk_size, pixel_percent, normal_drawing_algorithm_apply_palette2, 2, 1); + + pixel_calculation_time_per_task = System.currentTimeMillis() - time; + + postProcess(image_size, null, null); + + } + + private void drawIterationsDomainInternal(int condition, int thread_chunk_size, int image_size, int pixel_percent, AtomicInteger dCount, Location location, int a, int b) { + int loc, x, y; + do { + + loc = thread_chunk_size * (a * dCount.getAndIncrement() + b); + + if (loc >= condition) { + break; + } + + for (int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { + x = loc % image_size; + y = loc / image_size; + + if(rgbs[loc] >>> 24 != Constants.NORMAL_ALPHA) { + Complex val = iteration_algorithm.calculateDomain(location.getComplex(x, y)); + image_iterations[loc] = scaleDomainHeight(getDomainHeight(val)); + rgbs[loc] = domain_color.getDomainColor(val); + + if (domain_image_data_re != null && domain_image_data_im != null) { + domain_image_data_re[loc] = val.getRe(); + domain_image_data_im[loc] = val.getIm(); + } + task_calculated++; + } + + drawing_done++; + } + + if (drawing_done / pixel_percent >= 1) { + update(drawing_done); + drawing_done = 0; + } + + } while (true); + } + + @Override + protected void drawIterationsDomain(int image_size, boolean polar) { + + Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, false); + + int pixel_percent = (image_size * image_size) / 100; + + int condition = image_size * image_size; + + int thread_chunk_size = getThreadChunkSize(image_size, true); + + long time = System.currentTimeMillis(); + + drawIterationsDomainInternal(condition, thread_chunk_size, image_size, pixel_percent, normal_drawing_algorithm_pixel, location, 2, 0); + drawIterationsDomainInternal(condition, thread_chunk_size, image_size, pixel_percent, normal_drawing_algorithm_pixel2, location, 2, 1); + + pixel_calculation_time_per_task = System.currentTimeMillis() - time; + + try { + postProcess(image_size, null, location); + } + catch (StopSuccessiveRefinementException ex) {} + + } + + private void drawIterationsDomainAntialiasedInternal(int condition, int thread_chunk_size, int image_size, int pixel_percent, boolean storeExtraData, AntialiasingAlgorithm aa, int supersampling_num, int totalSamples, AtomicInteger dCount, Location location, int a, int b) { + int loc, x, y, color; + double f_val; + do { + + loc = thread_chunk_size * (a * dCount.getAndIncrement() + b); + + if (loc >= condition) { + break; + } + + for (int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { + x = loc % image_size; + y = loc / image_size; + + Complex val = iteration_algorithm.calculateDomain(location.getComplex(x, y)); + image_iterations[loc] = f_val = scaleDomainHeight(getDomainHeight(val)); + color = domain_color.getDomainColor(val); + + if(storeExtraData) { + pixelData[loc].set(0, color, f_val, true, totalSamples); + } + + if (domain_image_data_re != null && domain_image_data_im != null) { + domain_image_data_re[loc] = val.getRe(); + domain_image_data_im[loc] = val.getIm(); + } + + aa.initialize(color); + + //Supersampling + for (int i = 0; i < supersampling_num; i++) { + val = iteration_algorithm.calculateDomain(location.getAntialiasingComplex(i, loc)); + color = domain_color.getDomainColor(val); + + if(storeExtraData) { + f_val = scaleDomainHeight(getDomainHeight(val)); + pixelData[loc].set(i + 1, color, f_val, true, totalSamples); + } + + if(!aa.addSample(color)) { + break; + } + } + + rgbs[loc] = aa.getColor(); + + drawing_done++; + task_calculated++; + } + + if (drawing_done / pixel_percent >= 1) { + update(drawing_done); + drawing_done = 0; + } + + } while (true); + } + + @Override + protected void drawIterationsDomainAntialiased(int image_size, boolean polar) { + + int aaMethod = (filters_options_vals[MainWindow.ANTIALIASING] % 100) / 10; + boolean useJitter = aaMethod != 6 && ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x4) == 4; + Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, false); + int aaSamplesIndex = (filters_options_vals[MainWindow.ANTIALIASING] % 100) % 10; + int supersampling_num = getExtraSamples(aaSamplesIndex, aaMethod); + location.createAntialiasingSteps(aaMethod == 5, useJitter, supersampling_num); + + int pixel_percent = (image_size * image_size) / 100; + + int condition = image_size * image_size; + + boolean aaAvgWithMean = ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x1) == 1; + int colorSpace = filters_options_extra_vals[0][MainWindow.ANTIALIASING]; + int totalSamples = supersampling_num + 1; + + AntialiasingAlgorithm aa = AntialiasingAlgorithm.getAntialiasingAlgorithm(totalSamples, aaMethod, aaAvgWithMean, colorSpace, fs.aaSigmaR, fs.aaSigmaS); + + aa.setNeedsPostProcessing(needsPostProcessing()); + + boolean storeExtraData = pixelData != null; + + int thread_chunk_size = getThreadChunkSize(image_size, true); + + long time = System.currentTimeMillis(); + + drawIterationsDomainAntialiasedInternal(condition, thread_chunk_size, image_size, pixel_percent, storeExtraData, aa, supersampling_num, totalSamples, normal_drawing_algorithm_pixel, location, 2, 0); + drawIterationsDomainAntialiasedInternal(condition, thread_chunk_size, image_size, pixel_percent, storeExtraData, aa, supersampling_num, totalSamples, normal_drawing_algorithm_pixel2, location, 2, 1); + + pixel_calculation_time_per_task = System.currentTimeMillis() - time; + + try { + postProcess(image_size, aa, location); + } catch (StopSuccessiveRefinementException ex) {} + + } + +} diff --git a/src/fractalzoomer/core/drawing_algorithms/CircularBruteForceDraw.java b/src/fractalzoomer/core/drawing_algorithms/CircularBruteForceDraw.java index 9d7c236a0..bfbe99338 100644 --- a/src/fractalzoomer/core/drawing_algorithms/CircularBruteForceDraw.java +++ b/src/fractalzoomer/core/drawing_algorithms/CircularBruteForceDraw.java @@ -73,22 +73,42 @@ public static void initCoordinatesFastJulia(int fast_julia_image_size, boolean h coordinatesFastJulia = new Pixel[fast_julia_image_size * fast_julia_image_size]; - int loc = 0; - for (int y = 0; y < fast_julia_image_size; y++) { - for (int x = 0; x < fast_julia_image_size; x++, loc++) { - coordinatesFastJulia[loc] = new Pixel(x, y); + if(Pixel.COMPARE_ALG == 16) { //Interleave + int loc = 0; + for (int y = 0; y < fast_julia_image_size; y+= 2) { + for (int x = 0; x < fast_julia_image_size; x++, loc++) { + coordinatesFastJulia[loc] = new Pixel(x, y); + } } - } - if(Pixel.COMPARE_ALG == 4) { - shuffle(coordinatesFastJulia); + for (int y = 1; y < fast_julia_image_size; y+= 2) { + for (int x = 0; x < fast_julia_image_size; x++, loc++) { + coordinatesFastJulia[loc] = new Pixel(x, y); + } + } } else { - Arrays.sort(coordinatesFastJulia); + int loc = 0; + for (int y = 0; y < fast_julia_image_size; y++) { + for (int x = 0; x < fast_julia_image_size; x++, loc++) { + coordinatesFastJulia[loc] = new Pixel(x, y); + } + } + + if (Pixel.COMPARE_ALG == 4) { + shuffle(coordinatesFastJulia); + } else { + Arrays.sort(coordinatesFastJulia); + } } if(hasSuccessiveRefinement) { - CircularSuccessiveRefinementGuessingDraw.initCoordinatesFastJulia(fast_julia_image_size, true); + if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + CircularSuccessiveRefinementGuessing2Draw.initCoordinatesFastJulia(fast_julia_image_size, true); + } + else { + CircularSuccessiveRefinementGuessingDraw.initCoordinatesFastJulia(fast_julia_image_size, true); + } } } } @@ -109,28 +129,63 @@ public static void initCoordinates(int image_size, boolean zoom_to_cursor, boole coordinates = new Pixel[image_size * image_size]; - int loc = 0; - for (int y = 0; y < image_size; y++) { - for (int x = 0; x < image_size; x++, loc++) { - coordinates[loc] = new Pixel(x, y); + if(Pixel.COMPARE_ALG == 16) { //Interleave + int loc = 0; + for (int y = 0; y < image_size; y+= 2) { + for (int x = 0; x < image_size; x++, loc++) { + coordinates[loc] = new Pixel(x, y); + } } - } - if(Pixel.COMPARE_ALG == 4) { - shuffle(coordinates); + for (int y = 1; y < image_size; y+= 2) { + for (int x = 0; x < image_size; x++, loc++) { + coordinates[loc] = new Pixel(x, y); + } + } } else { - Arrays.sort(coordinates); + int loc = 0; + for (int y = 0; y < image_size; y++) { + for (int x = 0; x < image_size; x++, loc++) { + coordinates[loc] = new Pixel(x, y); + } + } + + if (Pixel.COMPARE_ALG == 4) { + shuffle(coordinates); + } else { + Arrays.sort(coordinates); + } } sorted_by_zoom_center = zoom_to_cursor; if(hasSuccessiveRefinement) { - CircularSuccessiveRefinementGuessingDraw.initCoordinates(image_size, true); + if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + CircularSuccessiveRefinementGuessing2Draw.initCoordinates(image_size, true); + } + else { + CircularSuccessiveRefinementGuessingDraw.initCoordinates(image_size, true); + } } } else if(doSort && (zoom_to_cursor || zoom_to_cursor != sorted_by_zoom_center)) { - if(Pixel.COMPARE_ALG == 4) { + + if(Pixel.COMPARE_ALG == 16) { //Interleave + int loc = 0; + for (int y = 0; y < image_size; y+= 2) { + for (int x = 0; x < image_size; x++, loc++) { + coordinates[loc] = new Pixel(x, y); + } + } + + for (int y = 1; y < image_size; y+= 2) { + for (int x = 0; x < image_size; x++, loc++) { + coordinates[loc] = new Pixel(x, y); + } + } + } + else if(Pixel.COMPARE_ALG == 4) { shuffle(coordinates); } else { @@ -139,7 +194,12 @@ else if(doSort && (zoom_to_cursor || zoom_to_cursor != sorted_by_zoom_center)) { sorted_by_zoom_center = zoom_to_cursor; if(hasSuccessiveRefinement) { - CircularSuccessiveRefinementGuessingDraw.initCoordinates(image_size, true); + if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + CircularSuccessiveRefinementGuessing2Draw.initCoordinates(image_size, true); + } + else { + CircularSuccessiveRefinementGuessingDraw.initCoordinates(image_size, true); + } } } @@ -159,11 +219,13 @@ public static void shuffle(Object[] array) { // mix-up the array public static void clear() { coordinates = null; CircularSuccessiveRefinementGuessingDraw.CoordinatesPerLevel = null; + CircularSuccessiveRefinementGuessing2Draw.CoordinatesPerLevel = null; } public static void clearFastJulia() { coordinatesFastJulia = null; CircularSuccessiveRefinementGuessingDraw.CoordinatesPerLevelFastJulia = null; + CircularSuccessiveRefinementGuessing2Draw.CoordinatesPerLevelFastJulia = null; } @Override @@ -178,22 +240,7 @@ protected void drawIterations(int image_size, boolean polar) { int condition = image_size * image_size; - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - - location.setReference(Fractal.refPoint); - } + initialize(location); boolean escaped_val; double f_val; @@ -325,18 +372,16 @@ protected void drawIterationsDomainAntialiased(int image_size, boolean polar) { rgbs[loc] = aa.getColor(); drawing_done++; + task_calculated++; } if (drawing_done / pixel_percent >= 1) { update(drawing_done); - task_calculated += drawing_done; drawing_done = 0; } } while (true); - task_calculated += drawing_done; - pixel_calculation_time_per_task = System.currentTimeMillis() - time; try { @@ -432,20 +477,7 @@ protected void drawIterationsAntialiased(int image_size, boolean polar) { int totalSamples = supersampling_num + 1; AntialiasingAlgorithm aa = AntialiasingAlgorithm.getAntialiasingAlgorithm(totalSamples, aaMethod, aaAvgWithMean, colorSpace, fs.aaSigmaR, fs.aaSigmaS); - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); boolean escaped_val; double f_val; @@ -500,18 +532,16 @@ protected void drawIterationsAntialiased(int image_size, boolean polar) { rgbs[loc] = aa.getColor(); drawing_done++; + task_calculated++; } if(drawing_done / pixel_percent >= 1) { update(drawing_done); - task_calculated += drawing_done; drawing_done = 0; } } while(true); - task_calculated += drawing_done; - pixel_calculation_time_per_task = System.currentTimeMillis() - time; try { @@ -844,20 +874,7 @@ protected void quickDrawIterations(int image_size, boolean polar) { Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (PERTURBATION_THEORY || HIGH_PRECISION_CALCULATION) && fractal.supportsPerturbationTheory()); - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); int color, loc2, x, y; int tempx, tempy; diff --git a/src/fractalzoomer/core/drawing_algorithms/CircularSuccessiveRefinementGuessing2ColorsAndIterationDataDraw.java b/src/fractalzoomer/core/drawing_algorithms/CircularSuccessiveRefinementGuessing2ColorsAndIterationDataDraw.java new file mode 100644 index 000000000..f16b61bc7 --- /dev/null +++ b/src/fractalzoomer/core/drawing_algorithms/CircularSuccessiveRefinementGuessing2ColorsAndIterationDataDraw.java @@ -0,0 +1,48 @@ +package fractalzoomer.core.drawing_algorithms; + +import fractalzoomer.main.ImageExpanderWindow; +import fractalzoomer.main.MainWindow; +import fractalzoomer.main.app_settings.*; +import org.apfloat.Apfloat; + +import java.awt.*; +import java.awt.image.BufferedImage; + +public class CircularSuccessiveRefinementGuessing2ColorsAndIterationDataDraw extends CircularSuccessiveRefinementGuessing2Draw { + public CircularSuccessiveRefinementGuessing2ColorsAndIterationDataDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, D3Settings d3s, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, boolean quickDraw, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, d3s, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, quickDraw, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps); + } + + public CircularSuccessiveRefinementGuessing2ColorsAndIterationDataDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, ImageExpanderWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps); + } + + public CircularSuccessiveRefinementGuessing2ColorsAndIterationDataDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, D3Settings d3s, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, boolean quickDraw, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps, Apfloat xJuliaCenter, Apfloat yJuliaCenter) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, d3s, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, quickDraw, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); + } + + public CircularSuccessiveRefinementGuessing2ColorsAndIterationDataDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, ImageExpanderWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps, Apfloat xJuliaCenter, Apfloat yJuliaCenter) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); + } + + public CircularSuccessiveRefinementGuessing2ColorsAndIterationDataDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps); + } + + public CircularSuccessiveRefinementGuessing2ColorsAndIterationDataDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, MainWindow ptr, Color fractal_color, Color dem_color, boolean fast_julia_filters, BufferedImage image, boolean periodicity_checking, FiltersSettings fs, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps, Apfloat xJuliaCenter, Apfloat yJuliaCenter) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, fast_julia_filters, image, periodicity_checking, fs, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); + } + + @Override + protected boolean isTheSame(int loca, int locb, int locc, int locd) { + return rgbs[loca] == rgbs[locb] && rgbs[locb] == rgbs[locc] && rgbs[locc] == rgbs[locd] + && image_iterations[loca] == image_iterations[locb] && image_iterations[locb] == image_iterations[locc] && image_iterations[locc] == image_iterations[locd]; + } + + @Override + protected boolean isTheSameFastJulia(int loca, int locb, int locc, int locd) { + return rgbs[loca] == rgbs[locb] && rgbs[locb] == rgbs[locc] && rgbs[locc] == rgbs[locd] + && image_iterations_fast_julia[loca] == image_iterations_fast_julia[locb] && image_iterations_fast_julia[locb] == image_iterations_fast_julia[locc] && image_iterations_fast_julia[locc] == image_iterations_fast_julia[locd]; + } + +} diff --git a/src/fractalzoomer/core/drawing_algorithms/CircularSuccessiveRefinementGuessing2Draw.java b/src/fractalzoomer/core/drawing_algorithms/CircularSuccessiveRefinementGuessing2Draw.java new file mode 100644 index 000000000..35d5de759 --- /dev/null +++ b/src/fractalzoomer/core/drawing_algorithms/CircularSuccessiveRefinementGuessing2Draw.java @@ -0,0 +1,1029 @@ +package fractalzoomer.core.drawing_algorithms; + +import fractalzoomer.core.PixelExtraData; +import fractalzoomer.core.TaskDraw; +import fractalzoomer.core.antialiasing.AntialiasingAlgorithm; +import fractalzoomer.core.location.Location; +import fractalzoomer.functions.Fractal; +import fractalzoomer.main.Constants; +import fractalzoomer.main.ImageExpanderWindow; +import fractalzoomer.main.MainWindow; +import fractalzoomer.main.app_settings.*; +import fractalzoomer.utils.Pixel; +import fractalzoomer.utils.StopSuccessiveRefinementException; +import org.apfloat.Apfloat; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.atomic.AtomicInteger; + +import static fractalzoomer.core.drawing_algorithms.CircularBruteForceDraw.coordinates; +import static fractalzoomer.core.drawing_algorithms.CircularBruteForceDraw.coordinatesFastJulia; + +public class CircularSuccessiveRefinementGuessing2Draw extends CircularSuccessiveRefinementGuessingDraw { + public CircularSuccessiveRefinementGuessing2Draw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, D3Settings d3s, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, boolean quickDraw, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, d3s, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, quickDraw, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps); + } + + public CircularSuccessiveRefinementGuessing2Draw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, ImageExpanderWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps); + } + + public CircularSuccessiveRefinementGuessing2Draw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, D3Settings d3s, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, boolean quickDraw, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps, Apfloat xJuliaCenter, Apfloat yJuliaCenter) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, d3s, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, quickDraw, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); + } + + public CircularSuccessiveRefinementGuessing2Draw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, ImageExpanderWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps, Apfloat xJuliaCenter, Apfloat yJuliaCenter) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); + } + + public CircularSuccessiveRefinementGuessing2Draw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps); + } + + public CircularSuccessiveRefinementGuessing2Draw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, MainWindow ptr, Color fractal_color, Color dem_color, boolean fast_julia_filters, BufferedImage image, boolean periodicity_checking, FiltersSettings fs, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps, Apfloat xJuliaCenter, Apfloat yJuliaCenter) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, fast_julia_filters, image, periodicity_checking, fs, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); + } + + public CircularSuccessiveRefinementGuessing2Draw(int FROMx, int TOx, int FROMy, int TOy, int max_iterations, MainWindow ptr, BufferedImage image, Color fractal_color, Color dem_color, int color_cycling_location, int color_cycling_location2, FiltersSettings fs, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, DomainColoringSettings ds, int gradient_offset, double contourFactor, boolean smoothing, GeneratedPaletteSettings gps, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, max_iterations, ptr, image, fractal_color, dem_color, color_cycling_location, color_cycling_location2, fs, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, ds, gradient_offset, contourFactor, smoothing, gps, pps); + } + + public CircularSuccessiveRefinementGuessing2Draw(int action, int FROMx, int TOx, int FROMy, int TOy, int max_iterations, MainWindow ptr, BufferedImage image, Color fractal_color, Color dem_color, int color_cycling_location, int color_cycling_location2, FiltersSettings fs, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, PostProcessSettings pps, DomainColoringSettings ds) { + super(action, FROMx, TOx, FROMy, TOy, max_iterations, ptr, image, fractal_color, dem_color, color_cycling_location, color_cycling_location2, fs, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, pps, ds); + } + + public static Pixel[][] CoordinatesPerLevel; + public static void initCoordinates(int image_size, boolean force) { + + if(force || CoordinatesPerLevel == null || coordinates.length != image_size * image_size) { + + CoordinatesPerLevel = new Pixel[SUCCESSIVE_REFINEMENT_CHUNK_X.length][]; + int current_chunk_size_x, current_chunk_size_y; + + int x, y; + for (int id = 0; id < CoordinatesPerLevel.length - 1; id++) { + + current_chunk_size_x = SUCCESSIVE_REFINEMENT_CHUNK_X[id]; + current_chunk_size_y = SUCCESSIVE_REFINEMENT_CHUNK_Y[id]; + + ArrayList list = new ArrayList<>(); + + if(Pixel.COMPARE_ALG == 16) { + for (int i = 0; i < coordinates.length; i++) { + Pixel pix = coordinates[i]; + x = pix.x; + y = pix.y; + + if (x % current_chunk_size_x != 0 || y % current_chunk_size_y != 0 || (y / current_chunk_size_y) % 2 == 1) { + continue; + } + list.add(pix); + } + + for (int i = 0; i < coordinates.length; i++) { + Pixel pix = coordinates[i]; + x = pix.x; + y = pix.y; + + if (x % current_chunk_size_x != 0 || y % current_chunk_size_y != 0 || (y / current_chunk_size_y) % 2 == 0) { + continue; + } + list.add(pix); + } + } + else { + for (int i = 0; i < coordinates.length; i++) { + Pixel pix = coordinates[i]; + x = pix.x; + y = pix.y; + + if (x % current_chunk_size_x != 0 || y % current_chunk_size_y != 0) { + continue; + } + list.add(pix); + } + } + + Pixel[] array = new Pixel[list.size()]; + CoordinatesPerLevel[id] = list.toArray(array); + } + + CoordinatesPerLevel[CoordinatesPerLevel.length - 1] = coordinates; + } + } + + public static Pixel[][] CoordinatesPerLevelFastJulia; + public static void initCoordinatesFastJulia(int image_size, boolean force) { + + if(force || CoordinatesPerLevelFastJulia == null || coordinatesFastJulia.length != image_size * image_size) { + CoordinatesPerLevelFastJulia = new Pixel[SUCCESSIVE_REFINEMENT_CHUNK_X.length][]; + int current_chunk_size_x, current_chunk_size_y; + + int x, y; + for (int id = 0; id < CoordinatesPerLevelFastJulia.length - 1; id++) { + + current_chunk_size_x = SUCCESSIVE_REFINEMENT_CHUNK_X[id]; + current_chunk_size_y = SUCCESSIVE_REFINEMENT_CHUNK_Y[id]; + + ArrayList list = new ArrayList<>(); + + if(Pixel.COMPARE_ALG == 16) { + for (int i = 0; i < coordinatesFastJulia.length; i++) { + Pixel pix = coordinatesFastJulia[i]; + x = pix.x; + y = pix.y; + + if (x % current_chunk_size_x != 0 || y % current_chunk_size_y != 0 || (y / current_chunk_size_y) % 2 == 1) { + continue; + } + list.add(pix); + } + + for (int i = 0; i < coordinatesFastJulia.length; i++) { + Pixel pix = coordinatesFastJulia[i]; + x = pix.x; + y = pix.y; + + if (x % current_chunk_size_x != 0 || y % current_chunk_size_y != 0 || (y / current_chunk_size_y) % 2 == 0) { + continue; + } + list.add(pix); + } + } + else { + for (int i = 0; i < coordinatesFastJulia.length; i++) { + Pixel pix = coordinatesFastJulia[i]; + x = pix.x; + y = pix.y; + + if (x % current_chunk_size_x != 0 || y % current_chunk_size_y != 0) { + continue; + } + list.add(pix); + } + } + + Pixel[] array = new Pixel[list.size()]; + CoordinatesPerLevelFastJulia[id] = list.toArray(array); + } + + CoordinatesPerLevelFastJulia[CoordinatesPerLevelFastJulia.length - 1] = coordinatesFastJulia; + } + } + + protected int getAggregateChunk(int current_chunk_size_x, int current_chunk_size_y) { + + if(SQUARE_RECT_CHUNK_AGGERAGATION == 0) { + return TWO_PASS_SUCCESSIVE_REFINEMENT ? Math.max(current_chunk_size_x, current_chunk_size_y) : Math.min(current_chunk_size_x, current_chunk_size_y); + } + else { + return TWO_PASS_SUCCESSIVE_REFINEMENT ? Math.min(current_chunk_size_x, current_chunk_size_y) : Math.max(current_chunk_size_x, current_chunk_size_y); + } + + } + + @Override + protected void drawIterations(int image_size, boolean polar) throws StopSuccessiveRefinementException { + + Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (HIGH_PRECISION_CALCULATION || PERTURBATION_THEORY) && fractal.supportsPerturbationTheory()); + + int pixel_percent = (image_size * image_size) / 100; + + + initialize(location); + + + int color, loc2, x, y; + int tempx, tempy; + + boolean escaped_val; + double f_val; + + + int current_chunk_size_x = 0; + int current_chunk_size_y = 0; + int prev_chunk_size_x; + int prev_chunk_size_y; + + int iteration = randomNumber; + int min_chunk_size = TaskDraw.GUESS_BLOCKS_SELECTION == 0 ? 0 : 1 << (TaskDraw.GUESS_BLOCKS_SELECTION - 1); + min_chunk_size = TWO_PASS_SUCCESSIVE_REFINEMENT ? min_chunk_size << 1 : min_chunk_size; + + int current_chunk_size2x = 0, current_chunk_size2y = 0; + + int xstart = 0; + int ystart = 0; + int xend = 0; + int yend = 0; + + int loca = 0; + int locb = 0; + int locc = 0; + int locd = 0; + + int condition; + + int stop_id = getStopAfterIter(); + int length = TWO_PASS_SUCCESSIVE_REFINEMENT ? SUCCESSIVE_REFINEMENT_CHUNK_X.length << 1 : SUCCESSIVE_REFINEMENT_CHUNK_X.length; + + task_completed = 0; + long nano_time = 0; + + for(int id = 0, id2 = 0; id < length; id++) { + + long time = System.nanoTime(); + + AtomicInteger ai = successive_refinement_drawing_algorithm2_pixel[id]; + + prev_chunk_size_x = current_chunk_size_x; + prev_chunk_size_y = current_chunk_size_y; + current_chunk_size_x = SUCCESSIVE_REFINEMENT_CHUNK_X[id2]; + current_chunk_size_y = SUCCESSIVE_REFINEMENT_CHUNK_Y[id2]; + + int coordinatesLoc; + + Pixel[] coordinates = CoordinatesPerLevel[id2]; + condition = coordinates.length; + + int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL2[id2]; + boolean performSecondPassActions = !TWO_PASS_SUCCESSIVE_REFINEMENT || (id & 1) == 1; + + do { + + coordinatesLoc = chunk_size * ai.getAndIncrement(); + + if (coordinatesLoc >= condition) { + break; + } + + for (int count = 0; count < chunk_size && coordinatesLoc < condition; count++, coordinatesLoc++) { + Pixel pix = coordinates[coordinatesLoc]; + x = pix.x; + y = pix.y; + + loc2 = y * image_size + x; + + if(!filled[loc2]) { + + int aggregate_chunk = getAggregateChunk(current_chunk_size_x, current_chunk_size_y); + boolean check = performSecondPassActions && aggregate_chunk <= min_chunk_size; + if(check) { + current_chunk_size2x = prev_chunk_size_x; + current_chunk_size2y = prev_chunk_size_y; + + xstart = (x / current_chunk_size2x) * current_chunk_size2x; + ystart = (y / current_chunk_size2y) * current_chunk_size2y; + xend = xstart + current_chunk_size2x; + yend = ystart + current_chunk_size2y; + + loca = ystart * image_size; + locb = loca + xend; + loca += xstart; + + locc = yend * image_size; + locd = locc + xend; + locc += xstart; + } + + if(check && xend < image_size && yend < image_size && isTheSame(loca, locb, locc, locd)) { + + + tempx = Math.min(image_size, x + current_chunk_size_x); + tempy = Math.min(image_size, y + current_chunk_size_y); + + int start_color = rgbs[loca]; + int skippedColor = getColorForSkippedPixels(start_color, iteration); + double start_iterations = image_iterations[loca]; + boolean start_escaped = escaped[loca]; + + for (int i = y; i < tempy; i++) { + for (int j = x, loc3 = i * image_size + j; j < tempx; j++, loc3++) { + if(!examined[loc3]) { + if (rgbs[loc3] >>> 24 != Constants.NORMAL_ALPHA) { + rgbs[loc3] = start_color; + image_iterations[loc3] = start_iterations; + escaped[loc3] = start_escaped; + task_completed++; + } + setFilledAndExaminedWithSkippedColor(examined, filled, skipped_colors, loc3, skippedColor); + drawing_done++; + } + } + } + } + else if (!examined[loc2]){ + if (rgbs[loc2] >>> 24 != Constants.NORMAL_ALPHA) { + image_iterations[loc2] = f_val = iteration_algorithm.calculate(location.getComplex(x, y)); + escaped[loc2] = escaped_val = iteration_algorithm.escaped(); + rgbs[loc2] = color = getFinalColor(f_val, escaped_val); + task_calculated++; + task_completed++; + } else { + color = rgbs[loc2]; + } + + examined[loc2] = true; + drawing_done++; + + tempx = Math.min(image_size, x + current_chunk_size_x); + tempy = Math.min(image_size, y + current_chunk_size_y); + + for (int i = y; i < tempy; i++) { + for (int j = x, loc3 = i * image_size + j; j < tempx; j++, loc3++) { + if (rgbs[loc3] >>> 24 != Constants.NORMAL_ALPHA) { + rgbs[loc3] = (color & 0xFFFFFF) | Constants.QUICKDRAW_CALCULATED_ALPHA_OFFSETED; + } + } + } + } + } + + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { + break; + } + } + + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { + break; + } + + if(drawing_done / pixel_percent >= 1) { + update(drawing_done); + drawing_done = 0; + } + + } while (true); + + nano_time += System.nanoTime() - time; + + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT) { + try { + successive_refinement_lock.lockRead(); + } catch (InterruptedException ex) { + + } + } + + try { + successive_refinement_drawing_algorithm_barrier.await(); + } catch (InterruptedException ex) { + + } catch (BrokenBarrierException ex) { + + } + + if(taskId == 0 && ptr != null) { + if(id == 0) { + ptr.setWholeImageDone(true); + ptr.reloadTitle(); + updateMode(ptr, false, iteration_algorithm.isJulia(), false, false); + } + ptr.getMainPanel().repaint(); + } + + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT) { + if (id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { + successive_refinement_lock.unlockRead(); + throw new StopSuccessiveRefinementException(); + } + successive_refinement_lock.unlockRead(); + } + + if(performSecondPassActions) { + iteration++; + id2++; + } + } + + if(SKIPPED_PIXELS_ALG != 0) { + applySkippedColor(image_size, false); + } + + if (SKIPPED_PIXELS_ALG == 4) { + drawSquares(image_size); + } + + pixel_calculation_time_per_task = nano_time / 1000000; + + postProcess(image_size, null, location); + + } + + @Override + protected void drawFastJuliaAntialiased(int image_size, boolean polar) { + + int aaMethod = (filters_options_vals[MainWindow.ANTIALIASING] % 100) / 10; + boolean useJitter = aaMethod != 6 && ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x4) == 4; + Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (PERTURBATION_THEORY || HIGH_PRECISION_CALCULATION) && fractal.supportsPerturbationTheory()); + int aaSamplesIndex = (filters_options_vals[MainWindow.ANTIALIASING] % 100) % 10; + int supersampling_num = getExtraSamples(aaSamplesIndex, aaMethod); + location.createAntialiasingSteps(aaMethod == 5, useJitter, supersampling_num); + + initialize(location); + + boolean aaAvgWithMean = ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x1) == 1; + int colorSpace = filters_options_extra_vals[0][MainWindow.ANTIALIASING]; + int totalSamples = supersampling_num + 1; + + AntialiasingAlgorithm aa = AntialiasingAlgorithm.getAntialiasingAlgorithm(totalSamples, aaMethod, aaAvgWithMean, colorSpace, fs.aaSigmaR, fs.aaSigmaS); + + aa.setNeedsPostProcessing(needsPostProcessing()); + + boolean storeExtraData = pixelData_fast_julia != null; + + int color, loc2, x, y; + int tempx, tempy; + + boolean escaped_val; + double f_val; + double temp_result; + + int current_chunk_size_x = 0; + int current_chunk_size_y = 0; + int prev_chunk_size_x; + int prev_chunk_size_y; + int iteration = randomNumber; + int min_chunk_size = TaskDraw.GUESS_BLOCKS_SELECTION == 0 ? 0 : 1 << (TaskDraw.GUESS_BLOCKS_SELECTION - 1); + min_chunk_size = TWO_PASS_SUCCESSIVE_REFINEMENT ? min_chunk_size << 1 : min_chunk_size; + + int current_chunk_size2x = 0, current_chunk_size2y = 0; + + int xstart = 0; + int ystart = 0; + int xend = 0; + int yend = 0; + + int loca = 0; + int locb = 0; + int locc = 0; + int locd = 0; + + int condition; + int length = TWO_PASS_SUCCESSIVE_REFINEMENT ? SUCCESSIVE_REFINEMENT_CHUNK_X.length << 1 : SUCCESSIVE_REFINEMENT_CHUNK_X.length; + + + for(int id = 0, id2 = 0; id < length; id++) { + AtomicInteger ai = successive_refinement_drawing_algorithm2_pixel[id]; + + prev_chunk_size_x = current_chunk_size_x; + prev_chunk_size_y = current_chunk_size_y; + current_chunk_size_x = SUCCESSIVE_REFINEMENT_CHUNK_X[id2]; + current_chunk_size_y = SUCCESSIVE_REFINEMENT_CHUNK_Y[id2]; + + Pixel[] coordinates = CoordinatesPerLevelFastJulia[id2]; + condition = coordinates.length; + int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL2[id2]; + boolean performSecondPassActions = !TWO_PASS_SUCCESSIVE_REFINEMENT || (id & 1) == 1; + + + int coordinatesLoc; + + do { + + coordinatesLoc = chunk_size * ai.getAndIncrement(); + + if (coordinatesLoc >= condition) { + break; + } + + for (int count = 0; count < chunk_size && coordinatesLoc < condition; count++, coordinatesLoc++) { + Pixel pix = coordinates[coordinatesLoc]; + x = pix.x; + y = pix.y; + + + loc2 = y * image_size + x; + + if(!filled_fast_julia[loc2]) { + + int aggregate_chunk = getAggregateChunk(current_chunk_size_x, current_chunk_size_y); + boolean check = performSecondPassActions && aggregate_chunk <= min_chunk_size; + if(check) { + current_chunk_size2x = prev_chunk_size_x; + current_chunk_size2y = prev_chunk_size_y; + + xstart = (x / current_chunk_size2x) * current_chunk_size2x; + ystart = (y / current_chunk_size2y) * current_chunk_size2y; + xend = xstart + current_chunk_size2x; + yend = ystart + current_chunk_size2y; + + loca = ystart * image_size; + locb = loca + xend; + loca += xstart; + + locc = yend * image_size; + locd = locc + xend; + locc += xstart; + } + + if(check && xend < image_size && yend < image_size && isTheSameFastJulia(loca, locb, locc, locd)) { + + tempx = Math.min(image_size, x + current_chunk_size_x); + tempy = Math.min(image_size, y + current_chunk_size_y); + + int start_color = rgbs[loca]; + int skippedColor = getColorForSkippedPixels(start_color, iteration); + double start_iterations = image_iterations_fast_julia[loca]; + boolean start_escaped = escaped_fast_julia[loca]; + + PixelExtraData start_extra_data = null; + if(storeExtraData) { + start_extra_data = pixelData_fast_julia[loca]; + } + + for (int i = y; i < tempy; i++) { + for (int j = x, loc3 = i * image_size + j; j < tempx; j++, loc3++) { + if(!examined_fast_julia[loc3]) { + rgbs[loc3] = start_color; + image_iterations_fast_julia[loc3] = start_iterations; + escaped_fast_julia[loc3] = start_escaped; + setFilledAndExaminedWithSkippedColor(examined_fast_julia, filled_fast_julia, skipped_colors_fast_julia, loc3, skippedColor); + if(storeExtraData) { + pixelData_fast_julia[loc3] = new PixelExtraData(start_extra_data, skippedColor); + } + } + } + } + } + else if (!examined_fast_julia[loc2]){ + + image_iterations_fast_julia[loc2] = f_val = iteration_algorithm.calculate(location.getComplex(x, y)); + escaped_fast_julia[loc2] = escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(f_val, escaped_val); + + examined_fast_julia[loc2] = true; + + if(storeExtraData) { + pixelData_fast_julia[loc2].set(0, color, f_val, escaped_val, totalSamples); + } + + aa.initialize(color); + + //Supersampling + for(int i = 0; i < supersampling_num; i++) { + temp_result = iteration_algorithm.calculate(location.getAntialiasingComplex(i, loc2)); + escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(temp_result, escaped_val); + + if(storeExtraData) { + pixelData_fast_julia[loc2].set(i + 1, color, temp_result, escaped_val, totalSamples); + } + + if(!aa.addSample(color)) { + break; + } + } + + rgbs[loc2] = aa.getColor(); + } + } + } + + } while (true); + + try { + successive_refinement_drawing_algorithm_barrier.await(); + } catch (InterruptedException ex) { + + } catch (BrokenBarrierException ex) { + + } + + if(performSecondPassActions) { + iteration++; + id2++; + } + } + + + if(SKIPPED_PIXELS_ALG != 0) { + applySkippedColor(image_size, true); + } + + + if (SKIPPED_PIXELS_ALG == 4) { + drawSquares(image_size); + } + + + postProcessFastJulia(image_size, aa, location); + + } + + @Override + protected void drawIterationsAntialiased(int image_size, boolean polar) throws StopSuccessiveRefinementException { + + int aaMethod = (filters_options_vals[MainWindow.ANTIALIASING] % 100) / 10; + boolean useJitter = aaMethod != 6 && ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x4) == 4; + Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (PERTURBATION_THEORY || HIGH_PRECISION_CALCULATION) && fractal.supportsPerturbationTheory()); + int aaSamplesIndex = (filters_options_vals[MainWindow.ANTIALIASING] % 100) % 10; + int supersampling_num = getExtraSamples(aaSamplesIndex, aaMethod); + location.createAntialiasingSteps(aaMethod == 5, useJitter, supersampling_num); + int pixel_percent = (image_size * image_size) / 100; + + initialize(location); + + boolean aaAvgWithMean = ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x1) == 1; + int colorSpace = filters_options_extra_vals[0][MainWindow.ANTIALIASING]; + int totalSamples = supersampling_num + 1; + + AntialiasingAlgorithm aa = AntialiasingAlgorithm.getAntialiasingAlgorithm(totalSamples, aaMethod, aaAvgWithMean, colorSpace, fs.aaSigmaR, fs.aaSigmaS); + + aa.setNeedsPostProcessing(needsPostProcessing()); + + boolean storeExtraData = pixelData != null; + + int color, loc2, x, y; + int tempx, tempy; + + boolean escaped_val; + double f_val; + double temp_result; + + + int current_chunk_size_x = 0; + int current_chunk_size_y = 0; + int prev_chunk_size_x; + int prev_chunk_size_y; + int iteration = randomNumber; + int min_chunk_size = TaskDraw.GUESS_BLOCKS_SELECTION == 0 ? 0 : 1 << (TaskDraw.GUESS_BLOCKS_SELECTION - 1); + min_chunk_size = TWO_PASS_SUCCESSIVE_REFINEMENT ? min_chunk_size << 1 : min_chunk_size; + + int current_chunk_size2x = 0, current_chunk_size2y = 0; + + int xstart = 0; + int ystart = 0; + int xend = 0; + int yend = 0; + + int loca = 0; + int locb = 0; + int locc = 0; + int locd = 0; + + int condition; + + task_completed = 0; + + int stop_id = getStopAfterIter(); + int length = TWO_PASS_SUCCESSIVE_REFINEMENT ? SUCCESSIVE_REFINEMENT_CHUNK_X.length << 1 : SUCCESSIVE_REFINEMENT_CHUNK_X.length; + + long nano_time = 0; + + for(int id = 0, id2 = 0; id < length; id++) { + long time = System.nanoTime(); + AtomicInteger ai = successive_refinement_drawing_algorithm2_pixel[id]; + + prev_chunk_size_x = current_chunk_size_x; + prev_chunk_size_y = current_chunk_size_y; + current_chunk_size_x = SUCCESSIVE_REFINEMENT_CHUNK_X[id2]; + current_chunk_size_y = SUCCESSIVE_REFINEMENT_CHUNK_Y[id2]; + + Pixel[] coordinates = CoordinatesPerLevel[id2]; + condition = coordinates.length; + int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL2[id2]; + boolean performSecondPassActions = !TWO_PASS_SUCCESSIVE_REFINEMENT || (id & 1) == 1; + + int coordinatesLoc; + + do { + + coordinatesLoc = chunk_size * ai.getAndIncrement(); + + if (coordinatesLoc >= condition) { + break; + } + + for (int count = 0; count < chunk_size && coordinatesLoc < condition; count++, coordinatesLoc++) { + Pixel pix = coordinates[coordinatesLoc]; + x = pix.x; + y = pix.y; + + + loc2 = y * image_size + x; + + if(!filled[loc2]) { + + int aggregate_chunk = getAggregateChunk(current_chunk_size_x, current_chunk_size_y); + boolean check = performSecondPassActions && aggregate_chunk <= min_chunk_size; + if(check) { + current_chunk_size2x = prev_chunk_size_x; + current_chunk_size2y = prev_chunk_size_y; + + xstart = (x / current_chunk_size2x) * current_chunk_size2x; + ystart = (y / current_chunk_size2y) * current_chunk_size2y; + xend = xstart + current_chunk_size2x; + yend = ystart + current_chunk_size2y; + + loca = ystart * image_size; + locb = loca + xend; + loca += xstart; + + locc = yend * image_size; + locd = locc + xend; + locc += xstart; + } + + if(check && xend < image_size && yend < image_size && isTheSame(loca, locb, locc, locd)) { + + + tempx = Math.min(image_size, x + current_chunk_size_x); + tempy = Math.min(image_size, y + current_chunk_size_y); + + int start_color = rgbs[loca]; + int skippedColor = getColorForSkippedPixels(start_color, iteration); + double start_iterations = image_iterations[loca]; + boolean start_escaped = escaped[loca]; + + PixelExtraData start_extra_data = null; + if(storeExtraData) { + start_extra_data = pixelData[loca]; + } + + for (int i = y; i < tempy; i++) { + for (int j = x, loc3 = i * image_size + j; j < tempx; j++, loc3++) { + if(!examined[loc3]) { + rgbs[loc3] = start_color; + image_iterations[loc3] = start_iterations; + escaped[loc3] = start_escaped; + setFilledAndExaminedWithSkippedColor(examined, filled, skipped_colors, loc3, skippedColor); + if(storeExtraData) { + pixelData[loc3] = new PixelExtraData(start_extra_data, skippedColor); + } + task_completed++; + drawing_done++; + } + } + } + } + else if (!examined[loc2]){ + image_iterations[loc2] = f_val = iteration_algorithm.calculate(location.getComplex(x, y)); + escaped[loc2] = escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(f_val, escaped_val); + task_calculated++; + + examined[loc2] = true; + drawing_done++; + task_completed++; + + if (storeExtraData) { + pixelData[loc2].set(0, color, f_val, escaped_val, totalSamples); + } + + aa.initialize(color); + + //Supersampling + for (int i = 0; i < supersampling_num; i++) { + temp_result = iteration_algorithm.calculate(location.getAntialiasingComplex(i, loc2)); + escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(temp_result, escaped_val); + + if (storeExtraData) { + pixelData[loc2].set(i + 1, color, temp_result, escaped_val, totalSamples); + } + + if (!aa.addSample(color)) { + break; + } + } + + rgbs[loc2] = color = aa.getColor(); + + tempx = Math.min(image_size, x + current_chunk_size_x); + tempy = Math.min(image_size, y + current_chunk_size_y); + + for (int i = y; i < tempy; i++) { + for (int j = x, loc3 = i * image_size + j; j < tempx; j++, loc3++) { + rgbs[loc3] = color; + } + } + } + } + + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { + break; + } + } + + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { + break; + } + + if(drawing_done / pixel_percent >= 1) { + update(drawing_done); + drawing_done = 0; + } + + } while (true); + + nano_time += System.nanoTime() - time; + + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT) { + try { + successive_refinement_lock.lockRead(); + } catch (InterruptedException ex) { + + } + } + + try { + successive_refinement_drawing_algorithm_barrier.await(); + } catch (InterruptedException ex) { + + } catch (BrokenBarrierException ex) { + } + + if(taskId == 0 && ptr != null) { + if(id == 0) { + ptr.setWholeImageDone(true); + ptr.reloadTitle(); + updateMode(ptr, false, iteration_algorithm.isJulia(), false, false); + } + ptr.getMainPanel().repaint(); + } + + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT) { + if (id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { + successive_refinement_lock.unlockRead(); + throw new StopSuccessiveRefinementException(); + } + successive_refinement_lock.unlockRead(); + } + + if(performSecondPassActions) { + iteration++; + id2++; + } + } + + if(SKIPPED_PIXELS_ALG != 0) { + applySkippedColor(image_size, false); + } + + if (SKIPPED_PIXELS_ALG == 4) { + drawSquares(image_size); + } + + pixel_calculation_time_per_task = nano_time / 1000000; + + postProcess(image_size, aa, location); + + } + + @Override + protected void drawFastJulia(int image_size, boolean polar) { + + Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (HIGH_PRECISION_CALCULATION || PERTURBATION_THEORY) && fractal.supportsPerturbationTheory()); + + initialize(location); + + + int loc2, x, y; + int tempx, tempy; + + boolean escaped_val; + double f_val; + + + int current_chunk_size_x = 0; + int current_chunk_size_y = 0; + int prev_chunk_size_x; + int prev_chunk_size_y; + int iteration = randomNumber; + int min_chunk_size = TaskDraw.GUESS_BLOCKS_SELECTION == 0 ? 0 : 1 << (TaskDraw.GUESS_BLOCKS_SELECTION - 1); + min_chunk_size = TWO_PASS_SUCCESSIVE_REFINEMENT ? min_chunk_size << 1 : min_chunk_size; + + int current_chunk_size2x = 0, current_chunk_size2y = 0; + + int xstart = 0; + int ystart = 0; + int xend = 0; + int yend = 0; + + int loca = 0; + int locb = 0; + int locc = 0; + int locd = 0; + + int length = TWO_PASS_SUCCESSIVE_REFINEMENT ? SUCCESSIVE_REFINEMENT_CHUNK_X.length << 1 : SUCCESSIVE_REFINEMENT_CHUNK_X.length; + + int condition; + + for(int id = 0, id2 = 0; id < length; id++) { + AtomicInteger ai = successive_refinement_drawing_algorithm2_pixel[id]; + + prev_chunk_size_x = current_chunk_size_x; + prev_chunk_size_y = current_chunk_size_y; + current_chunk_size_x = SUCCESSIVE_REFINEMENT_CHUNK_X[id2]; + current_chunk_size_y = SUCCESSIVE_REFINEMENT_CHUNK_Y[id2]; + + Pixel[] coordinates = CoordinatesPerLevelFastJulia[id2]; + condition = coordinates.length; + int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL2[id2]; + boolean performSecondPassActions = !TWO_PASS_SUCCESSIVE_REFINEMENT || (id & 1) == 1; + + + int coordinatesLoc; + + do { + + coordinatesLoc = chunk_size * ai.getAndIncrement(); + + if (coordinatesLoc >= condition) { + break; + } + + for (int count = 0; count < chunk_size && coordinatesLoc < condition; count++, coordinatesLoc++) { + Pixel pix = coordinates[coordinatesLoc]; + x = pix.x; + y = pix.y; + + loc2 = y * image_size + x; + + if(!filled_fast_julia[loc2]) { + + int aggregate_chunk = getAggregateChunk(current_chunk_size_x, current_chunk_size_y); + boolean check = performSecondPassActions && aggregate_chunk <= min_chunk_size; + if(check) { + current_chunk_size2x = prev_chunk_size_x; + current_chunk_size2y = prev_chunk_size_y; + + xstart = (x / current_chunk_size2x) * current_chunk_size2x; + ystart = (y / current_chunk_size2y) * current_chunk_size2y; + xend = xstart + current_chunk_size2x; + yend = ystart + current_chunk_size2y; + + loca = ystart * image_size; + locb = loca + xend; + loca += xstart; + + locc = yend * image_size; + locd = locc + xend; + locc += xstart; + } + + if(check && xend < image_size && yend < image_size && isTheSameFastJulia(loca, locb, locc, locd)) { + + + tempx = Math.min(image_size, x + current_chunk_size_x); + tempy = Math.min(image_size, y + current_chunk_size_y); + + int start_color = rgbs[loca]; + int skippedColor = getColorForSkippedPixels(start_color, iteration); + double start_iterations = image_iterations_fast_julia[loca]; + boolean start_escaped = escaped_fast_julia[loca]; + + for (int i = y; i < tempy; i++) { + for (int j = x, loc3 = i * image_size + j; j < tempx; j++, loc3++) { + if(!examined_fast_julia[loc3]) { + rgbs[loc3] = start_color; + image_iterations_fast_julia[loc3] = start_iterations; + escaped_fast_julia[loc3] = start_escaped; + setFilledAndExaminedWithSkippedColor(examined_fast_julia, filled_fast_julia, skipped_colors_fast_julia, loc3, skippedColor); + } + } + } + } + else if (!examined_fast_julia[loc2]){ + image_iterations_fast_julia[loc2] = f_val = iteration_algorithm.calculate(location.getComplex(x, y)); + escaped_fast_julia[loc2] = escaped_val = iteration_algorithm.escaped(); + rgbs[loc2] = getFinalColor(f_val, escaped_val); + + examined_fast_julia[loc2] = true; + } + } + + } + + } while (true); + + try { + successive_refinement_drawing_algorithm_barrier.await(); + } catch (InterruptedException ex) { + + } catch (BrokenBarrierException ex) { + + } + + if(performSecondPassActions) { + iteration++; + id2++; + } + } + + if(SKIPPED_PIXELS_ALG != 0) { + applySkippedColor(image_size, true); + } + + if (SKIPPED_PIXELS_ALG == 4) { + drawSquares(image_size); + } + + + postProcessFastJulia(image_size, null, location); + + } +} diff --git a/src/fractalzoomer/core/drawing_algorithms/CircularSuccessiveRefinementGuessingDraw.java b/src/fractalzoomer/core/drawing_algorithms/CircularSuccessiveRefinementGuessingDraw.java index f385b1f63..2867700a8 100644 --- a/src/fractalzoomer/core/drawing_algorithms/CircularSuccessiveRefinementGuessingDraw.java +++ b/src/fractalzoomer/core/drawing_algorithms/CircularSuccessiveRefinementGuessingDraw.java @@ -65,18 +65,43 @@ public static void initCoordinates(int image_size, boolean force) { int current_chunk_size = SUCCESSIVE_REFINEMENT_MAX_SIZE; int x, y; - for (int id = 0; current_chunk_size >= 2; current_chunk_size >>= 1, id++) { - + for (int id = 0; id < CoordinatesPerLevel.length - 1; current_chunk_size >>= 1, id++) { ArrayList list = new ArrayList<>(); - for (int i = 0; i < coordinates.length; i++) { - Pixel pix = coordinates[i]; - x = pix.x; - y = pix.y; - if (x % current_chunk_size != 0 || y % current_chunk_size != 0) { - continue; + if(Pixel.COMPARE_ALG == 16) { + for (int i = 0; i < coordinates.length; i++) { + Pixel pix = coordinates[i]; + x = pix.x; + y = pix.y; + + if (x % current_chunk_size != 0 || y % current_chunk_size != 0 || (y / current_chunk_size) % 2 == 1) { + continue; + } + list.add(pix); + } + + for (int i = 0; i < coordinates.length; i++) { + Pixel pix = coordinates[i]; + x = pix.x; + y = pix.y; + + if (x % current_chunk_size != 0 || y % current_chunk_size != 0 || (y / current_chunk_size) % 2 == 0) { + continue; + } + list.add(pix); + } + } + else { + for (int i = 0; i < coordinates.length; i++) { + Pixel pix = coordinates[i]; + x = pix.x; + y = pix.y; + + if (x % current_chunk_size != 0 || y % current_chunk_size != 0) { + continue; + } + list.add(pix); } - list.add(pix); } Pixel[] array = new Pixel[list.size()]; @@ -95,18 +120,44 @@ public static void initCoordinatesFastJulia(int image_size, boolean force) { int current_chunk_size = SUCCESSIVE_REFINEMENT_MAX_SIZE; int x, y; - for (int id = 0; current_chunk_size >= 2; current_chunk_size >>= 1, id++) { + for (int id = 0; id < CoordinatesPerLevelFastJulia.length - 1; current_chunk_size >>= 1, id++) { ArrayList list = new ArrayList<>(); - for (int i = 0; i < coordinatesFastJulia.length; i++) { - Pixel pix = coordinatesFastJulia[i]; - x = pix.x; - y = pix.y; - if (x % current_chunk_size != 0 || y % current_chunk_size != 0) { - continue; + if(Pixel.COMPARE_ALG == 16) { + for (int i = 0; i < coordinatesFastJulia.length; i++) { + Pixel pix = coordinatesFastJulia[i]; + x = pix.x; + y = pix.y; + + if (x % current_chunk_size != 0 || y % current_chunk_size != 0 || (y / current_chunk_size) % 2 == 1) { + continue; + } + list.add(pix); + } + + for (int i = 0; i < coordinatesFastJulia.length; i++) { + Pixel pix = coordinatesFastJulia[i]; + x = pix.x; + y = pix.y; + + if (x % current_chunk_size != 0 || y % current_chunk_size != 0 || (y / current_chunk_size) % 2 == 0) { + continue; + } + list.add(pix); + } + } + else { + for (int i = 0; i < coordinatesFastJulia.length; i++) { + Pixel pix = coordinatesFastJulia[i]; + x = pix.x; + y = pix.y; + + if (x % current_chunk_size != 0 || y % current_chunk_size != 0) { + continue; + } + list.add(pix); } - list.add(pix); } Pixel[] array = new Pixel[list.size()]; @@ -125,20 +176,7 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi int pixel_percent = (image_size * image_size) / 100; - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); int color, loc2, x, y; @@ -149,8 +187,10 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi int current_chunk_size = SUCCESSIVE_REFINEMENT_MAX_SIZE; + int prev_chunk_size = 0; int iteration = randomNumber; int min_chunk_size = TaskDraw.GUESS_BLOCKS_SELECTION == 0 ? 0 : 1 << (TaskDraw.GUESS_BLOCKS_SELECTION - 1); + min_chunk_size = TWO_PASS_SUCCESSIVE_REFINEMENT ? min_chunk_size << 1 : min_chunk_size; int current_chunk_size2 = 0; @@ -166,10 +206,12 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi int condition; + int stop_id = getStopAfterIter(); + task_completed = 0; long nano_time = 0; - for(int id = 0; current_chunk_size >= 1; current_chunk_size >>= 1, id++, iteration++) { + for(int id = 0, id2 = 0; current_chunk_size >= 1; id++) { long time = System.nanoTime(); @@ -177,9 +219,10 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi int coordinatesLoc; - Pixel[] coordinates = CoordinatesPerLevel[id]; + Pixel[] coordinates = CoordinatesPerLevel[id2]; condition = coordinates.length; - int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL[id]; + int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL[id2]; + boolean performSecondPassActions = !TWO_PASS_SUCCESSIVE_REFINEMENT || (id & 1) == 1; do { @@ -198,8 +241,9 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi if(!filled[loc2]) { - if(current_chunk_size <= min_chunk_size) { - current_chunk_size2 = current_chunk_size << 1; + boolean check = performSecondPassActions && current_chunk_size <= min_chunk_size; + if(check) { + current_chunk_size2 = prev_chunk_size; xstart = (x / current_chunk_size2) * current_chunk_size2; ystart = (y / current_chunk_size2) * current_chunk_size2; @@ -215,40 +259,45 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi locc += xstart; } - if(current_chunk_size <= min_chunk_size && xend < image_size && yend < image_size && isTheSame(loca, locb, locc, locd)) { + if(check && xend < image_size && yend < image_size && isTheSame(loca, locb, locc, locd)) { tempx = Math.min(image_size, x + current_chunk_size); tempy = Math.min(image_size, y + current_chunk_size); - int skippedColor = getColorForSkippedPixels(rgbs[loca], iteration); + int start_color = rgbs[loca]; + int skippedColor = getColorForSkippedPixels(start_color, iteration); + double start_iterations = image_iterations[loca]; + boolean start_escaped = escaped[loca]; + for (int i = y; i < tempy; i++) { for (int j = x, loc3 = i * image_size + j; j < tempx; j++, loc3++) { if(!examined[loc3]) { - rgbs[loc3] = rgbs[loca]; - image_iterations[loc3] = image_iterations[loca]; - escaped[loc3] = escaped[loca]; + if (rgbs[loc3] >>> 24 != Constants.NORMAL_ALPHA) { + rgbs[loc3] = start_color; + image_iterations[loc3] = start_iterations; + escaped[loc3] = start_escaped; + task_completed++; + } setFilledAndExaminedWithSkippedColor(examined, filled, skipped_colors, loc3, skippedColor); drawing_done++; - task_completed++; } } } } else if (!examined[loc2]){ - if (rgbs[loc2] >>> 24 != Constants.NORMAL_ALPHA) { image_iterations[loc2] = f_val = iteration_algorithm.calculate(location.getComplex(x, y)); escaped[loc2] = escaped_val = iteration_algorithm.escaped(); rgbs[loc2] = color = getFinalColor(f_val, escaped_val); task_calculated++; + task_completed++; } else { color = rgbs[loc2]; } examined[loc2] = true; drawing_done++; - task_completed++; tempx = Math.min(image_size, x + current_chunk_size); tempy = Math.min(image_size, y + current_chunk_size); @@ -263,12 +312,12 @@ else if (!examined[loc2]){ } } - if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > STOP_AFTER_ITER && STOP_SUCCESSIVE_REFINEMENT) { + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { break; } } - if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > STOP_AFTER_ITER && STOP_SUCCESSIVE_REFINEMENT) { + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { break; } @@ -298,8 +347,8 @@ else if (!examined[loc2]){ } if(taskId == 0 && ptr != null) { - ptr.setWholeImageDone(true); if(id == 0) { + ptr.setWholeImageDone(true); ptr.reloadTitle(); updateMode(ptr, false, iteration_algorithm.isJulia(), false, false); } @@ -307,12 +356,19 @@ else if (!examined[loc2]){ } if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT) { - if (id > STOP_AFTER_ITER && STOP_SUCCESSIVE_REFINEMENT) { + if (id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { successive_refinement_lock.unlockRead(); throw new StopSuccessiveRefinementException(); } successive_refinement_lock.unlockRead(); } + + prev_chunk_size = current_chunk_size; + if(performSecondPassActions) { + current_chunk_size >>= 1; + iteration++; + id2++; + } } if(SKIPPED_PIXELS_ALG != 0) { @@ -339,20 +395,7 @@ protected void drawFastJuliaAntialiased(int image_size, boolean polar) { int supersampling_num = getExtraSamples(aaSamplesIndex, aaMethod); location.createAntialiasingSteps(aaMethod == 5, useJitter, supersampling_num); - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); boolean aaAvgWithMean = ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x1) == 1; int colorSpace = filters_options_extra_vals[0][MainWindow.ANTIALIASING]; @@ -372,8 +415,10 @@ protected void drawFastJuliaAntialiased(int image_size, boolean polar) { double temp_result; int current_chunk_size = SUCCESSIVE_REFINEMENT_MAX_SIZE; + int prev_chunk_size = 0; int iteration = randomNumber; int min_chunk_size = TaskDraw.GUESS_BLOCKS_SELECTION == 0 ? 0 : 1 << (TaskDraw.GUESS_BLOCKS_SELECTION - 1); + min_chunk_size = TWO_PASS_SUCCESSIVE_REFINEMENT ? min_chunk_size << 1 : min_chunk_size; int current_chunk_size2 = 0; @@ -389,12 +434,13 @@ protected void drawFastJuliaAntialiased(int image_size, boolean polar) { int condition; - for(int id = 0; current_chunk_size >= 1; current_chunk_size >>= 1, id++, iteration++) { + for(int id = 0, id2 = 0; current_chunk_size >= 1; id++) { AtomicInteger ai = successive_refinement_drawing_algorithm_pixel[id]; - Pixel[] coordinates = CoordinatesPerLevelFastJulia[id]; + Pixel[] coordinates = CoordinatesPerLevelFastJulia[id2]; condition = coordinates.length; - int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL[id]; + int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL[id2]; + boolean performSecondPassActions = !TWO_PASS_SUCCESSIVE_REFINEMENT || (id & 1) == 1; int coordinatesLoc; @@ -416,8 +462,9 @@ protected void drawFastJuliaAntialiased(int image_size, boolean polar) { if(!filled_fast_julia[loc2]) { - if(current_chunk_size <= min_chunk_size) { - current_chunk_size2 = current_chunk_size << 1; + boolean check = performSecondPassActions && current_chunk_size <= min_chunk_size; + if(check) { + current_chunk_size2 = prev_chunk_size; xstart = (x / current_chunk_size2) * current_chunk_size2; ystart = (y / current_chunk_size2) * current_chunk_size2; @@ -433,22 +480,31 @@ protected void drawFastJuliaAntialiased(int image_size, boolean polar) { locc += xstart; } - if(current_chunk_size <= min_chunk_size && xend < image_size && yend < image_size && isTheSameFastJulia(loca, locb, locc, locd)) { + if(check && xend < image_size && yend < image_size && isTheSameFastJulia(loca, locb, locc, locd)) { tempx = Math.min(image_size, x + current_chunk_size); tempy = Math.min(image_size, y + current_chunk_size); - int skippedColor = getColorForSkippedPixels(rgbs[loca], iteration); + int start_color = rgbs[loca]; + int skippedColor = getColorForSkippedPixels(start_color, iteration); + double start_iterations = image_iterations_fast_julia[loca]; + boolean start_escaped = escaped_fast_julia[loca]; + + PixelExtraData start_extra_data = null; + if(storeExtraData) { + start_extra_data = pixelData_fast_julia[loca]; + } + for (int i = y; i < tempy; i++) { for (int j = x, loc3 = i * image_size + j; j < tempx; j++, loc3++) { if(!examined_fast_julia[loc3]) { - rgbs[loc3] = rgbs[loca]; - image_iterations_fast_julia[loc3] = image_iterations_fast_julia[loca]; - escaped_fast_julia[loc3] = escaped_fast_julia[loca]; + rgbs[loc3] = start_color; + image_iterations_fast_julia[loc3] = start_iterations; + escaped_fast_julia[loc3] = start_escaped; setFilledAndExaminedWithSkippedColor(examined_fast_julia, filled_fast_julia, skipped_colors_fast_julia, loc3, skippedColor); if(storeExtraData) { - pixelData_fast_julia[loc3] = new PixelExtraData(pixelData_fast_julia[loca], skippedColor); + pixelData_fast_julia[loc3] = new PixelExtraData(start_extra_data, skippedColor); } } } @@ -497,6 +553,13 @@ else if (!examined_fast_julia[loc2]){ } catch (BrokenBarrierException ex) { } + + prev_chunk_size = current_chunk_size; + if(performSecondPassActions) { + current_chunk_size >>= 1; + iteration++; + id2++; + } } @@ -525,20 +588,7 @@ protected void drawIterationsAntialiased(int image_size, boolean polar) throws S location.createAntialiasingSteps(aaMethod == 5, useJitter, supersampling_num); int pixel_percent = (image_size * image_size) / 100; - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); boolean aaAvgWithMean = ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x1) == 1; int colorSpace = filters_options_extra_vals[0][MainWindow.ANTIALIASING]; @@ -559,8 +609,10 @@ protected void drawIterationsAntialiased(int image_size, boolean polar) throws S int current_chunk_size = SUCCESSIVE_REFINEMENT_MAX_SIZE; + int prev_chunk_size = 0; int iteration = randomNumber; int min_chunk_size = TaskDraw.GUESS_BLOCKS_SELECTION == 0 ? 0 : 1 << (TaskDraw.GUESS_BLOCKS_SELECTION - 1); + min_chunk_size = TWO_PASS_SUCCESSIVE_REFINEMENT ? min_chunk_size << 1 : min_chunk_size; int current_chunk_size2 = 0; @@ -576,17 +628,20 @@ protected void drawIterationsAntialiased(int image_size, boolean polar) throws S int condition; + int stop_id = getStopAfterIter(); + task_completed = 0; long nano_time = 0; - for(int id = 0; current_chunk_size >= 1; current_chunk_size >>= 1, id++, iteration++) { + for(int id = 0, id2 = 0; current_chunk_size >= 1; id++) { long time = System.nanoTime(); AtomicInteger ai = successive_refinement_drawing_algorithm_pixel[id]; - Pixel[] coordinates = CoordinatesPerLevel[id]; + Pixel[] coordinates = CoordinatesPerLevel[id2]; condition = coordinates.length; - int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL[id]; + int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL[id2]; + boolean performSecondPassActions = !TWO_PASS_SUCCESSIVE_REFINEMENT || (id & 1) == 1; int coordinatesLoc; @@ -608,8 +663,9 @@ protected void drawIterationsAntialiased(int image_size, boolean polar) throws S if(!filled[loc2]) { - if(current_chunk_size <= min_chunk_size) { - current_chunk_size2 = current_chunk_size << 1; + boolean check = performSecondPassActions && current_chunk_size <= min_chunk_size; + if(check) { + current_chunk_size2 = prev_chunk_size; xstart = (x / current_chunk_size2) * current_chunk_size2; ystart = (y / current_chunk_size2) * current_chunk_size2; @@ -625,22 +681,31 @@ protected void drawIterationsAntialiased(int image_size, boolean polar) throws S locc += xstart; } - if(current_chunk_size <= min_chunk_size && xend < image_size && yend < image_size && isTheSame(loca, locb, locc, locd)) { + if(check && xend < image_size && yend < image_size && isTheSame(loca, locb, locc, locd)) { tempx = Math.min(image_size, x + current_chunk_size); tempy = Math.min(image_size, y + current_chunk_size); - int skippedColor = getColorForSkippedPixels(rgbs[loca], iteration); + int start_color = rgbs[loca]; + int skippedColor = getColorForSkippedPixels(start_color, iteration); + double start_iterations = image_iterations[loca]; + boolean start_escaped = escaped[loca]; + + PixelExtraData start_extra_data = null; + if(storeExtraData) { + start_extra_data = pixelData[loca]; + } + for (int i = y; i < tempy; i++) { for (int j = x, loc3 = i * image_size + j; j < tempx; j++, loc3++) { if(!examined[loc3]) { - rgbs[loc3] = rgbs[loca]; - image_iterations[loc3] = image_iterations[loca]; - escaped[loc3] = escaped[loca]; + rgbs[loc3] = start_color; + image_iterations[loc3] = start_iterations; + escaped[loc3] = start_escaped; setFilledAndExaminedWithSkippedColor(examined, filled, skipped_colors, loc3, skippedColor); if(storeExtraData) { - pixelData[loc3] = new PixelExtraData(pixelData[loca], skippedColor); + pixelData[loc3] = new PixelExtraData(start_extra_data, skippedColor); } task_completed++; drawing_done++; @@ -649,7 +714,6 @@ protected void drawIterationsAntialiased(int image_size, boolean polar) throws S } } else if (!examined[loc2]){ - image_iterations[loc2] = f_val = iteration_algorithm.calculate(location.getComplex(x, y)); escaped[loc2] = escaped_val = iteration_algorithm.escaped(); color = getFinalColor(f_val, escaped_val); @@ -659,30 +723,29 @@ else if (!examined[loc2]){ drawing_done++; task_completed++; - if(storeExtraData) { + if (storeExtraData) { pixelData[loc2].set(0, color, f_val, escaped_val, totalSamples); } aa.initialize(color); //Supersampling - for(int i = 0; i < supersampling_num; i++) { + for (int i = 0; i < supersampling_num; i++) { temp_result = iteration_algorithm.calculate(location.getAntialiasingComplex(i, loc2)); escaped_val = iteration_algorithm.escaped(); color = getFinalColor(temp_result, escaped_val); - if(storeExtraData) { + if (storeExtraData) { pixelData[loc2].set(i + 1, color, temp_result, escaped_val, totalSamples); } - if(!aa.addSample(color)) { + if (!aa.addSample(color)) { break; } } rgbs[loc2] = color = aa.getColor(); - tempx = Math.min(image_size, x + current_chunk_size); tempy = Math.min(image_size, y + current_chunk_size); @@ -694,12 +757,12 @@ else if (!examined[loc2]){ } } - if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > STOP_AFTER_ITER && STOP_SUCCESSIVE_REFINEMENT) { + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { break; } } - if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > STOP_AFTER_ITER && STOP_SUCCESSIVE_REFINEMENT) { + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { break; } @@ -728,8 +791,8 @@ else if (!examined[loc2]){ } if(taskId == 0 && ptr != null) { - ptr.setWholeImageDone(true); if(id == 0) { + ptr.setWholeImageDone(true); ptr.reloadTitle(); updateMode(ptr, false, iteration_algorithm.isJulia(), false, false); } @@ -737,12 +800,19 @@ else if (!examined[loc2]){ } if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT) { - if (id > STOP_AFTER_ITER && STOP_SUCCESSIVE_REFINEMENT) { + if (id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { successive_refinement_lock.unlockRead(); throw new StopSuccessiveRefinementException(); } successive_refinement_lock.unlockRead(); } + + prev_chunk_size = current_chunk_size; + if(performSecondPassActions) { + current_chunk_size >>= 1; + iteration++; + id2++; + } } if(SKIPPED_PIXELS_ALG != 0) { @@ -764,20 +834,7 @@ protected void drawFastJulia(int image_size, boolean polar) { Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (HIGH_PRECISION_CALCULATION || PERTURBATION_THEORY) && fractal.supportsPerturbationTheory()); - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); int loc2, x, y; @@ -788,8 +845,10 @@ protected void drawFastJulia(int image_size, boolean polar) { int current_chunk_size = SUCCESSIVE_REFINEMENT_MAX_SIZE; + int prev_chunk_size = 0; int iteration = randomNumber; int min_chunk_size = TaskDraw.GUESS_BLOCKS_SELECTION == 0 ? 0 : 1 << (TaskDraw.GUESS_BLOCKS_SELECTION - 1); + min_chunk_size = TWO_PASS_SUCCESSIVE_REFINEMENT ? min_chunk_size << 1 : min_chunk_size; int current_chunk_size2 = 0; @@ -805,12 +864,13 @@ protected void drawFastJulia(int image_size, boolean polar) { int condition; - for(int id = 0; current_chunk_size >= 1; current_chunk_size >>= 1, id++, iteration++) { + for(int id = 0, id2 = 0; current_chunk_size >= 1; id++) { AtomicInteger ai = successive_refinement_drawing_algorithm_pixel[id]; - Pixel[] coordinates = CoordinatesPerLevelFastJulia[id]; + Pixel[] coordinates = CoordinatesPerLevelFastJulia[id2]; condition = coordinates.length; - int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL[id]; + int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL[id2]; + boolean performSecondPassActions = !TWO_PASS_SUCCESSIVE_REFINEMENT || (id & 1) == 1; int coordinatesLoc; @@ -831,8 +891,9 @@ protected void drawFastJulia(int image_size, boolean polar) { if(!filled_fast_julia[loc2]) { - if(current_chunk_size <= min_chunk_size) { - current_chunk_size2 = current_chunk_size << 1; + boolean check = performSecondPassActions && current_chunk_size <= min_chunk_size; + if(check) { + current_chunk_size2 = prev_chunk_size; xstart = (x / current_chunk_size2) * current_chunk_size2; ystart = (y / current_chunk_size2) * current_chunk_size2; @@ -848,19 +909,23 @@ protected void drawFastJulia(int image_size, boolean polar) { locc += xstart; } - if(current_chunk_size <= min_chunk_size && xend < image_size && yend < image_size && isTheSameFastJulia(loca, locb, locc, locd)) { + if(check && xend < image_size && yend < image_size && isTheSameFastJulia(loca, locb, locc, locd)) { tempx = Math.min(image_size, x + current_chunk_size); tempy = Math.min(image_size, y + current_chunk_size); - int skippedColor = getColorForSkippedPixels(rgbs[loca], iteration); + int start_color = rgbs[loca]; + int skippedColor = getColorForSkippedPixels(start_color, iteration); + double start_iterations = image_iterations_fast_julia[loca]; + boolean start_escaped = escaped_fast_julia[loca]; + for (int i = y; i < tempy; i++) { for (int j = x, loc3 = i * image_size + j; j < tempx; j++, loc3++) { if(!examined_fast_julia[loc3]) { - rgbs[loc3] = rgbs[loca]; - image_iterations_fast_julia[loc3] = image_iterations_fast_julia[loca]; - escaped_fast_julia[loc3] = escaped_fast_julia[loca]; + rgbs[loc3] = start_color; + image_iterations_fast_julia[loc3] = start_iterations; + escaped_fast_julia[loc3] = start_escaped; setFilledAndExaminedWithSkippedColor(examined_fast_julia, filled_fast_julia, skipped_colors_fast_julia, loc3, skippedColor); } } @@ -886,6 +951,13 @@ else if (!examined_fast_julia[loc2]){ } catch (BrokenBarrierException ex) { } + + prev_chunk_size = current_chunk_size; + if(performSecondPassActions) { + current_chunk_size >>= 1; + iteration++; + id2++; + } } if(SKIPPED_PIXELS_ALG != 0) { @@ -1169,20 +1241,7 @@ protected void quickDrawIterations(int image_size, boolean polar) { Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (PERTURBATION_THEORY || HIGH_PRECISION_CALCULATION) && fractal.supportsPerturbationTheory()); - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); int color, loc2, x, y; int tempx, tempy; @@ -1265,8 +1324,8 @@ protected void quickDrawIterations(int image_size, boolean polar) { } if(taskId == 0) { - ptr.setWholeImageDone(true); if(id == 0) { + ptr.setWholeImageDone(true); ptr.reloadTitle(); updateMode(ptr, false, iteration_algorithm.isJulia(), false, false); } @@ -1364,8 +1423,8 @@ protected void quickDrawIterationsDomain(int image_size, boolean polar) { } if(taskId == 0) { - ptr.setWholeImageDone(true); if(id == 0) { + ptr.setWholeImageDone(true); ptr.reloadTitle(); updateMode(ptr, false, iteration_algorithm.isJulia(), false, false); } @@ -1550,18 +1609,16 @@ protected void drawIterationsDomainAntialiased(int image_size, boolean polar) { rgbs[loc] = aa.getColor(); drawing_done++; + task_calculated++; } if (drawing_done / pixel_percent >= 1) { update(drawing_done); - task_calculated += drawing_done; drawing_done = 0; } } while (true); - task_calculated += drawing_done; - pixel_calculation_time_per_task = System.currentTimeMillis() - time; try { diff --git a/src/fractalzoomer/core/drawing_algorithms/MarianiSilver2Draw.java b/src/fractalzoomer/core/drawing_algorithms/MarianiSilver2Draw.java index 764a61076..01464bde6 100644 --- a/src/fractalzoomer/core/drawing_algorithms/MarianiSilver2Draw.java +++ b/src/fractalzoomer/core/drawing_algorithms/MarianiSilver2Draw.java @@ -50,20 +50,7 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (PERTURBATION_THEORY || HIGH_PRECISION_CALCULATION) && fractal.supportsPerturbationTheory()); - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); ExpandingQueueSquare squares = new ExpandingQueueSquare(RENDER_USING_DFS ? INIT_QUEUE_SIZE : INIT_QUEUE_SIZE2); @@ -126,6 +113,7 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi temp_starting_pixel_color = rgbs[loc] = getFinalColor(temp_starting_value, temp_starting_escaped); drawing_done++; task_calculated++; + task_completed++; } else { temp_starting_value = image_iterations[loc]; @@ -146,6 +134,7 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi drawing_done++; task_calculated++; + task_completed++; } } @@ -162,6 +151,7 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi drawing_done++; task_calculated++; + task_completed++; } } @@ -177,6 +167,7 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi drawing_done++; task_calculated++; + task_completed++; } } @@ -193,6 +184,7 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi drawing_done++; task_calculated++; + task_completed++; } } @@ -242,9 +234,16 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi int temploc = k * image_size; int loc3 = temploc + x; int loc4 = temploc + temp1; - Arrays.fill(rgbs, loc3, loc4, skippedColor); - Arrays.fill(image_iterations, loc3, loc4, temp_starting_value); - Arrays.fill(escaped, loc3, loc4, temp_starting_escaped); + + for (int index = loc3; index < loc4; index++) { + if (rgbs[index] == notCalculated) { + image_iterations[index] = temp_starting_value; + rgbs[index] = skippedColor; + escaped[index] = temp_starting_escaped; + task_completed++; + } + } + drawing_done += chunk; } diff --git a/src/fractalzoomer/core/drawing_algorithms/MarianiSilver3ColorsAndIterationDataDraw.java b/src/fractalzoomer/core/drawing_algorithms/MarianiSilver3ColorsAndIterationDataDraw.java new file mode 100644 index 000000000..99d213ed4 --- /dev/null +++ b/src/fractalzoomer/core/drawing_algorithms/MarianiSilver3ColorsAndIterationDataDraw.java @@ -0,0 +1,67 @@ +/* + * Fractal Zoomer, Copyright (C) 2020 hrkalona2 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package fractalzoomer.core.drawing_algorithms; + +import fractalzoomer.main.ImageExpanderWindow; +import fractalzoomer.main.MainWindow; +import fractalzoomer.main.app_settings.*; +import org.apfloat.Apfloat; + +import java.awt.*; +import java.awt.image.BufferedImage; + +/** + * + * @author hrkalona2 + */ +public class MarianiSilver3ColorsAndIterationDataDraw extends MarianiSilver3Draw { + + public MarianiSilver3ColorsAndIterationDataDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, D3Settings d3s, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, boolean quickDraw, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, d3s, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, quickDraw, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps); + } + + public MarianiSilver3ColorsAndIterationDataDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, ImageExpanderWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps); + } + + public MarianiSilver3ColorsAndIterationDataDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, D3Settings d3s, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, boolean quickDraw, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps, Apfloat xJuliaCenter, Apfloat yJuliaCenter) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, d3s, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, quickDraw, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); + } + + public MarianiSilver3ColorsAndIterationDataDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, ImageExpanderWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps, Apfloat xJuliaCenter, Apfloat yJuliaCenter) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); + } + + public MarianiSilver3ColorsAndIterationDataDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps); + } + + public MarianiSilver3ColorsAndIterationDataDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, MainWindow ptr, Color fractal_color, Color dem_color, boolean fast_julia_filters, BufferedImage image, boolean periodicity_checking, FiltersSettings fs, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps, Apfloat xJuliaCenter, Apfloat yJuliaCenter) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, fast_julia_filters, image, periodicity_checking, fs, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); + } + + @Override + protected boolean isNotTheSame(int loc, int pixel_color, double pixel_value) { + return rgbs[loc] != pixel_color || image_iterations[loc] != pixel_value; + } + + @Override + protected boolean isNotTheSameFastJulia(int loc, int pixel_color, double pixel_value) { + return rgbs[loc] != pixel_color || image_iterations_fast_julia[loc] != pixel_value; + } + +} diff --git a/src/fractalzoomer/core/drawing_algorithms/MarianiSilver3Draw.java b/src/fractalzoomer/core/drawing_algorithms/MarianiSilver3Draw.java new file mode 100644 index 000000000..9317f75e5 --- /dev/null +++ b/src/fractalzoomer/core/drawing_algorithms/MarianiSilver3Draw.java @@ -0,0 +1,1550 @@ +/* + * Fractal Zoomer, Copyright (C) 2020 hrkalona2 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package fractalzoomer.core.drawing_algorithms; + +import fractalzoomer.core.PixelExtraData; +import fractalzoomer.core.TaskDraw; +import fractalzoomer.core.antialiasing.AntialiasingAlgorithm; +import fractalzoomer.core.location.Location; +import fractalzoomer.functions.Fractal; +import fractalzoomer.main.Constants; +import fractalzoomer.main.ImageExpanderWindow; +import fractalzoomer.main.MainWindow; +import fractalzoomer.main.app_settings.*; +import fractalzoomer.utils.ExpandingQueueSquare; +import fractalzoomer.utils.Square; +import fractalzoomer.utils.StopSuccessiveRefinementException; +import org.apfloat.Apfloat; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.util.Arrays; +import java.util.concurrent.BrokenBarrierException; + +/** + * + * @author hrkalona2 + */ +public class MarianiSilver3Draw extends MarianiSilverDraw { + + public MarianiSilver3Draw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, D3Settings d3s, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, boolean quickDraw, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, d3s, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, quickDraw, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps); + } + + public MarianiSilver3Draw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, ImageExpanderWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps); + } + + public MarianiSilver3Draw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, D3Settings d3s, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, boolean quickDraw, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps, Apfloat xJuliaCenter, Apfloat yJuliaCenter) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, d3s, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, quickDraw, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); + } + + public MarianiSilver3Draw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, ImageExpanderWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps, Apfloat xJuliaCenter, Apfloat yJuliaCenter) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); + } + + public MarianiSilver3Draw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps); + } + + public MarianiSilver3Draw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, MainWindow ptr, Color fractal_color, Color dem_color, boolean fast_julia_filters, BufferedImage image, boolean periodicity_checking, FiltersSettings fs, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps, Apfloat xJuliaCenter, Apfloat yJuliaCenter) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, fast_julia_filters, image, periodicity_checking, fs, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); + } + + @Override + protected void drawIterations(int image_size, boolean polar) throws StopSuccessiveRefinementException { + + Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (PERTURBATION_THEORY || HIGH_PRECISION_CALCULATION) && fractal.supportsPerturbationTheory()); + + initialize(location); + + int pixel_percent = (image_size * image_size) / 100; + + int loc; + + //ptr.setWholeImageDone(true); + + boolean escaped_val; + double f_val; + + task_completed = 0; + + long time = System.currentTimeMillis(); + + int x = FROMx; + location.precalculateX(x); + for (int y = FROMy; y < TOy; y++) { + loc = y * image_size + x; + + if(rgbs[loc] >>> 24 != Constants.NORMAL_ALPHA) { + image_iterations[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithY(y)); + escaped[loc] = escaped_val = iteration_algorithm.escaped(); + rgbs[loc] = getFinalColor(f_val, escaped_val); + task_calculated++; + task_completed++; + } + drawing_done++; + + } + + if (TOx == image_size) { + x = TOx - 1; + location.precalculateX(x); + for (int y = FROMy + 1; y < TOy; y++) { + loc = y * image_size + x; + + if(rgbs[loc] >>> 24 != Constants.NORMAL_ALPHA) { + image_iterations[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithY(y)); + escaped[loc] = escaped_val = iteration_algorithm.escaped(); + rgbs[loc] = getFinalColor(f_val, escaped_val); + task_calculated++; + task_completed++; + } + drawing_done++; + + } + } + + int y = FROMy; + location.precalculateY(y); + for (x = FROMx + 1, loc = y * image_size + x; x < TOx; x++, loc++) { + + if(rgbs[loc] >>> 24 != Constants.NORMAL_ALPHA) { + image_iterations[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithX(x)); + escaped[loc] = escaped_val = iteration_algorithm.escaped(); + rgbs[loc] = getFinalColor(f_val, escaped_val); + task_calculated++; + task_completed++; + } + drawing_done++; + + } + + if (TOy == image_size) { + y = TOy - 1; + + int xLimit = TOx; + + if (TOx == image_size) { + xLimit--; + } + + location.precalculateY(y); + for (x = FROMx + 1, loc = y * image_size + x; x < xLimit; x++, loc++) { + + if(rgbs[loc] >>> 24 != Constants.NORMAL_ALPHA) { + image_iterations[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithX(x)); + escaped[loc] = escaped_val = iteration_algorithm.escaped(); + rgbs[loc] = getFinalColor(f_val, escaped_val); + task_calculated++; + task_completed++; + } + drawing_done++; + + } + } + + if (drawing_done / pixel_percent >= 1) { + update(drawing_done); + drawing_done = 0; + } + + ExpandingQueueSquare squares = new ExpandingQueueSquare(RENDER_USING_DFS ? INIT_QUEUE_SIZE : INIT_QUEUE_SIZE2); + + Square square = new Square(FROMx, FROMy, TOx, TOy, randomNumber); + + squares.enqueue(square); + + try { + initialize_jobs_sync.await(); + } catch (InterruptedException ex) { + + } catch (BrokenBarrierException ex) { + + } + + int slice_FROMx; + int slice_FROMy; + int slice_TOx; + int slice_TOy; + + boolean whole_area; + int temp_starting_pixel_color; + double temp_starting_value; + boolean temp_starting_escaped; + + int skippedColor; + + do { + + Square currentSquare = null; + + if (squares.isEmpty()) { + break; + } + + if(RENDER_USING_DFS) { + currentSquare = squares.last(); + } + else { + currentSquare = squares.dequeue(); + } + + whole_area = true; + + slice_FROMx = currentSquare.x1; + slice_FROMy = currentSquare.y1; + slice_TOx = currentSquare.x2; + slice_TOy = currentSquare.y2; + + if (slice_TOy == image_size) { + slice_TOy--; + } + + if (slice_TOx == image_size) { + slice_TOx--; + } + + y = slice_FROMy; + x = slice_FROMx; + + loc = y * image_size + x; + + temp_starting_value = image_iterations[loc]; + temp_starting_pixel_color = rgbs[loc]; + temp_starting_escaped = escaped[loc]; + + int loc2; + for (loc = slice_FROMy * image_size + x, loc2 = slice_TOy * image_size + x; x <= slice_TOx; x++, loc++, loc2++) { + if (isNotTheSame(loc, temp_starting_pixel_color, temp_starting_value) || isNotTheSame(loc2, temp_starting_pixel_color, temp_starting_value)) { + whole_area = false; + break; + } + } + + if (whole_area) { + for (y = slice_FROMy + 1, loc = y * image_size + slice_FROMx, loc2 = y * image_size + slice_TOx; y <= slice_TOy - 1; y++, loc += image_size, loc2 += image_size) { + if (isNotTheSame(loc, temp_starting_pixel_color, temp_starting_value) || isNotTheSame(loc2, temp_starting_pixel_color, temp_starting_value)) { + whole_area = false; + break; + } + } + } + + if (!whole_area) { + + int xLength = slice_TOx - slice_FROMx + 1; + int yLength = slice_TOy - slice_FROMy + 1; + + if (canSubDivide(xLength, yLength)) { + if(getSplitMode(currentSquare.iteration - randomNumber) == 1) { + int halfY = slice_FROMy + (yLength >>> 1); + y = halfY; + location.precalculateY(y); + for (x = slice_FROMx + 1, loc = y * image_size + x; x < slice_TOx; x++, loc++) { + + if (rgbs[loc] >>> 24 != Constants.NORMAL_ALPHA) { + image_iterations[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithX(x)); + escaped[loc] = escaped_val = iteration_algorithm.escaped(); + rgbs[loc] = getFinalColor(f_val, escaped_val); + task_calculated++; + task_completed++; + } + drawing_done++; + } + + Square square1 = new Square(slice_FROMx, slice_FROMy, slice_TOx, halfY, currentSquare.iteration + 1); + + squares.enqueue(square1); + + Square square3 = new Square(slice_FROMx, halfY, slice_TOx, slice_TOy, currentSquare.iteration + 1); + + squares.enqueue(square3); + } + else { + int halfX = slice_FROMx + (xLength >>> 1); + x = halfX; + location.precalculateX(x); + for (y = slice_FROMy + 1; y < slice_TOy; y++) { + loc = y * image_size + x; + if(rgbs[loc] >>> 24 != Constants.NORMAL_ALPHA) { + image_iterations[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithY(y)); + escaped[loc] = escaped_val = iteration_algorithm.escaped(); + rgbs[loc] = getFinalColor(f_val, escaped_val); + task_calculated++; + task_completed++; + } + drawing_done++; + } + + Square square2 = new Square(slice_FROMx, slice_FROMy, halfX, slice_TOy, currentSquare.iteration + 1); + + squares.enqueue(square2); + + Square square4 = new Square(halfX, slice_FROMy, slice_TOx, slice_TOy, currentSquare.iteration + 1); + + squares.enqueue(square4); + } + } else { + //calculate the rest with the normal way + for (y = slice_FROMy + 1; y < slice_TOy; y++) { + for (x = slice_FROMx + 1, loc = y * image_size + x; x < slice_TOx; x++, loc++) { + if(rgbs[loc] >>> 24 != Constants.NORMAL_ALPHA) { + image_iterations[loc] = f_val = iteration_algorithm.calculate(location.getComplex(x, y)); + escaped[loc] = escaped_val = iteration_algorithm.escaped(); + rgbs[loc] = getFinalColor(f_val, escaped_val); + task_calculated++; + task_completed++; + } + drawing_done++; + } + } + + if (drawing_done / pixel_percent >= 1) { + update(drawing_done); + drawing_done = 0; + } + } + } else { + y = slice_FROMy + 1; + x = slice_FROMx + 1; + + int chunk = slice_TOx - x; + + skippedColor = getColorForSkippedPixels(temp_starting_pixel_color, currentSquare.iteration); + + for (int k = y; k < slice_TOy; k++) { + int temploc = k * image_size; + int loc3 = temploc + x; + int loc4 = temploc + slice_TOx; + + for (int index = loc3; index < loc4; index++) { + if (rgbs[index] >>> 24 != Constants.NORMAL_ALPHA) { + image_iterations[index] = temp_starting_value; + rgbs[index] = skippedColor; + escaped[index] = temp_starting_escaped; + task_completed++; + } + } + + drawing_done += chunk; + } + + if (drawing_done / pixel_percent >= 1) { + update(drawing_done); + drawing_done = 0; + } + + /*ptr.getMainPanel().repaint(); + try { + Thread.sleep(1); //demo + } + catch (InterruptedException ex) {}*/ + + } + + } while (true); + + if (SKIPPED_PIXELS_ALG == 4) { + drawSquares(image_size); + } + + pixel_calculation_time_per_task = System.currentTimeMillis() - time; + + postProcess(image_size, null, location); + } + + @Override + protected boolean canSubDivide(int xLength, int yLength) { + return (xLength >= MAX_TILE_SIZE || yLength >= MAX_TILE_SIZE) && (xLength >= 3 && yLength >= 3); + } + + private int getSplitMode(int iteration) { + if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM == 1) { + return ((iteration + 1) % 2); //1, 0, 1, 0,... + } + else if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM == 2) { + return iteration % 2; // 0, 1, 0, 1,... + } + else if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM == 3) { + //1, 0, 0, 1, 1, 0, 0, 1, 1 + int iter = iteration + 2; + int val = iter % 2; + int val2 = iter % 4; + if(val2 < 2) { + return val; + } + else { + return 1 - val; + } + } + else if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM == 4) { + //0, 1, 1, 0, 0, 1, 1, 0, 0,... + int val = iteration % 2; + int val2 = iteration % 4; + if(val2 < 2) { + return val; + } + else { + return 1 - val; + } + } + return -1; + } + + + @Override + protected void drawIterationsAntialiased(int image_size, boolean polar) throws StopSuccessiveRefinementException { + + int aaMethod = (filters_options_vals[MainWindow.ANTIALIASING] % 100) / 10; + boolean useJitter = aaMethod != 6 && ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x4) == 4; + Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, PERTURBATION_THEORY && fractal.supportsPerturbationTheory()); + int aaSamplesIndex = (filters_options_vals[MainWindow.ANTIALIASING] % 100) % 10; + int supersampling_num = getExtraSamples(aaSamplesIndex, aaMethod); + location.createAntialiasingSteps(aaMethod == 5, useJitter, supersampling_num); + + initialize(location); + + int pixel_percent = (image_size * image_size) / 100; + + int loc; + + boolean aaAvgWithMean = ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x1) == 1; + int colorSpace = filters_options_extra_vals[0][MainWindow.ANTIALIASING]; + int totalSamples = supersampling_num + 1; + + AntialiasingAlgorithm aa = AntialiasingAlgorithm.getAntialiasingAlgorithm(totalSamples, aaMethod, aaAvgWithMean, colorSpace, fs.aaSigmaR, fs.aaSigmaS); + + aa.setNeedsPostProcessing(needsPostProcessing()); + + boolean storeExtraData = pixelData != null; + + int color; + double temp_result; + + boolean escaped_val; + double f_val; + task_completed = 0; + + long time = System.currentTimeMillis(); + + int x = FROMx; + location.precalculateX(x); + for (int y = FROMy; y < TOy; y++) { + loc = y * image_size + x; + + image_iterations[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithY(y)); + escaped[loc] = escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(f_val, escaped_val); + + if(storeExtraData) { + pixelData[loc].set(0, color, f_val, escaped_val, totalSamples); + } + + aa.initialize(color); + + //Supersampling + for (int i = 0; i < supersampling_num; i++) { + temp_result = iteration_algorithm.calculate(location.getAntialiasingComplex(i, loc)); + escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(temp_result, escaped_val); + + if(storeExtraData) { + pixelData[loc].set(i + 1, color, temp_result, escaped_val, totalSamples); + } + + if(!aa.addSample(color)) { + break; + } + } + + rgbs[loc] = aa.getColor(); + + drawing_done++; + task_calculated++; + task_completed++; + } + + if (TOx == image_size) { + x = TOx - 1; + location.precalculateX(x); + for (int y = FROMy + 1; y < TOy; y++) { + loc = y * image_size + x; + + image_iterations[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithY(y)); + escaped[loc] = escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(f_val, escaped_val); + + if(storeExtraData) { + pixelData[loc].set(0, color, f_val, escaped_val, totalSamples); + } + + aa.initialize(color); + + //Supersampling + for (int i = 0; i < supersampling_num; i++) { + temp_result = iteration_algorithm.calculate(location.getAntialiasingComplex(i, loc)); + escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(temp_result, escaped_val); + + if(storeExtraData) { + pixelData[loc].set(i + 1, color, temp_result, escaped_val, totalSamples); + } + + if(!aa.addSample(color)) { + break; + } + } + + rgbs[loc] = aa.getColor(); + + drawing_done++; + task_calculated++; + task_completed++; + + } + } + + int y = FROMy; + location.precalculateY(y); + for (x = FROMx + 1, loc = y * image_size + x; x < TOx; x++, loc++) { + + image_iterations[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithX(x)); + escaped[loc] = escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(f_val, escaped_val); + + if(storeExtraData) { + pixelData[loc].set(0, color, f_val, escaped_val, totalSamples); + } + + aa.initialize(color); + + //Supersampling + for (int i = 0; i < supersampling_num; i++) { + temp_result = iteration_algorithm.calculate(location.getAntialiasingComplex(i, loc)); + escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(temp_result, escaped_val); + + if(storeExtraData) { + pixelData[loc].set(i + 1, color, temp_result, escaped_val, totalSamples); + } + + if(!aa.addSample(color)) { + break; + } + } + + rgbs[loc] = aa.getColor(); + + drawing_done++; + task_calculated++; + task_completed++; + } + + if (TOy == image_size) { + y = TOy - 1; + + int xLimit = TOx; + + if (TOx == image_size) { + xLimit--; + } + + location.precalculateY(y); + + for (x = FROMx + 1, loc = y * image_size + x; x < xLimit; x++, loc++) { + image_iterations[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithX(x)); + escaped[loc] = escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(f_val, escaped_val); + + if(storeExtraData) { + pixelData[loc].set(0, color, f_val, escaped_val, totalSamples); + } + + aa.initialize(color); + + //Supersampling + for (int i = 0; i < supersampling_num; i++) { + temp_result = iteration_algorithm.calculate(location.getAntialiasingComplex(i, loc)); + escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(temp_result, escaped_val); + + if(storeExtraData) { + pixelData[loc].set(i + 1, color, temp_result, escaped_val, totalSamples); + } + + if(!aa.addSample(color)) { + break; + } + } + + rgbs[loc] = aa.getColor(); + + drawing_done++; + task_calculated++; + task_completed++; + } + } + + if (drawing_done / pixel_percent >= 1) { + update(drawing_done); + drawing_done = 0; + } + + ExpandingQueueSquare squares = new ExpandingQueueSquare(RENDER_USING_DFS ? INIT_QUEUE_SIZE : INIT_QUEUE_SIZE2); + + Square square = new Square(FROMx, FROMy, TOx, TOy, randomNumber); + + squares.enqueue(square); + + try { + initialize_jobs_sync.await(); + } catch (InterruptedException ex) { + + } catch (BrokenBarrierException ex) { + + } + + int slice_FROMx; + int slice_FROMy; + int slice_TOx; + int slice_TOy; + + boolean whole_area; + int temp_starting_pixel_color; + double temp_starting_value; + boolean temp_starting_escaped; + PixelExtraData temp_starting_pixel_extra_data = null; + + int skippedColor; + + do { + + Square currentSquare = null; + + if (squares.isEmpty()) { + break; + } + + if(RENDER_USING_DFS) { + currentSquare = squares.last(); + } + else { + currentSquare = squares.dequeue(); + } + + whole_area = true; + + slice_FROMx = currentSquare.x1; + slice_FROMy = currentSquare.y1; + slice_TOx = currentSquare.x2; + slice_TOy = currentSquare.y2; + + if (slice_TOy == image_size) { + slice_TOy--; + } + + if (slice_TOx == image_size) { + slice_TOx--; + } + + y = slice_FROMy; + x = slice_FROMx; + + loc = y * image_size + x; + + temp_starting_value = image_iterations[loc]; + temp_starting_pixel_color = rgbs[loc]; + temp_starting_escaped = escaped[loc]; + if(storeExtraData) { + temp_starting_pixel_extra_data = pixelData[loc]; + } + + int loc2; + for (loc = slice_FROMy * image_size + x, loc2 = slice_TOy * image_size + x; x <= slice_TOx; x++, loc++, loc2++) { + if (isNotTheSame(loc, temp_starting_pixel_color, temp_starting_value) || isNotTheSame(loc2, temp_starting_pixel_color, temp_starting_value)) { + whole_area = false; + break; + } + } + + if (whole_area) { + for (y = slice_FROMy + 1, loc = y * image_size + slice_FROMx, loc2 = y * image_size + slice_TOx; y <= slice_TOy - 1; y++, loc += image_size, loc2 += image_size) { + if (isNotTheSame(loc, temp_starting_pixel_color, temp_starting_value) || isNotTheSame(loc2, temp_starting_pixel_color, temp_starting_value)) { + whole_area = false; + break; + } + } + } + + if (!whole_area) { + + int xLength = slice_TOx - slice_FROMx + 1; + int yLength = slice_TOy - slice_FROMy + 1; + + if (canSubDivide(xLength, yLength)) { + + if(getSplitMode(currentSquare.iteration - randomNumber) == 1) { + int halfY = slice_FROMy + (yLength >>> 1); + y = halfY; + location.precalculateY(y); + for (x = slice_FROMx + 1, loc = y * image_size + x; x < slice_TOx; x++, loc++) { + + image_iterations[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithX(x)); + escaped[loc] = escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(f_val, escaped_val); + + if(storeExtraData) { + pixelData[loc].set(0, color, f_val, escaped_val, totalSamples); + } + + aa.initialize(color); + + //Supersampling + for (int i = 0; i < supersampling_num; i++) { + temp_result = iteration_algorithm.calculate(location.getAntialiasingComplex(i, loc)); + escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(temp_result, escaped_val); + + if(storeExtraData) { + pixelData[loc].set(i + 1, color, temp_result, escaped_val, totalSamples); + } + + if(!aa.addSample(color)) { + break; + } + } + + rgbs[loc] = aa.getColor(); + + drawing_done++; + task_calculated++; + task_completed++; + } + + Square square1 = new Square(slice_FROMx, slice_FROMy, slice_TOx, halfY, currentSquare.iteration + 1); + + squares.enqueue(square1); + + Square square3 = new Square(slice_FROMx, halfY, slice_TOx, slice_TOy, currentSquare.iteration + 1); + + squares.enqueue(square3); + } + else { + int halfX = slice_FROMx + (xLength >>> 1); + x = halfX; + location.precalculateX(x); + for (y = slice_FROMy + 1; y < slice_TOy; y++) { + loc = y * image_size + x; + + image_iterations[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithY(y)); + escaped[loc] = escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(f_val, escaped_val); + + if(storeExtraData) { + pixelData[loc].set(0, color, f_val, escaped_val, totalSamples); + } + + aa.initialize(color); + + //Supersampling + for (int i = 0; i < supersampling_num; i++) { + temp_result = iteration_algorithm.calculate(location.getAntialiasingComplex(i, loc)); + escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(temp_result, escaped_val); + + if(storeExtraData) { + pixelData[loc].set(i + 1, color, temp_result, escaped_val, totalSamples); + } + + if(!aa.addSample(color)) { + break; + } + } + + rgbs[loc] = aa.getColor(); + + drawing_done++; + task_calculated++; + task_completed++; + + } + + Square square2 = new Square(slice_FROMx, slice_FROMy, halfX, slice_TOy, currentSquare.iteration + 1); + + squares.enqueue(square2); + + Square square4 = new Square(halfX, slice_FROMy, slice_TOx, slice_TOy, currentSquare.iteration + 1); + + squares.enqueue(square4); + } + } else { + //calculate the rest with the normal way + for (y = slice_FROMy + 1; y < slice_TOy; y++) { + for (x = slice_FROMx + 1, loc = y * image_size + x; x < slice_TOx; x++, loc++) { + + image_iterations[loc] = f_val = iteration_algorithm.calculate(location.getComplex(x, y)); + escaped[loc] = escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(f_val, escaped_val); + + if(storeExtraData) { + pixelData[loc].set(0, color, f_val, escaped_val, totalSamples); + } + + aa.initialize(color); + + //Supersampling + for (int i = 0; i < supersampling_num; i++) { + temp_result = iteration_algorithm.calculate(location.getAntialiasingComplex(i, loc)); + escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(temp_result, escaped_val); + + if(storeExtraData) { + pixelData[loc].set(i + 1, color, temp_result, escaped_val, totalSamples); + } + + if(!aa.addSample(color)) { + break; + } + } + + rgbs[loc] = aa.getColor(); + + drawing_done++; + task_calculated++; + task_completed++; + } + } + + if (drawing_done / pixel_percent >= 1) { + update(drawing_done); + drawing_done = 0; + } + } + } else { + y = slice_FROMy + 1; + x = slice_FROMx + 1; + + int chunk = slice_TOx - x; + + skippedColor = getColorForSkippedPixels(temp_starting_pixel_color, currentSquare.iteration); + + for (int k = y; k < slice_TOy; k++) { + int temploc = k * image_size; + int loc3 = temploc + x; + int loc4 = temploc + slice_TOx; + + for (int index = loc3; index < loc4; index++) { + image_iterations[index] = temp_starting_value; + rgbs[index] = skippedColor; + escaped[index] = temp_starting_escaped; + if(storeExtraData) { + pixelData[index] = new PixelExtraData(temp_starting_pixel_extra_data, skippedColor); + } + task_completed++; + } + + drawing_done += chunk; + } + + if (drawing_done / pixel_percent >= 1) { + update(drawing_done); + drawing_done = 0; + } + + } + + } while (true); + + if (SKIPPED_PIXELS_ALG == 4) { + drawSquares(image_size); + } + + pixel_calculation_time_per_task = System.currentTimeMillis() - time; + + postProcess(image_size, aa, location); + } + + @Override + protected void drawFastJulia(int image_size, boolean polar) { + + Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (PERTURBATION_THEORY || HIGH_PRECISION_CALCULATION) && fractal.supportsPerturbationTheory()); + + if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { + + if (reference_calc_sync.getAndIncrement() == 0) { + calculateReferenceFastJulia(location); + } + + try { + reference_sync.await(); + } catch (InterruptedException ex) { + + } catch (BrokenBarrierException ex) { + + } + + location.setReference(Fractal.refPoint); + } + + int loc; + + boolean escaped_val; + double f_val; + + int x = FROMx; + location.precalculateX(x); + for (int y = FROMy; y < TOy; y++) { + loc = y * image_size + x; + image_iterations_fast_julia[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithY(y)); + escaped_fast_julia[loc] = escaped_val = iteration_algorithm.escaped(); + rgbs[loc] = getFinalColor(f_val, escaped_val); + } + + if (TOx == image_size) { + x = TOx - 1; + location.precalculateX(x); + for (int y = FROMy + 1; y < TOy; y++) { + loc = y * image_size + x; + image_iterations_fast_julia[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithY(y)); + escaped_fast_julia[loc] = escaped_val = iteration_algorithm.escaped(); + rgbs[loc] = getFinalColor(f_val, escaped_val); + } + } + + int y = FROMy; + location.precalculateY(y); + for (x = FROMx + 1, loc = y * image_size + x; x < TOx; x++, loc++) { + image_iterations_fast_julia[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithX(x)); + escaped_fast_julia[loc] = escaped_val = iteration_algorithm.escaped(); + rgbs[loc] = getFinalColor(f_val, escaped_val); + } + + if (TOy == image_size) { + y = TOy - 1; + + int xLimit = TOx; + + if (TOx == image_size) { + xLimit--; + } + + location.precalculateY(y); + for (x = FROMx + 1, loc = y * image_size + x; x < xLimit; x++, loc++) { + image_iterations_fast_julia[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithX(x)); + escaped_fast_julia[loc] = escaped_val = iteration_algorithm.escaped(); + rgbs[loc] = getFinalColor(f_val, escaped_val); + } + } + + ExpandingQueueSquare squares = new ExpandingQueueSquare(RENDER_USING_DFS ? INIT_QUEUE_SIZE : INIT_QUEUE_SIZE2); + + Square square = new Square(FROMx, FROMy, TOx, TOy, randomNumber); + + squares.enqueue(square); + + try { + initialize_jobs_sync.await(); + } catch (InterruptedException ex) { + + } catch (BrokenBarrierException ex) { + + } + + int slice_FROMx; + int slice_FROMy; + int slice_TOx; + int slice_TOy; + + boolean whole_area; + int temp_starting_pixel_color; + double temp_starting_value; + boolean temp_starting_escaped; + + int skippedColor; + + do { + + Square currentSquare = null; + + if (squares.isEmpty()) { + break; + } + + if(RENDER_USING_DFS) { + currentSquare = squares.last(); + } + else { + currentSquare = squares.dequeue(); + } + + whole_area = true; + + slice_FROMx = currentSquare.x1; + slice_FROMy = currentSquare.y1; + slice_TOx = currentSquare.x2; + slice_TOy = currentSquare.y2; + + if (slice_TOy == image_size) { + slice_TOy--; + } + + if (slice_TOx == image_size) { + slice_TOx--; + } + + y = slice_FROMy; + x = slice_FROMx; + + loc = y * image_size + x; + + temp_starting_value = image_iterations_fast_julia[loc]; + temp_starting_pixel_color = rgbs[loc]; + temp_starting_escaped = escaped_fast_julia[loc]; + + int loc2; + for (loc = slice_FROMy * image_size + x, loc2 = slice_TOy * image_size + x; x <= slice_TOx; x++, loc++, loc2++) { + if (isNotTheSameFastJulia(loc, temp_starting_pixel_color, temp_starting_value) || isNotTheSameFastJulia(loc2, temp_starting_pixel_color, temp_starting_value)) { + whole_area = false; + break; + } + } + + if (whole_area) { + for (y = slice_FROMy + 1, loc = y * image_size + slice_FROMx, loc2 = y * image_size + slice_TOx; y <= slice_TOy - 1; y++, loc += image_size, loc2 += image_size) { + if (isNotTheSameFastJulia(loc, temp_starting_pixel_color, temp_starting_value) || isNotTheSameFastJulia(loc2, temp_starting_pixel_color, temp_starting_value)) { + whole_area = false; + break; + } + } + } + + if (!whole_area) { + + int xLength = slice_TOx - slice_FROMx + 1; + int yLength = slice_TOy - slice_FROMy + 1; + + if (canSubDivide(xLength, yLength)) { + + if(getSplitMode(currentSquare.iteration - randomNumber) == 1) { + int halfY = slice_FROMy + (yLength >>> 1); + y = halfY; + location.precalculateY(y); + for (x = slice_FROMx + 1, loc = y * image_size + x; x < slice_TOx; x++, loc++) { + image_iterations_fast_julia[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithX(x)); + escaped_fast_julia[loc] = escaped_val = iteration_algorithm.escaped(); + rgbs[loc] = getFinalColor(f_val, escaped_val); + } + + Square square1 = new Square(slice_FROMx, slice_FROMy, slice_TOx, halfY, currentSquare.iteration + 1); + + squares.enqueue(square1); + + Square square3 = new Square(slice_FROMx, halfY, slice_TOx, slice_TOy, currentSquare.iteration + 1); + + squares.enqueue(square3); + } + else { + int halfX = slice_FROMx + (xLength >>> 1); + x = halfX; + location.precalculateX(x); + for (y = slice_FROMy + 1; y < slice_TOy; y++) { + loc = y * image_size + x; + image_iterations_fast_julia[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithY(y)); + escaped_fast_julia[loc] = escaped_val = iteration_algorithm.escaped(); + rgbs[loc] = getFinalColor(f_val, escaped_val); + } + + Square square2 = new Square(slice_FROMx, slice_FROMy, halfX, slice_TOy, currentSquare.iteration + 1); + + squares.enqueue(square2); + + Square square4 = new Square(halfX, slice_FROMy, slice_TOx, slice_TOy, currentSquare.iteration + 1); + + squares.enqueue(square4); + } + } else { + //calculate the rest with the normal way + for (y = slice_FROMy + 1; y < slice_TOy; y++) { + for (x = slice_FROMx + 1, loc = y * image_size + x; x < slice_TOx; x++, loc++) { + image_iterations_fast_julia[loc] = f_val = iteration_algorithm.calculate(location.getComplex(x, y)); + escaped_fast_julia[loc] = escaped_val = iteration_algorithm.escaped(); + rgbs[loc] = getFinalColor(f_val, escaped_val); + } + } + } + + } else { + y = slice_FROMy + 1; + x = slice_FROMx + 1; + + skippedColor = getColorForSkippedPixels(temp_starting_pixel_color, currentSquare.iteration); + + for (int k = y; k < slice_TOy; k++) { + int temploc = k * image_size; + int loc3 = temploc + x; + int loc4 = temploc + slice_TOx; + + for (int index = loc3; index < loc4; index++) { + image_iterations_fast_julia[index] = temp_starting_value; + rgbs[index] = skippedColor; + escaped_fast_julia[index] = temp_starting_escaped; + } + } + } + + } while (true); + + if (SKIPPED_PIXELS_ALG == 4) { + drawSquares(image_size); + } + + postProcessFastJulia(image_size, null, location); + + } + + @Override + protected void drawFastJuliaAntialiased(int image_size, boolean polar) { + + int aaMethod = (filters_options_vals[MainWindow.ANTIALIASING] % 100) / 10; + boolean useJitter = aaMethod != 6 && ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x4) == 4; + Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (PERTURBATION_THEORY || HIGH_PRECISION_CALCULATION) && fractal.supportsPerturbationTheory()); + int aaSamplesIndex = (filters_options_vals[MainWindow.ANTIALIASING] % 100) % 10; + int supersampling_num = getExtraSamples(aaSamplesIndex, aaMethod); + location.createAntialiasingSteps(aaMethod == 5, useJitter, supersampling_num); + + if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { + + if (reference_calc_sync.getAndIncrement() == 0) { + calculateReferenceFastJulia(location); + } + + try { + reference_sync.await(); + } catch (InterruptedException ex) { + + } catch (BrokenBarrierException ex) { + + } + + location.setReference(Fractal.refPoint); + } + + int loc; + + int color; + + double temp_result; + + boolean aaAvgWithMean = ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x1) == 1; + int colorSpace = filters_options_extra_vals[0][MainWindow.ANTIALIASING]; + int totalSamples = supersampling_num + 1; + + AntialiasingAlgorithm aa = AntialiasingAlgorithm.getAntialiasingAlgorithm(totalSamples, aaMethod, aaAvgWithMean, colorSpace, fs.aaSigmaR, fs.aaSigmaS); + + boolean escaped_val; + double f_val; + + boolean storeExtraData = pixelData_fast_julia != null; + + aa.setNeedsPostProcessing(needsPostProcessing()); + + int x = FROMx; + location.precalculateX(x); + for (int y = FROMy; y < TOy; y++) { + loc = y * image_size + x; + image_iterations_fast_julia[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithY(y)); + escaped_fast_julia[loc] = escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(f_val, escaped_val); + + if(storeExtraData) { + pixelData_fast_julia[loc].set(0, color, f_val, escaped_val, totalSamples); + } + + aa.initialize(color); + + //Supersampling + for (int i = 0; i < supersampling_num; i++) { + temp_result = iteration_algorithm.calculate(location.getAntialiasingComplex(i, loc)); + escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(temp_result, escaped_val); + + if(storeExtraData) { + pixelData_fast_julia[loc].set(i + 1, color, temp_result, escaped_val, totalSamples); + } + + if(!aa.addSample(color)) { + break; + } + } + + rgbs[loc] = aa.getColor(); + } + + if (TOx == image_size) { + x = TOx - 1; + location.precalculateX(x); + for (int y = FROMy + 1; y < TOy; y++) { + loc = y * image_size + x; + + image_iterations_fast_julia[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithY(y)); + escaped_fast_julia[loc] = escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(f_val, escaped_val); + + if(storeExtraData) { + pixelData_fast_julia[loc].set(0, color, f_val, escaped_val, totalSamples); + } + + aa.initialize(color); + + //Supersampling + for (int i = 0; i < supersampling_num; i++) { + temp_result = iteration_algorithm.calculate(location.getAntialiasingComplex(i, loc)); + escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(temp_result, escaped_val); + + if(storeExtraData) { + pixelData_fast_julia[loc].set(i + 1, color, temp_result, escaped_val, totalSamples); + } + + if(!aa.addSample(color)) { + break; + } + } + + rgbs[loc] = aa.getColor(); + } + } + + int y = FROMy; + location.precalculateY(y); + for (x = FROMx + 1, loc = y * image_size + x; x < TOx; x++, loc++) { + image_iterations_fast_julia[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithX(x)); + escaped_fast_julia[loc] = escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(f_val, escaped_val); + + if(storeExtraData) { + pixelData_fast_julia[loc].set(0, color, f_val, escaped_val, totalSamples); + } + + aa.initialize(color); + + //Supersampling + for (int i = 0; i < supersampling_num; i++) { + temp_result = iteration_algorithm.calculate(location.getAntialiasingComplex(i, loc)); + escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(temp_result, escaped_val); + + if(storeExtraData) { + pixelData_fast_julia[loc].set(i + 1, color, temp_result, escaped_val, totalSamples); + } + + if(!aa.addSample(color)) { + break; + } + } + + rgbs[loc] = aa.getColor(); + } + + if (TOy == image_size) { + y = TOy - 1; + + int xLimit = TOx; + + if (TOx == image_size) { + xLimit--; + } + + location.precalculateY(y); + for (x = FROMx + 1, loc = y * image_size + x; x < xLimit; x++, loc++) { + image_iterations_fast_julia[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithX(x)); + escaped_fast_julia[loc] = escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(f_val, escaped_val); + + if(storeExtraData) { + pixelData_fast_julia[loc].set(0, color, f_val, escaped_val, totalSamples); + } + + aa.initialize(color); + + //Supersampling + for (int i = 0; i < supersampling_num; i++) { + temp_result = iteration_algorithm.calculate(location.getAntialiasingComplex(i, loc)); + escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(temp_result, escaped_val); + + if(storeExtraData) { + pixelData_fast_julia[loc].set(i + 1, color, temp_result, escaped_val, totalSamples); + } + + if(!aa.addSample(color)) { + break; + } + } + + rgbs[loc] = aa.getColor(); + } + } + + ExpandingQueueSquare squares = new ExpandingQueueSquare(RENDER_USING_DFS ? INIT_QUEUE_SIZE : INIT_QUEUE_SIZE2); + + Square square = new Square(FROMx, FROMy, TOx, TOy, randomNumber); + + squares.enqueue(square); + + try { + initialize_jobs_sync.await(); + } catch (InterruptedException ex) { + + } catch (BrokenBarrierException ex) { + + } + + int slice_FROMx; + int slice_FROMy; + int slice_TOx; + int slice_TOy; + + boolean whole_area; + int temp_starting_pixel_color; + double temp_starting_value; + boolean temp_starting_escaped; + PixelExtraData temp_starting_pixel_extra_data = null; + + int skippedColor; + + do { + + Square currentSquare = null; + + if (squares.isEmpty()) { + break; + } + + if(RENDER_USING_DFS) { + currentSquare = squares.last(); + } + else { + currentSquare = squares.dequeue(); + } + + whole_area = true; + + slice_FROMx = currentSquare.x1; + slice_FROMy = currentSquare.y1; + slice_TOx = currentSquare.x2; + slice_TOy = currentSquare.y2; + + if (slice_TOy == image_size) { + slice_TOy--; + } + + if (slice_TOx == image_size) { + slice_TOx--; + } + + y = slice_FROMy; + x = slice_FROMx; + + loc = y * image_size + x; + + temp_starting_value = image_iterations_fast_julia[loc]; + temp_starting_pixel_color = rgbs[loc]; + temp_starting_escaped = escaped_fast_julia[loc]; + if(storeExtraData) { + temp_starting_pixel_extra_data = pixelData_fast_julia[loc]; + } + + int loc2; + for (loc = slice_FROMy * image_size + x, loc2 = slice_TOy * image_size + x; x <= slice_TOx; x++, loc++, loc2++) { + if (isNotTheSameFastJulia(loc, temp_starting_pixel_color, temp_starting_value) || isNotTheSameFastJulia(loc2, temp_starting_pixel_color, temp_starting_value)) { + whole_area = false; + break; + } + } + + if (whole_area) { + for (y = slice_FROMy + 1, loc = y * image_size + slice_FROMx, loc2 = y * image_size + slice_TOx; y <= slice_TOy - 1; y++, loc += image_size, loc2 += image_size) { + if (isNotTheSameFastJulia(loc, temp_starting_pixel_color, temp_starting_value) || isNotTheSameFastJulia(loc2, temp_starting_pixel_color, temp_starting_value)) { + whole_area = false; + break; + } + } + } + + if (!whole_area) { + + int xLength = slice_TOx - slice_FROMx + 1; + int yLength = slice_TOy - slice_FROMy + 1; + + if (canSubDivide(xLength, yLength)) { + + if(getSplitMode(currentSquare.iteration - randomNumber) == 1) { + int halfY = slice_FROMy + (yLength >>> 1); + y = halfY; + location.precalculateY(y); + for (x = slice_FROMx + 1, loc = y * image_size + x; x < slice_TOx; x++, loc++) { + + image_iterations_fast_julia[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithX(x)); + escaped_fast_julia[loc] = escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(f_val, escaped_val); + + if(storeExtraData) { + pixelData_fast_julia[loc].set(0, color, f_val, escaped_val, totalSamples); + } + + aa.initialize(color); + + //Supersampling + for (int i = 0; i < supersampling_num; i++) { + temp_result = iteration_algorithm.calculate(location.getAntialiasingComplex(i, loc)); + escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(temp_result, escaped_val); + + if(storeExtraData) { + pixelData_fast_julia[loc].set(i + 1, color, temp_result, escaped_val, totalSamples); + } + + if(!aa.addSample(color)) { + break; + } + } + + rgbs[loc] = aa.getColor(); + } + + Square square1 = new Square(slice_FROMx, slice_FROMy, slice_TOx, halfY, currentSquare.iteration + 1); + + squares.enqueue(square1); + + Square square3 = new Square(slice_FROMx, halfY, slice_TOx, slice_TOy, currentSquare.iteration + 1); + + squares.enqueue(square3); + } + else { + int halfX = slice_FROMx + (xLength >>> 1); + x = halfX; + location.precalculateX(x); + for (y = slice_FROMy + 1; y < slice_TOy; y++) { + + loc = y * image_size + x; + + image_iterations_fast_julia[loc] = f_val = iteration_algorithm.calculate(location.getComplexWithY(y)); + escaped_fast_julia[loc] = escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(f_val, escaped_val); + + if(storeExtraData) { + pixelData_fast_julia[loc].set(0, color, f_val, escaped_val, totalSamples); + } + + aa.initialize(color); + + //Supersampling + for (int i = 0; i < supersampling_num; i++) { + temp_result = iteration_algorithm.calculate(location.getAntialiasingComplex(i, loc)); + escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(temp_result, escaped_val); + + if (storeExtraData) { + pixelData_fast_julia[loc].set(i + 1, color, temp_result, escaped_val, totalSamples); + } + + if (!aa.addSample(color)) { + break; + } + } + + rgbs[loc] = aa.getColor(); + } + + Square square2 = new Square(slice_FROMx, slice_FROMy, halfX, slice_TOy, currentSquare.iteration + 1); + + squares.enqueue(square2); + + Square square4 = new Square(halfX, slice_FROMy, slice_TOx, slice_TOy, currentSquare.iteration + 1); + + squares.enqueue(square4); + } + } else { + //calculate the rest with the normal way + for (y = slice_FROMy + 1; y < slice_TOy; y++) { + for (x = slice_FROMx + 1, loc = y * image_size + x; x < slice_TOx; x++, loc++) { + image_iterations_fast_julia[loc] = f_val = iteration_algorithm.calculate(location.getComplex(x, y)); + escaped_fast_julia[loc] = escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(f_val, escaped_val); + + if(storeExtraData) { + pixelData_fast_julia[loc].set(0, color, f_val, escaped_val, totalSamples); + } + + aa.initialize(color); + + //Supersampling + for (int i = 0; i < supersampling_num; i++) { + temp_result = iteration_algorithm.calculate(location.getAntialiasingComplex(i, loc)); + escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(temp_result, escaped_val); + + if(storeExtraData) { + pixelData_fast_julia[loc].set(i + 1, color, temp_result, escaped_val, totalSamples); + } + + if(!aa.addSample(color)) { + break; + } + } + + rgbs[loc] = aa.getColor(); + } + } + } + + } else { + y = slice_FROMy + 1; + x = slice_FROMx + 1; + + skippedColor = getColorForSkippedPixels(temp_starting_pixel_color, currentSquare.iteration); + + for (int k = y; k < slice_TOy; k++) { + int temploc = k * image_size; + int loc3 = temploc + x; + int loc4 = temploc + slice_TOx; + + for (int index = loc3; index < loc4; index++) { + image_iterations_fast_julia[index] = temp_starting_value; + rgbs[index] = skippedColor; + escaped_fast_julia[index] = temp_starting_escaped; + if(storeExtraData) { + pixelData_fast_julia[index] = new PixelExtraData(temp_starting_pixel_extra_data, skippedColor); + } + } + + } + } + + } while (true); + + if (SKIPPED_PIXELS_ALG == 4) { + drawSquares(image_size); + } + + postProcessFastJulia(image_size, aa, location); + + } + +} diff --git a/src/fractalzoomer/core/drawing_algorithms/MarianiSilverColorsAndIterationDataDraw.java b/src/fractalzoomer/core/drawing_algorithms/MarianiSilverColorsAndIterationDataDraw.java index f1471fb2a..7ded4a339 100644 --- a/src/fractalzoomer/core/drawing_algorithms/MarianiSilverColorsAndIterationDataDraw.java +++ b/src/fractalzoomer/core/drawing_algorithms/MarianiSilverColorsAndIterationDataDraw.java @@ -54,10 +54,12 @@ public MarianiSilverColorsAndIterationDataDraw(int FROMx, int TOx, int FROMy, in super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, fast_julia_filters, image, periodicity_checking, fs, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); } + @Override protected boolean isNotTheSame(int loc, int pixel_color, double pixel_value) { return rgbs[loc] != pixel_color || image_iterations[loc] != pixel_value; } + @Override protected boolean isNotTheSameFastJulia(int loc, int pixel_color, double pixel_value) { return rgbs[loc] != pixel_color || image_iterations_fast_julia[loc] != pixel_value; } diff --git a/src/fractalzoomer/core/drawing_algorithms/MarianiSilverDraw.java b/src/fractalzoomer/core/drawing_algorithms/MarianiSilverDraw.java index 9966dd090..52e516444 100644 --- a/src/fractalzoomer/core/drawing_algorithms/MarianiSilverDraw.java +++ b/src/fractalzoomer/core/drawing_algorithms/MarianiSilverDraw.java @@ -77,21 +77,7 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (PERTURBATION_THEORY || HIGH_PRECISION_CALCULATION) && fractal.supportsPerturbationTheory()); - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - - location.setReference(Fractal.refPoint); - } + initialize(location); int pixel_percent = (image_size * image_size) / 100; @@ -352,11 +338,17 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi int temploc = k * image_size; int loc3 = temploc + x; int loc4 = temploc + slice_TOx; - Arrays.fill(rgbs, loc3, loc4, skippedColor); - Arrays.fill(image_iterations, loc3, loc4, temp_starting_value); - Arrays.fill(escaped, loc3, loc4, temp_starting_escaped); + + for (int index = loc3; index < loc4; index++) { + if (rgbs[index] >>> 24 != Constants.NORMAL_ALPHA) { + image_iterations[index] = temp_starting_value; + rgbs[index] = skippedColor; + escaped[index] = temp_starting_escaped; + task_completed++; + } + } + drawing_done += chunk; - task_completed += chunk; } if (drawing_done / pixel_percent >= 1) { @@ -383,7 +375,7 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi postProcess(image_size, null, location); } - private boolean canSubDivide(int xLength, int yLength) { + protected boolean canSubDivide(int xLength, int yLength) { if(usesSquareChunks) { return xLength >= MAX_TILE_SIZE && yLength >= MAX_TILE_SIZE; } @@ -402,20 +394,7 @@ protected void drawIterationsAntialiased(int image_size, boolean polar) throws S int supersampling_num = getExtraSamples(aaSamplesIndex, aaMethod); location.createAntialiasingSteps(aaMethod == 5, useJitter, supersampling_num); - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); int pixel_percent = (image_size * image_size) / 100; @@ -843,16 +822,18 @@ protected void drawIterationsAntialiased(int image_size, boolean polar) throws S int temploc = k * image_size; int loc3 = temploc + x; int loc4 = temploc + slice_TOx; - Arrays.fill(rgbs, loc3, loc4, skippedColor); - Arrays.fill(image_iterations, loc3, loc4, temp_starting_value); - Arrays.fill(escaped, loc3, loc4, temp_starting_escaped); - if(storeExtraData) { - for(int n = loc3; n < loc4; n++) { - pixelData[n] = new PixelExtraData(temp_starting_pixel_extra_data, skippedColor); + + for (int index = loc3; index < loc4; index++) { + image_iterations[index] = temp_starting_value; + rgbs[index] = skippedColor; + escaped[index] = temp_starting_escaped; + if(storeExtraData) { + pixelData[index] = new PixelExtraData(temp_starting_pixel_extra_data, skippedColor); } + task_completed++; } + drawing_done += chunk; - task_completed += chunk; } if (drawing_done / pixel_percent >= 1) { @@ -1091,9 +1072,12 @@ protected void drawFastJulia(int image_size, boolean polar) { int temploc = k * image_size; int loc3 = temploc + x; int loc4 = temploc + slice_TOx; - Arrays.fill(rgbs, loc3, loc4, skippedColor); - Arrays.fill(image_iterations_fast_julia, loc3, loc4, temp_starting_value); - Arrays.fill(escaped_fast_julia, loc3, loc4, temp_starting_escaped); + + for (int index = loc3; index < loc4; index++) { + image_iterations_fast_julia[index] = temp_starting_value; + rgbs[index] = skippedColor; + escaped_fast_julia[index] = temp_starting_escaped; + } } } @@ -1512,12 +1496,13 @@ protected void drawFastJuliaAntialiased(int image_size, boolean polar) { int temploc = k * image_size; int loc3 = temploc + x; int loc4 = temploc + slice_TOx; - Arrays.fill(rgbs, loc3, loc4, skippedColor); - Arrays.fill(image_iterations_fast_julia, loc3, loc4, temp_starting_value); - Arrays.fill(escaped_fast_julia, loc3, loc4, temp_starting_escaped); - if(storeExtraData) { - for(int n = loc3; n < loc4; n++) { - pixelData_fast_julia[n] = new PixelExtraData(temp_starting_pixel_extra_data, skippedColor); + + for (int index = loc3; index < loc4; index++) { + image_iterations_fast_julia[index] = temp_starting_value; + rgbs[index] = skippedColor; + escaped_fast_julia[index] = temp_starting_escaped; + if(storeExtraData) { + pixelData_fast_julia[index] = new PixelExtraData(temp_starting_pixel_extra_data, skippedColor); } } } diff --git a/src/fractalzoomer/core/drawing_algorithms/SolidGuessingDraw.java b/src/fractalzoomer/core/drawing_algorithms/SolidGuessingDraw.java index 3daf061d2..3e1fa7fd4 100644 --- a/src/fractalzoomer/core/drawing_algorithms/SolidGuessingDraw.java +++ b/src/fractalzoomer/core/drawing_algorithms/SolidGuessingDraw.java @@ -25,20 +25,7 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (PERTURBATION_THEORY || HIGH_PRECISION_CALCULATION) && fractal.supportsPerturbationTheory()); - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); int pixel_percent = (image_size * image_size) / 100; @@ -75,11 +62,18 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi if(currentColor == prevColor) { int skippedColor = getColorForSkippedPixels(currentColor, randomNumber); int temp3 = loc - chunk; - Arrays.fill(image_iterations, temp3, loc, val); - Arrays.fill(rgbs, temp3, loc, skippedColor); - Arrays.fill(escaped, temp3, loc, esc); + + for (int index = temp3; index < loc; index++) { + if (rgbs[index] >>> 24 != Constants.NORMAL_ALPHA) { + image_iterations[index] = val; + rgbs[index] = skippedColor; + escaped[index] = esc; + task_completed++; + } + } + drawing_done += chunk; - task_completed += chunk; + } else { for(int x1 = x - chunk, loc1 = y * image_size + x1 ; x1 < x; x1++, loc1++) { diff --git a/src/fractalzoomer/core/drawing_algorithms/SuccessiveRefinementGuessing2ColorsAndIterationDataDraw.java b/src/fractalzoomer/core/drawing_algorithms/SuccessiveRefinementGuessing2ColorsAndIterationDataDraw.java new file mode 100644 index 000000000..d815a7844 --- /dev/null +++ b/src/fractalzoomer/core/drawing_algorithms/SuccessiveRefinementGuessing2ColorsAndIterationDataDraw.java @@ -0,0 +1,49 @@ +package fractalzoomer.core.drawing_algorithms; + +import fractalzoomer.main.ImageExpanderWindow; +import fractalzoomer.main.MainWindow; +import fractalzoomer.main.app_settings.*; +import org.apfloat.Apfloat; + +import java.awt.*; +import java.awt.image.BufferedImage; + +public class SuccessiveRefinementGuessing2ColorsAndIterationDataDraw extends SuccessiveRefinementGuessing2Draw { + + public SuccessiveRefinementGuessing2ColorsAndIterationDataDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, D3Settings d3s, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, boolean quickDraw, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, d3s, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, quickDraw, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps); + } + + public SuccessiveRefinementGuessing2ColorsAndIterationDataDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, ImageExpanderWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps); + } + + public SuccessiveRefinementGuessing2ColorsAndIterationDataDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, D3Settings d3s, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, boolean quickDraw, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps, Apfloat xJuliaCenter, Apfloat yJuliaCenter) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, d3s, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, quickDraw, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); + } + + public SuccessiveRefinementGuessing2ColorsAndIterationDataDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, ImageExpanderWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps, Apfloat xJuliaCenter, Apfloat yJuliaCenter) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); + } + + public SuccessiveRefinementGuessing2ColorsAndIterationDataDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps); + } + + public SuccessiveRefinementGuessing2ColorsAndIterationDataDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, MainWindow ptr, Color fractal_color, Color dem_color, boolean fast_julia_filters, BufferedImage image, boolean periodicity_checking, FiltersSettings fs, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps, Apfloat xJuliaCenter, Apfloat yJuliaCenter) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, fast_julia_filters, image, periodicity_checking, fs, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); + } + + @Override + protected boolean isTheSame(int loca, int locb, int locc, int locd) { + return rgbs[loca] == rgbs[locb] && rgbs[locb] == rgbs[locc] && rgbs[locc] == rgbs[locd] + && image_iterations[loca] == image_iterations[locb] && image_iterations[locb] == image_iterations[locc] && image_iterations[locc] == image_iterations[locd]; + } + + @Override + protected boolean isTheSameFastJulia(int loca, int locb, int locc, int locd) { + return rgbs[loca] == rgbs[locb] && rgbs[locb] == rgbs[locc] && rgbs[locc] == rgbs[locd] + && image_iterations_fast_julia[loca] == image_iterations_fast_julia[locb] && image_iterations_fast_julia[locb] == image_iterations_fast_julia[locc] && image_iterations_fast_julia[locc] == image_iterations_fast_julia[locd]; + } + +} diff --git a/src/fractalzoomer/core/drawing_algorithms/SuccessiveRefinementGuessing2Draw.java b/src/fractalzoomer/core/drawing_algorithms/SuccessiveRefinementGuessing2Draw.java new file mode 100644 index 000000000..c215cd3e5 --- /dev/null +++ b/src/fractalzoomer/core/drawing_algorithms/SuccessiveRefinementGuessing2Draw.java @@ -0,0 +1,902 @@ +package fractalzoomer.core.drawing_algorithms; + +import fractalzoomer.core.PixelExtraData; +import fractalzoomer.core.TaskDraw; +import fractalzoomer.core.antialiasing.AntialiasingAlgorithm; +import fractalzoomer.core.location.Location; +import fractalzoomer.functions.Fractal; +import fractalzoomer.main.Constants; +import fractalzoomer.main.ImageExpanderWindow; +import fractalzoomer.main.MainWindow; +import fractalzoomer.main.app_settings.*; +import fractalzoomer.utils.StopSuccessiveRefinementException; +import org.apfloat.Apfloat; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.atomic.AtomicInteger; + +public class SuccessiveRefinementGuessing2Draw extends SuccessiveRefinementGuessingDraw { + + public SuccessiveRefinementGuessing2Draw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, D3Settings d3s, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, boolean quickDraw, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, d3s, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, quickDraw, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps); + } + + public SuccessiveRefinementGuessing2Draw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, ImageExpanderWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps); + } + + public SuccessiveRefinementGuessing2Draw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, D3Settings d3s, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, boolean quickDraw, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps, Apfloat xJuliaCenter, Apfloat yJuliaCenter) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, d3s, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, quickDraw, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); + } + + public SuccessiveRefinementGuessing2Draw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, ImageExpanderWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps, Apfloat xJuliaCenter, Apfloat yJuliaCenter) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); + } + + public SuccessiveRefinementGuessing2Draw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps); + } + + public SuccessiveRefinementGuessing2Draw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, MainWindow ptr, Color fractal_color, Color dem_color, boolean fast_julia_filters, BufferedImage image, boolean periodicity_checking, FiltersSettings fs, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, boolean inverse_dem, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps,Apfloat xJuliaCenter, Apfloat yJuliaCenter) { + super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, fast_julia_filters, image, periodicity_checking, fs, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); + } + + public SuccessiveRefinementGuessing2Draw(int FROMx, int TOx, int FROMy, int TOy, int max_iterations, MainWindow ptr, BufferedImage image, Color fractal_color, Color dem_color, int color_cycling_location, int color_cycling_location2, FiltersSettings fs, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, DomainColoringSettings ds, int gradient_offset, double contourFactor, boolean smoothing, GeneratedPaletteSettings gps, PostProcessSettings pps) { + super(FROMx, TOx, FROMy, TOy, max_iterations, ptr, image, fractal_color, dem_color, color_cycling_location, color_cycling_location2, fs, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, ds, gradient_offset, contourFactor, smoothing, gps, pps); + } + + public SuccessiveRefinementGuessing2Draw(int action, int FROMx, int TOx, int FROMy, int TOy, int max_iterations, MainWindow ptr, BufferedImage image, Color fractal_color, Color dem_color, int color_cycling_location, int color_cycling_location2, FiltersSettings fs, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, PostProcessSettings pps, DomainColoringSettings ds) { + super(action, FROMx, TOx, FROMy, TOy, max_iterations, ptr, image, fractal_color, dem_color, color_cycling_location, color_cycling_location2, fs, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, pps, ds); + } + + protected int getAggregateChunk(int current_chunk_size_x, int current_chunk_size_y) { + + if(SQUARE_RECT_CHUNK_AGGERAGATION == 0) { + return TWO_PASS_SUCCESSIVE_REFINEMENT ? Math.max(current_chunk_size_x, current_chunk_size_y) : Math.min(current_chunk_size_x, current_chunk_size_y); + } + else { + return TWO_PASS_SUCCESSIVE_REFINEMENT ? Math.min(current_chunk_size_x, current_chunk_size_y) : Math.max(current_chunk_size_x, current_chunk_size_y); + } + + } + + @Override + protected void drawIterations(int image_size, boolean polar) throws StopSuccessiveRefinementException { + + Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (HIGH_PRECISION_CALCULATION || PERTURBATION_THEORY) && fractal.supportsPerturbationTheory()); + + int pixel_percent = (image_size * image_size) / 100; + + + initialize(location); + + + int color, loc2, loc, x, y; + int tempx, tempy; + + boolean escaped_val; + double f_val; + + int iteration = randomNumber; + + int min_chunk_size = TaskDraw.GUESS_BLOCKS_SELECTION == 0 ? 0 : 1 << (TaskDraw.GUESS_BLOCKS_SELECTION - 1); + min_chunk_size = TWO_PASS_SUCCESSIVE_REFINEMENT ? min_chunk_size << 1 : min_chunk_size; + + int current_chunk_size2x = 0; + int current_chunk_size2y = 0; + + int xstart = 0; + int ystart = 0; + int xend = 0; + int yend = 0; + + int loca = 0; + int locb = 0; + int locc = 0; + int locd = 0; + + task_completed = 0; + + long nano_time = 0; + + int current_chunk_size_x = 0; + int current_chunk_size_y = 0; + int prev_chunk_size_x; + int prev_chunk_size_y; + + int stop_id = getStopAfterIter(); + int length = TWO_PASS_SUCCESSIVE_REFINEMENT ? SUCCESSIVE_REFINEMENT_CHUNK_X.length << 1 : SUCCESSIVE_REFINEMENT_CHUNK_X.length; + + for(int id = 0, id2 = 0; id < length; id++) { + long time = System.nanoTime(); + AtomicInteger ai = successive_refinement_drawing_algorithm2_pixel[id]; + + prev_chunk_size_x = current_chunk_size_x; + prev_chunk_size_y = current_chunk_size_y; + current_chunk_size_x = SUCCESSIVE_REFINEMENT_CHUNK_X[id2]; + current_chunk_size_y = SUCCESSIVE_REFINEMENT_CHUNK_Y[id2]; + + int image_size_tile_x = image_size % current_chunk_size_x == 0 ? image_size / current_chunk_size_x : image_size / current_chunk_size_x + 1; + int image_size_tile_y = image_size % current_chunk_size_y == 0 ? image_size / current_chunk_size_y : image_size / current_chunk_size_y + 1; + + int condition = (image_size_tile_x) * (image_size_tile_y); + int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL2[id2]; + boolean performSecondPassActions = !TWO_PASS_SUCCESSIVE_REFINEMENT || (id & 1) == 1; + + do { + + loc = chunk_size * ai.getAndIncrement(); + + if (loc >= condition) { + break; + } + + for (int count = 0; count < chunk_size && loc < condition; count++, loc++) { + tempx = loc % image_size_tile_x; + tempy = loc / image_size_tile_x; + + x = tempx * current_chunk_size_x; + y = tempy * current_chunk_size_y; + + loc2 = y * image_size + x; + + if(!filled[loc2]) { + + int aggregate_chunk = getAggregateChunk(current_chunk_size_x, current_chunk_size_y); + boolean check = performSecondPassActions && aggregate_chunk <= min_chunk_size; + if(check) { + current_chunk_size2x = prev_chunk_size_x; + current_chunk_size2y = prev_chunk_size_y; + + xstart = (x / current_chunk_size2x) * current_chunk_size2x; + ystart = (y / current_chunk_size2y) * current_chunk_size2y; + xend = xstart + current_chunk_size2x; + yend = ystart + current_chunk_size2y; + + loca = ystart * image_size; + locb = loca + xend; + loca += xstart; + + locc = yend * image_size; + locd = locc + xend; + locc += xstart; + } + + if(check && xend < image_size && yend < image_size && isTheSame(loca, locb, locc, locd)) { + + + tempx = Math.min(image_size, x + current_chunk_size_x); + tempy = Math.min(image_size, y + current_chunk_size_y); + + int start_color = rgbs[loca]; + int skippedColor = getColorForSkippedPixels(start_color, iteration); + double start_iterations = image_iterations[loca]; + boolean start_escaped = escaped[loca]; + + for (int i = y; i < tempy; i++) { + for (int j = x, loc3 = i * image_size + j; j < tempx; j++, loc3++) { + if(!examined[loc3]) { + if (rgbs[loc3] >>> 24 != Constants.NORMAL_ALPHA) { + rgbs[loc3] = start_color; + image_iterations[loc3] = start_iterations; + escaped[loc3] = start_escaped; + task_completed++; + } + setFilledAndExaminedWithSkippedColor(examined, filled, skipped_colors, loc3, skippedColor); + drawing_done++; + } + } + } + } + else if (!examined[loc2]){ + if (rgbs[loc2] >>> 24 != Constants.NORMAL_ALPHA) { + image_iterations[loc2] = f_val = iteration_algorithm.calculate(location.getComplex(x, y)); + escaped[loc2] = escaped_val = iteration_algorithm.escaped(); + rgbs[loc2] = color = getFinalColor(f_val, escaped_val); + task_calculated++; + task_completed++; + } else { + color = rgbs[loc2]; + } + + examined[loc2] = true; + drawing_done++; + + tempx = Math.min(image_size, x + current_chunk_size_x); + tempy = Math.min(image_size, y + current_chunk_size_y); + + for (int i = y; i < tempy; i++) { + for (int j = x, loc3 = i * image_size + j; j < tempx; j++, loc3++) { + if (rgbs[loc3] >>> 24 != Constants.NORMAL_ALPHA) { + rgbs[loc3] = (color & 0xFFFFFF) | Constants.QUICKDRAW_CALCULATED_ALPHA_OFFSETED; + } + } + } + } + } + + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { + break; + } + } + + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { + break; + } + + if(drawing_done / pixel_percent >= 1) { + update(drawing_done); + drawing_done = 0; + } + + } while (true); + + + nano_time += System.nanoTime() - time; + + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT) { + try { + successive_refinement_lock.lockRead(); + } catch (InterruptedException ex) { + + } + } + + try { + successive_refinement_drawing_algorithm_barrier.await(); + } catch (InterruptedException ex) { + + } catch (BrokenBarrierException ex) { + + } + + if(taskId == 0 && ptr != null) { + if(id == 0) { + ptr.setWholeImageDone(true); + ptr.reloadTitle(); + updateMode(ptr, false, iteration_algorithm.isJulia(), false, false); + } + ptr.getMainPanel().repaint(); + } + + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT) { + if (id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { + successive_refinement_lock.unlockRead(); + throw new StopSuccessiveRefinementException(); + } + successive_refinement_lock.unlockRead(); + } + + if(performSecondPassActions) { + iteration++; + id2++; + } + } + + if(SKIPPED_PIXELS_ALG != 0) { + applySkippedColor(image_size, false); + } + + if (SKIPPED_PIXELS_ALG == 4) { + drawSquares(image_size); + } + + pixel_calculation_time_per_task = nano_time / 1000000; + + postProcess(image_size, null, location); + + } + + @Override + protected void drawFastJuliaAntialiased(int image_size, boolean polar) { + + int aaMethod = (filters_options_vals[MainWindow.ANTIALIASING] % 100) / 10; + boolean useJitter = aaMethod != 6 && ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x4) == 4; + Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (PERTURBATION_THEORY || HIGH_PRECISION_CALCULATION) && fractal.supportsPerturbationTheory()); + int aaSamplesIndex = (filters_options_vals[MainWindow.ANTIALIASING] % 100) % 10; + int supersampling_num = getExtraSamples(aaSamplesIndex, aaMethod); + location.createAntialiasingSteps(aaMethod == 5, useJitter, supersampling_num); + + initialize(location); + + boolean aaAvgWithMean = ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x1) == 1; + int colorSpace = filters_options_extra_vals[0][MainWindow.ANTIALIASING]; + int totalSamples = supersampling_num + 1; + + AntialiasingAlgorithm aa = AntialiasingAlgorithm.getAntialiasingAlgorithm(totalSamples, aaMethod, aaAvgWithMean, colorSpace, fs.aaSigmaR, fs.aaSigmaS); + + aa.setNeedsPostProcessing(needsPostProcessing()); + + boolean storeExtraData = pixelData_fast_julia != null; + + int color, loc2, loc, x, y; + int tempx, tempy; + + boolean escaped_val; + double f_val; + double temp_result; + + int current_chunk_size_x = 0; + int current_chunk_size_y = 0; + int prev_chunk_size_x; + int prev_chunk_size_y; + int iteration = randomNumber; + int min_chunk_size = TaskDraw.GUESS_BLOCKS_SELECTION == 0 ? 0 : 1 << (TaskDraw.GUESS_BLOCKS_SELECTION - 1); + min_chunk_size = TWO_PASS_SUCCESSIVE_REFINEMENT ? min_chunk_size << 1 : min_chunk_size; + + int current_chunk_size2x = 0; + int current_chunk_size2y = 0; + + int xstart = 0; + int ystart = 0; + int xend = 0; + int yend = 0; + + int loca = 0; + int locb = 0; + int locc = 0; + int locd = 0; + + int length = TWO_PASS_SUCCESSIVE_REFINEMENT ? SUCCESSIVE_REFINEMENT_CHUNK_X.length << 1 : SUCCESSIVE_REFINEMENT_CHUNK_X.length; + + for(int id = 0, id2 = 0; id < length; id++) { + AtomicInteger ai = successive_refinement_drawing_algorithm2_pixel[id]; + + prev_chunk_size_x = current_chunk_size_x; + prev_chunk_size_y = current_chunk_size_y; + current_chunk_size_x = SUCCESSIVE_REFINEMENT_CHUNK_X[id2]; + current_chunk_size_y = SUCCESSIVE_REFINEMENT_CHUNK_Y[id2]; + + int image_size_tile_x = image_size % current_chunk_size_x == 0 ? image_size / current_chunk_size_x : image_size / current_chunk_size_x + 1; + int image_size_tile_y = image_size % current_chunk_size_y == 0 ? image_size / current_chunk_size_y : image_size / current_chunk_size_y + 1; + + int condition = (image_size_tile_x) * (image_size_tile_y); + + int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL2[id2]; + boolean performSecondPassActions = !TWO_PASS_SUCCESSIVE_REFINEMENT || (id & 1) == 1; + + do { + + loc = chunk_size * ai.getAndIncrement(); + + if (loc >= condition) { + break; + } + + for (int count = 0; count < chunk_size && loc < condition; count++, loc++) { + tempx = loc % image_size_tile_x; + tempy = loc / image_size_tile_x; + + x = tempx * current_chunk_size_x; + y = tempy * current_chunk_size_y; + + loc2 = y * image_size + x; + + if(!filled_fast_julia[loc2]) { + + int aggregate_chunk = getAggregateChunk(current_chunk_size_x, current_chunk_size_y); + boolean check = performSecondPassActions && aggregate_chunk <= min_chunk_size; + if(check) { + current_chunk_size2x = prev_chunk_size_x; + current_chunk_size2y = prev_chunk_size_y; + + xstart = (x / current_chunk_size2x) * current_chunk_size2x; + ystart = (y / current_chunk_size2y) * current_chunk_size2y; + xend = xstart + current_chunk_size2x; + yend = ystart + current_chunk_size2y; + + loca = ystart * image_size; + locb = loca + xend; + loca += xstart; + + locc = yend * image_size; + locd = locc + xend; + locc += xstart; + } + + if(check && xend < image_size && yend < image_size && isTheSameFastJulia(loca, locb, locc, locd)) { + + + tempx = Math.min(image_size, x + current_chunk_size_x); + tempy = Math.min(image_size, y + current_chunk_size_y); + + int start_color = rgbs[loca]; + int skippedColor = getColorForSkippedPixels(start_color, iteration); + double start_iterations = image_iterations_fast_julia[loca]; + boolean start_escaped = escaped_fast_julia[loca]; + + PixelExtraData start_extra_data = null; + if(storeExtraData) { + start_extra_data = pixelData_fast_julia[loca]; + } + + for (int i = y; i < tempy; i++) { + for (int j = x, loc3 = i * image_size + j; j < tempx; j++, loc3++) { + if(!examined_fast_julia[loc3]) { + rgbs[loc3] = start_color; + image_iterations_fast_julia[loc3] = start_iterations; + escaped_fast_julia[loc3] = start_escaped; + setFilledAndExaminedWithSkippedColor(examined_fast_julia, filled_fast_julia, skipped_colors_fast_julia, loc3, skippedColor); + if(storeExtraData) { + pixelData_fast_julia[loc3] = new PixelExtraData(start_extra_data, skippedColor); + } + } + } + } + } + else if (!examined_fast_julia[loc2]){ + + image_iterations_fast_julia[loc2] = f_val = iteration_algorithm.calculate(location.getComplex(x, y)); + escaped_fast_julia[loc2] = escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(f_val, escaped_val); + + examined_fast_julia[loc2] = true; + + if(storeExtraData) { + pixelData_fast_julia[loc2].set(0, color, f_val, escaped_val, totalSamples); + } + + aa.initialize(color); + + //Supersampling + for(int i = 0; i < supersampling_num; i++) { + temp_result = iteration_algorithm.calculate(location.getAntialiasingComplex(i, loc2)); + escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(temp_result, escaped_val); + + if(storeExtraData) { + pixelData_fast_julia[loc2].set(i + 1, color, temp_result, escaped_val, totalSamples); + } + + if(!aa.addSample(color)) { + break; + } + } + + rgbs[loc2] = aa.getColor(); + } + } + } + + } while (true); + + try { + successive_refinement_drawing_algorithm_barrier.await(); + } catch (InterruptedException ex) { + + } catch (BrokenBarrierException ex) { + + } + + if(performSecondPassActions) { + iteration++; + id2++; + } + } + + + if(SKIPPED_PIXELS_ALG != 0) { + applySkippedColor(image_size, true); + } + + + if (SKIPPED_PIXELS_ALG == 4) { + drawSquares(image_size); + } + + + postProcessFastJulia(image_size, aa, location); + + } + + @Override + protected void drawIterationsAntialiased(int image_size, boolean polar) throws StopSuccessiveRefinementException { + + int aaMethod = (filters_options_vals[MainWindow.ANTIALIASING] % 100) / 10; + boolean useJitter = aaMethod != 6 && ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x4) == 4; + Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (PERTURBATION_THEORY || HIGH_PRECISION_CALCULATION) && fractal.supportsPerturbationTheory()); + int aaSamplesIndex = (filters_options_vals[MainWindow.ANTIALIASING] % 100) % 10; + int supersampling_num = getExtraSamples(aaSamplesIndex, aaMethod); + location.createAntialiasingSteps(aaMethod == 5, useJitter, supersampling_num); + int pixel_percent = (image_size * image_size) / 100; + + initialize(location); + + boolean aaAvgWithMean = ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x1) == 1; + int colorSpace = filters_options_extra_vals[0][MainWindow.ANTIALIASING]; + int totalSamples = supersampling_num + 1; + + AntialiasingAlgorithm aa = AntialiasingAlgorithm.getAntialiasingAlgorithm(totalSamples, aaMethod, aaAvgWithMean, colorSpace, fs.aaSigmaR, fs.aaSigmaS); + + aa.setNeedsPostProcessing(needsPostProcessing()); + + boolean storeExtraData = pixelData != null; + + int color, loc2, loc, x, y; + int tempx, tempy; + + boolean escaped_val; + double f_val; + double temp_result; + + + int current_chunk_size_x = 0; + int current_chunk_size_y = 0; + int prev_chunk_size_x; + int prev_chunk_size_y; + int iteration = randomNumber; + int min_chunk_size = TaskDraw.GUESS_BLOCKS_SELECTION == 0 ? 0 : 1 << (TaskDraw.GUESS_BLOCKS_SELECTION - 1); + min_chunk_size = TWO_PASS_SUCCESSIVE_REFINEMENT ? min_chunk_size << 1 : min_chunk_size; + + int current_chunk_size2x = 0, current_chunk_size2y = 0; + + int xstart = 0; + int ystart = 0; + int xend = 0; + int yend = 0; + + int loca = 0; + int locb = 0; + int locc = 0; + int locd = 0; + task_completed = 0; + + long nano_time = 0; + + int stop_id = getStopAfterIter(); + int length = TWO_PASS_SUCCESSIVE_REFINEMENT ? SUCCESSIVE_REFINEMENT_CHUNK_X.length << 1 : SUCCESSIVE_REFINEMENT_CHUNK_X.length; + + for(int id = 0, id2 = 0; id < length; id++) { + long time = System.nanoTime(); + AtomicInteger ai = successive_refinement_drawing_algorithm2_pixel[id]; + + prev_chunk_size_x = current_chunk_size_x; + prev_chunk_size_y = current_chunk_size_y; + current_chunk_size_x = SUCCESSIVE_REFINEMENT_CHUNK_X[id2]; + current_chunk_size_y = SUCCESSIVE_REFINEMENT_CHUNK_Y[id2]; + + int image_size_tile_x = image_size % current_chunk_size_x == 0 ? image_size / current_chunk_size_x : image_size / current_chunk_size_x + 1; + int image_size_tile_y = image_size % current_chunk_size_y == 0 ? image_size / current_chunk_size_y : image_size / current_chunk_size_y + 1; + + int condition = (image_size_tile_x) * (image_size_tile_y); + int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL2[id2]; + boolean performSecondPassActions = !TWO_PASS_SUCCESSIVE_REFINEMENT || (id & 1) == 1; + + do { + + loc = chunk_size * ai.getAndIncrement(); + + if (loc >= condition) { + break; + } + + for (int count = 0; count < chunk_size && loc < condition; count++, loc++) { + tempx = loc % image_size_tile_x; + tempy = loc / image_size_tile_x; + + x = tempx * current_chunk_size_x; + y = tempy * current_chunk_size_y; + + loc2 = y * image_size + x; + + if(!filled[loc2]) { + + int aggregate_chunk = getAggregateChunk(current_chunk_size_x, current_chunk_size_y); + boolean check = performSecondPassActions && aggregate_chunk <= min_chunk_size; + if(check) { + current_chunk_size2x = prev_chunk_size_x; + current_chunk_size2y = prev_chunk_size_y; + + xstart = (x / current_chunk_size2x) * current_chunk_size2x; + ystart = (y / current_chunk_size2y) * current_chunk_size2y; + xend = xstart + current_chunk_size2x; + yend = ystart + current_chunk_size2y; + + loca = ystart * image_size; + locb = loca + xend; + loca += xstart; + + locc = yend * image_size; + locd = locc + xend; + locc += xstart; + } + + if(check && xend < image_size && yend < image_size && isTheSame(loca, locb, locc, locd)) { + + tempx = Math.min(image_size, x + current_chunk_size_x); + tempy = Math.min(image_size, y + current_chunk_size_y); + + int start_color = rgbs[loca]; + int skippedColor = getColorForSkippedPixels(start_color, iteration); + double start_iterations = image_iterations[loca]; + boolean start_escaped = escaped[loca]; + + PixelExtraData start_extra_data = null; + if(storeExtraData) { + start_extra_data = pixelData[loca]; + } + + for (int i = y; i < tempy; i++) { + for (int j = x, loc3 = i * image_size + j; j < tempx; j++, loc3++) { + if(!examined[loc3]) { + rgbs[loc3] = start_color; + image_iterations[loc3] = start_iterations; + escaped[loc3] = start_escaped; + setFilledAndExaminedWithSkippedColor(examined, filled, skipped_colors, loc3, skippedColor); + if(storeExtraData) { + pixelData[loc3] = new PixelExtraData(start_extra_data, skippedColor); + } + task_completed++; + drawing_done++; + } + } + } + } + else if (!examined[loc2]){ + image_iterations[loc2] = f_val = iteration_algorithm.calculate(location.getComplex(x, y)); + escaped[loc2] = escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(f_val, escaped_val); + task_calculated++; + + examined[loc2] = true; + drawing_done++; + task_completed++; + + if (storeExtraData) { + pixelData[loc2].set(0, color, f_val, escaped_val, totalSamples); + } + + aa.initialize(color); + + //Supersampling + for (int i = 0; i < supersampling_num; i++) { + temp_result = iteration_algorithm.calculate(location.getAntialiasingComplex(i, loc2)); + escaped_val = iteration_algorithm.escaped(); + color = getFinalColor(temp_result, escaped_val); + + if (storeExtraData) { + pixelData[loc2].set(i + 1, color, temp_result, escaped_val, totalSamples); + } + + if (!aa.addSample(color)) { + break; + } + } + + rgbs[loc2] = color = aa.getColor(); + + tempx = Math.min(image_size, x + current_chunk_size_x); + tempy = Math.min(image_size, y + current_chunk_size_y); + + for (int i = y; i < tempy; i++) { + for (int j = x, loc3 = i * image_size + j; j < tempx; j++, loc3++) { + rgbs[loc3] = color; + } + } + } + } + + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { + break; + } + } + + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { + break; + } + + if(drawing_done / pixel_percent >= 1) { + update(drawing_done); + drawing_done = 0; + } + + } while (true); + + nano_time += System.nanoTime() - time; + + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT) { + try { + successive_refinement_lock.lockRead(); + } catch (InterruptedException ex) { + + } + } + + try { + successive_refinement_drawing_algorithm_barrier.await(); + } catch (InterruptedException ex) { + + } catch (BrokenBarrierException ex) { + } + + if(taskId == 0 && ptr != null) { + if(id == 0) { + ptr.setWholeImageDone(true); + ptr.reloadTitle(); + updateMode(ptr, false, iteration_algorithm.isJulia(), false, false); + } + ptr.getMainPanel().repaint(); + } + + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT) { + if (id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { + successive_refinement_lock.unlockRead(); + throw new StopSuccessiveRefinementException(); + } + successive_refinement_lock.unlockRead(); + } + + if(performSecondPassActions) { + iteration++; + id2++; + } + } + + if(SKIPPED_PIXELS_ALG != 0) { + applySkippedColor(image_size, false); + } + + if (SKIPPED_PIXELS_ALG == 4) { + drawSquares(image_size); + } + + pixel_calculation_time_per_task = nano_time / 1000000; + + postProcess(image_size, aa, location); + + } + + @Override + protected void drawFastJulia(int image_size, boolean polar) { + + Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (HIGH_PRECISION_CALCULATION || PERTURBATION_THEORY) && fractal.supportsPerturbationTheory()); + + initialize(location); + + + int loc2, loc, x, y; + int tempx, tempy; + + boolean escaped_val; + double f_val; + + + int current_chunk_size_x = 0, current_chunk_size_y = 0; + int prev_chunk_size_x, prev_chunk_size_y; + int iteration = randomNumber; + int min_chunk_size = TaskDraw.GUESS_BLOCKS_SELECTION == 0 ? 0 : 1 << (TaskDraw.GUESS_BLOCKS_SELECTION - 1); + min_chunk_size = TWO_PASS_SUCCESSIVE_REFINEMENT ? min_chunk_size << 1 : min_chunk_size; + + int current_chunk_size2x = 0, current_chunk_size2y = 0; + + int xstart = 0; + int ystart = 0; + int xend = 0; + int yend = 0; + + int loca = 0; + int locb = 0; + int locc = 0; + int locd = 0; + + int length = TWO_PASS_SUCCESSIVE_REFINEMENT ? SUCCESSIVE_REFINEMENT_CHUNK_X.length << 1 : SUCCESSIVE_REFINEMENT_CHUNK_X.length; + + for(int id = 0, id2 = 0; id < length; id++) { + AtomicInteger ai = successive_refinement_drawing_algorithm2_pixel[id]; + + prev_chunk_size_x = current_chunk_size_x; + prev_chunk_size_y = current_chunk_size_y; + current_chunk_size_x = SUCCESSIVE_REFINEMENT_CHUNK_X[id2]; + current_chunk_size_y = SUCCESSIVE_REFINEMENT_CHUNK_Y[id2]; + + int image_size_tile_x = image_size % current_chunk_size_x == 0 ? image_size / current_chunk_size_x : image_size / current_chunk_size_x + 1; + int image_size_tile_y = image_size % current_chunk_size_y == 0 ? image_size / current_chunk_size_y : image_size / current_chunk_size_y + 1; + + int condition = (image_size_tile_x) * (image_size_tile_y); + + int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL2[id2]; + boolean performSecondPassActions = !TWO_PASS_SUCCESSIVE_REFINEMENT || (id & 1) == 1; + + do { + + loc = chunk_size * ai.getAndIncrement(); + + if (loc >= condition) { + break; + } + + for (int count = 0; count < chunk_size && loc < condition; count++, loc++) { + tempx = loc % image_size_tile_x; + tempy = loc / image_size_tile_x; + + x = tempx * current_chunk_size_x; + y = tempy * current_chunk_size_y; + + loc2 = y * image_size + x; + + if(!filled_fast_julia[loc2]) { + + int aggregate_chunk = getAggregateChunk(current_chunk_size_x, current_chunk_size_y); + boolean check = performSecondPassActions && aggregate_chunk <= min_chunk_size; + if(check) { + current_chunk_size2x = prev_chunk_size_x; + current_chunk_size2y = prev_chunk_size_y; + + xstart = (x / current_chunk_size2x) * current_chunk_size2x; + ystart = (y / current_chunk_size2y) * current_chunk_size2y; + xend = xstart + current_chunk_size2x; + yend = ystart + current_chunk_size2y; + + loca = ystart * image_size; + locb = loca + xend; + loca += xstart; + + locc = yend * image_size; + locd = locc + xend; + locc += xstart; + } + + if(check && xend < image_size && yend < image_size && isTheSameFastJulia(loca, locb, locc, locd)) { + + + tempx = Math.min(image_size, x + current_chunk_size_x); + tempy = Math.min(image_size, y + current_chunk_size_y); + + int start_color = rgbs[loca]; + int skippedColor = getColorForSkippedPixels(start_color, iteration); + double start_iterations = image_iterations_fast_julia[loca]; + boolean start_escaped = escaped_fast_julia[loca]; + + for (int i = y; i < tempy; i++) { + for (int j = x, loc3 = i * image_size + j; j < tempx; j++, loc3++) { + if(!examined_fast_julia[loc3]) { + rgbs[loc3] = start_color; + image_iterations_fast_julia[loc3] = start_iterations; + escaped_fast_julia[loc3] = start_escaped; + setFilledAndExaminedWithSkippedColor(examined_fast_julia, filled_fast_julia, skipped_colors_fast_julia, loc3, skippedColor); + } + } + } + } + else if (!examined_fast_julia[loc2]){ + image_iterations_fast_julia[loc2] = f_val = iteration_algorithm.calculate(location.getComplex(x, y)); + escaped_fast_julia[loc2] = escaped_val = iteration_algorithm.escaped(); + rgbs[loc2] = getFinalColor(f_val, escaped_val); + + examined_fast_julia[loc2] = true; + } + } + + } + + } while (true); + + try { + successive_refinement_drawing_algorithm_barrier.await(); + } catch (InterruptedException ex) { + + } catch (BrokenBarrierException ex) { + + } + + if(performSecondPassActions) { + iteration++; + id2++; + } + } + + if(SKIPPED_PIXELS_ALG != 0) { + applySkippedColor(image_size, true); + } + + if (SKIPPED_PIXELS_ALG == 4) { + drawSquares(image_size); + } + + + postProcessFastJulia(image_size, null, location); + + } +} diff --git a/src/fractalzoomer/core/drawing_algorithms/SuccessiveRefinementGuessingDraw.java b/src/fractalzoomer/core/drawing_algorithms/SuccessiveRefinementGuessingDraw.java index 4ce61e9d7..9e6f1b96a 100644 --- a/src/fractalzoomer/core/drawing_algorithms/SuccessiveRefinementGuessingDraw.java +++ b/src/fractalzoomer/core/drawing_algorithms/SuccessiveRefinementGuessingDraw.java @@ -27,6 +27,13 @@ public class SuccessiveRefinementGuessingDraw extends TaskDraw { public static int[] skipped_colors_fast_julia; protected static int STOP_AFTER_ITER = 2; + protected int getStopAfterIter() { + if(TWO_PASS_SUCCESSIVE_REFINEMENT) { + return STOP_AFTER_ITER << 1; + } + return STOP_AFTER_ITER; + } + public SuccessiveRefinementGuessingDraw(int FROMx, int TOx, int FROMy, int TOy, Apfloat xCenter, Apfloat yCenter, Apfloat size, int max_iterations, FunctionSettings fns, D3Settings d3s, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, FiltersSettings fs, boolean periodicity_checking, int color_cycling_location, int color_cycling_location2, boolean exterior_de, double exterior_de_factor, double height_ratio, boolean polar_projection, double circle_period, DomainColoringSettings ds, boolean inverse_dem, boolean quickDraw, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, JitterSettings js, PostProcessSettings pps) { super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, d3s, ptr, fractal_color, dem_color, image, fs, periodicity_checking, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, ds, inverse_dem, quickDraw, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps); } @@ -51,8 +58,8 @@ public SuccessiveRefinementGuessingDraw(int FROMx, int TOx, int FROMy, int TOy, super(FROMx, TOx, FROMy, TOy, xCenter, yCenter, size, max_iterations, fns, ptr, fractal_color, dem_color, fast_julia_filters, image, periodicity_checking, fs, color_cycling_location, color_cycling_location2, exterior_de, exterior_de_factor, height_ratio, polar_projection, circle_period, inverse_dem, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, gradient_offset, contourFactor, gps, js, pps, xJuliaCenter, yJuliaCenter); } - public SuccessiveRefinementGuessingDraw(int FROMx, int TOx, int FROMy, int TOy, int max_iterations, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, int color_cycling_location, int color_cycling_location2, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, int color_cycling_speed, FiltersSettings fs, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, boolean cycle_colors, boolean cycle_lights, boolean cycle_gradient, int color_cycling_adjusting_value, DomainColoringSettings ds, int gradient_offset, double contourFactor, boolean smoothing, GeneratedPaletteSettings gps, PostProcessSettings pps) { - super(FROMx, TOx, FROMy, TOy, max_iterations, ptr, fractal_color, dem_color, image, color_cycling_location, color_cycling_location2, color_cycling_speed, fs, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, cycle_colors, cycle_lights, cycle_gradient, color_cycling_adjusting_value, ds, gradient_offset, contourFactor, smoothing, gps, pps); + public SuccessiveRefinementGuessingDraw(int FROMx, int TOx, int FROMy, int TOy, int max_iterations, MainWindow ptr, Color fractal_color, Color dem_color, BufferedImage image, int color_cycling_location, int color_cycling_location2, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, FiltersSettings fs, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, DomainColoringSettings ds, int gradient_offset, double contourFactor, GeneratedPaletteSettings gps, PostProcessSettings pps, ColorCyclingSettings ccs) { + super(FROMx, TOx, FROMy, TOy, max_iterations, ptr, fractal_color, dem_color, image, color_cycling_location, color_cycling_location2, fs, color_intensity, transfer_function, color_density, color_intensity2, transfer_function2, color_density2, usePaletteForInColoring, color_blending, post_processing_order, pbs, ds, gradient_offset, contourFactor, gps, pps, ccs); } public SuccessiveRefinementGuessingDraw(int FROMx, int TOx, int FROMy, int TOy, int max_iterations, MainWindow ptr, BufferedImage image, Color fractal_color, Color dem_color, int color_cycling_location, int color_cycling_location2, FiltersSettings fs, double color_intensity, int transfer_function, double color_density, double color_intensity2, int transfer_function2, double color_density2, boolean usePaletteForInColoring, BlendingSettings color_blending, int[] post_processing_order, PaletteGradientMergingSettings pbs, DomainColoringSettings ds, int gradient_offset, double contourFactor, boolean smoothing, GeneratedPaletteSettings gps, PostProcessSettings pps) { @@ -81,20 +88,7 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi int pixel_percent = (image_size * image_size) / 100; - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); int color, loc2, loc, x, y; @@ -105,9 +99,11 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi int current_chunk_size = SUCCESSIVE_REFINEMENT_MAX_SIZE; + int prev_chunk_size = 0; int iteration = randomNumber; int min_chunk_size = TaskDraw.GUESS_BLOCKS_SELECTION == 0 ? 0 : 1 << (TaskDraw.GUESS_BLOCKS_SELECTION - 1); + min_chunk_size = TWO_PASS_SUCCESSIVE_REFINEMENT ? min_chunk_size << 1 : min_chunk_size; int current_chunk_size2 = 0; @@ -121,17 +117,21 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi int locc = 0; int locd = 0; + + int stop_id = getStopAfterIter(); + task_completed = 0; long nano_time = 0; - for(int id = 0; current_chunk_size >= 1; current_chunk_size >>= 1, id++, iteration++) { + for(int id = 0, id2 = 0; current_chunk_size >= 1; id++) { long time = System.nanoTime(); AtomicInteger ai = successive_refinement_drawing_algorithm_pixel[id]; int image_size_tile = image_size % current_chunk_size == 0 ? image_size / current_chunk_size : image_size / current_chunk_size + 1; int condition = (image_size_tile) * (image_size_tile); - int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL[id]; + int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL[id2]; + boolean performSecondPassActions = !TWO_PASS_SUCCESSIVE_REFINEMENT || (id & 1) == 1; do { @@ -152,8 +152,9 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi if(!filled[loc2]) { - if(current_chunk_size <= min_chunk_size) { - current_chunk_size2 = current_chunk_size << 1; + boolean check = performSecondPassActions && current_chunk_size <= min_chunk_size; + if(check) { + current_chunk_size2 = prev_chunk_size; xstart = (x / current_chunk_size2) * current_chunk_size2; ystart = (y / current_chunk_size2) * current_chunk_size2; @@ -169,40 +170,45 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi locc += xstart; } - if(current_chunk_size <= min_chunk_size && xend < image_size && yend < image_size && isTheSame(loca, locb, locc, locd)) { - + if(check && xend < image_size && yend < image_size && isTheSame(loca, locb, locc, locd)) { tempx = Math.min(image_size, x + current_chunk_size); tempy = Math.min(image_size, y + current_chunk_size); - int skippedColor = getColorForSkippedPixels(rgbs[loca], iteration); + int start_color = rgbs[loca]; + int skippedColor = getColorForSkippedPixels(start_color, iteration); + double start_iterations = image_iterations[loca]; + boolean start_escaped = escaped[loca]; for (int i = y; i < tempy; i++) { for (int j = x, loc3 = i * image_size + j; j < tempx; j++, loc3++) { if(!examined[loc3]) { - rgbs[loc3] = rgbs[loca]; - image_iterations[loc3] = image_iterations[loca]; - escaped[loc3] = escaped[loca]; + if (rgbs[loc3] >>> 24 != Constants.NORMAL_ALPHA) { + rgbs[loc3] = start_color; + image_iterations[loc3] = start_iterations; + escaped[loc3] = start_escaped; + task_completed++; + } + setFilledAndExaminedWithSkippedColor(examined, filled, skipped_colors, loc3, skippedColor); - task_completed++; drawing_done++; } } } } - else if (!examined[loc2]){ + else if (!examined[loc2]) { if (rgbs[loc2] >>> 24 != Constants.NORMAL_ALPHA) { image_iterations[loc2] = f_val = iteration_algorithm.calculate(location.getComplex(x, y)); escaped[loc2] = escaped_val = iteration_algorithm.escaped(); rgbs[loc2] = color = getFinalColor(f_val, escaped_val); task_calculated++; + task_completed++; } else { color = rgbs[loc2]; } examined[loc2] = true; - task_completed++; drawing_done++; tempx = Math.min(image_size, x + current_chunk_size); @@ -218,12 +224,12 @@ else if (!examined[loc2]){ } } - if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > STOP_AFTER_ITER && STOP_SUCCESSIVE_REFINEMENT) { + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { break; } } - if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > STOP_AFTER_ITER && STOP_SUCCESSIVE_REFINEMENT) { + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { break; } @@ -254,8 +260,8 @@ else if (!examined[loc2]){ } if(taskId == 0 && ptr != null) { - ptr.setWholeImageDone(true); if(id == 0) { + ptr.setWholeImageDone(true); ptr.reloadTitle(); updateMode(ptr, false, iteration_algorithm.isJulia(), false, false); } @@ -263,12 +269,19 @@ else if (!examined[loc2]){ } if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT) { - if (id > STOP_AFTER_ITER && STOP_SUCCESSIVE_REFINEMENT) { + if (id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { successive_refinement_lock.unlockRead(); throw new StopSuccessiveRefinementException(); } successive_refinement_lock.unlockRead(); } + + prev_chunk_size = current_chunk_size; + if(performSecondPassActions) { + current_chunk_size >>= 1; + iteration++; + id2++; + } } if(SKIPPED_PIXELS_ALG != 0) { @@ -298,15 +311,17 @@ protected void drawSquares(int image_size) { int colB = grey; int length = 14; + int thread_chunk_size = getThreadChunkSize(image_size, CHUNK_SIZE_PER_ROW); + do { - loc = THREAD_CHUNK_SIZE * draw_squares_pixel.getAndIncrement(); + loc = thread_chunk_size * draw_squares_pixel.getAndIncrement(); if(loc >= condition) { break; } - for(int count = 0; count < THREAD_CHUNK_SIZE && loc < condition; count++, loc++) { + for(int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { x = loc % image_size; y = loc / image_size; @@ -344,15 +359,17 @@ protected void applySkippedColor(int image_size, boolean isFastJulia) { int[] colors = isFastJulia ? skipped_colors_fast_julia : skipped_colors; + int thread_chunk_size = getThreadChunkSize(image_size, CHUNK_SIZE_PER_ROW); + do { - loc = THREAD_CHUNK_SIZE * apply_skipped_color_pixel.getAndIncrement(); + loc = thread_chunk_size * apply_skipped_color_pixel.getAndIncrement(); if (loc >= condition) { break; } - for (int count = 0; count < THREAD_CHUNK_SIZE && loc < condition; count++, loc++) { + for (int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { x = loc % image_size; y = loc / image_size; @@ -380,20 +397,7 @@ protected void drawFastJuliaAntialiased(int image_size, boolean polar) { int supersampling_num = getExtraSamples(aaSamplesIndex, aaMethod); location.createAntialiasingSteps(aaMethod == 5, useJitter, supersampling_num); - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); boolean aaAvgWithMean = ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x1) == 1; int colorSpace = filters_options_extra_vals[0][MainWindow.ANTIALIASING]; @@ -413,8 +417,11 @@ protected void drawFastJuliaAntialiased(int image_size, boolean polar) { double temp_result; int current_chunk_size = SUCCESSIVE_REFINEMENT_MAX_SIZE; + int prev_chunk_size = 0; int iteration = randomNumber; int min_chunk_size = TaskDraw.GUESS_BLOCKS_SELECTION == 0 ? 0 : 1 << (TaskDraw.GUESS_BLOCKS_SELECTION - 1); + min_chunk_size = TWO_PASS_SUCCESSIVE_REFINEMENT ? min_chunk_size << 1 : min_chunk_size; + int current_chunk_size2 = 0; @@ -428,12 +435,13 @@ protected void drawFastJuliaAntialiased(int image_size, boolean polar) { int locc = 0; int locd = 0; - for(int id = 0; current_chunk_size >= 1; current_chunk_size >>= 1, id++, iteration++) { + for(int id = 0, id2 = 0; current_chunk_size >= 1; id++) { AtomicInteger ai = successive_refinement_drawing_algorithm_pixel[id]; int image_size_tile = image_size % current_chunk_size == 0 ? image_size / current_chunk_size : image_size / current_chunk_size + 1; int condition = (image_size_tile) * (image_size_tile); - int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL[id]; + int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL[id2]; + boolean performSecondPassActions = !TWO_PASS_SUCCESSIVE_REFINEMENT || (id & 1) == 1; do { @@ -454,8 +462,9 @@ protected void drawFastJuliaAntialiased(int image_size, boolean polar) { if(!filled_fast_julia[loc2]) { - if(current_chunk_size <= min_chunk_size) { - current_chunk_size2 = current_chunk_size << 1; + boolean check = performSecondPassActions && current_chunk_size <= min_chunk_size; + if(check) { + current_chunk_size2 = prev_chunk_size; xstart = (x / current_chunk_size2) * current_chunk_size2; ystart = (y / current_chunk_size2) * current_chunk_size2; @@ -471,23 +480,31 @@ protected void drawFastJuliaAntialiased(int image_size, boolean polar) { locc += xstart; } - if(current_chunk_size <= min_chunk_size && xend < image_size && yend < image_size && isTheSameFastJulia(loca, locb, locc, locd)) { + if(check && xend < image_size && yend < image_size && isTheSameFastJulia(loca, locb, locc, locd)) { tempx = Math.min(image_size, x + current_chunk_size); tempy = Math.min(image_size, y + current_chunk_size); - int skippedColor = getColorForSkippedPixels(rgbs[loca], iteration); + int start_color = rgbs[loca]; + int skippedColor = getColorForSkippedPixels(start_color, iteration); + double start_iterations = image_iterations_fast_julia[loca]; + boolean start_escaped = escaped_fast_julia[loca]; + + PixelExtraData start_extra_data = null; + if(storeExtraData) { + start_extra_data = pixelData_fast_julia[loca]; + } for (int i = y; i < tempy; i++) { for (int j = x, loc3 = i * image_size + j; j < tempx; j++, loc3++) { if(!examined_fast_julia[loc3]) { - rgbs[loc3] = rgbs[loca]; - image_iterations_fast_julia[loc3] = image_iterations_fast_julia[loca]; - escaped_fast_julia[loc3] = escaped_fast_julia[loca]; + rgbs[loc3] = start_color; + image_iterations_fast_julia[loc3] = start_iterations; + escaped_fast_julia[loc3] = start_escaped; setFilledAndExaminedWithSkippedColor(examined_fast_julia, filled_fast_julia, skipped_colors_fast_julia, loc3, skippedColor); if(storeExtraData) { - pixelData_fast_julia[loc3] = new PixelExtraData(pixelData_fast_julia[loca], skippedColor); + pixelData_fast_julia[loc3] = new PixelExtraData(start_extra_data, skippedColor); } } } @@ -536,6 +553,13 @@ else if (!examined_fast_julia[loc2]){ } catch (BrokenBarrierException ex) { } + + prev_chunk_size = current_chunk_size; + if(performSecondPassActions) { + current_chunk_size >>= 1; + iteration++; + id2++; + } } @@ -564,20 +588,7 @@ protected void drawIterationsAntialiased(int image_size, boolean polar) throws S location.createAntialiasingSteps(aaMethod == 5, useJitter, supersampling_num); int pixel_percent = (image_size * image_size) / 100; - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); boolean aaAvgWithMean = ((filters_options_vals[MainWindow.ANTIALIASING] / 100) & 0x1) == 1; int colorSpace = filters_options_extra_vals[0][MainWindow.ANTIALIASING]; @@ -598,8 +609,10 @@ protected void drawIterationsAntialiased(int image_size, boolean polar) throws S int current_chunk_size = SUCCESSIVE_REFINEMENT_MAX_SIZE; + int prev_chunk_size = 0; int iteration = randomNumber; int min_chunk_size = TaskDraw.GUESS_BLOCKS_SELECTION == 0 ? 0 : 1 << (TaskDraw.GUESS_BLOCKS_SELECTION - 1); + min_chunk_size = TWO_PASS_SUCCESSIVE_REFINEMENT ? min_chunk_size << 1 : min_chunk_size; int current_chunk_size2 = 0; @@ -614,15 +627,18 @@ protected void drawIterationsAntialiased(int image_size, boolean polar) throws S int locd = 0; task_completed = 0; + int stop_id = getStopAfterIter(); + long nano_time = 0; - for(int id = 0; current_chunk_size >= 1; current_chunk_size >>= 1, id++, iteration++) { + for(int id = 0, id2 = 0; current_chunk_size >= 1; id++) { long time = System.nanoTime(); AtomicInteger ai = successive_refinement_drawing_algorithm_pixel[id]; int image_size_tile = image_size % current_chunk_size == 0 ? image_size / current_chunk_size : image_size / current_chunk_size + 1; int condition = (image_size_tile) * (image_size_tile); - int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL[id]; + int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL[id2]; + boolean performSecondPassActions = !TWO_PASS_SUCCESSIVE_REFINEMENT || (id & 1) == 1; do { @@ -643,8 +659,9 @@ protected void drawIterationsAntialiased(int image_size, boolean polar) throws S if(!filled[loc2]) { - if(current_chunk_size <= min_chunk_size) { - current_chunk_size2 = current_chunk_size << 1; + boolean check = performSecondPassActions && current_chunk_size <= min_chunk_size; + if(check) { + current_chunk_size2 = prev_chunk_size; xstart = (x / current_chunk_size2) * current_chunk_size2; ystart = (y / current_chunk_size2) * current_chunk_size2; @@ -660,23 +677,30 @@ protected void drawIterationsAntialiased(int image_size, boolean polar) throws S locc += xstart; } - if(current_chunk_size <= min_chunk_size && xend < image_size && yend < image_size && isTheSame(loca, locb, locc, locd)) { + if(check && xend < image_size && yend < image_size && isTheSame(loca, locb, locc, locd)) { tempx = Math.min(image_size, x + current_chunk_size); tempy = Math.min(image_size, y + current_chunk_size); - int skippedColor = getColorForSkippedPixels(rgbs[loca], iteration); + int start_color = rgbs[loca]; + int skippedColor = getColorForSkippedPixels(start_color, iteration); + double start_iterations = image_iterations[loca]; + boolean start_escaped = escaped[loca]; + PixelExtraData start_extra_data = null; + if(storeExtraData) { + start_extra_data = pixelData[loca]; + } for (int i = y; i < tempy; i++) { for (int j = x, loc3 = i * image_size + j; j < tempx; j++, loc3++) { if(!examined[loc3]) { - rgbs[loc3] = rgbs[loca]; - image_iterations[loc3] = image_iterations[loca]; - escaped[loc3] = escaped[loca]; + rgbs[loc3] = start_color; + image_iterations[loc3] = start_iterations; + escaped[loc3] = start_escaped; setFilledAndExaminedWithSkippedColor(examined, filled, skipped_colors, loc3, skippedColor); if(storeExtraData) { - pixelData[loc3] = new PixelExtraData(pixelData[loca], skippedColor); + pixelData[loc3] = new PixelExtraData(start_extra_data, skippedColor); } task_completed++; drawing_done++; @@ -685,7 +709,6 @@ protected void drawIterationsAntialiased(int image_size, boolean polar) throws S } } else if (!examined[loc2]){ - image_iterations[loc2] = f_val = iteration_algorithm.calculate(location.getComplex(x, y)); escaped[loc2] = escaped_val = iteration_algorithm.escaped(); color = getFinalColor(f_val, escaped_val); @@ -695,30 +718,29 @@ else if (!examined[loc2]){ drawing_done++; task_completed++; - if(storeExtraData) { + if (storeExtraData) { pixelData[loc2].set(0, color, f_val, escaped_val, totalSamples); } aa.initialize(color); //Supersampling - for(int i = 0; i < supersampling_num; i++) { + for (int i = 0; i < supersampling_num; i++) { temp_result = iteration_algorithm.calculate(location.getAntialiasingComplex(i, loc2)); escaped_val = iteration_algorithm.escaped(); color = getFinalColor(temp_result, escaped_val); - if(storeExtraData) { + if (storeExtraData) { pixelData[loc2].set(i + 1, color, temp_result, escaped_val, totalSamples); } - if(!aa.addSample(color)) { + if (!aa.addSample(color)) { break; } } rgbs[loc2] = color = aa.getColor(); - tempx = Math.min(image_size, x + current_chunk_size); tempy = Math.min(image_size, y + current_chunk_size); @@ -730,12 +752,12 @@ else if (!examined[loc2]){ } } - if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > STOP_AFTER_ITER && STOP_SUCCESSIVE_REFINEMENT) { + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { break; } } - if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > STOP_AFTER_ITER && STOP_SUCCESSIVE_REFINEMENT) { + if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT && id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { break; } @@ -764,8 +786,8 @@ else if (!examined[loc2]){ } if(taskId == 0 && ptr != null) { - ptr.setWholeImageDone(true); if(id == 0) { + ptr.setWholeImageDone(true); ptr.reloadTitle(); updateMode(ptr, false, iteration_algorithm.isJulia(), false, false); } @@ -773,12 +795,19 @@ else if (!examined[loc2]){ } if(USE_QUICKDRAW_ON_GREEDY_SUCCESSIVE_REFINEMENT) { - if (id > STOP_AFTER_ITER && STOP_SUCCESSIVE_REFINEMENT) { + if (id > stop_id && STOP_SUCCESSIVE_REFINEMENT) { successive_refinement_lock.unlockRead(); throw new StopSuccessiveRefinementException(); } successive_refinement_lock.unlockRead(); } + + prev_chunk_size = current_chunk_size; + if(performSecondPassActions) { + current_chunk_size >>= 1; + iteration++; + id2++; + } } if(SKIPPED_PIXELS_ALG != 0) { @@ -800,20 +829,7 @@ protected void drawFastJulia(int image_size, boolean polar) { Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (HIGH_PRECISION_CALCULATION || PERTURBATION_THEORY) && fractal.supportsPerturbationTheory()); - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); int loc2, loc, x, y; @@ -824,8 +840,10 @@ protected void drawFastJulia(int image_size, boolean polar) { int current_chunk_size = SUCCESSIVE_REFINEMENT_MAX_SIZE; + int prev_chunk_size = 0; int iteration = randomNumber; int min_chunk_size = TaskDraw.GUESS_BLOCKS_SELECTION == 0 ? 0 : 1 << (TaskDraw.GUESS_BLOCKS_SELECTION - 1); + min_chunk_size = TWO_PASS_SUCCESSIVE_REFINEMENT ? min_chunk_size << 1 : min_chunk_size; int current_chunk_size2 = 0; @@ -839,12 +857,13 @@ protected void drawFastJulia(int image_size, boolean polar) { int locc = 0; int locd = 0; - for(int id = 0; current_chunk_size >= 1; current_chunk_size >>= 1, id++, iteration++) { + for(int id = 0, id2 = 0; current_chunk_size >= 1; id++) { AtomicInteger ai = successive_refinement_drawing_algorithm_pixel[id]; int image_size_tile = image_size % current_chunk_size == 0 ? image_size / current_chunk_size : image_size / current_chunk_size + 1; int condition = (image_size_tile) * (image_size_tile); - int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL[id]; + int chunk_size = THREAD_CHUNK_SIZE_PER_LEVEL[id2]; + boolean performSecondPassActions = !TWO_PASS_SUCCESSIVE_REFINEMENT || (id & 1) == 1; do { @@ -865,8 +884,9 @@ protected void drawFastJulia(int image_size, boolean polar) { if(!filled_fast_julia[loc2]) { - if(current_chunk_size <= min_chunk_size) { - current_chunk_size2 = current_chunk_size << 1; + boolean check = performSecondPassActions && current_chunk_size <= min_chunk_size; + if(check) { + current_chunk_size2 = prev_chunk_size; xstart = (x / current_chunk_size2) * current_chunk_size2; ystart = (y / current_chunk_size2) * current_chunk_size2; @@ -882,19 +902,23 @@ protected void drawFastJulia(int image_size, boolean polar) { locc += xstart; } - if(current_chunk_size <= min_chunk_size && xend < image_size && yend < image_size && isTheSameFastJulia(loca, locb, locc, locd)) { + if(check && xend < image_size && yend < image_size && isTheSameFastJulia(loca, locb, locc, locd)) { tempx = Math.min(image_size, x + current_chunk_size); tempy = Math.min(image_size, y + current_chunk_size); - int skippedColor = getColorForSkippedPixels(rgbs[loca], iteration); + int start_color = rgbs[loca]; + int skippedColor = getColorForSkippedPixels(start_color, iteration); + double start_iterations = image_iterations_fast_julia[loca]; + boolean start_escaped = escaped_fast_julia[loca]; + for (int i = y; i < tempy; i++) { for (int j = x, loc3 = i * image_size + j; j < tempx; j++, loc3++) { if(!examined_fast_julia[loc3]) { - rgbs[loc3] = rgbs[loca]; - image_iterations_fast_julia[loc3] = image_iterations_fast_julia[loca]; - escaped_fast_julia[loc3] = escaped_fast_julia[loca]; + rgbs[loc3] = start_color; + image_iterations_fast_julia[loc3] = start_iterations; + escaped_fast_julia[loc3] = start_escaped; setFilledAndExaminedWithSkippedColor(examined_fast_julia, filled_fast_julia, skipped_colors_fast_julia, loc3, skippedColor); } } @@ -920,6 +944,13 @@ else if (!examined_fast_julia[loc2]){ } catch (BrokenBarrierException ex) { } + + prev_chunk_size = current_chunk_size; + if(performSecondPassActions) { + current_chunk_size >>= 1; + iteration++; + id2++; + } } if(SKIPPED_PIXELS_ALG != 0) { @@ -983,15 +1014,17 @@ protected void applyPostProcessingPointFilter(int image_size, double[] image_ite int x, y, loc; int condition = image_size * image_size; + int thread_chunk_size = getThreadChunkSize(image_size, CHUNK_SIZE_PER_ROW); + do { - loc = THREAD_CHUNK_SIZE * normal_drawing_algorithm_post_processing.getAndIncrement(); + loc = thread_chunk_size * normal_drawing_algorithm_post_processing.getAndIncrement(); if(loc >= condition) { break; } - for(int count = 0; count < THREAD_CHUNK_SIZE && loc < condition; count++, loc++) { + for(int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { x = loc % image_size; y = loc / image_size; @@ -1026,17 +1059,19 @@ protected void changePalette(int image_size) throws StopSuccessiveRefinementExce int condition = image_size * image_size; task_completed = 0; + int thread_chunk_size = getThreadChunkSize(image_size, CHUNK_SIZE_PER_ROW); + long time = System.currentTimeMillis(); do { - loc = THREAD_CHUNK_SIZE * normal_drawing_algorithm_apply_palette.getAndIncrement(); + loc = thread_chunk_size * normal_drawing_algorithm_apply_palette.getAndIncrement(); if(loc >= condition) { break; } - for(int count = 0; count < THREAD_CHUNK_SIZE && loc < condition; count++, loc++) { + for(int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { if (domain_coloring) { rgbs[loc] = domain_color.getDomainColor(new Complex(domain_image_data_re[loc], domain_image_data_im[loc])); } else { @@ -1117,17 +1152,19 @@ protected void changePaletteWithAA(int image_size) throws StopSuccessiveRefineme PixelExtraData data; task_completed = 0; + int thread_chunk_size = getThreadChunkSize(image_size, CHUNK_SIZE_PER_ROW); + long time = System.currentTimeMillis(); do { - loc = THREAD_CHUNK_SIZE * normal_drawing_algorithm_apply_palette.getAndIncrement(); + loc = thread_chunk_size * normal_drawing_algorithm_apply_palette.getAndIncrement(); if(loc >= condition) { break; } - for(int count = 0; count < THREAD_CHUNK_SIZE && loc < condition; count++, loc++) { + for(int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { data = pixelData[loc]; data.update_rgb(0, color = getStandardColor(data.values[0], data.escaped[0])); @@ -1209,17 +1246,19 @@ protected void drawIterationsDomain(int image_size, boolean polar) { int condition = image_size * image_size; + int thread_chunk_size = getThreadChunkSize(image_size, CHUNK_SIZE_PER_ROW); + long time = System.currentTimeMillis(); do { - loc = THREAD_CHUNK_SIZE * normal_drawing_algorithm_pixel.getAndIncrement(); + loc = thread_chunk_size * normal_drawing_algorithm_pixel.getAndIncrement(); if (loc >= condition) { break; } - for (int count = 0; count < THREAD_CHUNK_SIZE && loc < condition; count++, loc++) { + for (int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { x = loc % image_size; y = loc / image_size; @@ -1282,19 +1321,21 @@ protected void drawIterationsDomainAntialiased(int image_size, boolean polar) { boolean storeExtraData = pixelData != null; + int thread_chunk_size = getThreadChunkSize(image_size, CHUNK_SIZE_PER_ROW); + double f_val; long time = System.currentTimeMillis(); do { - loc = THREAD_CHUNK_SIZE * normal_drawing_algorithm_pixel.getAndIncrement(); + loc = thread_chunk_size * normal_drawing_algorithm_pixel.getAndIncrement(); if (loc >= condition) { break; } - for (int count = 0; count < THREAD_CHUNK_SIZE && loc < condition; count++, loc++) { + for (int count = 0; count < thread_chunk_size && loc < condition; count++, loc++) { x = loc % image_size; y = loc / image_size; @@ -1331,18 +1372,16 @@ protected void drawIterationsDomainAntialiased(int image_size, boolean polar) { rgbs[loc] = aa.getColor(); drawing_done++; + task_calculated++; } if (drawing_done / pixel_percent >= 1) { update(drawing_done); - task_calculated += drawing_done; drawing_done = 0; } } while (true); - task_calculated += drawing_done; - pixel_calculation_time_per_task = System.currentTimeMillis() - time; try { diff --git a/src/fractalzoomer/core/drawing_algorithms/TiledGuessingDraw.java b/src/fractalzoomer/core/drawing_algorithms/TiledGuessingDraw.java index c80de1efd..714e59355 100644 --- a/src/fractalzoomer/core/drawing_algorithms/TiledGuessingDraw.java +++ b/src/fractalzoomer/core/drawing_algorithms/TiledGuessingDraw.java @@ -45,20 +45,7 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi Location location = Location.getInstanceForDrawing(xCenter, yCenter, size, height_ratio, image_size, circle_period, rotation_center, rotation_vals, fractal, js, polar, (PERTURBATION_THEORY || HIGH_PRECISION_CALCULATION) && fractal.supportsPerturbationTheory()); - if(PERTURBATION_THEORY && fractal.supportsPerturbationTheory() && !HIGH_PRECISION_CALCULATION) { - if (reference_calc_sync.getAndIncrement() == 0) { - calculateReference(location); - } - - try { - reference_sync.await(); - } catch (InterruptedException ex) { - - } catch (BrokenBarrierException ex) { - - } - location.setReference(Fractal.refPoint); - } + initialize(location); int pixel_percent = (image_size * image_size) / 100; @@ -202,11 +189,15 @@ protected void drawIterations(int image_size, boolean polar) throws StopSuccessi int temploc = k * image_size; temp3 = temploc + x; temp4 = temploc + temp1; - Arrays.fill(image_iterations, temp3, temp4, temp_starting_pixel_cicle); - Arrays.fill(rgbs, temp3, temp4, skippedColor); - Arrays.fill(escaped, temp3, temp4, temp_starting_escaped); + for (int index = temp3; index < temp4; index++) { + if (rgbs[index] == notCalculated) { + image_iterations[index] = temp_starting_pixel_cicle; + rgbs[index] = skippedColor; + escaped[index] = temp_starting_escaped; + task_completed++; + } + } drawing_done += chunk; - task_completed += chunk; } if (drawing_done / pixel_percent >= 1) { diff --git a/src/fractalzoomer/core/la/ATInfo.java b/src/fractalzoomer/core/la/ATInfo.java index ab93d3cac..0d680c1c1 100644 --- a/src/fractalzoomer/core/la/ATInfo.java +++ b/src/fractalzoomer/core/la/ATInfo.java @@ -23,11 +23,11 @@ protected boolean Usable(MantExp SqrRadius) { } public boolean isValid(Complex DeltaSub0) { - return DeltaSub0.chebychevNorm() <= ThresholdC.toDouble(); + return DeltaSub0.chebyshevNorm() <= ThresholdC.toDouble(); } public boolean isValid(MantExpComplex DeltaSub0) { - return DeltaSub0.chebychevNorm().compareToBothPositiveReduced(ThresholdC) <= 0; + return DeltaSub0.chebyshevNorm().compareToBothPositiveReduced(ThresholdC) <= 0; } public Complex getC(Complex dc) { diff --git a/src/fractalzoomer/core/la/GenericLAInfo.java b/src/fractalzoomer/core/la/GenericLAInfo.java index 8d6d771d2..65e15c046 100644 --- a/src/fractalzoomer/core/la/GenericLAInfo.java +++ b/src/fractalzoomer/core/la/GenericLAInfo.java @@ -1,26 +1,18 @@ package fractalzoomer.core.la; -import fractalzoomer.core.Complex; -import fractalzoomer.core.GenericComplex; -import fractalzoomer.core.MantExp; -import fractalzoomer.core.MantExpComplex; +import fractalzoomer.core.*; import fractalzoomer.core.la.impl.LAInfo; import fractalzoomer.core.la.impl.LAInfoDeep; import fractalzoomer.core.la.impl_refindex.LAInfoDeepRI; import fractalzoomer.core.la.impl_refindex.LAInfoRI; +import fractalzoomer.functions.Fractal; public abstract class GenericLAInfo { - public static double[] refRe; - public static double[] refIm; - public static double[] refMantsRe; - public static double[] refMantsIm; - public static long[] refExpRe; - public static long[] refExpIm; private static final int ITERATIONS_MEMORY_THRESHOLD = 50_000_000; - public static GenericLAInfo create(int length, boolean deepZoom, int refIndex) { - if(length > ITERATIONS_MEMORY_THRESHOLD) { + public static GenericLAInfo create(int length, boolean deepZoom, int refIndex, ReferenceDecompressor referenceDecompressor) { + if(TaskDraw.USE_RI_ON_BLA2 || (!TaskDraw.DISABLE_RI_ON_BLA2 && !TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE && length > ITERATIONS_MEMORY_THRESHOLD)) { if (deepZoom) { return LAInfoDeepRI.create(refIndex); } else { @@ -29,15 +21,15 @@ public static GenericLAInfo create(int length, boolean deepZoom, int refIndex) { } else { if (deepZoom) { - return LAInfoDeep.create(refIndex); + return LAInfoDeep.create(refIndex, referenceDecompressor); } else { - return LAInfo.create(refIndex); + return LAInfo.create(refIndex, referenceDecompressor); } } } public static GenericLAInfo create(int length, boolean deepZoom) { - if(length > ITERATIONS_MEMORY_THRESHOLD) { + if(TaskDraw.USE_RI_ON_BLA2 || (!TaskDraw.DISABLE_RI_ON_BLA2 && !TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE && length > ITERATIONS_MEMORY_THRESHOLD)) { if (deepZoom) { return LAInfoDeepRI.create(); } else { @@ -53,66 +45,66 @@ public static GenericLAInfo create(int length, boolean deepZoom) { } } - protected abstract GenericLAInfo Composite(LAInfo LA) throws InvalidCalculationException; - protected abstract GenericLAInfo Composite(LAInfoRI LA) throws InvalidCalculationException; + protected abstract GenericLAInfo Composite(LAInfo LA, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException; + protected abstract GenericLAInfo Composite(LAInfoRI LA, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException; - protected abstract GenericLAInfo Composite(LAInfoDeep LA); - protected abstract GenericLAInfo Composite(LAInfoDeepRI LA); + protected abstract GenericLAInfo Composite(LAInfoDeep LA, ReferenceDecompressor referenceDecompressor); + protected abstract GenericLAInfo Composite(LAInfoDeepRI LA, ReferenceDecompressor referenceDecompressor); - protected abstract GenericLAInfo Step(int RefIndex) throws InvalidCalculationException; - protected abstract boolean Composite(LAInfo out, LAInfo LA) throws InvalidCalculationException; - protected abstract boolean Composite(LAInfoRI out, LAInfoRI LA) throws InvalidCalculationException; - protected abstract boolean Composite(LAInfoDeep out, LAInfoDeep LA); + protected abstract GenericLAInfo Step(int RefIndex, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException; + protected abstract boolean Composite(LAInfo out, LAInfo LA, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException; + protected abstract boolean Composite(LAInfoRI out, LAInfoRI LA, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException; + protected abstract boolean Composite(LAInfoDeep out, LAInfoDeep LA, ReferenceDecompressor referenceDecompressor); - protected abstract boolean Composite(LAInfoDeepRI out, LAInfoDeepRI LA); - protected abstract boolean Step(LAInfoDeep out, int zRefIndex); - protected abstract boolean Step(LAInfoDeepRI out, int zRefIndex); - protected abstract boolean Step(LAInfo out, int zRefIndex) throws InvalidCalculationException; - protected abstract boolean Step(LAInfoRI out, int zRefIndex) throws InvalidCalculationException; + protected abstract boolean Composite(LAInfoDeepRI out, LAInfoDeepRI LA, ReferenceDecompressor referenceDecompressor); + protected abstract boolean Step(LAInfoDeep out, int zRefIndex, ReferenceDecompressor referenceDecompressor); + protected abstract boolean Step(LAInfoDeepRI out, int zRefIndex, ReferenceDecompressor referenceDecompressor); + protected abstract boolean Step(LAInfo out, int zRefIndex, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException; + protected abstract boolean Step(LAInfoRI out, int zRefIndex, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException; - protected boolean Step(GenericLAInfo out, int zRefIndex) throws InvalidCalculationException { + protected boolean Step(GenericLAInfo out, int zRefIndex, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { if(out instanceof LAInfo) { - return Step((LAInfo) out, zRefIndex); + return Step((LAInfo) out, zRefIndex, referenceDecompressor); } else if(out instanceof LAInfoRI) { - return Step((LAInfoRI) out, zRefIndex); + return Step((LAInfoRI) out, zRefIndex, referenceDecompressor); } else if(out instanceof LAInfoDeep) { - return Step((LAInfoDeep) out, zRefIndex); + return Step((LAInfoDeep) out, zRefIndex, referenceDecompressor); } else { - return Step((LAInfoDeepRI) out, zRefIndex); + return Step((LAInfoDeepRI) out, zRefIndex, referenceDecompressor); } } - protected GenericLAInfo Composite(GenericLAInfo LA) throws InvalidCalculationException { + protected GenericLAInfo Composite(GenericLAInfo LA, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { if(LA instanceof LAInfo) { - return Composite((LAInfo) LA); + return Composite((LAInfo) LA, referenceDecompressor); } else if(LA instanceof LAInfoRI) { - return Composite((LAInfoRI) LA); + return Composite((LAInfoRI) LA, referenceDecompressor); } else if(LA instanceof LAInfoDeep) { - return Composite((LAInfoDeep) LA); + return Composite((LAInfoDeep) LA, referenceDecompressor); } else { - return Composite((LAInfoDeepRI) LA); + return Composite((LAInfoDeepRI) LA, referenceDecompressor); } } - protected boolean Composite(GenericLAInfo out, GenericLAInfo LA) throws InvalidCalculationException { + protected boolean Composite(GenericLAInfo out, GenericLAInfo LA, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { if(LA instanceof LAInfo) { - return Composite((LAInfo) out, (LAInfo) LA); + return Composite((LAInfo) out, (LAInfo) LA, referenceDecompressor); } else if(LA instanceof LAInfoRI) { - return Composite((LAInfoRI) out, (LAInfoRI) LA); + return Composite((LAInfoRI) out, (LAInfoRI) LA, referenceDecompressor); } else if(LA instanceof LAInfoDeep) { - return Composite((LAInfoDeep) out, (LAInfoDeep) LA); + return Composite((LAInfoDeep) out, (LAInfoDeep) LA, referenceDecompressor); } else { - return Composite((LAInfoDeepRI) out, (LAInfoDeepRI) LA); + return Composite((LAInfoDeepRI) out, (LAInfoDeepRI) LA, referenceDecompressor); } } @@ -133,7 +125,8 @@ protected boolean DetectPeriod(GenericComplex z) { } } - public abstract GenericComplex getRef(); + public abstract GenericComplex getRef(Fractal f); + public Complex getRefDouble() {return null;} public abstract GenericComplex getZCoeff(); @@ -154,15 +147,15 @@ public GenericLAInfo toDouble() { return this; } - protected LAstep Prepare(MantExpComplex dz) { + protected LAstep Prepare(Fractal f, MantExpComplex dz) { return null; } - protected LAstep Prepare(Complex dz) { + protected LAstep Prepare(Fractal f, Complex dz) { return null; } - protected LAstep Prepare(double dre, double dim) { + protected LAstep Prepare(Fractal f, double dre, double dim) { return null; } @@ -198,4 +191,12 @@ public MantExpComplex EvaluateDzdc2(MantExpComplex z, MantExpComplex dzdc2, Mant return null; } + public abstract boolean isEqual(GenericLAInfo other); + + @Override + public String toString() { + return ""; + } + + } diff --git a/src/fractalzoomer/core/la/LAInfoBase.java b/src/fractalzoomer/core/la/LAInfoBase.java index a92021a49..8d20642af 100644 --- a/src/fractalzoomer/core/la/LAInfoBase.java +++ b/src/fractalzoomer/core/la/LAInfoBase.java @@ -1,15 +1,14 @@ package fractalzoomer.core.la; -import fractalzoomer.core.Complex; -import fractalzoomer.core.GenericComplex; -import fractalzoomer.core.MantExp; -import fractalzoomer.core.MantExpComplex; +import fractalzoomer.core.*; import fractalzoomer.core.la.impl.LAInfo; import fractalzoomer.core.la.impl.LAInfoDeep; import fractalzoomer.core.la.impl_refindex.LAInfoDeepRI; import fractalzoomer.core.la.impl_refindex.LAInfoRI; import fractalzoomer.main.app_settings.ApproximationDefaultSettings; +import static fractalzoomer.core.la.LAReference.f; + public abstract class LAInfoBase extends GenericLAInfo { public static int DETECTION_METHOD = ApproximationDefaultSettings.DETECTION_METHOD; public static double Stage0PeriodDetectionThreshold = ApproximationDefaultSettings.Stage0PeriodDetectionThreshold; @@ -36,7 +35,7 @@ protected boolean Stage0DetectPeriod(MantExpComplex z) { } @Override - protected boolean Step(LAInfoRI out, int zRefIndex) throws InvalidCalculationException { + protected boolean Step(LAInfoRI out, int zRefIndex, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { return false; } @@ -46,42 +45,42 @@ protected boolean isLAThresholdZero() { } @Override - protected boolean Composite(LAInfoRI out, LAInfoRI LA) throws InvalidCalculationException { + protected boolean Composite(LAInfoRI out, LAInfoRI LA, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { return false; } @Override - protected boolean Composite(LAInfoDeep out, LAInfoDeep LA) { + protected boolean Composite(LAInfoDeep out, LAInfoDeep LA, ReferenceDecompressor referenceDecompressor) { return false; } @Override - protected boolean Composite(LAInfoDeepRI out, LAInfoDeepRI LA) { + protected boolean Composite(LAInfoDeepRI out, LAInfoDeepRI LA, ReferenceDecompressor referenceDecompressor) { return false; } @Override - protected boolean Step(LAInfoDeep out, int zRefIndex) { + protected boolean Step(LAInfoDeep out, int zRefIndex, ReferenceDecompressor referenceDecompressor) { return false; } @Override - protected boolean Step(LAInfoDeepRI out, int zRefIndex) { + protected boolean Step(LAInfoDeepRI out, int zRefIndex, ReferenceDecompressor referenceDecompressor) { return false; } @Override - protected GenericLAInfo Composite(LAInfoRI LA) throws InvalidCalculationException { + protected GenericLAInfo Composite(LAInfoRI LA, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { return null; } @Override - protected GenericLAInfo Composite(LAInfoDeep LA) { + protected GenericLAInfo Composite(LAInfoDeep LA, ReferenceDecompressor referenceDecompressor) { return null; } @Override - protected GenericLAInfo Composite(LAInfoDeepRI LA) { + protected GenericLAInfo Composite(LAInfoDeepRI LA, ReferenceDecompressor referenceDecompressor) { return null; } @@ -106,17 +105,17 @@ public double dgetLAThresholdC() { } @Override - protected boolean Step(LAInfo out, int zRefIndex) throws InvalidCalculationException { + protected boolean Step(LAInfo out, int zRefIndex, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { return false; } @Override - protected GenericLAInfo Composite(LAInfo LA) throws InvalidCalculationException { + protected GenericLAInfo Composite(LAInfo LA, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { return null; } @Override - protected boolean Composite(LAInfo out, LAInfo LA) throws InvalidCalculationException { + protected boolean Composite(LAInfo out, LAInfo LA, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { return false; } @@ -198,12 +197,12 @@ public static ATInfo CreateAT(GenericLAInfo Next, Complex ZCoeff, Complex CCoeff Result.CCoeffInvZCoeff = Result.CCoeff.times(Result.InvZCoeff); Result.CCoeffInvZCoeff.Normalize(); - Result.RefC = Next.getRef().toMantExpComplex().times(zCm); + Result.RefC = Next.getRef(f).toMantExpComplex().times(zCm); Result.RefC.Normalize(); Result.SqrEscapeRadius = MantExp.minBothPositive(zCm.norm_squared().multiply(LAThreshold), atLimit).toDouble(); - Result.ThresholdC = MantExp.minBothPositive(new MantExp(LAThresholdC), atLimit.divide(Result.CCoeff.chebychevNorm())); + Result.ThresholdC = MantExp.minBothPositive(new MantExp(LAThresholdC), atLimit.divide(Result.CCoeff.chebyshevNorm())); Result.ThresholdC.Normalize(); return Result; @@ -211,12 +210,12 @@ public static ATInfo CreateAT(GenericLAInfo Next, Complex ZCoeff, Complex CCoeff @Override protected boolean Stage0DetectPeriod(Complex z) { - return z.chebychevNorm() / new Complex(ZCoeffRe, ZCoeffIm).chebychevNorm() * LAThresholdScale < LAThreshold * Stage0PeriodDetectionThreshold; + return z.chebyshevNorm() / new Complex(ZCoeffRe, ZCoeffIm).chebyshevNorm() * LAThresholdScale < LAThreshold * Stage0PeriodDetectionThreshold; } @Override protected boolean DetectPeriod(Complex z) { - return z.chebychevNorm() / new Complex(ZCoeffRe, ZCoeffIm).chebychevNorm() * LAThresholdScale < LAThreshold * PeriodDetectionThreshold; + return z.chebyshevNorm() / new Complex(ZCoeffRe, ZCoeffIm).chebyshevNorm() * LAThresholdScale < LAThreshold * PeriodDetectionThreshold; } diff --git a/src/fractalzoomer/core/la/LAInfoBaseDeep.java b/src/fractalzoomer/core/la/LAInfoBaseDeep.java index 90fe5641d..5f7363d58 100644 --- a/src/fractalzoomer/core/la/LAInfoBaseDeep.java +++ b/src/fractalzoomer/core/la/LAInfoBaseDeep.java @@ -1,15 +1,13 @@ package fractalzoomer.core.la; -import fractalzoomer.core.Complex; -import fractalzoomer.core.GenericComplex; -import fractalzoomer.core.MantExp; -import fractalzoomer.core.MantExpComplex; +import fractalzoomer.core.*; import fractalzoomer.core.la.impl.LAInfo; import fractalzoomer.core.la.impl.LAInfoDeep; import fractalzoomer.core.la.impl_refindex.LAInfoDeepRI; import fractalzoomer.core.la.impl_refindex.LAInfoRI; import static fractalzoomer.core.la.LAInfoBase.atLimit; +import static fractalzoomer.core.la.LAReference.f; public abstract class LAInfoBaseDeep extends GenericLAInfo { @@ -53,32 +51,32 @@ public double dgetLAThresholdC() { } @Override - protected GenericLAInfo Composite(LAInfoDeepRI LA) { + protected GenericLAInfo Composite(LAInfoDeepRI LA, ReferenceDecompressor referenceDecompressor) { return null; } @Override - protected boolean Composite(LAInfo out, LAInfo LA) { + protected boolean Composite(LAInfo out, LAInfo LA, ReferenceDecompressor referenceDecompressor) { return false; } @Override - protected boolean Composite(LAInfoRI out, LAInfoRI LA) throws InvalidCalculationException { + protected boolean Composite(LAInfoRI out, LAInfoRI LA, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { return false; } @Override - protected boolean Step(LAInfoDeepRI out, int zRefIndex) { + protected boolean Step(LAInfoDeepRI out, int zRefIndex, ReferenceDecompressor referenceDecompressor) { return false; } @Override - protected boolean Step(LAInfo out, int zRefIndex) throws InvalidCalculationException { + protected boolean Step(LAInfo out, int zRefIndex, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { return false; } @Override - protected boolean Step(LAInfoRI out, int zRefIndex) throws InvalidCalculationException { + protected boolean Step(LAInfoRI out, int zRefIndex, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { return false; } @@ -98,43 +96,43 @@ protected boolean Stage0DetectPeriod(Complex z) { } @Override - protected boolean Composite(LAInfoDeepRI out, LAInfoDeepRI LA) { + protected boolean Composite(LAInfoDeepRI out, LAInfoDeepRI LA, ReferenceDecompressor referenceDecompressor) { return false; } @Override - protected GenericLAInfo Composite(LAInfo LA) { + protected GenericLAInfo Composite(LAInfo LA, ReferenceDecompressor referenceDecompressor) { return null; } @Override - protected GenericLAInfo Composite(LAInfoRI LA) throws InvalidCalculationException { + protected GenericLAInfo Composite(LAInfoRI LA, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { return null; } @Override - protected boolean Step(LAInfoDeep out, int zRefIndex) { + protected boolean Step(LAInfoDeep out, int zRefIndex, ReferenceDecompressor referenceDecompressor) { return false; } @Override - protected GenericLAInfo Composite(LAInfoDeep LA) { + protected GenericLAInfo Composite(LAInfoDeep LA, ReferenceDecompressor referenceDecompressor) { return null; } @Override - protected boolean Composite(LAInfoDeep out, LAInfoDeep LA) { + protected boolean Composite(LAInfoDeep out, LAInfoDeep LA, ReferenceDecompressor referenceDecompressor) { return false; } @Override protected boolean DetectPeriod(MantExpComplex z) { - return z.chebychevNorm().divide(new MantExpComplex(ZCoeffExp, ZCoeffRe, ZCoeffIm).chebychevNorm()).multiply_mutable(LAThresholdScale).compareToBothPositive(new MantExp(LAThresholdExp, LAThresholdMant).multiply(PeriodDetectionThreshold)) < 0; + return z.chebyshevNorm().divide(new MantExpComplex(ZCoeffExp, ZCoeffRe, ZCoeffIm).chebyshevNorm()).multiply_mutable(LAThresholdScale).compareToBothPositive(new MantExp(LAThresholdExp, LAThresholdMant).multiply(PeriodDetectionThreshold)) < 0; } @Override protected boolean Stage0DetectPeriod(MantExpComplex z) { - return z.chebychevNorm().divide(new MantExpComplex(ZCoeffExp, ZCoeffRe, ZCoeffIm).chebychevNorm()).multiply_mutable(LAThresholdScale).compareToBothPositive(new MantExp(LAThresholdExp, LAThresholdMant).multiply(Stage0PeriodDetectionThreshold)) < 0; + return z.chebyshevNorm().divide(new MantExpComplex(ZCoeffExp, ZCoeffRe, ZCoeffIm).chebyshevNorm()).multiply_mutable(LAThresholdScale).compareToBothPositive(new MantExp(LAThresholdExp, LAThresholdMant).multiply(Stage0PeriodDetectionThreshold)) < 0; } @Override @@ -190,12 +188,12 @@ public static ATInfo CreateAT(GenericLAInfo Next, MantExpComplex ZCoeff, MantExp Result.CCoeffInvZCoeff = Result.CCoeff.times(Result.InvZCoeff); Result.CCoeffInvZCoeff.Normalize(); - Result.RefC = Next.getRef().toMantExpComplex().times(ZCoeff); + Result.RefC = Next.getRef(f).toMantExpComplex().times(ZCoeff); Result.RefC.Normalize(); Result.SqrEscapeRadius = MantExp.minBothPositive(ZCoeff.norm_squared().multiply(LAThreshold), atLimit).toDouble(); - Result.ThresholdC = MantExp.minBothPositive(LAThresholdC, atLimit.divide(Result.CCoeff.chebychevNorm())); + Result.ThresholdC = MantExp.minBothPositive(LAThresholdC, atLimit.divide(Result.CCoeff.chebyshevNorm())); return Result; } diff --git a/src/fractalzoomer/core/la/LAReference.java b/src/fractalzoomer/core/la/LAReference.java index c4838ad22..923961b84 100644 --- a/src/fractalzoomer/core/la/LAReference.java +++ b/src/fractalzoomer/core/la/LAReference.java @@ -5,7 +5,12 @@ import fractalzoomer.functions.Fractal; import fractalzoomer.main.app_settings.ApproximationDefaultSettings; + +import java.util.ArrayList; import java.util.Arrays; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; +import java.util.stream.IntStream; class LAStageInfo { int LAIndex; @@ -20,7 +25,7 @@ public LAInfoI() { StepLength = 0; NextStageLAIndex = 0; } -}; +} class LAData { public GenericLAInfo la; @@ -40,18 +45,33 @@ void invalidateInfo() { StepLength = -1; NextStageLAIndex = -1; } + + @Override + public String toString() { + String res = ""; + if(la != null) { + res += la.toString(); + } + res += StepLength + "\n"; + res += NextStageLAIndex + "\n"; + return res; + } } public class LAReference { public static boolean CONVERT_TO_DOUBLE_WHEN_POSSIBLE = false; - private static final int lowBound = 64; - private static final double log16 = Math.log(16); + private static final int lowBound = ApproximationDefaultSettings.lowBound; + public static double periodDivisor = ApproximationDefaultSettings.PeriodDivisor; private static final MantExp doubleRadiusLimit = new MantExp(0x1.0p-896); public static MantExp doubleThresholdLimit = new MantExp(ApproximationDefaultSettings.DoubleThresholdLimit); + public static int NthRootOption = ApproximationDefaultSettings.NthRootOption; public boolean UseAT; + public static Fractal f; + public static ReferenceDecompressor referenceDecompressor; + public ATInfo AT; public int LAStageCount; @@ -64,8 +84,12 @@ public class LAReference { private static final int MaxLAStages = 512; private static final int DEFAULT_SIZE = 131072; + private static final int DEFAULT_SIZE_THREAD = 4096; private LAData[] LAs; + private LAData[][] LAsPerThread; + private LAData[] LastLAPerThread; + private int[] LAcurrentIndexPerThread; private int LAcurrentIndex; private LAStageInfo[] LAStages; @@ -101,7 +125,31 @@ private void addToLA(LAData laData) throws Exception { } } - private int LAsize() { + private void addToLA(LAData laData, int threadId) throws Exception { + int currentLaIndex = LAcurrentIndexPerThread[threadId]; + LAsPerThread[threadId][currentLaIndex] = laData; + currentLaIndex++; + LAcurrentIndexPerThread[threadId] = currentLaIndex; + + if (currentLaIndex >= LAsPerThread[threadId].length) { + long newLen = ((long) LAsPerThread[threadId].length) << 1; + if(newLen > (long)Integer.MAX_VALUE) { + throw new Exception("No space"); + } + LAsPerThread[threadId] = Arrays.copyOf(LAsPerThread[threadId], (int)newLen); + } + } + + private void popLA(int threadId) { + int currentLaIndex = LAcurrentIndexPerThread[threadId]; + if(currentLaIndex > 0) { + currentLaIndex--; + LAcurrentIndexPerThread[threadId] = currentLaIndex; + LAsPerThread[threadId][currentLaIndex] = null; + } + } + + public int LAsize() { return LAcurrentIndex; } @@ -112,7 +160,29 @@ private void popLA() { } } - private boolean CreateLAFromOrbit(DoubleReference ref, DeepReference refDeep, int maxRefIteration, boolean deepZoom) throws Exception { + private int getNthRoot(double val) { + if(NthRootOption == 0) {//Original + double NthRoot = Math.round(log2(val) / 4.0); + NthRoot = NthRoot < 1 ? 1 : NthRoot; + return (int)Math.round(Math.pow(val, 1.0 / NthRoot)); + } + + double NthRoot = log2(val) / periodDivisor; + NthRoot = NthRoot < 1 ? 1 : NthRoot; + return (int)Math.round(Math.pow(val, 1.0 / NthRoot)); + } + + private boolean CreateLAFromOrbit(DoubleReference ref, DeepReference refDeep, int maxRefIteration, boolean deepZoom, Fractal f) throws Exception { + + LAReference.f = f; + + if((deepZoom && refDeep.compressed) || (!deepZoom && ref.compressed)) { + if (deepZoom) { + referenceDecompressor = f.getReferenceDecompressors()[refDeep.id]; + } else { + referenceDecompressor = f.getReferenceDecompressors()[ref.id]; + } + } init(deepZoom); @@ -120,18 +190,7 @@ private boolean CreateLAFromOrbit(DoubleReference ref, DeepReference refDeep, in GenericLAInfo LA; - if(deepZoom) { - GenericLAInfo.refExpRe = refDeep.exps; - GenericLAInfo.refExpIm = refDeep.expsIm; - GenericLAInfo.refMantsRe = refDeep.mantsRe; - GenericLAInfo.refMantsIm = refDeep.mantsIm; - } - else { - GenericLAInfo.refRe = ref.re; - GenericLAInfo.refIm = ref.im; - } - - LA = GenericLAInfo.create(maxRefIteration, deepZoom, 0).Step(1); + LA = GenericLAInfo.create(maxRefIteration, deepZoom, 0, referenceDecompressor).Step(1, referenceDecompressor); LAInfoI LAI = new LAInfoI(); LAI.NextStageLAIndex = 0; @@ -145,7 +204,7 @@ private boolean CreateLAFromOrbit(DoubleReference ref, DeepReference refDeep, in GenericLAInfo NewLA = GenericLAInfo.create(maxRefIteration, deepZoom); - boolean PeriodDetected = LA.Step(NewLA, i); + boolean PeriodDetected = LA.Step(NewLA, i, referenceDecompressor); if (PeriodDetected) { Period = i; @@ -159,12 +218,14 @@ private boolean CreateLAFromOrbit(DoubleReference ref, DeepReference refDeep, in LAI.NextStageLAIndex = i; - if (i + 1 < maxRefIteration) { - LA = GenericLAInfo.create(maxRefIteration, deepZoom, i).Step(i + 1); - i += 2; + int ip1 = i + 1; + + if (ip1 >= maxRefIteration) { + LA = GenericLAInfo.create(maxRefIteration, deepZoom, i, referenceDecompressor); + i++; } else { - LA = GenericLAInfo.create(maxRefIteration, deepZoom, i); - i += 1; + LA = GenericLAInfo.create(maxRefIteration, deepZoom, i, referenceDecompressor).Step(ip1, referenceDecompressor); + i += 2; } break; } @@ -178,12 +239,11 @@ private boolean CreateLAFromOrbit(DoubleReference ref, DeepReference refDeep, in if (Period == 0) { if (maxRefIteration > lowBound) { - LA = GenericLAInfo.create(maxRefIteration, deepZoom, 0).Step(1); + LA = GenericLAInfo.create(maxRefIteration, deepZoom, 0, referenceDecompressor).Step(1, referenceDecompressor); LAI.NextStageLAIndex = 0; i = 2; - double NthRoot = Math.round(Math.log(maxRefIteration) / log16); - Period = (int)Math.round(Math.pow(maxRefIteration, 1.0 / NthRoot)); + Period = getNthRoot(maxRefIteration); PeriodBegin = 0; PeriodEnd = Period; @@ -196,7 +256,7 @@ private boolean CreateLAFromOrbit(DoubleReference ref, DeepReference refDeep, in addToLA(laData); laData = new LAData(); - laData.la = GenericLAInfo.create(maxRefIteration, deepZoom, maxRefIteration); + laData.la = GenericLAInfo.create(maxRefIteration, deepZoom, maxRefIteration, referenceDecompressor); laData.invalidateInfo(); addToLA(laData); @@ -207,12 +267,11 @@ private boolean CreateLAFromOrbit(DoubleReference ref, DeepReference refDeep, in } else if (Period > lowBound) { popLA(); - LA = GenericLAInfo.create(maxRefIteration, deepZoom, 0).Step(1); + LA = GenericLAInfo.create(maxRefIteration, deepZoom, 0, referenceDecompressor).Step(1, referenceDecompressor); LAI.NextStageLAIndex = 0; i = 2; - double NthRoot = Math.round(Math.log(Period) / log16); - Period = (int)Math.round(Math.pow(Period, 1.0 / NthRoot)); + Period = getNthRoot(Period); PeriodBegin = 0; PeriodEnd = Period; @@ -220,7 +279,7 @@ private boolean CreateLAFromOrbit(DoubleReference ref, DeepReference refDeep, in for (; i < maxRefIteration; i++) { GenericLAInfo NewLA = GenericLAInfo.create(maxRefIteration, deepZoom); - boolean PeriodDetected = LA.Step(NewLA, i); + boolean PeriodDetected = LA.Step(NewLA, i, referenceDecompressor); if (PeriodDetected || i >= PeriodEnd) { LAI.StepLength = i - PeriodBegin; @@ -240,16 +299,16 @@ private boolean CreateLAFromOrbit(DoubleReference ref, DeepReference refDeep, in boolean detected; if(deepZoom) { - detected = NewLA.DetectPeriod(Fractal.getArrayDeepValue(refDeep, ip1)); + detected = NewLA.DetectPeriod(f.getArrayDeepValue(referenceDecompressor, refDeep, ip1)); } else { - detected = NewLA.DetectPeriod(Fractal.getArrayValue(ref, ip1)); + detected = NewLA.DetectPeriod(f.getArrayValue(referenceDecompressor, ref, ip1)); } if (detected || ip1 >= maxRefIteration) { - LA = GenericLAInfo.create(maxRefIteration, deepZoom, i); + LA = GenericLAInfo.create(maxRefIteration, deepZoom, i, referenceDecompressor); } else { - LA = GenericLAInfo.create(maxRefIteration, deepZoom, i).Step(ip1); + LA = GenericLAInfo.create(maxRefIteration, deepZoom, i, referenceDecompressor).Step(ip1, referenceDecompressor); i++; } } else { @@ -267,23 +326,521 @@ private boolean CreateLAFromOrbit(DoubleReference ref, DeepReference refDeep, in LAStages[0].MacroItCount = LAsize(); laData = new LAData(); - laData.la = GenericLAInfo.create(maxRefIteration, deepZoom, maxRefIteration); + laData.la = GenericLAInfo.create(maxRefIteration, deepZoom, maxRefIteration, referenceDecompressor); addToLA(laData); return true; } + private int i; + private int PeriodBegin; + private int PeriodEnd; + private GenericLAInfo LA; + + private int Period; + private volatile Exception[] exceptions; + private CompletableFuture[] StartIndex; + + private volatile int[] FinishIndex; + private int ThreadCount; + + private boolean CreateLAFromOrbit_MT(DoubleReference ref, DeepReference refDeep, int maxRefIteration, boolean deepZoom, Fractal f) throws Exception { + + int WorkThreshholdForThreads = 50000; + int MaxThreadCount = TaskDraw.la_thread_executor.getCorePoolSize(); + + ThreadCount = maxRefIteration / WorkThreshholdForThreads; + + if (ThreadCount > MaxThreadCount) { + ThreadCount = MaxThreadCount; + } + else if (ThreadCount == 0) { + ThreadCount = 1; + } + + if(ThreadCount == 1) { + return CreateLAFromOrbit(ref, refDeep, maxRefIteration, deepZoom , f); + } + + LAReference.f = f; + + if((deepZoom && refDeep.compressed) || (!deepZoom && ref.compressed)) { + if (deepZoom) { + referenceDecompressor = f.getReferenceDecompressors()[refDeep.id]; + } else { + referenceDecompressor = f.getReferenceDecompressors()[ref.id]; + } + } + + init(deepZoom); + + Period = 0; + + + LA = GenericLAInfo.create(maxRefIteration, deepZoom, 0, referenceDecompressor).Step(1, referenceDecompressor); - private boolean CreateNewLAStage(int maxRefIteration, boolean deepZoom) throws Exception { + LAInfoI LAI = new LAInfoI(); + LAI.NextStageLAIndex = 0; + + if(LA.isZCoeffZero()) { + return false; + } + + for (i = 2; i < maxRefIteration; i++) { + + GenericLAInfo NewLA = GenericLAInfo.create(maxRefIteration, deepZoom); + + boolean PeriodDetected = LA.Step(NewLA, i, referenceDecompressor); + + if (PeriodDetected) { + Period = i; + LAI.StepLength = Period; + + LAData laData = new LAData(); + laData.la = LA; + laData.setInfo(LAI); + + addToLA(laData); + + LAI.NextStageLAIndex = i; + + int ip1 = i + 1; + + if (ip1 >= maxRefIteration) { + LA = GenericLAInfo.create(maxRefIteration, deepZoom, i, referenceDecompressor); + i++; + } else { + LA = GenericLAInfo.create(maxRefIteration, deepZoom, i, referenceDecompressor).Step(ip1, referenceDecompressor); + i += 2; + } + break; + } + LA = NewLA; + } + + LAStageCount = 1; + + PeriodBegin = Period; + PeriodEnd = PeriodBegin + Period; + + if (Period == 0) { + if (maxRefIteration > lowBound) { + LA = GenericLAInfo.create(maxRefIteration, deepZoom, 0, referenceDecompressor).Step(1, referenceDecompressor); + LAI.NextStageLAIndex = 0; + i = 2; + + Period = getNthRoot(maxRefIteration); + + PeriodBegin = 0; + PeriodEnd = Period; + } else { + LAI.StepLength = maxRefIteration; + + LAData laData = new LAData(); + laData.la = LA; + laData.setInfo(LAI); + addToLA(laData); + + laData = new LAData(); + laData.la = GenericLAInfo.create(maxRefIteration, deepZoom, maxRefIteration, referenceDecompressor); + laData.invalidateInfo(); + addToLA(laData); + + LAStages[0].MacroItCount = 1; + + return false; + } + } else if (Period > lowBound) { + popLA(); + + LA = GenericLAInfo.create(maxRefIteration, deepZoom, 0, referenceDecompressor).Step(1, referenceDecompressor); + LAI.NextStageLAIndex = 0; + i = 2; + + Period = getNthRoot(Period); + + PeriodBegin = 0; + PeriodEnd = Period; + } + + Runnable[] Tasks = new Runnable[ThreadCount]; + StartIndex = new CompletableFuture[ThreadCount]; + + exceptions = new Exception[ThreadCount]; + LAsPerThread = new LAData[ThreadCount][DEFAULT_SIZE_THREAD]; + LastLAPerThread = new LAData[ThreadCount]; + LAcurrentIndexPerThread = new int[ThreadCount]; + FinishIndex = new int[ThreadCount]; + + for(int i = 0; i < ThreadCount; i++) { + StartIndex[i] = new CompletableFuture<>(); + } + + ArrayList> futures = new ArrayList<>(); + + ReferenceDecompressor[] referenceDecompressors = new ReferenceDecompressor[ThreadCount]; + if(referenceDecompressor != null) { + for (int i = 0; i < referenceDecompressors.length; i++) { + referenceDecompressors[i] = new ReferenceDecompressor(referenceDecompressor); + } + } + + Tasks[0] = new Runnable() { + int ThreadID = 0; + @Override + public void run() { + try { + int threadBoundary = maxRefIteration / ThreadCount; + int nextThread = ThreadID + 1; + int prevStart = 0; + ReferenceDecompressor referenceDecompressor = referenceDecompressors[ThreadID]; + + for (; i < maxRefIteration; i++) { + GenericLAInfo NewLA = GenericLAInfo.create(maxRefIteration, deepZoom); + boolean PeriodDetected = LA.Step(NewLA, i, referenceDecompressor); + + if (PeriodDetected || i >= PeriodEnd) { + LAI.StepLength = i - PeriodBegin; + + LAData laData = new LAData(); + laData.la = LA; + laData.setInfo(LAI); + + addToLA(laData); + + LAI.NextStageLAIndex = i; + PeriodBegin = i; + PeriodEnd = PeriodBegin + Period; + + int ip1 = i + 1; + + boolean detected; + + if (deepZoom) { + detected = NewLA.DetectPeriod(f.getArrayDeepValue(referenceDecompressor, refDeep, ip1)); + } else { + detected = NewLA.DetectPeriod(f.getArrayValue(referenceDecompressor, ref, ip1)); + } + + if (detected || ip1 >= maxRefIteration) { + LA = GenericLAInfo.create(maxRefIteration, deepZoom, i, referenceDecompressor); + } else { + LA = GenericLAInfo.create(maxRefIteration, deepZoom, i, referenceDecompressor).Step(ip1, referenceDecompressor); + i++; + } + + if (i > threadBoundary) { + + if(i >= maxRefIteration) { + break; + } + + if(nextThread < StartIndex.length) { + int nextStart = StartIndex[nextThread].get(); + + if (nextStart < 0) { //The next tread had an exception + return; + } + + if (i == nextStart - 1) { + i++; + break; + } else if (i >= nextStart) { + //throw new Exception("Thread( " + ThreadID + " ) error " + i + " >= " + nextStart); +// if(prevStart != nextStart) { +// System.out.println("Thread( " + ThreadID + " ) error " + i + " >= " + nextStart); +// } +// prevStart = nextStart; + nextThread++; + } + } + } + } else { + LA = NewLA; + } + } + + FinishIndex[ThreadID] = i; + + LAI.StepLength = i - PeriodBegin; + + LAData laData = new LAData(); + laData.la = LA; + laData.setInfo(LAI); + + LastLAPerThread[ThreadID] = laData; + } + catch (Exception ex) { + exceptions[ThreadID] = ex; + StartIndex[ThreadID].complete(-1); + FinishIndex[ThreadID] = -1; + } + } + }; + + for(int i = 1; i < Tasks.length; i++) { + final int id = i; + Tasks[i] = new Runnable() { + int ThreadID = id; + @Override + public void run() { + try { + ReferenceDecompressor referenceDecompressor = referenceDecompressors[ThreadID]; + int LastThread = ThreadCount - 1; + int nextThread = ThreadID + 1; + int Begin = (int)((long)maxRefIteration * ThreadID / ThreadCount); + int End = (int)((long)maxRefIteration * (ThreadID + 1) / ThreadCount); + int prevStart = 0; + + int j = Begin; + + LAInfoI LAI_ = new LAInfoI(); + LAI_.NextStageLAIndex = j; + + GenericLAInfo LA_2 = GenericLAInfo.create(maxRefIteration, deepZoom, j, referenceDecompressor); + LA_2 = LA_2.Step(j + 1, referenceDecompressor); + int j2 = j + 2; + + GenericLAInfo LA_ = GenericLAInfo.create(maxRefIteration, deepZoom, j - 1, referenceDecompressor); + LA_ = LA_.Step(j, referenceDecompressor); + int j1 = j + 1; + + + int PeriodBegin = 0; + int PeriodEnd = 0; + boolean PeriodDetected2 = false; + boolean PeriodDetected = false; + + for (; j2 < maxRefIteration || j1 < maxRefIteration; j1++, j2++) { + GenericLAInfo NewLA = GenericLAInfo.create(maxRefIteration, deepZoom); + PeriodDetected = LA_.Step(NewLA, j1, referenceDecompressor); + + if(PeriodDetected) { + LAI_.NextStageLAIndex = j1; + PeriodBegin = j1; + PeriodEnd = PeriodBegin + Period; + + int jp1 = j1 + 1; + + if (jp1 >= maxRefIteration) { + LA_ = GenericLAInfo.create(maxRefIteration, deepZoom, j1, referenceDecompressor); + j1++; + } else { + LA_ = GenericLAInfo.create(maxRefIteration, deepZoom, j1, referenceDecompressor).Step(jp1, referenceDecompressor); + j1 += 2; + } + break; + } + + LA_ = NewLA; + + if(j2 < maxRefIteration) { + GenericLAInfo NewLA2 = GenericLAInfo.create(maxRefIteration, deepZoom); + PeriodDetected2 = LA_2.Step(NewLA2, j2, referenceDecompressor); + + if (PeriodDetected2) { + LAI_.NextStageLAIndex = j2; + PeriodBegin = j2; + PeriodEnd = PeriodBegin + Period; + + int jp1 = j2 + 1; + + if (jp1 >= maxRefIteration) { + LA_2 = GenericLAInfo.create(maxRefIteration, deepZoom, j2, referenceDecompressor); + j2++; + } else { + LA_2 = GenericLAInfo.create(maxRefIteration, deepZoom, j2, referenceDecompressor).Step(jp1, referenceDecompressor); + j2 += 2; + } + break; + } + + LA_2 = NewLA2; + } + + } + + if(PeriodDetected2) { + LA_ = LA_2; + j = j2; + } + else if(PeriodDetected) { + j = j1; + } + else { + j = maxRefIteration; + } + + //Just for protection + if(ThreadID == LastThread || (j >= Begin && j < End)) { + StartIndex[ThreadID].complete(j); + } + else { + int nextStart = StartIndex[nextThread].get(); + + if(nextStart < 0) { + return; + } + + StartIndex[ThreadID].complete(nextStart); //Abort the current thread and leave its task to the previous + FinishIndex[ThreadID] = -1; + return; + } + + for (; j < maxRefIteration; j++) { + GenericLAInfo NewLA = GenericLAInfo.create(maxRefIteration, deepZoom); + PeriodDetected = LA_.Step(NewLA, j, referenceDecompressor); + + if(PeriodDetected || j >= PeriodEnd) { + LAI_.StepLength = j - PeriodBegin; + + LAData laData = new LAData(); + laData.la = LA_; + laData.setInfo(LAI_); + addToLA(laData, ThreadID); + + LAI_.NextStageLAIndex = j; + PeriodBegin = j; + PeriodEnd = PeriodBegin + Period; + + int jp1 = j + 1; + + boolean detected; + + if(deepZoom) { + detected = NewLA.DetectPeriod(f.getArrayDeepValue(referenceDecompressor, refDeep, jp1)); + } + else { + detected = NewLA.DetectPeriod(f.getArrayValue(referenceDecompressor, ref, jp1)); + } + + if (detected || jp1 >= maxRefIteration) { + LA_ = GenericLAInfo.create(maxRefIteration, deepZoom, j, referenceDecompressor); + } else { + LA_ = GenericLAInfo.create(maxRefIteration, deepZoom, j, referenceDecompressor).Step(jp1, referenceDecompressor); + j++; + } + + if (j > End) { + if (ThreadID == LastThread) throw new Exception("Last Thread cannot reach this"); + + if(j >= maxRefIteration) { + break; + } + + if(nextThread < StartIndex.length) { + int nextStart = StartIndex[nextThread].get(); + + if (nextStart < 0) { //The next tread had an exception + return; + } + + if (j == nextStart - 1) { + j++; + break; + } else if (j >= nextStart) { + //throw new Exception("Thread( " +ThreadID + " ) error " + j + " >= " + nextStart); +// if(prevStart != nextStart) { +// System.out.println("Thread( " + ThreadID + " ) error " + j + " >= " + nextStart); +// } +// prevStart = nextStart; + nextThread++; + } + } + } + } + else { + LA_ = NewLA; + } + } + + FinishIndex[ThreadID] = j; + + LAI_.StepLength = j - PeriodBegin; + + LAData laData = new LAData(); + laData.la = LA_; + laData.setInfo(LAI_); + + LastLAPerThread[ThreadID] = laData; + } + catch (Exception ex) { + exceptions[ThreadID] = ex; + StartIndex[ThreadID].complete(-1); + FinishIndex[ThreadID] = -1; + } + } + }; + } + + for(int i = 0; i < Tasks.length; i++) { + futures.add(TaskDraw.la_thread_executor.submit(Tasks[i])); + } + + for(int i = 0; i < futures.size(); i++) { + futures.get(i).get(); + } + + for(int i = 0; i < Tasks.length; i++) { + if(exceptions[i] != null) { + throw exceptions[i]; + } + } + + + { + int lastThreadToAdd = 0; + + int i = 0; + int j = i; + while (i < Tasks.length - 1 && FinishIndex[j] > StartIndex[i + 1].get()) { + i++; //Skip, if there is a missalignment + } + i++; + + for (; i < Tasks.length; i++) { + int length = LAcurrentIndexPerThread[i]; + LAData[] threadData = LAsPerThread[i]; + for (int k = 0; k < length; k++) { + addToLA(threadData[k]); + } + + if(FinishIndex[i] > StartIndex[i].get()) { //If this thread managed to search + lastThreadToAdd = i; + } + + j = i; + while (i < Tasks.length - 1 && FinishIndex[j] > StartIndex[i + 1].get()) { + i++; //Skip, if there is a missalignment + } + } + + addToLA(LastLAPerThread[lastThreadToAdd]); + } + + LAsPerThread = null; + LAcurrentIndexPerThread = null; + LastLAPerThread = null; + + LAStages[0].MacroItCount = LAsize(); + + LAData laData = new LAData(); + laData.la = GenericLAInfo.create(maxRefIteration, deepZoom, maxRefIteration, referenceDecompressor); + + addToLA(laData); + + return true; + } + + + private boolean CreateNewLAStage(int maxRefIteration, boolean deepZoom, int PrevStage, int CurrentStage) throws Exception { GenericLAInfo LA; LAInfoI LAI = new LAInfoI(); int i; int PeriodBegin; int PeriodEnd; - int PrevStage = LAStageCount - 1; - int CurrentStage = LAStageCount; int PrevStageLAIndex = LAStages[PrevStage].LAIndex; int PrevStageMacroItCount = LAStages[PrevStage].MacroItCount; @@ -301,7 +858,7 @@ private boolean CreateNewLAStage(int maxRefIteration, boolean deepZoom) throws E LAStages[CurrentStage].UseDoublePrecision = !deepZoom; LAStages[CurrentStage].LAIndex = LAsize(); - LA = PrevStageLA.Composite(PrevStageLAp1); + LA = PrevStageLA.Composite(PrevStageLAp1, referenceDecompressor); LAI.NextStageLAIndex = 0; i = prevLaData.StepLength + prevLaDataP1.StepLength; int j; @@ -312,7 +869,7 @@ private boolean CreateNewLAStage(int maxRefIteration, boolean deepZoom) throws E int PrevStageLAIndexj = PrevStageLAIndex + j; LAData prevLaDataj = LAs[PrevStageLAIndexj]; GenericLAInfo PrevStageLAj = prevLaDataj.la; - boolean PeriodDetected = LA.Composite(NewLA, PrevStageLAj); + boolean PeriodDetected = LA.Composite(NewLA, PrevStageLAj, referenceDecompressor); if (PeriodDetected) { if (PrevStageLAj.isLAThresholdZero()) break; @@ -332,12 +889,12 @@ private boolean CreateNewLAStage(int maxRefIteration, boolean deepZoom) throws E LAData prevLaDatajp1 = LAs[PrevStageLAIndexjp1]; GenericLAInfo PrevStageLAjp1 = prevLaDatajp1.la; - if (NewLA.DetectPeriod(PrevStageLAjp1.getRef()) || j + 1 >= PrevStageMacroItCount) { + if (NewLA.DetectPeriod(PrevStageLAjp1.getRef(f)) || j + 1 >= PrevStageMacroItCount) { LA = PrevStageLAj; i += prevLaDataj.StepLength; j++; } else { - LA = PrevStageLAj.Composite(PrevStageLAjp1); + LA = PrevStageLAj.Composite(PrevStageLAjp1, referenceDecompressor); i += prevLaDataj.StepLength + prevLaDatajp1.StepLength; j += 2; } @@ -354,15 +911,14 @@ private boolean CreateNewLAStage(int maxRefIteration, boolean deepZoom) throws E if (Period == 0) { if (maxRefIteration > prevLaData.StepLength * lowBound) { - LA = PrevStageLA.Composite(PrevStageLAp1); + LA = PrevStageLA.Composite(PrevStageLAp1, referenceDecompressor); i = prevLaData.StepLength + prevLaDataP1.StepLength; LAI.NextStageLAIndex = 0; j = 2; double Ratio = ((double)(maxRefIteration)) / prevLaData.StepLength; - double NthRoot = Math.round(Math.log(Ratio) / log16); // log16 - Period = prevLaData.StepLength * (int)Math.round(Math.pow(Ratio, 1.0 / NthRoot)); + Period = prevLaData.StepLength * getNthRoot(Ratio); PeriodBegin = 0; PeriodEnd = Period; @@ -376,7 +932,7 @@ private boolean CreateNewLAStage(int maxRefIteration, boolean deepZoom) throws E addToLA(laData); laData = new LAData(); - laData.la = GenericLAInfo.create(maxRefIteration, deepZoom, maxRefIteration); + laData.la = GenericLAInfo.create(maxRefIteration, deepZoom, maxRefIteration, referenceDecompressor); laData.invalidateInfo(); addToLA(laData); @@ -389,16 +945,14 @@ private boolean CreateNewLAStage(int maxRefIteration, boolean deepZoom) throws E else if (Period > prevLaData.StepLength * lowBound) { popLA(); - LA = PrevStageLA.Composite(PrevStageLAp1); + LA = PrevStageLA.Composite(PrevStageLAp1, referenceDecompressor); i = prevLaData.StepLength + prevLaDataP1.StepLength; LAI.NextStageLAIndex = 0; j = 2; double Ratio = ((double)(Period)) / prevLaData.StepLength; - - double NthRoot = Math.round(Math.log(Ratio) / log16); - Period = prevLaData.StepLength * ((int)Math.round(Math.pow(Ratio, 1.0 / NthRoot))); + Period = prevLaData.StepLength * getNthRoot(Ratio); PeriodBegin = 0; PeriodEnd = Period; @@ -411,7 +965,7 @@ else if (Period > prevLaData.StepLength * lowBound) { LAData prevLaDataj = LAs[PrevStageLAIndexj]; GenericLAInfo PrevStageLAj = prevLaDataj.la; - boolean PeriodDetected = LA.Composite(NewLA, PrevStageLAj); + boolean PeriodDetected = LA.Composite(NewLA, PrevStageLAj, referenceDecompressor); if (PeriodDetected || i >= PeriodEnd) { LAI.StepLength = i - PeriodBegin; @@ -428,10 +982,10 @@ else if (Period > prevLaData.StepLength * lowBound) { LAData prevLaDatajP1 = LAs[PrevStageLAIndexj + 1]; GenericLAInfo PrevStageLAjp1 = prevLaDatajP1.la; - if (NewLA.DetectPeriod(PrevStageLAjp1.getRef()) || j + 1 >= PrevStageMacroItCount) { + if (NewLA.DetectPeriod(PrevStageLAjp1.getRef(f)) || j + 1 >= PrevStageMacroItCount) { LA = PrevStageLAj; } else { - LA = PrevStageLAj.Composite(PrevStageLAjp1); + LA = PrevStageLAj.Composite(PrevStageLAjp1, referenceDecompressor); i += prevLaDataj.StepLength; j++; } @@ -452,7 +1006,7 @@ else if (Period > prevLaData.StepLength * lowBound) { LAStages[CurrentStage].MacroItCount = LAsize() - LAStages[CurrentStage].LAIndex; laData = new LAData(); - laData.la = GenericLAInfo.create(maxRefIteration, deepZoom, maxRefIteration); + laData.la = GenericLAInfo.create(maxRefIteration, deepZoom, maxRefIteration, referenceDecompressor); addToLA(laData); return true; @@ -460,10 +1014,21 @@ else if (Period > prevLaData.StepLength * lowBound) { private boolean DoubleUsableAtPrevStage(int stage, MantExp radius) { - LAStageInfo lasi = LAStages[stage]; - if(lasi != null) { + LAStageInfo lasi; + if(stage < LAStages.length && (lasi = LAStages[stage]) != null) { int LAIndex = lasi.LAIndex; - GenericLAInfo LA = LAs[LAIndex].la; + + LAData laData = LAs[LAIndex]; + + if(laData == null) { + return false; + } + GenericLAInfo LA = laData.la; + + if(LA == null) { + return false; + } + return radius.compareToBothPositiveReduced(doubleRadiusLimit) > 0 || (LA.getLAThreshold().compareToBothPositiveReduced(doubleThresholdLimit) > 0 && LA.getLAThresholdC().compareToBothPositiveReduced(doubleThresholdLimit) > 0); @@ -473,6 +1038,20 @@ private boolean DoubleUsableAtPrevStage(int stage, MantExp radius) { } + private void DismissStage(int Stage) { + int LAIndex = LAStages[Stage].LAIndex; + int length = LAsize() - LAIndex; + + for(int i = 0; i < length; i++) { + popLA(); + } + + LAStages[Stage] = null; + if(LAStageCount == Stage + 1) { + LAStageCount--; + } + } + public void GenerateApproximationData(MantExp radius, ReferenceData refData, ReferenceDeepData refDeepData, int maxRefIteration, boolean deepZoom, Fractal f) { try { @@ -483,10 +1062,16 @@ public void GenerateApproximationData(MantExp radius, ReferenceData refData, Ref boolean PeriodDetected; try { - PeriodDetected = CreateLAFromOrbit(refData.Reference, refDeepData.Reference, maxRefIteration, deepZoom); + if(TaskDraw.USE_THREADS_FOR_BLA2) { + PeriodDetected = CreateLAFromOrbit_MT(refData.Reference, refDeepData.Reference, maxRefIteration, deepZoom, f); + } + else { + PeriodDetected = CreateLAFromOrbit(refData.Reference, refDeepData.Reference, maxRefIteration, deepZoom, f); + } } catch (InvalidCalculationException ex) { - PeriodDetected = false; + DismissStage(0); + return; } if (!PeriodDetected) return; @@ -496,20 +1081,19 @@ public void GenerateApproximationData(MantExp radius, ReferenceData refData, Ref } boolean convertedToDouble = false; + boolean dismissedStage = false; while (true) { int PrevStage = LAStageCount - 1; int CurrentStage = LAStageCount; try { - PeriodDetected = CreateNewLAStage(maxRefIteration, deepZoom); - + PeriodDetected = CreateNewLAStage(maxRefIteration, deepZoom, PrevStage, CurrentStage); } catch (InvalidCalculationException ex) { - PeriodDetected = false; - } - catch (Exception ex) { - PeriodDetected = false; + DismissStage(CurrentStage); + dismissedStage = true; + break; } if (deepZoom && (!f.useFullFloatExp() || CONVERT_TO_DOUBLE_WHEN_POSSIBLE) && DoubleUsableAtPrevStage(CurrentStage, radius)) { @@ -523,7 +1107,7 @@ else if(LAInfo.DETECTION_METHOD == 1) { if (!PeriodDetected) break; } - if (deepZoom && (!f.useFullFloatExp() || CONVERT_TO_DOUBLE_WHEN_POSSIBLE) && DoubleUsableAtPrevStage(LAStageCount, radius)) { + if (deepZoom && !dismissedStage && (!f.useFullFloatExp() || CONVERT_TO_DOUBLE_WHEN_POSSIBLE) && DoubleUsableAtPrevStage(LAStageCount, radius)) { ConvertStageToDouble(LAStageCount - 1); convertedToDouble = true; } @@ -536,9 +1120,6 @@ else if(LAInfo.DETECTION_METHOD == 1) { //Recreate data to save memory if (deepZoom && (refData.Reference == null || refData.Reference.dataLength() != maxRefIteration + 1) && (convertedToDouble || performDoublePrecisionSimplePerturbation)) { f.createLowPrecisionOrbit(maxRefIteration + 1, refData, refDeepData); - - GenericLAInfo.refRe = refData.Reference.re; - GenericLAInfo.refIm = refData.Reference.im; } } catch (Exception ex) { @@ -576,8 +1157,15 @@ void ConvertStageToDouble(int Stage) { LAStages[Stage].UseDoublePrecision = true; int length = LAIndex + MacroItCount; - for (int i = LAIndex; i <= length; i++) { - LAs[i].la = LAs[i].la.toDouble(); + + if(TaskDraw.USE_THREADS_FOR_BLA2) { + IntStream.range(LAIndex, length + 1). + parallel().forEach(i -> LAs[i].la = LAs[i].la.toDouble()); + } + else { + for (int i = LAIndex; i <= length; i++) { + LAs[i].la = LAs[i].la.toDouble(); + } } } @@ -586,26 +1174,33 @@ void MinimizeStage(int Stage) { int MacroItCount = LAStages[Stage].MacroItCount; int length = LAIndex + MacroItCount; - for (int i = LAIndex; i <= length; i++) { - LAs[i].la = LAs[i].la.minimize(); + + if(TaskDraw.USE_THREADS_FOR_BLA2) { + IntStream.range(LAIndex, length + 1). + parallel().forEach(i -> LAs[i].la = LAs[i].la.minimize()); + } + else { + for (int i = LAIndex; i <= length; i++) { + LAs[i].la = LAs[i].la.minimize(); + } } } public boolean isLAStageInvalid(int LAIndex, Complex dc) { - return (dc.chebychevNorm() >= LAs[LAIndex].la.dgetLAThresholdC()); + return (dc.chebyshevNorm() >= LAs[LAIndex].la.dgetLAThresholdC()); } - public boolean isLAStageInvalid(int LAIndex, double dcChebychevNorm) { - return (dcChebychevNorm >= LAs[LAIndex].la.dgetLAThresholdC()); + public boolean isLAStageInvalid(int LAIndex, double dcChebyshevNorm) { + return (dcChebyshevNorm >= LAs[LAIndex].la.dgetLAThresholdC()); } public boolean isLAStageInvalid(int LAIndex, MantExpComplex dc) { - return (dc.chebychevNorm().compareToBothPositiveReduced((LAs[LAIndex].la).getLAThresholdC()) >= 0); + return (dc.chebyshevNorm().compareToBothPositiveReduced((LAs[LAIndex].la).getLAThresholdC()) >= 0); } - public boolean isLAStageInvalid(int LAIndex, MantExp dcChebychevNorm) { - return (dcChebychevNorm.compareToBothPositiveReduced((LAs[LAIndex].la).getLAThresholdC()) >= 0); + public boolean isLAStageInvalid(int LAIndex, MantExp dcChebyshevNorm) { + return (dcChebyshevNorm.compareToBothPositiveReduced((LAs[LAIndex].la).getLAThresholdC()) >= 0); } public boolean useDoublePrecisionAtStage(int stage) { @@ -620,7 +1215,7 @@ public int getMacroItCount(int CurrentLAStage) { return LAStages[CurrentLAStage].MacroItCount; } - public LAstep getLA(int LAIndex, Complex dz, int j, int iterations, int max_iterations) { + public LAstep getLA(Fractal f, int LAIndex, Complex dz, int j, int iterations, int max_iterations) { int LAIndexj = LAIndex + j; LAData laData = LAs[LAIndexj]; @@ -632,11 +1227,11 @@ public LAstep getLA(int LAIndex, Complex dz, int j, int iterations, int max_iter if(usuable) { GenericLAInfo LAj = laData.la; - las = LAj.Prepare(dz); + las = LAj.Prepare(f, dz); if(!las.unusable) { las.LAj = LAj; - las.Refp1 = (Complex) LAs[LAIndexj + 1].la.getRef(); + las.Refp1 = (Complex) LAs[LAIndexj + 1].la.getRef(f); las.step = l; } } @@ -651,7 +1246,7 @@ public LAstep getLA(int LAIndex, Complex dz, int j, int iterations, int max_iter } - public LAstep getLA(int LAIndex, double dre, double dim, int j, int iterations, int max_iterations) { + public LAstep getLA(Fractal f, int LAIndex, double dre, double dim, int j, int iterations, int max_iterations) { int LAIndexj = LAIndex + j; LAData laData = LAs[LAIndexj]; @@ -663,11 +1258,11 @@ public LAstep getLA(int LAIndex, double dre, double dim, int j, int iterations, if(usuable) { GenericLAInfo LAj = laData.la; - las = LAj.Prepare(dre, dim); + las = LAj.Prepare(f, dre, dim); if(!las.unusable) { las.LAj = LAj; - las.Refp1 = (Complex) LAs[LAIndexj + 1].la.getRef(); + las.Refp1 = (Complex) LAs[LAIndexj + 1].la.getRef(f); las.step = l; } } @@ -682,7 +1277,7 @@ public LAstep getLA(int LAIndex, double dre, double dim, int j, int iterations, } - public LAstep getLA(int LAIndex, MantExpComplex dz, int j, int iterations, int max_iterations) { + public LAstep getLA(Fractal f, int LAIndex, MantExpComplex dz, int j, int iterations, int max_iterations) { int LAIndexj = LAIndex + j; LAData laData = LAs[LAIndexj]; @@ -694,11 +1289,11 @@ public LAstep getLA(int LAIndex, MantExpComplex dz, int j, int iterations, int m if(usuable) { GenericLAInfo LAj = laData.la; - las = LAj.Prepare(dz); + las = LAj.Prepare(f, dz); if(!las.unusable) { las.LAj = LAj; - las.Refp1Deep = (MantExpComplex) LAs[LAIndexj + 1].la.getRef(); + las.Refp1Deep = (MantExpComplex) LAs[LAIndexj + 1].la.getRef(f); las.step = l; } } @@ -713,6 +1308,21 @@ public LAstep getLA(int LAIndex, MantExpComplex dz, int j, int iterations, int m } + private static double log2 = Math.log(2); + + private double log2(double x) { + return Math.log(x) / log2; + } + + @Override + public int hashCode() { + int hash = 0; + for(int i = 0; i < LAcurrentIndex; i++) { + hash = 31 * hash + LAs[i].toString().hashCode(); + } + return hash; + } + public static void main(String[] args) { long mem; diff --git a/src/fractalzoomer/core/la/impl/LAInfo.java b/src/fractalzoomer/core/la/impl/LAInfo.java index d2af73f2f..c42d4cbb1 100644 --- a/src/fractalzoomer/core/la/impl/LAInfo.java +++ b/src/fractalzoomer/core/la/impl/LAInfo.java @@ -1,12 +1,10 @@ package fractalzoomer.core.la.impl; -import fractalzoomer.core.Complex; -import fractalzoomer.core.GenericComplex; -import fractalzoomer.core.MantExp; -import fractalzoomer.core.la.GenericLAInfo; -import fractalzoomer.core.la.InvalidCalculationException; -import fractalzoomer.core.la.LAInfoBase; -import fractalzoomer.core.la.LAstep; +import fractalzoomer.core.*; +import fractalzoomer.core.la.*; +import fractalzoomer.functions.Fractal; + +import static fractalzoomer.core.la.LAReference.f; public class LAInfo extends LAInfoBase { protected double RefRe, RefIm; @@ -18,20 +16,21 @@ public static LAInfo create() { return new LAInfo(); } - public static LAInfo create(int RefIndex) { + public static LAInfo create(int RefIndex, ReferenceDecompressor referenceDecompressor) { if(DETECTION_METHOD == 1) { - return new LAInfoDetection2(RefIndex); + return new LAInfoDetection2(RefIndex, referenceDecompressor); } - return new LAInfo(RefIndex); + return new LAInfo(RefIndex, referenceDecompressor); } protected LAInfo() { } - protected LAInfo(int RefIndex) { - RefRe = refRe[RefIndex]; - RefIm = refIm[RefIndex]; + protected LAInfo(int RefIndex, ReferenceDecompressor referenceDecompressor) { + Complex val = f.getArrayValue(referenceDecompressor, Fractal.reference, RefIndex); + RefRe = val.getRe(); + RefIm = val.getIm(); ZCoeffRe = 1.0; ZCoeffIm = 0.0; CCoeffRe = 1.0; @@ -56,7 +55,7 @@ protected LAInfo(LAInfo other) { } protected LAInfo(LAInfoDeep deep) { - Complex Ref = deep.getRef().toComplex(); + Complex Ref = deep.getRefDouble(); Complex ZCoeff = deep.getZCoeff().toComplex(); Complex CCoeff = deep.getCCoeff().toComplex(); @@ -74,22 +73,25 @@ protected LAInfo(LAInfoDeep deep) { } @Override - public GenericComplex getRef() { + public GenericComplex getRef(Fractal f) { return new Complex(RefRe, RefIm); } @Override - protected boolean Step(LAInfo out, int zRefIndex) throws InvalidCalculationException { + public Complex getRefDouble() {return new Complex(RefRe, RefIm);} + + @Override + protected boolean Step(LAInfo out, int zRefIndex, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { - Complex z = new Complex(refRe[zRefIndex], refIm[zRefIndex]); + Complex z = f.getArrayValue(referenceDecompressor, Fractal.reference, zRefIndex); - double ChebyMagz = z.chebychevNorm(); + double ChebyMagz = z.chebyshevNorm(); Complex ZCoeff = new Complex(ZCoeffRe, ZCoeffIm); Complex CCoeff = new Complex(CCoeffRe, CCoeffIm); - double ChebyMagZCoeff = ZCoeff.chebychevNorm(); - double ChebyMagCCoeff = CCoeff.chebychevNorm(); + double ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + double ChebyMagCCoeff = CCoeff.chebyshevNorm(); out.LAThreshold = Math.min(LAThreshold, ChebyMagz / ChebyMagZCoeff * LAThresholdScale); out.LAThresholdC = Math.min(LAThresholdC, ChebyMagz / ChebyMagCCoeff * LAThresholdCScale); @@ -117,22 +119,22 @@ protected boolean Step(LAInfo out, int zRefIndex) throws InvalidCalculationExcep } @Override - protected GenericLAInfo Step(int zRefIndex) throws InvalidCalculationException { + protected GenericLAInfo Step(int zRefIndex, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { LAInfo Result = new LAInfo(); - Step(Result, zRefIndex); + Step(Result, zRefIndex, referenceDecompressor); return Result; } @Override - protected boolean Composite(LAInfo out, LAInfo LA) throws InvalidCalculationException { + protected boolean Composite(LAInfo out, LAInfo LA, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { Complex z = new Complex(LA.RefRe, LA.RefIm); Complex ZCoeff = new Complex(ZCoeffRe, ZCoeffIm); Complex CCoeff = new Complex(CCoeffRe, CCoeffIm); - double ChebyMagz = z.chebychevNorm(); - double ChebyMagZCoeff = ZCoeff.chebychevNorm(); - double ChebyMagCCoeff = CCoeff.chebychevNorm(); + double ChebyMagz = z.chebyshevNorm(); + double ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + double ChebyMagCCoeff = CCoeff.chebyshevNorm(); out.LAThreshold = Math.min(LAThreshold, ChebyMagz / ChebyMagZCoeff * LAThresholdScale); out.LAThresholdC = Math.min(LAThresholdC, ChebyMagz / ChebyMagCCoeff * LAThresholdCScale); @@ -145,8 +147,8 @@ protected boolean Composite(LAInfo out, LAInfo LA) throws InvalidCalculationExce - ChebyMagZCoeff = outZCoeff.chebychevNorm(); - ChebyMagCCoeff = outCCoeff.chebychevNorm(); + ChebyMagZCoeff = outZCoeff.chebyshevNorm(); + ChebyMagCCoeff = outCCoeff.chebyshevNorm(); double temp = out.LAThreshold; out.LAThreshold = Math.min(out.LAThreshold, LA.LAThreshold / ChebyMagZCoeff); out.LAThresholdC = Math.min(out.LAThresholdC, LA.LAThreshold / ChebyMagCCoeff); @@ -177,25 +179,25 @@ protected boolean Composite(LAInfo out, LAInfo LA) throws InvalidCalculationExce } @Override - protected LAInfo Composite(LAInfo LA) throws InvalidCalculationException { + protected LAInfo Composite(LAInfo LA, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { LAInfo Result = new LAInfo(); - Composite(Result, LA); + Composite(Result, LA, referenceDecompressor); return Result; } @Override - public LAstep Prepare(Complex dz) { + public LAstep Prepare(Fractal f, Complex dz) { Complex newdz = dz.times(new Complex( 2 * RefRe, 2 * RefIm).plus_mutable(dz)); LAstep temp = new LAstep(); - temp.unusable = newdz.chebychevNorm() >= LAThreshold; + temp.unusable = newdz.chebyshevNorm() >= LAThreshold; temp.newDz = newdz; return temp; } @Override - public LAstep Prepare(double dre, double dim) { + public LAstep Prepare(Fractal f, double dre, double dim) { double newdre = 2 * RefRe + dre; double newdim = 2 * RefIm + dim; @@ -210,4 +212,39 @@ public LAstep Prepare(double dre, double dim) { return tempstep; } + @Override + public String toString() { + return ZCoeffRe + "\n" + + ZCoeffIm + "\n" + + CCoeffRe + "\n" + + CCoeffIm + "\n" + + LAThreshold + "\n" + + LAThresholdC + "\n" + + RefRe + "\n" + + RefIm + "\n"; + } + + @Override + public boolean isEqual(GenericLAInfo other) { + if(other == null) { + return false; + } + if(!(other instanceof LAInfo)) { + return false; + } + LAInfo oth = (LAInfo) other; + if(this == other) { + return true; + } + + return ZCoeffRe == oth.ZCoeffRe && + ZCoeffIm == oth.ZCoeffIm && + CCoeffRe == oth.CCoeffRe && + CCoeffIm == oth.CCoeffIm && + LAThreshold == oth.LAThreshold && + LAThresholdC == oth.LAThresholdC && + RefRe == oth.RefRe && + RefIm == oth.RefIm; + } + } diff --git a/src/fractalzoomer/core/la/impl/LAInfoDeep.java b/src/fractalzoomer/core/la/impl/LAInfoDeep.java index b251a4d7c..0f94ba4da 100644 --- a/src/fractalzoomer/core/la/impl/LAInfoDeep.java +++ b/src/fractalzoomer/core/la/impl/LAInfoDeep.java @@ -1,12 +1,12 @@ package fractalzoomer.core.la.impl; -import fractalzoomer.core.GenericComplex; -import fractalzoomer.core.MantExp; -import fractalzoomer.core.MantExpComplex; -import fractalzoomer.core.TaskDraw; +import fractalzoomer.core.*; import fractalzoomer.core.la.GenericLAInfo; import fractalzoomer.core.la.LAInfoBaseDeep; import fractalzoomer.core.la.LAstep; +import fractalzoomer.functions.Fractal; + +import static fractalzoomer.core.la.LAReference.f; public class LAInfoDeep extends LAInfoBaseDeep { double RefRe, RefIm; @@ -28,18 +28,18 @@ public static LAInfoDeep create() { } } - public static LAInfoDeep create(int refIndex) { + public static LAInfoDeep create(int refIndex, ReferenceDecompressor referenceDecompressor) { if(LAInfo.DETECTION_METHOD == 1) { if (TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { - return new LAInfoDeepDetection2Full(refIndex); + return new LAInfoDeepDetection2Full(refIndex, referenceDecompressor); } - return new LAInfoDeepDetection2(refIndex); + return new LAInfoDeepDetection2(refIndex, referenceDecompressor); } else { if (TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { - return new LAInfoDeepFull(refIndex); + return new LAInfoDeepFull(refIndex, referenceDecompressor); } - return new LAInfoDeep(refIndex); + return new LAInfoDeep(refIndex, referenceDecompressor); } } @@ -68,8 +68,8 @@ protected LAInfoDeep(LAInfoDeep other) { LAThresholdCExp = other.LAThresholdCExp; } - protected LAInfoDeep(int RefIndex) { - MantExpComplex z = new MantExpComplex(refExpRe[RefIndex], refMantsRe[RefIndex], refMantsIm[RefIndex]); + protected LAInfoDeep(int RefIndex, ReferenceDecompressor referenceDecompressor) { + MantExpComplex z = f.getArrayDeepValue(referenceDecompressor, Fractal.referenceDeep, RefIndex); //z.Normalize(); RefRe = z.getMantissaReal(); RefIm = z.getMantissaImag(); @@ -96,22 +96,25 @@ protected LAInfoDeep(int RefIndex) { } @Override - public GenericComplex getRef() { + public GenericComplex getRef(Fractal f) { return new MantExpComplex(RefExp, RefRe, RefIm); } @Override - protected boolean Step(LAInfoDeep out, int zRefIndex) { + public Complex getRefDouble() {return new MantExpComplex(RefExp, RefRe, RefIm).toComplex();} + + @Override + protected boolean Step(LAInfoDeep out, int zRefIndex, ReferenceDecompressor referenceDecompressor) { - MantExpComplex z = new MantExpComplex(refExpRe[zRefIndex], refMantsRe[zRefIndex], refMantsIm[zRefIndex]); + MantExpComplex z = f.getArrayDeepValue(referenceDecompressor, Fractal.referenceDeep, zRefIndex); - MantExp ChebyMagz = z.chebychevNorm(); + MantExp ChebyMagz = z.chebyshevNorm(); MantExpComplex ZCoeff = new MantExpComplex(ZCoeffExp, ZCoeffRe, ZCoeffIm); MantExpComplex CCoeff = new MantExpComplex(CCoeffExp, CCoeffRe, CCoeffIm); - MantExp ChebyMagZCoeff = ZCoeff.chebychevNorm(); - MantExp ChebyMagCCoeff = CCoeff.chebychevNorm(); + MantExp ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + MantExp ChebyMagCCoeff = CCoeff.chebyshevNorm(); MantExp temp1 = ChebyMagz.divide(ChebyMagZCoeff).multiply_mutable(LAThresholdScale); temp1.Normalize(); @@ -151,25 +154,25 @@ protected boolean Step(LAInfoDeep out, int zRefIndex) { } @Override - protected GenericLAInfo Step(int zRefIndex) { + protected GenericLAInfo Step(int zRefIndex, ReferenceDecompressor referenceDecompressor) { LAInfoDeep Result = new LAInfoDeep(); - Step(Result, zRefIndex); + Step(Result, zRefIndex, referenceDecompressor); return Result; } @Override - protected boolean Composite(LAInfoDeep out, LAInfoDeep LA) { + protected boolean Composite(LAInfoDeep out, LAInfoDeep LA, ReferenceDecompressor referenceDecompressor) { MantExpComplex z = new MantExpComplex(LA.RefExp, LA.RefRe, LA.RefIm); - MantExp ChebyMagz = z.chebychevNorm(); + MantExp ChebyMagz = z.chebyshevNorm(); MantExpComplex ZCoeff = new MantExpComplex(ZCoeffExp, ZCoeffRe, ZCoeffIm); MantExpComplex CCoeff = new MantExpComplex(CCoeffExp, CCoeffRe, CCoeffIm); MantExp LAThreshold = new MantExp(LAThresholdExp, LAThresholdMant); MantExp LAThresholdC = new MantExp(LAThresholdCExp, LAThresholdCMant); - MantExp ChebyMagZCoeff = ZCoeff.chebychevNorm(); - MantExp ChebyMagCCoeff = CCoeff.chebychevNorm(); + MantExp ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + MantExp ChebyMagCCoeff = CCoeff.chebyshevNorm(); MantExp temp1 = ChebyMagz.divide(ChebyMagZCoeff).multiply_mutable(LAThresholdScale); temp1.Normalize(); @@ -187,8 +190,8 @@ protected boolean Composite(LAInfoDeep out, LAInfoDeep LA) { MantExpComplex outCCoeff = z2.times(CCoeff); outCCoeff.Normalize(); - ChebyMagZCoeff = outZCoeff.chebychevNorm(); - ChebyMagCCoeff = outCCoeff.chebychevNorm(); + ChebyMagZCoeff = outZCoeff.chebyshevNorm(); + ChebyMagCCoeff = outCCoeff.chebyshevNorm(); MantExp temp = outLAThreshold; MantExp LA_LAThreshold = new MantExp(LA.LAThresholdExp, LA.LAThresholdMant); @@ -231,21 +234,21 @@ protected boolean Composite(LAInfoDeep out, LAInfoDeep LA) { } @Override - protected LAInfoDeep Composite(LAInfoDeep LA) { + protected LAInfoDeep Composite(LAInfoDeep LA, ReferenceDecompressor referenceDecompressor) { LAInfoDeep Result = new LAInfoDeep(); - Composite(Result, LA); + Composite(Result, LA, referenceDecompressor); return Result; } @Override - public LAstep Prepare(MantExpComplex dz) { + public LAstep Prepare(Fractal f, MantExpComplex dz) { //*2 is + 1 MantExpComplex newdz = dz.times(new MantExpComplex(RefExp + 1, RefRe, RefIm).plus_mutable(dz)); newdz.Normalize(); LAstep temp = new LAstep(); - temp.unusable = newdz.chebychevNorm().compareToBothPositiveReduced(new MantExp(LAThresholdExp, LAThresholdMant)) >= 0; + temp.unusable = newdz.chebyshevNorm().compareToBothPositiveReduced(new MantExp(LAThresholdExp, LAThresholdMant)) >= 0; temp.newDzDeep = newdz; return temp; } @@ -255,4 +258,53 @@ public GenericLAInfo toDouble() { return new LAInfo(this); } + @Override + public String toString() { + return ZCoeffRe + "\n" + + ZCoeffIm + "\n" + + ZCoeffExp + "\n" + + CCoeffRe + "\n" + + CCoeffIm + "\n" + + CCoeffExp + "\n" + + LAThresholdMant + "\n" + + LAThresholdExp + "\n" + + LAThresholdCMant + "\n" + + LAThresholdExp + "\n" + + RefRe + "\n" + + RefIm + "\n" + + RefExp + "\n"; + } + + @Override + public boolean isEqual(GenericLAInfo other) { + if(other == null) { + return false; + } + if(!(other instanceof LAInfoDeep)) { + return false; + } + LAInfoDeep oth = (LAInfoDeep) other; + if(this == other) { + return true; + } + + return ZCoeffRe == oth.ZCoeffRe && + ZCoeffIm == oth.ZCoeffIm && + ZCoeffExp == oth.ZCoeffExp && + + CCoeffRe == oth.CCoeffRe && + CCoeffIm == oth.CCoeffIm && + CCoeffExp == oth.CCoeffExp && + + LAThresholdMant == oth.LAThresholdMant && + LAThresholdExp == oth.LAThresholdExp && + + LAThresholdCMant == oth.LAThresholdCMant && + LAThresholdCExp == oth.LAThresholdCExp && + + RefRe == oth.RefRe && + RefIm == oth.RefIm && + RefExp == oth.RefExp; + } + } diff --git a/src/fractalzoomer/core/la/impl/LAInfoDeepDetection2.java b/src/fractalzoomer/core/la/impl/LAInfoDeepDetection2.java index f12c779b9..7c8bd7cdc 100644 --- a/src/fractalzoomer/core/la/impl/LAInfoDeepDetection2.java +++ b/src/fractalzoomer/core/la/impl/LAInfoDeepDetection2.java @@ -2,7 +2,11 @@ import fractalzoomer.core.MantExp; import fractalzoomer.core.MantExpComplex; +import fractalzoomer.core.ReferenceDecompressor; import fractalzoomer.core.la.GenericLAInfo; +import fractalzoomer.functions.Fractal; + +import static fractalzoomer.core.la.LAReference.f; public class LAInfoDeepDetection2 extends LAInfoDeep { double MinMagMant; @@ -12,8 +16,8 @@ protected LAInfoDeepDetection2() { super(); } - protected LAInfoDeepDetection2(int refIndex) { - super(refIndex); + protected LAInfoDeepDetection2(int refIndex, ReferenceDecompressor referenceDecompressor) { + super(refIndex, referenceDecompressor); MantExp MinMag = MantExp.FOUR; MinMagMant = MinMag.getMantissa(); MinMagExp = MinMag.getExp(); @@ -21,27 +25,27 @@ protected LAInfoDeepDetection2(int refIndex) { @Override protected boolean DetectPeriod(MantExpComplex z) { - return z.chebychevNorm().compareToBothPositive(new MantExp(MinMagExp, MinMagMant).multiply(PeriodDetectionThreshold2)) < 0; + return z.chebyshevNorm().compareToBothPositive(new MantExp(MinMagExp, MinMagMant).multiply(PeriodDetectionThreshold2)) < 0; } @Override protected boolean Stage0DetectPeriod(MantExpComplex z) { - return z.chebychevNorm().compareToBothPositive(new MantExp(MinMagExp, MinMagMant).multiply(Stage0PeriodDetectionThreshold2)) < 0; + return z.chebyshevNorm().compareToBothPositive(new MantExp(MinMagExp, MinMagMant).multiply(Stage0PeriodDetectionThreshold2)) < 0; } @Override - protected boolean Step(LAInfoDeep out1, int zRefIndex) { + protected boolean Step(LAInfoDeep out1, int zRefIndex, ReferenceDecompressor referenceDecompressor) { LAInfoDeepDetection2 out = (LAInfoDeepDetection2)out1; - MantExpComplex z = new MantExpComplex(refExpRe[zRefIndex], refMantsRe[zRefIndex], refMantsIm[zRefIndex]); + MantExpComplex z = f.getArrayDeepValue(referenceDecompressor, Fractal.referenceDeep, zRefIndex); - MantExp ChebyMagz = z.chebychevNorm(); + MantExp ChebyMagz = z.chebyshevNorm(); MantExpComplex ZCoeff = new MantExpComplex(ZCoeffExp, ZCoeffRe, ZCoeffIm); MantExpComplex CCoeff = new MantExpComplex(CCoeffExp, CCoeffRe, CCoeffIm); - MantExp ChebyMagZCoeff = ZCoeff.chebychevNorm(); - MantExp ChebyMagCCoeff = CCoeff.chebychevNorm(); + MantExp ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + MantExp ChebyMagCCoeff = CCoeff.chebyshevNorm(); MantExp temp1 = ChebyMagz.divide(ChebyMagZCoeff).multiply_mutable(LAThresholdScale); temp1.Normalize(); @@ -87,29 +91,29 @@ protected boolean Step(LAInfoDeep out1, int zRefIndex) { } @Override - protected GenericLAInfo Step(int zRefIndex) { + protected GenericLAInfo Step(int zRefIndex, ReferenceDecompressor referenceDecompressor) { LAInfoDeepDetection2 Result = new LAInfoDeepDetection2(); - Step(Result, zRefIndex); + Step(Result, zRefIndex, referenceDecompressor); return Result; } @Override - protected boolean Composite(LAInfoDeep out1, LAInfoDeep LA1) { + protected boolean Composite(LAInfoDeep out1, LAInfoDeep LA1, ReferenceDecompressor referenceDecompressor) { LAInfoDeepDetection2 out = (LAInfoDeepDetection2)out1; LAInfoDeepDetection2 LA = (LAInfoDeepDetection2)LA1; MantExpComplex z = new MantExpComplex(LA.RefExp, LA.RefRe, LA.RefIm); - MantExp ChebyMagz = z.chebychevNorm(); + MantExp ChebyMagz = z.chebyshevNorm(); MantExpComplex ZCoeff = new MantExpComplex(ZCoeffExp, ZCoeffRe, ZCoeffIm); MantExpComplex CCoeff = new MantExpComplex(CCoeffExp, CCoeffRe, CCoeffIm); MantExp LAThreshold = new MantExp(LAThresholdExp, LAThresholdMant); MantExp LAThresholdC = new MantExp(LAThresholdCExp, LAThresholdCMant); - MantExp ChebyMagZCoeff = ZCoeff.chebychevNorm(); - MantExp ChebyMagCCoeff = CCoeff.chebychevNorm(); + MantExp ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + MantExp ChebyMagCCoeff = CCoeff.chebyshevNorm(); MantExp temp1 = ChebyMagz.divide(ChebyMagZCoeff).multiply_mutable(LAThresholdScale); temp1.Normalize(); @@ -127,8 +131,8 @@ protected boolean Composite(LAInfoDeep out1, LAInfoDeep LA1) { MantExpComplex outCCoeff = z2.times(CCoeff); outCCoeff.Normalize(); - ChebyMagZCoeff = outZCoeff.chebychevNorm(); - ChebyMagCCoeff = outCCoeff.chebychevNorm(); + ChebyMagZCoeff = outZCoeff.chebyshevNorm(); + ChebyMagCCoeff = outCCoeff.chebyshevNorm(); MantExp LA_LAThreshold = new MantExp(LA.LAThresholdExp, LA.LAThresholdMant); MantExpComplex LAZCoeff = new MantExpComplex(LA.ZCoeffExp, LA.ZCoeffRe, LA.ZCoeffIm); @@ -176,10 +180,10 @@ protected boolean Composite(LAInfoDeep out1, LAInfoDeep LA1) { return temp.compareToBothPositive(MinMag.multiply(PeriodDetectionThreshold2)) < 0; } @Override - protected LAInfoDeepDetection2 Composite(LAInfoDeep LA) { + protected LAInfoDeepDetection2 Composite(LAInfoDeep LA, ReferenceDecompressor referenceDecompressor) { LAInfoDeepDetection2 Result = new LAInfoDeepDetection2(); - Composite(Result, LA); + Composite(Result, LA, referenceDecompressor); return Result; } @@ -187,4 +191,57 @@ protected LAInfoDeepDetection2 Composite(LAInfoDeep LA) { public GenericLAInfo minimize() { return new LAInfoDeep(this); } + + @Override + public String toString() { + return ZCoeffRe + "\n" + + ZCoeffIm + "\n" + + ZCoeffExp + "\n" + + CCoeffRe + "\n" + + CCoeffIm + "\n" + + CCoeffExp + "\n" + + LAThresholdMant + "\n" + + LAThresholdExp + "\n" + + LAThresholdCMant + "\n" + + LAThresholdExp + "\n" + + RefRe + "\n" + + RefIm + "\n" + + RefExp + "\n" + + MinMagMant + "\n" + + MinMagExp + "\n"; + } + @Override + public boolean isEqual(GenericLAInfo other) { + if(other == null) { + return false; + } + if(!(other instanceof LAInfoDeepDetection2)) { + return false; + } + LAInfoDeepDetection2 oth = (LAInfoDeepDetection2) other; + if(this == other) { + return true; + } + + return ZCoeffRe == oth.ZCoeffRe && + ZCoeffIm == oth.ZCoeffIm && + ZCoeffExp == oth.ZCoeffExp && + + CCoeffRe == oth.CCoeffRe && + CCoeffIm == oth.CCoeffIm && + CCoeffExp == oth.CCoeffExp && + + LAThresholdMant == oth.LAThresholdMant && + LAThresholdExp == oth.LAThresholdExp && + + LAThresholdCMant == oth.LAThresholdCMant && + LAThresholdCExp == oth.LAThresholdCExp && + + RefRe == oth.RefRe && + RefIm == oth.RefIm && + RefExp == oth.RefExp && + + MinMagMant == oth.MinMagMant && + MinMagExp == oth.MinMagExp; + } } diff --git a/src/fractalzoomer/core/la/impl/LAInfoDeepDetection2Full.java b/src/fractalzoomer/core/la/impl/LAInfoDeepDetection2Full.java index de40360d5..cd40856cf 100644 --- a/src/fractalzoomer/core/la/impl/LAInfoDeepDetection2Full.java +++ b/src/fractalzoomer/core/la/impl/LAInfoDeepDetection2Full.java @@ -3,7 +3,11 @@ import fractalzoomer.core.MantExp; import fractalzoomer.core.MantExpComplex; import fractalzoomer.core.MantExpComplexFull; +import fractalzoomer.core.ReferenceDecompressor; import fractalzoomer.core.la.GenericLAInfo; +import fractalzoomer.functions.Fractal; + +import static fractalzoomer.core.la.LAReference.f; public class LAInfoDeepDetection2Full extends LAInfoDeepFull { double MinMagMant; @@ -13,8 +17,8 @@ protected LAInfoDeepDetection2Full() { super(); } - protected LAInfoDeepDetection2Full(int refIndex) { - super(refIndex); + protected LAInfoDeepDetection2Full(int refIndex, ReferenceDecompressor referenceDecompressor) { + super(refIndex, referenceDecompressor); MantExp MinMag = MantExp.FOUR; MinMagMant = MinMag.getMantissa(); MinMagExp = MinMag.getExp(); @@ -22,28 +26,28 @@ protected LAInfoDeepDetection2Full(int refIndex) { @Override protected boolean DetectPeriod(MantExpComplex z) { - return z.chebychevNorm().compareToBothPositive(new MantExp(MinMagExp, MinMagMant).multiply(PeriodDetectionThreshold2)) < 0; + return z.chebyshevNorm().compareToBothPositive(new MantExp(MinMagExp, MinMagMant).multiply(PeriodDetectionThreshold2)) < 0; } @Override protected boolean Stage0DetectPeriod(MantExpComplex z) { - return z.chebychevNorm().compareToBothPositive(new MantExp(MinMagExp, MinMagMant).multiply(Stage0PeriodDetectionThreshold2)) < 0; + return z.chebyshevNorm().compareToBothPositive(new MantExp(MinMagExp, MinMagMant).multiply(Stage0PeriodDetectionThreshold2)) < 0; } @Override - protected boolean Step(LAInfoDeep out1, int zRefIndex) { + protected boolean Step(LAInfoDeep out1, int zRefIndex, ReferenceDecompressor referenceDecompressor) { LAInfoDeepDetection2Full out = (LAInfoDeepDetection2Full)out1; - MantExpComplex z = new MantExpComplexFull(refExpRe[zRefIndex], refExpIm[zRefIndex], refMantsRe[zRefIndex], refMantsIm[zRefIndex]); + MantExpComplex z = f.getArrayDeepValue(referenceDecompressor, Fractal.referenceDeep, zRefIndex); - MantExp ChebyMagz = z.chebychevNorm(); + MantExp ChebyMagz = z.chebyshevNorm(); MantExpComplex ZCoeff = new MantExpComplexFull(ZCoeffExp, ZCoeffExpIm, ZCoeffRe, ZCoeffIm); MantExpComplex CCoeff = new MantExpComplexFull(CCoeffExp, CCoeffExpIm, CCoeffRe, CCoeffIm); - MantExp ChebyMagZCoeff = ZCoeff.chebychevNorm(); - MantExp ChebyMagCCoeff = CCoeff.chebychevNorm(); + MantExp ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + MantExp ChebyMagCCoeff = CCoeff.chebyshevNorm(); MantExp temp1 = ChebyMagz.divide(ChebyMagZCoeff).multiply_mutable(LAThresholdScale); temp1.Normalize(); @@ -90,29 +94,29 @@ protected boolean Step(LAInfoDeep out1, int zRefIndex) { return outMinMag.compareToBothPositive(MinMag.multiply(Stage0PeriodDetectionThreshold2)) < 0; } @Override - protected GenericLAInfo Step(int zRefIndex) { + protected GenericLAInfo Step(int zRefIndex, ReferenceDecompressor referenceDecompressor) { LAInfoDeepDetection2Full Result = new LAInfoDeepDetection2Full(); - Step(Result, zRefIndex); + Step(Result, zRefIndex, referenceDecompressor); return Result; } @Override - protected boolean Composite(LAInfoDeep out1, LAInfoDeep LA1) { + protected boolean Composite(LAInfoDeep out1, LAInfoDeep LA1, ReferenceDecompressor referenceDecompressor) { LAInfoDeepDetection2Full out = (LAInfoDeepDetection2Full)out1; LAInfoDeepDetection2Full LA = (LAInfoDeepDetection2Full)LA1; MantExpComplex z = new MantExpComplexFull(LA.RefExp, LA.RefExpIm, LA.RefRe, LA.RefIm); - MantExp ChebyMagz = z.chebychevNorm(); + MantExp ChebyMagz = z.chebyshevNorm(); MantExpComplex ZCoeff = new MantExpComplexFull(ZCoeffExp, ZCoeffExpIm, ZCoeffRe, ZCoeffIm); MantExpComplex CCoeff = new MantExpComplexFull(CCoeffExp, CCoeffExpIm, CCoeffRe, CCoeffIm); MantExp LAThreshold = new MantExp(LAThresholdExp, LAThresholdMant); MantExp LAThresholdC = new MantExp(LAThresholdCExp, LAThresholdCMant); - MantExp ChebyMagZCoeff = ZCoeff.chebychevNorm(); - MantExp ChebyMagCCoeff = CCoeff.chebychevNorm(); + MantExp ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + MantExp ChebyMagCCoeff = CCoeff.chebyshevNorm(); MantExp temp1 = ChebyMagz.divide(ChebyMagZCoeff).multiply_mutable(LAThresholdScale); temp1.Normalize(); @@ -130,8 +134,8 @@ protected boolean Composite(LAInfoDeep out1, LAInfoDeep LA1) { MantExpComplex outCCoeff = z2.times(CCoeff); outCCoeff.Normalize(); - ChebyMagZCoeff = outZCoeff.chebychevNorm(); - ChebyMagCCoeff = outCCoeff.chebychevNorm(); + ChebyMagZCoeff = outZCoeff.chebyshevNorm(); + ChebyMagCCoeff = outCCoeff.chebyshevNorm(); MantExp LA_LAThreshold = new MantExp(LA.LAThresholdExp, LA.LAThresholdMant); MantExpComplex LAZCoeff = new MantExpComplexFull(LA.ZCoeffExp, LA.ZCoeffExpIm, LA.ZCoeffRe, LA.ZCoeffIm); @@ -183,10 +187,10 @@ protected boolean Composite(LAInfoDeep out1, LAInfoDeep LA1) { } @Override - protected LAInfoDeepDetection2Full Composite(LAInfoDeep LA) { + protected LAInfoDeepDetection2Full Composite(LAInfoDeep LA, ReferenceDecompressor referenceDecompressor) { LAInfoDeepDetection2Full Result = new LAInfoDeepDetection2Full(); - Composite(Result, LA); + Composite(Result, LA, referenceDecompressor); return Result; } @@ -194,4 +198,64 @@ protected LAInfoDeepDetection2Full Composite(LAInfoDeep LA) { public GenericLAInfo minimize() { return new LAInfoDeepFull(this); } + + @Override + public String toString() { + return ZCoeffRe + "\n" + + ZCoeffIm + "\n" + + ZCoeffExp + "\n" + + ZCoeffExpIm + "\n" + + CCoeffRe + "\n" + + CCoeffIm + "\n" + + CCoeffExp + "\n" + + CCoeffExpIm + "\n" + + LAThresholdMant + "\n" + + LAThresholdExp + "\n" + + LAThresholdCMant + "\n" + + LAThresholdExp + "\n" + + RefRe + "\n" + + RefIm + "\n" + + RefExp + "\n" + + RefExpIm + "\n" + + MinMagMant + "\n" + + MinMagExp + "\n"; + } + + @Override + public boolean isEqual(GenericLAInfo other) { + if(other == null) { + return false; + } + if(!(other instanceof LAInfoDeepDetection2Full)) { + return false; + } + LAInfoDeepDetection2Full oth = (LAInfoDeepDetection2Full) other; + if(this == other) { + return true; + } + + return ZCoeffRe == oth.ZCoeffRe && + ZCoeffIm == oth.ZCoeffIm && + ZCoeffExp == oth.ZCoeffExp && + ZCoeffExpIm == oth.ZCoeffExpIm && + + CCoeffRe == oth.CCoeffRe && + CCoeffIm == oth.CCoeffIm && + CCoeffExp == oth.CCoeffExp && + CCoeffExpIm == oth.CCoeffExpIm && + + LAThresholdMant == oth.LAThresholdMant && + LAThresholdExp == oth.LAThresholdExp && + + LAThresholdCMant == oth.LAThresholdCMant && + LAThresholdCExp == oth.LAThresholdCExp && + + RefRe == oth.RefRe && + RefIm == oth.RefIm && + RefExp == oth.RefExp && + RefExpIm == oth.RefExpIm && + + MinMagMant == oth.MinMagMant && + MinMagExp == oth.MinMagExp; + } } diff --git a/src/fractalzoomer/core/la/impl/LAInfoDeepFull.java b/src/fractalzoomer/core/la/impl/LAInfoDeepFull.java index a1df86531..47e996967 100644 --- a/src/fractalzoomer/core/la/impl/LAInfoDeepFull.java +++ b/src/fractalzoomer/core/la/impl/LAInfoDeepFull.java @@ -1,12 +1,12 @@ package fractalzoomer.core.la.impl; -import fractalzoomer.core.GenericComplex; -import fractalzoomer.core.MantExp; -import fractalzoomer.core.MantExpComplex; -import fractalzoomer.core.MantExpComplexFull; +import fractalzoomer.core.*; import fractalzoomer.core.la.ATInfo; import fractalzoomer.core.la.GenericLAInfo; import fractalzoomer.core.la.LAstep; +import fractalzoomer.functions.Fractal; + +import static fractalzoomer.core.la.LAReference.f; public class LAInfoDeepFull extends LAInfoDeep { long RefExpIm; @@ -40,8 +40,8 @@ protected LAInfoDeepFull(LAInfoDeepFull other) { LAThresholdCExp = other.LAThresholdCExp; } - protected LAInfoDeepFull(int refIndex) { - MantExpComplex z = new MantExpComplexFull(refExpRe[refIndex], refExpIm[refIndex], refMantsRe[refIndex], refMantsIm[refIndex]); + protected LAInfoDeepFull(int refIndex, ReferenceDecompressor referenceDecompressor) { + MantExpComplex z = f.getArrayDeepValue(referenceDecompressor, Fractal.referenceDeep, refIndex); //z.Normalize(); RefRe = z.getMantissaReal(); RefIm = z.getMantissaImag(); @@ -72,19 +72,22 @@ protected LAInfoDeepFull(int refIndex) { @Override protected boolean DetectPeriod(MantExpComplex z) { - return z.chebychevNorm().divide(new MantExpComplexFull(ZCoeffExp, ZCoeffExpIm, ZCoeffRe, ZCoeffIm).chebychevNorm()).multiply_mutable(LAThresholdScale).compareToBothPositive(new MantExp(LAThresholdExp, LAThresholdMant).multiply(PeriodDetectionThreshold)) < 0; + return z.chebyshevNorm().divide(new MantExpComplexFull(ZCoeffExp, ZCoeffExpIm, ZCoeffRe, ZCoeffIm).chebyshevNorm()).multiply_mutable(LAThresholdScale).compareToBothPositive(new MantExp(LAThresholdExp, LAThresholdMant).multiply(PeriodDetectionThreshold)) < 0; } @Override protected boolean Stage0DetectPeriod(MantExpComplex z) { - return z.chebychevNorm().divide(new MantExpComplexFull(ZCoeffExp, ZCoeffExpIm, ZCoeffRe, ZCoeffIm).chebychevNorm()).multiply_mutable(LAThresholdScale).compareToBothPositive(new MantExp(LAThresholdExp, LAThresholdMant).multiply(Stage0PeriodDetectionThreshold)) < 0; + return z.chebyshevNorm().divide(new MantExpComplexFull(ZCoeffExp, ZCoeffExpIm, ZCoeffRe, ZCoeffIm).chebyshevNorm()).multiply_mutable(LAThresholdScale).compareToBothPositive(new MantExp(LAThresholdExp, LAThresholdMant).multiply(Stage0PeriodDetectionThreshold)) < 0; } @Override - public GenericComplex getRef() { + public GenericComplex getRef(Fractal f) { return new MantExpComplexFull(RefExp, RefExpIm, RefRe, RefIm); } + @Override + public Complex getRefDouble() {return new MantExpComplexFull(RefExp, RefExpIm, RefRe, RefIm).toComplex();} + @Override public GenericComplex getZCoeff() { return new MantExpComplexFull(ZCoeffExp, ZCoeffExpIm, ZCoeffRe, ZCoeffIm); @@ -96,19 +99,19 @@ public GenericComplex getCCoeff() { } @Override - protected boolean Step(LAInfoDeep out1, int zRefIndex) { + protected boolean Step(LAInfoDeep out1, int zRefIndex, ReferenceDecompressor referenceDecompressor) { LAInfoDeepFull out = (LAInfoDeepFull)out1; - MantExpComplex z = new MantExpComplexFull(refExpRe[zRefIndex], refExpIm[zRefIndex], refMantsRe[zRefIndex], refMantsIm[zRefIndex]); + MantExpComplex z = f.getArrayDeepValue(referenceDecompressor, Fractal.referenceDeep, zRefIndex); - MantExp ChebyMagz = z.chebychevNorm(); + MantExp ChebyMagz = z.chebyshevNorm(); MantExpComplex ZCoeff = new MantExpComplexFull(ZCoeffExp, ZCoeffExpIm, ZCoeffRe, ZCoeffIm); MantExpComplex CCoeff = new MantExpComplexFull(CCoeffExp, CCoeffExpIm, CCoeffRe, CCoeffIm); - MantExp ChebyMagZCoeff = ZCoeff.chebychevNorm(); - MantExp ChebyMagCCoeff = CCoeff.chebychevNorm(); + MantExp ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + MantExp ChebyMagCCoeff = CCoeff.chebyshevNorm(); MantExp temp1 = ChebyMagz.divide(ChebyMagZCoeff).multiply_mutable(LAThresholdScale); temp1.Normalize(); @@ -157,29 +160,29 @@ protected boolean isZCoeffZero() { } @Override - protected GenericLAInfo Step(int zRefIndex) { + protected GenericLAInfo Step(int zRefIndex, ReferenceDecompressor referenceDecompressor) { LAInfoDeepFull Result = new LAInfoDeepFull(); - Step(Result, zRefIndex); + Step(Result, zRefIndex, referenceDecompressor); return Result; } @Override - protected boolean Composite(LAInfoDeep out1, LAInfoDeep LA1) { + protected boolean Composite(LAInfoDeep out1, LAInfoDeep LA1, ReferenceDecompressor referenceDecompressor) { LAInfoDeepFull out = (LAInfoDeepFull)out1; LAInfoDeepFull LA = (LAInfoDeepFull)LA1; MantExpComplex z = new MantExpComplexFull(LA.RefExp, LA.RefExpIm, LA.RefRe, LA.RefIm); - MantExp ChebyMagz = z.chebychevNorm(); + MantExp ChebyMagz = z.chebyshevNorm(); MantExpComplex ZCoeff = new MantExpComplexFull(ZCoeffExp, ZCoeffExpIm, ZCoeffRe, ZCoeffIm); MantExpComplex CCoeff = new MantExpComplexFull(CCoeffExp, CCoeffExpIm, CCoeffRe, CCoeffIm); MantExp LAThreshold = new MantExp(LAThresholdExp, LAThresholdMant); MantExp LAThresholdC = new MantExp(LAThresholdCExp, LAThresholdCMant); - MantExp ChebyMagZCoeff = ZCoeff.chebychevNorm(); - MantExp ChebyMagCCoeff = CCoeff.chebychevNorm(); + MantExp ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + MantExp ChebyMagCCoeff = CCoeff.chebyshevNorm(); MantExp temp1 = ChebyMagz.divide(ChebyMagZCoeff).multiply_mutable(LAThresholdScale); temp1.Normalize(); @@ -197,8 +200,8 @@ protected boolean Composite(LAInfoDeep out1, LAInfoDeep LA1) { MantExpComplex outCCoeff = z2.times(CCoeff); outCCoeff.Normalize(); - ChebyMagZCoeff = outZCoeff.chebychevNorm(); - ChebyMagCCoeff = outCCoeff.chebychevNorm(); + ChebyMagZCoeff = outZCoeff.chebyshevNorm(); + ChebyMagCCoeff = outCCoeff.chebyshevNorm(); MantExp temp = outLAThreshold; MantExp LA_LAThreshold = new MantExp(LA.LAThresholdExp, LA.LAThresholdMant); @@ -244,21 +247,21 @@ protected boolean Composite(LAInfoDeep out1, LAInfoDeep LA1) { } @Override - protected LAInfoDeepFull Composite(LAInfoDeep LA) { + protected LAInfoDeepFull Composite(LAInfoDeep LA, ReferenceDecompressor referenceDecompressor) { LAInfoDeepFull Result = new LAInfoDeepFull(); - Composite(Result, LA); + Composite(Result, LA, referenceDecompressor); return Result; } @Override - public LAstep Prepare(MantExpComplex dz) { + public LAstep Prepare(Fractal f, MantExpComplex dz) { //*2 is + 1 MantExpComplex newdz = dz.times(new MantExpComplexFull(RefExp + 1, RefExpIm + 1, RefRe, RefIm).plus_mutable(dz)); newdz.Normalize(); LAstep temp = new LAstep(); - temp.unusable = newdz.chebychevNorm().compareToBothPositiveReduced(new MantExp(LAThresholdExp, LAThresholdMant)) >= 0; + temp.unusable = newdz.chebyshevNorm().compareToBothPositiveReduced(new MantExp(LAThresholdExp, LAThresholdMant)) >= 0; temp.newDzDeep = newdz; return temp; } @@ -283,4 +286,59 @@ public MantExpComplex EvaluateDzdc2(MantExpComplex z, MantExpComplex dzdc2, Mant protected ATInfo CreateAT(GenericLAInfo Next) { return CreateAT(Next, new MantExpComplexFull(ZCoeffExp, ZCoeffExpIm, ZCoeffRe, ZCoeffIm), new MantExpComplexFull(CCoeffExp, CCoeffExpIm, CCoeffRe, CCoeffIm), LAThresholdExp, LAThresholdMant, LAThresholdCExp, LAThresholdCMant); } + + @Override + public String toString() { + return ZCoeffRe + "\n" + + ZCoeffIm + "\n" + + ZCoeffExp + "\n" + + ZCoeffExpIm + "\n" + + CCoeffRe + "\n" + + CCoeffIm + "\n" + + CCoeffExp + "\n" + + CCoeffExpIm + "\n" + + LAThresholdMant + "\n" + + LAThresholdExp + "\n" + + LAThresholdCMant + "\n" + + LAThresholdExp + "\n" + + RefRe + "\n" + + RefIm + "\n" + + RefExp + "\n" + + RefExpIm + "\n"; + } + + @Override + public boolean isEqual(GenericLAInfo other) { + if(other == null) { + return false; + } + if(!(other instanceof LAInfoDeepFull)) { + return false; + } + LAInfoDeepFull oth = (LAInfoDeepFull) other; + if(this == other) { + return true; + } + + return ZCoeffRe == oth.ZCoeffRe && + ZCoeffIm == oth.ZCoeffIm && + ZCoeffExp == oth.ZCoeffExp && + ZCoeffExpIm == oth.ZCoeffExpIm && + + CCoeffRe == oth.CCoeffRe && + CCoeffIm == oth.CCoeffIm && + CCoeffExp == oth.CCoeffExp && + CCoeffExpIm == oth.CCoeffExpIm && + + LAThresholdMant == oth.LAThresholdMant && + LAThresholdExp == oth.LAThresholdExp && + + LAThresholdCMant == oth.LAThresholdCMant && + LAThresholdCExp == oth.LAThresholdCExp && + + RefRe == oth.RefRe && + RefIm == oth.RefIm && + RefExp == oth.RefExp && + RefExpIm == oth.RefExpIm; + } } diff --git a/src/fractalzoomer/core/la/impl/LAInfoDetection2.java b/src/fractalzoomer/core/la/impl/LAInfoDetection2.java index c2a8f67d8..c94898108 100644 --- a/src/fractalzoomer/core/la/impl/LAInfoDetection2.java +++ b/src/fractalzoomer/core/la/impl/LAInfoDetection2.java @@ -1,8 +1,12 @@ package fractalzoomer.core.la.impl; import fractalzoomer.core.Complex; +import fractalzoomer.core.ReferenceDecompressor; import fractalzoomer.core.la.GenericLAInfo; import fractalzoomer.core.la.InvalidCalculationException; +import fractalzoomer.functions.Fractal; + +import static fractalzoomer.core.la.LAReference.f; public class LAInfoDetection2 extends LAInfo { protected double MinMag; @@ -11,35 +15,35 @@ protected LAInfoDetection2() { super(); } - protected LAInfoDetection2(int RefIndex) { - super(RefIndex); + protected LAInfoDetection2(int RefIndex, ReferenceDecompressor referenceDecompressor) { + super(RefIndex, referenceDecompressor); MinMag = 4.0; } @Override protected boolean DetectPeriod(Complex z) { - return z.chebychevNorm() < MinMag * PeriodDetectionThreshold2; + return z.chebyshevNorm() < MinMag * PeriodDetectionThreshold2; } @Override protected boolean Stage0DetectPeriod(Complex z) { - return z.chebychevNorm() < MinMag * Stage0PeriodDetectionThreshold2; + return z.chebyshevNorm() < MinMag * Stage0PeriodDetectionThreshold2; } @Override - protected boolean Step(LAInfo out1, int zRefIndex) throws InvalidCalculationException { + protected boolean Step(LAInfo out1, int zRefIndex, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { LAInfoDetection2 out = (LAInfoDetection2)out1; - Complex z = new Complex(refRe[zRefIndex], refIm[zRefIndex]); + Complex z = f.getArrayValue(referenceDecompressor, Fractal.reference, zRefIndex); - double ChebyMagz = z.chebychevNorm(); + double ChebyMagz = z.chebyshevNorm(); Complex ZCoeff = new Complex(ZCoeffRe, ZCoeffIm); Complex CCoeff = new Complex(CCoeffRe, CCoeffIm); - double ChebyMagZCoeff = ZCoeff.chebychevNorm(); - double ChebyMagCCoeff = CCoeff.chebychevNorm(); + double ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + double ChebyMagCCoeff = CCoeff.chebyshevNorm(); out.LAThreshold = Math.min(LAThreshold, ChebyMagz / ChebyMagZCoeff * LAThresholdScale); out.LAThresholdC = Math.min(LAThresholdC, ChebyMagz / ChebyMagCCoeff * LAThresholdCScale); @@ -69,15 +73,15 @@ protected boolean Step(LAInfo out1, int zRefIndex) throws InvalidCalculationExce } @Override - protected GenericLAInfo Step(int zRefIndex) throws InvalidCalculationException { + protected GenericLAInfo Step(int zRefIndex, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { LAInfoDetection2 Result = new LAInfoDetection2(); - Step(Result, zRefIndex); + Step(Result, zRefIndex, referenceDecompressor); return Result; } @Override - protected boolean Composite(LAInfo out1, LAInfo LA1) throws InvalidCalculationException { + protected boolean Composite(LAInfo out1, LAInfo LA1, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { LAInfoDetection2 out = (LAInfoDetection2)out1; LAInfoDetection2 LA = (LAInfoDetection2)LA1; @@ -86,9 +90,9 @@ protected boolean Composite(LAInfo out1, LAInfo LA1) throws InvalidCalculationEx Complex ZCoeff = new Complex(ZCoeffRe, ZCoeffIm); Complex CCoeff = new Complex(CCoeffRe, CCoeffIm); - double ChebyMagz = z.chebychevNorm(); - double ChebyMagZCoeff = ZCoeff.chebychevNorm(); - double ChebyMagCCoeff = CCoeff.chebychevNorm(); + double ChebyMagz = z.chebyshevNorm(); + double ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + double ChebyMagCCoeff = CCoeff.chebyshevNorm(); out.LAThreshold = Math.min(LAThreshold, ChebyMagz / ChebyMagZCoeff * LAThresholdScale); out.LAThresholdC = Math.min(LAThresholdC, ChebyMagz / ChebyMagCCoeff * LAThresholdCScale); @@ -101,8 +105,8 @@ protected boolean Composite(LAInfo out1, LAInfo LA1) throws InvalidCalculationEx - ChebyMagZCoeff = outZCoeff.chebychevNorm(); - ChebyMagCCoeff = outCCoeff.chebychevNorm(); + ChebyMagZCoeff = outZCoeff.chebyshevNorm(); + ChebyMagCCoeff = outCCoeff.chebyshevNorm(); out.LAThreshold = Math.min(out.LAThreshold, LA.LAThreshold / ChebyMagZCoeff); out.LAThresholdC = Math.min(out.LAThresholdC, LA.LAThreshold / ChebyMagCCoeff); @@ -136,10 +140,10 @@ protected boolean Composite(LAInfo out1, LAInfo LA1) throws InvalidCalculationEx } @Override - protected LAInfoDetection2 Composite(LAInfo LA) throws InvalidCalculationException { + protected LAInfoDetection2 Composite(LAInfo LA, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { LAInfoDetection2 Result = new LAInfoDetection2(); - Composite(Result, LA); + Composite(Result, LA, referenceDecompressor); return Result; } @@ -147,4 +151,41 @@ protected LAInfoDetection2 Composite(LAInfo LA) throws InvalidCalculationExcepti public GenericLAInfo minimize() { return new LAInfo(this); } + + @Override + public String toString() { + return ZCoeffRe + "\n" + + ZCoeffIm + "\n" + + CCoeffRe + "\n" + + CCoeffIm + "\n" + + LAThreshold + "\n" + + LAThresholdC + "\n" + + RefRe + "\n" + + RefIm + "\n" + + MinMag + "\n"; + } + + @Override + public boolean isEqual(GenericLAInfo other) { + if(other == null) { + return false; + } + if(!(other instanceof LAInfoDetection2)) { + return false; + } + LAInfoDetection2 oth = (LAInfoDetection2) other; + if(this == other) { + return true; + } + + return ZCoeffRe == oth.ZCoeffRe && + ZCoeffIm == oth.ZCoeffIm && + CCoeffRe == oth.CCoeffRe && + CCoeffIm == oth.CCoeffIm && + LAThreshold == oth.LAThreshold && + LAThresholdC == oth.LAThresholdC && + RefRe == oth.RefRe && + RefIm == oth.RefIm && + MinMag == oth.MinMag; + } } diff --git a/src/fractalzoomer/core/la/impl_refindex/LAInfoDeepDetection2FullRI.java b/src/fractalzoomer/core/la/impl_refindex/LAInfoDeepDetection2FullRI.java index cc94e5862..a125c280f 100644 --- a/src/fractalzoomer/core/la/impl_refindex/LAInfoDeepDetection2FullRI.java +++ b/src/fractalzoomer/core/la/impl_refindex/LAInfoDeepDetection2FullRI.java @@ -3,7 +3,11 @@ import fractalzoomer.core.MantExp; import fractalzoomer.core.MantExpComplex; import fractalzoomer.core.MantExpComplexFull; +import fractalzoomer.core.ReferenceDecompressor; import fractalzoomer.core.la.GenericLAInfo; +import fractalzoomer.functions.Fractal; + +import static fractalzoomer.core.la.LAReference.f; public class LAInfoDeepDetection2FullRI extends LAInfoDeepFullRI { double MinMagMant; @@ -22,28 +26,28 @@ protected LAInfoDeepDetection2FullRI(int RefIndex) { @Override protected boolean DetectPeriod(MantExpComplex z) { - return z.chebychevNorm().compareToBothPositive(new MantExp(MinMagExp, MinMagMant).multiply(PeriodDetectionThreshold2)) < 0; + return z.chebyshevNorm().compareToBothPositive(new MantExp(MinMagExp, MinMagMant).multiply(PeriodDetectionThreshold2)) < 0; } @Override protected boolean Stage0DetectPeriod(MantExpComplex z) { - return z.chebychevNorm().compareToBothPositive(new MantExp(MinMagExp, MinMagMant).multiply(Stage0PeriodDetectionThreshold2)) < 0; + return z.chebyshevNorm().compareToBothPositive(new MantExp(MinMagExp, MinMagMant).multiply(Stage0PeriodDetectionThreshold2)) < 0; } @Override - protected boolean Step(LAInfoDeepRI out1, int zRefIndex) { + protected boolean Step(LAInfoDeepRI out1, int zRefIndex, ReferenceDecompressor referenceDecompressor) { LAInfoDeepDetection2FullRI out = (LAInfoDeepDetection2FullRI)out1; - MantExpComplex z = new MantExpComplexFull(refExpRe[zRefIndex], refExpIm[zRefIndex], refMantsRe[zRefIndex], refMantsIm[zRefIndex]); + MantExpComplex z = f.getArrayDeepValue(referenceDecompressor, Fractal.referenceDeep, zRefIndex); - MantExp ChebyMagz = z.chebychevNorm(); + MantExp ChebyMagz = z.chebyshevNorm(); MantExpComplex ZCoeff = new MantExpComplexFull(ZCoeffExp, ZCoeffExpIm, ZCoeffRe, ZCoeffIm); MantExpComplex CCoeff = new MantExpComplexFull(CCoeffExp, CCoeffExpIm, CCoeffRe, CCoeffIm); - MantExp ChebyMagZCoeff = ZCoeff.chebychevNorm(); - MantExp ChebyMagCCoeff = CCoeff.chebychevNorm(); + MantExp ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + MantExp ChebyMagCCoeff = CCoeff.chebyshevNorm(); MantExp temp1 = ChebyMagz.divide(ChebyMagZCoeff).multiply_mutable(LAThresholdScale); temp1.Normalize(); @@ -87,22 +91,22 @@ protected boolean Step(LAInfoDeepRI out1, int zRefIndex) { return outMinMag.compareToBothPositive(MinMag.multiply(Stage0PeriodDetectionThreshold2)) < 0; } @Override - protected boolean Composite(LAInfoDeepRI out1, LAInfoDeepRI LA1) { + protected boolean Composite(LAInfoDeepRI out1, LAInfoDeepRI LA1, ReferenceDecompressor referenceDecompressor) { LAInfoDeepDetection2FullRI out = (LAInfoDeepDetection2FullRI)out1; LAInfoDeepDetection2FullRI LA = (LAInfoDeepDetection2FullRI)LA1; int zRefIndex = LA.RefIndex; - MantExpComplex z = new MantExpComplexFull(refExpRe[zRefIndex], refExpIm[zRefIndex], refMantsRe[zRefIndex], refMantsIm[zRefIndex]); - MantExp ChebyMagz = z.chebychevNorm(); + MantExpComplex z = f.getArrayDeepValue(referenceDecompressor, Fractal.referenceDeep, zRefIndex); + MantExp ChebyMagz = z.chebyshevNorm(); MantExpComplex ZCoeff = new MantExpComplexFull(ZCoeffExp, ZCoeffExpIm, ZCoeffRe, ZCoeffIm); MantExpComplex CCoeff = new MantExpComplexFull(CCoeffExp, CCoeffExpIm, CCoeffRe, CCoeffIm); MantExp LAThreshold = new MantExp(LAThresholdExp, LAThresholdMant); MantExp LAThresholdC = new MantExp(LAThresholdCExp, LAThresholdCMant); - MantExp ChebyMagZCoeff = ZCoeff.chebychevNorm(); - MantExp ChebyMagCCoeff = CCoeff.chebychevNorm(); + MantExp ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + MantExp ChebyMagCCoeff = CCoeff.chebyshevNorm(); MantExp temp1 = ChebyMagz.divide(ChebyMagZCoeff).multiply_mutable(LAThresholdScale); temp1.Normalize(); @@ -120,8 +124,8 @@ protected boolean Composite(LAInfoDeepRI out1, LAInfoDeepRI LA1) { MantExpComplex outCCoeff = z2.times(CCoeff); outCCoeff.Normalize(); - ChebyMagZCoeff = outZCoeff.chebychevNorm(); - ChebyMagCCoeff = outCCoeff.chebychevNorm(); + ChebyMagZCoeff = outZCoeff.chebyshevNorm(); + ChebyMagCCoeff = outCCoeff.chebyshevNorm(); MantExp LA_LAThreshold = new MantExp(LA.LAThresholdExp, LA.LAThresholdMant); MantExpComplex LAZCoeff = new MantExpComplexFull(LA.ZCoeffExp, LA.ZCoeffExpIm, LA.ZCoeffRe, LA.ZCoeffIm); @@ -170,10 +174,10 @@ protected boolean Composite(LAInfoDeepRI out1, LAInfoDeepRI LA1) { } @Override - protected LAInfoDeepDetection2FullRI Composite(LAInfoDeepRI LA) { + protected LAInfoDeepDetection2FullRI Composite(LAInfoDeepRI LA, ReferenceDecompressor referenceDecompressor) { LAInfoDeepDetection2FullRI Result = new LAInfoDeepDetection2FullRI(); - Composite(Result, LA); + Composite(Result, LA, referenceDecompressor); return Result; } @@ -183,10 +187,64 @@ public GenericLAInfo minimize() { } @Override - protected GenericLAInfo Step(int RefIndex) { + protected GenericLAInfo Step(int RefIndex, ReferenceDecompressor referenceDecompressor) { LAInfoDeepDetection2FullRI Result = new LAInfoDeepDetection2FullRI(); - Step(Result, RefIndex); + Step(Result, RefIndex, referenceDecompressor); return Result; } + + @Override + public String toString() { + return ZCoeffRe + "\n" + + ZCoeffIm + "\n" + + ZCoeffExp + "\n" + + ZCoeffExpIm + "\n" + + CCoeffRe + "\n" + + CCoeffIm + "\n" + + CCoeffExp + "\n" + + CCoeffExpIm + "\n" + + LAThresholdMant + "\n" + + LAThresholdExp + "\n" + + LAThresholdCMant + "\n" + + LAThresholdExp + "\n" + + RefIndex + "\n" + + MinMagMant + "\n" + + MinMagExp + "\n"; + } + + @Override + public boolean isEqual(GenericLAInfo other) { + if(other == null) { + return false; + } + if(!(other instanceof LAInfoDeepDetection2FullRI)) { + return false; + } + LAInfoDeepDetection2FullRI oth = (LAInfoDeepDetection2FullRI) other; + if(this == other) { + return true; + } + + return ZCoeffRe == oth.ZCoeffRe && + ZCoeffIm == oth.ZCoeffIm && + ZCoeffExp == oth.ZCoeffExp && + ZCoeffExpIm == oth.ZCoeffExpIm && + + CCoeffRe == oth.CCoeffRe && + CCoeffIm == oth.CCoeffIm && + CCoeffExp == oth.CCoeffExp && + CCoeffExpIm == oth.CCoeffExpIm && + + LAThresholdMant == oth.LAThresholdMant && + LAThresholdExp == oth.LAThresholdExp && + + LAThresholdCMant == oth.LAThresholdCMant && + LAThresholdCExp == oth.LAThresholdCExp && + + RefIndex == oth.RefIndex && + + MinMagMant == oth.MinMagMant && + MinMagExp == oth.MinMagExp; + } } diff --git a/src/fractalzoomer/core/la/impl_refindex/LAInfoDeepDetection2RI.java b/src/fractalzoomer/core/la/impl_refindex/LAInfoDeepDetection2RI.java index ab08569bf..2e207989f 100644 --- a/src/fractalzoomer/core/la/impl_refindex/LAInfoDeepDetection2RI.java +++ b/src/fractalzoomer/core/la/impl_refindex/LAInfoDeepDetection2RI.java @@ -2,7 +2,11 @@ import fractalzoomer.core.MantExp; import fractalzoomer.core.MantExpComplex; +import fractalzoomer.core.ReferenceDecompressor; import fractalzoomer.core.la.GenericLAInfo; +import fractalzoomer.functions.Fractal; + +import static fractalzoomer.core.la.LAReference.f; public class LAInfoDeepDetection2RI extends LAInfoDeepRI { double MinMagMant; @@ -21,27 +25,27 @@ protected LAInfoDeepDetection2RI(int RefIndex) { @Override protected boolean DetectPeriod(MantExpComplex z) { - return z.chebychevNorm().compareToBothPositive(new MantExp(MinMagExp, MinMagMant).multiply(PeriodDetectionThreshold2)) < 0; + return z.chebyshevNorm().compareToBothPositive(new MantExp(MinMagExp, MinMagMant).multiply(PeriodDetectionThreshold2)) < 0; } @Override protected boolean Stage0DetectPeriod(MantExpComplex z) { - return z.chebychevNorm().compareToBothPositive(new MantExp(MinMagExp, MinMagMant).multiply(Stage0PeriodDetectionThreshold2)) < 0; + return z.chebyshevNorm().compareToBothPositive(new MantExp(MinMagExp, MinMagMant).multiply(Stage0PeriodDetectionThreshold2)) < 0; } @Override - protected boolean Step(LAInfoDeepRI out1, int zRefIndex) { + protected boolean Step(LAInfoDeepRI out1, int zRefIndex, ReferenceDecompressor referenceDecompressor) { LAInfoDeepDetection2RI out = (LAInfoDeepDetection2RI)out1; - MantExpComplex z = new MantExpComplex(refExpRe[zRefIndex], refMantsRe[zRefIndex], refMantsIm[zRefIndex]); + MantExpComplex z = f.getArrayDeepValue(referenceDecompressor, Fractal.referenceDeep, zRefIndex); - MantExp ChebyMagz = z.chebychevNorm(); + MantExp ChebyMagz = z.chebyshevNorm(); MantExpComplex ZCoeff = new MantExpComplex(ZCoeffExp, ZCoeffRe, ZCoeffIm); MantExpComplex CCoeff = new MantExpComplex(CCoeffExp, CCoeffRe, CCoeffIm); - MantExp ChebyMagZCoeff = ZCoeff.chebychevNorm(); - MantExp ChebyMagCCoeff = CCoeff.chebychevNorm(); + MantExp ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + MantExp ChebyMagCCoeff = CCoeff.chebyshevNorm(); MantExp temp1 = ChebyMagz.divide(ChebyMagZCoeff).multiply_mutable(LAThresholdScale); temp1.Normalize(); @@ -85,22 +89,22 @@ protected boolean Step(LAInfoDeepRI out1, int zRefIndex) { } @Override - protected boolean Composite(LAInfoDeepRI out1, LAInfoDeepRI LA1) { + protected boolean Composite(LAInfoDeepRI out1, LAInfoDeepRI LA1, ReferenceDecompressor referenceDecompressor) { LAInfoDeepDetection2RI out = (LAInfoDeepDetection2RI)out1; LAInfoDeepDetection2RI LA = (LAInfoDeepDetection2RI)LA1; int zRefIndex = LA.RefIndex; - MantExpComplex z = new MantExpComplex(refExpRe[zRefIndex], refMantsRe[zRefIndex], refMantsIm[zRefIndex]); - MantExp ChebyMagz = z.chebychevNorm(); + MantExpComplex z = f.getArrayDeepValue(referenceDecompressor, Fractal.referenceDeep, zRefIndex); + MantExp ChebyMagz = z.chebyshevNorm(); MantExpComplex ZCoeff = new MantExpComplex(ZCoeffExp, ZCoeffRe, ZCoeffIm); MantExpComplex CCoeff = new MantExpComplex(CCoeffExp, CCoeffRe, CCoeffIm); MantExp LAThreshold = new MantExp(LAThresholdExp, LAThresholdMant); MantExp LAThresholdC = new MantExp(LAThresholdCExp, LAThresholdCMant); - MantExp ChebyMagZCoeff = ZCoeff.chebychevNorm(); - MantExp ChebyMagCCoeff = CCoeff.chebychevNorm(); + MantExp ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + MantExp ChebyMagCCoeff = CCoeff.chebyshevNorm(); MantExp temp1 = ChebyMagz.divide(ChebyMagZCoeff).multiply_mutable(LAThresholdScale); temp1.Normalize(); @@ -118,8 +122,8 @@ protected boolean Composite(LAInfoDeepRI out1, LAInfoDeepRI LA1) { MantExpComplex outCCoeff = z2.times(CCoeff); outCCoeff.Normalize(); - ChebyMagZCoeff = outZCoeff.chebychevNorm(); - ChebyMagCCoeff = outCCoeff.chebychevNorm(); + ChebyMagZCoeff = outZCoeff.chebyshevNorm(); + ChebyMagCCoeff = outCCoeff.chebyshevNorm(); MantExp LA_LAThreshold = new MantExp(LA.LAThresholdExp, LA.LAThresholdMant); MantExpComplex LAZCoeff = new MantExpComplex(LA.ZCoeffExp, LA.ZCoeffRe, LA.ZCoeffIm); @@ -165,18 +169,18 @@ protected boolean Composite(LAInfoDeepRI out1, LAInfoDeepRI LA1) { return temp.compareToBothPositive(MinMag.multiply(PeriodDetectionThreshold2)) < 0; } @Override - protected LAInfoDeepDetection2RI Composite(LAInfoDeepRI LA) { + protected LAInfoDeepDetection2RI Composite(LAInfoDeepRI LA, ReferenceDecompressor referenceDecompressor) { LAInfoDeepDetection2RI Result = new LAInfoDeepDetection2RI(); - Composite(Result, LA); + Composite(Result, LA, referenceDecompressor); return Result; } @Override - protected LAInfoDeepDetection2RI Step(int RefIndex) { + protected LAInfoDeepDetection2RI Step(int RefIndex, ReferenceDecompressor referenceDecompressor) { LAInfoDeepDetection2RI Result = new LAInfoDeepDetection2RI(); - Step(Result, RefIndex); + Step(Result, RefIndex, referenceDecompressor); return Result; } @@ -184,4 +188,54 @@ protected LAInfoDeepDetection2RI Step(int RefIndex) { public GenericLAInfo minimize() { return new LAInfoDeepRI(this); } + + @Override + public String toString() { + return ZCoeffRe + "\n" + + ZCoeffIm + "\n" + + ZCoeffExp + "\n" + + CCoeffRe + "\n" + + CCoeffIm + "\n" + + CCoeffExp + "\n" + + LAThresholdMant + "\n" + + LAThresholdExp + "\n" + + LAThresholdCMant + "\n" + + LAThresholdExp + "\n" + + RefIndex + "\n" + + MinMagMant + "\n" + + MinMagExp + "\n"; + } + + @Override + public boolean isEqual(GenericLAInfo other) { + if(other == null) { + return false; + } + if(!(other instanceof LAInfoDeepDetection2RI)) { + return false; + } + LAInfoDeepDetection2RI oth = (LAInfoDeepDetection2RI) other; + if(this == other) { + return true; + } + + return ZCoeffRe == oth.ZCoeffRe && + ZCoeffIm == oth.ZCoeffIm && + ZCoeffExp == oth.ZCoeffExp && + + CCoeffRe == oth.CCoeffRe && + CCoeffIm == oth.CCoeffIm && + CCoeffExp == oth.CCoeffExp && + + LAThresholdMant == oth.LAThresholdMant && + LAThresholdExp == oth.LAThresholdExp && + + LAThresholdCMant == oth.LAThresholdCMant && + LAThresholdCExp == oth.LAThresholdCExp && + + RefIndex == oth.RefIndex && + + MinMagMant == oth.MinMagMant && + MinMagExp == oth.MinMagExp; + } } diff --git a/src/fractalzoomer/core/la/impl_refindex/LAInfoDeepFullRI.java b/src/fractalzoomer/core/la/impl_refindex/LAInfoDeepFullRI.java index abf8bee65..d88f7a0d2 100644 --- a/src/fractalzoomer/core/la/impl_refindex/LAInfoDeepFullRI.java +++ b/src/fractalzoomer/core/la/impl_refindex/LAInfoDeepFullRI.java @@ -1,12 +1,12 @@ package fractalzoomer.core.la.impl_refindex; -import fractalzoomer.core.GenericComplex; -import fractalzoomer.core.MantExp; -import fractalzoomer.core.MantExpComplex; -import fractalzoomer.core.MantExpComplexFull; +import fractalzoomer.core.*; import fractalzoomer.core.la.ATInfo; import fractalzoomer.core.la.GenericLAInfo; import fractalzoomer.core.la.LAstep; +import fractalzoomer.functions.Fractal; + +import static fractalzoomer.core.la.LAReference.f; public class LAInfoDeepFullRI extends LAInfoDeepRI { long ZCoeffExpIm; @@ -63,17 +63,17 @@ protected LAInfoDeepFullRI(int RefIndex) { @Override protected boolean DetectPeriod(MantExpComplex z) { - return z.chebychevNorm().divide(new MantExpComplexFull(ZCoeffExp, ZCoeffExpIm, ZCoeffRe, ZCoeffIm).chebychevNorm()).multiply_mutable(LAThresholdScale).compareToBothPositive(new MantExp(LAThresholdExp, LAThresholdMant).multiply(PeriodDetectionThreshold)) < 0; + return z.chebyshevNorm().divide(new MantExpComplexFull(ZCoeffExp, ZCoeffExpIm, ZCoeffRe, ZCoeffIm).chebyshevNorm()).multiply_mutable(LAThresholdScale).compareToBothPositive(new MantExp(LAThresholdExp, LAThresholdMant).multiply(PeriodDetectionThreshold)) < 0; } @Override protected boolean Stage0DetectPeriod(MantExpComplex z) { - return z.chebychevNorm().divide(new MantExpComplexFull(ZCoeffExp, ZCoeffExpIm, ZCoeffRe, ZCoeffIm).chebychevNorm()).multiply_mutable(LAThresholdScale).compareToBothPositive(new MantExp(LAThresholdExp, LAThresholdMant).multiply(Stage0PeriodDetectionThreshold)) < 0; + return z.chebyshevNorm().divide(new MantExpComplexFull(ZCoeffExp, ZCoeffExpIm, ZCoeffRe, ZCoeffIm).chebyshevNorm()).multiply_mutable(LAThresholdScale).compareToBothPositive(new MantExp(LAThresholdExp, LAThresholdMant).multiply(Stage0PeriodDetectionThreshold)) < 0; } @Override - public GenericComplex getRef() { - return new MantExpComplexFull(refExpRe[RefIndex], refExpIm[RefIndex], refMantsRe[RefIndex], refMantsIm[RefIndex]); + public GenericComplex getRef(Fractal f) { + return f.getArrayDeepValue(Fractal.referenceDeep, RefIndex); } @Override @@ -87,19 +87,19 @@ public GenericComplex getCCoeff() { } @Override - protected boolean Step(LAInfoDeepRI out1, int zRefIndex) { + protected boolean Step(LAInfoDeepRI out1, int zRefIndex, ReferenceDecompressor referenceDecompressor) { LAInfoDeepFullRI out = (LAInfoDeepFullRI)out1; - MantExpComplex z = new MantExpComplexFull(refExpRe[zRefIndex], refExpIm[zRefIndex], refMantsRe[zRefIndex], refMantsIm[zRefIndex]); + MantExpComplex z = f.getArrayDeepValue(referenceDecompressor, Fractal.referenceDeep, zRefIndex); - MantExp ChebyMagz = z.chebychevNorm(); + MantExp ChebyMagz = z.chebyshevNorm(); MantExpComplex ZCoeff = new MantExpComplexFull(ZCoeffExp, ZCoeffExpIm, ZCoeffRe, ZCoeffIm); MantExpComplex CCoeff = new MantExpComplexFull(CCoeffExp, CCoeffExpIm, CCoeffRe, CCoeffIm); - MantExp ChebyMagZCoeff = ZCoeff.chebychevNorm(); - MantExp ChebyMagCCoeff = CCoeff.chebychevNorm(); + MantExp ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + MantExp ChebyMagCCoeff = CCoeff.chebyshevNorm(); MantExp temp1 = ChebyMagz.divide(ChebyMagZCoeff).multiply_mutable(LAThresholdScale); temp1.Normalize(); @@ -145,23 +145,23 @@ protected boolean isZCoeffZero() { } @Override - protected boolean Composite(LAInfoDeepRI out1, LAInfoDeepRI LA1) { + protected boolean Composite(LAInfoDeepRI out1, LAInfoDeepRI LA1, ReferenceDecompressor referenceDecompressor) { LAInfoDeepFullRI out = (LAInfoDeepFullRI)out1; LAInfoDeepFullRI LA = (LAInfoDeepFullRI)LA1; int zRefIndex = LA.RefIndex; - MantExpComplex z = new MantExpComplexFull(refExpRe[zRefIndex], refExpIm[zRefIndex], refMantsRe[zRefIndex], refMantsIm[zRefIndex]); - MantExp ChebyMagz = z.chebychevNorm(); + MantExpComplex z = f.getArrayDeepValue(referenceDecompressor, Fractal.referenceDeep, zRefIndex); + MantExp ChebyMagz = z.chebyshevNorm(); MantExpComplex ZCoeff = new MantExpComplexFull(ZCoeffExp, ZCoeffExpIm, ZCoeffRe, ZCoeffIm); MantExpComplex CCoeff = new MantExpComplexFull(CCoeffExp, CCoeffExpIm, CCoeffRe, CCoeffIm); MantExp LAThreshold = new MantExp(LAThresholdExp, LAThresholdMant); MantExp LAThresholdC = new MantExp(LAThresholdCExp, LAThresholdCMant); - MantExp ChebyMagZCoeff = ZCoeff.chebychevNorm(); - MantExp ChebyMagCCoeff = CCoeff.chebychevNorm(); + MantExp ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + MantExp ChebyMagCCoeff = CCoeff.chebyshevNorm(); MantExp temp1 = ChebyMagz.divide(ChebyMagZCoeff).multiply_mutable(LAThresholdScale); temp1.Normalize(); @@ -179,8 +179,8 @@ protected boolean Composite(LAInfoDeepRI out1, LAInfoDeepRI LA1) { MantExpComplex outCCoeff = z2.times(CCoeff); outCCoeff.Normalize(); - ChebyMagZCoeff = outZCoeff.chebychevNorm(); - ChebyMagCCoeff = outCCoeff.chebychevNorm(); + ChebyMagZCoeff = outZCoeff.chebyshevNorm(); + ChebyMagCCoeff = outCCoeff.chebyshevNorm(); MantExp temp = outLAThreshold; MantExp LA_LAThreshold = new MantExp(LA.LAThresholdExp, LA.LAThresholdMant); @@ -223,21 +223,21 @@ protected boolean Composite(LAInfoDeepRI out1, LAInfoDeepRI LA1) { } @Override - protected LAInfoDeepFullRI Composite(LAInfoDeepRI LA) { + protected LAInfoDeepFullRI Composite(LAInfoDeepRI LA, ReferenceDecompressor referenceDecompressor) { LAInfoDeepFullRI Result = new LAInfoDeepFullRI(); - Composite(Result, LA); + Composite(Result, LA, referenceDecompressor); return Result; } @Override - protected LAstep Prepare(MantExpComplex dz) { + protected LAstep Prepare(Fractal f, MantExpComplex dz) { //*2 is + 1 - MantExpComplex newdz = dz.times(new MantExpComplexFull(refExpRe[RefIndex] + 1, refExpIm[RefIndex] + 1, refMantsRe[RefIndex], refMantsIm[RefIndex]).plus_mutable(dz)); + MantExpComplex newdz = dz.times(f.getArrayDeepValue(Fractal.referenceDeep, RefIndex).times2_mutable().plus_mutable(dz)); newdz.Normalize(); LAstep temp = new LAstep(); - temp.unusable = newdz.chebychevNorm().compareToBothPositiveReduced(new MantExp(LAThresholdExp, LAThresholdMant)) >= 0; + temp.unusable = newdz.chebyshevNorm().compareToBothPositiveReduced(new MantExp(LAThresholdExp, LAThresholdMant)) >= 0; temp.newDzDeep = newdz; return temp; } @@ -263,10 +263,59 @@ protected ATInfo CreateAT(GenericLAInfo Next) { } @Override - protected GenericLAInfo Step(int RefIndex) { + protected GenericLAInfo Step(int RefIndex, ReferenceDecompressor referenceDecompressor) { LAInfoDeepFullRI Result = new LAInfoDeepFullRI(); - Step(Result, RefIndex); + Step(Result, RefIndex, referenceDecompressor); return Result; } + + @Override + public String toString() { + return ZCoeffRe + "\n" + + ZCoeffIm + "\n" + + ZCoeffExp + "\n" + + ZCoeffExpIm + "\n" + + CCoeffRe + "\n" + + CCoeffIm + "\n" + + CCoeffExp + "\n" + + CCoeffExpIm + "\n" + + LAThresholdMant + "\n" + + LAThresholdExp + "\n" + + LAThresholdCMant + "\n" + + LAThresholdExp + "\n" + + RefIndex; + } + + @Override + public boolean isEqual(GenericLAInfo other) { + if(other == null) { + return false; + } + if(!(other instanceof LAInfoDeepFullRI)) { + return false; + } + LAInfoDeepFullRI oth = (LAInfoDeepFullRI) other; + if(this == other) { + return true; + } + + return ZCoeffRe == oth.ZCoeffRe && + ZCoeffIm == oth.ZCoeffIm && + ZCoeffExp == oth.ZCoeffExp && + ZCoeffExpIm == oth.ZCoeffExpIm && + + CCoeffRe == oth.CCoeffRe && + CCoeffIm == oth.CCoeffIm && + CCoeffExp == oth.CCoeffExp && + CCoeffExpIm == oth.CCoeffExpIm && + + LAThresholdMant == oth.LAThresholdMant && + LAThresholdExp == oth.LAThresholdExp && + + LAThresholdCMant == oth.LAThresholdCMant && + LAThresholdCExp == oth.LAThresholdCExp && + + RefIndex == oth.RefIndex; + } } diff --git a/src/fractalzoomer/core/la/impl_refindex/LAInfoDeepRI.java b/src/fractalzoomer/core/la/impl_refindex/LAInfoDeepRI.java index 09e6a2810..23ca13624 100644 --- a/src/fractalzoomer/core/la/impl_refindex/LAInfoDeepRI.java +++ b/src/fractalzoomer/core/la/impl_refindex/LAInfoDeepRI.java @@ -1,13 +1,14 @@ package fractalzoomer.core.la.impl_refindex; -import fractalzoomer.core.GenericComplex; -import fractalzoomer.core.MantExp; -import fractalzoomer.core.MantExpComplex; -import fractalzoomer.core.TaskDraw; +import fractalzoomer.core.*; import fractalzoomer.core.la.GenericLAInfo; import fractalzoomer.core.la.LAInfoBaseDeep; import fractalzoomer.core.la.LAstep; import fractalzoomer.core.la.impl.LAInfo; +import fractalzoomer.core.la.impl.LAInfoDeep; +import fractalzoomer.functions.Fractal; + +import static fractalzoomer.core.la.LAReference.f; public class LAInfoDeepRI extends LAInfoBaseDeep { int RefIndex; @@ -88,20 +89,20 @@ protected LAInfoDeepRI(int RefIndex) { } @Override - public GenericComplex getRef() { - return new MantExpComplex(refExpRe[RefIndex], refMantsRe[RefIndex], refMantsIm[RefIndex]); + public GenericComplex getRef(Fractal f) { + return f.getArrayDeepValue(Fractal.referenceDeep, RefIndex); } @Override - protected boolean Step(LAInfoDeepRI out, int zRefIndex) { - MantExpComplex z = new MantExpComplex(refExpRe[zRefIndex], refMantsRe[zRefIndex], refMantsIm[zRefIndex]); - MantExp ChebyMagz = z.chebychevNorm(); + protected boolean Step(LAInfoDeepRI out, int zRefIndex, ReferenceDecompressor referenceDecompressor) { + MantExpComplex z = f.getArrayDeepValue(referenceDecompressor, Fractal.referenceDeep, zRefIndex); + MantExp ChebyMagz = z.chebyshevNorm(); MantExpComplex ZCoeff = new MantExpComplex(ZCoeffExp, ZCoeffRe, ZCoeffIm); MantExpComplex CCoeff = new MantExpComplex(CCoeffExp, CCoeffRe, CCoeffIm); - MantExp ChebyMagZCoeff = ZCoeff.chebychevNorm(); - MantExp ChebyMagCCoeff = CCoeff.chebychevNorm(); + MantExp ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + MantExp ChebyMagCCoeff = CCoeff.chebyshevNorm(); MantExp temp1 = ChebyMagz.divide(ChebyMagZCoeff).multiply_mutable(LAThresholdScale); temp1.Normalize(); @@ -139,18 +140,18 @@ protected boolean Step(LAInfoDeepRI out, int zRefIndex) { } @Override - protected boolean Composite(LAInfoDeepRI out, LAInfoDeepRI LA) { + protected boolean Composite(LAInfoDeepRI out, LAInfoDeepRI LA, ReferenceDecompressor referenceDecompressor) { int zRefIndex = LA.RefIndex; - MantExpComplex z = new MantExpComplex(refExpRe[zRefIndex], refMantsRe[zRefIndex], refMantsIm[zRefIndex]); - MantExp ChebyMagz = z.chebychevNorm(); + MantExpComplex z = f.getArrayDeepValue(referenceDecompressor, Fractal.referenceDeep, zRefIndex); + MantExp ChebyMagz = z.chebyshevNorm(); MantExpComplex ZCoeff = new MantExpComplex(ZCoeffExp, ZCoeffRe, ZCoeffIm); MantExpComplex CCoeff = new MantExpComplex(CCoeffExp, CCoeffRe, CCoeffIm); MantExp LAThreshold = new MantExp(LAThresholdExp, LAThresholdMant); MantExp LAThresholdC = new MantExp(LAThresholdCExp, LAThresholdCMant); - MantExp ChebyMagZCoeff = ZCoeff.chebychevNorm(); - MantExp ChebyMagCCoeff = CCoeff.chebychevNorm(); + MantExp ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + MantExp ChebyMagCCoeff = CCoeff.chebyshevNorm(); MantExp temp1 = ChebyMagz.divide(ChebyMagZCoeff).multiply_mutable(LAThresholdScale); temp1.Normalize(); @@ -168,8 +169,8 @@ protected boolean Composite(LAInfoDeepRI out, LAInfoDeepRI LA) { MantExpComplex outCCoeff = z2.times(CCoeff); outCCoeff.Normalize(); - ChebyMagZCoeff = outZCoeff.chebychevNorm(); - ChebyMagCCoeff = outCCoeff.chebychevNorm(); + ChebyMagZCoeff = outZCoeff.chebyshevNorm(); + ChebyMagCCoeff = outCCoeff.chebyshevNorm(); MantExp temp = outLAThreshold; MantExp LA_LAThreshold = new MantExp(LA.LAThresholdExp, LA.LAThresholdMant); @@ -210,30 +211,28 @@ protected boolean Composite(LAInfoDeepRI out, LAInfoDeepRI LA) { } @Override - protected LAInfoDeepRI Composite(LAInfoDeepRI LA) { + protected LAInfoDeepRI Composite(LAInfoDeepRI LA, ReferenceDecompressor referenceDecompressor) { LAInfoDeepRI Result = new LAInfoDeepRI(); - Composite(Result, LA); + Composite(Result, LA, referenceDecompressor); return Result; } @Override - protected GenericLAInfo Step(int RefIndex) { + protected GenericLAInfo Step(int RefIndex, ReferenceDecompressor referenceDecompressor) { LAInfoDeepRI Result = new LAInfoDeepRI(); - Step(Result, RefIndex); + Step(Result, RefIndex, referenceDecompressor); return Result; } @Override - protected LAstep Prepare(MantExpComplex dz) { - //*2 is + 1 - - MantExpComplex newdz = dz.times(new MantExpComplex(refExpRe[RefIndex] + 1, refMantsRe[RefIndex], refMantsIm[RefIndex]).plus_mutable(dz)); + protected LAstep Prepare(Fractal f, MantExpComplex dz) { + MantExpComplex newdz = dz.times(f.getArrayDeepValue(Fractal.referenceDeep, RefIndex).times2_mutable().plus_mutable(dz)); newdz.Normalize(); LAstep temp = new LAstep(); - temp.unusable = newdz.chebychevNorm().compareToBothPositiveReduced(new MantExp(LAThresholdExp, LAThresholdMant)) >= 0; + temp.unusable = newdz.chebyshevNorm().compareToBothPositiveReduced(new MantExp(LAThresholdExp, LAThresholdMant)) >= 0; temp.newDzDeep = newdz; return temp; } @@ -241,4 +240,49 @@ protected LAstep Prepare(MantExpComplex dz) { public GenericLAInfo toDouble() { return new LAInfoRI(this); } + + @Override + public String toString() { + return ZCoeffRe + "\n" + + ZCoeffIm + "\n" + + ZCoeffExp + "\n" + + CCoeffRe + "\n" + + CCoeffIm + "\n" + + CCoeffExp + "\n" + + LAThresholdMant + "\n" + + LAThresholdExp + "\n" + + LAThresholdCMant + "\n" + + LAThresholdExp + "\n" + + RefIndex + "\n"; + } + + @Override + public boolean isEqual(GenericLAInfo other) { + if(other == null) { + return false; + } + if(!(other instanceof LAInfoDeepRI)) { + return false; + } + LAInfoDeepRI oth = (LAInfoDeepRI) other; + if(this == other) { + return true; + } + + return ZCoeffRe == oth.ZCoeffRe && + ZCoeffIm == oth.ZCoeffIm && + ZCoeffExp == oth.ZCoeffExp && + + CCoeffRe == oth.CCoeffRe && + CCoeffIm == oth.CCoeffIm && + CCoeffExp == oth.CCoeffExp && + + LAThresholdMant == oth.LAThresholdMant && + LAThresholdExp == oth.LAThresholdExp && + + LAThresholdCMant == oth.LAThresholdCMant && + LAThresholdCExp == oth.LAThresholdCExp && + + RefIndex == oth.RefIndex; + } } diff --git a/src/fractalzoomer/core/la/impl_refindex/LAInfoDetection2RI.java b/src/fractalzoomer/core/la/impl_refindex/LAInfoDetection2RI.java index 454e1120f..4c2cf7a52 100644 --- a/src/fractalzoomer/core/la/impl_refindex/LAInfoDetection2RI.java +++ b/src/fractalzoomer/core/la/impl_refindex/LAInfoDetection2RI.java @@ -1,8 +1,12 @@ package fractalzoomer.core.la.impl_refindex; import fractalzoomer.core.Complex; +import fractalzoomer.core.ReferenceDecompressor; import fractalzoomer.core.la.GenericLAInfo; import fractalzoomer.core.la.InvalidCalculationException; +import fractalzoomer.functions.Fractal; + +import static fractalzoomer.core.la.LAReference.f; public class LAInfoDetection2RI extends LAInfoRI { protected double MinMag; @@ -18,36 +22,36 @@ protected LAInfoDetection2RI(int RefIndex) { @Override protected boolean DetectPeriod(Complex z) { - return z.chebychevNorm() < MinMag * PeriodDetectionThreshold2; + return z.chebyshevNorm() < MinMag * PeriodDetectionThreshold2; } @Override protected boolean Stage0DetectPeriod(Complex z) { - return z.chebychevNorm() < MinMag * Stage0PeriodDetectionThreshold2; + return z.chebyshevNorm() < MinMag * Stage0PeriodDetectionThreshold2; } @Override - protected GenericLAInfo Step(int RefIndex) throws InvalidCalculationException { + protected GenericLAInfo Step(int RefIndex, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { LAInfoDetection2RI Result = new LAInfoDetection2RI(); - Step(Result, RefIndex); + Step(Result, RefIndex, referenceDecompressor); return Result; } @Override - protected boolean Step(LAInfoRI out1, int zRefIndex) throws InvalidCalculationException { + protected boolean Step(LAInfoRI out1, int zRefIndex, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { LAInfoDetection2RI out = (LAInfoDetection2RI)out1; - Complex z = new Complex(refRe[zRefIndex], refIm[zRefIndex]); + Complex z = f.getArrayValue(referenceDecompressor, Fractal.reference, zRefIndex); - double ChebyMagz = z.chebychevNorm(); + double ChebyMagz = z.chebyshevNorm(); Complex ZCoeff = new Complex(ZCoeffRe, ZCoeffIm); Complex CCoeff = new Complex(CCoeffRe, CCoeffIm); - double ChebyMagZCoeff = ZCoeff.chebychevNorm(); - double ChebyMagCCoeff = CCoeff.chebychevNorm(); + double ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + double ChebyMagCCoeff = CCoeff.chebyshevNorm(); out.LAThreshold = Math.min(LAThreshold, ChebyMagz / ChebyMagZCoeff * LAThresholdScale); out.LAThresholdC = Math.min(LAThresholdC, ChebyMagz / ChebyMagCCoeff * LAThresholdCScale); @@ -76,19 +80,19 @@ protected boolean Step(LAInfoRI out1, int zRefIndex) throws InvalidCalculationEx } @Override - protected boolean Composite(LAInfoRI out1, LAInfoRI LA1) throws InvalidCalculationException { + protected boolean Composite(LAInfoRI out1, LAInfoRI LA1, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { LAInfoDetection2RI out = (LAInfoDetection2RI)out1; LAInfoDetection2RI LA = (LAInfoDetection2RI)LA1; int zRefIndex = LA.RefIndex; - Complex z = new Complex(refRe[zRefIndex], refIm[zRefIndex]); + Complex z = f.getArrayValue(referenceDecompressor, Fractal.reference, zRefIndex); Complex ZCoeff = new Complex(ZCoeffRe, ZCoeffIm); Complex CCoeff = new Complex(CCoeffRe, CCoeffIm); - double ChebyMagz = z.chebychevNorm(); - double ChebyMagZCoeff = ZCoeff.chebychevNorm(); - double ChebyMagCCoeff = CCoeff.chebychevNorm(); + double ChebyMagz = z.chebyshevNorm(); + double ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + double ChebyMagCCoeff = CCoeff.chebyshevNorm(); out.LAThreshold = Math.min(LAThreshold, ChebyMagz / ChebyMagZCoeff * LAThresholdScale); out.LAThresholdC = Math.min(LAThresholdC, ChebyMagz / ChebyMagCCoeff * LAThresholdCScale); @@ -101,8 +105,8 @@ protected boolean Composite(LAInfoRI out1, LAInfoRI LA1) throws InvalidCalculati - ChebyMagZCoeff = outZCoeff.chebychevNorm(); - ChebyMagCCoeff = outCCoeff.chebychevNorm(); + ChebyMagZCoeff = outZCoeff.chebyshevNorm(); + ChebyMagCCoeff = outCCoeff.chebyshevNorm(); out.LAThreshold = Math.min(out.LAThreshold, LA.LAThreshold / ChebyMagZCoeff); out.LAThresholdC = Math.min(out.LAThresholdC, LA.LAThreshold / ChebyMagCCoeff); @@ -135,10 +139,10 @@ protected boolean Composite(LAInfoRI out1, LAInfoRI LA1) throws InvalidCalculati } @Override - protected LAInfoDetection2RI Composite(LAInfoRI LA) throws InvalidCalculationException { + protected LAInfoDetection2RI Composite(LAInfoRI LA, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { LAInfoDetection2RI Result = new LAInfoDetection2RI(); - Composite(Result, LA); + Composite(Result, LA, referenceDecompressor); return Result; } @@ -146,4 +150,38 @@ protected LAInfoDetection2RI Composite(LAInfoRI LA) throws InvalidCalculationExc public GenericLAInfo minimize() { return new LAInfoRI(this); } + + @Override + public String toString() { + return ZCoeffRe + "\n" + + ZCoeffIm + "\n" + + CCoeffRe + "\n" + + CCoeffIm + "\n" + + LAThreshold + "\n" + + LAThresholdC + "\n" + + RefIndex + "\n" + + MinMag + "\n"; + } + @Override + public boolean isEqual(GenericLAInfo other) { + if(other == null) { + return false; + } + if(!(other instanceof LAInfoDetection2RI)) { + return false; + } + LAInfoDetection2RI oth = (LAInfoDetection2RI) other; + if(this == other) { + return true; + } + + return ZCoeffRe == oth.ZCoeffRe && + ZCoeffIm == oth.ZCoeffIm && + CCoeffRe == oth.CCoeffRe && + CCoeffIm == oth.CCoeffIm && + LAThreshold == oth.LAThreshold && + LAThresholdC == oth.LAThresholdC && + RefIndex == oth.RefIndex && + MinMag == oth.MinMag; + } } diff --git a/src/fractalzoomer/core/la/impl_refindex/LAInfoRI.java b/src/fractalzoomer/core/la/impl_refindex/LAInfoRI.java index e06d6061f..6d6dc8eb7 100644 --- a/src/fractalzoomer/core/la/impl_refindex/LAInfoRI.java +++ b/src/fractalzoomer/core/la/impl_refindex/LAInfoRI.java @@ -3,11 +3,12 @@ import fractalzoomer.core.Complex; import fractalzoomer.core.GenericComplex; import fractalzoomer.core.MantExp; -import fractalzoomer.core.la.GenericLAInfo; -import fractalzoomer.core.la.InvalidCalculationException; -import fractalzoomer.core.la.LAInfoBase; -import fractalzoomer.core.la.LAstep; +import fractalzoomer.core.ReferenceDecompressor; +import fractalzoomer.core.la.*; import fractalzoomer.core.la.impl.LAInfo; +import fractalzoomer.functions.Fractal; + +import static fractalzoomer.core.la.LAReference.f; public class LAInfoRI extends LAInfoBase { int RefIndex; @@ -71,20 +72,20 @@ protected LAInfoRI(LAInfoDeepRI deep) { } @Override - public GenericComplex getRef() { - return new Complex(refRe[RefIndex], refIm[RefIndex]); + public GenericComplex getRef(Fractal f) { + return f.getArrayValue(Fractal.reference, RefIndex); } @Override - protected boolean Step(LAInfoRI out, int zRefIndex) throws InvalidCalculationException { - Complex z = new Complex(refRe[zRefIndex], refIm[zRefIndex]); - double ChebyMagz = z.chebychevNorm(); + protected boolean Step(LAInfoRI out, int zRefIndex, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { + Complex z = f.getArrayValue(referenceDecompressor, Fractal.reference, zRefIndex); + double ChebyMagz = z.chebyshevNorm(); Complex ZCoeff = new Complex(ZCoeffRe, ZCoeffIm); Complex CCoeff = new Complex(CCoeffRe, CCoeffIm); - double ChebyMagZCoeff = ZCoeff.chebychevNorm(); - double ChebyMagCCoeff = CCoeff.chebychevNorm(); + double ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + double ChebyMagCCoeff = CCoeff.chebyshevNorm(); out.LAThreshold = Math.min(LAThreshold, ChebyMagz / ChebyMagZCoeff * LAThresholdScale); out.LAThresholdC = Math.min(LAThresholdC, ChebyMagz / ChebyMagCCoeff * LAThresholdCScale); @@ -111,23 +112,23 @@ protected boolean Step(LAInfoRI out, int zRefIndex) throws InvalidCalculationExc } @Override - protected GenericLAInfo Step(int RefIndex) throws InvalidCalculationException { + protected GenericLAInfo Step(int RefIndex, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { LAInfoRI Result = new LAInfoRI(); - Step(Result, RefIndex); + Step(Result, RefIndex, referenceDecompressor); return Result; } @Override - protected boolean Composite(LAInfoRI out, LAInfoRI LA) throws InvalidCalculationException { + protected boolean Composite(LAInfoRI out, LAInfoRI LA, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { int zRefIndex = LA.RefIndex; - Complex z = new Complex(refRe[zRefIndex], refIm[zRefIndex]); + Complex z = f.getArrayValue(referenceDecompressor, Fractal.reference, zRefIndex); Complex ZCoeff = new Complex(ZCoeffRe, ZCoeffIm); Complex CCoeff = new Complex(CCoeffRe, CCoeffIm); - double ChebyMagz = z.chebychevNorm(); - double ChebyMagZCoeff = ZCoeff.chebychevNorm(); - double ChebyMagCCoeff = CCoeff.chebychevNorm(); + double ChebyMagz = z.chebyshevNorm(); + double ChebyMagZCoeff = ZCoeff.chebyshevNorm(); + double ChebyMagCCoeff = CCoeff.chebyshevNorm(); out.LAThreshold = Math.min(LAThreshold, ChebyMagz / ChebyMagZCoeff * LAThresholdScale); out.LAThresholdC = Math.min(LAThresholdC, ChebyMagz / ChebyMagCCoeff * LAThresholdCScale); @@ -138,8 +139,8 @@ protected boolean Composite(LAInfoRI out, LAInfoRI LA) throws InvalidCalculation //double RescaleFactor = out.LAThreshold / LAThreshold; Complex outCCoeff = z2.times(CCoeff); - ChebyMagZCoeff = outZCoeff.chebychevNorm(); - ChebyMagCCoeff = outCCoeff.chebychevNorm(); + ChebyMagZCoeff = outZCoeff.chebyshevNorm(); + ChebyMagCCoeff = outCCoeff.chebyshevNorm(); double temp = out.LAThreshold; out.LAThreshold = Math.min(out.LAThreshold, LA.LAThreshold / ChebyMagZCoeff); out.LAThresholdC = Math.min(out.LAThresholdC, LA.LAThreshold / ChebyMagCCoeff); @@ -169,27 +170,28 @@ protected boolean Composite(LAInfoRI out, LAInfoRI LA) throws InvalidCalculation } @Override - protected LAInfoRI Composite(LAInfoRI LA) throws InvalidCalculationException { + protected LAInfoRI Composite(LAInfoRI LA, ReferenceDecompressor referenceDecompressor) throws InvalidCalculationException { LAInfoRI Result = new LAInfoRI(); - Composite(Result, LA); + Composite(Result, LA, referenceDecompressor); return Result; } @Override - protected LAstep Prepare(Complex dz) { - Complex newdz = dz.times(new Complex(2 * refRe[RefIndex], 2 * refIm[RefIndex]).plus_mutable(dz)); + protected LAstep Prepare(Fractal f, Complex dz) { + Complex newdz = dz.times(f.getArrayValue(Fractal.reference, RefIndex).times2_mutable().plus_mutable(dz)); LAstep temp = new LAstep(); - temp.unusable = newdz.chebychevNorm() >= LAThreshold; + temp.unusable = newdz.chebyshevNorm() >= LAThreshold; temp.newDz = newdz; return temp; } @Override - protected LAstep Prepare(double dre, double dim) { - double newdre = 2 * refRe[RefIndex] + dre; - double newdim = 2 * refIm[RefIndex] + dim; + protected LAstep Prepare(Fractal f, double dre, double dim) { + Complex ref = f.getArrayValue(Fractal.reference, RefIndex); + double newdre = 2 * ref.getRe() + dre; + double newdim = 2 * ref.getIm() + dim; double temp = newdre * dre - newdim * dim; newdim = newdre * dim + newdim * dre; @@ -201,4 +203,37 @@ protected LAstep Prepare(double dre, double dim) { tempstep.newdim = newdim; return tempstep; } + + @Override + public String toString() { + return ZCoeffRe + "\n" + + ZCoeffIm + "\n" + + CCoeffRe + "\n" + + CCoeffIm + "\n" + + LAThreshold + "\n" + + LAThresholdC + "\n" + + RefIndex + "\n"; + } + + @Override + public boolean isEqual(GenericLAInfo other) { + if(other == null) { + return false; + } + if(!(other instanceof LAInfoRI)) { + return false; + } + LAInfoRI oth = (LAInfoRI) other; + if(this == other) { + return true; + } + + return ZCoeffRe == oth.ZCoeffRe && + ZCoeffIm == oth.ZCoeffIm && + CCoeffRe == oth.CCoeffRe && + CCoeffIm == oth.CCoeffIm && + LAThreshold == oth.LAThreshold && + LAThresholdC == oth.LAThresholdC && + RefIndex == oth.RefIndex; + } } diff --git a/src/fractalzoomer/core/location/Location.java b/src/fractalzoomer/core/location/Location.java index 08e11e4dc..95b7d1cae 100644 --- a/src/fractalzoomer/core/location/Location.java +++ b/src/fractalzoomer/core/location/Location.java @@ -135,7 +135,10 @@ public int getExtraSamplesNumber() { } public GenericComplex getAntialiasingComplex(int sample, int loc) {return null;} - public void setReference(GenericComplex ref) {reference = ref; } + public void setReference(GenericComplex ref) { + reference = ref; + fractal.initializeReferenceDecompressor(); + } public static Location getInstanceForDrawing(Apfloat xCenter, Apfloat yCenter, Apfloat size, double height_ratio, int image_size, double circle_period, Apfloat[] rotation_center, Apfloat[] rotation_vals, Fractal fractal, JitterSettings js, boolean polar, boolean highPresicion) { @@ -209,7 +212,7 @@ else if (bignumLib == Constants.BIGNUM_DOUBLE) { if(highPresicion && isDeep) { if(TaskDraw.USE_FAST_DELTA_LOCATION && fractal.usesDefaultPlane() && !Rotation.usesRotation(rotation_center, rotation_vals)) { - return new CartesianLocationDeltaDeep(xCenter, yCenter, size, height_ratio, image_size, js, bignumLib); + return new CartesianLocationDeltaDeep(xCenter, yCenter, size, height_ratio, image_size, js, fractal, bignumLib); } if(bignumLib == Constants.BIGNUM_BUILT_IN) { @@ -232,7 +235,7 @@ else if(highPresicion) { if(TaskDraw.USE_FAST_DELTA_LOCATION && fractal.usesDefaultPlane() && !Rotation.usesRotation(rotation_center, rotation_vals) && size.doubleValue() / offset.getImageSize(image_size) > 1e-305) { - return new CartesianLocationDelta(xCenter, yCenter, size, height_ratio, image_size, js, bignumLib); + return new CartesianLocationDelta(xCenter, yCenter, size, height_ratio, image_size, js, fractal, bignumLib); } if(bignumLib == Constants.BIGNUM_BUILT_IN) { @@ -510,8 +513,8 @@ private void precalculateJitterToAntialiasingStepsBigNum(BigNum[][] steps, BigNu for(int k = 0; k < NUMBER_OF_AA_JITTER_KERNELS; k++) { for (int i = 0; i < temp_x.length; i++) { - precalculatedJitterDataBigNum[k][0][i] = temp_x[i].add(ddx_antialiasing_size.mult(new BigNum(aaJitterKernelX[k][i]))); - precalculatedJitterDataBigNum[k][1][i] = temp_y[i].add(ddy_antialiasing_size.mult(new BigNum(aaJitterKernelY[k][i]))); + precalculatedJitterDataBigNum[k][0][i] = temp_x[i].add(ddx_antialiasing_size.mult(BigNum.create(aaJitterKernelX[k][i]))); + precalculatedJitterDataBigNum[k][1][i] = temp_y[i].add(ddy_antialiasing_size.mult(BigNum.create(aaJitterKernelY[k][i]))); } } @@ -544,19 +547,19 @@ public BigNum[][] createAntialiasingStepsBigNum(BigNum bntemp_size_image_size_x, ddy_antialiasing_size = bntemp_size_image_size_y.shift2toi(-4); } else if(samples > MAX_AA_SAMPLES_168 && !adaptive) { - BigNum oneFourteenth = new BigNum(MyApfloat.reciprocal(new MyApfloat(14.0))); + BigNum oneFourteenth = BigNum.create(MyApfloat.reciprocal(new MyApfloat(14.0))); ddx_antialiasing_size = bntemp_size_image_size_x.mult(oneFourteenth); ddy_antialiasing_size = bntemp_size_image_size_y.mult(oneFourteenth); } else if(samples > MAX_AA_SAMPLES_120 && !adaptive) { - BigNum oneTwelveth = new BigNum(MyApfloat.reciprocal(new MyApfloat(12.0))); + BigNum oneTwelveth = BigNum.create(MyApfloat.reciprocal(new MyApfloat(12.0))); ddx_antialiasing_size = bntemp_size_image_size_x.mult(oneTwelveth); ddy_antialiasing_size = bntemp_size_image_size_y.mult(oneTwelveth); } else if(samples > MAX_AA_SAMPLES_80 && !adaptive) { - BigNum oneTenth = new BigNum(MyApfloat.reciprocal(new MyApfloat(10.0))); + BigNum oneTenth = BigNum.create(MyApfloat.reciprocal(new MyApfloat(10.0))); ddx_antialiasing_size = bntemp_size_image_size_x.mult(oneTenth); ddy_antialiasing_size = bntemp_size_image_size_y.mult(oneTenth); @@ -566,7 +569,7 @@ else if(samples > MAX_AA_SAMPLES_48 && !adaptive) { ddy_antialiasing_size = bntemp_size_image_size_y.shift2toi(-3); } else if(samples > MAX_AA_SAMPLES_24 && !adaptive) { - BigNum oneSixth = new BigNum(MyApfloat.reciprocal(new MyApfloat(6.0))); + BigNum oneSixth = BigNum.create(MyApfloat.reciprocal(new MyApfloat(6.0))); ddx_antialiasing_size = bntemp_size_image_size_x.mult(oneSixth); ddy_antialiasing_size = bntemp_size_image_size_y.mult(oneSixth); @@ -676,7 +679,7 @@ public BigNum[][] createAntialiasingStepsBigNumGrid(BigNum ddx_antialiasing_size ddy_antialiasing_size_x8 = ddy_antialiasing_size.shift2toi(3); } - BigNum zero = new BigNum(); + BigNum zero = BigNum.create(); BigNum[][] data; if(!adaptive) { diff --git a/src/fractalzoomer/core/location/delta/CartesianLocationDelta.java b/src/fractalzoomer/core/location/delta/CartesianLocationDelta.java index e7a91e94d..d5ce68347 100644 --- a/src/fractalzoomer/core/location/delta/CartesianLocationDelta.java +++ b/src/fractalzoomer/core/location/delta/CartesianLocationDelta.java @@ -2,6 +2,7 @@ import fractalzoomer.core.*; import fractalzoomer.core.location.Location; +import fractalzoomer.functions.Fractal; import fractalzoomer.main.Constants; import fractalzoomer.main.app_settings.JitterSettings; import org.apfloat.Apfloat; @@ -29,10 +30,11 @@ public class CartesianLocationDelta extends Location { private double[] antialiasing_y; - public CartesianLocationDelta(Apfloat xCenter, Apfloat yCenter, Apfloat ddsize, double height_ratio, int image_size_in, JitterSettings js, int bignumLib) { + public CartesianLocationDelta(Apfloat xCenter, Apfloat yCenter, Apfloat ddsize, double height_ratio, int image_size_in, JitterSettings js, Fractal fractal, int bignumLib) { super(); + this.fractal = fractal; this.height_ratio = height_ratio; ddxcenter = xCenter; ddycenter = yCenter; @@ -74,6 +76,7 @@ public CartesianLocationDelta(Apfloat xCenter, Apfloat yCenter, Apfloat ddsize, public CartesianLocationDelta(CartesianLocationDelta other) { super(other); + fractal = other.fractal; reference = other.reference; temp_x_corner = other.temp_x_corner; temp_y_corner = other.temp_y_corner; diff --git a/src/fractalzoomer/core/location/delta/CartesianLocationDeltaDeep.java b/src/fractalzoomer/core/location/delta/CartesianLocationDeltaDeep.java index be6c4214d..bcce26de0 100644 --- a/src/fractalzoomer/core/location/delta/CartesianLocationDeltaDeep.java +++ b/src/fractalzoomer/core/location/delta/CartesianLocationDeltaDeep.java @@ -2,6 +2,7 @@ import fractalzoomer.core.*; import fractalzoomer.core.location.Location; +import fractalzoomer.functions.Fractal; import fractalzoomer.main.Constants; import fractalzoomer.main.app_settings.JitterSettings; import org.apfloat.Apfloat; @@ -30,10 +31,11 @@ public class CartesianLocationDeltaDeep extends Location { private MantExp[] antialiasing_y; - public CartesianLocationDeltaDeep(Apfloat xCenter, Apfloat yCenter, Apfloat ddsize, double height_ratio, int image_size_in, JitterSettings js, int bignumLib) { + public CartesianLocationDeltaDeep(Apfloat xCenter, Apfloat yCenter, Apfloat ddsize, double height_ratio, int image_size_in, JitterSettings js, Fractal fractal, int bignumLib) { super(); + this.fractal = fractal; this.mheight_ratio = new MantExp(height_ratio); ddxcenter = xCenter; ddycenter = yCenter; @@ -79,6 +81,7 @@ public CartesianLocationDeltaDeep(Apfloat xCenter, Apfloat yCenter, Apfloat ddsi public CartesianLocationDeltaDeep(CartesianLocationDeltaDeep other) { super(other); + fractal = other.fractal; reference = other.reference; temp_x_corner = other.temp_x_corner; temp_y_corner = other.temp_y_corner; diff --git a/src/fractalzoomer/core/location/normal/CartesianLocationNormalBigNumArbitrary.java b/src/fractalzoomer/core/location/normal/CartesianLocationNormalBigNumArbitrary.java index 585add938..f8d19e8c3 100644 --- a/src/fractalzoomer/core/location/normal/CartesianLocationNormalBigNumArbitrary.java +++ b/src/fractalzoomer/core/location/normal/CartesianLocationNormalBigNumArbitrary.java @@ -48,20 +48,20 @@ public CartesianLocationNormalBigNumArbitrary(Apfloat xCenter, Apfloat yCenter, point5 = new MyApfloat(0.5); - bnsize = new BigNum(size); + bnsize = BigNum.create(size); BigNum size_2_x = bnsize.divide2(); Apfloat ddimage_size = new MyApfloat(image_size); ddsize = size; - ddxcenter = new BigNum(xCenter); - ddycenter = new BigNum(yCenter); + ddxcenter = BigNum.create(xCenter); + ddycenter = BigNum.create(yCenter); Apfloat temp = MyApfloat.fp.multiply(size, this.height_ratio); - BigNum size_2_y = new BigNum(temp).divide2(); - bntemp_size_image_size_x = new BigNum(MyApfloat.fp.divide(size, ddimage_size)); - bntemp_size_image_size_y = new BigNum(MyApfloat.fp.divide(temp, ddimage_size)); + BigNum size_2_y = BigNum.create(temp).divide2(); + bntemp_size_image_size_x = BigNum.create(MyApfloat.fp.divide(size, ddimage_size)); + bntemp_size_image_size_y = BigNum.create(MyApfloat.fp.divide(temp, ddimage_size)); bntemp_xcenter_size = ddxcenter.sub(size_2_x); bntemp_ycenter_size = ddycenter.add(size_2_y); @@ -107,8 +107,8 @@ protected BigNumComplex getComplexBase(int x, int y) { if(js.enableJitter) { double[] res = GetPixelOffset(y, x, js.jitterSeed, js.jitterShape, js.jitterScale); - bntempX = bntemp_xcenter_size.add(bntemp_size_image_size_x.mult(new BigNum(x + res[1]))); - bntempY = bntemp_ycenter_size.sub(bntemp_size_image_size_y.mult(new BigNum(y + res[0]))); + bntempX = bntemp_xcenter_size.add(bntemp_size_image_size_x.mult(BigNum.create(x + res[1]))); + bntempY = bntemp_ycenter_size.sub(bntemp_size_image_size_y.mult(BigNum.create(y + res[0]))); } else { if (x == indexX + 1) { diff --git a/src/fractalzoomer/core/mpfr/LibMpfr.java b/src/fractalzoomer/core/mpfr/LibMpfr.java index 930fd6fc3..7022f9266 100644 --- a/src/fractalzoomer/core/mpfr/LibMpfr.java +++ b/src/fractalzoomer/core/mpfr/LibMpfr.java @@ -350,9 +350,12 @@ private LibMpfr() { public static native void mpfr_fz_square (mpfr_t re, mpfr_t im, mpfr_t temp, mpfr_t re_sqr, mpfr_t im_sqr, mpfr_t norm_sqr, int rnd); public static native void mpfr_fz_norm_square_with_components (mpfr_t re_sqr, mpfr_t im_sqr, mpfr_t norm_sqr, mpfr_t re, mpfr_t im, int rnd); public static native void mpfr_fz_get_d (double[] valRe, double[] valIm, mpfr_t re, mpfr_t im, int rnd); - public static native int mpfr_fz_get_d_2exp (double[] valRe, double[] valIm, long[] expRe, long[] expIm, mpfr_t re, mpfr_t im, int rnd); - public static native int mpfr_fz_get_d_2exp (double[] valRe, double[] valIm, int[] expRe, int[] expIm, mpfr_t re, mpfr_t im, int rnd); + public static native void mpfr_fz_get_d_2exp (double[] valRe, double[] valIm, long[] expRe, long[] expIm, mpfr_t re, mpfr_t im, int rnd); + public static native void mpfr_fz_get_d_2exp (double[] valRe, double[] valIm, int[] expRe, int[] expIm, mpfr_t re, mpfr_t im, int rnd); public static native void mpfr_fz_square_plus_c_simple (mpfr_t re, mpfr_t im, mpfr_t temp1, mpfr_t temp2, mpfr_t cre, mpfr_t cim, int rnd); + public static native void mpfr_fz_square_plus_c_simple_with_reduction_not_deep (mpfr_t re, mpfr_t im, mpfr_t temp1, mpfr_t temp2, mpfr_t cre, mpfr_t cim, int rnd, double[] valRe, double[] valIm); + public static native void mpfr_fz_square_plus_c_simple_with_reduction_deep (mpfr_t re, mpfr_t im, mpfr_t temp1, mpfr_t temp2, mpfr_t cre, mpfr_t cim, int rnd, double[] valRe, double[] valIm, long[] expRe, long[] expIm); + public static native void mpfr_fz_square_plus_c_simple_with_reduction_deep (mpfr_t re, mpfr_t im, mpfr_t temp1, mpfr_t temp2, mpfr_t cre, mpfr_t cim, int rnd, double[] valRe, double[] valIm, int[] expRe, int[] expIm); public static native void mpfr_fz_set (mpfr_t destre, mpfr_t destim, mpfr_t srcre, mpfr_t srcim, int rnd); public static native void mpfr_fz_norm_square (mpfr_t norm_sqr, mpfr_t temp1, mpfr_t re, mpfr_t im, int rnd); public static native void mpfr_fz_self_add (mpfr_t re, mpfr_t im, mpfr_t val_re, mpfr_t val_im, int rnd); @@ -363,4 +366,6 @@ private LibMpfr() { public static native void mpfr_fz_ApBmC_DsEmG (mpfr_t temp, mpfr_t temp2, mpfr_t a, mpfr_t b, double c, mpfr_t d, mpfr_t e, double g, int rnd); public static native void mpfr_fz_ApBmC_DpEmG (mpfr_t temp, mpfr_t temp2, mpfr_t a, mpfr_t b, mpfr_t c, mpfr_t d, mpfr_t e, mpfr_t g, int rnd); public static native void mpfr_fz_r_ball_pow2 (mpfr_t r, mpfr_t az, mpfr_t r0, mpfr_t azsquare, int rnd); + + public static native int mpfr_snprintf (byte[] buf, int n, String template, int rnd, mpfr_t val); } diff --git a/src/fractalzoomer/core/mpfr/MpfrBigNum.java b/src/fractalzoomer/core/mpfr/MpfrBigNum.java index 73924a90e..27dbcb9c1 100644 --- a/src/fractalzoomer/core/mpfr/MpfrBigNum.java +++ b/src/fractalzoomer/core/mpfr/MpfrBigNum.java @@ -1,13 +1,16 @@ package fractalzoomer.core.mpfr; -import fractalzoomer.core.MantExp; -import fractalzoomer.core.TaskDraw; +import fractalzoomer.core.*; import fractalzoomer.core.mpir.MpirBigNum; import fractalzoomer.core.mpir.mpf_t; import org.apfloat.Apfloat; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.lang.annotation.Native; +import java.nio.charset.StandardCharsets; + import static fractalzoomer.core.mpfr.LibMpfr.*; -import static fractalzoomer.core.mpir.LibMpir.LOAD_ERROR; public class MpfrBigNum { @@ -526,18 +529,24 @@ public double doubleValue() { } public MantExp getMantExp() { - if(mpfr_zero_p(mpfrMemory.peer) == 1) { - return new MantExp(); - } - if(isLong4) { int[] exp = new int[1]; double d = mpfr_get_d_2exp(exp, mpfrMemory.peer, rounding); + + if(d == 0) { + return new MantExp(); + } + return new MantExp(exp[0], d); } else { long[] exp = new long[1]; double d = mpfr_get_d_2exp(exp, mpfrMemory.peer, rounding); + + if(d == 0) { + return new MantExp(); + } + return new MantExp(exp[0], d); } @@ -600,37 +609,39 @@ public static MantExp[] get_d_2exp (MpfrBigNum re, MpfrBigNum im) { int[] reExp = new int[1]; int[] imExp = new int[1]; - int result = mpfr_fz_get_d_2exp(reD, imD, reExp, imExp, re.mpfrMemory.peer, im.mpfrMemory.peer, rounding); + mpfr_fz_get_d_2exp(reD, imD, reExp, imExp, re.mpfrMemory.peer, im.mpfrMemory.peer, rounding); - if(result == 0) { //No zero - return new MantExp[] {new MantExp(reExp[0], reD[0]), new MantExp(imExp[0], imD[0])}; + double v1 = reD[0], v2 = imD[0]; + if(v1 == 0 && v2 == 0) { + return new MantExp[] {new MantExp(), new MantExp()}; } - else if(result == 1) { // re is zero - return new MantExp[] {new MantExp(), new MantExp(imExp[0], imD[0])}; + else if(v1 == 0) { + return new MantExp[] {new MantExp(), new MantExp(imExp[0], v2)}; } - else if (result == 2) { // im is zero - return new MantExp[] {new MantExp(reExp[0], reD[0]), new MantExp()}; + else if(v2 == 0) { + return new MantExp[] {new MantExp(reExp[0], v1), new MantExp()}; } - else { // both - return new MantExp[] {new MantExp(), new MantExp()}; + else { + return new MantExp[] {new MantExp(reExp[0], v1), new MantExp(imExp[0], v2)}; } } else { long[] reExp = new long[1]; long[] imExp = new long[1]; - int result = mpfr_fz_get_d_2exp(reD, imD, reExp, imExp, re.mpfrMemory.peer, im.mpfrMemory.peer, rounding); + mpfr_fz_get_d_2exp(reD, imD, reExp, imExp, re.mpfrMemory.peer, im.mpfrMemory.peer, rounding); - if(result == 0) { - return new MantExp[] {new MantExp(reExp[0], reD[0]), new MantExp(imExp[0], imD[0])}; + double v1 = reD[0], v2 = imD[0]; + if(v1 == 0 && v2 == 0) { + return new MantExp[] {new MantExp(), new MantExp()}; } - else if(result == 1) { - return new MantExp[] {new MantExp(), new MantExp(imExp[0], imD[0])}; + else if(v1 == 0) { + return new MantExp[] {new MantExp(), new MantExp(imExp[0], v2)}; } - else if (result == 2) { - return new MantExp[] {new MantExp(reExp[0], reD[0]), new MantExp()}; + else if(v2 == 0) { + return new MantExp[] {new MantExp(reExp[0], v1), new MantExp()}; } else { - return new MantExp[] {new MantExp(), new MantExp()}; + return new MantExp[] {new MantExp(reExp[0], v1), new MantExp(imExp[0], v2)}; } } @@ -655,6 +666,35 @@ public static void z_sqr(MpfrBigNum re, MpfrBigNum im, MpfrBigNum temp, MpfrBigN } + static double[] valRe = new double[1]; + static double[] valIm = new double[1]; + static double[] mantissaRe = new double[1]; + static double[] mantissaIm = new double[1]; + + static long[] reExpL = new long[1]; + static long[] imExpL = new long[1]; + static int[] reExp = new int[1]; + static int[] imExp = new int[1]; + + public static void z_sqr_p_c_with_reduction(MpfrBigNum re, MpfrBigNum im, MpfrBigNum temp1, MpfrBigNum temp2, MpfrBigNum cre, MpfrBigNum cim, boolean deepZoom, Complex cz, MantExpComplex mcz) { + + if(deepZoom) { + if(isLong4) { + mpfr_fz_square_plus_c_simple_with_reduction_deep(re.mpfrMemory.peer, im.mpfrMemory.peer, temp1.mpfrMemory.peer, temp2.mpfrMemory.peer, cre.mpfrMemory.peer, cim.mpfrMemory.peer, rounding, mantissaRe, mantissaIm, reExp, imExp); + mcz.set(reExp[0], imExp[0], mantissaRe[0], mantissaIm[0]); + } + else { + mpfr_fz_square_plus_c_simple_with_reduction_deep(re.mpfrMemory.peer, im.mpfrMemory.peer, temp1.mpfrMemory.peer, temp2.mpfrMemory.peer, cre.mpfrMemory.peer, cim.mpfrMemory.peer, rounding, mantissaRe, mantissaIm, reExpL, imExpL); + mcz.set(reExpL[0], imExpL[0], mantissaRe[0], mantissaIm[0]); + } + } + else { + mpfr_fz_square_plus_c_simple_with_reduction_not_deep(re.mpfrMemory.peer, im.mpfrMemory.peer, temp1.mpfrMemory.peer, temp2.mpfrMemory.peer, cre.mpfrMemory.peer, cim.mpfrMemory.peer, rounding, valRe, valIm); + cz.assign(valRe[0], valIm[0]); + } + + } + public static void norm_sqr_with_components( MpfrBigNum reSqr, MpfrBigNum imSqr, MpfrBigNum normSqr, MpfrBigNum re, MpfrBigNum im) { mpfr_fz_norm_square_with_components(reSqr.mpfrMemory.peer, imSqr.mpfrMemory.peer, normSqr.mpfrMemory.peer, re.mpfrMemory.peer, im.mpfrMemory.peer, rounding); @@ -706,6 +746,16 @@ public String toString() { return "" + doubleValue(); } + public String toFullString() { + int n = (int)MyApfloat.precision * 2; + byte[] buf = new byte[n]; + String template = "%." + MyApfloat.precision + "R*g"; + mpfr_snprintf(buf, n, template, rounding, mpfrMemory.peer); + return new String(buf).trim(); + } + + public Apfloat toApfloat() { return new MyApfloat(toFullString());} + /*public static void main(String[] args) { String Re = "-1.7685653943536636812525937129345323689264178203655023808403568327813984751602057983694075544809385380635853233562272021595486038792597346267621026418533261924962244609714446430169626331467057579947033159779441985348128008304981334471441266997824980553144563791567792114724296121872944832614093450944724492334683449190475005836849397812504637683710510408861059046995537629068401998856337076707729082352934525561410799942777533219989198396355688230764560224323159046285245196155466314399804239661358274503819615557368332052446821888562141313581523317892262380088027074432482039394916527640029121955174213203521566050696042500969919946717868654263385845711621571084795576591138961066064076009303183875949501143195217469003173308513486183081233774459137115288547807735477262202007250717008710283162223251492449408111203225925774749231087606075791025786880373414419640567812051244300178691506999924356763498211814367907336500103294768040948403104863777932123346593677739181711573037377537612597105572567432844531248119698069826986109774175430124235000261952935148608089775593025955571455701166888054695292300393363716767974622037919908584052332982637466"; String Im = "0.00149693415390767795776818884840489556855946301445691471574014563855527433886417969977385819538260268120841953162872636930325763746322273045770475720864573841501787930094585669029854545526055550254240550601638349230447392478835897915689588386917873306732459133130195499040290663241163281171562214964938877814041525983714426684720617999806166857035264185620487882712073265176954914054913266203287997924901540871019242527521230712886590484380712839459054394699971951683593643432733875864612142164058384584027531954686991700717520592706134315477867770419967332102686480959769035927998828366145957010260008071330081671951130257876517738836139132327131150083875547829353693231330986024536074662266149266972020406424662729505261246207754916338512723205243386084554727716044392705072728590247105881028092304993724655676823686703579759639901910397135711042548453158584111749222905493046484296618244721966973379997931675069363108125568864266991641443350605262290076130999673222331940884558082142583551902556005768303536299446355536559649684565312212482597275388117026700207573378170627060834006934127513560312023382257072757055987599151386137785304306581858"; diff --git a/src/fractalzoomer/core/mpfr/custom_mpfr.c b/src/fractalzoomer/core/mpfr/custom_mpfr.c index 658c6db79..15a584ef6 100644 --- a/src/fractalzoomer/core/mpfr/custom_mpfr.c +++ b/src/fractalzoomer/core/mpfr/custom_mpfr.c @@ -1,183 +1,204 @@ -#define MPFR_NEED_LONGLONG_H -#include "mpfr-impl.h" - -//add this to mpfr.h -//__MPFR_DECLSPEC void mpfr_fz_square_plus_c (mpfr_ptr re, mpfr_ptr im, mpfr_ptr temp, mpfr_srcptr re_sqr, mpfr_srcptr im_sqr, mpfr_srcptr norm_sqr, mpfr_srcptr cre, mpfr_srcptr cim, mpfr_rnd_t rnd_mode); -//__MPFR_DECLSPEC void mpfr_fz_square (mpfr_ptr re, mpfr_ptr im, mpfr_ptr temp, mpfr_srcptr re_sqr, mpfr_srcptr im_sqr, mpfr_srcptr norm_sqr, mpfr_rnd_t rnd_mode); -//__MPFR_DECLSPEC void mpfr_fz_norm_square_with_components (mpfr_ptr re_sqr, mpfr_ptr im_sqr, mpfr_ptr norm_sqr, mpfr_srcptr re, mpfr_srcptr im, mpfr_rnd_t rnd_mode); -//__MPFR_DECLSPEC void mpfr_fz_get_d (double* valRe, double* valIm, mpfr_srcptr re, mpfr_srcptr im, mpfr_rnd_t rnd_mode); -//__MPFR_DECLSPEC int mpfr_fz_get_d_2exp (double* valRe, double* valIm, long *expRe, long* expIm, mpfr_srcptr re, mpfr_srcptr im, mpfr_rnd_t rnd_mode); -//__MPFR_DECLSPEC void mpfr_fz_square_plus_c_simple (mpfr_ptr re, mpfr_ptr im, mpfr_ptr temp1, mpfr_ptr temp2, mpfr_srcptr cre, mpfr_srcptr cim, mpfr_rnd_t rnd_mode); -//__MPFR_DECLSPEC void mpfr_fz_set (mpfr_ptr destre, mpfr_ptr destim, mpfr_srcptr srcre, mpfr_srcptr srcim, mpfr_rnd_t rnd_mode); -//__MPFR_DECLSPEC void mpfr_fz_norm_square (mpfr_ptr norm_sqr, mpfr_ptr temp1, mpfr_srcptr re, mpfr_srcptr im, mpfr_rnd_t rnd_mode); -//__MPFR_DECLSPEC void mpfr_fz_self_add (mpfr_ptr re, mpfr_ptr im, mpfr_srcptr val_re, mpfr_srcptr val_im, mpfr_rnd_t rnd_mode); -//__MPFR_DECLSPEC void mpfr_fz_self_sub (mpfr_ptr re, mpfr_ptr im, mpfr_srcptr val_re, mpfr_srcptr val_im, mpfr_rnd_t rnd_mode); -//__MPFR_DECLSPEC void mpfr_fz_rotation (mpfr_ptr x, mpfr_ptr y, mpfr_ptr temp_re, mpfr_ptr temp_im, mpfr_ptr f, mpfr_srcptr a, mpfr_srcptr asb, mpfr_srcptr apb, mpfr_rnd_t rnd_mode); -//__MPFR_DECLSPEC void mpfr_fz_AsBmC (mpfr_ptr temp, mpfr_srcptr a, mpfr_srcptr b, int c, mpfr_rnd_t rnd_mode); -//__MPFR_DECLSPEC void mpfr_fz_ApBmC (mpfr_ptr temp, mpfr_srcptr a, mpfr_srcptr b, int c, mpfr_rnd_t rnd_mode); -//__MPFR_DECLSPEC void mpfr_fz_ApBmC_DsEmG (mpfr_ptr temp, mpfr_ptr temp2, mpfr_srcptr a, mpfr_srcptr b, double c, mpfr_srcptr d, mpfr_srcptr e, double g, mpfr_rnd_t rnd_mode); -//__MPFR_DECLSPEC void mpfr_fz_ApBmC_DpEmG (mpfr_ptr temp, mpfr_ptr temp2, mpfr_srcptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_srcptr d, mpfr_srcptr e, mpfr_srcptr g, mpfr_rnd_t rnd_mode); -//_MPFR_DECLSPEC void mpfr_fz_r_ball_pow2 (mpfr_ptr r, mpfr_ptr az, mpfr_srcptr r0, mpfr_srcptr azsquare, mpfr_rnd_t rnd_mode); -//Also dont forget to modify the Makefiles in src/ and add custom_mpfr to every place required - -MPFR_HOT_FUNCTION_ATTR void -mpfr_fz_square_plus_c (mpfr_ptr re, mpfr_ptr im, mpfr_ptr temp, mpfr_srcptr re_sqr, mpfr_srcptr im_sqr, mpfr_srcptr norm_sqr, mpfr_srcptr cre, mpfr_srcptr cim, mpfr_rnd_t rnd_mode) -{ - mpfr_add(temp, re, im, rnd_mode); // temp = re + im - mpfr_sqr(temp, temp, rnd_mode); // temp = (re + im)^2 - mpfr_sub(im, temp, norm_sqr, rnd_mode); // im = (re + im)^2 - re^2 - im^2 - mpfr_add(im, im, cim, rnd_mode); // im = (re + im)^2 - re^2 - im^2 + cim - - mpfr_sub(re, re_sqr, im_sqr, rnd_mode); // re = re^2 - im^2 - mpfr_add(re, re, cre, rnd_mode); // re = re^2 - im^2 + cre -} - -MPFR_HOT_FUNCTION_ATTR void -mpfr_fz_square (mpfr_ptr re, mpfr_ptr im, mpfr_ptr temp, mpfr_srcptr re_sqr, mpfr_srcptr im_sqr, mpfr_srcptr norm_sqr, mpfr_rnd_t rnd_mode) -{ - mpfr_add(temp, re, im, rnd_mode); // temp = re + im - mpfr_sqr(temp, temp, rnd_mode); // temp = (re + im)^2 - mpfr_sub(im, temp, norm_sqr, rnd_mode); // im = (re + im)^2 - re^2 - im^2 - - mpfr_sub(re, re_sqr, im_sqr, rnd_mode); // re = re^2 - im^2 -} - - -MPFR_HOT_FUNCTION_ATTR void -mpfr_fz_square_plus_c_simple (mpfr_ptr re, mpfr_ptr im, mpfr_ptr temp1, mpfr_ptr temp2, mpfr_srcptr cre, mpfr_srcptr cim, mpfr_rnd_t rnd_mode) -{ - mpfr_add(temp1, re, im, rnd_mode); // temp1 = re + im - mpfr_sub(temp2, re, im, rnd_mode); // temp2 = re - im - mpfr_mul(temp2, temp1, temp2, rnd_mode); // temp2 = (re + im) * (re - im) - - mpfr_mul(im, re, im, rnd_mode); // im = re * im - - mpfr_add(re, temp2, cre, rnd_mode); // re = (re + im) * (re - im) + cre - mpfr_mul_2ui(im, im, 1, rnd_mode); // im = 2 * re * im - mpfr_add(im, im, cim, rnd_mode); // im = 2 * re * im + cim -} - -MPFR_HOT_FUNCTION_ATTR void -mpfr_fz_norm_square_with_components (mpfr_ptr re_sqr, mpfr_ptr im_sqr, mpfr_ptr norm_sqr, mpfr_srcptr re, mpfr_srcptr im, mpfr_rnd_t rnd_mode) -{ - mpfr_sqr(re_sqr, re, rnd_mode); // re^2 - mpfr_sqr(im_sqr, im, rnd_mode); // im^2 - mpfr_add(norm_sqr, re_sqr, im_sqr, rnd_mode); // re^2 + im^2 -} - -MPFR_HOT_FUNCTION_ATTR void -mpfr_fz_norm_square (mpfr_ptr norm_sqr, mpfr_ptr temp1, mpfr_srcptr re, mpfr_srcptr im, mpfr_rnd_t rnd_mode) -{ - mpfr_sqr(norm_sqr, re, rnd_mode); // re^2 - mpfr_sqr(temp1, im, rnd_mode); // im^2 - mpfr_add(norm_sqr, norm_sqr, temp1, rnd_mode); // re^2 + im^2 -} - -MPFR_HOT_FUNCTION_ATTR void -mpfr_fz_get_d (double* valRe, double* valIm, mpfr_srcptr re, mpfr_srcptr im, mpfr_rnd_t rnd_mode) -{ - *valRe = mpfr_get_d(re, rnd_mode); - *valIm = mpfr_get_d(im, rnd_mode); -} - -MPFR_HOT_FUNCTION_ATTR int -mpfr_fz_get_d_2exp (double* valRe, double* valIm, long *expRe, long* expIm, mpfr_srcptr re, mpfr_srcptr im, mpfr_rnd_t rnd_mode) -{ - int isZero = 0; - - if(mpfr_zero_p(re)) { - isZero = 0x1; - } - else { - *valRe = mpfr_get_d_2exp(expRe, re, rnd_mode); - } - - if(mpfr_zero_p(im)) { - isZero |= 0x2; - } - else { - *valIm = mpfr_get_d_2exp(expIm, im, rnd_mode); - } - - return isZero; -} - -MPFR_HOT_FUNCTION_ATTR void -mpfr_fz_set (mpfr_ptr destre, mpfr_ptr destim, mpfr_srcptr srcre, mpfr_srcptr srcim, mpfr_rnd_t rnd_mode) -{ - mpfr_set(destre, srcre, rnd_mode); - mpfr_set(destim, srcim, rnd_mode); -} - - -MPFR_HOT_FUNCTION_ATTR void -mpfr_fz_self_add (mpfr_ptr re, mpfr_ptr im, mpfr_srcptr val_re, mpfr_srcptr val_im, mpfr_rnd_t rnd_mode) -{ - mpfr_add(re, re, val_re, rnd_mode); - mpfr_add(im, im, val_im, rnd_mode); -} - -MPFR_HOT_FUNCTION_ATTR void -mpfr_fz_self_sub (mpfr_ptr re, mpfr_ptr im, mpfr_srcptr val_re, mpfr_srcptr val_im, mpfr_rnd_t rnd_mode) -{ - mpfr_sub(re, re, val_re, rnd_mode); - mpfr_sub(im, im, val_im, rnd_mode); -} - -MPFR_HOT_FUNCTION_ATTR void -mpfr_fz_rotation (mpfr_ptr x, mpfr_ptr y, mpfr_ptr temp_re, mpfr_ptr temp_im, mpfr_ptr f, mpfr_srcptr a, mpfr_srcptr asb, mpfr_srcptr apb, mpfr_rnd_t rnd_mode) -{ - mpfr_sub(f, x, y, rnd_mode); - mpfr_mul(f, a, f, rnd_mode); - - mpfr_mul(temp_re, asb, y, rnd_mode); - mpfr_mul(temp_im, apb, x, rnd_mode); - - mpfr_add(x, temp_re, f, rnd_mode); - mpfr_sub(y, temp_im, f, rnd_mode); -} - - -MPFR_HOT_FUNCTION_ATTR void -mpfr_fz_AsBmC (mpfr_ptr temp, mpfr_srcptr a, mpfr_srcptr b, int c, mpfr_rnd_t rnd_mode) -{ - mpfr_mul_si(temp, b, c, rnd_mode); - mpfr_sub(temp, a, temp, rnd_mode); -} - -MPFR_HOT_FUNCTION_ATTR void -mpfr_fz_ApBmC (mpfr_ptr temp, mpfr_srcptr a, mpfr_srcptr b, int c, mpfr_rnd_t rnd_mode) -{ - mpfr_mul_si(temp, b, c, rnd_mode); - mpfr_add(temp, a, temp, rnd_mode); -} - -MPFR_HOT_FUNCTION_ATTR void -mpfr_fz_ApBmC_DsEmG (mpfr_ptr temp, mpfr_ptr temp2, mpfr_srcptr a, mpfr_srcptr b, double c, mpfr_srcptr d, mpfr_srcptr e, double g, mpfr_rnd_t rnd_mode) -{ - mpfr_mul_d(temp, b, c, rnd_mode); - mpfr_add(temp, a, temp, rnd_mode); - - mpfr_mul_d(temp2, e, g, rnd_mode); - mpfr_sub(temp2, d, temp2, rnd_mode); -} - - -MPFR_HOT_FUNCTION_ATTR void -mpfr_fz_ApBmC_DpEmG (mpfr_ptr temp, mpfr_ptr temp2, mpfr_srcptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_srcptr d, mpfr_srcptr e, mpfr_srcptr g, mpfr_rnd_t rnd_mode) -{ - mpfr_mul(temp, b, c, rnd_mode); - mpfr_add(temp, a, temp, rnd_mode); - - mpfr_mul(temp2, e, g, rnd_mode); - mpfr_add(temp2, d, temp2, rnd_mode); -} - -MPFR_HOT_FUNCTION_ATTR void -mpfr_fz_r_ball_pow2 (mpfr_ptr r, mpfr_ptr az, mpfr_srcptr r0, mpfr_srcptr azsquare, mpfr_rnd_t rnd_mode) -{ - mpfr_add(az, r, az, rnd_mode); // az = az + r - mpfr_sqr(r, az, rnd_mode); // r = (az + r)^2 - mpfr_sub(r, r, azsquare, rnd_mode); - mpfr_add(r, r, r0, rnd_mode); -} +#define MPFR_NEED_LONGLONG_H +#include "mpfr-impl.h" + +//add this to mpfr.h +//__MPFR_DECLSPEC void mpfr_fz_square_plus_c (mpfr_ptr re, mpfr_ptr im, mpfr_ptr temp, mpfr_srcptr re_sqr, mpfr_srcptr im_sqr, mpfr_srcptr norm_sqr, mpfr_srcptr cre, mpfr_srcptr cim, mpfr_rnd_t rnd_mode); +//__MPFR_DECLSPEC void mpfr_fz_square (mpfr_ptr re, mpfr_ptr im, mpfr_ptr temp, mpfr_srcptr re_sqr, mpfr_srcptr im_sqr, mpfr_srcptr norm_sqr, mpfr_rnd_t rnd_mode); +//__MPFR_DECLSPEC void mpfr_fz_norm_square_with_components (mpfr_ptr re_sqr, mpfr_ptr im_sqr, mpfr_ptr norm_sqr, mpfr_srcptr re, mpfr_srcptr im, mpfr_rnd_t rnd_mode); +//__MPFR_DECLSPEC void mpfr_fz_get_d (double* valRe, double* valIm, mpfr_srcptr re, mpfr_srcptr im, mpfr_rnd_t rnd_mode); +//__MPFR_DECLSPEC void mpfr_fz_get_d_2exp (double* valRe, double* valIm, long *expRe, long* expIm, mpfr_srcptr re, mpfr_srcptr im, mpfr_rnd_t rnd_mode); +//__MPFR_DECLSPEC void mpfr_fz_square_plus_c_simple (mpfr_ptr re, mpfr_ptr im, mpfr_ptr temp1, mpfr_ptr temp2, mpfr_srcptr cre, mpfr_srcptr cim, mpfr_rnd_t rnd_mode); +//__MPFR_DECLSPEC void mpfr_fz_square_plus_c_simple_with_reduction_not_deep (mpfr_ptr re, mpfr_ptr im, mpfr_ptr temp1, mpfr_ptr temp2, mpfr_srcptr cre, mpfr_srcptr cim, mpfr_rnd_t rnd_mode, double* valRe, double* valIm); +//__MPFR_DECLSPEC void mpfr_fz_square_plus_c_simple_with_reduction_deep (mpfr_ptr re, mpfr_ptr im, mpfr_ptr temp1, mpfr_ptr temp2, mpfr_srcptr cre, mpfr_srcptr cim, mpfr_rnd_t rnd_mode, double* valRe, double* valIm, long* expRe, long* expIm); +//__MPFR_DECLSPEC void mpfr_fz_set (mpfr_ptr destre, mpfr_ptr destim, mpfr_srcptr srcre, mpfr_srcptr srcim, mpfr_rnd_t rnd_mode); +//__MPFR_DECLSPEC void mpfr_fz_norm_square (mpfr_ptr norm_sqr, mpfr_ptr temp1, mpfr_srcptr re, mpfr_srcptr im, mpfr_rnd_t rnd_mode); +//__MPFR_DECLSPEC void mpfr_fz_self_add (mpfr_ptr re, mpfr_ptr im, mpfr_srcptr val_re, mpfr_srcptr val_im, mpfr_rnd_t rnd_mode); +//__MPFR_DECLSPEC void mpfr_fz_self_sub (mpfr_ptr re, mpfr_ptr im, mpfr_srcptr val_re, mpfr_srcptr val_im, mpfr_rnd_t rnd_mode); +//__MPFR_DECLSPEC void mpfr_fz_rotation (mpfr_ptr x, mpfr_ptr y, mpfr_ptr temp_re, mpfr_ptr temp_im, mpfr_ptr f, mpfr_srcptr a, mpfr_srcptr asb, mpfr_srcptr apb, mpfr_rnd_t rnd_mode); +//__MPFR_DECLSPEC void mpfr_fz_AsBmC (mpfr_ptr temp, mpfr_srcptr a, mpfr_srcptr b, int c, mpfr_rnd_t rnd_mode); +//__MPFR_DECLSPEC void mpfr_fz_ApBmC (mpfr_ptr temp, mpfr_srcptr a, mpfr_srcptr b, int c, mpfr_rnd_t rnd_mode); +//__MPFR_DECLSPEC void mpfr_fz_ApBmC_DsEmG (mpfr_ptr temp, mpfr_ptr temp2, mpfr_srcptr a, mpfr_srcptr b, double c, mpfr_srcptr d, mpfr_srcptr e, double g, mpfr_rnd_t rnd_mode); +//__MPFR_DECLSPEC void mpfr_fz_ApBmC_DpEmG (mpfr_ptr temp, mpfr_ptr temp2, mpfr_srcptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_srcptr d, mpfr_srcptr e, mpfr_srcptr g, mpfr_rnd_t rnd_mode); +//_MPFR_DECLSPEC void mpfr_fz_r_ball_pow2 (mpfr_ptr r, mpfr_ptr az, mpfr_srcptr r0, mpfr_srcptr azsquare, mpfr_rnd_t rnd_mode); +//Also dont forget to modify the Makefiles in src/ and add custom_mpfr to every place required + +MPFR_HOT_FUNCTION_ATTR void +mpfr_fz_square_plus_c (mpfr_ptr re, mpfr_ptr im, mpfr_ptr temp, mpfr_srcptr re_sqr, mpfr_srcptr im_sqr, mpfr_srcptr norm_sqr, mpfr_srcptr cre, mpfr_srcptr cim, mpfr_rnd_t rnd_mode) +{ + mpfr_add(temp, re, im, rnd_mode); // temp = re + im + mpfr_sqr(temp, temp, rnd_mode); // temp = (re + im)^2 + mpfr_sub(im, temp, norm_sqr, rnd_mode); // im = (re + im)^2 - re^2 - im^2 + mpfr_add(im, im, cim, rnd_mode); // im = (re + im)^2 - re^2 - im^2 + cim + + mpfr_sub(re, re_sqr, im_sqr, rnd_mode); // re = re^2 - im^2 + mpfr_add(re, re, cre, rnd_mode); // re = re^2 - im^2 + cre +} + +MPFR_HOT_FUNCTION_ATTR void +mpfr_fz_square (mpfr_ptr re, mpfr_ptr im, mpfr_ptr temp, mpfr_srcptr re_sqr, mpfr_srcptr im_sqr, mpfr_srcptr norm_sqr, mpfr_rnd_t rnd_mode) +{ + mpfr_add(temp, re, im, rnd_mode); // temp = re + im + mpfr_sqr(temp, temp, rnd_mode); // temp = (re + im)^2 + mpfr_sub(im, temp, norm_sqr, rnd_mode); // im = (re + im)^2 - re^2 - im^2 + + mpfr_sub(re, re_sqr, im_sqr, rnd_mode); // re = re^2 - im^2 +} + + +MPFR_HOT_FUNCTION_ATTR void +mpfr_fz_square_plus_c_simple (mpfr_ptr re, mpfr_ptr im, mpfr_ptr temp1, mpfr_ptr temp2, mpfr_srcptr cre, mpfr_srcptr cim, mpfr_rnd_t rnd_mode) +{ + mpfr_add(temp1, re, im, rnd_mode); // temp1 = re + im + mpfr_sub(temp2, re, im, rnd_mode); // temp2 = re - im + mpfr_mul(temp2, temp1, temp2, rnd_mode); // temp2 = (re + im) * (re - im) + + mpfr_mul(im, re, im, rnd_mode); // im = re * im + + mpfr_add(re, temp2, cre, rnd_mode); // re = (re + im) * (re - im) + cre + mpfr_mul_2ui(im, im, 1, rnd_mode); // im = 2 * re * im + mpfr_add(im, im, cim, rnd_mode); // im = 2 * re * im + cim +} + +MPFR_HOT_FUNCTION_ATTR void +mpfr_fz_square_plus_c_simple_with_reduction_deep (mpfr_ptr re, mpfr_ptr im, mpfr_ptr temp1, mpfr_ptr temp2, mpfr_srcptr cre, mpfr_srcptr cim, mpfr_rnd_t rnd_mode, double* valRe, double* valIm, long* expRe, long* expIm) +{ + mpfr_add(temp1, re, im, rnd_mode); // temp1 = re + im + mpfr_sub(temp2, re, im, rnd_mode); // temp2 = re - im + mpfr_mul(temp2, temp1, temp2, rnd_mode); // temp2 = (re + im) * (re - im) + + mpfr_mul(im, re, im, rnd_mode); // im = re * im + + mpfr_add(re, temp2, cre, rnd_mode); // re = (re + im) * (re - im) + cre + mpfr_mul_2ui(im, im, 1, rnd_mode); // im = 2 * re * im + mpfr_add(im, im, cim, rnd_mode); // im = 2 * re * im + cim + + *valRe = mpfr_get_d_2exp(expRe, re, rnd_mode); + *valIm = mpfr_get_d_2exp(expIm, im, rnd_mode); +} + +MPFR_HOT_FUNCTION_ATTR void +mpfr_fz_square_plus_c_simple_with_reduction_not_deep (mpfr_ptr re, mpfr_ptr im, mpfr_ptr temp1, mpfr_ptr temp2, mpfr_srcptr cre, mpfr_srcptr cim, mpfr_rnd_t rnd_mode, double* valRe, double* valIm) +{ + mpfr_add(temp1, re, im, rnd_mode); // temp1 = re + im + mpfr_sub(temp2, re, im, rnd_mode); // temp2 = re - im + mpfr_mul(temp2, temp1, temp2, rnd_mode); // temp2 = (re + im) * (re - im) + + mpfr_mul(im, re, im, rnd_mode); // im = re * im + + mpfr_add(re, temp2, cre, rnd_mode); // re = (re + im) * (re - im) + cre + mpfr_mul_2ui(im, im, 1, rnd_mode); // im = 2 * re * im + mpfr_add(im, im, cim, rnd_mode); // im = 2 * re * im + cim + + *valRe = mpfr_get_d(re, rnd_mode); + *valIm = mpfr_get_d(im, rnd_mode); +} + +MPFR_HOT_FUNCTION_ATTR void +mpfr_fz_norm_square_with_components (mpfr_ptr re_sqr, mpfr_ptr im_sqr, mpfr_ptr norm_sqr, mpfr_srcptr re, mpfr_srcptr im, mpfr_rnd_t rnd_mode) +{ + mpfr_sqr(re_sqr, re, rnd_mode); // re^2 + mpfr_sqr(im_sqr, im, rnd_mode); // im^2 + mpfr_add(norm_sqr, re_sqr, im_sqr, rnd_mode); // re^2 + im^2 +} + +MPFR_HOT_FUNCTION_ATTR void +mpfr_fz_norm_square (mpfr_ptr norm_sqr, mpfr_ptr temp1, mpfr_srcptr re, mpfr_srcptr im, mpfr_rnd_t rnd_mode) +{ + mpfr_sqr(norm_sqr, re, rnd_mode); // re^2 + mpfr_sqr(temp1, im, rnd_mode); // im^2 + mpfr_add(norm_sqr, norm_sqr, temp1, rnd_mode); // re^2 + im^2 +} + +MPFR_HOT_FUNCTION_ATTR void +mpfr_fz_get_d (double* valRe, double* valIm, mpfr_srcptr re, mpfr_srcptr im, mpfr_rnd_t rnd_mode) +{ + *valRe = mpfr_get_d(re, rnd_mode); + *valIm = mpfr_get_d(im, rnd_mode); +} + +MPFR_HOT_FUNCTION_ATTR void +mpfr_fz_get_d_2exp (double* valRe, double* valIm, long *expRe, long* expIm, mpfr_srcptr re, mpfr_srcptr im, mpfr_rnd_t rnd_mode) +{ + *valRe = mpfr_get_d_2exp(expRe, re, rnd_mode); + *valIm = mpfr_get_d_2exp(expIm, im, rnd_mode); +} + +MPFR_HOT_FUNCTION_ATTR void +mpfr_fz_set (mpfr_ptr destre, mpfr_ptr destim, mpfr_srcptr srcre, mpfr_srcptr srcim, mpfr_rnd_t rnd_mode) +{ + mpfr_set(destre, srcre, rnd_mode); + mpfr_set(destim, srcim, rnd_mode); +} + + +MPFR_HOT_FUNCTION_ATTR void +mpfr_fz_self_add (mpfr_ptr re, mpfr_ptr im, mpfr_srcptr val_re, mpfr_srcptr val_im, mpfr_rnd_t rnd_mode) +{ + mpfr_add(re, re, val_re, rnd_mode); + mpfr_add(im, im, val_im, rnd_mode); +} + +MPFR_HOT_FUNCTION_ATTR void +mpfr_fz_self_sub (mpfr_ptr re, mpfr_ptr im, mpfr_srcptr val_re, mpfr_srcptr val_im, mpfr_rnd_t rnd_mode) +{ + mpfr_sub(re, re, val_re, rnd_mode); + mpfr_sub(im, im, val_im, rnd_mode); +} + +MPFR_HOT_FUNCTION_ATTR void +mpfr_fz_rotation (mpfr_ptr x, mpfr_ptr y, mpfr_ptr temp_re, mpfr_ptr temp_im, mpfr_ptr f, mpfr_srcptr a, mpfr_srcptr asb, mpfr_srcptr apb, mpfr_rnd_t rnd_mode) +{ + mpfr_sub(f, x, y, rnd_mode); + mpfr_mul(f, a, f, rnd_mode); + + mpfr_mul(temp_re, asb, y, rnd_mode); + mpfr_mul(temp_im, apb, x, rnd_mode); + + mpfr_add(x, temp_re, f, rnd_mode); + mpfr_sub(y, temp_im, f, rnd_mode); +} + + +MPFR_HOT_FUNCTION_ATTR void +mpfr_fz_AsBmC (mpfr_ptr temp, mpfr_srcptr a, mpfr_srcptr b, int c, mpfr_rnd_t rnd_mode) +{ + mpfr_mul_si(temp, b, c, rnd_mode); + mpfr_sub(temp, a, temp, rnd_mode); +} + +MPFR_HOT_FUNCTION_ATTR void +mpfr_fz_ApBmC (mpfr_ptr temp, mpfr_srcptr a, mpfr_srcptr b, int c, mpfr_rnd_t rnd_mode) +{ + mpfr_mul_si(temp, b, c, rnd_mode); + mpfr_add(temp, a, temp, rnd_mode); +} + +MPFR_HOT_FUNCTION_ATTR void +mpfr_fz_ApBmC_DsEmG (mpfr_ptr temp, mpfr_ptr temp2, mpfr_srcptr a, mpfr_srcptr b, double c, mpfr_srcptr d, mpfr_srcptr e, double g, mpfr_rnd_t rnd_mode) +{ + mpfr_mul_d(temp, b, c, rnd_mode); + mpfr_add(temp, a, temp, rnd_mode); + + mpfr_mul_d(temp2, e, g, rnd_mode); + mpfr_sub(temp2, d, temp2, rnd_mode); +} + + +MPFR_HOT_FUNCTION_ATTR void +mpfr_fz_ApBmC_DpEmG (mpfr_ptr temp, mpfr_ptr temp2, mpfr_srcptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_srcptr d, mpfr_srcptr e, mpfr_srcptr g, mpfr_rnd_t rnd_mode) +{ + mpfr_mul(temp, b, c, rnd_mode); + mpfr_add(temp, a, temp, rnd_mode); + + mpfr_mul(temp2, e, g, rnd_mode); + mpfr_add(temp2, d, temp2, rnd_mode); +} + +MPFR_HOT_FUNCTION_ATTR void +mpfr_fz_r_ball_pow2 (mpfr_ptr r, mpfr_ptr az, mpfr_srcptr r0, mpfr_srcptr azsquare, mpfr_rnd_t rnd_mode) +{ + mpfr_add(az, r, az, rnd_mode); // az = az + r + mpfr_sqr(r, az, rnd_mode); // r = (az + r)^2 + mpfr_sub(r, r, azsquare, rnd_mode); + mpfr_add(r, r, r0, rnd_mode); +} diff --git a/src/fractalzoomer/core/mpir/LibMpir.java b/src/fractalzoomer/core/mpir/LibMpir.java index a08c12bd4..e4b87f42e 100644 --- a/src/fractalzoomer/core/mpir/LibMpir.java +++ b/src/fractalzoomer/core/mpir/LibMpir.java @@ -215,9 +215,12 @@ private LibMpir() { public static native void mpir_fz_square (mpf_t re, mpf_t im, mpf_t temp, mpf_t re_sqr, mpf_t im_sqr, mpf_t norm_sqr); public static native void mpir_fz_norm_square_with_components (mpf_t re_sqr, mpf_t im_sqr, mpf_t norm_sqr, mpf_t re, mpf_t im, int use_threads); public static native void mpir_fz_get_d (double[] valRe, double[] valIm, mpf_t re, mpf_t im); - public static native int mpir_fz_get_d_2exp (double[] valRe, double[] valIm, long[] expRe, long[] expIm, mpf_t re, mpf_t im); - public static native int mpir_fz_get_d_2exp (double[] valRe, double[] valIm, int[] expRe, int[] expIm, mpf_t re, mpf_t im); + public static native void mpir_fz_get_d_2exp (double[] valRe, double[] valIm, long[] expRe, long[] expIm, mpf_t re, mpf_t im); + public static native void mpir_fz_get_d_2exp (double[] valRe, double[] valIm, int[] expRe, int[] expIm, mpf_t re, mpf_t im); public static native void mpir_fz_square_plus_c_simple (mpf_t re, mpf_t im, mpf_t temp1, mpf_t temp2, mpf_t temp3, mpf_t cre, mpf_t cim, int algorithm, int use_threads); + public static native void mpir_fz_square_plus_c_simple_with_reduction_not_deep (mpf_t re, mpf_t im, mpf_t temp1, mpf_t temp2, mpf_t temp3, mpf_t cre, mpf_t cim, int algorithm, int use_threads, double[] valRe, double[] valIm); + public static native void mpir_fz_square_plus_c_simple_with_reduction_deep (mpf_t re, mpf_t im, mpf_t temp1, mpf_t temp2, mpf_t temp3, mpf_t cre, mpf_t cim, int algorithm, int use_threads, double[] mantissaRe, double[] mantissaIm, long[] expRe, long[] expIm); + public static native void mpir_fz_square_plus_c_simple_with_reduction_deep (mpf_t re, mpf_t im, mpf_t temp1, mpf_t temp2, mpf_t temp3, mpf_t cre, mpf_t cim, int algorithm, int use_threads, double[] mantissaRe, double[] mantissaIm, int[] expRe, int[] expIm); public static native void mpir_fz_set (mpf_t destre, mpf_t destim, mpf_t srcre, mpf_t srcim); public static native void mpir_fz_norm_square (mpf_t norm_sqr, mpf_t temp1, mpf_t re, mpf_t im, int use_threads); public static native void mpir_fz_self_add (mpf_t re, mpf_t im, mpf_t val_re, mpf_t val_im); @@ -229,4 +232,6 @@ private LibMpir() { public static native void mpir_fz_ApBmC_DpEmG (mpf_t temp, mpf_t temp2, mpf_t a, mpf_t b, mpf_t c, mpf_t d, mpf_t e, mpf_t g); public static native void mpir_fz_r_ball_pow2 (mpf_t r, mpf_t az, mpf_t r0, mpf_t azsquare); + public static native int __gmp_snprintf (byte[] buf, int size, String template, mpf_t value); + } \ No newline at end of file diff --git a/src/fractalzoomer/core/mpir/MpirBigNum.java b/src/fractalzoomer/core/mpir/MpirBigNum.java index 1e66839e4..b8a62066a 100644 --- a/src/fractalzoomer/core/mpir/MpirBigNum.java +++ b/src/fractalzoomer/core/mpir/MpirBigNum.java @@ -1,17 +1,15 @@ package fractalzoomer.core.mpir; -import fractalzoomer.core.MantExp; -import fractalzoomer.core.TaskDraw; +import fractalzoomer.core.*; import fractalzoomer.core.mpfr.MpfrBigNum; import fractalzoomer.core.mpfr.mpfr_t; import org.apfloat.Apfloat; import java.util.Arrays; -import static fractalzoomer.core.mpfr.LibMpfr.mpfr_div_2ui; -import static fractalzoomer.core.mpfr.LibMpfr.mpfr_mul_2ui; import static fractalzoomer.core.mpir.LibMpir.*; +import static fractalzoomer.core.mpir.LibMpir.mpir_fz_square_plus_c_simple_with_reduction_deep; public class MpirBigNum { @@ -396,18 +394,21 @@ public double doubleValue() { } public MantExp getMantExp() { - if(__gmpf_cmp_ui(mpfMemory.peer, 0) == 0) { - return new MantExp(); - } if(isLong4) { int[] exp = new int[1]; double d = __gmpf_get_d_2exp(exp, mpfMemory.peer); + if(d == 0) { + return new MantExp(); + } return new MantExp(exp[0], d); } else { long[] exp = new long[1]; double d = __gmpf_get_d_2exp(exp, mpfMemory.peer); + if(d == 0) { + return new MantExp(); + } return new MantExp(exp[0], d); } @@ -459,38 +460,40 @@ public static MantExp[] get_d_2exp (MpirBigNum re, MpirBigNum im) { int[] reExp = new int[1]; int[] imExp = new int[1]; - int result = mpir_fz_get_d_2exp(reD, imD, reExp, imExp, re.mpfMemory.peer, im.mpfMemory.peer); + mpir_fz_get_d_2exp(reD, imD, reExp, imExp, re.mpfMemory.peer, im.mpfMemory.peer); - if(result == 0) { //No zero - return new MantExp[] {new MantExp(reExp[0], reD[0]), new MantExp(imExp[0], imD[0])}; + double v1 = reD[0], v2 = imD[0]; + if(v1 == 0 && v2 == 0) { + return new MantExp[] {new MantExp(), new MantExp()}; } - else if(result == 1) { // re is zero - return new MantExp[] {new MantExp(), new MantExp(imExp[0], imD[0])}; + else if(v1 == 0) { + return new MantExp[] {new MantExp(), new MantExp(imExp[0], v2)}; } - else if (result == 2) { // im is zero - return new MantExp[] {new MantExp(reExp[0], reD[0]), new MantExp()}; + else if(v2 == 0) { + return new MantExp[] {new MantExp(reExp[0], v1), new MantExp()}; } - else { // both - return new MantExp[] {new MantExp(), new MantExp()}; + else { + return new MantExp[] {new MantExp(reExp[0], v1), new MantExp(imExp[0], v2)}; } } else { long[] reExp = new long[1]; long[] imExp = new long[1]; - int result = mpir_fz_get_d_2exp(reD, imD, reExp, imExp, re.mpfMemory.peer, im.mpfMemory.peer); - - if(result == 0) { - return new MantExp[] {new MantExp(reExp[0], reD[0]), new MantExp(imExp[0], imD[0])}; + mpir_fz_get_d_2exp(reD, imD, reExp, imExp, re.mpfMemory.peer, im.mpfMemory.peer); + double v1 = reD[0], v2 = imD[0]; + if(v1 == 0 && v2 == 0) { + return new MantExp[] {new MantExp(), new MantExp()}; } - else if(result == 1) { - return new MantExp[] {new MantExp(), new MantExp(imExp[0], imD[0])}; + else if(v1 == 0) { + return new MantExp[] {new MantExp(), new MantExp(imExp[0], v2)}; } - else if (result == 2) { - return new MantExp[] {new MantExp(reExp[0], reD[0]), new MantExp()}; + else if(v2 == 0) { + return new MantExp[] {new MantExp(reExp[0], v1), new MantExp()}; } else { - return new MantExp[] {new MantExp(), new MantExp()}; + return new MantExp[] {new MantExp(reExp[0], v1), new MantExp(imExp[0], v2)}; } + } @@ -508,6 +511,35 @@ public static void z_sqr_p_c(MpirBigNum re, MpirBigNum im, MpirBigNum temp1, Mpi } + static double[] valRe = new double[1]; + static double[] valIm = new double[1]; + static double[] mantissaRe = new double[1]; + static double[] mantissaIm = new double[1]; + + static long[] reExpL = new long[1]; + static long[] imExpL = new long[1]; + static int[] reExp = new int[1]; + static int[] imExp = new int[1]; + + public static void z_sqr_p_c_with_reduction(MpirBigNum re, MpirBigNum im, MpirBigNum temp1, MpirBigNum temp2, MpirBigNum temp3, MpirBigNum cre, MpirBigNum cim, boolean deepZoom, Complex cz, MantExpComplex mcz) { + + if(deepZoom) { + if(isLong4) { + mpir_fz_square_plus_c_simple_with_reduction_deep(re.mpfMemory.peer, im.mpfMemory.peer, temp1.mpfMemory.peer, temp2.mpfMemory.peer, temp3.mpfMemory.peer, cre.mpfMemory.peer, cim.mpfMemory.peer, 1, use_threads, mantissaRe, mantissaIm, reExp, imExp); + mcz.set(reExp[0], imExp[0], mantissaRe[0], mantissaIm[0]); + } + else { + mpir_fz_square_plus_c_simple_with_reduction_deep(re.mpfMemory.peer, im.mpfMemory.peer, temp1.mpfMemory.peer, temp2.mpfMemory.peer, temp3.mpfMemory.peer, cre.mpfMemory.peer, cim.mpfMemory.peer, 1, use_threads, mantissaRe, mantissaIm, reExpL, imExpL); + mcz.set(reExpL[0], imExpL[0], mantissaRe[0], mantissaIm[0]); + } + } + else { + mpir_fz_square_plus_c_simple_with_reduction_not_deep(re.mpfMemory.peer, im.mpfMemory.peer, temp1.mpfMemory.peer, temp2.mpfMemory.peer, temp3.mpfMemory.peer, cre.mpfMemory.peer, cim.mpfMemory.peer, 1, use_threads, valRe, valIm); + cz.assign(valRe[0], valIm[0]); + } + + } + public static void z_sqr_p_c_no_threads(MpirBigNum re, MpirBigNum im, MpirBigNum temp1, MpirBigNum temp2, MpirBigNum temp3, MpirBigNum cre, MpirBigNum cim) { mpir_fz_square_plus_c_simple(re.mpfMemory.peer, im.mpfMemory.peer, temp1.mpfMemory.peer, temp2.mpfMemory.peer, temp3.mpfMemory.peer, cre.mpfMemory.peer, cim.mpfMemory.peer, 1, 0); @@ -572,6 +604,17 @@ public static void r_ball_pow2(MpirBigNum r, MpirBigNum az, MpirBigNum r0, MpirB } + public String toFullString() { +// int n = (int) MyApfloat.precision * 2; +// byte[] buf = new byte[n]; +// String template = "%." + MyApfloat.precision + "f"; +// __gmp_snprintf(buf, n, template, mpfMemory.peer); +// return new String(buf).trim(); + return new MpfrBigNum(this).toFullString(); + } + + public Apfloat toApfloat() { return new MyApfloat(toFullString());} + public static void main(String[] args) { MpfrBigNum b = new MpfrBigNum("1.536436437574574384584385466456436634574743734743754365532432523531"); diff --git a/src/fractalzoomer/core/mpir/custom_mpir.c b/src/fractalzoomer/core/mpir/custom_mpir.c index b0d30eef0..0925e9863 100644 --- a/src/fractalzoomer/core/mpir/custom_mpir.c +++ b/src/fractalzoomer/core/mpir/custom_mpir.c @@ -112,6 +112,159 @@ void mpir_fz_square_plus_c_simple(mpf_ptr re, mpf_ptr im, mpf_ptr temp1, mpf_ptr } + +void mpir_fz_square_plus_c_simple_with_reduction_not_deep(mpf_ptr re, mpf_ptr im, mpf_ptr temp1, mpf_ptr temp2, mpf_ptr temp3, mpf_srcptr cre, mpf_srcptr cim, int algorithm, int use_threads, double* valRe, double* valIm) +{ + if (algorithm == 0) { + if (use_threads) { + #pragma omp parallel sections num_threads(2) + { + #pragma omp section + { + mpf_add(temp1, re, im); // temp1 = re + im + mpf_sub(temp2, re, im); // temp2 = re - im + mpf_mul(temp2, temp1, temp2); // temp2 = (re + im) * (re - im) + } + #pragma omp section + { + mpf_mul(temp3, re, im); // temp3 = re * im + mpf_mul_2exp(temp3, temp3, 1); // temp3 = 2 * re * im + } + } + } + else { + mpf_add(temp1, re, im); // temp1 = re + im + mpf_sub(temp2, re, im); // temp2 = re - im + mpf_mul(temp2, temp1, temp2); // temp2 = (re + im) * (re - im) + + mpf_mul(temp3, re, im); // temp3 = re * im + mpf_mul_2exp(temp3, temp3, 1); // temp3 = 2 * re * im + } + + mpf_add(re, temp2, cre); // re = (re + im) * (re - im) + cre + mpf_add(im, temp3, cim); // im = 2 * re * im + cim + } + else { + if (use_threads) { + + #pragma omp parallel sections num_threads(3) + { + #pragma omp section + { + mpf_mul(temp1, re, re); // re^2 + } + #pragma omp section + { + mpf_mul(temp2, im, im); // im^2 + } + #pragma omp section + { + mpf_add(temp3, re, im); // temp3 = re + im + mpf_mul(temp3, temp3, temp3); // temp3 = (re + im)^2 + } + } + } + else { + mpf_mul(temp1, re, re); // re^2 + mpf_mul(temp2, im, im); // im^2 + + mpf_add(temp3, re, im); // temp3 = re + im + mpf_mul(temp3, temp3, temp3); // temp3 = (re + im)^2 + } + + + mpf_sub(re, temp1, temp2); // re = re^2 - im^2 + mpf_add(re, re, cre); // re = re^2 - im^2 + cre + + + mpf_add(temp1, temp1, temp2); // temp1 = re^2 + im^2 + + mpf_sub(im, temp3, temp1); // im = (re + im)^2 - re^2 - im^2 + mpf_add(im, im, cim); // im = (re + im)^2 - re^2 - im^2 + cim + } + + *valRe = mpf_get_d(re); + *valIm = mpf_get_d(im); + +} + +void mpir_fz_square_plus_c_simple_with_reduction_deep(mpf_ptr re, mpf_ptr im, mpf_ptr temp1, mpf_ptr temp2, mpf_ptr temp3, mpf_srcptr cre, mpf_srcptr cim, int algorithm, int use_threads, double* mantissaRe, double* mantissaIm, long* expRe, long* expIm) +{ + + if (algorithm == 0) { + if (use_threads) { + #pragma omp parallel sections num_threads(2) + { + #pragma omp section + { + mpf_add(temp1, re, im); // temp1 = re + im + mpf_sub(temp2, re, im); // temp2 = re - im + mpf_mul(temp2, temp1, temp2); // temp2 = (re + im) * (re - im) + } + #pragma omp section + { + mpf_mul(temp3, re, im); // temp3 = re * im + mpf_mul_2exp(temp3, temp3, 1); // temp3 = 2 * re * im + } + } + } + else { + mpf_add(temp1, re, im); // temp1 = re + im + mpf_sub(temp2, re, im); // temp2 = re - im + mpf_mul(temp2, temp1, temp2); // temp2 = (re + im) * (re - im) + + mpf_mul(temp3, re, im); // temp3 = re * im + mpf_mul_2exp(temp3, temp3, 1); // temp3 = 2 * re * im + } + + mpf_add(re, temp2, cre); // re = (re + im) * (re - im) + cre + mpf_add(im, temp3, cim); // im = 2 * re * im + cim + } + else { + if (use_threads) { + + #pragma omp parallel sections num_threads(3) + { + #pragma omp section + { + mpf_mul(temp1, re, re); // re^2 + } + #pragma omp section + { + mpf_mul(temp2, im, im); // im^2 + } + #pragma omp section + { + mpf_add(temp3, re, im); // temp3 = re + im + mpf_mul(temp3, temp3, temp3); // temp3 = (re + im)^2 + } + } + } + else { + mpf_mul(temp1, re, re); // re^2 + mpf_mul(temp2, im, im); // im^2 + + mpf_add(temp3, re, im); // temp3 = re + im + mpf_mul(temp3, temp3, temp3); // temp3 = (re + im)^2 + } + + + mpf_sub(re, temp1, temp2); // re = re^2 - im^2 + mpf_add(re, re, cre); // re = re^2 - im^2 + cre + + + mpf_add(temp1, temp1, temp2); // temp1 = re^2 + im^2 + + mpf_sub(im, temp3, temp1); // im = (re + im)^2 - re^2 - im^2 + mpf_add(im, im, cim); // im = (re + im)^2 - re^2 - im^2 + cim + } + + + *mantissaRe = mpf_get_d_2exp(expRe, re); + *mantissaIm = mpf_get_d_2exp(expIm, im); + +} + void mpir_fz_norm_square_with_components(mpf_ptr re_sqr, mpf_ptr im_sqr, mpf_ptr norm_sqr, mpf_srcptr re, mpf_srcptr im, int use_threads) { if (use_threads) { @@ -162,25 +315,10 @@ void mpir_fz_get_d(double* valRe, double* valIm, mpf_srcptr re, mpf_srcptr im) *valIm = mpf_get_d(im); } -int mpir_fz_get_d_2exp(double* valRe, double* valIm, long* expRe, long* expIm, mpf_srcptr re, mpf_srcptr im) +void mpir_fz_get_d_2exp(double* valRe, double* valIm, long* expRe, long* expIm, mpf_srcptr re, mpf_srcptr im) { - int isZero = 0; - - if (mpf_cmp_ui(re, 0) == 0) { - isZero = 0x1; - } - else { - *valRe = mpf_get_d_2exp(expRe, re); - } - - if (mpf_cmp_ui(im, 0) == 0) { - isZero |= 0x2; - } - else { - *valIm = mpf_get_d_2exp(expIm, im); - } - - return isZero; + *valRe = mpf_get_d_2exp(expRe, re); + *valIm = mpf_get_d_2exp(expIm, im); } void mpir_fz_set(mpf_ptr destre, mpf_ptr destim, mpf_srcptr srcre, mpf_srcptr srcim) diff --git a/src/fractalzoomer/core/unused/BigDecNum.java b/src/fractalzoomer/core/unused/BigDecNum.java index 109db036f..a6564241c 100644 --- a/src/fractalzoomer/core/unused/BigDecNum.java +++ b/src/fractalzoomer/core/unused/BigDecNum.java @@ -178,4 +178,6 @@ public BigDecNum pow(int n) { return new BigDecNum(bd.pow(n, mc)); } + public Apfloat toApfloat() { return new MyApfloat(bd.toString());} + } diff --git a/src/fractalzoomer/core/unused/BigDecNumComplex.java b/src/fractalzoomer/core/unused/BigDecNumComplex.java index 346a42d23..a1b62f548 100644 --- a/src/fractalzoomer/core/unused/BigDecNumComplex.java +++ b/src/fractalzoomer/core/unused/BigDecNumComplex.java @@ -324,6 +324,7 @@ public final BigDecNumComplex i_divide(double number) { } + @Override public final BigDecNumComplex reciprocal() { BigDecNum temp = re.square().add(im.square()).reciprocal(); @@ -994,4 +995,9 @@ public BigDecNumComplex square_mutable() { return square(); } + + @Override + public BigComplex toBigComplex() { + return new BigComplex(re.toApfloat(), im.toApfloat()); + } } diff --git a/src/fractalzoomer/core/unused/BigNum64.java b/src/fractalzoomer/core/unused/BigNum64.java deleted file mode 100644 index 243ca39a8..000000000 --- a/src/fractalzoomer/core/unused/BigNum64.java +++ /dev/null @@ -1,1810 +0,0 @@ -package fractalzoomer.core.unused; - -import fractalzoomer.core.MantExp; -import fractalzoomer.core.MyApfloat; -import fractalzoomer.core.TaskDraw; -import org.apfloat.Apfloat; -import org.apfloat.internal.LongMemoryDataStorage; - -import java.util.Arrays; - -import static fractalzoomer.core.MyApfloat.TWO; -import static org.apfloat.internal.LongRadixConstants.BASE_DIGITS; - -public class BigNum64 { - private long[] digits = null; - private int sign; - private boolean isOne; - private long scale; - private int offset; - private int bitOffset; - public static int fracDigits = 2; - public static int fracDigitsm1 = fracDigits - 1; - public static int fracDigitsp1 = fracDigits + 1; - - public static final long MASK = 0x0FFFFFFFFFFFFFFFL; - public static final int SHIFT = 60; - public static final long MASKD0 = 0x7FFFFFFFFFFFFFFFL; - - public static final long MASKI = 0x3FFFFFFFL; - public static final int SHIFTI = 30; - public static final long MASK31 = 0x40000000L; - public static final int SHIFTM1 = SHIFT - 1; - public static final int SHIFTM52 = SHIFT - 52; - public static int fracDigitsShift = fracDigits * SHIFT; - public static boolean useToDouble2 = fracDigits > 60; - public static boolean useKaratsuba = fracDigits > 15; - public static int fracDigits2 = fracDigits << 1; - public static int fracDigits05 = fracDigits >> 1; - - private static final double TWO_TO_SHIFT = Math.pow(2,-SHIFT); - - public static void reinitialize(double digits) { - - fracDigits = (int)((digits / SHIFT) * TaskDraw.BIGNUM_PRECISION_FACTOR) + 1; - fracDigitsm1 = fracDigits - 1; - fracDigitsp1 = fracDigits + 1; - fracDigitsShift = fracDigits * SHIFT; - useToDouble2 = fracDigits > 60; - useKaratsuba = fracDigits > 15; - fracDigits2 = fracDigits << 1; - fracDigits05 = fracDigits >> 1; - - } - - public static BigNum64 getMax() { - BigNum64 n = new BigNum64(); - n.digits[0] = MASKD0; - n.sign = 1; - return n; - } - - public BigNum64() { - digits = new long[fracDigitsp1]; - sign = 0; - isOne = false; - scale = 0; - offset = -1; - bitOffset = -1; - } - - public BigNum64(int val) { - digits = new long[fracDigitsp1]; - digits[0] = val; - isOne = val == 1 || val == -1; - sign = (int)Math.signum(val); - scale = 0; - offset = -1; - bitOffset = -1; - } - - public BigNum64(BigNum64 other) { - digits = Arrays.copyOf(other.digits, other.digits.length); - sign = other.sign; - isOne = other.isOne; - scale = 0; - offset = -1; - bitOffset = -1; - } - - public BigNum64(double val) { - - digits = new long[fracDigitsp1]; - if (val == 0) { - sign = 0; - isOne = false; - return; - } else if (Math.abs(val) == 1) { - isOne = true; - sign = (int) val; - digits[0] = 1; - return; - } - - sign = (int) Math.signum(val); - val = Math.abs(val); - digits[0] = (long) (val); - double fractionalPart = val - (long) val; - - if (fractionalPart != 0) { - - long bits = Double.doubleToRawLongBits(fractionalPart); - long f_exp = ((bits & 0x7FF0000000000000L) >>> 52) - Double.MAX_EXPONENT; - long mantissa = (bits & 0xFFFFFFFFFFFFFL) | (0x10000000000000L); - - if(f_exp < 0) { - long posExp = -f_exp; - - int index = (int) (posExp / SHIFT) + 1; - int bitOffset = (int) (posExp % SHIFT); - - if (bitOffset == 0) { - index--; - bitOffset = SHIFT; - } - - int k; - int i = index; - for (k = 53; k > 0 && i < digits.length; i++) { - int r; - - if (k == 53) { - r = SHIFT - k - bitOffset + 1; - k -= r < 0 ? 53 + r : 53 - r; - } else { - r = SHIFT - k; - k -= k; - } - - if (r >= 0) { - digits[i] = (mantissa << r) & MASK; - } else { - digits[i] = (mantissa >>> (-r)) & MASK; - } - - } - } - - } - } - - public BigNum64(Apfloat val) { - - Apfloat baseTwo = val.toRadix(2); - - sign = baseTwo.getImpl().signum(); - - isOne = false; - - digits = new long[fracDigitsp1]; - - LongMemoryDataStorage str = (LongMemoryDataStorage)baseTwo.getImpl().getDataStorage(); - - if(str == null || sign == 0) { //for zero - return; - } - - long[] data = str.getData(); - - if(data.length == 1 && data[0] == 1) { - isOne = true; - } - - int base_digits = BASE_DIGITS[2]; - - int offset = (int)str.getOffset(); - - int exponent = (int)baseTwo.getImpl().getExponent(); - - if(exponent == 1) { - int index = data.length >= 2 ? 1 : 0; - digits[0] = MASKD0 & data[index]; - offset++; - } - - int length = (data.length - offset) * base_digits; - int length2 = fracDigitsShift; - int dataOffset = exponent < 0 ? Math.abs(exponent) * base_digits : 0; - - for(int i = dataOffset, j = 0; i < length2 && i < length; i++, j++) { - int shift = base_digits - (j % base_digits) - 1; - long bit = (data[j / base_digits + offset] >>> shift) & 0x1; - - digits[(i / SHIFT) + 1] |= bit << (SHIFT - (i % SHIFT) - 1); - } - - scale = 0; - this.offset = -1; - bitOffset = -1; - - } - - public long getScale() { - - if(sign == 0) { - return Long.MIN_VALUE; - } - - if(offset != -1) { - return scale; - } - - int i; - long digit = 0; - for(i = 0; i < digits.length; i++) { - digit = digits[i]; - if(digit != 0) { - break; - } - } - - if(i == digits.length) { - return Long.MIN_VALUE; - } - - /*int r; - for(r = i == 0 ? SHIFT : SHIFTM1; r >= 0; r--) { - if(digits[i] >>> r != 0) { - break; - } - }*/ - - offset = i; - long v = digit; - double d = v & ~(v >>> 1); - //int r = (int)(((Double.doubleToRawLongBits(d) >> 52) & 0x7ff) - 1023); //Fix for the 64 bit, not needed here - bitOffset = (int)(((Double.doubleToRawLongBits(d) >> 52)) - 1023); - //r |= (r >> 31); //Fix for zero, not needed here - - scale = digits[0] != 0 ? ((long)i) * SHIFT + bitOffset : -(((long)i) * SHIFT) + bitOffset; - - return scale; - } - - public static BigNum64 getNegative(BigNum64 other) { - - BigNum64 copy = new BigNum64(); - copy.sign = other.sign;; - copy.isOne = other.isOne; - - long[] otherDigits = other.digits; - long[] digits = copy.digits; - - long s = (~otherDigits[fracDigits] & MASK) + 1; - digits[fracDigits] = s & MASK; - for (int i = fracDigitsm1; i > 0 ; i--) { - s = (~otherDigits[i] & MASK) + (s>>>SHIFT); - digits[i] = s & MASK; - } - - s = (~otherDigits[0]) + (s>>>SHIFT); - digits[0] = s; - - return copy; - } - - public void negSelf() { - - if(sign == 0) { - return; - } - /*if(digits[fracDigits]>0) { - digits[fracDigits] = (int)((digits[fracDigits]-1)^MASK); - for(int i=fracDigits-1; i>0; i--) digits[i] ^= MASK; - digits[0] = ~digits[0]; - } else { - long s = digits[fracDigits-1]-1; digits[fracDigits-1] = (int)(~s&MASK); - for(int i=fracDigits-2; i>0; i--) { - s = digits[i]+(s>>SHIFT); digits[i] = (int)(~s&MASK); - } - digits[0] = (int)(~(digits[0]+(s>>SHIFT))); - }*/ - - long s = (~digits[fracDigits] & MASK) + 1; - digits[fracDigits] = s & MASK; - for (int i = fracDigitsm1; i > 0 ; i--) { - s = (~digits[i] & MASK) + (s>>>SHIFT); - digits[i] = s & MASK; - } - - s = (~digits[0]) + (s>>>SHIFT); - digits[0] = s; - - } - - public BigNum64 negate() { - - BigNum64 res = new BigNum64(this); - - res.sign *= -1; - - return res; - - } - - public BigNum64 abs() { - - BigNum64 res = new BigNum64(this); - - if(sign == -1) { - res.sign = 1; - } - - return res; - } - - @Override - public String toString() { - StringBuilder ret = new StringBuilder((sign == -1 ? "-" : "") + toHexString(digits[0])); - for(int i=1; i<=fracDigits; i++) { - ret.append(i==1 ? "." : " "); - ret.append(toHexString(digits[i])); - } - return ret.toString(); - } - - private static final String ZEROS = "0000000000000000000000000000000000000000000000000000000000000000"; - - - public static String toHexString(long l) { - String s = Long.toHexString(l); - return ZEROS.substring(0,16-s.length())+s; - } - - public void print() { - - Apfloat sum = MyApfloat.ZERO; - int decimal_bit_count = -1; - - if(sign == -1) { - System.out.print("-"); - } - for (int i = 0; i < digits.length; i++) { - - if (i == 0) { - boolean zero = true; - for (int j = SHIFTM1; j >= 0; j--) { - sum = MyApfloat.fp.add(sum, MyApfloat.fp.multiply(MyApfloat.fp.pow(TWO, j), new MyApfloat((digits[i] >> j) & 0x1))); - - if (((digits[i] >> j) & 0x1) == 1) { - zero = false; - } - - if (!zero) { - System.out.print((digits[i] >> j) & 0x1); - } - } - if(zero) { - System.out.print("0"); - } - System.out.print("."); - } else { - for (int j = SHIFTM1; j >= 0; j--) { - sum = MyApfloat.fp.add(sum, MyApfloat.fp.multiply(MyApfloat.fp.pow(TWO, decimal_bit_count), new MyApfloat((digits[i] >> j) & 0x1))); - decimal_bit_count--; - - System.out.print((digits[i] >> j) & 0x1); - - } - - } - } - - sum = MyApfloat.fp.multiply(sum, new MyApfloat(sign)); - - System.out.println(); - //System.out.println(sum.toRadix(2).toString(true)); - //System.out.println(sum); - - - - } - - public int compare(BigNum64 other) { - - int signA = sign; - - long[] otherDigits = other.digits; - - int signB = other.sign; - - if(signA < signB) { - return -1; - } - else if(signA > signB) { - return 1; - } - else if(signA == signB) { - if (signA == 0) { - return 0; - } - - if(signA < 0) { - for (int i = 0; i < digits.length; i++) { - long digit = digits[i]; - long otherDigit = otherDigits[i]; - if (digit < otherDigit) { - return 1; - } else if (digit > otherDigit) { - return -1; - } - } - } - else { - for (int i = 0; i < digits.length; i++) { - long digit = digits[i]; - long otherDigit = otherDigits[i]; - if (digit < otherDigit) { - return -1; - } else if (digit > otherDigit) { - return 1; - } - } - } - } - - return 0; - - } - - static long binarySearch64(long v) { - - int shift = 32; - - long res = v >>> shift; - - if(res == 1) { - return shift; - } - else if (res > 1) { - shift += 16; //+16 - } - else { - shift -= 16; // -16 - } - - res = v >>> shift; - - if(res == 1) { - return shift; - } - else if (res > 1) { - shift += 8; //+8 - } - else { - shift -= 8; // -8 - } - - res = v >>> shift; - - if(res == 1) { - return shift; - } - else if (res > 1) { - shift += 4; // +4 - } - else { - shift -= 4; // -4 - } - - res = v >>> shift; - - if(res == 1) { - return shift; - } - else if (res > 1) { - shift += 2; // + 2 - } - else { - shift -= 2; // -2 - } - - res = v >>> shift; - - if(res == 1) { - return shift; - } - else if (res > 1) { - shift += 1; // + 1 - } - else { - - shift -= 1; // -1 - } - - return shift; - } - - - static int debruijn64[] = - { - 0, 58, 1, 59, 47, 53, 2, 60, 39, 48, 27, 54, 33, 42, 3, 61, 51, 37, 40, 49, - 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4, 62, 57, 46, 52, 38, 26, 32, 41, - 50, 36, 17, 19, 29, 10, 13, 21, 56, 45, 25, 31, 35, 16, 9, 12, 44, 24, 15, - 8, 23, 7, 6, 5, 63 - }; - - static long msbDeBruijn64(long v) { - - - /* Round down to one less than a power of 2. */ - v |= v >>> 1; - v |= v >>> 2; - v |= v >>> 4; - v |= v >>> 8; - v |= v >>> 16; - v |= v >>> 32; - - /* 0x03f6eaf2cd271461 is a hexadecimal representation of a De Bruijn - * sequence for binary words of length 6. The binary representation - * starts with 000000111111. This is required to make it work with one less - * than a power of 2 instead of an actual power of 2. - */ - - return debruijn64[(int)((v * 0x03f6eaf2cd271461L) >>> 58)]; - } - - public double doubleValue2() { - - long[] digits = this.digits; - - int i; - long digit = 0; - for(i = 0; i < digits.length; i++) { - digit = digits[i]; - if(digit != 0) { - break; - } - } - - if(i == digits.length) { - return 0; - } - - /*int r; - for(r = i == 0 ? SHIFT : SHIFTM1; r >= 0; r--) { - if(digits[i] >>> r != 0) { - break; - } - }*/ - offset = i; - long v = digit; - double d = v & ~(v >>> 1); - //int r = (int)(((Double.doubleToRawLongBits(d) >> 52) & 0x7ff) - 1023); //Fix for the 64 bit, not needed here - bitOffset = (int)(((Double.doubleToRawLongBits(d) >> 52)) - 1023); - //r |= (r >> 31); //Fix for zero, not needed here - - scale = digits[0] != 0 ? ((long)i) * SHIFT + bitOffset : -(((long)i) * SHIFT) + bitOffset; - - if (scale < Double.MIN_EXPONENT) { //accounting for +1 - return 0.0; - } - else if (scale >= Double.MAX_EXPONENT) { - return sign == -1 ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; - } - - long mantissa = 0; - - int temp = 52 - bitOffset; - - long val = digit; - if(temp >= 0) { - mantissa |= val << temp; - mantissa = mantissa & 0xFFFFFFFFFFFFFL; - if(temp == 0 && i + 1 < digits.length) { - mantissa += (digits[i + 1] >>> (SHIFTM1)) & 0x1; - } - } - else { - int shift = -temp; - mantissa |= val >>> shift; - mantissa = mantissa & 0xFFFFFFFFFFFFFL; - mantissa += (val >>> (shift - 1)) & 0x1; - } - - i++; - - int k; - for(k = bitOffset ; k < 52 && i < digits.length; k+=SHIFT, i++) { - val = digits[i]; - temp = 52 - k; - - if(temp > SHIFT) { - mantissa |= val << (temp - SHIFT); - mantissa = mantissa & 0xFFFFFFFFFFFFFL; - } - else { - int temp2 = k + SHIFTM52; - mantissa |= val >>> temp2; - mantissa = mantissa & 0xFFFFFFFFFFFFFL; - - if(temp2 == 0 && i + 1 < digits.length) { - mantissa += (digits[i + 1] >>> (SHIFTM1)) & 0x1; - } - else { - mantissa += (val >>> (temp2 - 1)) & 0x1; - } - } - } - - long finalScale = scale + (mantissa >>> 52); - if (finalScale <= Double.MIN_EXPONENT) { - return 0.0; - } - else if (finalScale >= Double.MAX_EXPONENT) { - return sign == -1 ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; - } - - // Bit 63 (the bit that is selected by the mask 0x8000000000000000L) represents the sign of the floating-point number. - // Bits 62-52 (the bits that are selected by the mask 0x7ff0000000000000L) represent the exponent. - // Bits 51-0 (the bits that are selected by the mask 0x000fffffffffffffL) represent the significand (sometimes called the mantissa) of the floating-point number. - - if(sign == -1) { - return Double.longBitsToDouble( (0x8000000000000000L) | (mantissa & 0xFFFFFFFFFFFFFL) | ((finalScale + Double.MAX_EXPONENT) << 52)); - } - else { - return Double.longBitsToDouble((mantissa & 0xFFFFFFFFFFFFFL) | ((finalScale + Double.MAX_EXPONENT) << 52)); - } - - } - - public double doubleValue() { - - if (sign == 0) { - return 0; - } - - if(isOne) { - return sign; - } - - if(useToDouble2) { - return doubleValue2(); - } - - double ret = 0; - - - /*if(digits[0]>=0) { - for(int i=fracDigits; i>=0; i--) { - ret *= TWO_TO_SHIFT; - ret += digits[i]; - } - } else { - ret--; - for(int i=fracDigits; i>0; i--) { - ret += digits[i] - MASK; - ret *= TWO_TO_SHIFT; - } - ret += digits[0]+1; - }*/ - - for(int i=fracDigits; i>=0; i--) { - ret *= TWO_TO_SHIFT; - ret += digits[i]; - } - - ret *= sign; - return ret; - } - - public BigNum64 add(BigNum64 a) { - - BigNum64 result = new BigNum64(); - - long[] otherDigits = a.digits; - int otherSign = a.sign; - - long[] resDigits = result.digits; - - long[] digits = this.digits; - int sign = this.sign; - - if(sign == 0 || otherSign == 0) { - if(sign == 0 && otherSign == 0){ - return result; - } - else if(sign == 0) { - result.sign = otherSign; - result.isOne = a.isOne; - System.arraycopy(otherDigits, 0, resDigits, 0, otherDigits.length); - } - else { - result.sign = sign; - result.isOne = isOne; - System.arraycopy(digits, 0, resDigits, 0, digits.length); - } - return result; - } - - if(sign != otherSign) { - if(sign == -1) { - BigNum64 copy = getNegative(this); - digits = copy.digits; - } - else - { - BigNum64 copy = getNegative(a); - otherDigits = copy.digits; - } - } - - long s = 0; - long isNonZero = 0; - for(int i=fracDigits; i>0; i--) { - s += digits[i]+otherDigits[i]; - long temp = s&MASK; - isNonZero |= temp; - resDigits[i] = temp; - s >>>= SHIFT; - } - long temp = digits[0]+otherDigits[0]+s; - result.isOne = (temp == 1 || temp == -1) && isNonZero == 0; - isNonZero |= temp; - resDigits[0] = temp; - - if(sign != otherSign) { - if(resDigits[0] < 0) { - result.sign = -1; - result.negSelf(); - } - else { - result.sign = isNonZero != 0 ? 1 : 0; - } - } - else { - result.sign = isNonZero != 0 ? sign : 0; - } - - return result; - } - - public BigNum64 sub(BigNum64 a) { - - BigNum64 result = new BigNum64(); - - long[] otherDigits = a.digits; - int otherSign = a.sign; - - long[] resDigits = result.digits; - - long[] digits = this.digits; - int sign = this.sign; - - if(sign == 0 || otherSign == 0) { - if(sign == 0 && otherSign == 0){ - return result; - } - else if(sign == 0) { - result.sign = -otherSign; - result.isOne = a.isOne; - System.arraycopy(otherDigits, 0, resDigits, 0, otherDigits.length); - } - else { - result.sign = sign; - result.isOne = isOne; - System.arraycopy(digits, 0, resDigits, 0, digits.length); - } - return result; - } - - if(sign == otherSign) { - // + + -> + - - // - - -> - + - if(sign == -1) { - BigNum64 copy = getNegative(this); - digits = copy.digits;; - } - else { - BigNum64 copy = getNegative(a); - otherDigits = copy.digits;; - } - } - - long s = 0; - long isNonZero = 0; - for(int i=fracDigits; i>0; i--) { - s += digits[i]+otherDigits[i]; - long temp = s&MASK; - isNonZero |= temp; - resDigits[i] = temp; - s >>>= SHIFT; - } - long temp = digits[0]+otherDigits[0]+s; - result.isOne = (temp == 1 || temp == -1) && isNonZero == 0; - isNonZero |= temp; - resDigits[0] = temp; - - if(sign == otherSign) { - if(resDigits[0] < 0) { - result.sign = -1; - result.negSelf(); - } - else { - result.sign = isNonZero != 0 ? 1 : 0; - } - } - else { - result.sign = isNonZero != 0 ? sign : 0; - } - - return result; - } - - public BigNum64 square() { - - - BigNum64 result = new BigNum64(); - - if(sign == 0) { - return result; - } - - long[] resDigits = result.digits; - long[] origDigitsA = this.digits; - - if(isOne) { - resDigits[0] = 1; - result.isOne = true; - result.sign = 1; - return result; - } - - int newFracDigits = fracDigits2; - int newLength = newFracDigits + 1; - int[] digits = new int[newLength]; - - long old_sum = 0; - - long sum = 0; - - int length = fracDigits05; - - long carry = 0; - - digits[0] = (int)origDigitsA[0]; - int j = 1, k = fracDigits; - int base = (j << 1) - 1, base2 = (k << 1); - for (; j <= length; j++, k--) { - long bdigit = origDigitsA[j]; - long adigit = origDigitsA[k]; - - long bjlo = bdigit & MASKI; - long aklo = adigit & MASKI; - - long bjhi = bdigit >>> SHIFTI; - long akhi = adigit >>> SHIFTI; - - digits[base2] = (int)(aklo); - digits[base] = (int)(bjhi); - base++; - base2--; - digits[base2] = (int)(akhi); - digits[base] = (int)(bjlo); - base++; - base2--; - - sum += bjlo * akhi; - carry += sum >>> SHIFTI; - sum = sum & MASKI; - - sum += bjhi * aklo; - carry += sum >>> SHIFTI; - sum = sum & MASKI; - - } - - if(j == k) { - long bdigit = origDigitsA[j]; - long aklo = bdigit & MASKI; - long bjhi = bdigit >>> SHIFTI; - - digits[base2] = (int)(aklo); - digits[base] = (int)(bjhi); - - sum += bjhi * aklo; - carry += sum >>> SHIFTI; - sum = sum & MASKI; - } - - carry = carry << 1; - sum = sum << 1; - carry += sum >>> SHIFTI; - sum = sum & MASKI; - - - old_sum = carry + (sum >>> (SHIFTI - 1)); // Roundish - - int m = fracDigits; - for(int i = newFracDigits; i > 0; i--, m--) { - - sum = old_sum; - - length = (i >> 1) - 1; - - long temp_sum = 0; - carry = 0; - - long bj, ak; - - for(j = 0, k = i; j <= length; j++, k--) { - bj = digits[j]; - ak = digits[k]; - temp_sum += bj * ak; - carry += temp_sum >>> SHIFTI; - temp_sum = temp_sum & MASKI; - } - - carry = carry << 1; - - bj = digits[j]; - ak = digits[k]; - temp_sum = (temp_sum << 1) + bj * ak; - - //carry += temp_sum >>> SHIFT; //Maybe its ok - //temp_sum = temp_sum & MASK; - - sum += temp_sum; - carry += sum >>> SHIFTI; - sum = sum & MASKI; - - long finalVal = sum; - - i--;//Unrolling - - sum = carry; - - length = i >> 1; - - temp_sum = 0; - carry = 0; - - for(j = 0, k = i; j <= length; j++, k--) { - bj = digits[j]; - ak = digits[k]; - temp_sum += bj * ak; - carry += temp_sum >>> SHIFTI; - temp_sum = temp_sum & MASKI; - } - - carry = carry << 1; - temp_sum = temp_sum << 1; - - //carry += temp_sum >>> SHIFT; //Maybe its ok - //temp_sum = temp_sum & MASK; - - sum += temp_sum; - carry += sum >>> SHIFTI; - sum = sum & MASKI; - - finalVal |= sum << SHIFTI; - - resDigits[m] = finalVal; - old_sum = carry; - } - - sum = old_sum; - - long bj = digits[0]; - long ak = digits[0]; - sum += bj * ak; - - result.sign = 1; - - result.digits[0] = sum; - - return result; - } - - public BigNum64 squareKaratsuba() { - - BigNum64 result = new BigNum64(); - - if(sign == 0) { - return result; - } - - long[] resDigits = result.digits; - long[] origDigitsA = this.digits; - - if(isOne) { - resDigits[0] = 1; - result.isOne = true; - result.sign = 1; - return result; - } - - int newFracDigits = fracDigits2; - int newLength = newFracDigits + 1; - int[] digits = new int[newLength]; - - long[] partials = new long[newLength]; - - long PartialSum = 0; - long PartialCarry = 0; - - long adigit = (int)origDigitsA[0]; - digits[0] = (int)adigit; - - long p = adigit * adigit; - long p0 = p; - partials[0] = p; - PartialSum += p; - - PartialCarry += PartialSum >>> SHIFTI; - PartialSum = PartialSum & MASKI; - - for(int i = 1, base = (i << 1) - 1; i <=fracDigits; i++) { - - adigit = origDigitsA[i]; - long aklo = adigit & MASKI; - - long akhi = adigit >>> SHIFTI; - - digits[base] = (int)(akhi); - p = akhi * akhi; - partials[base] = p; - PartialSum += p; - PartialCarry += PartialSum >>> SHIFTI; - PartialSum = PartialSum & MASKI; - - base++; - digits[base] = (int)(aklo); - p = aklo * aklo; - partials[base] = p; - PartialSum += p; - - PartialCarry += PartialSum >>> SHIFTI; - PartialSum = PartialSum & MASKI; - base++; - - - } - - long old_sum = 0; - - //for(int i = MAX_FRAC_DIGITS; i > 0; i--) { - //long sum += (int)(old_sum >>> SHIFT30); - - //long sum = (old_sum >>> SHIFT31); - - long sum = p0; - - int length = fracDigits; //newFracDigits >> 1; - - int j; - int k; - long carry = 0; - for (j = 1, k = newFracDigits; j <= length; j++, k--) { - long bj = digits[j]; - long bk = digits[k]; - - - long temp = bj + bk; - - sum += temp * temp; - carry += sum >>> SHIFTI; - sum = sum & MASKI; - - //System.out.println("a" + j + " * " + "a " + k); - } - - long bj, bk; - - sum -= PartialSum; - carry -= ((sum & MASK31) >>> SHIFTI) + PartialCarry; - sum = sum & MASKI; - - old_sum = carry + (sum >>> (SHIFTI - 1)); // Roundish - - long temp; - - //long shift = 0; - int m = fracDigits; - for(int i = newFracDigits; i > 0; i--, m--) { - - sum = old_sum; - - length = (i >> 1) - 1; - - carry = 0; - for(j = 0, k = i; j <= length; j++, k--) { - bj = digits[j]; - bk = digits[k]; - - temp = bj + bk; - - sum += temp * temp; - carry += sum >>> SHIFTI; - sum = sum & MASKI; - //System.out.println("a" + j + " * " + "a " + k); - } - - sum += (partials[k] << 1); - carry += sum >>> SHIFTI; - sum = sum & MASKI; - - - sum -= PartialSum; - carry -= ((sum & MASK31) >>> SHIFTI) + PartialCarry; - sum = sum & MASKI; - - long partialI = partials[i]; - PartialSum -= partialI & MASKI; - PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFTI; - PartialSum = PartialSum & MASKI; - - long finalVal = sum; - - i--; //Unrolling - - sum = carry; - - length = i >> 1; - - carry = 0; - for(j = 0, k = i; j <= length; j++, k--) { - bj = digits[j]; - bk = digits[k]; - - temp = bj + bk; - - sum += temp * temp; - carry += sum >>> SHIFTI; - sum = sum & MASKI; - //System.out.println("a" + j + " * " + "a " + k); - } - - sum -= PartialSum; - carry -= ((sum & MASK31) >>> SHIFTI) + PartialCarry; - finalVal |= (sum & MASKI) << SHIFTI; - - partialI = partials[i]; - PartialSum -= partialI & MASKI; - PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFTI; - PartialSum = PartialSum & MASKI; - - - resDigits[m] = finalVal; - old_sum = carry; - - } - - sum = old_sum; - - sum += p0; - - result.sign = 1; - - result.digits[0] = sum; - - return result; - } - - public BigNum64 mult(BigNum64 b) { - if(useKaratsuba) { - return multKaratsuba(b); - } - else { - return multFull(b); - } - } - - public BigNum64 multFull(BigNum64 b) { - - BigNum64 result = new BigNum64(); - - if(sign == 0 || b.sign == 0) { - return result; - } - - long[] resDigits = result.digits; - long[] origDigitsA = this.digits; - long[] origDigitsB = b.digits; - - if(isOne || b.isOne) { - if (isOne && b.isOne) { - resDigits[0] = 1; - result.isOne = true; - result.sign = sign * b.sign; - } - else if(isOne) { - System.arraycopy(origDigitsB, 0, resDigits, 0, origDigitsB.length); - result.sign = sign * b.sign; - } - else { - System.arraycopy(origDigitsA, 0, resDigits, 0, origDigitsA.length); - result.sign = sign * b.sign; - } - return result; - } - - int newFracDigits = fracDigits2; - int newLength = newFracDigits + 1; - int[] digits = new int[newLength]; - int[] bdigits = new int[newLength]; - - long old_sum = 0; - - long sum = 0; - long carry = 0; - digits[0] = (int)origDigitsA[0]; - bdigits[0] = (int)origDigitsB[0]; - - for (int j = 1, base = (j << 1) - 1, k = fracDigits, base2 = (k << 1); j <= fracDigits; j++, k--) { - - long bdigit = origDigitsB[j]; - long adigit = origDigitsA[k]; - - long bjlo = bdigit & MASKI; - long aklo = adigit & MASKI; - - long bjhi = bdigit >>> SHIFTI; - long akhi = adigit >>> SHIFTI; - - digits[base2] = (int)(aklo); - bdigits[base] = (int)(bjhi); - base++; - base2--; - digits[base2] = (int)(akhi); - bdigits[base] = (int)(bjlo); - base++; - base2--; - - sum += bjlo * akhi; - carry += sum >>> SHIFTI; - sum = sum & MASKI; - - sum += bjhi * aklo; - carry += sum >>> SHIFTI; - sum = sum & MASKI; - - } - - old_sum = carry + (sum >>> (SHIFTI - 1)); // Roundish - - long isNonZero = 0; - for(int i = newFracDigits, m = fracDigits; i > 0; i--, m--) { - - sum = old_sum; //carry from prev - carry = 0; - for(int j = 0, k = i; j <= i; j++, k--) { - long bj = bdigits[j]; - long ak = digits[k]; - - sum += bj * ak; - carry += sum >>> SHIFTI; - sum = sum & MASKI; - - } - - long finalVal = sum; - - i--;//Unrolling - - sum = carry; //carry from prev - carry = 0; - for(int j = 0, k = i; j <= i; j++, k--) { - long bj = bdigits[j]; - long ak = digits[k]; - - sum += bj * ak; - carry += sum >>> SHIFTI; - sum = sum & MASKI; - - } - - finalVal |= sum << SHIFTI; - resDigits[m] = finalVal; - - isNonZero |= finalVal; - old_sum = carry; - } - - sum = old_sum; - - long bj = bdigits[0]; - long ak = digits[0]; - - sum += bj * ak; - - long d0 = sum; - result.digits[0] = sum; - result.isOne = d0 == 1 && isNonZero == 0; - result.sign = sign * b.sign; - - return result; - - } - - public BigNum64 multKaratsuba(BigNum64 b) { - - BigNum64 result = new BigNum64(); - - if(sign == 0 || b.sign == 0) { - return result; - } - - long[] resDigits = result.digits; - long[] origDigitsA = this.digits; - long[] origDigitsB = b.digits; - - if(isOne || b.isOne) { - if (isOne && b.isOne) { - resDigits[0] = 1; - result.isOne = true; - result.sign = sign * b.sign; - } - else if(isOne) { - System.arraycopy(origDigitsB, 0, resDigits, 0, origDigitsB.length); - result.sign = sign * b.sign; - } - else { - System.arraycopy(origDigitsA, 0, resDigits, 0, origDigitsA.length); - result.sign = sign * b.sign; - } - return result; - } - - int newFracDigits = fracDigits2; - int newLength = newFracDigits + 1; - int[] digits = new int[newLength]; - int[] bdigits = new int[newLength]; - - long[] partials = new long[newLength]; - - - long PartialSum = 0; - long PartialCarry = 0; - - long adigit = (int)origDigitsA[0]; - long bdigit = (int)origDigitsB[0]; - digits[0] = (int)adigit; - bdigits[0] = (int)bdigit; - - long p = adigit * bdigit; - long p0 = p; - partials[0] = p; - PartialSum += p; - - PartialCarry += PartialSum >>> SHIFTI; - PartialSum = PartialSum & MASKI; - - for(int i = 1, base = (i << 1) - 1; i <=fracDigits; i++) { - - bdigit = origDigitsB[i]; - adigit = origDigitsA[i]; - - long bjlo = bdigit & MASKI; - long aklo = adigit & MASKI; - - long bjhi = bdigit >>> SHIFTI; - long akhi = adigit >>> SHIFTI; - - digits[base] = (int)(akhi); - bdigits[base] = (int)(bjhi); - p = akhi * bjhi; - partials[base] = p; - PartialSum += p; - PartialCarry += PartialSum >>> SHIFTI; - PartialSum = PartialSum & MASKI; - - base++; - digits[base] = (int)(aklo); - bdigits[base] = (int)(bjlo); - p = aklo * bjlo; - partials[base] = p; - PartialSum += p; - - PartialCarry += PartialSum >>> SHIFTI; - PartialSum = PartialSum & MASKI; - base++; - - - } - - long old_sum = 0; - - long sum = p0; - - int length = fracDigits;//newFracDigits >> 1; - - int j; - int k; - long carry = 0; - for (j = 1, k = newFracDigits; j <= length; j++, k--) { - long bj = bdigits[j]; - long bk = bdigits[k]; - long aj = digits[j]; - long ak = digits[k]; - - sum += (bk + bj) * (ak + aj); - carry += sum >>> SHIFTI; - sum = sum & MASKI; - - //System.out.println("partials " + k + " partials " + j); - - } - - long bj, bk, aj, ak; - - sum -= PartialSum; - carry -= ((sum & MASK31) >>> SHIFTI) + PartialCarry; - sum = sum & MASKI; - - old_sum = carry + (sum >>> (SHIFTI - 1)); // Roundish - - - long isNonZero = 0; - int m = fracDigits; - for(int i = newFracDigits; i > 0; i--, m--) { - - length = (i >> 1) - 1; - - sum = old_sum; //carry from prev - - carry = 0; - for(j = 0, k = i; j <= length; j++, k--) { - bj = bdigits[j]; - bk = bdigits[k]; - aj = digits[j]; - ak = digits[k]; - - sum += (bk + bj) * (ak + aj); - - carry += sum >>> SHIFTI; - sum = sum & MASKI; - //System.out.println("b " + k + " + b " + j + " * a " + k + " + a " + j); - //System.out.println("partials " + k + " partials " + j); - - } - - // System.out.println("partials " + k); - //System.out.println("NEXT"); - sum += partials[k] << 1; - - carry += sum >>> SHIFTI; - sum = sum & MASKI; - - sum -= PartialSum; - carry -= ((sum & MASK31) >>> SHIFTI) + PartialCarry; - sum = sum & MASKI; - - long partialI = partials[i]; - PartialSum -= partialI & MASKI; - PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFTI; - //PartialCarry -= ((PartialSum & MASK31) >>> SHIFTI); - PartialSum = PartialSum & MASKI; - //PartialCarry -= partialI >>> SHIFTI; - - long finalVal = sum; - - i--;//Unrolling - - length = i >> 1; - - sum = carry; - - carry = 0; - for(j = 0, k = i; j <= length; j++, k--) { - bj = bdigits[j]; - bk = bdigits[k]; - aj = digits[j]; - ak = digits[k]; - - sum += (bk + bj) * (ak + aj); - - carry += sum >>> SHIFTI; - sum = sum & MASKI; - - //System.out.println("b " + k + " + b " + j + " * a " + k + " + a " + j); - } - - sum -= PartialSum; - carry -= ((sum & MASK31) >>> SHIFTI) + PartialCarry; - finalVal |= (sum & MASKI) << SHIFTI; - - partialI = partials[i]; - PartialSum -= partialI & MASKI; - PartialCarry -= ((PartialSum & MASK31) + partialI) >>> SHIFTI; - //PartialCarry -= ((PartialSum & MASK31) >>> SHIFTI); - PartialSum = PartialSum & MASKI; - //PartialCarry -= partialI >>> SHIFTI; - - isNonZero |= finalVal; - resDigits[m] = finalVal; - old_sum = carry; - } - - sum = old_sum; - - sum += p0; - - long d0 = sum; - result.digits[0] = sum; - result.isOne = d0 == 1 && isNonZero == 0; - result.sign = sign * b.sign; - - return result; - - } - - public BigNum64 mult2() { - - BigNum64 res = new BigNum64(); - - if(sign == 0) { - return res; - } - - long [] resDigits = res.digits; - - if(isOne) { - resDigits[0] = 2; - res.sign = sign; - return res; - } - - long isNonZero = 0; - - long temp = (digits[fracDigits] << 1); - long val = temp & MASK; - resDigits[fracDigits] = val; - isNonZero |= val; - - for(int i=fracDigits - 1; i > 0; i--) { - temp = (digits[i] << 1) | ((temp >>> (SHIFT))); - val = temp & MASK; - isNonZero |= val; - resDigits[i] = val; - } - - temp = ((digits[0]) << 1) | ((temp >>> (SHIFT))); - resDigits[0] = temp; - res.sign = sign; - res.isOne = temp == 1 && isNonZero == 0; - return res; - - } - - public BigNum64 mult4() { - - BigNum64 res = new BigNum64(); - - if(sign == 0) { - return res; - } - - long [] resDigits = res.digits; - - if(isOne) { - resDigits[0] = 4; - res.sign = sign; - return res; - } - - long isNonZero = 0; - - long temp = (digits[fracDigits] << 2); - long val = temp & MASK; - resDigits[fracDigits] = val; - isNonZero |= val; - - for(int i=fracDigits - 1; i > 0; i--) { - temp = (digits[i] << 2) | ((temp >>> (SHIFT))); - val = temp & MASK; - isNonZero |= val; - resDigits[i] = val; - } - - temp = ((digits[0]) << 2) | ((temp >>> (SHIFT))); - resDigits[0] = temp; - res.sign = sign; - res.isOne = temp == 1 && isNonZero == 0; - return res; - - } - - public BigNum64 divide2() { - - BigNum64 res = new BigNum64(); - - if(sign == 0) { - return res; - } - - long [] resDigits = res.digits; - - if(isOne) { - resDigits[1] = 0x800000000000000L; - res.sign = sign; - return res; - } - - int isNonZero = 0; - - long temp = digits[0]; - long val = temp >>> 1; - - long bit = temp & 0x1; - - resDigits[0] = val; - isNonZero |= val; - - for(int i=1; i < fracDigits; i++) { - temp = digits[i]; - temp |= (bit << SHIFT); - bit = temp & 0x1; - temp = temp >>> 1; - val = temp & MASK; - resDigits[i] = val; - isNonZero |= val; - } - - temp = digits[fracDigits]; - temp |= (bit << SHIFT); - temp = temp >>> 1; - resDigits[fracDigits] = temp & MASK; - res.sign = sign; - res.isOne = temp == 1 && isNonZero == 0; - return res; - - } - - public BigNum64 divide4() { - - BigNum64 res = new BigNum64(); - - if(sign == 0) { - return res; - } - - long [] resDigits = res.digits; - - if(isOne) { - resDigits[1] = 0x400000000000000L; - res.sign = sign; - return res; - } - - int isNonZero = 0; - - - long temp = digits[0]; - long val = temp >>> 2; - - long bits = temp & 0x3; - - resDigits[0] = val; - isNonZero |= val; - - for(int i=1; i < fracDigits; i++) { - temp = digits[i]; - temp |= (bits << SHIFT); - bits = temp & 0x3; - temp = temp >>> 2; - val = temp & MASK; - resDigits[i] = val; - isNonZero |= val; - } - - temp = digits[fracDigits]; - temp |= (bits << SHIFT); - temp = temp >>> 2; - resDigits[fracDigits] = temp & MASK; - res.sign = sign; - res.isOne = temp == 1 && isNonZero == 0; - return res; - - } - - public boolean isPositive() { - //return digits[0] > 0; - return sign == 1; - } - public boolean isZero() { - return sign == 0; - } - public boolean isNegative() { - return sign == -1; - //return digits[0] < 0; - } - - public MantExp getMantExp() { - - if (sign == 0) { - return new MantExp(); - } - - if(isOne) { - return new MantExp(sign); - } - - long[] digits = this.digits; - - if(offset == -1) { - int i; - long digit = 0; - for (i = 0; i < digits.length; i++) { - digit = digits[i]; - if (digit != 0) { - break; - } - } - - if (i == digits.length) { - return new MantExp(); - } - - /*int r; - for(r = i == 0 ? SHIFT : SHIFTM1; r >= 0; r--) { - if(digits[i] >>> r != 0) { - break; - } - }*/ - - offset = i; - long v = digit; - double d = v & ~(v >>> 1); - //int r = (int)(((Double.doubleToRawLongBits(d) >> 52) & 0x7ff) - 1023); //Fix for the 64 bit, not needed here - bitOffset = (int) (((Double.doubleToRawLongBits(d) >> 52)) - 1023); - //r |= (r >> 31); //Fix for zero, not needed here - - scale = digits[0] != 0 ? ((long) i) * SHIFT + bitOffset : -(((long) i) * SHIFT) + bitOffset; - } - - long mantissa = 0; - - int temp = 52 - bitOffset; - int i = offset; - - long val = digits[i]; - if(temp >= 0) { - mantissa |= val << temp; - mantissa = mantissa & 0xFFFFFFFFFFFFFL; - if(temp == 0 && i + 1 < digits.length) { - mantissa += (digits[i + 1] >>> (SHIFTM1)) & 0x1; - } - } - else { - int shift = -temp; - mantissa |= val >>> shift; - mantissa = mantissa & 0xFFFFFFFFFFFFFL; - mantissa += (val >>> (shift - 1)) & 0x1; - } - - //System.out.println(digits[i]); - - i++; - - int k; - for(k = bitOffset ; k < 52 && i < digits.length; k+=SHIFT, i++) { - val = digits[i]; - temp = 52 - k; - - if(temp > SHIFT) { - mantissa |= val << (temp - SHIFT); - mantissa = mantissa & 0xFFFFFFFFFFFFFL; - } - else { - long temp2 = k + SHIFTM52; - mantissa |= val >>> temp2; - mantissa = mantissa & 0xFFFFFFFFFFFFFL; - - if(temp2 == 0 && i + 1 < digits.length) { - mantissa += (digits[i + 1] >>> (SHIFTM1)) & 0x1; - } - else { - mantissa += (val >>> (temp2 - 1)) & 0x1; - } - } - } - - // Bit 63 (the bit that is selected by the mask 0x8000000000000000L) represents the sign of the floating-point number. - // Bits 62-52 (the bits that are selected by the mask 0x7ff0000000000000L) represent the exponent. - // Bits 51-0 (the bits that are selected by the mask 0x000fffffffffffffL) represent the significand (sometimes called the mantissa) of the floating-point number. - - long exp = scale + (mantissa >>> 52); - double mantissaDouble; - - if(sign == -1) { - mantissaDouble = Double.longBitsToDouble( (0x8000000000000000L) | (mantissa & 0xFFFFFFFFFFFFFL) | (0x3FF0000000000000L)); - } - else { - mantissaDouble = Double.longBitsToDouble((mantissa & 0xFFFFFFFFFFFFFL) | (0x3FF0000000000000L)); - } - - return new MantExp(exp, mantissaDouble); - - - - } - - public static BigNum64 max(BigNum64 a, BigNum64 b) { - return a.compare(b) > 0 ? a : b; - } - - public static BigNum64 min(BigNum64 a, BigNum64 b) { - return a.compare(b) < 0 ? a : b; - } -} diff --git a/src/fractalzoomer/core/unused/MantExpSoft.java b/src/fractalzoomer/core/unused/MantExpSoft.java index 234a89cee..6daa78410 100644 --- a/src/fractalzoomer/core/unused/MantExpSoft.java +++ b/src/fractalzoomer/core/unused/MantExpSoft.java @@ -80,10 +80,14 @@ public MantExpSoft multiply(MantExpSoft factor) { long mantissa = ((long)this.mantissa) * ((long)factor.mantissa) >>> MANTISSA_BITS; long exp = this.exp + factor.exp; - if((mantissa & 0x40000000L) == 0) { + if(mantissa < 0x40000000L) { mantissa = mantissa << 1; exp--; } + else if (mantissa > 0x7FFFFFFFL) { + mantissa = mantissa >>> 1; + exp++; + } MantExpSoft res = new MantExpSoft((int)mantissa, exp, this.sign ^ factor.sign); diff --git a/src/fractalzoomer/fractal_options/PlanePointOption.java b/src/fractalzoomer/fractal_options/PlanePointOption.java index c938e8a2d..438ea9426 100644 --- a/src/fractalzoomer/fractal_options/PlanePointOption.java +++ b/src/fractalzoomer/fractal_options/PlanePointOption.java @@ -17,6 +17,7 @@ package fractalzoomer.fractal_options; import fractalzoomer.core.Complex; +import fractalzoomer.core.MantExpComplex; /** * @@ -29,6 +30,7 @@ protected PlanePointOption() { } public abstract Complex getValue(Complex pixel); + public abstract MantExpComplex getValueDeep(MantExpComplex pixel); public boolean isStatic() {return false;} diff --git a/src/fractalzoomer/fractal_options/initial_value/DefaultInitialValue.java b/src/fractalzoomer/fractal_options/initial_value/DefaultInitialValue.java index cfd71f82c..b21d85b21 100644 --- a/src/fractalzoomer/fractal_options/initial_value/DefaultInitialValue.java +++ b/src/fractalzoomer/fractal_options/initial_value/DefaultInitialValue.java @@ -18,6 +18,7 @@ package fractalzoomer.fractal_options.initial_value; import fractalzoomer.core.Complex; +import fractalzoomer.core.MantExpComplex; import fractalzoomer.fractal_options.PlanePointOption; /** @@ -39,6 +40,11 @@ public Complex getValue(Complex pixel) { return pixel; } + + @Override + public MantExpComplex getValueDeep(MantExpComplex pixel) { + return pixel; + } @Override public String toString() { diff --git a/src/fractalzoomer/fractal_options/initial_value/DefaultInitialValueWithFactor.java b/src/fractalzoomer/fractal_options/initial_value/DefaultInitialValueWithFactor.java index 357883c0d..8dbf8662d 100644 --- a/src/fractalzoomer/fractal_options/initial_value/DefaultInitialValueWithFactor.java +++ b/src/fractalzoomer/fractal_options/initial_value/DefaultInitialValueWithFactor.java @@ -1,6 +1,7 @@ package fractalzoomer.fractal_options.initial_value; import fractalzoomer.core.Complex; +import fractalzoomer.core.MantExpComplex; import fractalzoomer.fractal_options.PlanePointOption; public class DefaultInitialValueWithFactor extends PlanePointOption { @@ -21,6 +22,11 @@ public Complex getValue(Complex pixel) { } + @Override + public MantExpComplex getValueDeep(MantExpComplex pixel) { + return pixel.times(factor); + } + @Override public String toString() { diff --git a/src/fractalzoomer/fractal_options/initial_value/InitialValue.java b/src/fractalzoomer/fractal_options/initial_value/InitialValue.java index e980fbccd..ae63e28e6 100644 --- a/src/fractalzoomer/fractal_options/initial_value/InitialValue.java +++ b/src/fractalzoomer/fractal_options/initial_value/InitialValue.java @@ -17,6 +17,7 @@ package fractalzoomer.fractal_options.initial_value; import fractalzoomer.core.Complex; +import fractalzoomer.core.MantExpComplex; import fractalzoomer.fractal_options.PlanePointOption; /** @@ -47,6 +48,11 @@ public Complex getValue(Complex pixel) { return this.pixel; } + + @Override + public MantExpComplex getValueDeep(MantExpComplex pixel) { + return MantExpComplex.create(this.pixel); + } @Override public String toString() { diff --git a/src/fractalzoomer/fractal_options/initial_value/VariableConditionalInitialValue.java b/src/fractalzoomer/fractal_options/initial_value/VariableConditionalInitialValue.java index f51038f90..881cc26b8 100644 --- a/src/fractalzoomer/fractal_options/initial_value/VariableConditionalInitialValue.java +++ b/src/fractalzoomer/fractal_options/initial_value/VariableConditionalInitialValue.java @@ -17,6 +17,7 @@ package fractalzoomer.fractal_options.initial_value; import fractalzoomer.core.Complex; +import fractalzoomer.core.MantExpComplex; import fractalzoomer.core.TaskDraw; import fractalzoomer.fractal_options.PlanePointOption; import fractalzoomer.parser.ExpressionNode; @@ -232,6 +233,11 @@ public Complex getValue(Complex pixel) { } + @Override + public MantExpComplex getValueDeep(MantExpComplex pixel) { + return MantExpComplex.create(getValue(pixel.toComplex())); + } + @Override public String toString() { diff --git a/src/fractalzoomer/fractal_options/initial_value/VariableInitialValue.java b/src/fractalzoomer/fractal_options/initial_value/VariableInitialValue.java index cf10b6308..635b60bdc 100644 --- a/src/fractalzoomer/fractal_options/initial_value/VariableInitialValue.java +++ b/src/fractalzoomer/fractal_options/initial_value/VariableInitialValue.java @@ -17,6 +17,7 @@ package fractalzoomer.fractal_options.initial_value; import fractalzoomer.core.Complex; +import fractalzoomer.core.MantExpComplex; import fractalzoomer.core.TaskDraw; import fractalzoomer.fractal_options.PlanePointOption; import fractalzoomer.parser.ExpressionNode; @@ -80,6 +81,11 @@ public Complex getValue(Complex pixel) { } + @Override + public MantExpComplex getValueDeep(MantExpComplex pixel) { + return MantExpComplex.create(getValue(pixel.toComplex())); + } + @Override public String toString() { diff --git a/src/fractalzoomer/fractal_options/perturbation/DefaultPerturbation.java b/src/fractalzoomer/fractal_options/perturbation/DefaultPerturbation.java index f7c27b32d..3edcdd092 100644 --- a/src/fractalzoomer/fractal_options/perturbation/DefaultPerturbation.java +++ b/src/fractalzoomer/fractal_options/perturbation/DefaultPerturbation.java @@ -18,6 +18,7 @@ package fractalzoomer.fractal_options.perturbation; import fractalzoomer.core.Complex; +import fractalzoomer.core.MantExpComplex; import fractalzoomer.fractal_options.PlanePointOption; @@ -40,5 +41,10 @@ public Complex getValue(Complex pixel) { return pixel; } + + @Override + public MantExpComplex getValueDeep(MantExpComplex pixel) { + return pixel; + } } diff --git a/src/fractalzoomer/fractal_options/perturbation/Perturbation.java b/src/fractalzoomer/fractal_options/perturbation/Perturbation.java index e8f17b6e4..1ea8acd3c 100644 --- a/src/fractalzoomer/fractal_options/perturbation/Perturbation.java +++ b/src/fractalzoomer/fractal_options/perturbation/Perturbation.java @@ -18,6 +18,7 @@ package fractalzoomer.fractal_options.perturbation; import fractalzoomer.core.Complex; +import fractalzoomer.core.MantExpComplex; import fractalzoomer.fractal_options.PlanePointOption; @@ -42,5 +43,10 @@ public Complex getValue(Complex pixel) { return this.pixel.plus(pixel); } + + @Override + public MantExpComplex getValueDeep(MantExpComplex pixel) { + return MantExpComplex.create(this.pixel).plus(pixel); + } } diff --git a/src/fractalzoomer/fractal_options/perturbation/VariableConditionalPerturbation.java b/src/fractalzoomer/fractal_options/perturbation/VariableConditionalPerturbation.java index 6785776c8..eee0cf014 100644 --- a/src/fractalzoomer/fractal_options/perturbation/VariableConditionalPerturbation.java +++ b/src/fractalzoomer/fractal_options/perturbation/VariableConditionalPerturbation.java @@ -17,6 +17,7 @@ package fractalzoomer.fractal_options.perturbation; import fractalzoomer.core.Complex; +import fractalzoomer.core.MantExpComplex; import fractalzoomer.core.TaskDraw; import fractalzoomer.fractal_options.PlanePointOption; import fractalzoomer.parser.ExpressionNode; @@ -232,5 +233,10 @@ else if (result == 0) { //left == right return pixel; } + + @Override + public MantExpComplex getValueDeep(MantExpComplex pixel) { + return MantExpComplex.create(getValue(pixel.toComplex())); + } } diff --git a/src/fractalzoomer/fractal_options/perturbation/VariablePerturbation.java b/src/fractalzoomer/fractal_options/perturbation/VariablePerturbation.java index ec3129d77..e60a2fa6e 100644 --- a/src/fractalzoomer/fractal_options/perturbation/VariablePerturbation.java +++ b/src/fractalzoomer/fractal_options/perturbation/VariablePerturbation.java @@ -18,6 +18,7 @@ package fractalzoomer.fractal_options.perturbation; import fractalzoomer.core.Complex; +import fractalzoomer.core.MantExpComplex; import fractalzoomer.core.TaskDraw; import fractalzoomer.fractal_options.PlanePointOption; import fractalzoomer.parser.ExpressionNode; @@ -80,5 +81,10 @@ public Complex getValue(Complex pixel) { return pixel.plus(expr.getValue()); } + + @Override + public MantExpComplex getValueDeep(MantExpComplex pixel) { + return MantExpComplex.create(getValue(pixel.toComplex())); + } } diff --git a/src/fractalzoomer/functions/EscapingOrConverging.java b/src/fractalzoomer/functions/EscapingOrConverging.java index 9924a94f5..3c0ac8611 100644 --- a/src/fractalzoomer/functions/EscapingOrConverging.java +++ b/src/fractalzoomer/functions/EscapingOrConverging.java @@ -1,6 +1,7 @@ package fractalzoomer.functions; import fractalzoomer.core.Complex; +import fractalzoomer.core.TaskDraw; import fractalzoomer.fractal_options.iteration_statistics.*; import fractalzoomer.main.MainWindow; import fractalzoomer.main.app_settings.OrbitTrapSettings; @@ -22,15 +23,18 @@ public EscapingOrConverging() { public EscapingOrConverging(double xCenter, double yCenter, double size, int max_iterations, int bailout_test_algorithm, double bailout, String bailout_test_user_formula, String bailout_test_user_formula2, int bailout_test_comparison, double n_norm, boolean periodicity_checking, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, OrbitTrapSettings ots) { super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); + setConvergentBailout(1E-11); + } - convergent_bailout = 1E-11; + protected void setConvergentBailout(double val) { + convergent_bailout = TaskDraw.USER_CONVERGENT_BAILOUT > 0 ? TaskDraw.USER_CONVERGENT_BAILOUT : val; } public EscapingOrConverging(double xCenter, double yCenter, double size, int max_iterations, int bailout_test_algorithm, double bailout, String bailout_test_user_formula, String bailout_test_user_formula2, int bailout_test_comparison, double n_norm, boolean periodicity_checking, int plane_type, boolean apply_plane_on_julia, boolean apply_plane_on_julia_seed, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, OrbitTrapSettings ots, double xJuliaCenter, double yJuliaCenter) { super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, xJuliaCenter, yJuliaCenter); - convergent_bailout = 1E-11; + setConvergentBailout(1E-11); } //orbit diff --git a/src/fractalzoomer/functions/ExtendedConvergentType.java b/src/fractalzoomer/functions/ExtendedConvergentType.java index beadaf6c2..91e0b1cd8 100644 --- a/src/fractalzoomer/functions/ExtendedConvergentType.java +++ b/src/fractalzoomer/functions/ExtendedConvergentType.java @@ -45,15 +45,19 @@ public ExtendedConvergentType(double xCenter, double yCenter, double size, int m super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, false, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - convergent_bailout = 1E-10; + setConvergentBailout(1E-10); } + + protected void setConvergentBailout(double val) { + convergent_bailout = TaskDraw.USER_CONVERGENT_BAILOUT > 0 ? TaskDraw.USER_CONVERGENT_BAILOUT : val; + } public ExtendedConvergentType(double xCenter, double yCenter, double size, int max_iterations, int bailout_test_algorithm, double bailout, String bailout_test_user_formula, String bailout_test_user_formula2, int bailout_test_comparison, double n_norm, boolean periodicity_checking, int plane_type, boolean apply_plane_on_julia, boolean apply_plane_on_julia_seed, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, OrbitTrapSettings ots, double xJuliaCenter, double yJuliaCenter) { super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, false, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, xJuliaCenter, yJuliaCenter); - convergent_bailout = 1E-10; + setConvergentBailout(1E-10); } @@ -345,7 +349,7 @@ public double iterateFractalArbitraryPrecision(GenericComplex[] complex, Generic setTrueColorOut(z, zold, zold2, iterations, c, start, c0, pixelC); } - return out; + return getAndAccumulateHP(out); } gzold2.set(gzold); @@ -373,7 +377,7 @@ public double iterateFractalArbitraryPrecision(GenericComplex[] complex, Generic setTrueColorIn(z, zold, zold2, iterations, c, start, c0, pixelC); } - return in; + return getAndAccumulateHP(in); } @@ -492,7 +496,7 @@ public double iterateFractalWithPerturbation(Complex[] complex, MantExpComplex d int MaxRefIteration = getReferenceFinalIterationNumber(true, referenceData); int minExp = -1000; - int reducedExp = minExp / (int)power; + int reducedExp = minExp / (int)getPower(); DeltaSubN.Normalize(); long exp = DeltaSubN.getMinExp(); @@ -502,18 +506,25 @@ public double iterateFractalWithPerturbation(Complex[] complex, MantExpComplex d boolean useFullFloatExp = useFullFloatExp(); boolean doBailCheck = useFullFloatExp || TaskDraw.CHECK_BAILOUT_DURING_DEEP_NOT_FULL_FLOATEXP_MODE; + MantExpComplex refZm; + boolean usedDeepCode = false; if(useFullFloatExp || (totalSkippedIterations == 0 && exp <= minExp) || (totalSkippedIterations != 0 && exp <= reducedExp)) { usedDeepCode = true; + MantExpComplex zWithoutInitVal = MantExpComplex.create(); MantExpComplex z = MantExpComplex.create(); if(iterations != 0 && RefIteration < MaxRefIteration) { - z = getArrayDeepValue(referenceDeepData.ReferenceSubCp, RefIteration).plus_mutable(DeltaSubN); - complex[0] = getArrayDeepValue(referenceDeep, RefIteration).plus_mutable(DeltaSubN).toComplex(); + refZm = getArrayDeepValue(referenceDeep, RefIteration); + zWithoutInitVal = getArrayDeepValue(referenceDeepData.ReferenceSubCp, RefIteration, refZm).plus_mutable(DeltaSubN); + z = refZm.plus_mutable(DeltaSubN); + complex[0] = z.toComplex(); } else if(iterations != 0 && ReferencePeriod != 0) { RefIteration = RefIteration % ReferencePeriod; - z = getArrayDeepValue(referenceDeepData.ReferenceSubCp, RefIteration).plus_mutable(DeltaSubN); - complex[0] = getArrayDeepValue(referenceDeep, RefIteration).plus_mutable(DeltaSubN).toComplex(); + refZm = getArrayDeepValue(referenceDeep, RefIteration); + zWithoutInitVal = getArrayDeepValue(referenceDeepData.ReferenceSubCp, RefIteration, refZm).plus_mutable(DeltaSubN); + z = refZm.plus_mutable(DeltaSubN); + complex[0] = z.toComplex(); } MantExpComplex zoldDeep; @@ -549,16 +560,18 @@ else if(iterations != 0 && ReferencePeriod != 0) { zoldDeep = z; if (max_iterations > 1) { - z = getArrayDeepValue(referenceDeepData.ReferenceSubCp, RefIteration).plus_mutable(DeltaSubN); - complex[0] = getArrayDeepValue(referenceDeep, RefIteration).plus_mutable(DeltaSubN).toComplex(); + refZm = getArrayDeepValue(referenceDeep, RefIteration); + zWithoutInitVal = getArrayDeepValue(referenceDeepData.ReferenceSubCp, RefIteration, refZm).plus_mutable(DeltaSubN); + z = refZm.plus_mutable(DeltaSubN); + complex[0] = z.toComplex(); } if (statistic != null) { statistic.insert(complex[0], zold, zold2, iterations, complex[1], start, c0, z, zoldDeep, null); } - if (z.norm_squared().compareToBothPositive(DeltaSubN.norm_squared()) < 0 || RefIteration >= MaxRefIteration) { - DeltaSubN = z; + if (zWithoutInitVal.norm_squared().compareToBothPositive(DeltaSubN.norm_squared()) < 0 || RefIteration >= MaxRefIteration) { + DeltaSubN = zWithoutInitVal; RefIteration = 0; rebases++; } @@ -580,15 +593,18 @@ else if(iterations != 0 && ReferencePeriod != 0) { Complex CDeltaSubN = DeltaSubN.toComplex(); Complex CDeltaSub0 = DeltaSub0.toComplex(); + Complex refZ; if(!usedDeepCode && iterations != 0 && RefIteration < MaxRefIteration) { - zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration).plus_mutable(CDeltaSubN); - complex[0] = getArrayValue(reference, RefIteration).plus_mutable(CDeltaSubN); + refZ = getArrayValue(reference, RefIteration); + zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration, refZ).plus_mutable(CDeltaSubN); + complex[0] = refZ.plus_mutable(CDeltaSubN); } else if(!usedDeepCode && iterations != 0 && ReferencePeriod != 0) { RefIteration = RefIteration % ReferencePeriod; - zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration).plus_mutable(CDeltaSubN); - complex[0] = getArrayValue(reference, RefIteration).plus_mutable(CDeltaSubN); + refZ = getArrayValue(reference, RefIteration); + zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration, refZ).plus_mutable(CDeltaSubN); + complex[0] = refZ.plus_mutable(CDeltaSubN); } boolean isZero = CDeltaSub0.isZero(); @@ -632,8 +648,9 @@ else if(!usedDeepCode && iterations != 0 && ReferencePeriod != 0) { //No Plane influence work //No Pre filters work if (max_iterations > 1) { - zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration).plus_mutable(CDeltaSubN); - complex[0] = getArrayValue(reference, RefIteration).plus_mutable(CDeltaSubN); + refZ = getArrayValue(reference, RefIteration); + zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration, refZ).plus_mutable(CDeltaSubN); + complex[0] = refZ.plus_mutable(CDeltaSubN); } //No Post filters work @@ -689,14 +706,18 @@ public double iterateFractalWithPerturbation(Complex[] complex, Complex dpixel) Complex pixel = dpixel.plus(refPointSmall); + Complex refZ; + if(iterations != 0 && RefIteration < MaxRefIteration) { - complex[0] = getArrayValue(reference, RefIteration).plus_mutable(DeltaSubN); - zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration).plus_mutable(DeltaSubN); + refZ = getArrayValue(reference, RefIteration); + zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration, refZ).plus_mutable(DeltaSubN); + complex[0] = refZ.plus_mutable(DeltaSubN); } else if(iterations != 0 && ReferencePeriod != 0) { RefIteration = RefIteration % ReferencePeriod; - complex[0] = getArrayValue(reference, RefIteration).plus_mutable(DeltaSubN); - zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration).plus_mutable(DeltaSubN); + refZ = getArrayValue(reference, RefIteration); + zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration, refZ).plus_mutable(DeltaSubN); + complex[0] = refZ.plus_mutable(DeltaSubN); } for (; iterations < max_iterations; iterations++) { @@ -734,8 +755,9 @@ else if(iterations != 0 && ReferencePeriod != 0) { //No Plane influence work //No Pre filters work if(max_iterations > 1){ - zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration).plus_mutable(DeltaSubN); - complex[0] = getArrayValue(reference, RefIteration).plus_mutable(DeltaSubN); + refZ = getArrayValue(reference, RefIteration); + zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration, refZ).plus_mutable(DeltaSubN); + complex[0] = refZ.plus_mutable(DeltaSubN); } //No Post filters work @@ -786,6 +808,8 @@ public double iterateJuliaWithPerturbation(Complex[] complex, Complex dpixel) { ReferenceData data = referenceData; int MaxRefIteration = data.MaxRefIteration; + Complex refZ; + for (; iterations < max_iterations; iterations++) { //No update values @@ -821,8 +845,9 @@ public double iterateJuliaWithPerturbation(Complex[] complex, Complex dpixel) { //No Plane influence work //No Pre filters work if(max_iterations > 1){ - zWithoutInitVal = getArrayValue(data.ReferenceSubCp, RefIteration).plus_mutable(DeltaSubN); - complex[0] = getArrayValue(data.Reference, RefIteration).plus_mutable(DeltaSubN); + refZ = getArrayValue(data.Reference, RefIteration); + zWithoutInitVal = getArrayValue(data.ReferenceSubCp, RefIteration, refZ).plus_mutable(DeltaSubN); + complex[0] = refZ.plus_mutable(DeltaSubN); } //No Post filters work @@ -874,12 +899,10 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi MantExpComplex[] deltas = initializePerturbation(dpixel); MantExpComplex DeltaSubN = deltas[0]; // Delta z - Complex zWithoutInitVal = new Complex(); - Complex pixel = dpixel.plus(refPointSmallDeep).toComplex(); int minExp = -1000; - int reducedExp = minExp / (int)power; + int reducedExp = minExp / (int)getPower(); DeltaSubN.Normalize(); long exp = DeltaSubN.getMinExp(); @@ -891,8 +914,13 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi ReferenceData data = referenceData; int MaxRefIteration = data.MaxRefIteration; + MantExpComplex refZm; + if(useFullFloatExp || (totalSkippedIterations == 0 && exp <= minExp) || (totalSkippedIterations != 0 && exp <= reducedExp)) { - MantExpComplex z = getArrayDeepValue(deepData.ReferenceSubCp, RefIteration).plus_mutable(DeltaSubN); + MantExpComplex zWithoutInitVal = MantExpComplex.create(); + MantExpComplex z = getArrayDeepValue(deepData.Reference, RefIteration).plus_mutable(DeltaSubN); + + MantExpComplex zoldDeep; for (; iterations < max_iterations; iterations++) { if (trap != null) { @@ -922,18 +950,21 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi zold2.assign(zold); zold.assign(complex[0]); + zoldDeep = z; if (max_iterations > 1) { - z = getArrayDeepValue(deepData.ReferenceSubCp, RefIteration).plus_mutable(DeltaSubN); - complex[0] = getArrayDeepValue(deepData.Reference, RefIteration).plus_mutable(DeltaSubN).toComplex(); + refZm = getArrayDeepValue(deepData.Reference, RefIteration); + zWithoutInitVal = getArrayDeepValue(deepData.ReferenceSubCp, RefIteration, refZm).plus_mutable(DeltaSubN); + z = refZm.plus_mutable(DeltaSubN); + complex[0] = z.toComplex(); } if (statistic != null) { - statistic.insert(complex[0], zold, zold2, iterations, complex[1], start, c0); + statistic.insert(complex[0], zold, zold2, iterations, complex[1], start, c0, z, zoldDeep, null); } - if (z.norm_squared().compareToBothPositive(DeltaSubN.norm_squared()) < 0 || RefIteration >= MaxRefIteration) { - DeltaSubN = z; + if (zWithoutInitVal.norm_squared().compareToBothPositive(DeltaSubN.norm_squared()) < 0 || RefIteration >= MaxRefIteration) { + DeltaSubN = zWithoutInitVal; RefIteration = 0; deepData = secondReferenceDeepData; @@ -956,6 +987,8 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi if(!useFullFloatExp) { Complex CDeltaSubN = DeltaSubN.toComplex(); + Complex zWithoutInitVal = new Complex(); + Complex refZ; for (; iterations < max_iterations; iterations++) { @@ -992,8 +1025,9 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi //No Plane influence work //No Pre filters work if (max_iterations > 1) { - zWithoutInitVal = getArrayValue(data.ReferenceSubCp, RefIteration).plus_mutable(CDeltaSubN); - complex[0] = getArrayValue(data.Reference, RefIteration).plus_mutable(CDeltaSubN); + refZ = getArrayValue(data.Reference, RefIteration); + zWithoutInitVal = getArrayValue(data.ReferenceSubCp, RefIteration, refZ).plus_mutable(CDeltaSubN); + complex[0] = refZ.plus_mutable(CDeltaSubN); } //No Post filters work diff --git a/src/fractalzoomer/functions/Fractal.java b/src/fractalzoomer/functions/Fractal.java index 186b2315f..8d7bf1f57 100644 --- a/src/fractalzoomer/functions/Fractal.java +++ b/src/fractalzoomer/functions/Fractal.java @@ -44,6 +44,7 @@ import fractalzoomer.fractal_options.perturbation.VariableConditionalPerturbation; import fractalzoomer.fractal_options.perturbation.VariablePerturbation; import fractalzoomer.fractal_options.plane_influence.*; +import fractalzoomer.functions.root_finding_methods.RootFindingMethods; import fractalzoomer.in_coloring_algorithms.*; import fractalzoomer.main.Constants; import fractalzoomer.main.MainWindow; @@ -74,6 +75,7 @@ import java.util.List; import java.util.concurrent.atomic.LongAccumulator; import java.util.concurrent.atomic.LongAdder; +import java.util.function.Function; import static fractalzoomer.main.Constants.*; @@ -150,6 +152,12 @@ public abstract class Fractal { protected boolean isJulia; protected boolean isJuliaMap = false; protected PlanePointOption defaultInitVal; + protected ReferenceDecompressor[] referenceDecompressor = new ReferenceDecompressor[ReferenceData.REFERENCE_DATA_COUNT]; + protected ReferenceCompressor[] referenceCompressor = new ReferenceCompressor[ReferenceData.REFERENCE_DATA_COUNT]; + protected ReferenceCompressor[] subexpressionsCompressor = new ReferenceCompressor[ReferenceData.REFERENCE_DATA_COUNT * ReferenceData.SUBEXPRESSION_LENGTH]; + protected ReferenceDecompressor[] subexpressionsDecompressor = new ReferenceDecompressor[ReferenceData.REFERENCE_DATA_COUNT * ReferenceData.SUBEXPRESSION_LENGTH]; + + protected static Function[] functions = new Function[ReferenceData.REFERENCE_DATA_COUNT * ReferenceData.SUBEXPRESSION_LENGTH]; protected boolean isOrbit; protected boolean isDomain; protected int userPeriod; @@ -178,6 +186,8 @@ public abstract class Fractal { public static LongAccumulator total_min_iterations; public static LongAccumulator total_max_iterations; + public static LongAccumulator total_max_iterations_ignore_max_iter; + public static LongAdder total_iterations; public static LongAdder total_bla_iterations; @@ -200,10 +210,11 @@ public abstract class Fractal { public static ReferenceDeepData[] secondMultiReferenceDeepData;*/ static { - referenceData = new ReferenceData(); - secondReferenceData = new ReferenceData(); - referenceDeepData = new ReferenceDeepData(); - secondReferenceDeepData = new ReferenceDeepData(); + //If more of these are added, update REFERENCE_DATA_COUNT + referenceData = new ReferenceData(0); + secondReferenceData = new ReferenceData(1); + referenceDeepData = new ReferenceDeepData(2); + secondReferenceDeepData = new ReferenceDeepData(3); /*int max_data = 6; multiReferenceData = new ReferenceData[max_data]; @@ -229,12 +240,13 @@ public abstract class Fractal { public static MantExpComplex Cdeep; public static Complex refPointSmall; public static MantExpComplex refPointSmallDeep; + public static Complex seedSmall; + public static MantExpComplex seedSmallDeep; public static String RefType = ""; public static int SAskippedIterations; protected static final double scaledE = 2.2250738585072014e-308; protected static final int skippedThreshold = 6; - protected double power = 0; protected boolean burning_ship = false; protected static final int max_data = skippedThreshold * 2; public static DeepReference coefficients; @@ -368,6 +380,14 @@ public Complex perturbationFunction(Complex dz, ReferenceData data, int RefItera return new Complex(); } + public Complex perturbationFunction(Complex dz, DoubleReference data, int RefIteration) { + return new Complex(); + } + + public MantExpComplex perturbationFunction(MantExpComplex dz, DeepReference data, int RefIteration) { + return MantExpComplex.create(); + } + public MantExpComplex perturbationFunction(MantExpComplex dz, ReferenceDeepData data, int RefIteration) { return MantExpComplex.create(); } @@ -642,6 +662,14 @@ public boolean supportsPerturbationTheory() { return false; } + public boolean supportsReferenceCompression() { + return false; + } + + public boolean supportsExtendedReferenceCompression() { + return false; + } + public boolean needsSecondReference() { return isJulia; } @@ -946,6 +974,7 @@ public void calculateSeriesWrapper(Apfloat dsize, boolean deepZoom, Location ext progress.setForeground(MainWindow.progress_sa_color); progress.setString(SA_CALCULATION_STR + " " + String.format("%3d", 0) + "%"); } + initializeReferenceDecompressor(); SAOOMDiff = TaskDraw.SERIES_APPROXIMATION_OOM_DIFFERENCE; SAMaxSkip = TaskDraw.SERIES_APPROXIMATION_MAX_SKIP_ITER; calculateSeries(dsize, deepZoom, externalLocation, progress); @@ -970,6 +999,7 @@ public void calculateNanomb1Wrapper(boolean deepZoom, JProgressBar progress) { progress.setForeground(MainWindow.progress_nanomb1_color); progress.setString(NANOMB1_CALCULATION_STR + " " + String.format("%3d", 0) + "%"); } + initializeReferenceDecompressor(); calculateNanomb1(deepZoom, progress); if (progress != null) { progress.setValue(progress.getMaximum()); @@ -987,6 +1017,7 @@ public void calculateBLAWrapper(boolean deepZoom, Location externalLocation, JPr progress.setForeground(MainWindow.progress_bla_color); progress.setString(BLA_CALCULATION_STR + " " + String.format("%3d", 0) + "%"); } + initializeReferenceDecompressor(); BLAbits = TaskDraw.BLA_BITS; BLAStartingLevel = TaskDraw.BLA_STARTING_LEVEL; calculateBLA(deepZoom, externalLocation, progress); @@ -1011,6 +1042,8 @@ public void calculateBLA2Wrapper(boolean deepZoom, Location externalLocation, JP }); } + initializeReferenceDecompressor(); + calculateBLA2(deepZoom, externalLocation, progress); if (progress != null) { @@ -1038,6 +1071,8 @@ public void calculateBLA2ATWrapper(Location externalLocation, JProgressBar progr }); } + initializeReferenceDecompressor(); + calculateBLA2AT(externalLocation, progress); if (progress != null) { @@ -1101,15 +1136,16 @@ public boolean BLA2ParamsDiffer() { return true; } - double[] newParms = new double[8]; + double[] newParms = new double[9]; newParms[0] = LAInfo.DETECTION_METHOD; newParms[1] = LAInfo.Stage0PeriodDetectionThreshold; newParms[2] = LAInfo.PeriodDetectionThreshold; newParms[3] = LAInfo.Stage0PeriodDetectionThreshold2; - newParms[4] = LAInfo.Stage0PeriodDetectionThreshold2; + newParms[4] = LAInfo.PeriodDetectionThreshold2; newParms[5] = LAInfo.LAThresholdScale; newParms[6] = LAInfo.LAThresholdCScale; newParms[7] = LAReference.doubleThresholdLimit.toDouble(); + newParms[8] = LAReference.periodDivisor; for(int i = 0; i < newParms.length; i++) { if(newParms[i] != BLA2UsedParams[i]) { @@ -1130,15 +1166,16 @@ protected void calculateBLA2(boolean deepZoom, Location externalLocation, JProgr BLA2UsedFullFloatExp = useFullFloatExp(); - BLA2UsedParams = new double[8]; + BLA2UsedParams = new double[9]; BLA2UsedParams[0] = LAInfo.DETECTION_METHOD; BLA2UsedParams[1] = LAInfo.Stage0PeriodDetectionThreshold; BLA2UsedParams[2] = LAInfo.PeriodDetectionThreshold; BLA2UsedParams[3] = LAInfo.Stage0PeriodDetectionThreshold2; - BLA2UsedParams[4] = LAInfo.Stage0PeriodDetectionThreshold2; + BLA2UsedParams[4] = LAInfo.PeriodDetectionThreshold2; BLA2UsedParams[5] = LAInfo.LAThresholdScale; BLA2UsedParams[6] = LAInfo.LAThresholdCScale; BLA2UsedParams[7] = LAReference.doubleThresholdLimit.toDouble(); + BLA2UsedParams[8] = LAReference.periodDivisor; laReference.GenerateApproximationData(BLA2Size, referenceData, referenceDeepData, getBLA2Length(), deepZoom, this); @@ -1530,7 +1567,7 @@ protected GenericComplex[] initializeFromNanomb1(GenericComplex dpixel) { protected GenericComplex[] initializeFromSeries(GenericComplex pixel) { - if (power == 0) { + if (getPower() == 0) { return null; } @@ -1617,12 +1654,29 @@ public double getAndAccumulateStatsBLA(double val) { total_rebases.add(rebases); total_max_iterations.accumulate(iterations); total_min_iterations.accumulate(iterations); + total_iterations.add(iterations); + if(iterations < max_iterations) { + total_max_iterations_ignore_max_iter.accumulate(iterations); + } } return val; } + public double getAndAccumulateHP(double val) { + if(TaskDraw.GATHER_HIGHPRECISION_STATISTICS) { + total_max_iterations.accumulate(iterations); + total_min_iterations.accumulate(iterations); + total_iterations.add(iterations); + if(iterations < max_iterations) { + total_max_iterations_ignore_max_iter.accumulate(iterations); + } + } + + return val; + } + public double getAndAccumulateStatsScaled(double val) { @@ -1634,6 +1688,10 @@ public double getAndAccumulateStatsScaled(double val) { total_realigns.add(realigns); total_max_iterations.accumulate(iterations); total_min_iterations.accumulate(iterations); + total_iterations.add(iterations); + if(iterations < max_iterations) { + total_max_iterations_ignore_max_iter.accumulate(iterations); + } } return val; @@ -1648,6 +1706,10 @@ public double getAndAccumulateStatsNotScaled(double val) { total_rebases.add(rebases); total_max_iterations.accumulate(iterations); total_min_iterations.accumulate(iterations); + total_iterations.add(iterations); + if(iterations < max_iterations) { + total_max_iterations_ignore_max_iter.accumulate(iterations); + } } return val; @@ -1661,6 +1723,10 @@ public double getAndAccumulateStatsNotDeep(double val) { total_rebases.add(rebases); total_max_iterations.accumulate(iterations); total_min_iterations.accumulate(iterations); + total_iterations.add(iterations); + if(iterations < max_iterations) { + total_max_iterations_ignore_max_iter.accumulate(iterations); + } } return val; @@ -1844,7 +1910,7 @@ public double iterateFractalWithPerturbationBLA2(Complex[] complex, MantExpCompl precalculatePerturbationData(DeltaSub0); - MantExp DeltaSub0ChebyshevNorm = DeltaSub0.chebychevNorm(); + MantExp DeltaSub0ChebyshevNorm = DeltaSub0.chebyshevNorm(); iterations = BLA2SkippedIterations; bla_iterations = BLA2SkippedIterations; @@ -1896,7 +1962,7 @@ public double iterateFractalWithPerturbationBLA2(Complex[] complex, MantExpCompl while(iterations < max_iterations) { - LAstep las = laReference.getLA(LAIndex, DeltaSubN, RefIteration, iterations, max_iterations); + LAstep las = laReference.getLA(this, LAIndex, DeltaSubN, RefIteration, iterations, max_iterations); if(las.unusable) { RefIteration = las.nextStageLAindex; @@ -1939,7 +2005,7 @@ public double iterateFractalWithPerturbationBLA2(Complex[] complex, MantExpCompl // rebase - if(z.chebychevNorm().compareToBothPositiveReduced(DeltaSubN.chebychevNorm()) < 0|| RefIteration >= MacroItCount) { + if(z.chebyshevNorm().compareToBothPositiveReduced(DeltaSubN.chebyshevNorm()) < 0|| RefIteration >= MacroItCount) { DeltaSubN = z; RefIteration = 0; rebases++; @@ -2046,7 +2112,7 @@ public double iterateFractalWithPerturbationBLA2(Complex[] complex, MantExpCompl while(iterations < max_iterations) { - LAstep las = laReference.getLA(LAIndex, CDeltaSubN, RefIteration, iterations, max_iterations); + LAstep las = laReference.getLA(this, LAIndex, CDeltaSubN, RefIteration, iterations, max_iterations); if(las.unusable) { RefIteration = las.nextStageLAindex; @@ -2083,7 +2149,7 @@ public double iterateFractalWithPerturbationBLA2(Complex[] complex, MantExpCompl // rebase - if(complex[0].chebychevNorm() < CDeltaSubN.chebychevNorm() || RefIteration >= MacroItCount) { + if(complex[0].chebyshevNorm() < CDeltaSubN.chebyshevNorm() || RefIteration >= MacroItCount) { CDeltaSubN = complex[0]; RefIteration = 0; rebases++; @@ -2133,7 +2199,7 @@ public double iterateFractalWithPerturbationBLA2(Complex[] complex, Complex dpix precalculatePerturbationData(DeltaSub0); - double CDeltaSub0ChebyshevNorm = DeltaSub0.chebychevNorm(); + double CDeltaSub0ChebyshevNorm = DeltaSub0.chebyshevNorm(); iterations = BLA2SkippedIterations; bla_iterations = BLA2SkippedIterations; @@ -2171,7 +2237,7 @@ public double iterateFractalWithPerturbationBLA2(Complex[] complex, Complex dpix while(iterations < max_iterations) { - LAstep las = laReference.getLA(LAIndex, DeltaSubN, RefIteration, iterations, max_iterations); + LAstep las = laReference.getLA(this, LAIndex, DeltaSubN, RefIteration, iterations, max_iterations); if(las.unusable) { RefIteration = las.nextStageLAindex; @@ -2203,7 +2269,7 @@ public double iterateFractalWithPerturbationBLA2(Complex[] complex, Complex dpix // rebase - if(complex[0].chebychevNorm() < DeltaSubN.chebychevNorm() || RefIteration >= MacroItCount) { + if(complex[0].chebyshevNorm() < DeltaSubN.chebyshevNorm() || RefIteration >= MacroItCount) { DeltaSubN = complex[0]; RefIteration = 0; rebases++; @@ -2580,6 +2646,7 @@ public double iterateFractalWithPerturbationScaled(Complex[] complex, MantExpCom rebases = 0; realigns = 0; + double power = getPower(); double reAlignThreshold = power == 2 ? 1e100 : Math.exp(Math.log(1e200) / power); MantExpComplex[] deltas = initializePerturbation(dpixel); @@ -2598,7 +2665,7 @@ public double iterateFractalWithPerturbationScaled(Complex[] complex, MantExpCom int MaxRefIteration = getReferenceFinalIterationNumber(true, referenceData); int minExp = -1000; - int reducedExp = minExp / (int) power; + int reducedExp = minExp / (int) getPower(); DeltaSubN.Normalize(); long exp = DeltaSubN.getMinExp(); @@ -3031,7 +3098,7 @@ public double iterateFractalWithPerturbation(Complex[] complex, MantExpComplex d Complex pixel = dpixel.plus(refPointSmallDeep).toComplex(); int minExp = -1000; - int reducedExp = minExp / (int) power; + int reducedExp = minExp / (int) getPower(); DeltaSubN.Normalize(); long exp = DeltaSubN.getMinExp(); @@ -3173,7 +3240,7 @@ public double iterateFractalArbitraryPrecision(GenericComplex[] complex, Generic setTrueColorOut(z, zold, zold2, iterations, c, start, c0, pixelC); } - return out; + return getAndAccumulateHP(out); } gzold2.set(gzold); @@ -3200,7 +3267,7 @@ public double iterateFractalArbitraryPrecision(GenericComplex[] complex, Generic setTrueColorIn(z, zold, zold2, iterations, c, start, c0, pixelC); } - return in; + return getAndAccumulateHP(in); } @@ -3704,7 +3771,7 @@ protected void StatisticFactory(StatisticsSettings sts, double[] plane_transform statistic = new Equicontinuity(sts.statistic_intensity, sts.useSmoothing, sts.useAverage, log_bailout_squared, false, 0, sts.equicontinuityDenominatorFactor, sts.equicontinuityInvertFactor, sts.equicontinuityDelta); return; } else if (sts.statisticGroup == 3) { - statistic = new NormalMap(sts.statistic_intensity, power, sts.normalMapHeight, sts.normalMapAngle, sts.normalMapUseSecondDerivative, sts.normalMapDEfactor, isJulia, sts.normalMapUseDE, sts.normalMapInvertDE, sts.normalMapColoring, sts.useNormalMap, sts.normalMapDEUpperLimitFactor, sts.normalMapDEAAEffect, sts.normalMapOverrideColoring, sts.normalMapDeFadeAlgorithm, sts.normalMapDistanceEstimatorfactor); + statistic = new NormalMap(sts.statistic_intensity, getPower(), sts.normalMapHeight, sts.normalMapAngle, sts.normalMapUseSecondDerivative, sts.normalMapDEfactor, isJulia, sts.normalMapUseDE, sts.normalMapInvertDE, sts.normalMapColoring, sts.useNormalMap, sts.normalMapDEUpperLimitFactor, sts.normalMapDEAAEffect, sts.normalMapOverrideColoring, sts.normalMapDeFadeAlgorithm, sts.normalMapDistanceEstimatorfactor); return; } else if (sts.statisticGroup == 0) { switch (sts.statistic_type) { @@ -3736,7 +3803,7 @@ protected void StatisticFactory(StatisticsSettings sts, double[] plane_transform } if(sts.normalMapCombineWithOtherStatistics) { - statistic = new CombinedStatisticWithNormalMap(statistic, new NormalMap(sts.statistic_intensity, power, sts.normalMapHeight, sts.normalMapAngle, sts.normalMapUseSecondDerivative, sts.normalMapDEfactor, isJulia, sts.normalMapUseDE, sts.normalMapInvertDE, sts.normalMapColoring, sts.useNormalMap, sts.normalMapDEUpperLimitFactor, sts.normalMapDEAAEffect, sts.normalMapOverrideColoring, sts.normalMapDeFadeAlgorithm, sts.normalMapDistanceEstimatorfactor)); + statistic = new CombinedStatisticWithNormalMap(statistic, new NormalMap(sts.statistic_intensity, getPower(), sts.normalMapHeight, sts.normalMapAngle, sts.normalMapUseSecondDerivative, sts.normalMapDEfactor, isJulia, sts.normalMapUseDE, sts.normalMapInvertDE, sts.normalMapColoring, sts.useNormalMap, sts.normalMapDEUpperLimitFactor, sts.normalMapDEAAEffect, sts.normalMapOverrideColoring, sts.normalMapDeFadeAlgorithm, sts.normalMapDistanceEstimatorfactor)); } } @@ -4360,12 +4427,34 @@ public static void clearReferences(boolean clearJuliaReference, boolean mainRefD secondMultiReferenceData[i].clear(); secondMultiReferenceDeepData[i].clear(); }*/ + + for(int i = 0; i < functions.length; i++){ + functions[i] = null; + } } tinyRefPts.clear(); tinyRefPtsArray = null; nanomb1 = null; + + + } + + public static void clearStatistics() { + total_max_iterations = null; + total_min_iterations = null; + total_max_iterations_ignore_max_iter = null; + total_bla_iterations = null; + total_iterations = null; + total_bla_steps = null; + total_perturb_iterations = null; + total_nanomb1_skipped_iterations = null; + total_double_iterations = null; + total_scaled_iterations = null; + total_float_exp_iterations = null; + total_rebases = null; + total_realigns = null; } /*protected static boolean isLastTermNotNegligible(MantExpComplex[][] coefs, MantExpComplex[] delta, MantExp limit, int i, int terms) { @@ -4385,6 +4474,10 @@ public static void clearReferences(boolean clearJuliaReference, boolean mainRefD protected static boolean isLastTermNotNegligible(long[] magCoeff, long magDiffThreshold, int lastIndex) { long magLast = magCoeff[lastIndex]; + + if(magLast == Long.MIN_VALUE) { + return false; + } for (int k = 0; k < lastIndex; k++) { if(magCoeff[k] == Long.MIN_VALUE) { @@ -4442,58 +4535,280 @@ public MantExpComplex getBlaA(MantExpComplex z) { return null; } - public static Complex getArrayValue(DoubleReference array, int index) { + public Complex getArrayValue(DoubleReference array, int index) { + if(array.compressed) { + return referenceDecompressor[array.id].getArrayValue(array, index); + } + + return new Complex(array.re[index], array.im[index]); + } + + public Complex getArrayValue(ReferenceDecompressor rd, DoubleReference array, int index) { + if(array.compressed) { + return rd.getArrayValue(array, index); + } + return new Complex(array.re[index], array.im[index]); } - public static Complex getArrayValue(DoubleReference array, int index, Complex output) { - output.assign(array.re[index], array.im[index]); - return output; + public Complex getArrayValue(DoubleReference array, int index, Complex refZ) { + if(array.compressed) { + return subexpressionsDecompressor[array.id].getArrayValue(array, index, refZ); + } + + return new Complex(array.re[index], array.im[index]); } - public static void setArrayValue(DoubleReference array, int index, Complex val) { + public Complex getArrayValue(ReferenceDecompressor rd, DoubleReference array, int index, Complex refZ) { + if(array.compressed) { + return rd.getArrayValue(array, index, refZ); + } + + return new Complex(array.re[index], array.im[index]); + } + + public Complex setArrayValue(DoubleReference array, int index, Complex val) { + + if(array.compressed) { + return referenceCompressor[array.id].setArrayValue(array, index, val); + } + else { + + if (array.saveMemory) { + array.checkAllocation(index); + } + + array.re[index] = val.getRe(); + array.im[index] = val.getIm(); + + return val; + } + } + + public void setArrayValue(DoubleReference array, int index, Complex val, Complex refZ) { + + if(array.compressed) { + subexpressionsCompressor[array.id].setArrayValue(array, index, val, refZ); + } + else { + + if (array.saveMemory) { + array.checkAllocation(index); + } + + array.re[index] = val.getRe(); + array.im[index] = val.getIm(); + } + } + + public void setArrayValue(ReferenceCompressor referenceCompressor, DoubleReference array, int index, Complex val, Complex refZ) { + + if(array.compressed) { + referenceCompressor.setArrayValue(array, index, val, refZ); + } + else { + + if (array.saveMemory) { + array.checkAllocation(index); + } - if(array.saveMemory) { - array.checkAllocation(index); + array.re[index] = val.getRe(); + array.im[index] = val.getIm(); } + } + public Complex setArrayValue(ReferenceCompressor referenceCompressor, DoubleReference array, int index, Complex val) { + + if(array.compressed) { + return referenceCompressor.setArrayValue(array, index, val); + } + else { - array.re[index] = val.getRe(); - array.im[index] = val.getIm(); + if (array.saveMemory) { + array.checkAllocation(index); + } + + array.re[index] = val.getRe(); + array.im[index] = val.getIm(); + return val; + } } - public static MantExpComplex getArrayDeepValue(DeepReference array, int index) { + public MantExpComplex getArrayDeepValue(DeepReference array, int index) { + + if(array.compressed) { + return referenceDecompressor[array.id].getArrayDeepValue(array, index); + } + if(TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { return new MantExpComplexFull(array.exps[index], array.expsIm[index], array.mantsRe[index], array.mantsIm[index]); } return new MantExpComplex(array.exps[index], array.mantsRe[index], array.mantsIm[index]); } - public static MantExpComplex getArrayDeepValue(DeepReference array, int index, MantExpComplex output) { + public MantExpComplex getArrayDeepValue(DeepReference array, int index, MantExpComplex refZ) { + + if(array.compressed) { + return subexpressionsDecompressor[array.id].getArrayDeepValue(array, index, refZ); + } + if(TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { - output.assign(array.exps[index], array.expsIm[index], array.mantsRe[index], array.mantsIm[index]); - return output; + return new MantExpComplexFull(array.exps[index], array.expsIm[index], array.mantsRe[index], array.mantsIm[index]); } - output.assign(array.exps[index], array.mantsRe[index], array.mantsIm[index]); - return output; + return new MantExpComplex(array.exps[index], array.mantsRe[index], array.mantsIm[index]); } - protected static void setArrayDeepValue(DeepReference array, int index, MantExpComplex val) { + public MantExpComplex getArrayDeepValue(ReferenceDecompressor rd, DeepReference array, int index, MantExpComplex refZ) { + + if(array.compressed) { + return rd.getArrayDeepValue(array, index, refZ); + } - if(array.saveMemory) { - array.checkAllocation(index); + if(TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { + return new MantExpComplexFull(array.exps[index], array.expsIm[index], array.mantsRe[index], array.mantsIm[index]); } + return new MantExpComplex(array.exps[index], array.mantsRe[index], array.mantsIm[index]); + } - array.exps[index] = val.getExp(); - array.mantsRe[index] = val.getMantissaReal(); - array.mantsIm[index] = val.getMantissaImag(); + public MantExpComplex getArrayDeepValue(ReferenceDecompressor rd, DeepReference array, int index) { + + if(array.compressed) { + return rd.getArrayDeepValue(array, index); + } if(TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { - array.expsIm[index] = val.getExpImag(); + return new MantExpComplexFull(array.exps[index], array.expsIm[index], array.mantsRe[index], array.mantsIm[index]); + } + return new MantExpComplex(array.exps[index], array.mantsRe[index], array.mantsIm[index]); + } + + protected MantExpComplex setArrayDeepValue(DeepReference array, int index, MantExpComplex val) { + + if(array.compressed) { + return referenceCompressor[array.id].setArrayDeepValue(array, index, val); + } + else { + if (array.saveMemory) { + array.checkAllocation(index); + } + + array.exps[index] = val.getExp(); + array.mantsRe[index] = val.getMantissaReal(); + array.mantsIm[index] = val.getMantissaImag(); + + if (TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { + array.expsIm[index] = val.getExpImag(); + } + + return val; } } - protected static MantExpComplex getSACoefficient(int term, int i) { + protected void setArrayDeepValue(DeepReference array, int index, MantExpComplex val, MantExpComplex refZ) { + + if(array.compressed) { + subexpressionsCompressor[array.id].setArrayDeepValue(array, index, val, refZ); + } + else { + if (array.saveMemory) { + array.checkAllocation(index); + } + + array.exps[index] = val.getExp(); + array.mantsRe[index] = val.getMantissaReal(); + array.mantsIm[index] = val.getMantissaImag(); + + if (TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { + array.expsIm[index] = val.getExpImag(); + } + } + + } + + protected void setArrayDeepValue(ReferenceCompressor referenceCompressor, DeepReference array, int index, MantExpComplex val, MantExpComplex refZ) { + + if(array.compressed) { + referenceCompressor.setArrayDeepValue(array, index, val, refZ); + } + else { + if (array.saveMemory) { + array.checkAllocation(index); + } + + array.exps[index] = val.getExp(); + array.mantsRe[index] = val.getMantissaReal(); + array.mantsIm[index] = val.getMantissaImag(); + + if (TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { + array.expsIm[index] = val.getExpImag(); + } + } + + } + + protected MantExpComplex setArrayDeepValue(ReferenceCompressor referenceCompressor, DeepReference array, int index, MantExpComplex val) { + + if(array.compressed) { + return referenceCompressor.setArrayDeepValue(array, index, val); + } + else { + if (array.saveMemory) { + array.checkAllocation(index); + } + + array.exps[index] = val.getExp(); + array.mantsRe[index] = val.getMantissaReal(); + array.mantsIm[index] = val.getMantissaImag(); + + if (TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { + array.expsIm[index] = val.getExpImag(); + } + return val; + } + + } + + public MantExpComplex getArrayDeepValueRandomAccess(DeepReference array, int index) { + + if(array.compressed) { + return referenceDecompressor[array.id].getArrayDeepValueRandomAccess(array, index); + } + + if(TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { + return new MantExpComplexFull(array.exps[index], array.expsIm[index], array.mantsRe[index], array.mantsIm[index]); + } + return new MantExpComplex(array.exps[index], array.mantsRe[index], array.mantsIm[index]); + } + + public MantExpComplex getArrayDeepValueRandomAccess(DeepReference array, int index, MantExpComplex refZ) { + + if(array.compressed) { + return subexpressionsDecompressor[array.id].getArrayDeepValueRandomAccess(array, index, refZ); + } + + if(TaskDraw.MANTEXPCOMPLEX_FORMAT == 1) { + return new MantExpComplexFull(array.exps[index], array.expsIm[index], array.mantsRe[index], array.mantsIm[index]); + } + return new MantExpComplex(array.exps[index], array.mantsRe[index], array.mantsIm[index]); + } + + public Complex getArrayValueRandomAccess(DoubleReference array, int index) { + if(array.compressed) { + return referenceDecompressor[array.id].getArrayValueRandomAccess(array, index); + } + + return new Complex(array.re[index], array.im[index]); + } + + public Complex getArrayValueRandomAccess(DoubleReference array, int index, Complex refZ) { + if(array.compressed) { + return subexpressionsDecompressor[array.id].getArrayValueRandomAccess(array, index, refZ); + } + + return new Complex(array.re[index], array.im[index]); + } + + protected MantExpComplex getSACoefficient(int term, int i) { int dataIndex = i % max_data; int index = dataIndex * SATerms + term; @@ -4505,7 +4820,7 @@ protected static MantExpComplex getSACoefficient(int term, int i) { } - protected static void setSACoefficient(int term, int i, MantExpComplex val) { + protected void setSACoefficient(int term, int i, MantExpComplex val) { int dataIndex = i % max_data; int index = dataIndex * SATerms + term; @@ -4567,7 +4882,7 @@ public double getDoubleDoubleLimit() { } if(isJulia) { - return 1.0e-20; + return 1.0e-18; } return 5.0e-25; } @@ -4719,7 +5034,7 @@ protected GenericComplex[] initializeReferencePrecalculationData(GenericComplex return null; } - protected GenericComplex[] precalculateReferenceData(GenericComplex z, GenericComplex c, NormComponents normData, Location loc, int bigNumLib, boolean lowPrecReferenceOrbitNeeded, boolean deepZoom, ReferenceData referenceData, ReferenceDeepData referenceDeepData, int iterations) { + protected GenericComplex[] precalculateReferenceData(GenericComplex z, GenericComplex c, NormComponents normData, Location loc, int bigNumLib, boolean lowPrecReferenceOrbitNeeded, boolean deepZoom, ReferenceData referenceData, ReferenceDeepData referenceDeepData, int iterations, Complex cz, MantExpComplex mcz) { return null; } @@ -4727,6 +5042,14 @@ protected int[] getNeededPrecalculatedTermsIndexes() { return new int[0]; } + protected Function[] getPrecalculatedTermsFunctions(Complex c) { + return null; + } + + protected Function[] getPrecalculatedTermsFunctionsDeep(MantExpComplex c) { + return null; + } + public void calculateReferencePoint(GenericComplex inputPixel, Apfloat size, boolean deepZoom, int[] Iterations, int[] juliaIterations, Location externalLocation, JProgressBar progress) { LastCalculationSize = size; @@ -4748,17 +5071,19 @@ public void calculateReferencePoint(GenericComplex inputPixel, Apfloat size, boo boolean lowPrecReferenceOrbitNeeded = !needsOnlyExtendedReferenceOrbit(deepZoom, false); DoubleReference.SHOULD_SAVE_MEMORY = false; + boolean useCompressedRef = TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE && supportsReferenceCompression(); + int[] precalIndexes = getNeededPrecalculatedTermsIndexes(); if (iterations == 0) { if(lowPrecReferenceOrbitNeeded) { - referenceData.createAndSetShortcut(max_ref_iterations, needsRefSubCp(), getNeededPrecalculatedTermsIndexes()); + referenceData.createAndSetShortcut(max_ref_iterations, needsRefSubCp(), precalIndexes, useCompressedRef); } else { referenceData.deallocate(); } if (deepZoom) { - referenceDeepData.createAndSetShortcut(max_ref_iterations, needsRefSubCp(), getNeededPrecalculatedTermsIndexes()); + referenceDeepData.createAndSetShortcut(max_ref_iterations, needsRefSubCp(), precalIndexes, useCompressedRef); } } else if (max_ref_iterations > getReferenceLength()) { if(lowPrecReferenceOrbitNeeded) { @@ -4773,6 +5098,8 @@ public void calculateReferencePoint(GenericComplex inputPixel, Apfloat size, boo } } + inputPixel = getInputPixel(inputPixel); + GenericComplex z, c, zold, zold2, start, c0, pixel, initVal; Object normSquared; @@ -4868,15 +5195,35 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { Location loc = new Location(); refPoint = inputPixel; - refPointSmall = refPoint.toComplex(); - - if(lowPrecReferenceOrbitNeeded) { - C = c.toComplex(); - } if(deepZoom) { refPointSmallDeep = loc.getMantExpComplex(refPoint); Cdeep = loc.getMantExpComplex(c); + + if(isJulia) { + seedSmallDeep = loc.getMantExpComplex(c); + } + + if(lowPrecReferenceOrbitNeeded) { + C = Cdeep.toComplex(); + + if(isJulia) { + seedSmall = seedSmallDeep.toComplex(); + } + } + + refPointSmall = refPointSmallDeep.toComplex(); + } + else { + if(lowPrecReferenceOrbitNeeded) { + C = c.toComplex(); + + if(isJulia) { + seedSmall = c.toComplex(); + } + } + + refPointSmall = refPoint.toComplex(); } GenericComplex[] initialPrecal = initializeReferencePrecalculationData(c, loc, bigNumLib, lowPrecReferenceOrbitNeeded, deepZoom); @@ -4886,32 +5233,79 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { boolean preCalcNormData = bailout_algorithm2.getId() == MainWindow.BAILOUT_CONDITION_CIRCLE; NormComponents normData = null; - calculatedReferenceIterations = 0; + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[referenceDeep.id] = new ReferenceCompressor(this, iterations == 0 ? z.toMantExpComplex() : referenceData.compressorZm, c.toMantExpComplex(), start.toMantExpComplex()); - for (; iterations < max_ref_iterations; iterations++, calculatedReferenceIterations++) { + if(needsRefSubCp()) { + MantExpComplex cp = initVal.toMantExpComplex(); + Function f = x -> x.sub(cp); + functions[referenceDeepData.ReferenceSubCp.id] = f; + subexpressionsCompressor[referenceDeepData.ReferenceSubCp.id] = new ReferenceCompressor(f, true); + } + Function[] fs = getPrecalculatedTermsFunctionsDeep(c.toMantExpComplex()); + for(int i = 0; i < precalIndexes.length; i++) { + int id = referenceDeepData.PrecalculatedTerms[precalIndexes[i]].id; + functions[id] = fs[i]; + subexpressionsCompressor[id] = new ReferenceCompressor(fs[i], true); + } + } if(lowPrecReferenceOrbitNeeded) { - Complex cz = z.toComplex(); - if (cz.isInfinite()) { - break; + referenceCompressor[reference.id] = new ReferenceCompressor(this, iterations == 0 ? z.toComplex() : referenceData.compressorZ, c.toComplex(), start.toComplex()); + + if(needsRefSubCp()) { + Complex cp = initVal.toComplex(); + Function f = x -> x.sub(cp); + functions[referenceData.ReferenceSubCp.id] = f; + subexpressionsCompressor[referenceData.ReferenceSubCp.id] = new ReferenceCompressor(f); } - setArrayValue(reference, iterations, cz); + Function[] fs = getPrecalculatedTermsFunctions(c.toComplex()); + for(int i = 0; i < precalIndexes.length; i++) { + int id = referenceData.PrecalculatedTerms[precalIndexes[i]].id; + functions[id] = fs[i]; + subexpressionsCompressor[id] = new ReferenceCompressor(fs[i]); + } } + } + + calculatedReferenceIterations = 0; + + MantExpComplex mcz = null; + Complex cz = null; + MantExpComplex tempmcz = null; + + for (; iterations < max_ref_iterations; iterations++, calculatedReferenceIterations++) { if(deepZoom) { - setArrayDeepValue(referenceDeep, iterations, loc.getMantExpComplex(z)); + mcz = loc.getMantExpComplex(z); + if (mcz.isInfinite() || mcz.isNaN()) { + break; + } + tempmcz = setArrayDeepValue(referenceDeep, iterations, mcz); //ReferenceDeep[iterations] = new MantExpComplex(Reference[iterations]); } - calculateRefSubCp(z, initVal, loc, bigNumLib, lowPrecReferenceOrbitNeeded, deepZoom, referenceData, referenceDeepData, iterations); + if(lowPrecReferenceOrbitNeeded) { + cz = deepZoom ? mcz.toComplex() : z.toComplex(); + if (cz.isInfinite() || cz.isNaN()) { + break; + } + + cz = setArrayValue(reference, iterations, cz); + } + + mcz = tempmcz; + + calculateRefSubCp(z, initVal, loc, bigNumLib, lowPrecReferenceOrbitNeeded, deepZoom, referenceData, referenceDeepData, iterations, cz, mcz); if(preCalcNormData) { normData = z.normSquaredWithComponents(normData); normSquared = normData.normSquared; } - GenericComplex[] precalculatedData = precalculateReferenceData(z, c, normData, loc, bigNumLib, lowPrecReferenceOrbitNeeded, deepZoom, referenceData, referenceDeepData, iterations); + GenericComplex[] precalculatedData = precalculateReferenceData(z, c, normData, loc, bigNumLib, lowPrecReferenceOrbitNeeded, deepZoom, referenceData, referenceDeepData, iterations, cz, mcz); if (iterations > 0 && bailout_algorithm2.Escaped(z, zold, zold2, iterations, c, start, c0, normSquared, pixel)) { break; @@ -4942,6 +5336,34 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { referenceData.MaxRefIteration = iterations - 1; + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[referenceDeep.id].compact(referenceDeep); + referenceData.compressorZm = referenceCompressor[referenceDeep.id].getZDeep(); + + if(needsRefSubCp()) { + subexpressionsCompressor[referenceDeepData.ReferenceSubCp.id].compact(referenceDeepData.ReferenceSubCp); + } + + for(int i = 0; i < precalIndexes.length; i++) { + subexpressionsCompressor[referenceDeepData.PrecalculatedTerms[precalIndexes[i]].id].compact(referenceDeepData.PrecalculatedTerms[precalIndexes[i]]); + } + } + + if(lowPrecReferenceOrbitNeeded) { + referenceCompressor[reference.id].compact(reference); + referenceData.compressorZ = referenceCompressor[reference.id].getZ(); + + if(needsRefSubCp()) { + subexpressionsCompressor[referenceData.ReferenceSubCp.id].compact(referenceData.ReferenceSubCp); + } + + for(int i = 0; i < precalIndexes.length; i++) { + subexpressionsCompressor[referenceData.PrecalculatedTerms[precalIndexes[i]].id].compact(referenceData.PrecalculatedTerms[precalIndexes[i]]); + } + } + } + SAskippedIterations = 0; if(progress != null) { @@ -4953,7 +5375,6 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { if(isJulia) { calculateJuliaReferencePoint(inputPixel, size, deepZoom, juliaIterations, progress); } - } protected GenericComplex referenceFunction(GenericComplex z, GenericComplex c, NormComponents normData, GenericComplex[] initialPrecal, GenericComplex[] precalc) { @@ -4964,7 +5385,7 @@ protected boolean needsRefSubCp() { return false; } - protected void calculateRefSubCp(GenericComplex z, GenericComplex initVal, Location loc, int bigNumLib, boolean lowPrecReferenceOrbitNeeded, boolean deepZoom, ReferenceData referenceData, ReferenceDeepData referenceDeepData, int iterations) { + protected void calculateRefSubCp(GenericComplex z, GenericComplex initVal, Location loc, int bigNumLib, boolean lowPrecReferenceOrbitNeeded, boolean deepZoom, ReferenceData referenceData, ReferenceDeepData referenceDeepData, int iterations, Complex cz, MantExpComplex mcz) { } @@ -5038,8 +5459,132 @@ protected static long calculateSAmagnitude(long clog, long logwToThe) { } + public Complex function(Complex z, Complex c) { + return null; + } + + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + return null; + } + public boolean usesDefaultPlane() { return plane instanceof MuPlane; } + public void initializeReferenceDecompressor() { + + if(!(supportsPerturbationTheory() && TaskDraw.PERTURBATION_THEORY && TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE && supportsReferenceCompression())) { + return; + } + + if(referenceData.Reference != null) { + if((isJulia || this instanceof RootFindingMethods) && refPointSmall != null && seedSmall != null) { + referenceDecompressor[referenceData.Reference.id] = new ReferenceDecompressor(this, new Complex(seedSmall), new Complex(refPointSmall)); + } + else if (refPointSmall != null){ + referenceDecompressor[referenceData.Reference.id] = new ReferenceDecompressor(this, new Complex(refPointSmall), new Complex(defaultInitVal.getValue(refPointSmall))); + } + } + + if(secondReferenceData.Reference != null && seedSmall != null && refPointSmall != null) { + referenceDecompressor[secondReferenceData.Reference.id] = new ReferenceDecompressor(this, new Complex(seedSmall), new Complex(defaultInitVal.getValue(refPointSmall))); + } + + if(referenceDeepData.Reference != null) { + if((isJulia || this instanceof RootFindingMethods) && seedSmallDeep != null && refPointSmallDeep != null) { + referenceDecompressor[referenceDeepData.Reference.id] = new ReferenceDecompressor(this, MantExpComplex.copy(seedSmallDeep) , MantExpComplex.copy(refPointSmallDeep)); + } + else if (refPointSmallDeep != null) { + referenceDecompressor[referenceDeepData.Reference.id] = new ReferenceDecompressor(this, MantExpComplex.copy(refPointSmallDeep), MantExpComplex.copy(defaultInitVal.getValueDeep(refPointSmallDeep))); + } + } + + if(secondReferenceDeepData.Reference != null && seedSmallDeep != null && refPointSmallDeep != null) { + referenceDecompressor[secondReferenceDeepData.Reference.id] = new ReferenceDecompressor(this, MantExpComplex.copy(seedSmallDeep), MantExpComplex.copy(defaultInitVal.getValueDeep(refPointSmallDeep))); + } + + if(needsRefSubCp()) { + if(referenceData.ReferenceSubCp != null) { + subexpressionsDecompressor[referenceData.ReferenceSubCp.id] = new ReferenceDecompressor((Function) functions[referenceData.ReferenceSubCp.id]); + } + + if(referenceDeepData.ReferenceSubCp != null) { + subexpressionsDecompressor[referenceDeepData.ReferenceSubCp.id] = new ReferenceDecompressor((Function) functions[referenceDeepData.ReferenceSubCp.id], true); + } + + if(secondReferenceData.ReferenceSubCp != null) { + subexpressionsDecompressor[secondReferenceData.ReferenceSubCp.id] = new ReferenceDecompressor((Function) functions[secondReferenceData.ReferenceSubCp.id]); + } + + if(secondReferenceDeepData.ReferenceSubCp != null) { + subexpressionsDecompressor[secondReferenceDeepData.ReferenceSubCp.id] = new ReferenceDecompressor((Function) functions[secondReferenceDeepData.ReferenceSubCp.id], true); + } + } + + int[] precalIndexes = getNeededPrecalculatedTermsIndexes(); + for(int i = 0; i < precalIndexes.length; i++) { + int index = precalIndexes[i]; + + if(referenceData.PrecalculatedTerms[index] != null) { + subexpressionsDecompressor[referenceData.PrecalculatedTerms[index].id] = new ReferenceDecompressor((Function) functions[referenceData.PrecalculatedTerms[index].id]); + } + + if(referenceDeepData.PrecalculatedTerms[index] != null) { + subexpressionsDecompressor[referenceDeepData.PrecalculatedTerms[index].id] = new ReferenceDecompressor((Function) functions[referenceDeepData.PrecalculatedTerms[index].id], true); + } + + if(secondReferenceData.PrecalculatedTerms[index] != null) { + subexpressionsDecompressor[secondReferenceData.PrecalculatedTerms[index].id] = new ReferenceDecompressor((Function) functions[secondReferenceData.PrecalculatedTerms[index].id]); + } + + if(secondReferenceDeepData.PrecalculatedTerms[index] != null) { + subexpressionsDecompressor[secondReferenceDeepData.PrecalculatedTerms[index].id] = new ReferenceDecompressor((Function) functions[secondReferenceDeepData.PrecalculatedTerms[index].id], true); + } + } + } + + public long getBLAEntries() { + if(TaskDraw.APPROXIMATION_ALGORITHM == 4 && supportsBilinearApproximation2()) { + return laReference.isValid ? laReference.LAsize() : 0; + } + else if(TaskDraw.APPROXIMATION_ALGORITHM == 2 && supportsBilinearApproximation()) { + return B.isValid ? B.getTotalElements() : 0; + } + return 0; + } + + public ReferenceDecompressor[] getReferenceDecompressors() { + return referenceDecompressor; + } + + protected GenericComplex sanitizeInputPixel(GenericComplex inputPixel) { + if(inputPixel instanceof BigComplex && ((BigComplex)inputPixel).norm().compareTo(new MyApfloat(1e-4)) < 0) { + inputPixel = new BigComplex(1e-4, 1e-4); + } + else if(inputPixel instanceof MpfrBigNumComplex && ((MpfrBigNumComplex)inputPixel).norm().compare(1e-4) < 0) { + inputPixel = new MpfrBigNumComplex(1e-4, 1e-4); + } + else if(inputPixel instanceof MpirBigNumComplex && ((MpirBigNumComplex)inputPixel).norm().compare(1e-4) < 0) { + inputPixel = new MpirBigNumComplex(1e-4, 1e-4); + } + else if(inputPixel instanceof DDComplex && ((DDComplex)inputPixel).norm().compareTo(new DoubleDouble(1e-4)) < 0) { + inputPixel = new DDComplex(1e-4, 1e-4); + } + else if(inputPixel instanceof BigIntNumComplex && ((BigIntNumComplex)inputPixel).norm().compare(new BigIntNum(1e-4)) < 0) { + inputPixel = new BigIntNumComplex(1e-4, 1e-4); + } + else if(inputPixel instanceof Complex && ((Complex)inputPixel).norm() < 1e-4) { + inputPixel = new Complex(1e-4, 1e-4); + } + return inputPixel; + } + + protected GenericComplex getInputPixel(GenericComplex inputPixel) { + return inputPixel; + } + + protected double getPower() { + return 0; + } + } diff --git a/src/fractalzoomer/functions/Julia.java b/src/fractalzoomer/functions/Julia.java index f9c1e1225..59369f435 100644 --- a/src/fractalzoomer/functions/Julia.java +++ b/src/fractalzoomer/functions/Julia.java @@ -28,6 +28,7 @@ import javax.swing.*; import java.util.ArrayList; +import java.util.function.Function; import static fractalzoomer.main.Constants.*; @@ -472,7 +473,7 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi int MaxRefIteration = data.MaxRefIteration; int minExp = -1000; - int reducedExp = minExp / (int)power; + int reducedExp = minExp / (int)getPower(); DeltaSubN.Normalize(); long exp = DeltaSubN.getMinExp(); @@ -482,6 +483,8 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi if(useFullFloatExp || (totalSkippedIterations == 0 && exp <= minExp) || (totalSkippedIterations != 0 && exp <= reducedExp)) { MantExpComplex z = getArrayDeepValue(deepData.Reference, RefIteration).plus_mutable(DeltaSubN); + MantExpComplex zoldDeep; + for (; iterations < max_iterations; iterations++) { if (trap != null) { trap.check(complex[0], iterations); @@ -509,6 +512,7 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi zold2.assign(zold); zold.assign(complex[0]); + zoldDeep = z; if (max_iterations > 1) { z = getArrayDeepValue(deepData.Reference, RefIteration).plus_mutable(DeltaSubN); @@ -516,7 +520,7 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi } if (statistic != null) { - statistic.insert(complex[0], zold, zold2, iterations, complex[1], start, c0); + statistic.insert(complex[0], zold, zold2, iterations, complex[1], start, c0, z, zoldDeep , null); } if (z.norm_squared().compareToBothPositive(DeltaSubN.norm_squared()) < 0 || RefIteration >= MaxRefIteration) { @@ -639,17 +643,19 @@ protected void calculateJuliaReferencePoint(GenericComplex inputPixel, Apfloat s boolean lowPrecReferenceOrbitNeeded = !needsOnlyExtendedReferenceOrbit(deepZoom, false); DoubleReference.SHOULD_SAVE_MEMORY = false; + boolean useCompressedRef = TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE && supportsReferenceCompression(); + int[] precalIndexes = getNeededPrecalculatedTermsIndexes(); if (iterations == 0) { if(lowPrecReferenceOrbitNeeded) { - secondReferenceData.create(max_ref_iterations, needsRefSubCp(), getNeededPrecalculatedTermsIndexes()); + secondReferenceData.create(max_ref_iterations, needsRefSubCp(), precalIndexes, useCompressedRef); } else { secondReferenceData.deallocate(); } if (deepZoom) { - secondReferenceDeepData.create(max_ref_iterations, needsRefSubCp(), getNeededPrecalculatedTermsIndexes()); + secondReferenceDeepData.create(max_ref_iterations, needsRefSubCp(), precalIndexes, useCompressedRef); } } else if (max_ref_iterations > getSecondReferenceLength()) { if(lowPrecReferenceOrbitNeeded) { @@ -762,31 +768,79 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { boolean preCalcNormData = bailout_algorithm2.getId() == MainWindow.BAILOUT_CONDITION_CIRCLE; NormComponents normData = null; + MantExpComplex mcz = null; + Complex cz = null; + + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[secondReferenceDeepData.Reference.id] = new ReferenceCompressor(this, iterations == 0 ? z.toMantExpComplex() : secondReferenceData.compressorZm, c.toMantExpComplex(), start.toMantExpComplex()); + + if(needsRefSubCp()) { + MantExpComplex cp = initVal.toMantExpComplex(); + Function f = x -> x.sub(cp); + functions[secondReferenceDeepData.ReferenceSubCp.id] = f; + subexpressionsCompressor[secondReferenceDeepData.ReferenceSubCp.id] = new ReferenceCompressor(f, true); + } + + Function[] fs = getPrecalculatedTermsFunctionsDeep(c.toMantExpComplex()); + for(int i = 0; i < precalIndexes.length; i++) { + int id = secondReferenceDeepData.PrecalculatedTerms[precalIndexes[i]].id; + functions[id] = fs[i]; + subexpressionsCompressor[id] = new ReferenceCompressor(fs[i], true); + } + } + if(lowPrecReferenceOrbitNeeded) { + referenceCompressor[secondReferenceData.Reference.id] = new ReferenceCompressor(this, iterations == 0 ? z.toComplex() : secondReferenceData.compressorZ, c.toComplex(), start.toComplex()); + + if(needsRefSubCp()) { + Complex cp = initVal.toComplex(); + Function f = x -> x.sub(cp); + functions[secondReferenceData.ReferenceSubCp.id] = f; + subexpressionsCompressor[secondReferenceData.ReferenceSubCp.id] = new ReferenceCompressor(f); + } + + Function[] fs = getPrecalculatedTermsFunctions(c.toComplex()); + for(int i = 0; i < precalIndexes.length; i++) { + int id = secondReferenceData.PrecalculatedTerms[precalIndexes[i]].id; + functions[id] = fs[i]; + subexpressionsCompressor[id] = new ReferenceCompressor(fs[i]); + } + } + } + calculatedSecondReferenceIterations = 0; + MantExpComplex tempmcz = null; + for (; iterations < max_ref_iterations; iterations++, calculatedSecondReferenceIterations++) { + if(deepZoom) { + mcz = loc.getMantExpComplex(z); + if (mcz.isInfinite() || mcz.isNaN()) { + break; + } + tempmcz = setArrayDeepValue(secondReferenceDeepData.Reference, iterations, mcz); + } + if(lowPrecReferenceOrbitNeeded) { - Complex cz = z.toComplex(); + cz = deepZoom ? mcz.toComplex() : z.toComplex(); - if (cz.isInfinite()) { + if (cz.isInfinite() || cz.isNaN()) { break; } - setArrayValue(secondReferenceData.Reference, iterations, cz); + cz = setArrayValue(secondReferenceData.Reference, iterations, cz); } - if(deepZoom) { - setArrayDeepValue(secondReferenceDeepData.Reference, iterations, loc.getMantExpComplex(z)); - } + mcz = tempmcz; - calculateRefSubCp(z, initVal, loc, bigNumLib, lowPrecReferenceOrbitNeeded, deepZoom, secondReferenceData, secondReferenceDeepData, iterations); + calculateRefSubCp(z, initVal, loc, bigNumLib, lowPrecReferenceOrbitNeeded, deepZoom, secondReferenceData, secondReferenceDeepData, iterations, cz, mcz); if(preCalcNormData) { normData = z.normSquaredWithComponents(normData); normSquared = normData.normSquared; } - GenericComplex[] precalculatedData = precalculateReferenceData(z, c, normData, loc, bigNumLib, lowPrecReferenceOrbitNeeded, deepZoom, secondReferenceData, secondReferenceDeepData, iterations); + GenericComplex[] precalculatedData = precalculateReferenceData(z, c, normData, loc, bigNumLib, lowPrecReferenceOrbitNeeded, deepZoom, secondReferenceData, secondReferenceDeepData, iterations, cz, mcz); if (iterations > 0 && bailout_algorithm2.Escaped(z, zold, zold2, iterations, c, start, c0, normSquared, pixel)) { break; @@ -818,6 +872,34 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { secondReferenceData.MaxRefIteration = iterations - 1; + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[secondReferenceDeepData.Reference.id].compact(secondReferenceDeepData.Reference); + secondReferenceData.compressorZm = referenceCompressor[secondReferenceDeepData.Reference.id].getZDeep(); + + if(needsRefSubCp()) { + subexpressionsCompressor[secondReferenceDeepData.ReferenceSubCp.id].compact(secondReferenceDeepData.ReferenceSubCp); + } + + for(int i = 0; i < precalIndexes.length; i++) { + subexpressionsCompressor[secondReferenceDeepData.PrecalculatedTerms[precalIndexes[i]].id].compact(secondReferenceDeepData.PrecalculatedTerms[precalIndexes[i]]); + } + } + + if(lowPrecReferenceOrbitNeeded) { + referenceCompressor[secondReferenceData.Reference.id].compact(secondReferenceData.Reference); + secondReferenceData.compressorZ = referenceCompressor[secondReferenceData.Reference.id].getZ(); + + if(needsRefSubCp()) { + subexpressionsCompressor[secondReferenceData.ReferenceSubCp.id].compact(secondReferenceData.ReferenceSubCp); + } + + for(int i = 0; i < precalIndexes.length; i++) { + subexpressionsCompressor[secondReferenceData.PrecalculatedTerms[precalIndexes[i]].id].compact(secondReferenceData.PrecalculatedTerms[precalIndexes[i]]); + } + } + } + if(progress != null) { progress.setValue(progress.getMaximum()); progress.setString(REFERENCE_CALCULATION_STR + " 100%"); diff --git a/src/fractalzoomer/functions/formulas/general/newtonvariant/LambertWVariation.java b/src/fractalzoomer/functions/formulas/general/newtonvariant/LambertWVariation.java index 8ecbc74fb..03293797a 100644 --- a/src/fractalzoomer/functions/formulas/general/newtonvariant/LambertWVariation.java +++ b/src/fractalzoomer/functions/formulas/general/newtonvariant/LambertWVariation.java @@ -81,13 +81,11 @@ public LambertWVariation(double xCenter, double yCenter, double size, int max_it switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/formulas/m_like_generalization/BuffaloMandelbrot.java b/src/fractalzoomer/functions/formulas/m_like_generalization/BuffaloMandelbrot.java index 3b14399f6..f0be3e1fb 100644 --- a/src/fractalzoomer/functions/formulas/m_like_generalization/BuffaloMandelbrot.java +++ b/src/fractalzoomer/functions/formulas/m_like_generalization/BuffaloMandelbrot.java @@ -43,7 +43,6 @@ public BuffaloMandelbrot(double xCenter, double yCenter, double size, int max_it if(sts.statistic) { StatisticFactory(sts, plane_transform_center); } - power = 2; } public BuffaloMandelbrot(double xCenter, double yCenter, double size, int max_iterations, int bailout_test_algorithm, double bailout, String bailout_test_user_formula, String bailout_test_user_formula2, int bailout_test_comparison, double n_norm, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, boolean periodicity_checking, int plane_type, boolean apply_plane_on_julia, boolean apply_plane_on_julia_seed, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int escaping_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts, double xJuliaCenter, double yJuliaCenter) { @@ -60,7 +59,6 @@ public BuffaloMandelbrot(double xCenter, double yCenter, double size, int max_it pertur_val = new DefaultPerturbation(); init_val = new InitialValue(0, 0); - power = 2; } //orbit @@ -86,7 +84,6 @@ public BuffaloMandelbrot(double xCenter, double yCenter, double size, int max_it else { init_val = new InitialValue(0, 0); } - power = 2; } @@ -95,7 +92,6 @@ public BuffaloMandelbrot(double xCenter, double yCenter, double size, int max_it super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); pertur_val = new DefaultPerturbation(); init_val = new InitialValue(0, 0); - power = 2; } @Override @@ -295,4 +291,24 @@ protected GenericComplex referenceFunction(GenericComplex z, GenericComplex c, N } + @Override + public boolean supportsReferenceCompression() { + return true; + } + + @Override + public Complex function(Complex z, Complex c) { + return z.square_mutable().abs_mutable().plus_mutable(c); + } + + @Override + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + return z.square_mutable().abs_mutable().plus_mutable(c); + } + + @Override + public double getPower() { + return 2; + } + } diff --git a/src/fractalzoomer/functions/formulas/m_like_generalization/CelticMandelbrot.java b/src/fractalzoomer/functions/formulas/m_like_generalization/CelticMandelbrot.java index 62e4ea349..fc36c759a 100644 --- a/src/fractalzoomer/functions/formulas/m_like_generalization/CelticMandelbrot.java +++ b/src/fractalzoomer/functions/formulas/m_like_generalization/CelticMandelbrot.java @@ -43,7 +43,6 @@ public CelticMandelbrot(double xCenter, double yCenter, double size, int max_ite if(sts.statistic) { StatisticFactory(sts, plane_transform_center); } - power = 2; } public CelticMandelbrot(double xCenter, double yCenter, double size, int max_iterations, int bailout_test_algorithm, double bailout, String bailout_test_user_formula, String bailout_test_user_formula2, int bailout_test_comparison, double n_norm, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, boolean periodicity_checking, int plane_type, boolean apply_plane_on_julia, boolean apply_plane_on_julia_seed, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int escaping_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts, double xJuliaCenter, double yJuliaCenter) { @@ -60,7 +59,6 @@ public CelticMandelbrot(double xCenter, double yCenter, double size, int max_ite pertur_val = new DefaultPerturbation(); init_val = new InitialValue(0, 0); - power = 2; } //orbit @@ -86,8 +84,6 @@ public CelticMandelbrot(double xCenter, double yCenter, double size, int max_ite else { init_val = new InitialValue(0, 0); } - power = 2; - } public CelticMandelbrot(double xCenter, double yCenter, double size, int max_iterations, ArrayList complex_orbit, int plane_type, boolean apply_plane_on_julia, boolean apply_plane_on_julia_seed, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, double xJuliaCenter, double yJuliaCenter) { @@ -95,7 +91,6 @@ public CelticMandelbrot(double xCenter, double yCenter, double size, int max_ite super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); pertur_val = new DefaultPerturbation(); init_val = new InitialValue(0, 0); - power = 2; } @Override @@ -267,4 +262,24 @@ protected GenericComplex referenceFunction(GenericComplex z, GenericComplex c, N } + @Override + public boolean supportsReferenceCompression() { + return true; + } + + @Override + public Complex function(Complex z, Complex c) { + return z.square_mutable().absre_mutable().plus_mutable(c); + } + + @Override + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + return z.square_mutable().absre_mutable().plus_mutable(c); + } + + @Override + public double getPower() { + return 2; + } + } diff --git a/src/fractalzoomer/functions/formulas/m_like_generalization/Formula47.java b/src/fractalzoomer/functions/formulas/m_like_generalization/Formula47.java index 93930e647..92b5fb7ca 100644 --- a/src/fractalzoomer/functions/formulas/m_like_generalization/Formula47.java +++ b/src/fractalzoomer/functions/formulas/m_like_generalization/Formula47.java @@ -51,7 +51,6 @@ public Formula47(double xCenter, double yCenter, double size, int max_iterations if(sts.statistic) { StatisticFactory(sts, plane_transform_center); } - power = 2; } public Formula47(double xCenter, double yCenter, double size, int max_iterations, int bailout_test_algorithm, double bailout, String bailout_test_user_formula, String bailout_test_user_formula2, int bailout_test_comparison, double n_norm, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, boolean periodicity_checking, int plane_type, boolean apply_plane_on_julia, boolean apply_plane_on_julia_seed, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int escaping_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts, double xJuliaCenter, double yJuliaCenter) { @@ -68,7 +67,6 @@ public Formula47(double xCenter, double yCenter, double size, int max_iterations pertur_val = new DefaultPerturbation(); init_val = new InitialValue(0, 0); - power = 2; } //orbit @@ -94,7 +92,6 @@ public Formula47(double xCenter, double yCenter, double size, int max_iterations else { init_val = new InitialValue(0, 0); } - power = 2; } @@ -103,7 +100,6 @@ public Formula47(double xCenter, double yCenter, double size, int max_iterations super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); pertur_val = new DefaultPerturbation(); init_val = new InitialValue(0, 0); - power = 2; } @Override @@ -220,12 +216,17 @@ public GenericComplex[] initializeReferencePrecalculationData(GenericComplex c, GenericComplex c2 = c.times2(); - if(lowPrecReferenceOrbitNeeded) { - C2 = c2.toComplex(); - } - if(deepZoom) { C2Deep = loc.getMantExpComplex(c2); + + if(lowPrecReferenceOrbitNeeded) { + C2 = C2Deep.toComplex(); + } + } + else { + if(lowPrecReferenceOrbitNeeded) { + C2 = c2.toComplex(); + } } return new GenericComplex[] {c.square()}; @@ -249,4 +250,24 @@ else if(z instanceof MpirBigNumComplex) { } } + @Override + public boolean supportsReferenceCompression() { + return true; + } + + @Override + public Complex function(Complex z, Complex c) { + return z.square_mutable().plus_mutable(c.square()); + } + + @Override + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + return z.square_mutable().plus_mutable(c.square()); + } + + @Override + public double getPower() { + return 2; + } + } diff --git a/src/fractalzoomer/functions/formulas/m_like_generalization/PerpendicularBuffaloMandelbrot.java b/src/fractalzoomer/functions/formulas/m_like_generalization/PerpendicularBuffaloMandelbrot.java index f2ddd6ad0..a89e61a22 100644 --- a/src/fractalzoomer/functions/formulas/m_like_generalization/PerpendicularBuffaloMandelbrot.java +++ b/src/fractalzoomer/functions/formulas/m_like_generalization/PerpendicularBuffaloMandelbrot.java @@ -43,7 +43,6 @@ public PerpendicularBuffaloMandelbrot(double xCenter, double yCenter, double siz if(sts.statistic) { StatisticFactory(sts, plane_transform_center); } - power = 2; } public PerpendicularBuffaloMandelbrot(double xCenter, double yCenter, double size, int max_iterations, int bailout_test_algorithm, double bailout, String bailout_test_user_formula, String bailout_test_user_formula2, int bailout_test_comparison, double n_norm, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, boolean periodicity_checking, int plane_type, boolean apply_plane_on_julia, boolean apply_plane_on_julia_seed, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int escaping_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts, double xJuliaCenter, double yJuliaCenter) { @@ -60,7 +59,6 @@ public PerpendicularBuffaloMandelbrot(double xCenter, double yCenter, double siz pertur_val = new DefaultPerturbation(); init_val = new InitialValue(0, 0); - power = 2; } //orbit @@ -86,7 +84,6 @@ public PerpendicularBuffaloMandelbrot(double xCenter, double yCenter, double siz else { init_val = new InitialValue(0, 0); } - power = 2; } @@ -95,7 +92,6 @@ public PerpendicularBuffaloMandelbrot(double xCenter, double yCenter, double siz super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); pertur_val = new DefaultPerturbation(); init_val = new InitialValue(0, 0); - power = 2; } @Override @@ -283,4 +279,24 @@ protected GenericComplex referenceFunction(GenericComplex z, GenericComplex c, N } + @Override + public boolean supportsReferenceCompression() { + return true; + } + + @Override + public Complex function(Complex z, Complex c) { + return z.absNegateIm_mutable().square_mutable().absre_mutable().plus_mutable(c); + } + + @Override + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + return z.absNegateIm_mutable().square_mutable().absre_mutable().plus_mutable(c); + } + + @Override + public double getPower() { + return 2; + } + } diff --git a/src/fractalzoomer/functions/formulas/m_like_generalization/PerpendicularBurningShip.java b/src/fractalzoomer/functions/formulas/m_like_generalization/PerpendicularBurningShip.java index 5d86f5a9f..f4e1ba9be 100644 --- a/src/fractalzoomer/functions/formulas/m_like_generalization/PerpendicularBurningShip.java +++ b/src/fractalzoomer/functions/formulas/m_like_generalization/PerpendicularBurningShip.java @@ -43,7 +43,6 @@ public PerpendicularBurningShip(double xCenter, double yCenter, double size, int if(sts.statistic) { StatisticFactory(sts, plane_transform_center); } - power = 2; } public PerpendicularBurningShip(double xCenter, double yCenter, double size, int max_iterations, int bailout_test_algorithm, double bailout, String bailout_test_user_formula, String bailout_test_user_formula2, int bailout_test_comparison, double n_norm, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, boolean periodicity_checking, int plane_type, boolean apply_plane_on_julia, boolean apply_plane_on_julia_seed, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int escaping_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts, double xJuliaCenter, double yJuliaCenter) { @@ -60,7 +59,6 @@ public PerpendicularBurningShip(double xCenter, double yCenter, double size, int pertur_val = new DefaultPerturbation(); init_val = new InitialValue(0, 0); - power = 2; } //orbit @@ -86,7 +84,6 @@ public PerpendicularBurningShip(double xCenter, double yCenter, double size, int else { init_val = new InitialValue(0, 0); } - power = 2; } @@ -95,7 +92,6 @@ public PerpendicularBurningShip(double xCenter, double yCenter, double size, int super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); pertur_val = new DefaultPerturbation(); init_val = new InitialValue(0, 0); - power = 2; } @Override @@ -283,4 +279,24 @@ else if(z instanceof MpirBigNumComplex) { } + @Override + public boolean supportsReferenceCompression() { + return true; + } + + @Override + public Complex function(Complex z, Complex c) { + return z.absNegateIm_mutable().square_mutable().plus_mutable(c); + } + + @Override + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + return z.absNegateIm_mutable().square_mutable().plus_mutable(c); + } + + @Override + public double getPower() { + return 2; + } + } diff --git a/src/fractalzoomer/functions/formulas/m_like_generalization/PerpendicularCelticMandelbrot.java b/src/fractalzoomer/functions/formulas/m_like_generalization/PerpendicularCelticMandelbrot.java index 0b03b18d9..c739e3e25 100644 --- a/src/fractalzoomer/functions/formulas/m_like_generalization/PerpendicularCelticMandelbrot.java +++ b/src/fractalzoomer/functions/formulas/m_like_generalization/PerpendicularCelticMandelbrot.java @@ -43,7 +43,6 @@ public PerpendicularCelticMandelbrot(double xCenter, double yCenter, double size if(sts.statistic) { StatisticFactory(sts, plane_transform_center); } - power = 2; } public PerpendicularCelticMandelbrot(double xCenter, double yCenter, double size, int max_iterations, int bailout_test_algorithm, double bailout, String bailout_test_user_formula, String bailout_test_user_formula2, int bailout_test_comparison, double n_norm, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, boolean periodicity_checking, int plane_type, boolean apply_plane_on_julia, boolean apply_plane_on_julia_seed, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int escaping_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts, double xJuliaCenter, double yJuliaCenter) { @@ -60,7 +59,6 @@ public PerpendicularCelticMandelbrot(double xCenter, double yCenter, double size pertur_val = new DefaultPerturbation(); init_val = new InitialValue(0, 0); - power = 2; } //orbit @@ -86,7 +84,6 @@ public PerpendicularCelticMandelbrot(double xCenter, double yCenter, double size else { init_val = new InitialValue(0, 0); } - power = 2; } @@ -95,7 +92,6 @@ public PerpendicularCelticMandelbrot(double xCenter, double yCenter, double size super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); pertur_val = new DefaultPerturbation(); init_val = new InitialValue(0, 0); - power = 2; } @Override @@ -283,4 +279,24 @@ protected GenericComplex referenceFunction(GenericComplex z, GenericComplex c, N } + @Override + public boolean supportsReferenceCompression() { + return true; + } + + @Override + public Complex function(Complex z, Complex c) { + return z.absNegateRe_mutable().square_mutable().absre_mutable().plus_mutable(c); + } + + @Override + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + return z.absNegateRe_mutable().square_mutable().absre_mutable().plus_mutable(c); + } + + @Override + public double getPower() { + return 2; + } + } diff --git a/src/fractalzoomer/functions/formulas/m_like_generalization/PerpendicularMandelbrot.java b/src/fractalzoomer/functions/formulas/m_like_generalization/PerpendicularMandelbrot.java index f2c956fe9..56d72c947 100644 --- a/src/fractalzoomer/functions/formulas/m_like_generalization/PerpendicularMandelbrot.java +++ b/src/fractalzoomer/functions/formulas/m_like_generalization/PerpendicularMandelbrot.java @@ -43,7 +43,6 @@ public PerpendicularMandelbrot(double xCenter, double yCenter, double size, int if(sts.statistic) { StatisticFactory(sts, plane_transform_center); } - power = 2; } public PerpendicularMandelbrot(double xCenter, double yCenter, double size, int max_iterations, int bailout_test_algorithm, double bailout, String bailout_test_user_formula, String bailout_test_user_formula2, int bailout_test_comparison, double n_norm, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, boolean periodicity_checking, int plane_type, boolean apply_plane_on_julia, boolean apply_plane_on_julia_seed, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int escaping_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts, double xJuliaCenter, double yJuliaCenter) { @@ -60,7 +59,6 @@ public PerpendicularMandelbrot(double xCenter, double yCenter, double size, int pertur_val = new DefaultPerturbation(); init_val = new InitialValue(0, 0); - power = 2; } //orbit @@ -86,7 +84,6 @@ public PerpendicularMandelbrot(double xCenter, double yCenter, double size, int else { init_val = new InitialValue(0, 0); } - power = 2; } @@ -95,7 +92,6 @@ public PerpendicularMandelbrot(double xCenter, double yCenter, double size, int super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); pertur_val = new DefaultPerturbation(); init_val = new InitialValue(0, 0); - power = 2; } @Override @@ -284,4 +280,24 @@ else if(z instanceof MpirBigNumComplex) { } + @Override + public boolean supportsReferenceCompression() { + return true; + } + + @Override + public Complex function(Complex z, Complex c) { + return z.absNegateRe_mutable().square_mutable().plus_mutable(c); + } + + @Override + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + return z.absNegateRe_mutable().square_mutable().plus_mutable(c); + } + + @Override + public double getPower() { + return 2; + } + } diff --git a/src/fractalzoomer/functions/formulas/m_like_generalization/c_azb_dze/Formula48.java b/src/fractalzoomer/functions/formulas/m_like_generalization/c_azb_dze/Formula48.java new file mode 100644 index 000000000..7f09a4679 --- /dev/null +++ b/src/fractalzoomer/functions/formulas/m_like_generalization/c_azb_dze/Formula48.java @@ -0,0 +1,993 @@ +/* + * Fractal Zoomer, Copyright (C) 2020 hrkalona2 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package fractalzoomer.functions.formulas.m_like_generalization.c_azb_dze; + +import fractalzoomer.core.*; +import fractalzoomer.core.location.Location; +import fractalzoomer.fractal_options.initial_value.InitialValue; +import fractalzoomer.fractal_options.initial_value.VariableConditionalInitialValue; +import fractalzoomer.fractal_options.initial_value.VariableInitialValue; +import fractalzoomer.fractal_options.perturbation.DefaultPerturbation; +import fractalzoomer.functions.Julia; +import fractalzoomer.main.Constants; +import fractalzoomer.main.app_settings.OrbitTrapSettings; +import fractalzoomer.main.app_settings.StatisticsSettings; +import fractalzoomer.utils.NormComponents; + +import java.util.ArrayList; +import java.util.function.Function; + +/** + * + * @author hrkalona2 + */ +public class Formula48 extends Julia { + + public Formula48(double xCenter, double yCenter, double size, int max_iterations, int bailout_test_algorithm, double bailout, String bailout_test_user_formula, String bailout_test_user_formula2, int bailout_test_comparison, double n_norm, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, boolean periodicity_checking, int plane_type, double[] rotation_vals, double[] rotation_center, boolean perturbation, double[] perturbation_vals, boolean variable_perturbation, int user_perturbation_algorithm, String[] user_perturbation_conditions, String[] user_perturbation_condition_formula, String perturbation_user_formula, boolean init_value, double[] initial_vals, boolean variable_init_value, int user_initial_value_algorithm, String[] user_initial_value_conditions, String[] user_initial_value_condition_formula, String initial_value_user_formula, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int escaping_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { + + super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); + + setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); + + if(init_value) { + if(variable_init_value) { + if(user_initial_value_algorithm == 0) { + init_val = new VariableInitialValue(initial_value_user_formula, xCenter, yCenter, size, max_iterations, plane_transform_center, globalVars); + } + else { + init_val = new VariableConditionalInitialValue(user_initial_value_conditions, user_initial_value_condition_formula, xCenter, yCenter, size, max_iterations, plane_transform_center, globalVars); + } + } + else { + init_val = new InitialValue(initial_vals[0], initial_vals[1]); + } + } + else { + init_val = new InitialValue(1, 0); + } + + OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, escaping_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); + + InColoringAlgorithmFactory(in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, plane_transform_center); + + if(sts.statistic) { + StatisticFactory(sts, plane_transform_center); + } + defaultInitVal = new InitialValue(1, 0); + } + + public Formula48(double xCenter, double yCenter, double size, int max_iterations, int bailout_test_algorithm, double bailout, String bailout_test_user_formula, String bailout_test_user_formula2, int bailout_test_comparison, double n_norm, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, boolean periodicity_checking, int plane_type, boolean apply_plane_on_julia, boolean apply_plane_on_julia_seed, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int escaping_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts, double xJuliaCenter, double yJuliaCenter) { + + super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, xJuliaCenter, yJuliaCenter); + + OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, escaping_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); + + InColoringAlgorithmFactory(in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, plane_transform_center); + + if(sts.statistic) { + StatisticFactory(sts, plane_transform_center); + } + + pertur_val = new DefaultPerturbation(); + init_val = new InitialValue(1, 0); + defaultInitVal = new InitialValue(1, 0); + } + + //orbit + public Formula48(double xCenter, double yCenter, double size, int max_iterations, ArrayList complex_orbit, int plane_type, double[] rotation_vals, double[] rotation_center, boolean perturbation, double[] perturbation_vals, boolean variable_perturbation, int user_perturbation_algorithm, String[] user_perturbation_conditions, String[] user_perturbation_condition_formula, String perturbation_user_formula, boolean init_value, double[] initial_vals, boolean variable_init_value, int user_initial_value_algorithm, String[] user_initial_value_conditions, String[] user_initial_value_condition_formula, String initial_value_user_formula, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower) { + + super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower); + + setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); + + if(init_value) { + if(variable_init_value) { + if(user_initial_value_algorithm == 0) { + init_val = new VariableInitialValue(initial_value_user_formula, xCenter, yCenter, size, max_iterations, plane_transform_center, globalVars); + } + else { + init_val = new VariableConditionalInitialValue(user_initial_value_conditions, user_initial_value_condition_formula, xCenter, yCenter, size, max_iterations, plane_transform_center, globalVars); + } + } + else { + init_val = new InitialValue(initial_vals[0], initial_vals[1]); + } + } + else { + init_val = new InitialValue(1, 0); + } + defaultInitVal = new InitialValue(1, 0); + + } + + public Formula48(double xCenter, double yCenter, double size, int max_iterations, ArrayList complex_orbit, int plane_type, boolean apply_plane_on_julia, boolean apply_plane_on_julia_seed, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, double xJuliaCenter, double yJuliaCenter) { + + super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); + pertur_val = new DefaultPerturbation(); + init_val = new InitialValue(1, 0); + defaultInitVal = new InitialValue(1, 0); + } + + @Override + public void function(Complex[] complex) { + + complex[0].square_mutable(); + (complex[0].plus_mutable(complex[0].reciprocal())).times_mutable(complex[1]); + + } + + //Todo has glitches + @Override + public double iterateFractalWithPerturbation(Complex[] complex, Complex dpixel) { + + + double_iterations = 0; + rebases = 0; + + Complex[] deltas = initializePerturbation(dpixel); + Complex DeltaSubN = deltas[0]; // Delta z + Complex DeltaSub0 = deltas[1]; // Delta c + + precalculatePerturbationData(DeltaSub0); + + iterations = nanomb1SkippedIterations != 0 ? nanomb1SkippedIterations : SAskippedIterations; + int RefIteration = iterations; + + int ReferencePeriod = getPeriod(); + + int MaxRefIteration = getReferenceFinalIterationNumber(true, referenceData); + + Complex refZ; + Complex zWithoutInitVal = new Complex(); + + if(iterations != 0 && RefIteration < MaxRefIteration) { + refZ = getArrayValue(reference, RefIteration); + zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration, refZ).plus_mutable(DeltaSubN); + complex[0] = refZ.plus_mutable(DeltaSubN); + } + else if(iterations != 0 && ReferencePeriod != 0) { + RefIteration = RefIteration % ReferencePeriod; + refZ = getArrayValue(reference, RefIteration); + zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration, refZ).plus_mutable(DeltaSubN); + complex[0] = refZ.plus_mutable(DeltaSubN); + } + + Complex pixel = dpixel.plus(refPointSmall); + + for (; iterations < max_iterations; iterations++) { + + //No update values + + if (trap != null) { + trap.check(complex[0], iterations); + } + + if (bailout_algorithm.escaped(complex[0], zold, zold2, iterations, complex[1], start, c0, 0.0, pixel)) { + escaped = true; + + Object[] object = {iterations, complex[0], zold, zold2, complex[1], start, c0, pixel}; + double res = out_color_algorithm.getResult(object); + + res = getFinalValueOut(res, complex[0]); + + if (outTrueColorAlgorithm != null) { + setTrueColorOut(complex[0], zold, zold2, iterations, complex[1], start, c0, pixel); + } + + return getAndAccumulateStatsNotDeep(res); + } + + DeltaSubN = perturbationFunction(DeltaSubN, DeltaSub0, RefIteration); + + RefIteration++; + double_iterations++; + + zold2.assign(zold); + zold.assign(complex[0]); + + //No Plane influence work + //No Pre filters work + if(max_iterations > 1){ + refZ = getArrayValue(reference, RefIteration); + zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration, refZ).plus_mutable(DeltaSubN); + complex[0] = refZ.plus_mutable(DeltaSubN); + } + //No Post filters work + + if (statistic != null) { + statistic.insert(complex[0], zold, zold2, iterations, complex[1], start, c0); + } + + if (zWithoutInitVal.norm_squared() < DeltaSubN.norm_squared() || RefIteration >= MaxRefIteration) { + DeltaSubN = zWithoutInitVal; + RefIteration = 0; + rebases++; + } + + } + + Object[] object = {complex[0], zold, zold2, complex[1], start, c0, pixel}; + double in = in_color_algorithm.getResult(object); + + in = getFinalValueIn(in, complex[0]); + + if (inTrueColorAlgorithm != null) { + setTrueColorIn(complex[0], zold, zold2, iterations, complex[1], start, c0, pixel); + } + + return getAndAccumulateStatsNotDeep(in); + + } + + @Override + public double iterateFractalWithPerturbation(Complex[] complex, MantExpComplex dpixel) { + + float_exp_iterations = 0; + double_iterations = 0; + rebases = 0; + + MantExpComplex[] deltas = initializePerturbation(dpixel); + MantExpComplex DeltaSubN = deltas[0]; // Delta z + MantExpComplex DeltaSub0 = deltas[1]; // Delta c + + precalculatePerturbationData(DeltaSub0); + + int totalSkippedIterations = nanomb1SkippedIterations != 0 ? nanomb1SkippedIterations : SAskippedIterations; + iterations = totalSkippedIterations; + int RefIteration = iterations; + + int ReferencePeriod = getPeriod(); + + int MaxRefIteration = getReferenceFinalIterationNumber(true, referenceData); + + int minExp = -1000; + int reducedExp = minExp / (int)getPower(); + + DeltaSubN.Normalize(); + long exp = DeltaSubN.getMinExp(); + + MantExpComplex cDeep = dpixel.plus(refPointSmallDeep); + Complex pixel = cDeep.toComplex(); + + boolean useFullFloatExp = useFullFloatExp(); + boolean doBailCheck = useFullFloatExp || TaskDraw.CHECK_BAILOUT_DURING_DEEP_NOT_FULL_FLOATEXP_MODE; + + boolean usedDeepCode = false; + + MantExpComplex refZm; + + if(useFullFloatExp || (totalSkippedIterations == 0 && exp <= minExp) || (totalSkippedIterations != 0 && exp <= reducedExp)) { + usedDeepCode = true; + MantExpComplex zWithoutInitVal = MantExpComplex.create(); + MantExpComplex z = MantExpComplex.create(); + if(iterations != 0 && RefIteration < MaxRefIteration) { + refZm = getArrayDeepValue(referenceDeep, RefIteration); + zWithoutInitVal = getArrayDeepValue(referenceDeepData.ReferenceSubCp, RefIteration, refZm).plus_mutable(DeltaSubN); + z = refZm.plus_mutable(DeltaSubN); + complex[0] = z.toComplex(); + } + else if(iterations != 0 && ReferencePeriod != 0) { + RefIteration = RefIteration % ReferencePeriod; + refZm = getArrayDeepValue(referenceDeep, RefIteration); + zWithoutInitVal = getArrayDeepValue(referenceDeepData.ReferenceSubCp, RefIteration, refZm).plus_mutable(DeltaSubN); + z = refZm.plus_mutable(DeltaSubN); + complex[0] = z.toComplex(); + } + + MantExpComplex zoldDeep; + + + for (; iterations < max_iterations; iterations++) { + if (trap != null) { + trap.check(complex[0], iterations); + } + + if (doBailCheck && bailout_algorithm.escaped(complex[0], zold, zold2, iterations, complex[1], start, c0, 0.0, pixel)) { + escaped = true; + + Object[] object = {iterations, complex[0], zold, zold2, complex[1], start, c0, pixel}; + double res = out_color_algorithm.getResult(object); + + res = getFinalValueOut(res, complex[0]); + + if (outTrueColorAlgorithm != null) { + setTrueColorOut(complex[0], zold, zold2, iterations, complex[1], start, c0, pixel); + } + + return getAndAccumulateStatsNotScaled(res); + } + + DeltaSubN = perturbationFunction(DeltaSubN, DeltaSub0, RefIteration); + + RefIteration++; + float_exp_iterations++; + + zold2.assign(zold); + zold.assign(complex[0]); + zoldDeep = z; + + if (max_iterations > 1) { + refZm = getArrayDeepValue(referenceDeep, RefIteration); + zWithoutInitVal = getArrayDeepValue(referenceDeepData.ReferenceSubCp, RefIteration, refZm).plus_mutable(DeltaSubN); + z = refZm.plus_mutable(DeltaSubN); + complex[0] = z.toComplex(); + } + + if (statistic != null) { + statistic.insert(complex[0], zold, zold2, iterations, complex[1], start, c0, z, zoldDeep, cDeep); + } + + if (zWithoutInitVal.norm_squared().compareToBothPositive(DeltaSubN.norm_squared()) < 0 || RefIteration >= MaxRefIteration) { + DeltaSubN = zWithoutInitVal; + RefIteration = 0; + rebases++; + } + + DeltaSubN.Normalize(); + + if(!useFullFloatExp) { + if (DeltaSubN.getMinExp() > reducedExp) { + iterations++; + break; + } + } + } + } + + if(!useFullFloatExp) { + Complex CDeltaSubN = DeltaSubN.toComplex(); + Complex CDeltaSub0 = DeltaSub0.toComplex(); + + boolean isZero = CDeltaSub0.isZero(); + Complex zWithoutInitVal = new Complex(); + + Complex refZ; + + if(!usedDeepCode && iterations != 0 && RefIteration < MaxRefIteration) { + refZ = getArrayValue(reference, RefIteration); + zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration, refZ).plus_mutable(CDeltaSubN); + complex[0] = refZ.plus_mutable(CDeltaSubN); + } + else if(!usedDeepCode && iterations != 0 && ReferencePeriod != 0) { + RefIteration = RefIteration % ReferencePeriod; + refZ = getArrayValue(reference, RefIteration); + zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration, refZ).plus_mutable(CDeltaSubN); + complex[0] = refZ.plus_mutable(CDeltaSubN); + } + + for (; iterations < max_iterations; iterations++) { + + //No update values + + if (trap != null) { + trap.check(complex[0], iterations); + } + + if (bailout_algorithm.escaped(complex[0], zold, zold2, iterations, complex[1], start, c0, 0.0, pixel)) { + escaped = true; + + Object[] object = {iterations, complex[0], zold, zold2, complex[1], start, c0, pixel}; + double res = out_color_algorithm.getResult(object); + + res = getFinalValueOut(res, complex[0]); + + if (outTrueColorAlgorithm != null) { + setTrueColorOut(complex[0], zold, zold2, iterations, complex[1], start, c0, pixel); + } + + return getAndAccumulateStatsNotScaled(res); + } + + if (isZero) { + CDeltaSubN = perturbationFunction(CDeltaSubN, RefIteration); + } else { + CDeltaSubN = perturbationFunction(CDeltaSubN, CDeltaSub0, RefIteration); + } + + RefIteration++; + double_iterations++; + + zold2.assign(zold); + zold.assign(complex[0]); + + //No Plane influence work + //No Pre filters work + if (max_iterations > 1) { + refZ = getArrayValue(reference, RefIteration); + zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration, refZ).plus_mutable(CDeltaSubN); + complex[0] = refZ.plus_mutable(CDeltaSubN); + } + //No Post filters work + + if (statistic != null) { + statistic.insert(complex[0], zold, zold2, iterations, complex[1], start, c0); + } + + if (zWithoutInitVal.norm_squared() < CDeltaSubN.norm_squared() || RefIteration >= MaxRefIteration) { + CDeltaSubN = zWithoutInitVal; + RefIteration = 0; + rebases++; + } + + } + } + + Object[] object = {complex[0], zold, zold2, complex[1], start, c0, pixel}; + double in = in_color_algorithm.getResult(object); + + in = getFinalValueIn(in, complex[0]); + + if (inTrueColorAlgorithm != null) { + setTrueColorIn(complex[0], zold, zold2, iterations, complex[1], start, c0, pixel); + } + + return getAndAccumulateStatsNotScaled(in); + + } + + @Override + public double iterateJuliaWithPerturbation(Complex[] complex, Complex dpixel) { + + double_iterations = 0; + rebases = 0; + + iterations = 0; + + int RefIteration = iterations; + + Complex[] deltas = initializePerturbation(dpixel); + Complex DeltaSubN = deltas[0]; // Delta z + + Complex pixel = dpixel.plus(refPointSmall); + + ReferenceData data = referenceData; + int MaxRefIteration = data.MaxRefIteration; + + Complex zWithoutInitVal = new Complex(); + + Complex refZ; + + for (; iterations < max_iterations; iterations++) { + + //No update values + + if (trap != null) { + trap.check(complex[0], iterations); + } + + if (bailout_algorithm.escaped(complex[0], zold, zold2, iterations, complex[1], start, c0, 0.0, pixel)) { + escaped = true; + + Object[] object = {iterations, complex[0], zold, zold2, complex[1], start, c0, pixel}; + double res = out_color_algorithm.getResult(object); + + res = getFinalValueOut(res, complex[0]); + + if (outTrueColorAlgorithm != null) { + setTrueColorOut(complex[0], zold, zold2, iterations, complex[1], start, c0, pixel); + } + + return getAndAccumulateStatsNotDeep(res); + } + + DeltaSubN = perturbationFunction(DeltaSubN, data, RefIteration); + + RefIteration++; + double_iterations++; + + zold2.assign(zold); + zold.assign(complex[0]); + + //No Plane influence work + //No Pre filters work + if(max_iterations > 1) { + refZ = getArrayValue(data.Reference, RefIteration); + zWithoutInitVal = getArrayValue(data.ReferenceSubCp, RefIteration, refZ).plus_mutable(DeltaSubN); + complex[0] = refZ.plus_mutable(DeltaSubN); + } + //No Post filters work + + if (statistic != null) { + statistic.insert(complex[0], zold, zold2, iterations, complex[1], start, c0); + } + + if (zWithoutInitVal.norm_squared() < DeltaSubN.norm_squared() || RefIteration >= MaxRefIteration) { + DeltaSubN = zWithoutInitVal; + RefIteration = 0; + + data = secondReferenceData; + MaxRefIteration = data.MaxRefIteration; + rebases++; + } + } + + Object[] object = {complex[0], zold, zold2, complex[1], start, c0, pixel}; + double in = in_color_algorithm.getResult(object); + + in = getFinalValueIn(in, complex[0]); + + if (inTrueColorAlgorithm != null) { + setTrueColorIn(complex[0], zold, zold2, iterations, complex[1], start, c0, pixel); + } + + return getAndAccumulateStatsNotDeep(in); + + } + + @Override + public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpixel) { + + float_exp_iterations = 0; + double_iterations = 0; + rebases = 0; + + int totalSkippedIterations = 0; + + iterations = 0; + + int RefIteration = iterations; + + MantExpComplex[] deltas = initializePerturbation(dpixel); + MantExpComplex DeltaSubN = deltas[0]; // Delta z + + MantExpComplex cDeep = dpixel.plus(refPointSmallDeep); + Complex pixel = cDeep.toComplex(); + + ReferenceDeepData deepData = referenceDeepData; + ReferenceData data = referenceData; + int MaxRefIteration = data.MaxRefIteration; + + int minExp = -1000; + int reducedExp = minExp / (int)getPower(); + + MantExpComplex refZm; + + DeltaSubN.Normalize(); + long exp = DeltaSubN.getMinExp(); + + boolean useFullFloatExp = useFullFloatExp(); + boolean doBailCheck = useFullFloatExp || TaskDraw.CHECK_BAILOUT_DURING_DEEP_NOT_FULL_FLOATEXP_MODE; + + if(useFullFloatExp || (totalSkippedIterations == 0 && exp <= minExp) || (totalSkippedIterations != 0 && exp <= reducedExp)) { + MantExpComplex zWithoutInitVal = MantExpComplex.create(); + MantExpComplex z = getArrayDeepValue(deepData.Reference, RefIteration).plus_mutable(DeltaSubN); + MantExpComplex zoldDeep; + + for (; iterations < max_iterations; iterations++) { + if (trap != null) { + trap.check(complex[0], iterations); + } + + if (doBailCheck && bailout_algorithm.escaped(complex[0], zold, zold2, iterations, complex[1], start, c0, 0.0, pixel)) { + escaped = true; + + Object[] object = {iterations, complex[0], zold, zold2, complex[1], start, c0, pixel}; + double res = out_color_algorithm.getResult(object); + + res = getFinalValueOut(res, complex[0]); + + if (outTrueColorAlgorithm != null) { + setTrueColorOut(complex[0], zold, zold2, iterations, complex[1], start, c0, pixel); + } + + return getAndAccumulateStatsNotScaled(res); + } + + DeltaSubN = perturbationFunction(DeltaSubN, deepData, RefIteration); + + RefIteration++; + float_exp_iterations++; + + zold2.assign(zold); + zold.assign(complex[0]); + zoldDeep = z; + + if (max_iterations > 1) { + refZm = getArrayDeepValue(deepData.Reference, RefIteration); + zWithoutInitVal = getArrayDeepValue(deepData.ReferenceSubCp, RefIteration, refZm).plus_mutable(DeltaSubN); + z = refZm.plus_mutable(DeltaSubN); + complex[0] = z.toComplex(); + } + + if (statistic != null) { + statistic.insert(complex[0], zold, zold2, iterations, complex[1], start, c0, z, zoldDeep , cDeep); + } + + if (zWithoutInitVal.norm_squared().compareToBothPositive(DeltaSubN.norm_squared()) < 0 || RefIteration >= MaxRefIteration) { + DeltaSubN = zWithoutInitVal; + RefIteration = 0; + + deepData = secondReferenceDeepData; + data = secondReferenceData; + MaxRefIteration = data.MaxRefIteration; + + rebases++; + } + + DeltaSubN.Normalize(); + + if(!useFullFloatExp) { + if (DeltaSubN.getMinExp() > reducedExp) { + iterations++; + break; + } + } + } + } + + if(!useFullFloatExp) { + Complex CDeltaSubN = DeltaSubN.toComplex(); + + Complex zWithoutInitVal = new Complex(); + + Complex refZ; + + for (; iterations < max_iterations; iterations++) { + + //No update values + + if (trap != null) { + trap.check(complex[0], iterations); + } + + if (bailout_algorithm.escaped(complex[0], zold, zold2, iterations, complex[1], start, c0, 0.0, pixel)) { + escaped = true; + + Object[] object = {iterations, complex[0], zold, zold2, complex[1], start, c0, pixel}; + double res = out_color_algorithm.getResult(object); + + res = getFinalValueOut(res, complex[0]); + + if (outTrueColorAlgorithm != null) { + setTrueColorOut(complex[0], zold, zold2, iterations, complex[1], start, c0, pixel); + } + + return getAndAccumulateStatsNotScaled(res); + } + + CDeltaSubN = perturbationFunction(CDeltaSubN, data, RefIteration); + + RefIteration++; + double_iterations++; + + zold2.assign(zold); + zold.assign(complex[0]); + + //No Plane influence work + //No Pre filters work + if (max_iterations > 1) { + refZ = getArrayValue(data.Reference, RefIteration); + zWithoutInitVal = getArrayValue(data.ReferenceSubCp, RefIteration, refZ).plus_mutable(CDeltaSubN); + complex[0] = refZ.plus_mutable(CDeltaSubN); + } + //No Post filters work + + if (statistic != null) { + statistic.insert(complex[0], zold, zold2, iterations, complex[1], start, c0); + } + + if (zWithoutInitVal.norm_squared() < CDeltaSubN.norm_squared() || RefIteration >= MaxRefIteration) { + CDeltaSubN = zWithoutInitVal; + RefIteration = 0; + + data = secondReferenceData; + MaxRefIteration = data.MaxRefIteration; + rebases++; + } + + } + } + + Object[] object = {complex[0], zold, zold2, complex[1], start, c0, pixel}; + double in = in_color_algorithm.getResult(object); + + in = getFinalValueIn(in, complex[0]); + + if (inTrueColorAlgorithm != null) { + setTrueColorIn(complex[0], zold, zold2, iterations, complex[1], start, c0, pixel); + } + + return getAndAccumulateStatsNotScaled(in); + + } + + @Override + protected GenericComplex[] precalculateReferenceData(GenericComplex z, GenericComplex c, NormComponents normData, Location loc, int bigNumLib, boolean lowPrecReferenceOrbitNeeded, boolean deepZoom, ReferenceData referenceData, ReferenceDeepData referenceDeepData, int iterations, Complex cz, MantExpComplex mcz) { + + GenericComplex preCalc; + + //5*Z^4 - 1 + if (bigNumLib == Constants.BIGNUM_APFLOAT) { + preCalc = z.fourth().times(MyApfloat.FIVE).sub(MyApfloat.ONE); + } + else { + preCalc = z.fourth().times_mutable(5).sub_mutable(1); + } + + GenericComplex preCalc2; + + //2*Z*(Z^4 - 1) + if (bigNumLib == Constants.BIGNUM_APFLOAT) { + preCalc2 = z.fourth().sub(MyApfloat.ONE).times(z).times2(); + } + else { + preCalc2 = z.fourth().sub_mutable(1).times_mutable(z).times2_mutable(); + } + + MantExpComplex precalcm = null; + MantExpComplex precalcm2 = null; + if(deepZoom) { + precalcm = loc.getMantExpComplex(preCalc); + precalcm2 = loc.getMantExpComplex(preCalc2); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], iterations, precalcm, mcz); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], iterations, precalcm2, mcz); + } + if(lowPrecReferenceOrbitNeeded) { + setArrayValue(referenceData.PrecalculatedTerms[0], iterations, deepZoom ? precalcm.toComplex() : preCalc.toComplex(), cz); + } + if(lowPrecReferenceOrbitNeeded) { + setArrayValue(referenceData.PrecalculatedTerms[1], iterations, deepZoom ? precalcm2.toComplex() : preCalc2.toComplex(), cz); + } + + return new GenericComplex[] {}; + } + + @Override + protected int[] getNeededPrecalculatedTermsIndexes() { + + return new int[] {0, 1}; + + } + + @Override + protected Function[] getPrecalculatedTermsFunctions(Complex c) { + Function f1 = x -> x.fourth().times_mutable(5).sub_mutable(1); + Function f2 = x -> x.fourth().sub_mutable(1).times_mutable(x).times2_mutable(); + return new Function[] {f1, f2}; + } + + @Override + protected Function[] getPrecalculatedTermsFunctionsDeep(MantExpComplex c) { + Function f1 = x -> x.fourth().times_mutable(MantExp.FIVE).sub_mutable(MantExp.ONE); + Function f2 = x -> x.fourth().sub_mutable(MantExp.ONE).times_mutable(x).times2_mutable(); + return new Function[] {f1, f2}; + } + + @Override + public boolean supportsPerturbationTheory() { + if(isJuliaMap) { + return false; + } + return !isJulia || !juliter; + } + @Override + public double getDoubleLimit() { + return 1.0e-5; + } + + @Override + public double getDoubleDoubleLimit() { + return 1.0e-12; + } + + @Override + public String getRefType() { + return super.getRefType() + (isJulia ? "-Julia-" + bigSeed.toStringPretty() : ""); + } + + @Override + public void function(GenericComplex[] complex) { + + if(complex[0].isZero()) { + throw new ArithmeticException("Division by zero"); + } + + complex[0] = complex[0].square_mutable(); + complex[0] = (complex[0].plus_mutable(complex[0].reciprocal())).times_mutable(complex[1]); + + } + + /* + (C * (((z + 4*Z)*z^3)*Z^2 + ((5*Z^4 - 1)*z + 2*Z*(Z^4 - 1))*z) + + c * (((z + 4*Z)*z^3)*Z^2 + ((2*(3*z + 2*Z)*z + Z^2)*Z^2 + 1)*Z^2)) + / (Z^2 + (2*Z + z)*z) * Z^2 + */ + + @Override + public Complex perturbationFunction(Complex z, Complex c, int RefIteration) { + + Complex Z = getArrayValue(reference, RefIteration); + Complex Zsqr = Z.square(); + Complex Z2 = Z.times2(); + + Complex temp = z.plus(Z.times4()).times_mutable(z.cube()).times_mutable(Zsqr); + + Complex nom = C.times(temp.plus(getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration, Z).times_mutable(z).plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration, Z)).times_mutable(z))) + .plus_mutable(c.times(temp.plus(z.times(3).plus_mutable(Z2).times_mutable(z).times2_mutable().plus_mutable(Zsqr).times_mutable(Zsqr).plus_mutable(1).times_mutable(Zsqr)))); + + Complex denom = Zsqr.plus(Z2.plus(z).times_mutable(z)).times_mutable(Zsqr); + + return nom.divide_mutable(denom); + + + } + + @Override + public MantExpComplex perturbationFunction(MantExpComplex z, MantExpComplex c, int RefIteration) { + + MantExpComplex Z = getArrayDeepValue(referenceDeep, RefIteration); + MantExpComplex Zsqr = Z.square(); + MantExpComplex Z2 = Z.times2(); + + MantExpComplex temp = z.plus(Z.times4()).times_mutable(z.cube()).times_mutable(Zsqr); + + MantExpComplex nom = Cdeep.times(temp.plus(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration, Z).times_mutable(z).plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration, Z)).times_mutable(z))) + .plus_mutable(c.times(temp.plus(z.times(MantExp.THREE).plus_mutable(Z2).times_mutable(z).times2_mutable().plus_mutable(Zsqr).times_mutable(Zsqr).plus_mutable(MantExp.ONE).times_mutable(Zsqr)))); + + MantExpComplex denom = Zsqr.plus(Z2.plus(z).times_mutable(z)).times_mutable(Zsqr); + + return nom.divide_mutable(denom); + } + + @Override + public Complex perturbationFunction(Complex z, int RefIteration) { + + Complex Z = getArrayValue(reference, RefIteration); + Complex Zsqr = Z.square(); + Complex Z2 = Z.times2(); + + Complex temp = z.plus(Z.times4()).times_mutable(z.cube()).times_mutable(Zsqr); + + Complex nom = C.times(temp.plus(getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration, Z).times_mutable(z).plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration, Z)).times_mutable(z))); + + Complex denom = Zsqr.plus(Z2.plus(z).times_mutable(z)).times_mutable(Zsqr); + + return nom.divide_mutable(denom); + + } + + @Override + public MantExpComplex perturbationFunction(MantExpComplex z, int RefIteration) { + + MantExpComplex Z = getArrayDeepValue(referenceDeep, RefIteration); + MantExpComplex Zsqr = Z.square(); + MantExpComplex Z2 = Z.times2(); + + MantExpComplex temp = z.plus(Z.times4()).times_mutable(z.cube()).times_mutable(Zsqr); + + MantExpComplex nom = Cdeep.times(temp.plus(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration, Z).times_mutable(z).plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration, Z)).times_mutable(z))); + + MantExpComplex denom = Zsqr.plus(Z2.plus(z).times_mutable(z)).times_mutable(Zsqr); + + return nom.divide_mutable(denom); + } + + @Override + public Complex perturbationFunction(Complex z, ReferenceData data, int RefIteration) { + + Complex Z = getArrayValue(data.Reference, RefIteration); + Complex Zsqr = Z.square(); + Complex Z2 = Z.times2(); + + Complex temp = z.plus(Z.times4()).times_mutable(z.cube()).times_mutable(Zsqr); + + Complex nom = C.times(temp.plus(getArrayValue(data.PrecalculatedTerms[0], RefIteration, Z).times_mutable(z).plus_mutable(getArrayValue(data.PrecalculatedTerms[1], RefIteration, Z)).times_mutable(z))); + + Complex denom = Zsqr.plus(Z2.plus(z).times_mutable(z)).times_mutable(Zsqr); + + return nom.divide_mutable(denom); + } + + @Override + public MantExpComplex perturbationFunction(MantExpComplex z, ReferenceDeepData data, int RefIteration) { + + MantExpComplex Z = getArrayDeepValue(data.Reference, RefIteration); + MantExpComplex Zsqr = Z.square(); + MantExpComplex Z2 = Z.times2(); + + MantExpComplex temp = z.plus(Z.times4()).times_mutable(z.cube()).times_mutable(Zsqr); + + MantExpComplex nom = Cdeep.times(temp.plus(getArrayDeepValue(data.PrecalculatedTerms[0], RefIteration, Z).times_mutable(z).plus_mutable(getArrayDeepValue(data.PrecalculatedTerms[1], RefIteration, Z)).times_mutable(z))); + + MantExpComplex denom = Zsqr.plus(Z2.plus(z).times_mutable(z)).times_mutable(Zsqr); + + return nom.divide_mutable(denom); + } + + + @Override + public boolean supportsBigIntnum() { + return true; + } + + @Override + public boolean supportsMpfrBignum() { return true;} + + @Override + public boolean supportsMpirBignum() { return true;} + + + @Override + protected boolean needsRefSubCp() { + return true; + } + + @Override + protected void calculateRefSubCp(GenericComplex z, GenericComplex initVal, Location loc, int bigNumLib, boolean lowPrecReferenceOrbitNeeded, boolean deepZoom, ReferenceData referenceData, ReferenceDeepData referenceDeepData, int iterations, Complex cz, MantExpComplex mcz) { + + GenericComplex zsubcp; + if(bigNumLib == Constants.BIGNUM_MPFR) { + zsubcp = z.sub(initVal, workSpaceData.temp1, workSpaceData.temp2); + } + else if(bigNumLib == Constants.BIGNUM_MPIR) { + zsubcp = z.sub(initVal, workSpaceData.temp1p, workSpaceData.temp2p); + } + else { + zsubcp = z.sub(initVal); + } + + MantExpComplex zsubcpm = null; + if(deepZoom) { + zsubcpm = loc.getMantExpComplex(zsubcp); + setArrayDeepValue(referenceDeepData.ReferenceSubCp, iterations, zsubcpm, mcz); + } + + if(lowPrecReferenceOrbitNeeded) { + setArrayValue(referenceData.ReferenceSubCp, iterations, deepZoom ? zsubcpm.toComplex() : zsubcp.toComplex(), cz); + } + + } + + @Override + protected GenericComplex referenceFunction(GenericComplex z, GenericComplex c, NormComponents normData, GenericComplex[] initialPrecal, GenericComplex[] precalc) { + if(z.isZero()) { + throw new ArithmeticException("Division by zero"); + } + z = z.square_mutable(); + return (z.plus_mutable(z.reciprocal())).times_mutable(c); + } + + @Override + public boolean supportsReferenceCompression() { + return true; + } + + @Override + public Complex function(Complex z, Complex c) { + z.square_mutable(); + return (z.plus_mutable(z.reciprocal())).times_mutable(c); + } + + @Override + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + z.square_mutable(); + return (z.plus_mutable(z.reciprocal())).times_mutable(c); + } + + @Override + protected GenericComplex getInputPixel(GenericComplex inputPixel) { + if(isJulia) { + return sanitizeInputPixel(inputPixel); + } + return inputPixel; + } + + @Override + public double getPower() { + return 4; + } +} diff --git a/src/fractalzoomer/functions/general/NewtonThirdDegreeParameterSpace.java b/src/fractalzoomer/functions/general/NewtonThirdDegreeParameterSpace.java index 9fa819ea0..c790f71f0 100644 --- a/src/fractalzoomer/functions/general/NewtonThirdDegreeParameterSpace.java +++ b/src/fractalzoomer/functions/general/NewtonThirdDegreeParameterSpace.java @@ -17,6 +17,7 @@ import javax.swing.*; import java.util.ArrayList; +import java.util.function.Function; import static fractalzoomer.main.Constants.*; @@ -37,7 +38,6 @@ public NewtonThirdDegreeParameterSpace(double xCenter, double yCenter, double si setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); - power = 3; defaultInitVal = new DefaultInitialValueWithFactor(1.0 / 3.0); if (init_value) { @@ -79,13 +79,11 @@ public NewtonThirdDegreeParameterSpace(double xCenter, double yCenter, double si switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } @@ -98,7 +96,6 @@ public NewtonThirdDegreeParameterSpace(double xCenter, double yCenter, double si StatisticFactory(sts, plane_transform_center); } - power = 3; defaultInitVal = new DefaultInitialValueWithFactor(1.0 / 3.0); pertur_val = new DefaultPerturbation(); init_val = defaultInitVal; @@ -111,7 +108,6 @@ public NewtonThirdDegreeParameterSpace(double xCenter, double yCenter, double si setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); - power = 3; defaultInitVal = new DefaultInitialValueWithFactor(1.0 / 3.0); if (init_value) { @@ -133,7 +129,6 @@ public NewtonThirdDegreeParameterSpace(double xCenter, double yCenter, double si public NewtonThirdDegreeParameterSpace(double xCenter, double yCenter, double size, int max_iterations, ArrayList complex_orbit, int plane_type, boolean apply_plane_on_julia, boolean apply_plane_on_julia_seed, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, double xJuliaCenter, double yJuliaCenter) { super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); - power = 3; defaultInitVal = new DefaultInitialValueWithFactor(1.0 / 3.0); pertur_val = new DefaultPerturbation(); init_val = defaultInitVal; @@ -163,6 +158,94 @@ public String getRefType() { return super.getRefType() + (isJulia ? "-Julia-" + bigSeed.toStringPretty() : ""); } + @Override + protected int[] getNeededPrecalculatedTermsIndexes() { + if(!isJulia) { + return new int[] {0, 1, 2, 3, 4, 5, 6, 7}; + } + return new int[] {0, 1, 2, 3, 4}; + } + + @Override + protected Function[] getPrecalculatedTermsFunctions(Complex c) { + + Complex c4 = c.times4(); + Complex csqr = c.square(); + Complex csqrs3 = csqr.sub(3); + Complex csqr2s3 = csqr.times2().sub_mutable(3); + Complex c2 = c.times2(); + + Function f1 = x -> { + Complex zsqr = x.square(); + return c4.times(x).sub_mutable(zsqr.times(3)).sub_mutable(csqrs3).times_mutable(zsqr).plus_mutable(csqr).sub_mutable(c4.times(x));}; + + Function f2 = x -> c.sub(x).times_mutable(x).times_mutable(9).sub_mutable(csqr2s3).times_mutable(x).sub_mutable(c);; + + Function f3 = x -> c2.times(x).sub(x.square().times_mutable(3)).plus_mutable(1); + + Function f4 = x -> { + Complex zsqr = x.square(); + Complex c4z = c4.times(x); + return c4z.sub(zsqr.times(3)).times_mutable(3).sub_mutable(csqr2s3.times2()).times_mutable(zsqr).sub_mutable(c4z).sub_mutable(1); + }; + + Function f5 = x -> c.sub(x).times_mutable(x).times(12).sub_mutable(csqrs3.times2()).times_mutable(x).sub_mutable(c4); + if(!isJulia) { + Function f6 = x -> c.sub(x).times_mutable(x).plus_mutable(1).times_mutable(x).sub(c); + + Function f7 = x -> c2.times(x).sub(x.square().times_mutable(3).sub_mutable(1)).times_mutable(x); + Function f8 = x -> { + Complex zsqr = x.square(); + return zsqr.sub(2).times_mutable(zsqr).plus_mutable(1); + }; + + return new Function[] {f1, f2, f3, f4, f5, f6, f7, f8}; + } + return new Function[] {f1, f2, f3, f4, f5}; + } + + @Override + protected Function[] getPrecalculatedTermsFunctionsDeep(MantExpComplex c) { + MantExpComplex c4 = c.times4(); + c4.Normalize(); + MantExpComplex csqr = c.square(); + csqr.Normalize(); + MantExpComplex csqrs3 = csqr.sub(MantExp.THREE); + csqrs3.Normalize(); + MantExpComplex csqr2s3 = csqr.times2().sub_mutable(MantExp.THREE); + csqr2s3.Normalize(); + MantExpComplex c2 = c.times2(); + c2.Normalize(); + + Function f1 = x -> { + MantExpComplex zsqr = x.square(); + return c4.times(x).sub_mutable(zsqr.times(MantExp.THREE)).sub_mutable(csqrs3).times_mutable(zsqr).plus_mutable(csqr).sub_mutable(c4.times(x));}; + + Function f2 = x -> c.sub(x).times_mutable(x).times_mutable(MantExp.NINE).sub_mutable(csqr2s3).times_mutable(x).sub_mutable(c);; + + Function f3 = x -> c2.times(x).sub(x.square().times_mutable(MantExp.THREE)).plus_mutable(MantExp.ONE); + + Function f4 = x -> { + MantExpComplex zsqr = x.square(); + MantExpComplex c4z = c4.times(x); + return c4z.sub(zsqr.times(MantExp.THREE)).times_mutable(MantExp.THREE).sub_mutable(csqr2s3.times2()).times_mutable(zsqr).sub_mutable(c4z).sub_mutable(MantExp.ONE); + }; + + Function f5 = x -> c.sub(x).times_mutable(x).times(MantExp.TWELVE).sub_mutable(csqrs3.times2()).times_mutable(x).sub_mutable(c4); + if(!isJulia) { + Function f6 = x -> c.sub(x).times_mutable(x).plus_mutable(MantExp.ONE).times_mutable(x).sub(c); + + Function f7 = x -> c2.times(x).sub(x.square().times_mutable(MantExp.THREE).sub_mutable(MantExp.ONE)).times_mutable(x); + Function f8 = x -> { + MantExpComplex zsqr = x.square(); + return zsqr.sub(MantExp.TWO).times_mutable(zsqr).plus_mutable(MantExp.ONE); + }; + + return new Function[] {f1, f2, f3, f4, f5, f6, f7, f8}; + } + return new Function[] {f1, f2, f3, f4, f5}; + } + @Override public void calculateReferencePoint(GenericComplex inputPixel, Apfloat size, boolean deepZoom, int[] Iterations, int[] juliaIterations, Location externalLocation, JProgressBar progress) { @@ -185,28 +268,20 @@ public void calculateReferencePoint(GenericComplex inputPixel, Apfloat size, boo boolean lowPrecReferenceOrbitNeeded = !needsOnlyExtendedReferenceOrbit(deepZoom, false); DoubleReference.SHOULD_SAVE_MEMORY = false; + boolean useCompressedRef = TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE && supportsReferenceCompression(); + int[] preCalcIndexes = getNeededPrecalculatedTermsIndexes(); if(iterations == 0) { if(lowPrecReferenceOrbitNeeded) { - if(!isJulia) { - referenceData.createAndSetShortcut(max_ref_iterations, true, 8); - } - else { - referenceData.createAndSetShortcut(max_ref_iterations, true, 5); - } + referenceData.createAndSetShortcut(max_ref_iterations, true, preCalcIndexes, useCompressedRef); } else { referenceData.deallocate(); } if (deepZoom) { - if(!isJulia) { - referenceDeepData.createAndSetShortcut(max_ref_iterations, true, 8); - } - else { - referenceDeepData.createAndSetShortcut(max_ref_iterations, true, 5); - } + referenceDeepData.createAndSetShortcut(max_ref_iterations, true, preCalcIndexes, useCompressedRef); } } else if (max_ref_iterations > getReferenceLength()){ @@ -300,12 +375,6 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { refPoint = inputPixel; - refPointSmall = refPoint.toComplex(); - - if(lowPrecReferenceOrbitNeeded) { - C = c.toComplex(); - } - c4big = c.times4(); c2big = c.times2(); csqrbig = c.square(); @@ -327,24 +396,75 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { if(deepZoom) { refPointSmallDeep = loc.getMantExpComplex(refPoint); Cdeep = loc.getMantExpComplex(c); + + if(isJulia) { + seedSmallDeep = loc.getMantExpComplex(c); + } + + refPointSmall = refPointSmallDeep.toComplex(); + + if(lowPrecReferenceOrbitNeeded) { + C = Cdeep.toComplex(); + } + + if(lowPrecReferenceOrbitNeeded && isJulia) { + seedSmall = seedSmallDeep.toComplex(); + } } + else { + refPointSmall = refPoint.toComplex(); - RefType = getRefType(); + if(lowPrecReferenceOrbitNeeded) { + C = c.toComplex(); + } - convergent_bailout_algorithm.setReferenceMode(true); + if(lowPrecReferenceOrbitNeeded && isJulia) { + seedSmall = c.toComplex(); + } + } - calculatedReferenceIterations = 0; + RefType = getRefType(); - for (; iterations < max_ref_iterations; iterations++, calculatedReferenceIterations++) { + convergent_bailout_algorithm.setReferenceMode(true); + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[referenceDeep.id] = new ReferenceCompressor(this, iterations == 0 ? z.toMantExpComplex() : referenceData.compressorZm, c.toMantExpComplex(), start.toMantExpComplex()); + + MantExpComplex cp = initVal.toMantExpComplex(); + Function f = x -> x.sub(cp); + functions[referenceDeepData.ReferenceSubCp.id] = f; + subexpressionsCompressor[referenceDeepData.ReferenceSubCp.id] = new ReferenceCompressor(f, true); + + Function[] fs = getPrecalculatedTermsFunctionsDeep(c.toMantExpComplex()); + for(int i = 0; i < preCalcIndexes.length; i++) { + int id = referenceDeepData.PrecalculatedTerms[preCalcIndexes[i]].id; + functions[id] = fs[i]; + subexpressionsCompressor[id] = new ReferenceCompressor(fs[i], true); + } + } if(lowPrecReferenceOrbitNeeded) { - Complex cz = z.toComplex(); - if (cz.isInfinite()) { - break; + referenceCompressor[reference.id] = new ReferenceCompressor(this, iterations == 0 ? z.toComplex() : referenceData.compressorZ, c.toComplex(), start.toComplex()); + + Complex cp = initVal.toComplex(); + Function f = x -> x.sub(cp); + functions[referenceData.ReferenceSubCp.id] = f; + subexpressionsCompressor[referenceData.ReferenceSubCp.id] = new ReferenceCompressor(f); + + Function[] fs = getPrecalculatedTermsFunctions(c.toComplex()); + for(int i = 0; i < preCalcIndexes.length; i++) { + int id = referenceData.PrecalculatedTerms[preCalcIndexes[i]].id; + functions[id] = fs[i]; + subexpressionsCompressor[id] = new ReferenceCompressor(fs[i]); } - - setArrayValue(reference, iterations, cz); } + } + + calculatedReferenceIterations = 0; + MantExpComplex tempmcz = null; + Complex cz = null; + + for (; iterations < max_ref_iterations; iterations++, calculatedReferenceIterations++) { GenericComplex zsubcp; if(bigNumLib == Constants.BIGNUM_MPFR) { @@ -357,13 +477,6 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { zsubcp = z.sub(initVal); } - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.ReferenceSubCp, iterations, zsubcp.toComplex()); - } - if(deepZoom) { - setArrayDeepValue(referenceDeepData.ReferenceSubCp, iterations, loc.getMantExpComplex(zsubcp)); - } - GenericComplex zsqr = z.square(); GenericComplex zsqr3; @@ -381,10 +494,6 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { GenericComplex c4zSzsqr3 = c4z.sub(zsqr3); GenericComplex preCalc = c4zSzsqr3.sub(csqrs3big).times_mutable(zsqr).plus_mutable(csqrbig).sub_mutable(c4z); - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[0], iterations, preCalc.toComplex()); - } - GenericComplex csztz = c.sub(z).times_mutable(z); GenericComplex preCalc2; // 9*C*Z^2 - 9*Z^3 - (2*C^2 - 3)*Z- C for catastrophic cancelation @@ -395,11 +504,6 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { preCalc2 = csztz.times(MyApfloat.NINE).sub(csqr2s3big).times(z).sub(c); } - - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[1], iterations, preCalc2.toComplex()); - } - GenericComplex c2z = c2big.times(z); GenericComplex preCalc3; if(bigNumLib != Constants.BIGNUM_APFLOAT) { @@ -408,11 +512,6 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { else { preCalc3 = c2z.sub(zsqr3).plus(MyApfloat.ONE); } - - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[2], iterations, preCalc3.toComplex()); - } - GenericComplex preCalc4; if(bigNumLib != Constants.BIGNUM_APFLOAT) { @@ -422,10 +521,6 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { preCalc4 = c4zSzsqr3.times(MyApfloat.THREE).sub(csqr2s3big.times2()).times(zsqr).sub(c4z).sub(MyApfloat.ONE); } - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[3], iterations, preCalc4.toComplex()); - } - //12*(C*Z^2 - Z^3)-2*(C^2-3)*Z -4*C GenericComplex preCalc5; @@ -436,10 +531,6 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { preCalc5 = csztz.times(MyApfloat.TWELVE).sub(csqrs3big.times2()).times(z).sub(c4big); } - if (lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[4], iterations, preCalc5.toComplex()); - } - GenericComplex zsqr3s1; if (bigNumLib != Constants.BIGNUM_APFLOAT) { zsqr3s1 = zsqr3.sub(1); @@ -448,53 +539,87 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { zsqr3s1 = zsqr3.sub(MyApfloat.ONE); } + GenericComplex preCalc7 = null; + GenericComplex preCalc8 = null; + GenericComplex preCalc6 = null; if(!isJulia) { ////C*Z^2-Z^3-C+Z - GenericComplex preCalc6; if (bigNumLib != Constants.BIGNUM_APFLOAT) { preCalc6 = csztz.plus(1).times_mutable(z).sub(c); } else { preCalc6 = csztz.plus(MyApfloat.ONE).times(z).sub(c); } - if (lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[5], iterations, preCalc6.toComplex()); - } - //2*C*Z^2 + (-3*Z^2+1)*Z - GenericComplex preCalc7 = c2z.sub(zsqr3s1).times_mutable(z); - - if (lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[6], iterations, preCalc7.toComplex()); - } + preCalc7 = c2z.sub(zsqr3s1).times_mutable(z); ////(Z^2-2)*Z^2 + 1 - GenericComplex preCalc8; - if (bigNumLib != Constants.BIGNUM_APFLOAT) { preCalc8 = zsqr.sub(2).times_mutable(zsqr).plus_mutable(1); } else { preCalc8 = zsqr.sub(MyApfloat.TWO).times(zsqr).plus(MyApfloat.ONE); } + } - if (lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[7], iterations, preCalc8.toComplex()); + MantExpComplex zsubcpm = null, czm = null; + MantExpComplex precalm = null, precal2m = null, precal3m = null, precal4m = null, precal5m = null; + MantExpComplex precal6m = null, precal7m = null, precal8m = null; + if(deepZoom) { + czm = loc.getMantExpComplex(z); + if (czm.isInfinite() || czm.isNaN()) { + break; } + tempmcz = setArrayDeepValue(referenceDeep, iterations, czm); + } - if(deepZoom) { - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[5], iterations, loc.getMantExpComplex(preCalc6)); - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[6], iterations, loc.getMantExpComplex(preCalc7)); - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[7], iterations, loc.getMantExpComplex(preCalc8)); + if(lowPrecReferenceOrbitNeeded) { + cz = deepZoom ? czm.toComplex() : z.toComplex(); + if (cz.isInfinite() || cz.isNaN()) { + break; } + + cz = setArrayValue(reference, iterations, cz); } + czm = tempmcz; + if(deepZoom) { - setArrayDeepValue(referenceDeep, iterations, loc.getMantExpComplex(z)); - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], iterations, loc.getMantExpComplex(preCalc)); - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], iterations, loc.getMantExpComplex(preCalc2)); - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[2], iterations, loc.getMantExpComplex(preCalc3)); - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[3], iterations, loc.getMantExpComplex(preCalc4)); - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[4], iterations, loc.getMantExpComplex(preCalc5)); + zsubcpm = loc.getMantExpComplex(zsubcp); + precalm = loc.getMantExpComplex(preCalc); + precal2m = loc.getMantExpComplex(preCalc2); + precal3m = loc.getMantExpComplex(preCalc3); + precal4m = loc.getMantExpComplex(preCalc4); + precal5m = loc.getMantExpComplex(preCalc5); + setArrayDeepValue(referenceDeepData.ReferenceSubCp, iterations, zsubcpm, czm); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], iterations, precalm, czm); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], iterations, precal2m, czm); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[2], iterations, precal3m, czm); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[3], iterations, precal4m, czm); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[4], iterations, precal5m, czm); + + if(!isJulia) { + precal6m = loc.getMantExpComplex(preCalc6); + precal7m = loc.getMantExpComplex(preCalc7); + precal8m = loc.getMantExpComplex(preCalc8); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[5], iterations, precal6m, czm); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[6], iterations, precal7m, czm); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[7], iterations, precal8m, czm); + } + } + + if(lowPrecReferenceOrbitNeeded) { + setArrayValue(referenceData.ReferenceSubCp, iterations, deepZoom ? zsubcpm.toComplex() : zsubcp.toComplex(), cz); + setArrayValue(referenceData.PrecalculatedTerms[0], iterations, deepZoom ? precalm.toComplex() : preCalc.toComplex(), cz); + setArrayValue(referenceData.PrecalculatedTerms[1], iterations, deepZoom ? precal2m.toComplex() : preCalc2.toComplex(), cz); + setArrayValue(referenceData.PrecalculatedTerms[2], iterations, deepZoom ? precal3m.toComplex() : preCalc3.toComplex(), cz); + setArrayValue(referenceData.PrecalculatedTerms[3], iterations, deepZoom ? precal4m.toComplex() : preCalc4.toComplex(), cz); + setArrayValue(referenceData.PrecalculatedTerms[4], iterations, deepZoom ? precal5m.toComplex() : preCalc5.toComplex(), cz); + + if(!isJulia) { + setArrayValue(referenceData.PrecalculatedTerms[5], iterations, deepZoom ? precal6m.toComplex() : preCalc6.toComplex(), cz); + setArrayValue(referenceData.PrecalculatedTerms[6], iterations, deepZoom ? precal7m.toComplex() : preCalc7.toComplex(), cz); + setArrayValue(referenceData.PrecalculatedTerms[7], iterations, deepZoom ? precal8m.toComplex() : preCalc8.toComplex(), cz); + } } if (iterations > 0 && convergent_bailout_algorithm.Converged(z, zold, zold2, iterations, c, start, c0, pixel)) { @@ -532,6 +657,30 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { referenceData.MaxRefIteration = iterations - 1; + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[referenceDeep.id].compact(referenceDeep); + referenceData.compressorZm = referenceCompressor[referenceDeep.id].getZDeep(); + + subexpressionsCompressor[referenceDeepData.ReferenceSubCp.id].compact(referenceDeepData.ReferenceSubCp); + + for(int i = 0; i < preCalcIndexes.length; i++) { + subexpressionsCompressor[referenceDeepData.PrecalculatedTerms[preCalcIndexes[i]].id].compact(referenceDeepData.PrecalculatedTerms[preCalcIndexes[i]]); + } + } + + if(lowPrecReferenceOrbitNeeded) { + referenceCompressor[reference.id].compact(reference); + referenceData.compressorZ = referenceCompressor[reference.id].getZ(); + + subexpressionsCompressor[referenceData.ReferenceSubCp.id].compact(referenceData.ReferenceSubCp); + + for(int i = 0; i < preCalcIndexes.length; i++) { + subexpressionsCompressor[referenceData.PrecalculatedTerms[preCalcIndexes[i]].id].compact(referenceData.PrecalculatedTerms[preCalcIndexes[i]]); + } + } + } + SAskippedIterations = 0; if(progress != null) { @@ -571,17 +720,19 @@ protected void calculateJuliaReferencePoint(GenericComplex inputPixel, Apfloat s boolean lowPrecReferenceOrbitNeeded = !needsOnlyExtendedReferenceOrbit(deepZoom, false); DoubleReference.SHOULD_SAVE_MEMORY = false; + boolean useCompressedRef = TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE && supportsReferenceCompression(); + int[] preCalcIndexes = getNeededPrecalculatedTermsIndexes(); if (iterations == 0) { if(lowPrecReferenceOrbitNeeded) { - secondReferenceData.create(max_ref_iterations,true, 5); + secondReferenceData.create(max_ref_iterations,true, preCalcIndexes, useCompressedRef); } else { secondReferenceData.deallocate(); } if (deepZoom) { - secondReferenceDeepData.create(max_ref_iterations,true, 5); + secondReferenceDeepData.create(max_ref_iterations,true, preCalcIndexes, useCompressedRef); } } else if (max_ref_iterations > getSecondReferenceLength()) { if(lowPrecReferenceOrbitNeeded) { @@ -671,18 +822,45 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { convergent_bailout_algorithm.setReferenceMode(true); - calculatedSecondReferenceIterations = 0; - - for (; iterations < max_ref_iterations; iterations++, calculatedSecondReferenceIterations++) { - + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[secondReferenceDeepData.Reference.id] = new ReferenceCompressor(this, iterations == 0 ? z.toMantExpComplex() : secondReferenceData.compressorZm, c.toMantExpComplex(), start.toMantExpComplex()); + + MantExpComplex cp = initVal.toMantExpComplex(); + Function f = x -> x.sub(cp); + functions[secondReferenceDeepData.ReferenceSubCp.id] = f; + subexpressionsCompressor[secondReferenceDeepData.ReferenceSubCp.id] = new ReferenceCompressor(f, true); + + Function[] fs = getPrecalculatedTermsFunctionsDeep(c.toMantExpComplex()); + for(int i = 0; i < preCalcIndexes.length; i++) { + int id = secondReferenceDeepData.PrecalculatedTerms[preCalcIndexes[i]].id; + functions[id] = fs[i]; + subexpressionsCompressor[id] = new ReferenceCompressor(fs[i], true); + } + } if(lowPrecReferenceOrbitNeeded) { - Complex cz = z.toComplex(); - if (cz.isInfinite()) { - break; + referenceCompressor[secondReferenceData.Reference.id] = new ReferenceCompressor(this, iterations == 0 ? z.toComplex() : secondReferenceData.compressorZ, c.toComplex(), start.toComplex()); + + Complex cp = initVal.toComplex(); + Function f = x -> x.sub(cp); + functions[secondReferenceData.ReferenceSubCp.id] = f; + subexpressionsCompressor[secondReferenceData.ReferenceSubCp.id] = new ReferenceCompressor(f); + + Function[] fs = getPrecalculatedTermsFunctions(c.toComplex()); + for(int i = 0; i < preCalcIndexes.length; i++) { + int id = secondReferenceData.PrecalculatedTerms[preCalcIndexes[i]].id; + functions[id] = fs[i]; + subexpressionsCompressor[id] = new ReferenceCompressor(fs[i]); } - - setArrayValue(secondReferenceData.Reference, iterations, cz); } + } + + calculatedSecondReferenceIterations = 0; + + MantExpComplex tempczm = null; + Complex cz = null; + + for (; iterations < max_ref_iterations; iterations++, calculatedSecondReferenceIterations++) { GenericComplex zsubcp; if(bigNumLib == Constants.BIGNUM_MPFR) { @@ -695,13 +873,6 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { zsubcp = z.sub(initVal); } - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(secondReferenceData.ReferenceSubCp, iterations, zsubcp.toComplex()); - } - if(deepZoom) { - setArrayDeepValue(secondReferenceDeepData.ReferenceSubCp, iterations, loc.getMantExpComplex(zsubcp)); - } - GenericComplex zsqr = z.square(); GenericComplex zsqr3; @@ -718,10 +889,6 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { GenericComplex c4zSzsqr3 = c4z.sub(zsqr3); GenericComplex preCalc = c4zSzsqr3.sub(csqrs3big).times_mutable(zsqr).plus_mutable(csqrbig).sub_mutable(c4z); - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(secondReferenceData.PrecalculatedTerms[0], iterations, preCalc.toComplex()); - } - GenericComplex csztz = c.sub(z).times_mutable(z); GenericComplex preCalc2; // 9*C*Z^2 - 9*Z^3 - (2*C^2 - 3)*Z- C for catastrophic cancelation @@ -732,10 +899,6 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { preCalc2 = csztz.times(MyApfloat.NINE).sub(csqr2s3big).times(z).sub(c); } - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(secondReferenceData.PrecalculatedTerms[1], iterations, preCalc2.toComplex()); - } - GenericComplex c2z = c2big.times(z); GenericComplex preCalc3; if(bigNumLib != Constants.BIGNUM_APFLOAT) { @@ -745,10 +908,6 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { preCalc3 = c2z.sub(zsqr3).plus(MyApfloat.ONE); } - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(secondReferenceData.PrecalculatedTerms[2], iterations, preCalc3.toComplex()); - } - GenericComplex preCalc4; if(bigNumLib != Constants.BIGNUM_APFLOAT) { @@ -758,10 +917,6 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { preCalc4 = c4zSzsqr3.times(MyApfloat.THREE).sub(csqr2s3big.times2()).times(zsqr).sub(c4z).sub(MyApfloat.ONE); } - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(secondReferenceData.PrecalculatedTerms[3], iterations, preCalc4.toComplex()); - } - //12*(C*Z^2 - Z^3)-2*(C^2-3)*Z -4*C GenericComplex preCalc5; @@ -772,17 +927,49 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { preCalc5 = csztz.times(MyApfloat.TWELVE).sub(csqrs3big.times2()).times(z).sub(c4big); } + MantExpComplex zsubcpm = null, czm = null; + MantExpComplex precalm = null, precal2m = null, precal3m = null, precal4m = null, precal5m = null; + if(deepZoom) { + czm = loc.getMantExpComplex(z); + if (czm.isInfinite() || czm.isNaN()) { + break; + } + tempczm = setArrayDeepValue(secondReferenceDeepData.Reference, iterations, czm); + } + if(lowPrecReferenceOrbitNeeded) { - setArrayValue(secondReferenceData.PrecalculatedTerms[4], iterations, preCalc5.toComplex()); + cz = deepZoom ? czm.toComplex() : z.toComplex(); + if (cz.isInfinite() || cz.isNaN()) { + break; + } + + cz = setArrayValue(secondReferenceData.Reference, iterations, cz); } + czm = tempczm; + if(deepZoom) { - setArrayDeepValue(secondReferenceDeepData.Reference, iterations, loc.getMantExpComplex(z)); - setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[0], iterations, loc.getMantExpComplex(preCalc)); - setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[1], iterations, loc.getMantExpComplex(preCalc2)); - setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[2], iterations, loc.getMantExpComplex(preCalc3)); - setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[3], iterations, loc.getMantExpComplex(preCalc4)); - setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[4], iterations, loc.getMantExpComplex(preCalc5)); + zsubcpm = loc.getMantExpComplex(zsubcp); + precalm = loc.getMantExpComplex(preCalc); + precal2m = loc.getMantExpComplex(preCalc2); + precal3m = loc.getMantExpComplex(preCalc3); + precal4m = loc.getMantExpComplex(preCalc4); + precal5m = loc.getMantExpComplex(preCalc5); + setArrayDeepValue(secondReferenceDeepData.ReferenceSubCp, iterations, zsubcpm, czm); + setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[0], iterations, precalm, czm); + setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[1], iterations, precal2m, czm); + setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[2], iterations, precal3m, czm); + setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[3], iterations, precal4m, czm); + setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[4], iterations, precal5m, czm); + } + + if(lowPrecReferenceOrbitNeeded) { + setArrayValue(secondReferenceData.ReferenceSubCp, iterations, deepZoom ? zsubcpm.toComplex() : zsubcp.toComplex(), cz); + setArrayValue(secondReferenceData.PrecalculatedTerms[0], iterations, deepZoom ? precalm.toComplex() : preCalc.toComplex(), cz); + setArrayValue(secondReferenceData.PrecalculatedTerms[1], iterations, deepZoom ? precal2m.toComplex() : preCalc2.toComplex(), cz); + setArrayValue(secondReferenceData.PrecalculatedTerms[2], iterations, deepZoom ? precal3m.toComplex() : preCalc3.toComplex(), cz); + setArrayValue(secondReferenceData.PrecalculatedTerms[3], iterations, deepZoom ? precal4m.toComplex() : preCalc4.toComplex(), cz); + setArrayValue(secondReferenceData.PrecalculatedTerms[4], iterations, deepZoom ? precal5m.toComplex() : preCalc5.toComplex(), cz); } if (iterations > 0 && convergent_bailout_algorithm.Converged(z, zold, zold2, iterations, c, start, c0, pixel)) { @@ -821,6 +1008,31 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { secondReferenceData.MaxRefIteration = iterations - 1; + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[secondReferenceDeepData.Reference.id].compact(secondReferenceDeepData.Reference); + secondReferenceData.compressorZm = referenceCompressor[secondReferenceDeepData.Reference.id].getZDeep(); + + subexpressionsCompressor[secondReferenceDeepData.ReferenceSubCp.id].compact(secondReferenceDeepData.ReferenceSubCp); + + for(int i = 0; i < preCalcIndexes.length; i++) { + subexpressionsCompressor[secondReferenceDeepData.PrecalculatedTerms[preCalcIndexes[i]].id].compact(secondReferenceDeepData.PrecalculatedTerms[preCalcIndexes[i]]); + } + } + + if(lowPrecReferenceOrbitNeeded) { + referenceCompressor[secondReferenceData.Reference.id].compact(secondReferenceData.Reference); + secondReferenceData.compressorZ = referenceCompressor[secondReferenceData.Reference.id].getZ(); + + subexpressionsCompressor[secondReferenceData.ReferenceSubCp.id].compact(secondReferenceData.ReferenceSubCp); + + for(int i = 0; i < preCalcIndexes.length; i++) { + subexpressionsCompressor[secondReferenceData.PrecalculatedTerms[preCalcIndexes[i]].id].compact(secondReferenceData.PrecalculatedTerms[preCalcIndexes[i]]); + } + } + } + + if(progress != null) { progress.setValue(progress.getMaximum()); progress.setString(REFERENCE_CALCULATION_STR + " 100%"); @@ -841,22 +1053,27 @@ public Complex perturbationFunction(Complex z, Complex c, int RefIteration) { Complex zsqr = z.square(); - Complex temp1 = getArrayValue(referenceData.PrecalculatedTerms[2], RefIteration); + Complex Z = null; + if(reference.compressed) { + Z = getArrayValue(reference, RefIteration); + } + + Complex temp1 = getArrayValue(referenceData.PrecalculatedTerms[2], RefIteration, Z); Complex temp9 = temp1.times(c); - Complex temp11 = getArrayValue(referenceData.PrecalculatedTerms[7], RefIteration); + Complex temp11 = getArrayValue(referenceData.PrecalculatedTerms[7], RefIteration, Z); Complex num = temp1.times2().times_mutable(z.cube()) - .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[4], RefIteration).sub_mutable(temp9).times_mutable(zsqr)) + .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[4], RefIteration, Z).sub_mutable(temp9).times_mutable(zsqr)) .sub_mutable(temp11.times_mutable(c)) - .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration).sub_mutable(getArrayValue(referenceData.PrecalculatedTerms[5], RefIteration).times_mutable(c)).times2_mutable().times_mutable(z)); + .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration, Z).sub_mutable(getArrayValue(referenceData.PrecalculatedTerms[5], RefIteration, Z).times_mutable(c)).times2_mutable().times_mutable(z)); - Complex denom = getArrayValue(referenceData.PrecalculatedTerms[3], RefIteration) + Complex denom = getArrayValue(referenceData.PrecalculatedTerms[3], RefIteration, Z) .plus_mutable(temp1.times(zsqr).times_mutable(3)) - .sub_mutable(getArrayValue(referenceData.PrecalculatedTerms[6], RefIteration).times_mutable(c).times2_mutable()) - .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration).sub_mutable(temp9).times_mutable(z).times2_mutable()) + .sub_mutable(getArrayValue(referenceData.PrecalculatedTerms[6], RefIteration, Z).times_mutable(c).times2_mutable()) + .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration, Z).sub_mutable(temp9).times_mutable(z).times2_mutable()) ; @@ -870,22 +1087,27 @@ public MantExpComplex perturbationFunction(MantExpComplex z, MantExpComplex c, i MantExpComplex zsqr = z.square(); - MantExpComplex temp1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[2], RefIteration); + MantExpComplex Z = null; + if(referenceDeep.compressed) { + Z = getArrayDeepValue(referenceDeep, RefIteration); + } + + MantExpComplex temp1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[2], RefIteration, Z); MantExpComplex temp9 = temp1.times(c); - MantExpComplex temp11 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[7], RefIteration); + MantExpComplex temp11 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[7], RefIteration, Z); MantExpComplex num = temp1.times2().times_mutable(z.cube()) - .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[4], RefIteration).sub_mutable(temp9).times_mutable(zsqr)) + .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[4], RefIteration, Z).sub_mutable(temp9).times_mutable(zsqr)) .sub_mutable(temp11.times_mutable(c)) - .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration).sub_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[5], RefIteration).times_mutable(c)).times2_mutable().times_mutable(z)); + .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration, Z).sub_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[5], RefIteration, Z).times_mutable(c)).times2_mutable().times_mutable(z)); - MantExpComplex denom = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[3], RefIteration) + MantExpComplex denom = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[3], RefIteration, Z) .plus_mutable(temp1.times(zsqr).times_mutable(MantExp.THREE)) - .sub_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[6], RefIteration).times_mutable(c).times2_mutable()) - .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration).sub_mutable(temp9).times_mutable(z).times2_mutable()) + .sub_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[6], RefIteration, Z).times_mutable(c).times2_mutable()) + .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration, Z).sub_mutable(temp9).times_mutable(z).times2_mutable()) ; @@ -897,22 +1119,27 @@ public MantExpComplex perturbationFunction(MantExpComplex z, MantExpComplex c, i public Complex perturbationFunction(Complex z, Complex c, ReferenceData data, int RefIteration) { Complex zsqr = z.square(); - Complex temp1 = getArrayValue(data.PrecalculatedTerms[2], RefIteration); + Complex Z = null; + if(data.Reference.compressed) { + Z = getArrayValue(data.Reference, RefIteration); + } + + Complex temp1 = getArrayValue(data.PrecalculatedTerms[2], RefIteration, Z); Complex temp9 = temp1.times(c); - Complex temp11 = getArrayValue(data.PrecalculatedTerms[7], RefIteration); + Complex temp11 = getArrayValue(data.PrecalculatedTerms[7], RefIteration, Z); Complex num = temp1.times2().times_mutable(z.cube()) - .plus_mutable(getArrayValue(data.PrecalculatedTerms[4], RefIteration).sub_mutable(temp9).times_mutable(zsqr)) + .plus_mutable(getArrayValue(data.PrecalculatedTerms[4], RefIteration, Z).sub_mutable(temp9).times_mutable(zsqr)) .sub_mutable(temp11.times_mutable(c)) - .plus_mutable(getArrayValue(data.PrecalculatedTerms[0], RefIteration).sub_mutable(getArrayValue(data.PrecalculatedTerms[5], RefIteration).times_mutable(c)).times2_mutable().times_mutable(z)); + .plus_mutable(getArrayValue(data.PrecalculatedTerms[0], RefIteration, Z).sub_mutable(getArrayValue(data.PrecalculatedTerms[5], RefIteration, Z).times_mutable(c)).times2_mutable().times_mutable(z)); - Complex denom = getArrayValue(data.PrecalculatedTerms[3], RefIteration) + Complex denom = getArrayValue(data.PrecalculatedTerms[3], RefIteration, Z) .plus_mutable(temp1.times(zsqr).times_mutable(3)) - .sub_mutable(getArrayValue(data.PrecalculatedTerms[6], RefIteration).times_mutable(c).times2_mutable()) - .plus_mutable(getArrayValue(data.PrecalculatedTerms[1], RefIteration).sub_mutable(temp9).times_mutable(z).times2_mutable()) + .sub_mutable(getArrayValue(data.PrecalculatedTerms[6], RefIteration, Z).times_mutable(c).times2_mutable()) + .plus_mutable(getArrayValue(data.PrecalculatedTerms[1], RefIteration, Z).sub_mutable(temp9).times_mutable(z).times2_mutable()) ; @@ -924,22 +1151,27 @@ public Complex perturbationFunction(Complex z, Complex c, ReferenceData data, in public MantExpComplex perturbationFunction(MantExpComplex z, MantExpComplex c, ReferenceDeepData data, int RefIteration) { MantExpComplex zsqr = z.square(); - MantExpComplex temp1 = getArrayDeepValue(data.PrecalculatedTerms[2], RefIteration); + MantExpComplex Z = null; + if(data.Reference.compressed) { + Z = getArrayDeepValue(data.Reference, RefIteration); + } + + MantExpComplex temp1 = getArrayDeepValue(data.PrecalculatedTerms[2], RefIteration, Z); MantExpComplex temp9 = temp1.times(c); - MantExpComplex temp11 = getArrayDeepValue(data.PrecalculatedTerms[7], RefIteration); + MantExpComplex temp11 = getArrayDeepValue(data.PrecalculatedTerms[7], RefIteration, Z); MantExpComplex num = temp1.times2().times_mutable(z.cube()) - .plus_mutable(getArrayDeepValue(data.PrecalculatedTerms[4], RefIteration).sub_mutable(temp9).times_mutable(zsqr)) + .plus_mutable(getArrayDeepValue(data.PrecalculatedTerms[4], RefIteration, Z).sub_mutable(temp9).times_mutable(zsqr)) .sub_mutable(temp11.times_mutable(c)) - .plus_mutable(getArrayDeepValue(data.PrecalculatedTerms[0], RefIteration).sub_mutable(getArrayDeepValue(data.PrecalculatedTerms[5], RefIteration).times_mutable(c)).times2_mutable().times_mutable(z)); + .plus_mutable(getArrayDeepValue(data.PrecalculatedTerms[0], RefIteration, Z).sub_mutable(getArrayDeepValue(data.PrecalculatedTerms[5], RefIteration, Z).times_mutable(c)).times2_mutable().times_mutable(z)); - MantExpComplex denom = getArrayDeepValue(data.PrecalculatedTerms[3], RefIteration) + MantExpComplex denom = getArrayDeepValue(data.PrecalculatedTerms[3], RefIteration, Z) .plus_mutable(temp1.times(zsqr).times_mutable(MantExp.THREE)) - .sub_mutable(getArrayDeepValue(data.PrecalculatedTerms[6], RefIteration).times_mutable(c).times2_mutable()) - .plus_mutable(getArrayDeepValue(data.PrecalculatedTerms[1], RefIteration).sub_mutable(temp9).times_mutable(z).times2_mutable()) + .sub_mutable(getArrayDeepValue(data.PrecalculatedTerms[6], RefIteration, Z).times_mutable(c).times2_mutable()) + .plus_mutable(getArrayDeepValue(data.PrecalculatedTerms[1], RefIteration, Z).sub_mutable(temp9).times_mutable(z).times2_mutable()) ; @@ -952,17 +1184,22 @@ public Complex perturbationFunction(Complex z, int RefIteration) { Complex zsqr = z.square(); - Complex temp1 = getArrayValue(referenceData.PrecalculatedTerms[2], RefIteration); + Complex Z = null; + if(reference.compressed) { + Z = getArrayValue(reference, RefIteration); + } + + Complex temp1 = getArrayValue(referenceData.PrecalculatedTerms[2], RefIteration, Z); Complex num = temp1.times2().times_mutable(z.cube()) - .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[4], RefIteration).times_mutable(zsqr)) - .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration).times2_mutable().times_mutable(z)); + .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[4], RefIteration, Z).times_mutable(zsqr)) + .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration, Z).times2_mutable().times_mutable(z)); - Complex denom = getArrayValue(referenceData.PrecalculatedTerms[3], RefIteration) + Complex denom = getArrayValue(referenceData.PrecalculatedTerms[3], RefIteration, Z) .plus_mutable(temp1.times(zsqr).times_mutable(3)) - .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration).times_mutable(z).times2_mutable()) + .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration, Z).times_mutable(z).times2_mutable()) ; @@ -975,17 +1212,22 @@ public MantExpComplex perturbationFunction(MantExpComplex z, int RefIteration) { MantExpComplex zsqr = z.square(); - MantExpComplex temp1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[2], RefIteration); + MantExpComplex Z = null; + if(referenceDeep.compressed) { + Z = getArrayDeepValue(referenceDeep, RefIteration); + } + + MantExpComplex temp1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[2], RefIteration, Z); MantExpComplex num = temp1.times2().times_mutable(z.cube()) - .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[4], RefIteration).times_mutable(zsqr)) - .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration).times2_mutable().times_mutable(z)); + .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[4], RefIteration, Z).times_mutable(zsqr)) + .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration, Z).times2_mutable().times_mutable(z)); - MantExpComplex denom = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[3], RefIteration) + MantExpComplex denom = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[3], RefIteration, Z) .plus_mutable(temp1.times(zsqr).times_mutable(MantExp.THREE)) - .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration).times_mutable(z).times2_mutable()) + .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration, Z).times_mutable(z).times2_mutable()) ; @@ -997,17 +1239,22 @@ public Complex perturbationFunction(Complex z, ReferenceData data, int RefIterat Complex zsqr = z.square(); - Complex temp1 = getArrayValue(data.PrecalculatedTerms[2], RefIteration); + Complex Z = null; + if(data.Reference.compressed) { + Z = getArrayValue(data.Reference, RefIteration); + } + + Complex temp1 = getArrayValue(data.PrecalculatedTerms[2], RefIteration, Z); Complex num = temp1.times2().times_mutable(z.cube()) - .plus_mutable(getArrayValue(data.PrecalculatedTerms[4], RefIteration).times_mutable(zsqr)) - .plus_mutable(getArrayValue(data.PrecalculatedTerms[0], RefIteration).times2_mutable().times_mutable(z)); + .plus_mutable(getArrayValue(data.PrecalculatedTerms[4], RefIteration, Z).times_mutable(zsqr)) + .plus_mutable(getArrayValue(data.PrecalculatedTerms[0], RefIteration, Z).times2_mutable().times_mutable(z)); - Complex denom = getArrayValue(data.PrecalculatedTerms[3], RefIteration) + Complex denom = getArrayValue(data.PrecalculatedTerms[3], RefIteration, Z) .plus_mutable(temp1.times(zsqr).times_mutable(3)) - .plus_mutable(getArrayValue(data.PrecalculatedTerms[1], RefIteration).times_mutable(z).times2_mutable()) + .plus_mutable(getArrayValue(data.PrecalculatedTerms[1], RefIteration, Z).times_mutable(z).times2_mutable()) ; @@ -1020,17 +1267,22 @@ public MantExpComplex perturbationFunction(MantExpComplex z, ReferenceDeepData d MantExpComplex zsqr = z.square(); - MantExpComplex temp1 = getArrayDeepValue(data.PrecalculatedTerms[2], RefIteration); + MantExpComplex Z = null; + if(data.Reference.compressed) { + Z = getArrayDeepValue(data.Reference, RefIteration); + } + + MantExpComplex temp1 = getArrayDeepValue(data.PrecalculatedTerms[2], RefIteration, Z); MantExpComplex num = temp1.times2().times_mutable(z.cube()) - .plus_mutable(getArrayDeepValue(data.PrecalculatedTerms[4], RefIteration).times_mutable(zsqr)) - .plus_mutable(getArrayDeepValue(data.PrecalculatedTerms[0], RefIteration).times2_mutable().times_mutable(z)); + .plus_mutable(getArrayDeepValue(data.PrecalculatedTerms[4], RefIteration, Z).times_mutable(zsqr)) + .plus_mutable(getArrayDeepValue(data.PrecalculatedTerms[0], RefIteration, Z).times2_mutable().times_mutable(z)); - MantExpComplex denom = getArrayDeepValue(data.PrecalculatedTerms[3], RefIteration) + MantExpComplex denom = getArrayDeepValue(data.PrecalculatedTerms[3], RefIteration, Z) .plus_mutable(temp1.times(zsqr).times_mutable(MantExp.THREE)) - .plus_mutable(getArrayDeepValue(data.PrecalculatedTerms[1], RefIteration).times_mutable(z).times2_mutable()) + .plus_mutable(getArrayDeepValue(data.PrecalculatedTerms[1], RefIteration, Z).times_mutable(z).times2_mutable()) ; @@ -1231,4 +1483,29 @@ public int[] getSecondNextIterations() { // protected boolean additionalConvergentBailoutTest(Complex z, Complex zold, Complex zold2, int iterations, Complex c, Complex start, Complex c0, Complex pixel) { // return z.distance_squared(1) <= 1e-3 || z.distance_squared(-1) <= 1e-3; // } + + @Override + public boolean supportsReferenceCompression() { + return true; + } + + @Override + public Complex function(Complex z, Complex c) { + return z.sub_mutable(z.sub(1).times_mutable(z.plus(1)).times_mutable(z.sub(c)).divide_mutable(c.times(z).times2_mutable().negative_mutable().plus_mutable(z.square().times_mutable(3)).sub_mutable(1))); + } + + @Override + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + return z.sub_mutable(z.sub(MantExp.ONE).times_mutable(z.plus(MantExp.ONE)).times_mutable(z.sub(c)).divide_mutable(c.times(z).times2_mutable().negative_mutable().plus_mutable(z.square().times_mutable(MantExp.THREE)).sub_mutable(MantExp.ONE))); + } + + @Override + protected boolean needsRefSubCp() { + return true; + } + + @Override + public double getPower() { + return 3; + } } diff --git a/src/fractalzoomer/functions/general/Nova.java b/src/fractalzoomer/functions/general/Nova.java index b74169c3c..d2517389f 100644 --- a/src/fractalzoomer/functions/general/Nova.java +++ b/src/fractalzoomer/functions/general/Nova.java @@ -81,6 +81,7 @@ import javax.swing.*; import java.util.ArrayList; +import java.util.function.Function; import static fractalzoomer.main.Constants.*; @@ -105,7 +106,7 @@ public Nova(double xCenter, double yCenter, double size, int max_iterations, int super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, false, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); if(nova_method == MainWindow.NOVA_TRAUB_OSTROWSKI) { - convergent_bailout = 1E-8; + setConvergentBailout(1E-8); } this.nova_method = nova_method; @@ -116,7 +117,6 @@ public Nova(double xCenter, double yCenter, double size, int max_iterations, int supportsPerturbation = false; if(nova_method == MainWindow.NOVA_NEWTON && z_exponent[0] == 3 && z_exponent[1] == 0 && relaxation[0] == 1 && relaxation[1] == 0 && defaultNovaInitialValue) { - power = 3; supportsPerturbation = true; } @@ -170,7 +170,7 @@ public Nova(double xCenter, double yCenter, double size, int max_iterations, int //Todo: Check which other methods need this if(nova_method == MainWindow.NOVA_TRAUB_OSTROWSKI) { - convergent_bailout = 1E-8; + setConvergentBailout(1E-8); } this.nova_method = nova_method; @@ -183,7 +183,6 @@ public Nova(double xCenter, double yCenter, double size, int max_iterations, int supportsPerturbation = false; if(nova_method == MainWindow.NOVA_NEWTON && z_exponent[0] == 3 && z_exponent[1] == 0 && relaxation[0] == 1 && relaxation[1] == 0 && defaultNovaInitialValue) { - power = 3; supportsPerturbation = true; } @@ -195,15 +194,15 @@ public Nova(double xCenter, double yCenter, double size, int max_iterations, int case MainWindow.BINARY_DECOMPOSITION2: case MainWindow.BANDED: if (nova_method == MainWindow.NOVA_HALLEY || nova_method == MainWindow.NOVA_HOUSEHOLDER || nova_method == MainWindow.NOVA_WHITTAKER || nova_method == MainWindow.NOVA_WHITTAKER_DOUBLE_CONVEX || nova_method == MainWindow.NOVA_SUPER_HALLEY) { - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); } else if (nova_method == MainWindow.NOVA_NEWTON || nova_method == MainWindow.NOVA_STEFFENSEN) { - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); } else if (nova_method == MainWindow.NOVA_SCHRODER) { - convergent_bailout = 1E-6; + setConvergentBailout(1E-6); } break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } @@ -243,7 +242,6 @@ public Nova(double xCenter, double yCenter, double size, int max_iterations, Arr supportsPerturbation = false; if(nova_method == MainWindow.NOVA_NEWTON && z_exponent[0] == 3 && z_exponent[1] == 0 && relaxation[0] == 1 && relaxation[1] == 0 && defaultNovaInitialValue) { - power = 3; supportsPerturbation = true; } @@ -284,7 +282,6 @@ public Nova(double xCenter, double yCenter, double size, int max_iterations, Arr supportsPerturbation = false; if(nova_method == MainWindow.NOVA_NEWTON && z_exponent[0] == 3 && z_exponent[1] == 0 && relaxation[0] == 1 && relaxation[1] == 0 && defaultNovaInitialValue) { - power = 3; supportsPerturbation = true; } @@ -917,6 +914,23 @@ public boolean supportsPerturbationTheory() { return supportsPerturbation; } + @Override + protected int[] getNeededPrecalculatedTermsIndexes() { + return new int[] {0}; + } + + @Override + protected Function[] getPrecalculatedTermsFunctions(Complex c) { + Function f1 = x -> x.fourth().sub_mutable(x); + return new Function[] {f1}; + } + + @Override + protected Function[] getPrecalculatedTermsFunctionsDeep(MantExpComplex c) { + Function f1 = x -> x.fourth().sub_mutable(x); + return new Function[] {f1}; + } + @Override public void calculateReferencePoint(GenericComplex inputPixel, Apfloat size, boolean deepZoom, int[] Iterations, int[] juliaIterations, Location externalLocation, JProgressBar progress) { @@ -938,17 +952,19 @@ public void calculateReferencePoint(GenericComplex inputPixel, Apfloat size, boo boolean lowPrecReferenceOrbitNeeded = !needsOnlyExtendedReferenceOrbit(deepZoom, false); DoubleReference.SHOULD_SAVE_MEMORY = false; + boolean useCompressedRef = TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE && supportsReferenceCompression(); + int[] preCalcIndexes = getNeededPrecalculatedTermsIndexes(); if(iterations == 0) { if(lowPrecReferenceOrbitNeeded) { - referenceData.createAndSetShortcut(max_ref_iterations, true, 1); + referenceData.createAndSetShortcut(max_ref_iterations, true, preCalcIndexes, useCompressedRef); } else { referenceData.deallocate(); } if (deepZoom) { - referenceDeepData.createAndSetShortcut(max_ref_iterations, true, 1); + referenceDeepData.createAndSetShortcut(max_ref_iterations, true, preCalcIndexes, useCompressedRef); } } else if (max_ref_iterations > getReferenceLength()){ @@ -965,27 +981,10 @@ else if (max_ref_iterations > getReferenceLength()){ } if(isJulia) { - if(inputPixel instanceof BigComplex && ((BigComplex)inputPixel).norm().compareTo(new MyApfloat(1e-4)) < 0) { - inputPixel = new BigComplex(1e-4, 1e-4); - } - else if(inputPixel instanceof BigIntNumComplex && ((BigIntNumComplex)inputPixel).norm().compare(new BigIntNum(1e-4)) < 0) { - inputPixel = new BigIntNumComplex(1e-4, 1e-4); - } - else if(inputPixel instanceof MpfrBigNumComplex && ((MpfrBigNumComplex)inputPixel).norm().compare(1e-4) < 0) { - inputPixel = new MpfrBigNumComplex(1e-4, 1e-4); - } - else if(inputPixel instanceof MpirBigNumComplex && ((MpirBigNumComplex)inputPixel).norm().compare(1e-4) < 0) { - inputPixel = new MpirBigNumComplex(1e-4, 1e-4); - } - else if(inputPixel instanceof DDComplex && ((DDComplex)inputPixel).norm().compareTo(new DoubleDouble(1e-4)) < 0) { - inputPixel = new DDComplex(1e-4, 1e-4); - } - else if(inputPixel instanceof Complex && ((Complex)inputPixel).norm() < 1e-4) { - inputPixel = new Complex(1e-4, 1e-4); - } + //Due to zero, all around zero will not work + inputPixel = sanitizeInputPixel(inputPixel); } - int bigNumLib = TaskDraw.getBignumLibrary(size, this); GenericComplex z, c, zold, zold2, start, c0, initVal, pixel; @@ -1072,28 +1071,68 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { refPoint = inputPixel; - refPointSmall = refPoint.toComplex(); - if(deepZoom) { refPointSmallDeep = loc.getMantExpComplex(refPoint); + refPointSmall = refPointSmallDeep.toComplex(); + if(isJulia) { + seedSmallDeep = loc.getMantExpComplex(c); + } + + if(lowPrecReferenceOrbitNeeded && isJulia) { + seedSmall = seedSmallDeep.toComplex(); + } + } + else { + refPointSmall = refPoint.toComplex(); + if(lowPrecReferenceOrbitNeeded && isJulia) { + seedSmall = c.toComplex(); + } } RefType = getRefType(); convergent_bailout_algorithm.setReferenceMode(true); - calculatedReferenceIterations = 0; - - for (; iterations < max_iterations; iterations++, calculatedReferenceIterations++) { + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[referenceDeep.id] = new ReferenceCompressor(this, iterations == 0 ? z.toMantExpComplex() : referenceData.compressorZm, c.toMantExpComplex(), start.toMantExpComplex()); + + MantExpComplex cp = initVal.toMantExpComplex(); + Function f = x -> x.sub(cp); + functions[referenceDeepData.ReferenceSubCp.id] = f; + subexpressionsCompressor[referenceDeepData.ReferenceSubCp.id] = new ReferenceCompressor(f, true); + + Function[] fs = getPrecalculatedTermsFunctionsDeep(c.toMantExpComplex()); + for(int i = 0; i < preCalcIndexes.length; i++) { + int id = referenceDeepData.PrecalculatedTerms[preCalcIndexes[i]].id; + functions[id] = fs[i]; + subexpressionsCompressor[id] = new ReferenceCompressor(fs[i], true); + } + } if(lowPrecReferenceOrbitNeeded) { - Complex cz = z.toComplex(); - if (cz.isInfinite()) { - break; + referenceCompressor[reference.id] = new ReferenceCompressor(this, iterations == 0 ? z.toComplex() : referenceData.compressorZ, c.toComplex(), start.toComplex()); + + Complex cp = initVal.toComplex(); + Function f = x -> x.sub(cp); + functions[referenceData.ReferenceSubCp.id] = f; + subexpressionsCompressor[referenceData.ReferenceSubCp.id] = new ReferenceCompressor(f); + + Function[] fs = getPrecalculatedTermsFunctions(c.toComplex()); + for(int i = 0; i < preCalcIndexes.length; i++) { + int id = referenceData.PrecalculatedTerms[preCalcIndexes[i]].id; + functions[id] = fs[i]; + subexpressionsCompressor[id] = new ReferenceCompressor(fs[i]); } - - setArrayValue(reference, iterations, cz); } + } + + calculatedReferenceIterations = 0; + + MantExpComplex tempmcz = null; + Complex cz = null; + + for (; iterations < max_iterations; iterations++, calculatedReferenceIterations++) { GenericComplex zsubcp; if(bigNumLib == Constants.BIGNUM_MPFR) { @@ -1106,13 +1145,6 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { zsubcp = z.sub(initVal); } - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.ReferenceSubCp, iterations, zsubcp.toComplex()); - } - if(deepZoom) { - setArrayDeepValue(referenceDeepData.ReferenceSubCp, iterations, loc.getMantExpComplex(zsubcp)); - } - GenericComplex zcubes1; if(bigNumLib != BIGNUM_APFLOAT) { @@ -1125,13 +1157,39 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { GenericComplex preCalc; preCalc = zcubes1.times(z); //Z^4-Z for catastrophic cancelation + MantExpComplex czm = null; + MantExpComplex precalm = null; + MantExpComplex zsubcpm = null; + + if(deepZoom) { + czm = loc.getMantExpComplex(z); + if (czm.isInfinite() || czm.isNaN()) { + break; + } + tempmcz = setArrayDeepValue(referenceDeep, iterations, czm); + } + if(lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[0], iterations, preCalc.toComplex()); + cz = deepZoom ? czm.toComplex() : z.toComplex(); + if (cz.isInfinite() || cz.isNaN()) { + break; + } + + cz = setArrayValue(reference, iterations, cz); } + czm = tempmcz; + if(deepZoom) { - setArrayDeepValue(referenceDeep, iterations, loc.getMantExpComplex(z)); - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], iterations, loc.getMantExpComplex(preCalc)); + precalm = loc.getMantExpComplex(preCalc); + zsubcpm = loc.getMantExpComplex(zsubcp); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], iterations, precalm, czm); + setArrayDeepValue(referenceDeepData.ReferenceSubCp, iterations, zsubcpm, czm); + } + + if(lowPrecReferenceOrbitNeeded) { + setArrayValue(referenceData.PrecalculatedTerms[0], iterations, deepZoom ? precalm.toComplex() : preCalc.toComplex(), cz); + setArrayValue(referenceData.ReferenceSubCp, iterations, deepZoom ? zsubcpm.toComplex() : zsubcp.toComplex(), cz); } if (iterations > 0 && convergent_bailout_algorithm.Converged(z, zold, zold2, iterations, c, start, c0, pixel)) { @@ -1168,6 +1226,28 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { referenceData.MaxRefIteration = iterations - 1; + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[referenceDeep.id].compact(referenceDeep); + referenceData.compressorZm = referenceCompressor[referenceDeep.id].getZDeep(); + subexpressionsCompressor[referenceDeepData.ReferenceSubCp.id].compact(referenceDeepData.ReferenceSubCp); + + for(int i = 0; i < preCalcIndexes.length; i++) { + subexpressionsCompressor[referenceDeepData.PrecalculatedTerms[preCalcIndexes[i]].id].compact(referenceDeepData.PrecalculatedTerms[preCalcIndexes[i]]); + } + } + + if(lowPrecReferenceOrbitNeeded) { + referenceCompressor[reference.id].compact(reference); + referenceData.compressorZ = referenceCompressor[reference.id].getZ(); + subexpressionsCompressor[referenceData.ReferenceSubCp.id].compact(referenceData.ReferenceSubCp); + + for(int i = 0; i < preCalcIndexes.length; i++) { + subexpressionsCompressor[referenceData.PrecalculatedTerms[preCalcIndexes[i]].id].compact(referenceData.PrecalculatedTerms[preCalcIndexes[i]]); + } + } + } + SAskippedIterations = 0; if(progress != null) { @@ -1179,7 +1259,6 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { if(isJulia) { calculateJuliaReferencePoint(inputPixel, size, deepZoom, juliaIterations, progress); } - } @Override @@ -1205,17 +1284,19 @@ protected void calculateJuliaReferencePoint(GenericComplex inputPixel, Apfloat s boolean lowPrecReferenceOrbitNeeded = !needsOnlyExtendedReferenceOrbit(deepZoom, false); DoubleReference.SHOULD_SAVE_MEMORY = false; + boolean useCompressedRef = TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE && supportsReferenceCompression(); + int[] preCalcIndexes = getNeededPrecalculatedTermsIndexes(); if (iterations == 0) { if(lowPrecReferenceOrbitNeeded) { - secondReferenceData.create(max_ref_iterations,true, 1); + secondReferenceData.create(max_ref_iterations,true, preCalcIndexes, useCompressedRef); } else { secondReferenceData.deallocate(); } if (deepZoom) { - secondReferenceDeepData.create(max_ref_iterations,true, 1); + secondReferenceDeepData.create(max_ref_iterations,true, preCalcIndexes, useCompressedRef); } } else if (max_ref_iterations > getSecondReferenceLength()) { if(lowPrecReferenceOrbitNeeded) { @@ -1316,18 +1397,44 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { convergent_bailout_algorithm.setReferenceMode(true); - calculatedSecondReferenceIterations = 0; - - for (; iterations < max_ref_iterations; iterations++, calculatedSecondReferenceIterations++) { - + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[secondReferenceDeepData.Reference.id] = new ReferenceCompressor(this, iterations == 0 ? z.toMantExpComplex() : secondReferenceData.compressorZm, c.toMantExpComplex(), start.toMantExpComplex()); + + MantExpComplex cp = initVal.toMantExpComplex(); + Function f = x -> x.sub(cp); + functions[secondReferenceDeepData.ReferenceSubCp.id] = f; + subexpressionsCompressor[secondReferenceDeepData.ReferenceSubCp.id] = new ReferenceCompressor(f, true); + + Function[] fs = getPrecalculatedTermsFunctionsDeep(c.toMantExpComplex()); + for(int i = 0; i < preCalcIndexes.length; i++) { + int id = secondReferenceDeepData.PrecalculatedTerms[preCalcIndexes[i]].id; + functions[id] = fs[i]; + subexpressionsCompressor[id] = new ReferenceCompressor(fs[i], true); + } + } if(lowPrecReferenceOrbitNeeded) { - Complex cz = z.toComplex(); - if (cz.isInfinite()) { - break; + referenceCompressor[secondReferenceData.Reference.id] = new ReferenceCompressor(this, iterations == 0 ? z.toComplex() : secondReferenceData.compressorZ, c.toComplex(), start.toComplex()); + + Complex cp = initVal.toComplex(); + Function f = x -> x.sub(cp); + functions[secondReferenceData.ReferenceSubCp.id] = f; + subexpressionsCompressor[secondReferenceData.ReferenceSubCp.id] = new ReferenceCompressor(f); + + Function[] fs = getPrecalculatedTermsFunctions(c.toComplex()); + for(int i = 0; i < preCalcIndexes.length; i++) { + int id = secondReferenceData.PrecalculatedTerms[preCalcIndexes[i]].id; + functions[id] = fs[i]; + subexpressionsCompressor[id] = new ReferenceCompressor(fs[i]); } - - setArrayValue(secondReferenceData.Reference, iterations, cz); } + } + + calculatedSecondReferenceIterations = 0; + MantExpComplex tempczm = null; + Complex cz = null; + + for (; iterations < max_ref_iterations; iterations++, calculatedSecondReferenceIterations++) { GenericComplex zsubcp; if(bigNumLib == Constants.BIGNUM_MPFR) { @@ -1340,13 +1447,6 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { zsubcp = z.sub(initVal); } - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(secondReferenceData.ReferenceSubCp, iterations, zsubcp.toComplex()); - } - if(deepZoom) { - setArrayDeepValue(secondReferenceDeepData.ReferenceSubCp, iterations, loc.getMantExpComplex(zsubcp)); - } - GenericComplex zcubes1; if(bigNumLib != Constants.BIGNUM_APFLOAT) { @@ -1359,13 +1459,39 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { GenericComplex preCalc; preCalc = zcubes1.times(z); //Z^4-Z for catastrophic cancelation + MantExpComplex czm = null; + MantExpComplex precalm = null; + MantExpComplex zsubcpm = null; + + if(deepZoom) { + czm = loc.getMantExpComplex(z); + if (czm.isInfinite() || czm.isNaN()) { + break; + } + tempczm = setArrayDeepValue(secondReferenceDeepData.Reference, iterations, czm); + } + if(lowPrecReferenceOrbitNeeded) { - setArrayValue(secondReferenceData.PrecalculatedTerms[0], iterations, preCalc.toComplex()); + cz = deepZoom ? czm.toComplex() : z.toComplex(); + if (cz.isInfinite() || cz.isNaN()) { + break; + } + + cz = setArrayValue(secondReferenceData.Reference, iterations, cz); } + czm = tempczm; + if(deepZoom) { - setArrayDeepValue(secondReferenceDeepData.Reference, iterations, loc.getMantExpComplex(z)); - setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[0], iterations, loc.getMantExpComplex(preCalc)); + precalm = loc.getMantExpComplex(preCalc); + zsubcpm = loc.getMantExpComplex(zsubcp); + setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[0], iterations, precalm, czm); + setArrayDeepValue(secondReferenceDeepData.ReferenceSubCp, iterations, zsubcpm, czm); + } + + if(lowPrecReferenceOrbitNeeded) { + setArrayValue(secondReferenceData.PrecalculatedTerms[0], iterations, deepZoom ? precalm.toComplex() : preCalc.toComplex(), cz); + setArrayValue(secondReferenceData.ReferenceSubCp, iterations, deepZoom ? zsubcpm.toComplex() : zsubcp.toComplex(), cz); } if (iterations > 0 && convergent_bailout_algorithm.Converged(z, zold, zold2, iterations, c, start, c0, pixel)) { @@ -1402,6 +1528,30 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { secondReferenceData.MaxRefIteration = iterations - 1; + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[secondReferenceDeepData.Reference.id].compact(secondReferenceDeepData.Reference); + secondReferenceData.compressorZm = referenceCompressor[secondReferenceDeepData.Reference.id].getZDeep(); + + subexpressionsCompressor[secondReferenceDeepData.ReferenceSubCp.id].compact(secondReferenceDeepData.ReferenceSubCp); + + for(int i = 0; i < preCalcIndexes.length; i++) { + subexpressionsCompressor[secondReferenceDeepData.PrecalculatedTerms[preCalcIndexes[i]].id].compact(secondReferenceDeepData.PrecalculatedTerms[preCalcIndexes[i]]); + } + } + + if(lowPrecReferenceOrbitNeeded) { + referenceCompressor[secondReferenceData.Reference.id].compact(secondReferenceData.Reference); + secondReferenceData.compressorZ = referenceCompressor[secondReferenceData.Reference.id].getZ(); + + subexpressionsCompressor[secondReferenceData.ReferenceSubCp.id].compact(secondReferenceData.ReferenceSubCp); + + for(int i = 0; i < preCalcIndexes.length; i++) { + subexpressionsCompressor[secondReferenceData.PrecalculatedTerms[preCalcIndexes[i]].id].compact(secondReferenceData.PrecalculatedTerms[preCalcIndexes[i]]); + } + } + } + if(progress != null) { progress.setValue(progress.getMaximum()); progress.setString(REFERENCE_CALCULATION_STR + " 100%"); @@ -1437,7 +1587,7 @@ public Complex perturbationFunction(Complex z, Complex c, int RefIteration) { Complex Z = getArrayValue(reference, RefIteration); Complex temp = Z.times2().plus_mutable(z).times_mutable(z).times_mutable(Z.square()); - return temp.plus(getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration)).sub_mutable(z.times(0.5)).times_mutable(z).divide_mutable(temp.plus(Z.fourth()).times_mutable(1.5)).plus_mutable(c); + return temp.plus(getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration , Z)).sub_mutable(z.times(0.5)).times_mutable(z).divide_mutable(temp.plus(Z.fourth()).times_mutable(1.5)).plus_mutable(c); } @Override @@ -1446,7 +1596,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, MantExpComplex c, i MantExpComplex Z = getArrayDeepValue(referenceDeep, RefIteration); MantExpComplex temp = Z.times2().plus_mutable(z).times_mutable(z).times_mutable(Z.square()); - return temp.plus(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration)).sub_mutable(z.divide2()).times_mutable(z).divide_mutable(temp.plus(Z.fourth()).times_mutable(MantExp.ONEPOINTFIVE)).plus_mutable(c); + return temp.plus(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration, Z)).sub_mutable(z.divide2()).times_mutable(z).divide_mutable(temp.plus(Z.fourth()).times_mutable(MantExp.ONEPOINTFIVE)).plus_mutable(c); } @Override @@ -1455,7 +1605,7 @@ public Complex perturbationFunction(Complex z, int RefIteration) { Complex Z = getArrayValue(reference, RefIteration); Complex temp = Z.times2().plus_mutable(z).times_mutable(z).times_mutable(Z.square()); - return temp.plus(getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration)).sub_mutable(z.times(0.5)).times_mutable(z).divide_mutable(temp.plus(Z.fourth()).times_mutable(1.5)); + return temp.plus(getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration, Z)).sub_mutable(z.times(0.5)).times_mutable(z).divide_mutable(temp.plus(Z.fourth()).times_mutable(1.5)); } @@ -1465,7 +1615,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, int RefIteration) { MantExpComplex Z = getArrayDeepValue(referenceDeep, RefIteration); MantExpComplex temp = Z.times2().plus_mutable(z).times_mutable(z).times_mutable(Z.square()); - return temp.plus(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration)).sub_mutable(z.divide2()).times_mutable(z).divide_mutable(temp.plus(Z.fourth()).times_mutable(MantExp.ONEPOINTFIVE)); + return temp.plus(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration, Z)).sub_mutable(z.divide2()).times_mutable(z).divide_mutable(temp.plus(Z.fourth()).times_mutable(MantExp.ONEPOINTFIVE)); } @Override @@ -1474,7 +1624,7 @@ public Complex perturbationFunction(Complex z, ReferenceData data, int RefIterat Complex Z = getArrayValue(data.Reference, RefIteration); Complex temp = Z.times2().plus_mutable(z).times_mutable(z).times_mutable(Z.square()); - return temp.plus(getArrayValue(data.PrecalculatedTerms[0], RefIteration)).sub_mutable(z.times(0.5)).times_mutable(z).divide_mutable(temp.plus(Z.fourth()).times_mutable(1.5)); + return temp.plus(getArrayValue(data.PrecalculatedTerms[0], RefIteration, Z)).sub_mutable(z.times(0.5)).times_mutable(z).divide_mutable(temp.plus(Z.fourth()).times_mutable(1.5)); } @@ -1484,7 +1634,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, ReferenceDeepData d MantExpComplex Z = getArrayDeepValue(data.Reference, RefIteration); MantExpComplex temp = Z.times2().plus_mutable(z).times_mutable(z).times_mutable(Z.square()); - return temp.plus(getArrayDeepValue(data.PrecalculatedTerms[0], RefIteration)).sub_mutable(z.divide2()).times_mutable(z).divide_mutable(temp.plus(Z.fourth()).times_mutable(MantExp.ONEPOINTFIVE)); + return temp.plus(getArrayDeepValue(data.PrecalculatedTerms[0], RefIteration, Z)).sub_mutable(z.divide2()).times_mutable(z).divide_mutable(temp.plus(Z.fourth()).times_mutable(MantExp.ONEPOINTFIVE)); } @Override @@ -1545,4 +1695,32 @@ public boolean supportsBigIntnum() { return true; } + @Override + public boolean supportsReferenceCompression() { + return true; + } + + @Override + public Complex function(Complex z, Complex c) { + return z.sub_mutable(z.cube().sub_mutable(1).divide_mutable(z.square().times_mutable(3))).plus_mutable(c); + } + + @Override + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + return z.sub_mutable(z.cube().sub_mutable(MantExp.ONE).divide_mutable(z.square().times_mutable(MantExp.THREE))).plus_mutable(c); + } + + @Override + protected boolean needsRefSubCp() { + return true; + } + + @Override + public double getPower() { + if(z_exponent.getRe() != 0 && z_exponent.getIm() == 0) { + return z_exponent.getRe(); + } + return 0; + } + } diff --git a/src/fractalzoomer/functions/lambda/Lambda.java b/src/fractalzoomer/functions/lambda/Lambda.java index 28cca1ae1..91d8f72c9 100644 --- a/src/fractalzoomer/functions/lambda/Lambda.java +++ b/src/fractalzoomer/functions/lambda/Lambda.java @@ -29,6 +29,7 @@ import fractalzoomer.utils.NormComponents; import java.util.ArrayList; +import java.util.function.Function; /** * @@ -46,8 +47,6 @@ public Lambda(double xCenter, double yCenter, double size, int max_iterations, i defaultInitVal = new InitialValue(0.5, 0); - power = 2; - setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); if(init_value) { @@ -80,8 +79,6 @@ public Lambda(double xCenter, double yCenter, double size, int max_iterations, i super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, xJuliaCenter, yJuliaCenter); - power = 2; - defaultInitVal = new InitialValue(0.5, 0); OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, escaping_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); @@ -101,8 +98,6 @@ public Lambda(double xCenter, double yCenter, double size, int max_iterations, A super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower); - power = 2; - defaultInitVal = new InitialValue(0.5, 0); setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); @@ -132,7 +127,6 @@ public Lambda(double xCenter, double yCenter, double size, int max_iterations, A defaultInitVal = new InitialValue(0.5, 0); pertur_val = new DefaultPerturbation(); init_val = defaultInitVal; - power = 2; } @Override @@ -180,11 +174,14 @@ public Complex perturbationFunction(Complex z, Complex c, int RefIteration) { return DeltaSub0.negative().times(DnSqrPlustwoDnXn.plus(X.square()).sub_mutable(0.25)) .sub_mutable(refPointSmall.times(DnSqrPlustwoDnXn));*/ + Complex refZ = null; + if(reference.compressed) { + refZ = getArrayValue(reference, RefIteration); + } + Complex temp = z.plus(getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration, refZ)).times_mutable(z).negative_mutable(); - Complex temp = z.plus(getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration)).times_mutable(z).negative_mutable(); - - return temp.times(C).plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration).plus_mutable(temp).times_mutable(c)); + return temp.times(C).plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration, refZ).plus_mutable(temp).times_mutable(c)); @@ -193,15 +190,25 @@ public Complex perturbationFunction(Complex z, Complex c, int RefIteration) { @Override public MantExpComplex perturbationFunction(MantExpComplex z, MantExpComplex c, int RefIteration) { - MantExpComplex temp = z.plus(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration)).times_mutable(z).negative_mutable(); + MantExpComplex refZ = null; + if(referenceDeep.compressed) { + refZ = getArrayDeepValue(referenceDeep, RefIteration); + } + + MantExpComplex temp = z.plus(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration, refZ)).times_mutable(z).negative_mutable(); - return temp.times(Cdeep).plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration).plus_mutable(temp).times_mutable(c)); + return temp.times(Cdeep).plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration, refZ).plus_mutable(temp).times_mutable(c)); } @Override public Complex perturbationFunction(Complex z, int RefIteration) { - Complex temp = z.plus(getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration)).times_mutable(z).negative_mutable(); + Complex refZ = null; + if(reference.compressed) { + refZ = getArrayValue(reference, RefIteration); + } + + Complex temp = z.plus(getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration, refZ)).times_mutable(z).negative_mutable(); return temp.times(C); } @@ -209,7 +216,12 @@ public Complex perturbationFunction(Complex z, int RefIteration) { @Override public MantExpComplex perturbationFunction(MantExpComplex z, int RefIteration) { - MantExpComplex temp = z.plus(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration)).times_mutable(z).negative_mutable(); + MantExpComplex refZ = null; + if(referenceDeep.compressed) { + refZ = getArrayDeepValue(referenceDeep, RefIteration); + } + + MantExpComplex temp = z.plus(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration, refZ)).times_mutable(z).negative_mutable(); return temp.times(Cdeep); } @@ -217,7 +229,12 @@ public MantExpComplex perturbationFunction(MantExpComplex z, int RefIteration) { @Override public Complex perturbationFunction(Complex z, ReferenceData data, int RefIteration) { - Complex temp = z.plus(getArrayValue(data.PrecalculatedTerms[0], RefIteration)).times_mutable(z).negative_mutable(); + Complex refZ = null; + if(data.Reference.compressed) { + refZ = getArrayValue(data.Reference, RefIteration); + } + + Complex temp = z.plus(getArrayValue(data.PrecalculatedTerms[0], RefIteration, refZ)).times_mutable(z).negative_mutable(); return temp.times(C); } @@ -225,7 +242,12 @@ public Complex perturbationFunction(Complex z, ReferenceData data, int RefIterat @Override public MantExpComplex perturbationFunction(MantExpComplex z, ReferenceDeepData data, int RefIteration) { - MantExpComplex temp = z.plus(getArrayDeepValue(data.PrecalculatedTerms[0], RefIteration)).times_mutable(z).negative_mutable(); + MantExpComplex refZ = null; + if(data.Reference.compressed) { + refZ = getArrayDeepValue(data.Reference, RefIteration); + } + + MantExpComplex temp = z.plus(getArrayDeepValue(data.PrecalculatedTerms[0], RefIteration, refZ)).times_mutable(z).negative_mutable(); return temp.times(Cdeep); } @@ -252,14 +274,19 @@ public double iterateFractalWithPerturbation(Complex[] complex, Complex dpixel) int MaxRefIteration = getReferenceFinalIterationNumber(true, referenceData); + Complex refZ; Complex zWithoutInitVal = new Complex(); if(iterations != 0 && RefIteration < MaxRefIteration) { - complex[0] = getArrayValue(reference, RefIteration).plus_mutable(DeltaSubN); + refZ = getArrayValue(reference, RefIteration); + zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration, refZ).plus_mutable(DeltaSubN); + complex[0] = refZ.plus_mutable(DeltaSubN); } else if(iterations != 0 && ReferencePeriod != 0) { RefIteration = RefIteration % ReferencePeriod; - complex[0] = getArrayValue(reference, RefIteration).plus_mutable(DeltaSubN); + refZ = getArrayValue(reference, RefIteration); + zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration, refZ).plus_mutable(DeltaSubN); + complex[0] = refZ.plus_mutable(DeltaSubN); } Complex pixel = dpixel.plus(refPointSmall); @@ -298,8 +325,9 @@ else if(iterations != 0 && ReferencePeriod != 0) { //No Plane influence work //No Pre filters work if(max_iterations > 1){ - zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration).plus_mutable(DeltaSubN); - complex[0] = getArrayValue(reference, RefIteration).plus_mutable(DeltaSubN); + refZ = getArrayValue(reference, RefIteration); + zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration, refZ).plus_mutable(DeltaSubN); + complex[0] = refZ.plus_mutable(DeltaSubN); } //No Post filters work @@ -350,7 +378,7 @@ public double iterateFractalWithPerturbation(Complex[] complex, MantExpComplex d int MaxRefIteration = getReferenceFinalIterationNumber(true, referenceData); int minExp = -1000; - int reducedExp = minExp / (int)power; + int reducedExp = minExp / (int)getPower(); DeltaSubN.Normalize(); long exp = DeltaSubN.getMinExp(); @@ -363,32 +391,35 @@ public double iterateFractalWithPerturbation(Complex[] complex, MantExpComplex d boolean usedDeepCode = false; + MantExpComplex refZm; + if(useFullFloatExp || (totalSkippedIterations == 0 && exp <= minExp) || (totalSkippedIterations != 0 && exp <= reducedExp)) { usedDeepCode = true; + MantExpComplex zWithoutInitVal = MantExpComplex.create(); MantExpComplex z = MantExpComplex.create(); if(iterations != 0 && RefIteration < MaxRefIteration) { - z = getArrayDeepValue(referenceDeepData.ReferenceSubCp, RefIteration).plus_mutable(DeltaSubN); - complex[0] = getArrayDeepValue(referenceDeep, RefIteration).plus_mutable(DeltaSubN).toComplex(); + refZm = getArrayDeepValue(referenceDeep, RefIteration); + zWithoutInitVal = getArrayDeepValue(referenceDeepData.ReferenceSubCp, RefIteration, refZm).plus_mutable(DeltaSubN); + z = refZm.plus_mutable(DeltaSubN); + complex[0] = z.toComplex(); } else if(iterations != 0 && ReferencePeriod != 0) { RefIteration = RefIteration % ReferencePeriod; - z = getArrayDeepValue(referenceDeepData.ReferenceSubCp, RefIteration).plus_mutable(DeltaSubN); - complex[0] = getArrayDeepValue(referenceDeep, RefIteration).plus_mutable(DeltaSubN).toComplex(); + refZm = getArrayDeepValue(referenceDeep, RefIteration); + zWithoutInitVal = getArrayDeepValue(referenceDeepData.ReferenceSubCp, RefIteration, refZm).plus_mutable(DeltaSubN); + z = refZm.plus_mutable(DeltaSubN); + complex[0] = z.toComplex(); } MantExpComplex zoldDeep; - MantExp norm_squared_m = null; - if(doBailCheck) { - norm_squared_m = z.norm_squared(); - } for (; iterations < max_iterations; iterations++) { if (trap != null) { trap.check(complex[0], iterations); } - if (doBailCheck && bailout_algorithm2.escaped(complex[0], zold, zold2, iterations, complex[1], start, c0, norm_squared_m.toDouble(), pixel)) { + if (doBailCheck && bailout_algorithm.escaped(complex[0], zold, zold2, iterations, complex[1], start, c0, 0.0, pixel)) { escaped = true; Object[] object = {iterations, complex[0], zold, zold2, complex[1], start, c0, pixel}; @@ -413,17 +444,18 @@ else if(iterations != 0 && ReferencePeriod != 0) { zoldDeep = z; if (max_iterations > 1) { - z = getArrayDeepValue(referenceDeepData.ReferenceSubCp, RefIteration).plus_mutable(DeltaSubN); - complex[0] = getArrayDeepValue(referenceDeep, RefIteration).plus_mutable(DeltaSubN).toComplex(); + refZm = getArrayDeepValue(referenceDeep, RefIteration); + zWithoutInitVal = getArrayDeepValue(referenceDeepData.ReferenceSubCp, RefIteration, refZm).plus_mutable(DeltaSubN); + z = refZm.plus_mutable(DeltaSubN); + complex[0] = z.toComplex(); } if (statistic != null) { statistic.insert(complex[0], zold, zold2, iterations, complex[1], start, c0, z, zoldDeep, cDeep); } - norm_squared_m = z.norm_squared(); - if (norm_squared_m.compareToBothPositive(DeltaSubN.norm_squared()) < 0 || RefIteration >= MaxRefIteration) { - DeltaSubN = z; + if (zWithoutInitVal.norm_squared().compareToBothPositive(DeltaSubN.norm_squared()) < 0 || RefIteration >= MaxRefIteration) { + DeltaSubN = zWithoutInitVal; RefIteration = 0; rebases++; } @@ -446,12 +478,18 @@ else if(iterations != 0 && ReferencePeriod != 0) { boolean isZero = CDeltaSub0.isZero(); Complex zWithoutInitVal = new Complex(); + Complex refZ; + if(!usedDeepCode && iterations != 0 && RefIteration < MaxRefIteration) { - complex[0] = getArrayValue(reference, RefIteration).plus_mutable(CDeltaSubN); + refZ = getArrayValue(reference, RefIteration); + zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration, refZ).plus_mutable(CDeltaSubN); + complex[0] = refZ.plus_mutable(CDeltaSubN); } else if(!usedDeepCode && iterations != 0 && ReferencePeriod != 0) { RefIteration = RefIteration % ReferencePeriod; - complex[0] = getArrayValue(reference, RefIteration).plus_mutable(CDeltaSubN); + refZ = getArrayValue(reference, RefIteration); + zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration, refZ).plus_mutable(CDeltaSubN); + complex[0] = refZ.plus_mutable(CDeltaSubN); } for (; iterations < max_iterations; iterations++) { @@ -492,8 +530,9 @@ else if(!usedDeepCode && iterations != 0 && ReferencePeriod != 0) { //No Plane influence work //No Pre filters work if (max_iterations > 1) { - zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration).plus_mutable(CDeltaSubN); - complex[0] = getArrayValue(reference, RefIteration).plus_mutable(CDeltaSubN); + refZ = getArrayValue(reference, RefIteration); + zWithoutInitVal = getArrayValue(referenceData.ReferenceSubCp, RefIteration, refZ).plus_mutable(CDeltaSubN); + complex[0] = refZ.plus_mutable(CDeltaSubN); } //No Post filters work @@ -543,6 +582,8 @@ public double iterateJuliaWithPerturbation(Complex[] complex, Complex dpixel) { Complex zWithoutInitVal = new Complex(); + Complex refZ; + for (; iterations < max_iterations; iterations++) { //No update values @@ -576,9 +617,10 @@ public double iterateJuliaWithPerturbation(Complex[] complex, Complex dpixel) { //No Plane influence work //No Pre filters work - if(max_iterations > 1){ - zWithoutInitVal = getArrayValue(data.ReferenceSubCp, RefIteration).plus_mutable(DeltaSubN); - complex[0] = getArrayValue(data.Reference, RefIteration).plus_mutable(DeltaSubN); + if(max_iterations > 1) { + refZ = getArrayValue(data.Reference, RefIteration); + zWithoutInitVal = getArrayValue(data.ReferenceSubCp, RefIteration, refZ).plus_mutable(DeltaSubN); + complex[0] = refZ.plus_mutable(DeltaSubN); } //No Post filters work @@ -625,14 +667,17 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi MantExpComplex[] deltas = initializePerturbation(dpixel); MantExpComplex DeltaSubN = deltas[0]; // Delta z - Complex pixel = dpixel.plus(refPointSmallDeep).toComplex(); + MantExpComplex cDeep = dpixel.plus(refPointSmallDeep); + Complex pixel = cDeep.toComplex(); ReferenceDeepData deepData = referenceDeepData; ReferenceData data = referenceData; int MaxRefIteration = data.MaxRefIteration; int minExp = -1000; - int reducedExp = minExp / (int)power; + int reducedExp = minExp / (int)getPower(); + + MantExpComplex refZm; DeltaSubN.Normalize(); long exp = DeltaSubN.getMinExp(); @@ -641,7 +686,9 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi boolean doBailCheck = useFullFloatExp || TaskDraw.CHECK_BAILOUT_DURING_DEEP_NOT_FULL_FLOATEXP_MODE; if(useFullFloatExp || (totalSkippedIterations == 0 && exp <= minExp) || (totalSkippedIterations != 0 && exp <= reducedExp)) { - MantExpComplex z = getArrayDeepValue(deepData.ReferenceSubCp, RefIteration).plus_mutable(DeltaSubN); + MantExpComplex zWithoutInitVal = MantExpComplex.create(); + MantExpComplex z = getArrayDeepValue(deepData.Reference, RefIteration).plus_mutable(DeltaSubN); + MantExpComplex zoldDeep; for (; iterations < max_iterations; iterations++) { if (trap != null) { @@ -670,18 +717,21 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi zold2.assign(zold); zold.assign(complex[0]); + zoldDeep = z; if (max_iterations > 1) { - z = getArrayDeepValue(deepData.ReferenceSubCp, RefIteration).plus_mutable(DeltaSubN); - complex[0] = getArrayDeepValue(deepData.Reference, RefIteration).plus_mutable(DeltaSubN).toComplex(); + refZm = getArrayDeepValue(deepData.Reference, RefIteration); + zWithoutInitVal = getArrayDeepValue(deepData.ReferenceSubCp, RefIteration, refZm).plus_mutable(DeltaSubN); + z = refZm.plus_mutable(DeltaSubN); + complex[0] = z.toComplex(); } if (statistic != null) { - statistic.insert(complex[0], zold, zold2, iterations, complex[1], start, c0); + statistic.insert(complex[0], zold, zold2, iterations, complex[1], start, c0, z, zoldDeep , cDeep); } - if (z.norm_squared().compareToBothPositive(DeltaSubN.norm_squared()) < 0 || RefIteration >= MaxRefIteration) { - DeltaSubN = z; + if (zWithoutInitVal.norm_squared().compareToBothPositive(DeltaSubN.norm_squared()) < 0 || RefIteration >= MaxRefIteration) { + DeltaSubN = zWithoutInitVal; RefIteration = 0; deepData = secondReferenceDeepData; @@ -707,6 +757,8 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi Complex zWithoutInitVal = new Complex(); + Complex refZ; + for (; iterations < max_iterations; iterations++) { //No update values @@ -741,8 +793,9 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi //No Plane influence work //No Pre filters work if (max_iterations > 1) { - zWithoutInitVal = getArrayValue(data.ReferenceSubCp, RefIteration).plus_mutable(CDeltaSubN); - complex[0] = getArrayValue(data.Reference, RefIteration).plus_mutable(CDeltaSubN); + refZ = getArrayValue(data.Reference, RefIteration); + zWithoutInitVal = getArrayValue(data.ReferenceSubCp, RefIteration, refZ).plus_mutable(CDeltaSubN); + complex[0] = refZ.plus_mutable(CDeltaSubN); } //No Post filters work @@ -796,7 +849,7 @@ protected boolean needsRefSubCp() { } @Override - protected GenericComplex[] precalculateReferenceData(GenericComplex z, GenericComplex c, NormComponents normData, Location loc, int bigNumLib, boolean lowPrecReferenceOrbitNeeded, boolean deepZoom, ReferenceData referenceData, ReferenceDeepData referenceDeepData, int iterations) { + protected GenericComplex[] precalculateReferenceData(GenericComplex z, GenericComplex c, NormComponents normData, Location loc, int bigNumLib, boolean lowPrecReferenceOrbitNeeded, boolean deepZoom, ReferenceData referenceData, ReferenceDeepData referenceDeepData, int iterations, Complex cz, MantExpComplex mcz) { GenericComplex preCalc; @@ -811,16 +864,18 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { preCalc = z.times2().sub_mutable(1); //2*Z-1 for catastrophic cancelation } - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[0], iterations, preCalc.toComplex()); - } + MantExpComplex precalcm = null; if(deepZoom) { - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], iterations, loc.getMantExpComplex(preCalc)); + precalcm = loc.getMantExpComplex(preCalc); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], iterations, precalcm, mcz); + } + if(lowPrecReferenceOrbitNeeded) { + setArrayValue(referenceData.PrecalculatedTerms[0], iterations, deepZoom ? precalcm.toComplex() : preCalc.toComplex(), cz); } GenericComplex preCalc2; - //Maybe this is not needed, as Z^2 - Z does not go to 0 when Z = 0.5 + //Maybe this is not needed, as Z-Z^2 does not go to 0 when Z = 0.5 if(normData != null) { preCalc2 = z.sub(z.squareFast(normData)); } @@ -829,12 +884,13 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { } if(!isJulia) { - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[1], iterations, preCalc2.toComplex()); - } - + MantExpComplex precalc2m = null; if(deepZoom) { - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], iterations, loc.getMantExpComplex(preCalc2)); + precalc2m = loc.getMantExpComplex(preCalc2); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], iterations, precalc2m, mcz); + } + if(lowPrecReferenceOrbitNeeded) { + setArrayValue(referenceData.PrecalculatedTerms[1], iterations, deepZoom ? precalc2m.toComplex() : preCalc2.toComplex(), cz); } } @@ -851,7 +907,27 @@ protected int[] getNeededPrecalculatedTermsIndexes() { } @Override - protected void calculateRefSubCp(GenericComplex z, GenericComplex initVal, Location loc, int bigNumLib, boolean lowPrecReferenceOrbitNeeded, boolean deepZoom, ReferenceData referenceData, ReferenceDeepData referenceDeepData, int iterations) { + protected Function[] getPrecalculatedTermsFunctions(Complex c) { + Function f1 = x -> x.times2().sub_mutable(1); + if (!isJulia) { + Function f2 = x -> x.sub(x.square()); + return new Function[] {f1, f2}; + } + return new Function[] {f1}; + } + + @Override + protected Function[] getPrecalculatedTermsFunctionsDeep(MantExpComplex c) { + Function f1 = x -> x.times2().sub_mutable(MantExp.ONE); + if (!isJulia) { + Function f2 = x -> x.sub(x.square()); + return new Function[] {f1, f2}; + } + return new Function[] {f1}; + } + + @Override + protected void calculateRefSubCp(GenericComplex z, GenericComplex initVal, Location loc, int bigNumLib, boolean lowPrecReferenceOrbitNeeded, boolean deepZoom, ReferenceData referenceData, ReferenceDeepData referenceDeepData, int iterations, Complex cz, MantExpComplex mcz) { GenericComplex zsubcp; if(bigNumLib == Constants.BIGNUM_MPFR) { @@ -864,11 +940,14 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { zsubcp = z.sub(initVal); } - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.ReferenceSubCp, iterations, zsubcp.toComplex()); - } + MantExpComplex zsubcpm = null; if(deepZoom) { - setArrayDeepValue(referenceDeepData.ReferenceSubCp, iterations, loc.getMantExpComplex(zsubcp)); + zsubcpm = loc.getMantExpComplex(zsubcp); + setArrayDeepValue(referenceDeepData.ReferenceSubCp, iterations, zsubcpm, mcz); + } + + if(lowPrecReferenceOrbitNeeded) { + setArrayValue(referenceData.ReferenceSubCp, iterations, deepZoom ? zsubcpm.toComplex() : zsubcp.toComplex(), cz); } } @@ -877,4 +956,24 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { protected GenericComplex referenceFunction(GenericComplex z, GenericComplex c, NormComponents normData, GenericComplex[] initialPrecal, GenericComplex[] precalc) { return precalc[0].times_mutable(c); } + + @Override + public boolean supportsReferenceCompression() { + return true; + } + + @Override + public Complex function(Complex z, Complex c) { + return c.times(z.sub(z.square())); + } + + @Override + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + return c.times(z.sub(z.square())); + } + + @Override + public double getPower() { + return 2; + } } diff --git a/src/fractalzoomer/functions/magnet/Magnet1.java b/src/fractalzoomer/functions/magnet/Magnet1.java index d7fc1c34d..c0b9a16ca 100644 --- a/src/fractalzoomer/functions/magnet/Magnet1.java +++ b/src/fractalzoomer/functions/magnet/Magnet1.java @@ -33,6 +33,7 @@ import javax.swing.*; import java.util.ArrayList; +import java.util.function.Function; import static fractalzoomer.main.Constants.REFERENCE_CALCULATION_STR; @@ -65,9 +66,7 @@ public Magnet1(double xCenter, double yCenter, double size, int max_iterations, super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - convergent_bailout = 1E-12; - - power = 4; + setConvergentBailout(1E-12); setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); @@ -91,10 +90,8 @@ public Magnet1(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.ITERATIONS_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; - break; case MainWindow.ITERATIONS_PLUS_RE_PLUS_IM_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; } @@ -112,17 +109,13 @@ public Magnet1(double xCenter, double yCenter, double size, int max_iterations, super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, xJuliaCenter, yJuliaCenter); - convergent_bailout = 1E-12; - - power = 4; + setConvergentBailout(1E-12); switch (out_coloring_algorithm) { case MainWindow.ITERATIONS_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; - break; case MainWindow.ITERATIONS_PLUS_RE_PLUS_IM_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; } @@ -143,8 +136,6 @@ public Magnet1(double xCenter, double yCenter, double size, int max_iterations, super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower); - power = 4; - setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); if(init_value) { @@ -169,7 +160,6 @@ public Magnet1(double xCenter, double yCenter, double size, int max_iterations, public Magnet1(double xCenter, double yCenter, double size, int max_iterations, ArrayList complex_orbit, int plane_type, boolean apply_plane_on_julia, boolean apply_plane_on_julia_seed, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, double xJuliaCenter, double yJuliaCenter) { super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); - power = 4; pertur_val = new DefaultPerturbation(); init_val = new InitialValue(0, 0); } @@ -189,6 +179,167 @@ public boolean supportsPerturbationTheory() { return !isJulia || !juliter; } + @Override + protected int[] getNeededPrecalculatedTermsIndexes() { + if(!isJulia) { + return new int[] {0, 1, 2, 3, 4, 5, 6, 7}; + } + return new int[] {0, 1, 2, 3, 6}; + } + + @Override + protected Function[] getPrecalculatedTermsFunctions(Complex c) { + + Complex csqr = c.square(); + Complex ccube = c.cube(); + Complex c4 = c.times4(); + Complex csqrsc4 = csqr.sub(c4); + Complex precalc2 = csqrsc4.plus(4); + Complex cs2 = c.sub(2); + Complex cs24 = cs2.times4(); + Complex cs23 = cs2.times(3); + Complex c12 = c.times(12); + Complex c12s6 = c12.sub(6); + Complex precalc6 = ccube.sub(csqr.times(7)).plus_mutable(c12s6); + Complex csqr4 = csqr.times4(); + + Complex precalcl = csqr.sub(c.times(3)).plus_mutable(2); + Complex precalc12 = ccube.negative().plus_mutable(csqr4).sub_mutable(c.times(5)).plus_mutable(2); + Complex precalc14 = precalcl.times2(); + Complex csqr24 = csqr.times(24); + Complex c12s8 = c12.sub(8); + + Complex precalc10 = c.fourth().sub_mutable(ccube.times(8)).plus_mutable(csqr24).sub_mutable(c.times(32)).plus_mutable(16); + Complex precalc4 = ccube.sub(csqr.times(6)); + Complex precalc5 = precalc4.plus(c12s8).times_mutable(8); + Complex cs212 = cs2.times(12); + Complex csqr7 = csqr.times(7); + + Complex precalc11 = ccube.sub(csqr7).plus_mutable(c12s6); + + Function f1 = x -> precalc2.plus(cs24.times(x)).plus_mutable(x.square().times4_mutable()); + + Function f2 = x -> cs23.times(x.cube()).plus_mutable(x.fourth().times2_mutable()).plus_mutable(precalc2.times(x.square())).plus_mutable(precalc14.times(x)) + .plus_mutable(precalc6).times_mutable(x).plus_mutable(precalc12); + + Function f3 = x -> precalc10.plus(cs2.times(x.cube()).times_mutable(32)).plus_mutable(x.cube().times_mutable(16).plus_mutable(precalc2.times(x).times_mutable(24)).plus_mutable(precalc5).times_mutable(x)); + + Function f4 = x -> precalc4.plus(cs212.times(x.square())).plus_mutable(x.cube().times_mutable(8)).plus_mutable(precalc2.times(x).times_mutable(6)).plus_mutable(c12s8); + + Function f7 = x -> precalc2.plus(cs24.times(x)).times_mutable(x.square()).times_mutable(3) + .plus_mutable(x.fourth().times_mutable(10)) + .plus_mutable(precalc11).plus_mutable(precalcl.times4().times_mutable(x)); + + if(!isJulia) { + Complex c2 = c.times2(); + Complex precalc9 = csqr.sub(c2).plus_mutable(1); + Complex precalc13 = c2.sub(3); + Complex precalc8 = c.sub(3).times2_mutable(); + Complex precalc3 = csqrsc4.plus(3).times2_mutable(); + Complex precalc7 = csqr.sub(c.times(6)).plus_mutable(4); + Complex cs6 = c.sub(6); + + Function f5 = x -> precalc9.sub(precalc2.plus(x.square().times4_mutable()).sub_mutable(x.cube().sub_mutable(precalc8.times(x))).times_mutable(x)); + Function f6 = x -> x.cube().plus_mutable(precalc8.times(x)).sub_mutable(cs24).times_mutable(x).plus_mutable(precalc13); + Function f8 = x -> cs6.times(x.cube()).plus_mutable(x.fourth().times2_mutable()).plus_mutable(precalc7.times(x)).plus_mutable(x.square().times4_mutable()) + .sub_mutable(precalc3).times_mutable(x).plus_mutable(precalcl); + + return new Function[] {f1, f2, f3, f4, f5, f6, f7, f8}; + } + return new Function[] {f1, f2, f3, f4, f7}; + } + + @Override + protected Function[] getPrecalculatedTermsFunctionsDeep(MantExpComplex c) { + MantExpComplex csqr = c.square(); + csqr.Normalize(); + MantExpComplex ccube = c.cube(); + ccube.Normalize(); + MantExpComplex c4 = c.times4(); + c4.Normalize(); + MantExpComplex csqrsc4 = csqr.sub(c4); + csqrsc4.Normalize(); + MantExpComplex precalc2 = csqrsc4.plus(MantExp.FOUR); + precalc2.Normalize(); + MantExpComplex cs2 = c.sub(MantExp.TWO); + cs2.Normalize(); + MantExpComplex cs24 = cs2.times4(); + cs24.Normalize(); + MantExpComplex cs23 = cs2.times(MantExp.THREE); + cs23.Normalize(); + MantExpComplex c12 = c.times(MantExp.TWELVE); + c12.Normalize(); + MantExpComplex c12s6 = c12.sub(MantExp.SIX); + c12s6.Normalize(); + MantExpComplex precalc6 = ccube.sub(csqr.times(MantExp.SEVEN)).plus_mutable(c12s6); + precalc6.Normalize(); + MantExpComplex csqr4 = csqr.times4(); + csqr4.Normalize(); + + MantExpComplex precalcl = csqr.sub(c.times(MantExp.THREE)).plus_mutable(MantExp.TWO); + precalcl.Normalize(); + MantExpComplex precalc12 = ccube.negative().plus_mutable(csqr4).sub_mutable(c.times(MantExp.FIVE)).plus_mutable(MantExp.TWO); + precalc12.Normalize(); + MantExpComplex precalc14 = precalcl.times2(); + precalc14.Normalize(); + MantExpComplex csqr24 = csqr.times(MantExp.TWENTYFOUR); + csqr24.Normalize(); + MantExpComplex c12s8 = c12.sub(MantExp.EIGHT); + c12s8.Normalize(); + + MantExpComplex precalc10 = c.fourth().sub_mutable(ccube.times8()).plus_mutable(csqr24).sub_mutable(c.times32()).plus_mutable(MantExp.SIXTEEN); + precalc10.Normalize(); + MantExpComplex precalc4 = ccube.sub(csqr.times(MantExp.SIX)); + precalc4.Normalize(); + MantExpComplex precalc5 = precalc4.plus(c12s8).times8_mutable(); + precalc5.Normalize(); + MantExpComplex cs212 = cs2.times(MantExp.TWELVE); + cs212.Normalize(); + MantExpComplex csqr7 = csqr.times(MantExp.SEVEN); + csqr7.Normalize(); + + MantExpComplex precalc11 = ccube.sub(csqr7).plus_mutable(c12s6); + precalc11.Normalize(); + + Function f1 = x -> precalc2.plus(cs24.times(x)).plus_mutable(x.square().times4_mutable()); + + Function f2 = x -> cs23.times(x.cube()).plus_mutable(x.fourth().times2_mutable()).plus_mutable(precalc2.times(x.square())).plus_mutable(precalc14.times(x)) + .plus_mutable(precalc6).times_mutable(x).plus_mutable(precalc12); + + Function f3 = x -> precalc10.plus(cs2.times(x.cube()).times32_mutable()).plus_mutable(x.cube().times16_mutable().plus_mutable(precalc2.times(x).times_mutable(MantExp.TWENTYFOUR)).plus_mutable(precalc5).times_mutable(x)); + + Function f4 = x -> precalc4.plus(cs212.times(x.square())).plus_mutable(x.cube().times8_mutable()).plus_mutable(precalc2.times(x).times_mutable(MantExp.SIX)).plus_mutable(c12s8); + + Function f7 = x -> precalc2.plus(cs24.times(x)).times_mutable(x.square()).times_mutable(MantExp.THREE) + .plus_mutable(x.fourth().times_mutable(MantExp.TEN)) + .plus_mutable(precalc11).plus_mutable(precalcl.times4().times_mutable(x)); + + if(!isJulia) { + MantExpComplex c2 = c.times2(); + c2.Normalize(); + MantExpComplex precalc9 = csqr.sub(c2).plus_mutable(MantExp.ONE); + precalc9.Normalize(); + MantExpComplex precalc13 = c2.sub(MantExp.THREE); + precalc13.Normalize(); + MantExpComplex precalc8 = c.sub(MantExp.THREE).times2_mutable(); + precalc8.Normalize(); + MantExpComplex precalc3 = csqrsc4.plus(MantExp.THREE).times2_mutable(); + precalc3.Normalize(); + MantExpComplex precalc7 = csqr.sub(c.times(MantExp.SIX)).plus_mutable(MantExp.FOUR); + precalc7.Normalize(); + MantExpComplex cs6 = c.sub(MantExp.SIX); + cs6.Normalize(); + + Function f5 = x -> precalc9.sub(precalc2.plus(x.square().times4_mutable()).sub_mutable(x.cube().sub_mutable(precalc8.times(x))).times_mutable(x)); + Function f6 = x -> x.cube().plus_mutable(precalc8.times(x)).sub_mutable(cs24).times_mutable(x).plus_mutable(precalc13); + Function f8 = x -> cs6.times(x.cube()).plus_mutable(x.fourth().times2_mutable()).plus_mutable(precalc7.times(x)).plus_mutable(x.square().times4_mutable()) + .sub_mutable(precalc3).times_mutable(x).plus_mutable(precalcl); + + return new Function[] {f1, f2, f3, f4, f5, f6, f7, f8}; + } + return new Function[] {f1, f2, f3, f4, f7}; + } + @Override public void calculateReferencePoint(GenericComplex inputPixel, Apfloat size, boolean deepZoom, int[] Iterations, int[] juliaIterations, Location externalLocation, JProgressBar progress) { @@ -210,27 +361,19 @@ public void calculateReferencePoint(GenericComplex inputPixel, Apfloat size, boo boolean lowPrecReferenceOrbitNeeded = !needsOnlyExtendedReferenceOrbit(deepZoom, false); DoubleReference.SHOULD_SAVE_MEMORY = false; + boolean useCompressedRef = TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE && supportsReferenceCompression(); + int [] preCalcIndexes = getNeededPrecalculatedTermsIndexes(); if (iterations == 0) { if(lowPrecReferenceOrbitNeeded) { - if(!isJulia) { - referenceData.createAndSetShortcut(max_ref_iterations, false, 8); - } - else { - referenceData.createAndSetShortcut(max_ref_iterations, false, new int[] {0, 1, 2, 3, 6}); - } + referenceData.createAndSetShortcut(max_ref_iterations, false, preCalcIndexes, useCompressedRef); } else { referenceData.deallocate(); } if (deepZoom) { - if(!isJulia) { - referenceDeepData.createAndSetShortcut(max_ref_iterations, false, 8); - } - else { - referenceDeepData.createAndSetShortcut(max_ref_iterations, false, new int[] {0, 1, 2, 3, 6}); - } + referenceDeepData.createAndSetShortcut(max_ref_iterations, false, preCalcIndexes, useCompressedRef); } } else if (max_ref_iterations > getReferenceLength()) { if(lowPrecReferenceOrbitNeeded) { @@ -322,12 +465,6 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { Location loc = new Location(); refPoint = inputPixel; - refPointSmall = refPoint.toComplex(); - - - if(lowPrecReferenceOrbitNeeded) { - C = c.toComplex(); - } GenericComplex c2big = c.times2(); @@ -534,6 +671,31 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { if(deepZoom) { refPointSmallDeep = loc.getMantExpComplex(refPoint); Cdeep = loc.getMantExpComplex(c); + + refPointSmall = refPointSmallDeep.toComplex(); + + if(isJulia) { + seedSmallDeep = loc.getMantExpComplex(c); + } + + if(lowPrecReferenceOrbitNeeded) { + C = Cdeep.toComplex(); + } + + if(lowPrecReferenceOrbitNeeded && isJulia) { + seedSmall = seedSmallDeep.toComplex(); + } + } + else { + refPointSmall = refPoint.toComplex(); + + if(lowPrecReferenceOrbitNeeded) { + C = c.toComplex(); + } + + if(lowPrecReferenceOrbitNeeded && isJulia) { + seedSmall = c.toComplex(); + } } RefType = getRefType(); @@ -543,22 +705,35 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { convergent_bailout_algorithm.setReferenceMode(true); - calculatedReferenceIterations = 0; - - for (; iterations < max_ref_iterations; iterations++, calculatedReferenceIterations++) { + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[referenceDeep.id] = new ReferenceCompressor(this, iterations == 0 ? z.toMantExpComplex() : referenceData.compressorZm, c.toMantExpComplex(), start.toMantExpComplex()); - if (lowPrecReferenceOrbitNeeded) { - Complex cz = z.toComplex(); - if (cz.isInfinite()) { - break; + Function[] fs = getPrecalculatedTermsFunctionsDeep(c.toMantExpComplex()); + for(int i = 0; i < preCalcIndexes.length; i++) { + int id = referenceDeepData.PrecalculatedTerms[preCalcIndexes[i]].id; + functions[id] = fs[i]; + subexpressionsCompressor[id] = new ReferenceCompressor(fs[i], true); } - - setArrayValue(reference, iterations, cz); } + if(lowPrecReferenceOrbitNeeded) { + referenceCompressor[reference.id] = new ReferenceCompressor(this, iterations == 0 ? z.toComplex() : referenceData.compressorZ, c.toComplex(), start.toComplex()); - if (deepZoom) { - setArrayDeepValue(referenceDeep, iterations, loc.getMantExpComplex(z)); + Function[] fs = getPrecalculatedTermsFunctions(c.toComplex()); + for(int i = 0; i < preCalcIndexes.length; i++) { + int id = referenceData.PrecalculatedTerms[preCalcIndexes[i]].id; + functions[id] = fs[i]; + subexpressionsCompressor[id] = new ReferenceCompressor(fs[i]); + } } + } + + calculatedReferenceIterations = 0; + + MantExpComplex tempczm = null; + Complex cz = null; + + for (; iterations < max_ref_iterations; iterations++, calculatedReferenceIterations++) { if (preCalcNormData) { normData = z.normSquaredWithComponents(normData); @@ -579,18 +754,10 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { GenericComplex cs24tzbig = cs24big.times(z); GenericComplex preCalc = precalc2big.plus(cs24tzbig).plus_mutable(zsqr4); //C^2 + 4*(C - 2)*Z + 4*Z^2 - 4*C + 4 - if (lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[0], iterations, preCalc.toComplex()); - } - //3*(C - 2)*Z^4 + 2*Z^5 + (C^2 - 4*C + 4)*Z^3 - C^3 + 2*(C^2 - 3*C + 2)*Z^2 + 4*C^2 + (C^3 - 7*C^2 + 12*C - 6)*Z - 5*C + 2 GenericComplex preCalc2 = cs23big.times(zcube).plus_mutable(zfourth.times2()).plus_mutable(precalc2big.times(zsqr)).plus_mutable(precalc14big.times(z)) .plus_mutable(precalc6big).times_mutable(z).plus_mutable(precalc12big); - if (lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[1], iterations, preCalc2.toComplex()); - } - GenericComplex temp8 = cs2big.times(zcube); //(C - 2)*Z^3 GenericComplex temp1Z = precalc2big.times(z); @@ -603,10 +770,6 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { preCalc3 = precalc10big.plus(temp8.times(MyApfloat.THIRTYTWO)).plus(zcube.times(MyApfloat.SIXTEEN).plus(temp1Z.times(MyApfloat.TWENTYFOUR)).plus(precalc5big).times(z)); } - if (lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[2], iterations, preCalc3.toComplex()); - } - GenericComplex preCalc4; if (bigNumLib != Constants.BIGNUM_APFLOAT) { preCalc4 = precalc4big.plus(cs212big.times(zsqr)).plus_mutable(zcube.times(8)).plus_mutable(temp1Z.times(6)).plus_mutable(c12s8big); @@ -614,26 +777,12 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { preCalc4 = precalc4big.plus(cs212big.times(zsqr)).plus(zcube.times(MyApfloat.EIGHT)).plus(temp1Z.times(MyApfloat.SIX)).plus(c12s8big); } - if (lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[3], iterations, preCalc4.toComplex()); - } - GenericComplex temp = precalc8big.times(z); //2*(C-3)*Z GenericComplex preCalc5 = null, preCalc6 = null, preCalc8 = null; if (!isJulia) { preCalc5 = precalc9big.sub(precalc2big.plus(zsqr4).sub_mutable(zcube.sub(temp)).times_mutable(z)); - - if (lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[4], iterations, preCalc5.toComplex()); - } - - preCalc6 = zcube.plus(temp).sub_mutable(cs24big).times_mutable(z).plus_mutable(precalc13big); - - if (lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[5], iterations, preCalc6.toComplex()); - } } @@ -649,30 +798,66 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { .plus(precalc11big).plus(precalclbig.times4().times(z)); } - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[6], iterations, preCalc7.toComplex()); - } - if (!isJulia) { preCalc8 = cs6big.times(zcube).plus_mutable(zfourth.times2()).plus_mutable(precalc7big.times(z)).plus_mutable(zsqr4) .sub_mutable(precalc3big).times_mutable(z).plus_mutable(precalclbig); + } + + MantExpComplex precalm = null, precal2m = null, precal3m = null, precal4m = null, precalc7m = null; + MantExpComplex precal5m = null, precal6m = null, precal8m = null; + MantExpComplex czm = null; + if(deepZoom) { + czm = loc.getMantExpComplex(z); + if (czm.isInfinite() || czm.isNaN()) { + break; + } + tempczm = setArrayDeepValue(referenceDeep, iterations, czm); + } - if (lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[7], iterations, preCalc8.toComplex()); + if (lowPrecReferenceOrbitNeeded) { + cz = deepZoom ? czm.toComplex() : z.toComplex(); + if (cz.isInfinite() || cz.isNaN()) { + break; } + + cz = setArrayValue(reference, iterations, cz); } + czm = tempczm; + if(deepZoom) { - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], iterations, loc.getMantExpComplex(preCalc)); - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], iterations, loc.getMantExpComplex(preCalc2)); - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[2], iterations, loc.getMantExpComplex(preCalc3)); - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[3], iterations, loc.getMantExpComplex(preCalc4)); - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[6], iterations, loc.getMantExpComplex(preCalc7)); + precalm = loc.getMantExpComplex(preCalc); + precal2m = loc.getMantExpComplex(preCalc2); + precal3m = loc.getMantExpComplex(preCalc3); + precal4m = loc.getMantExpComplex(preCalc4); + precalc7m = loc.getMantExpComplex(preCalc7); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], iterations, precalm, czm); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], iterations, precal2m, czm); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[2], iterations, precal3m, czm); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[3], iterations, precal4m, czm); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[6], iterations, precalc7m, czm); if(!isJulia) { - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[4], iterations, loc.getMantExpComplex(preCalc5)); - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[5], iterations, loc.getMantExpComplex(preCalc6)); - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[7], iterations, loc.getMantExpComplex(preCalc8)); + precal5m = loc.getMantExpComplex(preCalc5); + precal6m = loc.getMantExpComplex(preCalc6); + precal8m = loc.getMantExpComplex(preCalc8); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[4], iterations, precal5m, czm); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[5], iterations, precal6m, czm); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[7], iterations, precal8m, czm); + } + } + + if (lowPrecReferenceOrbitNeeded) { + setArrayValue(referenceData.PrecalculatedTerms[0], iterations, deepZoom ? precalm.toComplex() : preCalc.toComplex(), cz); + setArrayValue(referenceData.PrecalculatedTerms[1], iterations, deepZoom ? precal2m.toComplex() : preCalc2.toComplex(), cz); + setArrayValue(referenceData.PrecalculatedTerms[2], iterations, deepZoom ? precal3m.toComplex() : preCalc3.toComplex(), cz); + setArrayValue(referenceData.PrecalculatedTerms[3], iterations, deepZoom ? precal4m.toComplex() : preCalc4.toComplex(), cz); + setArrayValue(referenceData.PrecalculatedTerms[6], iterations, deepZoom ? precalc7m.toComplex() : preCalc7.toComplex(), cz); + + if(!isJulia) { + setArrayValue(referenceData.PrecalculatedTerms[4], iterations, deepZoom ? precal5m.toComplex() : preCalc5.toComplex(), cz); + setArrayValue(referenceData.PrecalculatedTerms[5], iterations, deepZoom ? precal6m.toComplex() : preCalc6.toComplex(), cz); + setArrayValue(referenceData.PrecalculatedTerms[7], iterations, deepZoom ? precal8m.toComplex() : preCalc8.toComplex(), cz); } } @@ -710,6 +895,26 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { referenceData.MaxRefIteration = iterations - 1; + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[referenceDeep.id].compact(referenceDeep); + referenceData.compressorZm = referenceCompressor[referenceDeep.id].getZDeep(); + + for(int i = 0; i < preCalcIndexes.length; i++) { + subexpressionsCompressor[referenceDeepData.PrecalculatedTerms[preCalcIndexes[i]].id].compact(referenceDeepData.PrecalculatedTerms[preCalcIndexes[i]]); + } + } + + if(lowPrecReferenceOrbitNeeded) { + referenceCompressor[reference.id].compact(reference); + referenceData.compressorZ = referenceCompressor[reference.id].getZ(); + + for(int i = 0; i < preCalcIndexes.length; i++) { + subexpressionsCompressor[referenceData.PrecalculatedTerms[preCalcIndexes[i]].id].compact(referenceData.PrecalculatedTerms[preCalcIndexes[i]]); + } + } + } + SAskippedIterations = 0; if(progress != null) { @@ -722,7 +927,6 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { if(isJulia) { calculateJuliaReferencePoint(inputPixel, size, deepZoom, juliaIterations, progress); } - } @Override @@ -748,17 +952,19 @@ protected void calculateJuliaReferencePoint(GenericComplex inputPixel, Apfloat s boolean lowPrecReferenceOrbitNeeded = !needsOnlyExtendedReferenceOrbit(deepZoom, false); DoubleReference.SHOULD_SAVE_MEMORY = false; + boolean useCompressedRef = TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE && supportsReferenceCompression(); + int[] preCalcIndexes = getNeededPrecalculatedTermsIndexes(); if (iterations == 0) { if(lowPrecReferenceOrbitNeeded) { - secondReferenceData.create(max_ref_iterations,false, new int[] {0, 1, 2, 3, 6}); + secondReferenceData.create(max_ref_iterations,false, preCalcIndexes, useCompressedRef); } else { secondReferenceData.deallocate(); } if (deepZoom) { - secondReferenceDeepData.create(max_ref_iterations,false, new int[] {0, 1, 2, 3, 6}); + secondReferenceDeepData.create(max_ref_iterations,false, preCalcIndexes, useCompressedRef); } } else if (max_ref_iterations > getSecondReferenceLength()) { if(lowPrecReferenceOrbitNeeded) { @@ -852,22 +1058,35 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { convergent_bailout_algorithm.setReferenceMode(true); - calculatedSecondReferenceIterations = 0; - - for (; iterations < max_ref_iterations; iterations++, calculatedSecondReferenceIterations++) { + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[secondReferenceDeepData.Reference.id] = new ReferenceCompressor(this, iterations == 0 ? z.toMantExpComplex() : secondReferenceData.compressorZm, c.toMantExpComplex(), start.toMantExpComplex()); - if(lowPrecReferenceOrbitNeeded) { - Complex cz = z.toComplex(); - if (cz.isInfinite()) { - break; + Function[] fs = getPrecalculatedTermsFunctionsDeep(c.toMantExpComplex()); + for(int i = 0; i < preCalcIndexes.length; i++) { + int id = secondReferenceDeepData.PrecalculatedTerms[preCalcIndexes[i]].id; + functions[id] = fs[i]; + subexpressionsCompressor[id] = new ReferenceCompressor(fs[i], true); } - - setArrayValue(secondReferenceData.Reference, iterations, cz); } + if(lowPrecReferenceOrbitNeeded) { + referenceCompressor[secondReferenceData.Reference.id] = new ReferenceCompressor(this, iterations == 0 ? z.toComplex() : secondReferenceData.compressorZ, c.toComplex(), start.toComplex()); - if(deepZoom) { - setArrayDeepValue(secondReferenceDeepData.Reference, iterations, loc.getMantExpComplex(z)); + Function[] fs = getPrecalculatedTermsFunctions(c.toComplex()); + for(int i = 0; i < preCalcIndexes.length; i++) { + int id = secondReferenceData.PrecalculatedTerms[preCalcIndexes[i]].id; + functions[id] = fs[i]; + subexpressionsCompressor[id] = new ReferenceCompressor(fs[i]); + } } + } + + calculatedSecondReferenceIterations = 0; + + MantExpComplex tempmcz = null; + Complex cz = null; + + for (; iterations < max_ref_iterations; iterations++, calculatedSecondReferenceIterations++) { if(preCalcNormData) { normData = z.normSquaredWithComponents(normData); @@ -889,18 +1108,10 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { GenericComplex cs24tzbig = cs24big.times(z); GenericComplex preCalc = precalc2big.plus(cs24tzbig).plus_mutable(zsqr4); //C^2 + 4*(C - 2)*Z + 4*Z^2 - 4*C + 4 - if (lowPrecReferenceOrbitNeeded) { - setArrayValue(secondReferenceData.PrecalculatedTerms[0], iterations, preCalc.toComplex()); - } - //3*(C - 2)*Z^4 + 2*Z^5 + (C^2 - 4*C + 4)*Z^3 - C^3 + 2*(C^2 - 3*C + 2)*Z^2 + 4*C^2 + (C^3 - 7*C^2 + 12*C - 6)*Z - 5*C + 2 GenericComplex preCalc2 = cs23big.times(zcube).plus_mutable(zfourth.times2()).plus_mutable(precalc2big.times(zsqr)).plus_mutable(precalc14big.times(z)) .plus_mutable(precalc6big).times_mutable(z).plus_mutable(precalc12big); - if (lowPrecReferenceOrbitNeeded) { - setArrayValue(secondReferenceData.PrecalculatedTerms[1], iterations, preCalc2.toComplex()); - } - GenericComplex temp8 = cs2big.times(zcube); //(C - 2)*Z^3 GenericComplex temp1Z = precalc2big.times(z); @@ -913,10 +1124,6 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { preCalc3 = precalc10big.plus(temp8.times(MyApfloat.THIRTYTWO)).plus(zcube.times(MyApfloat.SIXTEEN).plus(temp1Z.times(MyApfloat.TWENTYFOUR)).plus(precalc5big).times(z)); } - if (lowPrecReferenceOrbitNeeded) { - setArrayValue(secondReferenceData.PrecalculatedTerms[2], iterations, preCalc3.toComplex()); - } - GenericComplex preCalc4; if (bigNumLib != Constants.BIGNUM_APFLOAT) { preCalc4 = precalc4big.plus(cs212big.times(zsqr)).plus_mutable(zcube.times(8)).plus_mutable(temp1Z.times(6)).plus_mutable(c12s8big); @@ -924,11 +1131,6 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { preCalc4 = precalc4big.plus(cs212big.times(zsqr)).plus(zcube.times(MyApfloat.EIGHT)).plus(temp1Z.times(MyApfloat.SIX)).plus(c12s8big); } - if (lowPrecReferenceOrbitNeeded) { - setArrayValue(secondReferenceData.PrecalculatedTerms[3], iterations, preCalc4.toComplex()); - } - - GenericComplex preCalc7; if(bigNumLib != Constants.BIGNUM_APFLOAT) { preCalc7 = precalc2big.plus(cs24tzbig).times_mutable(zsqr).times_mutable(3) @@ -941,16 +1143,47 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { .plus(precalc11big).plus(precalclbig.times4().times(z)); } + MantExpComplex precalm = null, precal2m = null, precal3m = null, precal4m = null, precalc7m = null; + MantExpComplex czm = null; + if(deepZoom) { + czm = loc.getMantExpComplex(z); + if (czm.isInfinite() || czm.isNaN()) { + break; + } + tempmcz = setArrayDeepValue(secondReferenceDeepData.Reference, iterations, czm); + } + if(lowPrecReferenceOrbitNeeded) { - setArrayValue(secondReferenceData.PrecalculatedTerms[6], iterations, preCalc7.toComplex()); + cz = deepZoom ? czm.toComplex() : z.toComplex(); + if (cz.isInfinite() || cz.isNaN()) { + break; + } + + cz = setArrayValue(secondReferenceData.Reference, iterations, cz); } + czm = tempmcz; + if(deepZoom) { - setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[0], iterations, loc.getMantExpComplex(preCalc)); - setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[1], iterations, loc.getMantExpComplex(preCalc2)); - setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[2], iterations, loc.getMantExpComplex(preCalc3)); - setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[3], iterations, loc.getMantExpComplex(preCalc4)); - setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[6], iterations, loc.getMantExpComplex(preCalc7)); + precalm = loc.getMantExpComplex(preCalc); + precal2m = loc.getMantExpComplex(preCalc2); + precal3m = loc.getMantExpComplex(preCalc3); + precal4m = loc.getMantExpComplex(preCalc4); + precalc7m = loc.getMantExpComplex(preCalc7); + + setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[0], iterations, precalm, czm); + setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[1], iterations, precal2m, czm); + setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[2], iterations, precal3m, czm); + setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[3], iterations, precal4m, czm); + setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[6], iterations, precalc7m, czm); + } + + if(lowPrecReferenceOrbitNeeded) { + setArrayValue(secondReferenceData.PrecalculatedTerms[0], iterations, deepZoom ? precalm.toComplex() : preCalc.toComplex(), cz); + setArrayValue(secondReferenceData.PrecalculatedTerms[1], iterations, deepZoom ? precal2m.toComplex() : preCalc2.toComplex(), cz); + setArrayValue(secondReferenceData.PrecalculatedTerms[2], iterations, deepZoom ? precal3m.toComplex() : preCalc3.toComplex(), cz); + setArrayValue(secondReferenceData.PrecalculatedTerms[3], iterations, deepZoom ? precal4m.toComplex() : preCalc4.toComplex(), cz); + setArrayValue(secondReferenceData.PrecalculatedTerms[6], iterations, deepZoom ? precalc7m.toComplex() : preCalc7.toComplex(), cz); } if (iterations > 0 && (convergent_bailout_algorithm.Converged(z, root, zold, zold2, iterations, c, start, c0, pixel) @@ -987,6 +1220,26 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { secondReferenceData.MaxRefIteration = iterations - 1; + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[secondReferenceDeepData.Reference.id].compact(secondReferenceDeepData.Reference); + secondReferenceData.compressorZm = referenceCompressor[secondReferenceDeepData.Reference.id].getZDeep(); + + for(int i = 0; i < preCalcIndexes.length; i++) { + subexpressionsCompressor[secondReferenceDeepData.PrecalculatedTerms[preCalcIndexes[i]].id].compact(secondReferenceDeepData.PrecalculatedTerms[preCalcIndexes[i]]); + } + } + + if(lowPrecReferenceOrbitNeeded) { + referenceCompressor[secondReferenceData.Reference.id].compact(secondReferenceData.Reference); + secondReferenceData.compressorZ = referenceCompressor[secondReferenceData.Reference.id].getZ(); + + for(int i = 0; i < preCalcIndexes.length; i++) { + subexpressionsCompressor[secondReferenceData.PrecalculatedTerms[preCalcIndexes[i]].id].compact(secondReferenceData.PrecalculatedTerms[preCalcIndexes[i]]); + } + } + } + if(progress != null) { progress.setValue(progress.getMaximum()); progress.setString(REFERENCE_CALCULATION_STR + " 100%"); @@ -1018,9 +1271,9 @@ public Complex perturbationFunction(Complex z, Complex c, int RefIteration) { Complex zsqr = z.square(); - Complex temp2 = getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration);//C^2 + 4*(C - 2)*Z + 4*Z^2 - 4*C + 4 + Complex temp2 = getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration, Z);//C^2 + 4*(C - 2)*Z + 4*Z^2 - 4*C + 4 Complex temp9 = temp2.times(c); - Complex temp10 = getArrayValue(referenceData.PrecalculatedTerms[3], RefIteration); + Complex temp10 = getArrayValue(referenceData.PrecalculatedTerms[3], RefIteration, Z); // C^4 // + 32*(C - 2)*Z^3 @@ -1035,7 +1288,7 @@ public Complex perturbationFunction(Complex z, Complex c, int RefIteration) { // + 4*(C^3 + 12*(C - 2)*Z^2 + 8*Z^3 - 6*C^2 + 6*(C^2 - 4*C + 4)*Z + (C^2 + 4*(C - 2)*Z + 4*Z^2 - 4*C + 4)*c + 12*C - 8)*z // - 32*C // + 16 - Complex denom = getArrayValue(referenceData.PrecalculatedTerms[2], RefIteration) + Complex denom = getArrayValue(referenceData.PrecalculatedTerms[2], RefIteration, Z) .plus_mutable(temp2.times(csqr)) .plus_mutable(temp2.times(zsqr).times4_mutable()) .plus_mutable(temp10.times(c).times2_mutable()) @@ -1055,13 +1308,13 @@ public Complex perturbationFunction(Complex z, Complex c, int RefIteration) { Complex b1 = (temp2.times(Z)).times(z.cube()).times4_mutable(); - Complex c1 = getArrayValue(referenceData.PrecalculatedTerms[5], RefIteration).times_mutable(csqr); + Complex c1 = getArrayValue(referenceData.PrecalculatedTerms[5], RefIteration, Z).times_mutable(csqr); - Complex d1 = getArrayValue(referenceData.PrecalculatedTerms[6], RefIteration).plus_mutable(temp9).times2_mutable().times_mutable(zsqr); + Complex d1 = getArrayValue(referenceData.PrecalculatedTerms[6], RefIteration, Z).plus_mutable(temp9).times2_mutable().times_mutable(zsqr); - Complex e1 = getArrayValue(referenceData.PrecalculatedTerms[7], RefIteration).times2_mutable().times_mutable(c); + Complex e1 = getArrayValue(referenceData.PrecalculatedTerms[7], RefIteration, Z).times2_mutable().times_mutable(c); - Complex f1 = (getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration).sub_mutable(getArrayValue(referenceData.PrecalculatedTerms[4], RefIteration).times_mutable(c)) + Complex f1 = (getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration, Z).sub_mutable(getArrayValue(referenceData.PrecalculatedTerms[4], RefIteration, Z).times_mutable(c)) ).times4_mutable().times_mutable(z); Complex num = a1 @@ -1087,9 +1340,9 @@ public MantExpComplex perturbationFunction(MantExpComplex z, MantExpComplex c, i MantExpComplex zsqr = z.square(); - MantExpComplex temp2 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration);//C^2 + 4*(C - 2)*Z + 4*Z^2 - 4*C + 4 + MantExpComplex temp2 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration, Z);//C^2 + 4*(C - 2)*Z + 4*Z^2 - 4*C + 4 MantExpComplex temp9 = temp2.times(c); - MantExpComplex temp10 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[3], RefIteration); + MantExpComplex temp10 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[3], RefIteration, Z); // C^4 // + 32*(C - 2)*Z^3 @@ -1104,7 +1357,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, MantExpComplex c, i // + 4*(C^3 + 12*(C - 2)*Z^2 + 8*Z^3 - 6*C^2 + 6*(C^2 - 4*C + 4)*Z + (C^2 + 4*(C - 2)*Z + 4*Z^2 - 4*C + 4)*c + 12*C - 8)*z // - 32*C // + 16 - MantExpComplex denom = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[2], RefIteration) + MantExpComplex denom = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[2], RefIteration, Z) .plus_mutable(temp2.times(csqr)) .plus_mutable(temp2.times(zsqr).times4_mutable()) .plus_mutable(temp10.times(c).times2_mutable()) @@ -1124,13 +1377,13 @@ public MantExpComplex perturbationFunction(MantExpComplex z, MantExpComplex c, i MantExpComplex b1 = (temp2.times(Z)).times(z.cube()).times4_mutable(); - MantExpComplex c1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[5], RefIteration).times_mutable(csqr); + MantExpComplex c1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[5], RefIteration, Z).times_mutable(csqr); - MantExpComplex d1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[6], RefIteration).plus_mutable(temp9).times2_mutable().times_mutable(zsqr); + MantExpComplex d1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[6], RefIteration, Z).plus_mutable(temp9).times2_mutable().times_mutable(zsqr); - MantExpComplex e1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[7], RefIteration).times2_mutable().times_mutable(c); + MantExpComplex e1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[7], RefIteration, Z).times2_mutable().times_mutable(c); - MantExpComplex f1 = (getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration).sub_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[4], RefIteration).times_mutable(c)) + MantExpComplex f1 = (getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration, Z).sub_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[4], RefIteration, Z).times_mutable(c)) ).times4_mutable().times_mutable(z); MantExpComplex num = a1 @@ -1155,8 +1408,8 @@ public Complex perturbationFunction(Complex z, int RefIteration) { Complex zsqr = z.square(); - Complex temp2 = getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration);//C^2 + 4*(C - 2)*Z + 4*Z^2 - 4*C + 4 - Complex temp10 = getArrayValue(referenceData.PrecalculatedTerms[3], RefIteration); + Complex temp2 = getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration, Z);//C^2 + 4*(C - 2)*Z + 4*Z^2 - 4*C + 4 + Complex temp10 = getArrayValue(referenceData.PrecalculatedTerms[3], RefIteration, Z); // C^4 // + 32*(C - 2)*Z^3 @@ -1171,7 +1424,7 @@ public Complex perturbationFunction(Complex z, int RefIteration) { // + 4*(C^3 + 12*(C - 2)*Z^2 + 8*Z^3 - 6*C^2 + 6*(C^2 - 4*C + 4)*Z + (C^2 + 4*(C - 2)*Z + 4*Z^2 - 4*C + 4)*c + 12*C - 8)*z // - 32*C // + 16 - Complex denom = getArrayValue(referenceData.PrecalculatedTerms[2], RefIteration) + Complex denom = getArrayValue(referenceData.PrecalculatedTerms[2], RefIteration, Z) .plus_mutable(temp2.times(zsqr).times4_mutable()) .plus_mutable(temp10.times(z).times4_mutable()); @@ -1190,10 +1443,10 @@ public Complex perturbationFunction(Complex z, int RefIteration) { Complex b1 = (temp2.times(Z)).times(z.cube()).times4_mutable(); - Complex d1 = getArrayValue(referenceData.PrecalculatedTerms[6], RefIteration).times2_mutable().times_mutable(zsqr); + Complex d1 = getArrayValue(referenceData.PrecalculatedTerms[6], RefIteration, Z).times2_mutable().times_mutable(zsqr); - Complex f1 = (getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration) + Complex f1 = (getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration, Z) ).times4_mutable().times_mutable(z); Complex num = a1 @@ -1215,8 +1468,8 @@ public MantExpComplex perturbationFunction(MantExpComplex z, int RefIteration) { MantExpComplex zsqr = z.square(); - MantExpComplex temp2 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration);//C^2 + 4*(C - 2)*Z + 4*Z^2 - 4*C + 4 - MantExpComplex temp10 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[3], RefIteration); + MantExpComplex temp2 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration, Z);//C^2 + 4*(C - 2)*Z + 4*Z^2 - 4*C + 4 + MantExpComplex temp10 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[3], RefIteration, Z); // C^4 // + 32*(C - 2)*Z^3 @@ -1231,7 +1484,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, int RefIteration) { // + 4*(C^3 + 12*(C - 2)*Z^2 + 8*Z^3 - 6*C^2 + 6*(C^2 - 4*C + 4)*Z + (C^2 + 4*(C - 2)*Z + 4*Z^2 - 4*C + 4)*c + 12*C - 8)*z // - 32*C // + 16 - MantExpComplex denom = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[2], RefIteration) + MantExpComplex denom = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[2], RefIteration, Z) .plus_mutable(temp2.times(zsqr).times4_mutable()) .plus_mutable(temp10.times(z).times4_mutable()); @@ -1250,10 +1503,10 @@ public MantExpComplex perturbationFunction(MantExpComplex z, int RefIteration) { MantExpComplex b1 = (temp2.times(Z)).times(z.cube()).times4_mutable(); - MantExpComplex d1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[6], RefIteration).times2_mutable().times_mutable(zsqr); + MantExpComplex d1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[6], RefIteration, Z).times2_mutable().times_mutable(zsqr); - MantExpComplex f1 = (getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration) + MantExpComplex f1 = (getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration, Z) ).times4_mutable().times_mutable(z); MantExpComplex num = a1 @@ -1276,8 +1529,8 @@ public Complex perturbationFunction(Complex z, ReferenceData data, int RefIterat Complex zsqr = z.square(); - Complex temp2 = getArrayValue(data.PrecalculatedTerms[0], RefIteration);//C^2 + 4*(C - 2)*Z + 4*Z^2 - 4*C + 4 - Complex temp10 = getArrayValue(data.PrecalculatedTerms[3], RefIteration); + Complex temp2 = getArrayValue(data.PrecalculatedTerms[0], RefIteration, Z);//C^2 + 4*(C - 2)*Z + 4*Z^2 - 4*C + 4 + Complex temp10 = getArrayValue(data.PrecalculatedTerms[3], RefIteration, Z); // C^4 // + 32*(C - 2)*Z^3 @@ -1292,7 +1545,7 @@ public Complex perturbationFunction(Complex z, ReferenceData data, int RefIterat // + 4*(C^3 + 12*(C - 2)*Z^2 + 8*Z^3 - 6*C^2 + 6*(C^2 - 4*C + 4)*Z + (C^2 + 4*(C - 2)*Z + 4*Z^2 - 4*C + 4)*c + 12*C - 8)*z // - 32*C // + 16 - Complex denom = getArrayValue(data.PrecalculatedTerms[2], RefIteration) + Complex denom = getArrayValue(data.PrecalculatedTerms[2], RefIteration, Z) .plus_mutable(temp2.times(zsqr).times4_mutable()) .plus_mutable(temp10.times(z).times4_mutable()); @@ -1311,10 +1564,10 @@ public Complex perturbationFunction(Complex z, ReferenceData data, int RefIterat Complex b1 = (temp2.times(Z)).times(z.cube()).times4_mutable(); - Complex d1 = getArrayValue(data.PrecalculatedTerms[6], RefIteration).times2_mutable().times_mutable(zsqr); + Complex d1 = getArrayValue(data.PrecalculatedTerms[6], RefIteration, Z).times2_mutable().times_mutable(zsqr); - Complex f1 = (getArrayValue(data.PrecalculatedTerms[1], RefIteration) + Complex f1 = (getArrayValue(data.PrecalculatedTerms[1], RefIteration, Z) ).times4_mutable().times_mutable(z); Complex num = a1 @@ -1336,8 +1589,8 @@ public MantExpComplex perturbationFunction(MantExpComplex z, ReferenceDeepData d MantExpComplex zsqr = z.square(); - MantExpComplex temp2 = getArrayDeepValue(data.PrecalculatedTerms[0], RefIteration);//C^2 + 4*(C - 2)*Z + 4*Z^2 - 4*C + 4 - MantExpComplex temp10 = getArrayDeepValue(data.PrecalculatedTerms[3], RefIteration); + MantExpComplex temp2 = getArrayDeepValue(data.PrecalculatedTerms[0], RefIteration, Z);//C^2 + 4*(C - 2)*Z + 4*Z^2 - 4*C + 4 + MantExpComplex temp10 = getArrayDeepValue(data.PrecalculatedTerms[3], RefIteration, Z); // C^4 // + 32*(C - 2)*Z^3 @@ -1352,7 +1605,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, ReferenceDeepData d // + 4*(C^3 + 12*(C - 2)*Z^2 + 8*Z^3 - 6*C^2 + 6*(C^2 - 4*C + 4)*Z + (C^2 + 4*(C - 2)*Z + 4*Z^2 - 4*C + 4)*c + 12*C - 8)*z // - 32*C // + 16 - MantExpComplex denom = getArrayDeepValue(data.PrecalculatedTerms[2], RefIteration) + MantExpComplex denom = getArrayDeepValue(data.PrecalculatedTerms[2], RefIteration, Z) .plus_mutable(temp2.times(zsqr).times4_mutable()) .plus_mutable(temp10.times(z).times4_mutable()); @@ -1371,10 +1624,10 @@ public MantExpComplex perturbationFunction(MantExpComplex z, ReferenceDeepData d MantExpComplex b1 = (temp2.times(Z)).times(z.cube()).times4_mutable(); - MantExpComplex d1 = getArrayDeepValue(data.PrecalculatedTerms[6], RefIteration).times2_mutable().times_mutable(zsqr); + MantExpComplex d1 = getArrayDeepValue(data.PrecalculatedTerms[6], RefIteration, Z).times2_mutable().times_mutable(zsqr); - MantExpComplex f1 = (getArrayDeepValue(data.PrecalculatedTerms[1], RefIteration) + MantExpComplex f1 = (getArrayDeepValue(data.PrecalculatedTerms[1], RefIteration, Z) ).times4_mutable().times_mutable(z); MantExpComplex num = a1 @@ -1401,4 +1654,24 @@ public boolean supportsBigIntnum() { @Override public boolean supportsMpirBignum() { return true;} + + @Override + public boolean supportsReferenceCompression() { + return true; + } + + @Override + public Complex function(Complex z, Complex c) { + return (z.square().plus_mutable(c.sub(1))).divide_mutable(z.times2().plus_mutable(c.sub(2))).square_mutable(); + } + + @Override + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + return (z.square().plus_mutable(c.sub(MantExp.ONE))).divide_mutable(z.times2().plus_mutable(c.sub(MantExp.TWO))).square_mutable(); + } + + @Override + public double getPower() { + return 4; + } } diff --git a/src/fractalzoomer/functions/magnet/Magnet13.java b/src/fractalzoomer/functions/magnet/Magnet13.java index e7675b091..448967344 100644 --- a/src/fractalzoomer/functions/magnet/Magnet13.java +++ b/src/fractalzoomer/functions/magnet/Magnet13.java @@ -38,7 +38,7 @@ public Magnet13(double xCenter, double yCenter, double size, int max_iterations, super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - convergent_bailout = 1E-12; + setConvergentBailout(1E-12); setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); @@ -62,10 +62,8 @@ public Magnet13(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.ITERATIONS_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; - break; case MainWindow.ITERATIONS_PLUS_RE_PLUS_IM_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; } @@ -83,15 +81,13 @@ public Magnet13(double xCenter, double yCenter, double size, int max_iterations, super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, xJuliaCenter, yJuliaCenter); - convergent_bailout = 1E-12; + setConvergentBailout(1E-12); switch (out_coloring_algorithm) { case MainWindow.ITERATIONS_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; - break; case MainWindow.ITERATIONS_PLUS_RE_PLUS_IM_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; } diff --git a/src/fractalzoomer/functions/magnet/Magnet14.java b/src/fractalzoomer/functions/magnet/Magnet14.java index c6d31ac7e..8068aab04 100644 --- a/src/fractalzoomer/functions/magnet/Magnet14.java +++ b/src/fractalzoomer/functions/magnet/Magnet14.java @@ -38,7 +38,7 @@ public Magnet14(double xCenter, double yCenter, double size, int max_iterations, super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - convergent_bailout = 1E-12; + setConvergentBailout(1E-12); setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); @@ -62,10 +62,8 @@ public Magnet14(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.ITERATIONS_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; - break; case MainWindow.ITERATIONS_PLUS_RE_PLUS_IM_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; } @@ -83,15 +81,13 @@ public Magnet14(double xCenter, double yCenter, double size, int max_iterations, super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, xJuliaCenter, yJuliaCenter); - convergent_bailout = 1E-12; + setConvergentBailout(1E-12); switch (out_coloring_algorithm) { case MainWindow.ITERATIONS_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; - break; case MainWindow.ITERATIONS_PLUS_RE_PLUS_IM_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; } diff --git a/src/fractalzoomer/functions/magnet/Magnet2.java b/src/fractalzoomer/functions/magnet/Magnet2.java index 01448ebc3..3db5dac53 100644 --- a/src/fractalzoomer/functions/magnet/Magnet2.java +++ b/src/fractalzoomer/functions/magnet/Magnet2.java @@ -37,7 +37,7 @@ public Magnet2(double xCenter, double yCenter, double size, int max_iterations, super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); @@ -61,10 +61,8 @@ public Magnet2(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.ITERATIONS_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; - break; case MainWindow.ITERATIONS_PLUS_RE_PLUS_IM_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; } @@ -81,15 +79,13 @@ public Magnet2(double xCenter, double yCenter, double size, int max_iterations, super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, xJuliaCenter, yJuliaCenter); - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); switch (out_coloring_algorithm) { case MainWindow.ITERATIONS_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; - break; case MainWindow.ITERATIONS_PLUS_RE_PLUS_IM_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; } diff --git a/src/fractalzoomer/functions/magnet/Magnet23.java b/src/fractalzoomer/functions/magnet/Magnet23.java index 2ddda905d..9115202c5 100644 --- a/src/fractalzoomer/functions/magnet/Magnet23.java +++ b/src/fractalzoomer/functions/magnet/Magnet23.java @@ -37,7 +37,7 @@ public Magnet23(double xCenter, double yCenter, double size, int max_iterations, super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); @@ -61,10 +61,8 @@ public Magnet23(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.ITERATIONS_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; - break; case MainWindow.ITERATIONS_PLUS_RE_PLUS_IM_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; } @@ -81,15 +79,13 @@ public Magnet23(double xCenter, double yCenter, double size, int max_iterations, super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, xJuliaCenter, yJuliaCenter); - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); switch (out_coloring_algorithm) { case MainWindow.ITERATIONS_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; - break; case MainWindow.ITERATIONS_PLUS_RE_PLUS_IM_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; } diff --git a/src/fractalzoomer/functions/magnet/Magnet24.java b/src/fractalzoomer/functions/magnet/Magnet24.java index 82d336106..c187c82ba 100644 --- a/src/fractalzoomer/functions/magnet/Magnet24.java +++ b/src/fractalzoomer/functions/magnet/Magnet24.java @@ -37,7 +37,7 @@ public Magnet24(double xCenter, double yCenter, double size, int max_iterations, super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - convergent_bailout = 1E-9; + setConvergentBailout(1E-19); setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); @@ -61,10 +61,8 @@ public Magnet24(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.ITERATIONS_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; - break; case MainWindow.ITERATIONS_PLUS_RE_PLUS_IM_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; } @@ -81,15 +79,13 @@ public Magnet24(double xCenter, double yCenter, double size, int max_iterations, super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, xJuliaCenter, yJuliaCenter); - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); switch (out_coloring_algorithm) { case MainWindow.ITERATIONS_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; - break; case MainWindow.ITERATIONS_PLUS_RE_PLUS_IM_PLUS_RE_DIVIDE_IM: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; } diff --git a/src/fractalzoomer/functions/magnet/MagnetPataki2.java b/src/fractalzoomer/functions/magnet/MagnetPataki2.java index 0e7f08fb4..3994916ef 100644 --- a/src/fractalzoomer/functions/magnet/MagnetPataki2.java +++ b/src/fractalzoomer/functions/magnet/MagnetPataki2.java @@ -12,6 +12,7 @@ import fractalzoomer.utils.NormComponents; import java.util.ArrayList; +import java.util.function.Function; public class MagnetPataki2 extends MagnetPatakiType { @@ -19,7 +20,7 @@ public MagnetPataki2(double xCenter, double yCenter, double size, int max_iterat super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, out_coloring_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, smoothing, periodicity_checking, plane_type, rotation_vals, rotation_center, perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, user_perturbation_conditions, user_perturbation_condition_formula, perturbation_user_formula, init_value, initial_vals, variable_init_value, user_initial_value_algorithm, user_initial_value_conditions, user_initial_value_condition_formula, initial_value_user_formula, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, escaping_smooth_algorithm, ots, sts); - power = exponent = 2; + exponent = 2; setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); if(init_value) { @@ -53,7 +54,7 @@ public MagnetPataki2(double xCenter, double yCenter, double size, int max_iterat super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, out_coloring_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, smoothing, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, escaping_smooth_algorithm, ots, sts, xJuliaCenter, yJuliaCenter); - power = exponent = 2; + exponent = 2; OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, escaping_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); InColoringAlgorithmFactory(in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, plane_transform_center); @@ -72,7 +73,7 @@ public MagnetPataki2(double xCenter, double yCenter, double size, int max_iterat super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, rotation_vals, rotation_center, perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, user_perturbation_conditions, user_perturbation_condition_formula, perturbation_user_formula, init_value, initial_vals, variable_init_value, user_initial_value_algorithm, user_initial_value_conditions, user_initial_value_condition_formula, initial_value_user_formula, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower); - power = exponent = 2; + exponent = 2; setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); @@ -98,7 +99,7 @@ public MagnetPataki2(double xCenter, double yCenter, double size, int max_iterat public MagnetPataki2(double xCenter, double yCenter, double size, int max_iterations, ArrayList complex_orbit, int plane_type, boolean apply_plane_on_julia, boolean apply_plane_on_julia_seed, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, double xJuliaCenter, double yJuliaCenter) { super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); - power = exponent = 2; + exponent = 2; pertur_val = new DefaultPerturbation(); init_val = new InitialValue(0, 0); } @@ -194,7 +195,7 @@ public Complex perturbationFunction(Complex z, Complex c, int RefIteration) { Complex Z = getArrayValue(reference, RefIteration); - Complex zsqrs1 = getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration); + Complex zsqrs1 = getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration, Z); Complex temp = Z.times2().plus(z).times_mutable(z); //(2*Z + z)*z @@ -203,7 +204,7 @@ public Complex perturbationFunction(Complex z, Complex c, int RefIteration) { .sub_mutable(zsqrs1.times(c)).negative_mutable(); Complex denom = temp.times(zsqrs1) - .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration)) + .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration, Z)) ; return num.divide_mutable(denom); @@ -215,7 +216,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, MantExpComplex c, i MantExpComplex Z = getArrayDeepValue(referenceDeep, RefIteration); - MantExpComplex zsqrs1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration); + MantExpComplex zsqrs1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration, Z); MantExpComplex temp = Z.times2().plus(z).times_mutable(z); //(2*Z + z)*z @@ -224,7 +225,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, MantExpComplex c, i .sub_mutable(zsqrs1.times(c)).negative_mutable(); MantExpComplex denom = temp.times(zsqrs1) - .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); @@ -235,7 +236,7 @@ public Complex perturbationFunction(Complex z, int RefIteration) { Complex Z = getArrayValue(reference, RefIteration); - Complex zsqrs1 = getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration); + Complex zsqrs1 = getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration, Z); Complex temp = Z.times2().plus(z).times_mutable(z); //(2*Z + z)*z @@ -244,7 +245,7 @@ public Complex perturbationFunction(Complex z, int RefIteration) { .negative_mutable(); Complex denom = temp.times(zsqrs1) - .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); } @@ -254,7 +255,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, int RefIteration) { MantExpComplex Z = getArrayDeepValue(referenceDeep, RefIteration); - MantExpComplex zsqrs1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration); + MantExpComplex zsqrs1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration, Z); MantExpComplex temp = Z.times2().plus(z).times_mutable(z); //(2*Z + z)*z @@ -263,7 +264,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, int RefIteration) { .negative_mutable(); MantExpComplex denom = temp.times(zsqrs1) - .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); @@ -273,7 +274,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, int RefIteration) { public Complex perturbationFunction(Complex z, ReferenceData data, int RefIteration) { Complex Z = getArrayValue(data.Reference, RefIteration); - Complex zsqrs1 = getArrayValue(data.PrecalculatedTerms[0], RefIteration); + Complex zsqrs1 = getArrayValue(data.PrecalculatedTerms[0], RefIteration, Z); Complex temp = Z.times2().plus(z).times_mutable(z); //(2*Z + z)*z @@ -282,7 +283,7 @@ public Complex perturbationFunction(Complex z, ReferenceData data, int RefIterat .negative_mutable(); Complex denom = temp.times(zsqrs1) - .plus_mutable(getArrayValue(data.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayValue(data.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); @@ -292,7 +293,7 @@ public Complex perturbationFunction(Complex z, ReferenceData data, int RefIterat public MantExpComplex perturbationFunction(MantExpComplex z, ReferenceDeepData data, int RefIteration) { MantExpComplex Z = getArrayDeepValue(data.Reference, RefIteration); - MantExpComplex zsqrs1 = getArrayDeepValue(data.PrecalculatedTerms[0], RefIteration); + MantExpComplex zsqrs1 = getArrayDeepValue(data.PrecalculatedTerms[0], RefIteration, Z); MantExpComplex temp = Z.times2().plus(z).times_mutable(z); //(2*Z + z)*z @@ -301,14 +302,28 @@ public MantExpComplex perturbationFunction(MantExpComplex z, ReferenceDeepData d .negative_mutable(); MantExpComplex denom = temp.times(zsqrs1) - .plus_mutable(getArrayDeepValue(data.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayDeepValue(data.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); } @Override - protected GenericComplex[] precalculateReferenceData(GenericComplex z, GenericComplex c, NormComponents normData, Location loc, int bigNumLib, boolean lowPrecReferenceOrbitNeeded, boolean deepZoom, ReferenceData referenceData, ReferenceDeepData referenceDeepData, int iterations) { + protected Function[] getPrecalculatedTermsFunctions(Complex c) { + Function f1 = x -> x.square().sub_mutable(1); + Function f2 = x -> {Complex temp = x.square(); return temp.sub(2).times_mutable(temp).plus_mutable(1);}; + return new Function[] {f1, f2}; + } + + @Override + protected Function[] getPrecalculatedTermsFunctionsDeep(MantExpComplex c) { + Function f1 = x -> x.square().sub_mutable(MantExp.ONE); + Function f2 = x -> {MantExpComplex temp = x.square(); return temp.sub(MantExp.TWO).times_mutable(temp).plus_mutable(MantExp.ONE);}; + return new Function[] {f1, f2}; + } + + @Override + protected GenericComplex[] precalculateReferenceData(GenericComplex z, GenericComplex c, NormComponents normData, Location loc, int bigNumLib, boolean lowPrecReferenceOrbitNeeded, boolean deepZoom, ReferenceData referenceData, ReferenceDeepData referenceDeepData, int iterations, Complex cz, MantExpComplex mcz) { GenericComplex zsqr; if(normData != null) { zsqr = z.squareFast_mutable(normData); @@ -325,13 +340,6 @@ protected GenericComplex[] precalculateReferenceData(GenericComplex z, GenericCo preCalc = zsqr.sub(MyApfloat.ONE); } - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[0], iterations, preCalc.toComplex()); - } - if(deepZoom) { - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], iterations, loc.getMantExpComplex(preCalc)); - } - GenericComplex preCalc2; if(bigNumLib != Constants.BIGNUM_APFLOAT) { preCalc2 = zsqr.sub(2).times_mutable(zsqr).plus_mutable(1); @@ -340,11 +348,17 @@ protected GenericComplex[] precalculateReferenceData(GenericComplex z, GenericCo preCalc2 = zsqr.sub(MyApfloat.TWO).times(zsqr).plus(MyApfloat.ONE); } - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[1], iterations, preCalc2.toComplex()); - } + MantExpComplex precalcm = null; + MantExpComplex precalc2m = null; if(deepZoom) { - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], iterations, loc.getMantExpComplex(preCalc2)); + precalcm = loc.getMantExpComplex(preCalc); + precalc2m = loc.getMantExpComplex(preCalc2); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], iterations, precalcm, mcz); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], iterations, precalc2m, mcz); + } + if(lowPrecReferenceOrbitNeeded) { + setArrayValue(referenceData.PrecalculatedTerms[0], iterations, deepZoom ? precalcm.toComplex() : preCalc.toComplex(), cz); + setArrayValue(referenceData.PrecalculatedTerms[1], iterations, deepZoom ? precalc2m.toComplex() : preCalc2.toComplex(), cz); } return new GenericComplex[] {zsqr, preCalc}; @@ -360,5 +374,20 @@ public String getRefType() { return super.getRefType() + (isJulia ? "-Julia-" + bigSeed.toStringPretty() : ""); } + @Override + public boolean supportsReferenceCompression() { + return true; + } + @Override + public Complex function(Complex z, Complex c) { + Complex zsqr = z.square(); + return zsqr.plus(c).divide_mutable(zsqr.sub(1)); + } + + @Override + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + MantExpComplex zsqr = z.square(); + return zsqr.plus(c).divide_mutable(zsqr.sub(MantExp.ONE)); + } } diff --git a/src/fractalzoomer/functions/magnet/MagnetPataki3.java b/src/fractalzoomer/functions/magnet/MagnetPataki3.java index f822d09d8..47cbc0559 100644 --- a/src/fractalzoomer/functions/magnet/MagnetPataki3.java +++ b/src/fractalzoomer/functions/magnet/MagnetPataki3.java @@ -12,6 +12,7 @@ import fractalzoomer.utils.NormComponents; import java.util.ArrayList; +import java.util.function.Function; public class MagnetPataki3 extends MagnetPatakiType { @@ -19,7 +20,7 @@ public MagnetPataki3(double xCenter, double yCenter, double size, int max_iterat super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, out_coloring_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, smoothing, periodicity_checking, plane_type, rotation_vals, rotation_center, perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, user_perturbation_conditions, user_perturbation_condition_formula, perturbation_user_formula, init_value, initial_vals, variable_init_value, user_initial_value_algorithm, user_initial_value_conditions, user_initial_value_condition_formula, initial_value_user_formula, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, escaping_smooth_algorithm, ots, sts); - power = exponent = 3; + exponent = 3; setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); if(init_value) { @@ -53,7 +54,7 @@ public MagnetPataki3(double xCenter, double yCenter, double size, int max_iterat super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, out_coloring_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, smoothing, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, escaping_smooth_algorithm, ots, sts, xJuliaCenter, yJuliaCenter); - power = exponent = 3; + exponent = 3; OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, escaping_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); InColoringAlgorithmFactory(in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, plane_transform_center); @@ -72,7 +73,7 @@ public MagnetPataki3(double xCenter, double yCenter, double size, int max_iterat super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, rotation_vals, rotation_center, perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, user_perturbation_conditions, user_perturbation_condition_formula, perturbation_user_formula, init_value, initial_vals, variable_init_value, user_initial_value_algorithm, user_initial_value_conditions, user_initial_value_condition_formula, initial_value_user_formula, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower); - power = exponent = 3; + exponent = 3; setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); @@ -98,7 +99,7 @@ public MagnetPataki3(double xCenter, double yCenter, double size, int max_iterat public MagnetPataki3(double xCenter, double yCenter, double size, int max_iterations, ArrayList complex_orbit, int plane_type, boolean apply_plane_on_julia, boolean apply_plane_on_julia_seed, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, double xJuliaCenter, double yJuliaCenter) { super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); - power = exponent = 3; + exponent = 3; pertur_val = new DefaultPerturbation(); init_val = new InitialValue(0, 0); } @@ -147,7 +148,7 @@ public Complex perturbationFunction(Complex z, Complex c, int RefIteration) { Complex Z = getArrayValue(reference, RefIteration); Complex Zsqr = Z.square(); - Complex zcubes1 = getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration); + Complex zcubes1 = getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration, Z); Complex temp = Zsqr.times(3).plus_mutable(Z.times(3).plus_mutable(z).times_mutable(z)).times_mutable(z); //3*Z^2 + (3*Z + z)*z)*z @@ -155,7 +156,7 @@ public Complex perturbationFunction(Complex z, Complex c, int RefIteration) { .sub_mutable(zcubes1.times(c)).negative_mutable(); Complex denom = temp.times(zcubes1) - .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); @@ -168,7 +169,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, MantExpComplex c, i MantExpComplex Zsqr = Z.square(); - MantExpComplex zcubes1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration); + MantExpComplex zcubes1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration, Z); MantExpComplex temp = Zsqr.times(MantExp.THREE).plus_mutable(Z.times(MantExp.THREE).plus_mutable(z).times_mutable(z)).times_mutable(z); //3*Z^2 + (3*Z + z)*z)*z @@ -176,7 +177,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, MantExpComplex c, i .sub_mutable(zcubes1.times(c)).negative_mutable(); MantExpComplex denom = temp.times(zcubes1) - .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); @@ -188,7 +189,7 @@ public Complex perturbationFunction(Complex z, int RefIteration) { Complex Z = getArrayValue(reference, RefIteration); Complex Zsqr = Z.square(); - Complex zcubes1 = getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration); + Complex zcubes1 = getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration, Z); Complex temp = Zsqr.times(3).plus_mutable(Z.times(3).plus_mutable(z).times_mutable(z)).times_mutable(z); //3*Z^2 + (3*Z + z)*z)*z @@ -196,7 +197,7 @@ public Complex perturbationFunction(Complex z, int RefIteration) { .negative_mutable(); Complex denom = temp.times(zcubes1) - .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); } @@ -208,7 +209,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, int RefIteration) { MantExpComplex Zsqr = Z.square(); - MantExpComplex zcubes1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration); + MantExpComplex zcubes1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration, Z); MantExpComplex temp = Zsqr.times(MantExp.THREE).plus_mutable(Z.times(MantExp.THREE).plus_mutable(z).times_mutable(z)).times_mutable(z); //3*Z^2 + (3*Z + z)*z)*z @@ -216,7 +217,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, int RefIteration) { .negative_mutable(); MantExpComplex denom = temp.times(zcubes1) - .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); @@ -227,7 +228,7 @@ public Complex perturbationFunction(Complex z, ReferenceData data, int RefIterat Complex Z = getArrayValue(data.Reference, RefIteration); Complex Zsqr = Z.square(); - Complex zcubes1 = getArrayValue(data.PrecalculatedTerms[0], RefIteration); + Complex zcubes1 = getArrayValue(data.PrecalculatedTerms[0], RefIteration, Z); Complex temp = Zsqr.times(3).plus_mutable(Z.times(3).plus_mutable(z).times_mutable(z)).times_mutable(z); //3*Z^2 + (3*Z + z)*z)*z @@ -235,7 +236,7 @@ public Complex perturbationFunction(Complex z, ReferenceData data, int RefIterat .negative_mutable(); Complex denom = temp.times(zcubes1) - .plus_mutable(getArrayValue(data.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayValue(data.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); @@ -246,7 +247,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, ReferenceDeepData d MantExpComplex Z = getArrayDeepValue(data.Reference, RefIteration); MantExpComplex Zsqr = Z.square(); - MantExpComplex zcubes1 = getArrayDeepValue(data.PrecalculatedTerms[0], RefIteration); + MantExpComplex zcubes1 = getArrayDeepValue(data.PrecalculatedTerms[0], RefIteration, Z); MantExpComplex temp = Zsqr.times(MantExp.THREE).plus_mutable(Z.times(MantExp.THREE).plus_mutable(z).times_mutable(z)).times_mutable(z); //3*Z^2 + (3*Z + z)*z)*z @@ -254,14 +255,28 @@ public MantExpComplex perturbationFunction(MantExpComplex z, ReferenceDeepData d .negative_mutable(); MantExpComplex denom = temp.times(zcubes1) - .plus_mutable(getArrayDeepValue(data.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayDeepValue(data.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); } @Override - protected GenericComplex[] precalculateReferenceData(GenericComplex z, GenericComplex c, NormComponents normData, Location loc, int bigNumLib, boolean lowPrecReferenceOrbitNeeded, boolean deepZoom, ReferenceData referenceData, ReferenceDeepData referenceDeepData, int iterations) { + protected Function[] getPrecalculatedTermsFunctions(Complex c) { + Function f1 = x -> x.cube().sub_mutable(1); + Function f2 = x -> {Complex temp = x.cube(); return temp.sub(2).times_mutable(temp).plus_mutable(1);}; + return new Function[] {f1, f2}; + } + + @Override + protected Function[] getPrecalculatedTermsFunctionsDeep(MantExpComplex c) { + Function f1 = x -> x.cube().sub_mutable(MantExp.ONE); + Function f2 = x -> {MantExpComplex temp = x.cube(); return temp.sub(MantExp.TWO).times_mutable(temp).plus_mutable(MantExp.ONE);}; + return new Function[] {f1, f2}; + } + + @Override + protected GenericComplex[] precalculateReferenceData(GenericComplex z, GenericComplex c, NormComponents normData, Location loc, int bigNumLib, boolean lowPrecReferenceOrbitNeeded, boolean deepZoom, ReferenceData referenceData, ReferenceDeepData referenceDeepData, int iterations, Complex cz, MantExpComplex mcz) { GenericComplex zcube; if(normData != null) { zcube = z.cubeFast_mutable(normData); @@ -278,13 +293,6 @@ protected GenericComplex[] precalculateReferenceData(GenericComplex z, GenericCo preCalc = zcube.sub(MyApfloat.ONE); } - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[0], iterations, preCalc.toComplex()); - } - if(deepZoom) { - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], iterations, loc.getMantExpComplex(preCalc)); - } - GenericComplex preCalc2; if(bigNumLib != Constants.BIGNUM_APFLOAT) { preCalc2 = zcube.sub(2).times_mutable(zcube).plus_mutable(1); @@ -293,11 +301,17 @@ protected GenericComplex[] precalculateReferenceData(GenericComplex z, GenericCo preCalc2 = zcube.sub(MyApfloat.TWO).times(zcube).plus(MyApfloat.ONE); } - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[1], iterations, preCalc2.toComplex()); - } + MantExpComplex precalcm = null; + MantExpComplex precalc2m = null; if(deepZoom) { - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], iterations, loc.getMantExpComplex(preCalc2)); + precalcm = loc.getMantExpComplex(preCalc); + precalc2m = loc.getMantExpComplex(preCalc2); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], iterations, precalcm, mcz); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], iterations, precalc2m, mcz); + } + if(lowPrecReferenceOrbitNeeded) { + setArrayValue(referenceData.PrecalculatedTerms[0], iterations, deepZoom ? precalcm.toComplex() : preCalc.toComplex(), cz); + setArrayValue(referenceData.PrecalculatedTerms[1], iterations, deepZoom ? precalc2m.toComplex() : preCalc2.toComplex(), cz); } return new GenericComplex[] {zcube, preCalc}; @@ -313,5 +327,22 @@ public String getRefType() { return super.getRefType() + (isJulia ? "-Julia-" + bigSeed.toStringPretty() : ""); } + @Override + public boolean supportsReferenceCompression() { + return true; + } + + @Override + public Complex function(Complex z, Complex c) { + Complex zcube = z.cube(); + return zcube.plus(c).divide_mutable(zcube.sub(1)); + } + + @Override + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + MantExpComplex zcube = z.cube(); + return zcube.plus(c).divide_mutable(zcube.sub(MantExp.ONE)); + } + } diff --git a/src/fractalzoomer/functions/magnet/MagnetPataki4.java b/src/fractalzoomer/functions/magnet/MagnetPataki4.java index 7de29c6b0..147f19339 100644 --- a/src/fractalzoomer/functions/magnet/MagnetPataki4.java +++ b/src/fractalzoomer/functions/magnet/MagnetPataki4.java @@ -12,6 +12,7 @@ import fractalzoomer.utils.NormComponents; import java.util.ArrayList; +import java.util.function.Function; public class MagnetPataki4 extends MagnetPatakiType { @@ -19,7 +20,7 @@ public MagnetPataki4(double xCenter, double yCenter, double size, int max_iterat super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, out_coloring_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, smoothing, periodicity_checking, plane_type, rotation_vals, rotation_center, perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, user_perturbation_conditions, user_perturbation_condition_formula, perturbation_user_formula, init_value, initial_vals, variable_init_value, user_initial_value_algorithm, user_initial_value_conditions, user_initial_value_condition_formula, initial_value_user_formula, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, escaping_smooth_algorithm, ots, sts); - power = exponent = 4; + exponent = 4; setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); if(init_value) { @@ -53,7 +54,7 @@ public MagnetPataki4(double xCenter, double yCenter, double size, int max_iterat super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, out_coloring_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, smoothing, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, escaping_smooth_algorithm, ots, sts, xJuliaCenter, yJuliaCenter); - power = exponent = 4; + exponent = 4; OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, escaping_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); InColoringAlgorithmFactory(in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, plane_transform_center); @@ -72,7 +73,7 @@ public MagnetPataki4(double xCenter, double yCenter, double size, int max_iterat super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, rotation_vals, rotation_center, perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, user_perturbation_conditions, user_perturbation_condition_formula, perturbation_user_formula, init_value, initial_vals, variable_init_value, user_initial_value_algorithm, user_initial_value_conditions, user_initial_value_condition_formula, initial_value_user_formula, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower); - power = exponent = 4; + exponent = 4; setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); @@ -98,7 +99,7 @@ public MagnetPataki4(double xCenter, double yCenter, double size, int max_iterat public MagnetPataki4(double xCenter, double yCenter, double size, int max_iterations, ArrayList complex_orbit, int plane_type, boolean apply_plane_on_julia, boolean apply_plane_on_julia_seed, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, double xJuliaCenter, double yJuliaCenter) { super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); - power = exponent = 4; + exponent = 4; pertur_val = new DefaultPerturbation(); init_val = new InitialValue(0, 0); } @@ -148,7 +149,7 @@ public Complex perturbationFunction(Complex z, Complex c, int RefIteration) { Complex ZCube = Z.cube(); Complex Zsqr = Z.square(); - Complex zfourths1 = getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration); + Complex zfourths1 = getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration, Z); Complex temp = z.plus(Z.times4()).times_mutable(z).plus_mutable(Zsqr.times(6)).times_mutable(z).plus_mutable(ZCube.times4()).times_mutable(z); @@ -156,7 +157,7 @@ public Complex perturbationFunction(Complex z, Complex c, int RefIteration) { .sub_mutable(zfourths1.times(c)).negative_mutable(); Complex denom = temp.times(zfourths1) - .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); @@ -170,7 +171,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, MantExpComplex c, i MantExpComplex ZCube = Z.cube(); MantExpComplex Zsqr = Z.square(); - MantExpComplex zfourths1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration); + MantExpComplex zfourths1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration, Z); MantExpComplex temp = z.plus(Z.times4()).times_mutable(z).plus_mutable(Zsqr.times(MantExp.SIX)).times_mutable(z).plus_mutable(ZCube.times4()).times_mutable(z); @@ -178,7 +179,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, MantExpComplex c, i .sub_mutable(zfourths1.times(c)).negative_mutable(); MantExpComplex denom = temp.times(zfourths1) - .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); @@ -191,7 +192,7 @@ public Complex perturbationFunction(Complex z, int RefIteration) { Complex ZCube = Z.cube(); Complex Zsqr = Z.square(); - Complex zfourths1 = getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration); + Complex zfourths1 = getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration, Z); Complex temp = z.plus(Z.times4()).times_mutable(z).plus_mutable(Zsqr.times(6)).times_mutable(z).plus_mutable(ZCube.times4()).times_mutable(z); @@ -199,7 +200,7 @@ public Complex perturbationFunction(Complex z, int RefIteration) { .negative_mutable(); Complex denom = temp.times(zfourths1) - .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); } @@ -213,7 +214,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, int RefIteration) { MantExpComplex Zsqr = Z.square(); - MantExpComplex zfourths1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration); + MantExpComplex zfourths1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration, Z); MantExpComplex temp = z.plus(Z.times4()).times_mutable(z).plus_mutable(Zsqr.times(MantExp.SIX)).times_mutable(z).plus_mutable(ZCube.times4()).times_mutable(z); @@ -221,7 +222,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, int RefIteration) { .negative_mutable(); MantExpComplex denom = temp.times(zfourths1) - .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); @@ -233,7 +234,7 @@ public Complex perturbationFunction(Complex z, ReferenceData data, int RefIterat Complex ZCube = Z.cube(); Complex Zsqr = Z.square(); - Complex zfourths1 = getArrayValue(data.PrecalculatedTerms[0], RefIteration); + Complex zfourths1 = getArrayValue(data.PrecalculatedTerms[0], RefIteration, Z); Complex temp = z.plus(Z.times4()).times_mutable(z).plus_mutable(Zsqr.times(6)).times_mutable(z).plus_mutable(ZCube.times4()).times_mutable(z); @@ -241,7 +242,7 @@ public Complex perturbationFunction(Complex z, ReferenceData data, int RefIterat .negative_mutable(); Complex denom = temp.times(zfourths1) - .plus_mutable(getArrayValue(data.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayValue(data.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); @@ -254,7 +255,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, ReferenceDeepData d MantExpComplex Zsqr = Z.square(); - MantExpComplex zfourths1 = getArrayDeepValue(data.PrecalculatedTerms[0], RefIteration); + MantExpComplex zfourths1 = getArrayDeepValue(data.PrecalculatedTerms[0], RefIteration, Z); MantExpComplex temp = z.plus(Z.times4()).times_mutable(z).plus_mutable(Zsqr.times(MantExp.SIX)).times_mutable(z).plus_mutable(ZCube.times4()).times_mutable(z); @@ -262,14 +263,28 @@ public MantExpComplex perturbationFunction(MantExpComplex z, ReferenceDeepData d .negative_mutable(); MantExpComplex denom = temp.times(zfourths1) - .plus_mutable(getArrayDeepValue(data.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayDeepValue(data.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); } @Override - protected GenericComplex[] precalculateReferenceData(GenericComplex z, GenericComplex c, NormComponents normData, Location loc, int bigNumLib, boolean lowPrecReferenceOrbitNeeded, boolean deepZoom, ReferenceData referenceData, ReferenceDeepData referenceDeepData, int iterations) { + protected Function[] getPrecalculatedTermsFunctions(Complex c) { + Function f1 = x -> x.fourth().sub_mutable(1); + Function f2 = x -> {Complex temp = x.fourth(); return temp.sub(2).times_mutable(temp).plus_mutable(1);}; + return new Function[] {f1, f2}; + } + + @Override + protected Function[] getPrecalculatedTermsFunctionsDeep(MantExpComplex c) { + Function f1 = x -> x.fourth().sub_mutable(MantExp.ONE); + Function f2 = x -> {MantExpComplex temp = x.fourth(); return temp.sub(MantExp.TWO).times_mutable(temp).plus_mutable(MantExp.ONE);}; + return new Function[] {f1, f2}; + } + + @Override + protected GenericComplex[] precalculateReferenceData(GenericComplex z, GenericComplex c, NormComponents normData, Location loc, int bigNumLib, boolean lowPrecReferenceOrbitNeeded, boolean deepZoom, ReferenceData referenceData, ReferenceDeepData referenceDeepData, int iterations, Complex cz, MantExpComplex mcz) { GenericComplex zfourth; if(normData != null) { zfourth = z.fourthFast_mutable(normData); @@ -286,13 +301,6 @@ protected GenericComplex[] precalculateReferenceData(GenericComplex z, GenericCo preCalc = zfourth.sub(MyApfloat.ONE); } - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[0], iterations, preCalc.toComplex()); - } - if(deepZoom) { - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], iterations, loc.getMantExpComplex(preCalc)); - } - GenericComplex preCalc2; if(bigNumLib != Constants.BIGNUM_APFLOAT) { preCalc2 = zfourth.sub(2).times_mutable(zfourth).plus_mutable(1); @@ -301,11 +309,18 @@ protected GenericComplex[] precalculateReferenceData(GenericComplex z, GenericCo preCalc2 = zfourth.sub(MyApfloat.TWO).times(zfourth).plus(MyApfloat.ONE); } - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[1], iterations, preCalc2.toComplex()); - } + MantExpComplex precalM = null; + MantExpComplex precal2M = null; if(deepZoom) { - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], iterations, loc.getMantExpComplex(preCalc2)); + precalM = loc.getMantExpComplex(preCalc); + precal2M = loc.getMantExpComplex(preCalc2); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], iterations, precalM, mcz); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], iterations, precal2M, mcz); + } + + if(lowPrecReferenceOrbitNeeded) { + setArrayValue(referenceData.PrecalculatedTerms[0], iterations, deepZoom ? precalM.toComplex() : preCalc.toComplex(), cz); + setArrayValue(referenceData.PrecalculatedTerms[1], iterations, deepZoom ? precal2M.toComplex() : preCalc2.toComplex(), cz); } return new GenericComplex[] {zfourth, preCalc}; @@ -321,5 +336,22 @@ public String getRefType() { return super.getRefType() + (isJulia ? "-Julia-" + bigSeed.toStringPretty() : ""); } + @Override + public boolean supportsReferenceCompression() { + return true; + } + + @Override + public Complex function(Complex z, Complex c) { + Complex zfourth = z.fourth(); + return zfourth.plus(c).divide_mutable(zfourth.sub(1)); + } + + @Override + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + MantExpComplex zfourth = z.fourth(); + return zfourth.plus(c).divide_mutable(zfourth.sub(MantExp.ONE)); + } + } diff --git a/src/fractalzoomer/functions/magnet/MagnetPataki5.java b/src/fractalzoomer/functions/magnet/MagnetPataki5.java index 36e78e137..c1392f182 100644 --- a/src/fractalzoomer/functions/magnet/MagnetPataki5.java +++ b/src/fractalzoomer/functions/magnet/MagnetPataki5.java @@ -12,6 +12,7 @@ import fractalzoomer.utils.NormComponents; import java.util.ArrayList; +import java.util.function.Function; public class MagnetPataki5 extends MagnetPatakiType { @@ -19,7 +20,7 @@ public MagnetPataki5(double xCenter, double yCenter, double size, int max_iterat super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, out_coloring_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, smoothing, periodicity_checking, plane_type, rotation_vals, rotation_center, perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, user_perturbation_conditions, user_perturbation_condition_formula, perturbation_user_formula, init_value, initial_vals, variable_init_value, user_initial_value_algorithm, user_initial_value_conditions, user_initial_value_condition_formula, initial_value_user_formula, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, escaping_smooth_algorithm, ots, sts); - power = exponent = 5; + exponent = 5; setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); if(init_value) { @@ -53,7 +54,7 @@ public MagnetPataki5(double xCenter, double yCenter, double size, int max_iterat super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, out_coloring_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, smoothing, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, escaping_smooth_algorithm, ots, sts, xJuliaCenter, yJuliaCenter); - power = exponent = 5; + exponent = 5; OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, escaping_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); InColoringAlgorithmFactory(in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, plane_transform_center); @@ -72,7 +73,7 @@ public MagnetPataki5(double xCenter, double yCenter, double size, int max_iterat super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, rotation_vals, rotation_center, perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, user_perturbation_conditions, user_perturbation_condition_formula, perturbation_user_formula, init_value, initial_vals, variable_init_value, user_initial_value_algorithm, user_initial_value_conditions, user_initial_value_condition_formula, initial_value_user_formula, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower); - power = exponent = 5; + exponent = 5; setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); @@ -98,7 +99,7 @@ public MagnetPataki5(double xCenter, double yCenter, double size, int max_iterat public MagnetPataki5(double xCenter, double yCenter, double size, int max_iterations, ArrayList complex_orbit, int plane_type, boolean apply_plane_on_julia, boolean apply_plane_on_julia_seed, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, double xJuliaCenter, double yJuliaCenter) { super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); - power = exponent = 5; + exponent = 5; pertur_val = new DefaultPerturbation(); init_val = new InitialValue(0, 0); } @@ -149,7 +150,7 @@ public Complex perturbationFunction(Complex z, Complex c, int RefIteration) { Complex ZCube = Z.cube(); Complex Zsqr = Z.square(); - Complex zfifths1 = getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration); + Complex zfifths1 = getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration, Z); Complex temp = ZFourth.times(5).plus_mutable(ZCube.times(10).plus_mutable(Zsqr.times(10).plus_mutable(Z.times(5).plus_mutable(z).times_mutable(z)).times_mutable(z)).times_mutable(z)).times_mutable(z); @@ -157,7 +158,7 @@ public Complex perturbationFunction(Complex z, Complex c, int RefIteration) { .sub_mutable(zfifths1.times(c)).negative_mutable(); Complex denom = temp.times(zfifths1) - .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); @@ -172,7 +173,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, MantExpComplex c, i MantExpComplex ZCube = Z.cube(); MantExpComplex Zsqr = Z.square(); - MantExpComplex zfifths1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration); + MantExpComplex zfifths1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration, Z); MantExpComplex temp = ZFourth.times(MantExp.FIVE).plus_mutable(ZCube.times(MantExp.TEN).plus_mutable(Zsqr.times(MantExp.TEN).plus_mutable(Z.times(MantExp.FIVE).plus_mutable(z).times_mutable(z)).times_mutable(z)).times_mutable(z)).times_mutable(z); @@ -180,7 +181,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, MantExpComplex c, i .sub_mutable(zfifths1.times(c)).negative_mutable(); MantExpComplex denom = temp.times(zfifths1) - .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); @@ -194,7 +195,7 @@ public Complex perturbationFunction(Complex z, int RefIteration) { Complex ZCube = Z.cube(); Complex Zsqr = Z.square(); - Complex zfifths1 = getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration); + Complex zfifths1 = getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration, Z); Complex temp = ZFourth.times(5).plus_mutable(ZCube.times(10).plus_mutable(Zsqr.times(10).plus_mutable(Z.times(5).plus_mutable(z).times_mutable(z)).times_mutable(z)).times_mutable(z)).times_mutable(z); @@ -202,7 +203,7 @@ public Complex perturbationFunction(Complex z, int RefIteration) { .negative_mutable(); Complex denom = temp.times(zfifths1) - .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayValue(referenceData.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); } @@ -216,7 +217,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, int RefIteration) { MantExpComplex ZCube = Z.cube(); MantExpComplex Zsqr = Z.square(); - MantExpComplex zfifths1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration); + MantExpComplex zfifths1 = getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration, Z); MantExpComplex temp = ZFourth.times(MantExp.FIVE).plus_mutable(ZCube.times(MantExp.TEN).plus_mutable(Zsqr.times(MantExp.TEN).plus_mutable(Z.times(MantExp.FIVE).plus_mutable(z).times_mutable(z)).times_mutable(z)).times_mutable(z)).times_mutable(z); @@ -224,7 +225,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, int RefIteration) { .negative_mutable(); MantExpComplex denom = temp.times(zfifths1) - .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); @@ -238,7 +239,7 @@ public Complex perturbationFunction(Complex z, ReferenceData data, int RefIterat Complex ZCube = Z.cube(); Complex Zsqr = Z.square(); - Complex zfifths1 = getArrayValue(data.PrecalculatedTerms[0], RefIteration); + Complex zfifths1 = getArrayValue(data.PrecalculatedTerms[0], RefIteration, Z); Complex temp = ZFourth.times(5).plus_mutable(ZCube.times(10).plus_mutable(Zsqr.times(10).plus_mutable(Z.times(5).plus_mutable(z).times_mutable(z)).times_mutable(z)).times_mutable(z)).times_mutable(z); @@ -246,7 +247,7 @@ public Complex perturbationFunction(Complex z, ReferenceData data, int RefIterat .negative_mutable(); Complex denom = temp.times(zfifths1) - .plus_mutable(getArrayValue(data.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayValue(data.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); @@ -260,7 +261,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, ReferenceDeepData d MantExpComplex ZCube = Z.cube(); MantExpComplex Zsqr = Z.square(); - MantExpComplex zfifths1 = getArrayDeepValue(data.PrecalculatedTerms[0], RefIteration); + MantExpComplex zfifths1 = getArrayDeepValue(data.PrecalculatedTerms[0], RefIteration, Z); MantExpComplex temp = ZFourth.times(MantExp.FIVE).plus_mutable(ZCube.times(MantExp.TEN).plus_mutable(Zsqr.times(MantExp.TEN).plus_mutable(Z.times(MantExp.FIVE).plus_mutable(z).times_mutable(z)).times_mutable(z)).times_mutable(z)).times_mutable(z); @@ -268,14 +269,28 @@ public MantExpComplex perturbationFunction(MantExpComplex z, ReferenceDeepData d .negative_mutable(); MantExpComplex denom = temp.times(zfifths1) - .plus_mutable(getArrayDeepValue(data.PrecalculatedTerms[1], RefIteration)); + .plus_mutable(getArrayDeepValue(data.PrecalculatedTerms[1], RefIteration, Z)); return num.divide_mutable(denom); } @Override - protected GenericComplex[] precalculateReferenceData(GenericComplex z, GenericComplex c, NormComponents normData, Location loc, int bigNumLib, boolean lowPrecReferenceOrbitNeeded, boolean deepZoom, ReferenceData referenceData, ReferenceDeepData referenceDeepData, int iterations) { + protected Function[] getPrecalculatedTermsFunctions(Complex c) { + Function f1 = x -> x.fifth().sub_mutable(1); + Function f2 = x -> {Complex temp = x.fifth(); return temp.sub(2).times_mutable(temp).plus_mutable(1);}; + return new Function[] {f1, f2}; + } + + @Override + protected Function[] getPrecalculatedTermsFunctionsDeep(MantExpComplex c) { + Function f1 = x -> x.fifth().sub_mutable(MantExp.ONE); + Function f2 = x -> {MantExpComplex temp = x.fifth(); return temp.sub(MantExp.TWO).times_mutable(temp).plus_mutable(MantExp.ONE);}; + return new Function[] {f1, f2}; + } + + @Override + protected GenericComplex[] precalculateReferenceData(GenericComplex z, GenericComplex c, NormComponents normData, Location loc, int bigNumLib, boolean lowPrecReferenceOrbitNeeded, boolean deepZoom, ReferenceData referenceData, ReferenceDeepData referenceDeepData, int iterations, Complex cz, MantExpComplex mcz) { GenericComplex zfifth; if(normData != null) { zfifth = z.fifthFast_mutable(normData); @@ -292,13 +307,6 @@ protected GenericComplex[] precalculateReferenceData(GenericComplex z, GenericCo preCalc = zfifth.sub(MyApfloat.ONE); } - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[0], iterations, preCalc.toComplex()); - } - if(deepZoom) { - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], iterations, loc.getMantExpComplex(preCalc)); - } - GenericComplex preCalc2; if(bigNumLib != Constants.BIGNUM_APFLOAT) { preCalc2 = zfifth.sub(2).times_mutable(zfifth).plus_mutable(1); @@ -307,11 +315,17 @@ protected GenericComplex[] precalculateReferenceData(GenericComplex z, GenericCo preCalc2 = zfifth.sub(MyApfloat.TWO).times(zfifth).plus(MyApfloat.ONE); } - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[1], iterations, preCalc2.toComplex()); - } + MantExpComplex precalcm = null; + MantExpComplex precalc2m = null; if(deepZoom) { - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], iterations, loc.getMantExpComplex(preCalc2)); + precalcm = loc.getMantExpComplex(preCalc); + precalc2m = loc.getMantExpComplex(preCalc2); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], iterations, precalcm, mcz); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[1], iterations, precalc2m, mcz); + } + if(lowPrecReferenceOrbitNeeded) { + setArrayValue(referenceData.PrecalculatedTerms[0], iterations, deepZoom ? precalcm.toComplex() : preCalc.toComplex(), cz); + setArrayValue(referenceData.PrecalculatedTerms[1], iterations, deepZoom ? precalc2m.toComplex() : preCalc2.toComplex(), cz); } return new GenericComplex[] {zfifth, preCalc}; @@ -327,4 +341,21 @@ public String getRefType() { return super.getRefType() + (isJulia ? "-Julia-" + bigSeed.toStringPretty() : ""); } + @Override + public boolean supportsReferenceCompression() { + return true; + } + + @Override + public Complex function(Complex z, Complex c) { + Complex zfifth = z.fifth(); + return zfifth.plus(c).divide_mutable(zfifth.sub(1)); + } + + @Override + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + MantExpComplex zfifth = z.fifth(); + return zfifth.plus(c).divide_mutable(zfifth.sub(MantExp.ONE)); + } + } diff --git a/src/fractalzoomer/functions/magnet/MagnetPatakiType.java b/src/fractalzoomer/functions/magnet/MagnetPatakiType.java index 96b5c92a6..8b7ccf79c 100644 --- a/src/fractalzoomer/functions/magnet/MagnetPatakiType.java +++ b/src/fractalzoomer/functions/magnet/MagnetPatakiType.java @@ -122,12 +122,17 @@ public GenericComplex[] initializeReferencePrecalculationData(GenericComplex c, cp1 = c.plus(MyApfloat.ONE); } - if(lowPrecReferenceOrbitNeeded) { - Cp1 = cp1.toComplex(); - } - if(deepZoom) { Cp1Deep = loc.getMantExpComplex(cp1); + + if(lowPrecReferenceOrbitNeeded) { + Cp1 = Cp1Deep.toComplex(); + } + } + else { + if(lowPrecReferenceOrbitNeeded) { + Cp1 = cp1.toComplex(); + } } return null; @@ -159,6 +164,11 @@ public double getDoubleDoubleLimit() { return 5.0e-25; } - return 1.0e-20; + return 1.0e-18; + } + + @Override + public double getPower() { + return exponent; } } diff --git a/src/fractalzoomer/functions/magnet/MagnetType.java b/src/fractalzoomer/functions/magnet/MagnetType.java index bcc70cbcd..5db0477d3 100644 --- a/src/fractalzoomer/functions/magnet/MagnetType.java +++ b/src/fractalzoomer/functions/magnet/MagnetType.java @@ -48,6 +48,10 @@ public MagnetType(double xCenter, double yCenter, double size, int max_iteration } + protected void setConvergentBailout(double val) { + convergent_bailout = TaskDraw.USER_CONVERGENT_BAILOUT > 0 ? TaskDraw.USER_CONVERGENT_BAILOUT : val; + } + public MagnetType(double xCenter, double yCenter, double size, int max_iterations, int bailout_test_algorithm, double bailout, String bailout_test_user_formula, String bailout_test_user_formula2, int bailout_test_comparison, double n_norm, boolean periodicity_checking, int plane_type, boolean apply_plane_on_julia, boolean apply_plane_on_julia_seed, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, OrbitTrapSettings ots, double xJuliaCenter, double yJuliaCenter) { super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, xJuliaCenter, yJuliaCenter); @@ -283,7 +287,7 @@ public double iterateFractalArbitraryPrecision(GenericComplex[] complex, Generic setTrueColorOut(z, zold, zold2, iterations, c, start, c0, pixelC); } - return out; + return getAndAccumulateHP(out); } gzold2.set(gzold); @@ -310,7 +314,7 @@ public double iterateFractalArbitraryPrecision(GenericComplex[] complex, Generic setTrueColorIn(z, zold, zold2, iterations, c, start, c0, pixelC); } - return in; + return getAndAccumulateHP(in); } @@ -661,7 +665,7 @@ public double iterateFractalWithPerturbation(Complex[] complex, MantExpComplex d int MaxRefIteration = getReferenceFinalIterationNumber(true, referenceData); int minExp = -1000; - int reducedExp = minExp / (int)power; + int reducedExp = minExp / (int)getPower(); DeltaSubN.Normalize(); long exp = DeltaSubN.getMinExp(); @@ -949,7 +953,7 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi int minExp = -1000; - int reducedExp = minExp / (int)power; + int reducedExp = minExp / (int)getPower(); DeltaSubN.Normalize(); long exp = DeltaSubN.getMinExp(); @@ -969,6 +973,7 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi if(useFullFloatExp || (totalSkippedIterations == 0 && exp <= minExp) || (totalSkippedIterations != 0 && exp <= reducedExp)) { MantExpComplex z = getArrayDeepValue(deepData.Reference, RefIteration).plus_mutable(DeltaSubN); + MantExpComplex zoldDeep; for (; iterations < max_iterations; iterations++) { if (trap != null) { trap.check(complex[0], iterations); @@ -999,6 +1004,7 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi zold2.assign(zold); zold.assign(complex[0]); + zoldDeep = z; if (max_iterations > 1) { z = getArrayDeepValue(deepData.Reference, RefIteration).plus_mutable(DeltaSubN); @@ -1006,7 +1012,7 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi } if (statistic != null) { - statistic.insert(complex[0], zold, zold2, iterations, complex[1], start, c0); + statistic.insert(complex[0], zold, zold2, iterations, complex[1], start, c0, z, zoldDeep , null); } if (z.norm_squared().compareToBothPositive(DeltaSubN.norm_squared()) < 0 || RefIteration >= MaxRefIteration) { diff --git a/src/fractalzoomer/functions/mandelbrot/Mandelbar.java b/src/fractalzoomer/functions/mandelbrot/Mandelbar.java index fc3c330a9..37b0a5148 100644 --- a/src/fractalzoomer/functions/mandelbrot/Mandelbar.java +++ b/src/fractalzoomer/functions/mandelbrot/Mandelbar.java @@ -43,8 +43,6 @@ public Mandelbar(double xCenter, double yCenter, double size, int max_iterations super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - power = 2; - setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); if(init_value) { @@ -77,8 +75,6 @@ public Mandelbar(double xCenter, double yCenter, double size, int max_iterations super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, xJuliaCenter, yJuliaCenter); - power = 2; - OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, escaping_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); InColoringAlgorithmFactory(in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, plane_transform_center); @@ -96,8 +92,6 @@ public Mandelbar(double xCenter, double yCenter, double size, int max_iterations super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower); - power = 2; - setPertubationOption(perturbation, perturbation_vals, variable_perturbation, user_perturbation_algorithm, perturbation_user_formula, user_perturbation_conditions, user_perturbation_condition_formula, plane_transform_center); if(init_value) { @@ -122,7 +116,6 @@ public Mandelbar(double xCenter, double yCenter, double size, int max_iterations public Mandelbar(double xCenter, double yCenter, double size, int max_iterations, ArrayList complex_orbit, int plane_type, boolean apply_plane_on_julia, boolean apply_plane_on_julia_seed, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, double xJuliaCenter, double yJuliaCenter) { super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); - power = 2; pertur_val = new DefaultPerturbation(); init_val = new DefaultInitialValue(); } @@ -289,4 +282,24 @@ public boolean supportsBigIntnum() { @Override public boolean supportsMpirBignum() { return true;} + @Override + public boolean supportsReferenceCompression() { + return true; + } + + @Override + public Complex function(Complex z, Complex c) { + return z.conjugate_mutable().square_plus_c_mutable(c); + } + + @Override + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + return z.conjugate_mutable().square_mutable().plus_mutable(c); + } + + @Override + public double getPower() { + return 2; + } + } diff --git a/src/fractalzoomer/functions/mandelbrot/Mandelbrot.java b/src/fractalzoomer/functions/mandelbrot/Mandelbrot.java index 67f99d897..a3504162b 100644 --- a/src/fractalzoomer/functions/mandelbrot/Mandelbrot.java +++ b/src/fractalzoomer/functions/mandelbrot/Mandelbrot.java @@ -36,7 +36,6 @@ import fractalzoomer.fractal_options.initial_value.VariableInitialValue; import fractalzoomer.fractal_options.perturbation.DefaultPerturbation; import fractalzoomer.fractal_options.plane_influence.NoPlaneInfluence; -import fractalzoomer.functions.Fractal; import fractalzoomer.functions.Julia; import fractalzoomer.main.Constants; import fractalzoomer.main.MainWindow; @@ -89,8 +88,6 @@ public Mandelbrot(double xCenter, double yCenter, double size, int max_iteration not_burning_ship = !burning_ship; this.mandel_grass = mandel_grass; - power = 2; - if (burning_ship) { type = new BurningShip(); } else { @@ -174,8 +171,6 @@ public Mandelbrot(double xCenter, double yCenter, double size, int max_iteration not_burning_ship = !burning_ship; this.mandel_grass = mandel_grass; - power = 2; - if (burning_ship) { type = new BurningShip(); } else { @@ -237,8 +232,6 @@ public Mandelbrot(double xCenter, double yCenter, double size, int max_iteration not_burning_ship = !burning_ship; this.mandel_grass = mandel_grass; - power = 2; - if (burning_ship) { type = new BurningShip(); } else { @@ -277,8 +270,6 @@ public Mandelbrot(double xCenter, double yCenter, double size, int max_iteration not_burning_ship = !burning_ship; this.mandel_grass = mandel_grass; - power = 2; - if (burning_ship) { type = new BurningShip(); } else { @@ -915,6 +906,8 @@ public boolean shouldRecalculateForPeriodDetection(boolean deepZoom, Location ex return true; } + initializeReferenceDecompressor(); + if (deepZoom) { if(referenceData.period_mdzdc == null) { return true; @@ -922,8 +915,9 @@ public boolean shouldRecalculateForPeriodDetection(boolean deepZoom, Location ex MantExpComplex mdzdc = referenceData.period_mdzdc; MantExp mradius = externalLocation.getSize().multiply2_mutable(); + MantExp temp = mdzdc.times(mradius).chebyshevNorm(); - if (mradius.multiply(mdzdc.chebychevNorm()).compareToBothPositive(getArrayDeepValue(referenceDeep, DetectedPeriod).chebychevNorm()) > 0) { + if (temp.compareToBothPositiveReduced(getArrayDeepValue(referenceDeep, DetectedPeriod).chebyshevNorm()) > 0) { return false; } } else { @@ -934,7 +928,7 @@ public boolean shouldRecalculateForPeriodDetection(boolean deepZoom, Location ex Complex dzdc = referenceData.period_dzdc; double radius = this.size * 2; - if (radius * dzdc.chebychevNorm() > getArrayValue(reference, DetectedPeriod).chebychevNorm()) { + if (radius * dzdc.chebyshevNorm() > getArrayValue(reference, DetectedPeriod).chebyshevNorm()) { return false; } } @@ -967,17 +961,18 @@ public void calculateReferencePoint(GenericComplex inputPixel, Apfloat size, boo boolean stopReferenceCalculationOnDetectedPeriod = detectPeriod && TaskDraw.STOP_REFERENCE_CALCULATION_AFTER_DETECTED_PERIOD && userPeriod == 0 && canStopOnDetectedPeriod(); DoubleReference.SHOULD_SAVE_MEMORY = stopReferenceCalculationOnDetectedPeriod; + boolean useCompressedRef = TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE && supportsReferenceCompression(); if (iterations == 0) { if(lowPrecReferenceOrbitNeeded) { - referenceData.createAndSetShortcut(max_ref_iterations,false, 0); + referenceData.createAndSetShortcut(max_ref_iterations,false, 0, useCompressedRef); } else { referenceData.deallocate(); } if (deepZoom) { - referenceDeepData.createAndSetShortcut(max_ref_iterations,false, 0); + referenceDeepData.createAndSetShortcut(max_ref_iterations,false, 0, useCompressedRef); } } else if (max_ref_iterations > getReferenceLength()) { if(lowPrecReferenceOrbitNeeded) { @@ -1017,8 +1012,8 @@ public void calculateReferencePoint(GenericComplex inputPixel, Apfloat size, boo c0 = c; pixel = bn; if(detectPeriod && detectPeriodAlgorithm == 0) { - r0 = new BigNum(size); - r = iterations == 0 ? new BigNum((BigNum) r0) : referenceData.lastRValue; + r0 = BigNum.create(size); + r = iterations == 0 ? BigNum.copy((BigNum) r0) : referenceData.lastRValue; } } else if(bigNumLib == BIGNUM_BIGINT) { @@ -1113,10 +1108,23 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { normSquared = z.normSquared(); refPoint = inputPixel; - refPointSmall = refPoint.toComplex(); if(deepZoom) { refPointSmallDeep = loc.getMantExpComplex(refPoint); + refPointSmall = refPointSmallDeep.toComplex(); + if(isJulia) { + seedSmallDeep = loc.getMantExpComplex(c); + } + + if(lowPrecReferenceOrbitNeeded && isJulia) { + seedSmall = seedSmallDeep.toComplex(); + } + } + else { + refPointSmall = refPoint.toComplex(); + if(lowPrecReferenceOrbitNeeded && isJulia) { + seedSmall = c.toComplex(); + } } RefType = getRefType(); @@ -1138,6 +1146,7 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { MantExp mradius = null; double radius = 0; + MantExp temp; if(detectPeriod && DetectedPeriod == 0 && detectPeriodAlgorithm == 1) { if (iterations == 0) { @@ -1162,23 +1171,55 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { } } - Complex cz = null; - MantExpComplex mcz = null; - Complex period_dzdc = null; MantExpComplex period_mdzdc = null; calculatedReferenceIterations = 0; - for (; iterations < max_ref_iterations; iterations++, calculatedReferenceIterations++) { + boolean combineReductionWithFunction = !preCalcNormData && (bigNumLib == Constants.BIGNUM_MPIR || bigNumLib == Constants.BIGNUM_MPFR); + boolean notCombineReductionWithFunction = !combineReductionWithFunction; + + Complex cz = combineReductionWithFunction && lowPrecReferenceOrbitNeeded ? new Complex() : null; + MantExpComplex mcz = combineReductionWithFunction && deepZoom ? MantExpComplex.create() : null; + if(combineReductionWithFunction && deepZoom) { + mcz = loc.getMantExpComplex(z); + } + + if(combineReductionWithFunction && lowPrecReferenceOrbitNeeded && !deepZoom) { + cz = z.toComplex(); + } + + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[referenceDeep.id] = new ReferenceCompressor(this, iterations == 0 ? z.toMantExpComplex() : referenceData.compressorZm, c.toMantExpComplex(), start.toMantExpComplex()); + } if(lowPrecReferenceOrbitNeeded) { - cz = z.toComplex(); + referenceCompressor[reference.id] = new ReferenceCompressor(this, iterations == 0 ? z.toComplex() : referenceData.compressorZ, c.toComplex(), start.toComplex()); + } + } - if (cz.isInfinite()) { - break; + MantExpComplex tempmcz = null; + + for (; iterations < max_ref_iterations; iterations++, calculatedReferenceIterations++) { + + if(deepZoom) { + if(notCombineReductionWithFunction) { + mcz = loc.getMantExpComplex(z); } - setArrayValue(reference, iterations, cz); + + tempmcz = setArrayDeepValue(referenceDeep, iterations, mcz); + } + + if(lowPrecReferenceOrbitNeeded) { + if(notCombineReductionWithFunction) { + cz = deepZoom ? mcz.toComplex() : z.toComplex(); + } + else if(deepZoom) { + cz = mcz.toComplex(); + } + + cz = setArrayValue(reference, iterations, cz); if(gatherTinyRefPts) { if (burning_ship) { @@ -1193,10 +1234,7 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { } } - if(deepZoom) { - mcz = loc.getMantExpComplex(z); - setArrayDeepValue(referenceDeep, iterations, mcz); - } + mcz = tempmcz; if(stopReferenceCalculationOnDetectedPeriod && DetectedPeriod != 0) { break; @@ -1272,12 +1310,13 @@ else if (bigNumLib == Constants.BIGNUM_DOUBLEDOUBLE) { else { if (DetectedPeriod == 0 && iterations > 0) { if (deepZoom) { - if (mradius.multiply(mdzdc.chebychevNorm()).compareToBothPositive(mcz.chebychevNorm()) > 0) { + temp = mdzdc.times(mradius).chebyshevNorm(); + if (temp.compareToBothPositiveReduced(mcz.chebyshevNorm()) > 0) { DetectedPeriod = iterations; period_mdzdc = MantExpComplex.copy(mdzdc); } } else { - if (radius * dzdc.chebychevNorm() > cz.chebychevNorm()) { + if (radius * dzdc.chebyshevNorm() > cz.chebyshevNorm()) { DetectedPeriod = iterations; period_dzdc = new Complex(dzdc); } @@ -1320,18 +1359,18 @@ else if (bigNumLib == Constants.BIGNUM_DOUBLEDOUBLE) { else { if(isMpfrComplex) { if (burning_ship) { - z = z.abs_mutable().square_plus_c_mutable(c, workSpaceData.temp1, workSpaceData.temp2); + z = z.abs_mutable().square_plus_c_mutable_with_reduction(c, workSpaceData.temp1, workSpaceData.temp2, deepZoom, cz, mcz); } else { - z = z.square_plus_c_mutable(c, workSpaceData.temp1, workSpaceData.temp2); + z = z.square_plus_c_mutable_with_reduction(c, workSpaceData.temp1, workSpaceData.temp2, deepZoom, cz, mcz); } } else if(isMpirComplex) { if (burning_ship) { - z = z.abs_mutable().square_plus_c_mutable(c, workSpaceData.temp1p, workSpaceData.temp2p, workSpaceData.temp3p); + z = z.abs_mutable().square_plus_c_mutable_with_reduction(c, workSpaceData.temp1p, workSpaceData.temp2p, workSpaceData.temp3p, deepZoom, cz, mcz); } else { - z = z.square_plus_c_mutable(c, workSpaceData.temp1p, workSpaceData.temp2p, workSpaceData.temp3p); + z = z.square_plus_c_mutable_with_reduction(c, workSpaceData.temp1p, workSpaceData.temp2p, workSpaceData.temp3p, deepZoom, cz, mcz); } } else { @@ -1366,6 +1405,18 @@ else if(isMpirComplex) { referenceData.MaxRefIteration = iterations - 1; + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[referenceDeep.id].compact(referenceDeep); + referenceData.compressorZm = referenceCompressor[referenceDeep.id].getZDeep(); + } + + if(lowPrecReferenceOrbitNeeded) { + referenceCompressor[reference.id].compact(reference); + referenceData.compressorZ = referenceCompressor[reference.id].getZ(); + } + } + if(progress != null) { progress.setValue(progress.getMaximum()); progress.setString(REFERENCE_CALCULATION_STR + " 100%"); @@ -1397,7 +1448,6 @@ else if(isBLA2InUse) { calculateBLA2Wrapper(deepZoom, externalLocation, progress); } - if(gatherTinyRefPts) { tinyRefPtsArray = tinyRefPts.stream().mapToInt(i -> i).toArray(); } @@ -1527,7 +1577,7 @@ protected void calculateNanomb1(boolean deepZoom, JProgressBar progress) { fp.cstep(getArrayDeepValue(referenceDeep, iteration)); } else { - fp.cstep(MantExpComplex.create(getArrayValue(reference, iteration))); + fp.cstep(getArrayValue(reference, iteration).toMantExpComplex()); } if(progress != null && total % 50 == 0) { @@ -1555,12 +1605,33 @@ protected void calculateNanomb1(boolean deepZoom, JProgressBar progress) { int max_ref_iterations = getReferenceMaxIterations(); - DoubleReference.SHOULD_SAVE_MEMORY = false; + DoubleReference ref1; - DoubleReference ref1 = new DoubleReference(max_ref_iterations_period, max_ref_iterations); + ReferenceCompressor referenceCompressor = null; + ReferenceCompressor referenceCompressorDeep = null; + ReferenceDecompressor referenceDecompressor = null; + ReferenceDecompressor referenceDecompressorDeep = null; - if (deepZoom) { - ref1Deep = new DeepReference(max_ref_iterations_period, max_ref_iterations); + if(TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE) { + Complex initVal = defaultInitVal.getValue(null); + ref1 = new CompressedDoubleReference(max_ref_iterations_period, max_ref_iterations); + referenceCompressor = new ReferenceCompressor(this, new Complex(initVal), new Complex(refPointSmall), new Complex(initVal)); + referenceDecompressor = new ReferenceDecompressor(this, new Complex(refPointSmall), new Complex(initVal)); + + if (deepZoom) { + ref1Deep = new CompressedDeepReference(max_ref_iterations_period, max_ref_iterations); + referenceCompressorDeep = new ReferenceCompressor(this, MantExpComplex.create(initVal), MantExpComplex.copy(refPointSmallDeep), MantExpComplex.create(initVal)); + referenceDecompressorDeep = new ReferenceDecompressor(this, MantExpComplex.copy(refPointSmallDeep), MantExpComplex.create(initVal)); + } + } + else { + DoubleReference.SHOULD_SAVE_MEMORY = false; + + ref1 = new DoubleReference(max_ref_iterations_period, max_ref_iterations); + + if (deepZoom) { + ref1Deep = new DeepReference(max_ref_iterations_period, max_ref_iterations); + } } boolean gatherTinyRefPts = TaskDraw.PERTUBATION_PIXEL_ALGORITHM == 1 && supportsScaledIterations() && deepZoom && TaskDraw.GATHER_TINY_REF_INDEXES; @@ -1569,27 +1640,24 @@ protected void calculateNanomb1(boolean deepZoom, JProgressBar progress) { tinyRefPts.clear(); } - MantExpComplex workSpaceDeep = MantExpComplex.create(); - Complex workSpace = new Complex(); - MantExpComplex temp; for(int iteration = 0; iteration < max_ref_iterations_period; iteration++, total++){ if(deepZoom) { - zlo = getArrayDeepValue(referenceDeep, iteration, workSpaceDeep); + zlo = getArrayDeepValue(referenceDecompressorDeep, referenceDeep, iteration); temp = zlo.plus(zlo1); - setArrayDeepValue(ref1Deep, iteration, temp); + setArrayDeepValue(referenceCompressorDeep, ref1Deep, iteration, temp); Complex cz = temp.toComplex(); - setArrayValue(ref1, iteration, cz); + cz = setArrayValue(referenceCompressor, ref1, iteration, cz); if(gatherTinyRefPts && cz.hypot() < scaledE) {//burning_ship is not implemented for this tinyRefPts.add(iteration); } } else { - zlo = MantExpComplex.create(getArrayValue(reference, iteration, workSpace)); - setArrayValue(ref1, iteration, zlo.plus(zlo1).toComplex()); + zlo = MantExpComplex.create(getArrayValue(referenceDecompressor, reference, iteration)); + setArrayValue(referenceCompressor, ref1, iteration, zlo.plus(zlo1).toComplex()); } zlo1 = zlo1.times(zlo1.plus(zlo.times2())).plus_mutable(nucleusPos); @@ -1602,6 +1670,14 @@ protected void calculateNanomb1(boolean deepZoom, JProgressBar progress) { } } + if(TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE) { + if(deepZoom) { + referenceCompressorDeep.compact(ref1Deep); + } + + referenceCompressor.compact(ref1); + } + referenceData.setReference(ref1); if(deepZoom) { @@ -1979,7 +2055,7 @@ protected void calculateSeries(Apfloat dsize, boolean deepZoom, Location loc, JP SAskippedIterations = i <= skippedThreshold ? 0 : i - skippedThreshold; } - public static void calcCoeffs(int k, int old_i, int new_i, MantExpComplex twoRef, long[] magCoeff, long[] logwToThe) { + public void calcCoeffs(int k, int old_i, int new_i, MantExpComplex twoRef, long[] magCoeff, long[] logwToThe) { MantExpComplex sum = k == 0 ? MantExpComplex.create(1, 0) : MantExpComplex.create(); int calcLength = (k >> 1); @@ -2025,6 +2101,19 @@ public boolean supportsPerturbationTheory() { return !isJulia || !juliter; } + @Override + public boolean supportsReferenceCompression() { + return true; + } + + @Override + public boolean supportsExtendedReferenceCompression() { + if(isJuliaMap) { + return false; + } + return !burning_ship && !isJulia; + } + @Override public boolean supportsSeriesApproximation() { return !burning_ship && !isJulia; @@ -2220,6 +2309,18 @@ public Complex perturbationFunction(Complex DeltaSubN, ReferenceData data, int R } } + @Override + public Complex perturbationFunction(Complex DeltaSubN, DoubleReference ref, int RefIteration) { + //Not for burning ship + return getArrayValue(ref, RefIteration).times2_mutable().plus_mutable(DeltaSubN).times_mutable(DeltaSubN); + } + + @Override + public MantExpComplex perturbationFunction(MantExpComplex dz, DeepReference data, int RefIteration) { + //Not for burning ship + return getArrayDeepValue(data, RefIteration).times2_mutable().plus_mutable(dz).times_mutable(dz); + } + @Override public MantExpComplex perturbationFunction(MantExpComplex DeltaSubN, ReferenceDeepData data, int RefIteration) { if(not_burning_ship) { @@ -2324,24 +2425,33 @@ public static int firstOrderBallPeriod(Complex c0, double size, int n) { @Override public void createLowPrecisionOrbit(int length, ReferenceData refData, ReferenceDeepData refDeepData) { - DoubleReference.SHOULD_SAVE_MEMORY = false; - refData.createAndSetShortcut(length, false, 0); - DoubleReference reference = refData.Reference; - DeepReference deepReference = refDeepData.Reference; - MantExpComplex output = MantExpComplex.create(); - for (int i = 0; i < length; i++) { - Fractal.setArrayValue(reference, i, Fractal.getArrayDeepValue(deepReference, i, output).toComplex()); + if(refDeepData.Reference.compressed) { + refData.createAndSetShortcut(length, false, 0, true); + CompressedDoubleReference reference = (CompressedDoubleReference) refData.Reference; + CompressedDeepReference deepReference = (CompressedDeepReference) refDeepData.Reference; + ReferenceCompressor.createLowPrecisionOrbit(reference, deepReference); + reference.setLengthOverride(deepReference.length()); } + else { + DoubleReference.SHOULD_SAVE_MEMORY = false; + refData.createAndSetShortcut(length, false, 0, false); + DoubleReference reference = refData.Reference; + DeepReference deepReference = refDeepData.Reference; - reference.setLengthOverride(deepReference.length()); + for (int i = 0; i < length; i++) { + setArrayValue(reference, i, getArrayDeepValue(deepReference, i).toComplex()); + } + + reference.setLengthOverride(deepReference.length()); + } } @Override public double iterateFractalWithPerturbation(Complex[] complex, Complex dpixel) { - if(burning_ship) { - super.iterateFractalWithPerturbation(complex, dpixel); + if(TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE || burning_ship) { + return super.iterateFractalWithPerturbation(complex, dpixel); } double_iterations = 0; @@ -2461,6 +2571,10 @@ public double iterateFractalWithPerturbation(Complex[] complex, Complex dpixel) @Override public double iterateFractalWithPerturbationBLA(Complex[] complex, Complex dpixel) { + if(TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE) { + return super.iterateFractalWithPerturbationBLA(complex, dpixel); + } + bla_steps = 0; bla_iterations = 0; perturb_iterations = 0; @@ -2649,6 +2763,10 @@ public double iterateFractalWithPerturbationBLA(Complex[] complex, Complex dpixe @Override public double iterateFractalWithPerturbationBLA2(Complex[] complex, Complex dpixel) { + if(TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE) { + return super.iterateFractalWithPerturbationBLA2(complex, dpixel); + } + bla_steps = 0; bla_iterations = 0; perturb_iterations = 0; @@ -2714,7 +2832,7 @@ public double iterateFractalWithPerturbationBLA2(Complex[] complex, Complex dpix while(iterations < max_iterations) { - LAstep las = laReference.getLA(LAIndex, dre, dim, RefIteration, iterations, max_iterations); + LAstep las = laReference.getLA(this, LAIndex, dre, dim, RefIteration, iterations, max_iterations); if(las.unusable) { RefIteration = las.nextStageLAindex; @@ -2865,6 +2983,10 @@ private double PerturbationAfterBLA2(Complex[] complex, Complex pixel, double zr @Override public double iterateFractalWithPerturbationBLA2(Complex[] complex, MantExpComplex dpixel) { + if(TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE) { + return super.iterateFractalWithPerturbationBLA2(complex, dpixel); + } + bla_steps = 0; bla_iterations = 0; perturb_iterations = 0; @@ -2880,7 +3002,7 @@ public double iterateFractalWithPerturbationBLA2(Complex[] complex, MantExpCompl precalculatePerturbationData(DeltaSub0); - MantExp DeltaSub0ChebyshevNorm = DeltaSub0.chebychevNorm(); + MantExp DeltaSub0ChebyshevNorm = DeltaSub0.chebyshevNorm(); iterations = BLA2SkippedIterations; bla_iterations = BLA2SkippedIterations; @@ -2932,7 +3054,7 @@ public double iterateFractalWithPerturbationBLA2(Complex[] complex, MantExpCompl while(iterations < max_iterations) { - LAstep las = laReference.getLA(LAIndex, DeltaSubN, RefIteration, iterations, max_iterations); + LAstep las = laReference.getLA(this, LAIndex, DeltaSubN, RefIteration, iterations, max_iterations); if(las.unusable) { RefIteration = las.nextStageLAindex; @@ -2975,7 +3097,7 @@ public double iterateFractalWithPerturbationBLA2(Complex[] complex, MantExpCompl // rebase - if(z.chebychevNorm().compareToBothPositiveReduced(DeltaSubN.chebychevNorm()) < 0|| RefIteration >= MacroItCount) { + if(z.chebyshevNorm().compareToBothPositiveReduced(DeltaSubN.chebyshevNorm()) < 0|| RefIteration >= MacroItCount) { DeltaSubN = z; RefIteration = 0; rebases++; @@ -3088,7 +3210,7 @@ public double iterateFractalWithPerturbationBLA2(Complex[] complex, MantExpCompl while(iterations < max_iterations) { - LAstep las = laReference.getLA(LAIndex, dre, dim, RefIteration, iterations, max_iterations); + LAstep las = laReference.getLA(this, LAIndex, dre, dim, RefIteration, iterations, max_iterations); if(las.unusable) { RefIteration = las.nextStageLAindex; @@ -3167,8 +3289,8 @@ public double iterateFractalWithPerturbationBLA2(Complex[] complex, MantExpCompl @Override protected double PerturbationAfterExtendedRange(Complex[] complex, Complex pixel, MantExpComplex DeltaSubN, MantExpComplex DeltaSub0, int RefIteration, int MaxRefIteration, int ReferencePeriod, boolean usedDeepCode) { - if(burning_ship) { - super.PerturbationAfterExtendedRange(complex, pixel, DeltaSubN, DeltaSub0, RefIteration, MaxRefIteration, ReferencePeriod, usedDeepCode); + if(TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE || burning_ship) { + return super.PerturbationAfterExtendedRange(complex, pixel, DeltaSubN, DeltaSub0, RefIteration, MaxRefIteration, ReferencePeriod, usedDeepCode); } Complex CDeltaSubN = DeltaSubN.toComplex(); @@ -3278,8 +3400,8 @@ protected double PerturbationAfterExtendedRange(Complex[] complex, Complex pixel @Override public double iterateJuliaWithPerturbation(Complex[] complex, Complex dpixel) { - if(burning_ship) { - super.iterateJuliaWithPerturbation(complex, dpixel); + if(TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE || burning_ship) { + return super.iterateJuliaWithPerturbation(complex, dpixel); } double_iterations = 0; @@ -3384,8 +3506,8 @@ public double iterateJuliaWithPerturbation(Complex[] complex, Complex dpixel) { @Override public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpixel) { - if(burning_ship) { - super.iterateJuliaWithPerturbation(complex, dpixel); + if(TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE || burning_ship) { + return super.iterateJuliaWithPerturbation(complex, dpixel); } float_exp_iterations = 0; @@ -3408,7 +3530,7 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi int MaxRefIteration = data.MaxRefIteration; int minExp = -1000; - int reducedExp = minExp / (int)power; + int reducedExp = minExp / (int)getPower(); DeltaSubN.Normalize(); long exp = DeltaSubN.getMinExp(); @@ -3418,6 +3540,8 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi if(useFullFloatExp || (totalSkippedIterations == 0 && exp <= minExp) || (totalSkippedIterations != 0 && exp <= reducedExp)) { MantExpComplex z = getArrayDeepValue(deepData.Reference, RefIteration).plus_mutable(DeltaSubN); + MantExpComplex zoldDeep; + for (; iterations < max_iterations; iterations++) { if (trap != null) { trap.check(complex[0], iterations); @@ -3445,6 +3569,7 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi zold2.assign(zold); zold.assign(complex[0]); + zoldDeep = z; if (max_iterations > 1) { z = getArrayDeepValue(deepData.Reference, RefIteration).plus_mutable(DeltaSubN); @@ -3452,7 +3577,7 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi } if (statistic != null) { - statistic.insert(complex[0], zold, zold2, iterations, complex[1], start, c0); + statistic.insert(complex[0], zold, zold2, iterations, complex[1], start, c0, z, zoldDeep , null); } if (z.norm_squared().compareToBothPositive(DeltaSubN.norm_squared()) < 0 || RefIteration >= MaxRefIteration) { @@ -3568,8 +3693,8 @@ public double iterateJuliaWithPerturbation(Complex[] complex, MantExpComplex dpi @Override public double iterateFractalWithPerturbationScaled(Complex[] complex, MantExpComplex dpixel) { - if(burning_ship) { - super.iterateFractalWithPerturbationScaled(complex, dpixel); + if(TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE || burning_ship) { + return super.iterateFractalWithPerturbationScaled(complex, dpixel); } float_exp_iterations = 0; @@ -3578,6 +3703,7 @@ public double iterateFractalWithPerturbationScaled(Complex[] complex, MantExpCom rebases = 0; realigns = 0; + double power = getPower(); double reAlignThreshold = power == 2 ? 1e100 : Math.exp(Math.log(1e200) / power); MantExpComplex[] deltas = initializePerturbation(dpixel); @@ -3596,7 +3722,7 @@ public double iterateFractalWithPerturbationScaled(Complex[] complex, MantExpCom int MaxRefIteration = getReferenceFinalIterationNumber(true, referenceData); int minExp = -1000; - int reducedExp = minExp / (int) power; + int reducedExp = minExp / (int) getPower(); DeltaSubN.Normalize(); long exp = DeltaSubN.getMinExp(); @@ -3970,4 +4096,29 @@ public double iterateFractalWithPerturbationScaled(Complex[] complex, MantExpCom return getAndAccumulateStatsScaled(in); } + + @Override + public Complex function(Complex z, Complex c) { + if(not_burning_ship) { + return z.square_mutable_plus_c_mutable(c); + } + else { + return z.abs_mutable().square_mutable_plus_c_mutable(c); + } + } + + @Override + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + if(not_burning_ship) { + return z.square_mutable().plus_mutable(c); + } + else { + return z.abs_mutable().square_mutable().plus_mutable(c); + } + } + + @Override + public double getPower() { + return 2; + } } diff --git a/src/fractalzoomer/functions/mandelbrot/MandelbrotCubed.java b/src/fractalzoomer/functions/mandelbrot/MandelbrotCubed.java index 25f522e85..f1d85d415 100644 --- a/src/fractalzoomer/functions/mandelbrot/MandelbrotCubed.java +++ b/src/fractalzoomer/functions/mandelbrot/MandelbrotCubed.java @@ -67,8 +67,6 @@ public MandelbrotCubed(double xCenter, double yCenter, double size, int max_iter this.burning_ship = burning_ship; not_burning_ship = !burning_ship; - power = 3; - if(burning_ship) { type = new BurningShip(); } @@ -118,8 +116,6 @@ public MandelbrotCubed(double xCenter, double yCenter, double size, int max_iter this.burning_ship = burning_ship; not_burning_ship = !burning_ship; - power = 3; - if(burning_ship) { type = new BurningShip(); } @@ -154,8 +150,6 @@ public MandelbrotCubed(double xCenter, double yCenter, double size, int max_iter this.burning_ship = burning_ship; not_burning_ship = !burning_ship; - power = 3; - if(burning_ship) { type = new BurningShip(); } @@ -198,8 +192,6 @@ public MandelbrotCubed(double xCenter, double yCenter, double size, int max_iter this.burning_ship = burning_ship; not_burning_ship = !burning_ship; - power = 3; - if(burning_ship) { type = new BurningShip(); } @@ -242,6 +234,8 @@ public boolean shouldRecalculateForPeriodDetection(boolean deepZoom, Location ex return true; } + initializeReferenceDecompressor(); + if (deepZoom) { if(referenceData.period_mdzdc == null) { return true; @@ -249,8 +243,9 @@ public boolean shouldRecalculateForPeriodDetection(boolean deepZoom, Location ex MantExpComplex mdzdc = referenceData.period_mdzdc; MantExp mradius = externalLocation.getSize().multiply2_mutable(); + MantExp temp = mdzdc.times(mradius).chebyshevNorm(); - if (mradius.multiply(mdzdc.chebychevNorm()).compareToBothPositive(getArrayDeepValue(referenceDeep, DetectedPeriod).chebychevNorm()) > 0) { + if (temp.compareToBothPositiveReduced(getArrayDeepValue(referenceDeep, DetectedPeriod).chebyshevNorm()) > 0) { return false; } } else { @@ -261,7 +256,7 @@ public boolean shouldRecalculateForPeriodDetection(boolean deepZoom, Location ex Complex dzdc = referenceData.period_dzdc; double radius = this.size * 2; - if (radius * dzdc.chebychevNorm() > getArrayValue(reference, DetectedPeriod).chebychevNorm()) { + if (radius * dzdc.chebyshevNorm() > getArrayValue(reference, DetectedPeriod).chebyshevNorm()) { return false; } } @@ -294,17 +289,18 @@ public void calculateReferencePoint(GenericComplex inputPixel, Apfloat size, boo boolean stopReferenceCalculationOnDetectedPeriod = detectPeriod && TaskDraw.STOP_REFERENCE_CALCULATION_AFTER_DETECTED_PERIOD && userPeriod == 0 && canStopOnDetectedPeriod(); DoubleReference.SHOULD_SAVE_MEMORY = stopReferenceCalculationOnDetectedPeriod; + boolean useCompressedRef = TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE && supportsReferenceCompression(); if (iterations == 0) { if(lowPrecReferenceOrbitNeeded) { - referenceData.createAndSetShortcut(max_ref_iterations, false, 0); + referenceData.createAndSetShortcut(max_ref_iterations, false, 0, useCompressedRef); } else { referenceData.deallocate(); } if (deepZoom) { - referenceDeepData.createAndSetShortcut(max_ref_iterations, false, 0); + referenceDeepData.createAndSetShortcut(max_ref_iterations, false, 0, useCompressedRef); } } else if (max_ref_iterations > getReferenceLength()) { if(lowPrecReferenceOrbitNeeded) { @@ -341,8 +337,8 @@ public void calculateReferencePoint(GenericComplex inputPixel, Apfloat size, boo pixel = bn; if(detectPeriod && detectPeriodAlgorithm == 0) { //referenceData.minValue = iterations == 0 ? BigNum.getMax() : referenceData.minValue; - r0 = new BigNum(size); - r = iterations == 0 ? new BigNum((BigNum) r0) : referenceData.lastRValue; + r0 = BigNum.create(size); + r = iterations == 0 ? BigNum.copy((BigNum) r0) : referenceData.lastRValue; } } else if(bigNumLib == BIGNUM_BIGINT) { @@ -439,10 +435,23 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { Location loc = new Location(); refPoint = inputPixel; - refPointSmall = refPoint.toComplex(); if(deepZoom) { refPointSmallDeep = loc.getMantExpComplex(refPoint); + refPointSmall = refPointSmallDeep.toComplex(); + if(isJulia) { + seedSmallDeep = loc.getMantExpComplex(c); + } + + if(lowPrecReferenceOrbitNeeded && isJulia) { + seedSmall = seedSmallDeep.toComplex(); + } + } + else { + refPointSmall = refPoint.toComplex(); + if(lowPrecReferenceOrbitNeeded && isJulia) { + seedSmall = c.toComplex(); + } } boolean isSeriesInUse = TaskDraw.APPROXIMATION_ALGORITHM == 1 && supportsSeriesApproximation(); @@ -491,26 +500,36 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { Complex cz = null; MantExpComplex mcz = null; + MantExp temp; - calculatedReferenceIterations = 0; + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[referenceDeep.id] = new ReferenceCompressor(this, iterations == 0 ? z.toMantExpComplex() : referenceData.compressorZm, c.toMantExpComplex(), start.toMantExpComplex()); + } + if(lowPrecReferenceOrbitNeeded) { + referenceCompressor[reference.id] = new ReferenceCompressor(this, iterations == 0 ? z.toComplex() : referenceData.compressorZ, c.toComplex(), start.toComplex()); + } + } - for (; iterations < max_ref_iterations; iterations++, calculatedReferenceIterations++) { + calculatedReferenceIterations = 0; - if(lowPrecReferenceOrbitNeeded) { - cz = z.toComplex(); - if (cz.isInfinite()) { - break; - } + MantExpComplex tempmcz = null; - setArrayValue(reference, iterations, cz); - } + for (; iterations < max_ref_iterations; iterations++, calculatedReferenceIterations++) { if(deepZoom) { mcz = loc.getMantExpComplex(z); - setArrayDeepValue(referenceDeep, iterations, mcz); + tempmcz = setArrayDeepValue(referenceDeep, iterations, mcz); //ReferenceDeep[iterations] = new MantExpComplex(Reference[iterations]); } + if(lowPrecReferenceOrbitNeeded) { + cz = deepZoom ? mcz.toComplex() : z.toComplex(); + cz = setArrayValue(reference, iterations, cz); + } + + mcz = tempmcz; + if(stopReferenceCalculationOnDetectedPeriod && DetectedPeriod != 0) { break; } @@ -586,12 +605,13 @@ else if (bigNumLib == Constants.BIGNUM_DOUBLEDOUBLE) { else { if (DetectedPeriod == 0 && iterations > 0) { if (deepZoom) { - if (mradius.multiply(mdzdc.chebychevNorm()).compareToBothPositive(mcz.chebychevNorm()) > 0) { + temp = mdzdc.times(mradius).chebyshevNorm(); + if (temp.compareToBothPositiveReduced(mcz.chebyshevNorm()) > 0) { DetectedPeriod = iterations; period_mdzdc = MantExpComplex.copy(mdzdc); } } else { - if (radius * dzdc.chebychevNorm() > cz.chebychevNorm()) { + if (radius * dzdc.chebyshevNorm() > cz.chebyshevNorm()) { DetectedPeriod = iterations; period_dzdc = new Complex(dzdc); } @@ -680,6 +700,18 @@ else if(isMpirComplex) { referenceData.MaxRefIteration = iterations - 1; + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[referenceDeep.id].compact(referenceDeep); + referenceData.compressorZm = referenceCompressor[referenceDeep.id].getZDeep(); + } + + if(lowPrecReferenceOrbitNeeded) { + referenceCompressor[reference.id].compact(reference); + referenceData.compressorZ = referenceCompressor[reference.id].getZ(); + } + } + if(progress != null) { progress.setValue(progress.getMaximum()); progress.setString(REFERENCE_CALCULATION_STR + " 100%"); @@ -1278,4 +1310,34 @@ public boolean supportsPeriod() { @Override public boolean supportsMpirBignum() { return true;} + @Override + public boolean supportsReferenceCompression() { + return true; + } + + @Override + public Complex function(Complex z, Complex c) { + if(not_burning_ship) { + return z.cube_mutable().plus_mutable(c); + } + else { + return z.abs_mutable().cube_mutable().plus_mutable(c); + } + } + + @Override + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + if(not_burning_ship) { + return z.cube_mutable().plus_mutable(c); + } + else { + return z.abs_mutable().cube_mutable().plus_mutable(c); + } + } + + @Override + public double getPower() { + return 3; + } + } diff --git a/src/fractalzoomer/functions/mandelbrot/MandelbrotEighth.java b/src/fractalzoomer/functions/mandelbrot/MandelbrotEighth.java index a893dc924..7116488b3 100644 --- a/src/fractalzoomer/functions/mandelbrot/MandelbrotEighth.java +++ b/src/fractalzoomer/functions/mandelbrot/MandelbrotEighth.java @@ -45,8 +45,6 @@ public MandelbrotEighth(double xCenter, double yCenter, double size, int max_ite super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - power = 8; - if(burning_ship) { type = new BurningShip(); } @@ -93,8 +91,6 @@ public MandelbrotEighth(double xCenter, double yCenter, double size, int max_ite super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, xJuliaCenter, yJuliaCenter); - power = 8; - if(burning_ship) { type = new BurningShip(); } @@ -126,8 +122,6 @@ public MandelbrotEighth(double xCenter, double yCenter, double size, int max_ite super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower); - power = 8; - if(burning_ship) { type = new BurningShip(); } @@ -167,8 +161,6 @@ public MandelbrotEighth(double xCenter, double yCenter, double size, int max_ite super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); - power = 8; - if(burning_ship) { type = new BurningShip(); } @@ -196,4 +188,9 @@ public void function(Complex[] complex) { type2.getValue(complex[0]); } + + @Override + public double getPower() { + return 8; + } } diff --git a/src/fractalzoomer/functions/mandelbrot/MandelbrotFifth.java b/src/fractalzoomer/functions/mandelbrot/MandelbrotFifth.java index 30c035f05..0680de38a 100644 --- a/src/fractalzoomer/functions/mandelbrot/MandelbrotFifth.java +++ b/src/fractalzoomer/functions/mandelbrot/MandelbrotFifth.java @@ -67,8 +67,6 @@ public MandelbrotFifth(double xCenter, double yCenter, double size, int max_iter this.burning_ship = burning_ship; not_burning_ship = !burning_ship; - power = 5; - if(burning_ship) { type = new BurningShip(); } @@ -118,8 +116,6 @@ public MandelbrotFifth(double xCenter, double yCenter, double size, int max_iter this.burning_ship = burning_ship; not_burning_ship = !burning_ship; - power = 5; - if(burning_ship) { type = new BurningShip(); } @@ -154,8 +150,6 @@ public MandelbrotFifth(double xCenter, double yCenter, double size, int max_iter this.burning_ship = burning_ship; not_burning_ship = !burning_ship; - power = 5; - if(burning_ship) { type = new BurningShip(); } @@ -198,8 +192,6 @@ public MandelbrotFifth(double xCenter, double yCenter, double size, int max_iter this.burning_ship = burning_ship; not_burning_ship = !burning_ship; - power = 5; - if(burning_ship) { type = new BurningShip(); } @@ -242,6 +234,8 @@ public boolean shouldRecalculateForPeriodDetection(boolean deepZoom, Location ex return true; } + initializeReferenceDecompressor(); + if (deepZoom) { if(referenceData.period_mdzdc == null) { return true; @@ -249,8 +243,9 @@ public boolean shouldRecalculateForPeriodDetection(boolean deepZoom, Location ex MantExpComplex mdzdc = referenceData.period_mdzdc; MantExp mradius = externalLocation.getSize().multiply2_mutable(); + MantExp temp = mdzdc.times(mradius).chebyshevNorm(); - if (mradius.multiply(mdzdc.chebychevNorm()).compareToBothPositive(getArrayDeepValue(referenceDeep, DetectedPeriod).chebychevNorm()) > 0) { + if (temp.compareToBothPositiveReduced(getArrayDeepValue(referenceDeep, DetectedPeriod).chebyshevNorm()) > 0) { return false; } } else { @@ -261,7 +256,7 @@ public boolean shouldRecalculateForPeriodDetection(boolean deepZoom, Location ex Complex dzdc = referenceData.period_dzdc; double radius = this.size * 2; - if (radius * dzdc.chebychevNorm() > getArrayValue(reference, DetectedPeriod).chebychevNorm()) { + if (radius * dzdc.chebyshevNorm() > getArrayValue(reference, DetectedPeriod).chebyshevNorm()) { return false; } } @@ -294,17 +289,18 @@ public void calculateReferencePoint(GenericComplex inputPixel, Apfloat size, boo boolean stopReferenceCalculationOnDetectedPeriod = detectPeriod && TaskDraw.STOP_REFERENCE_CALCULATION_AFTER_DETECTED_PERIOD && userPeriod == 0 && canStopOnDetectedPeriod(); DoubleReference.SHOULD_SAVE_MEMORY = stopReferenceCalculationOnDetectedPeriod; + boolean useCompressedRef = TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE && supportsReferenceCompression(); if (iterations == 0) { if(lowPrecReferenceOrbitNeeded) { - referenceData.createAndSetShortcut(max_ref_iterations,false, 0); + referenceData.createAndSetShortcut(max_ref_iterations,false, 0, useCompressedRef); } else { referenceData.deallocate(); } if (deepZoom) { - referenceDeepData.createAndSetShortcut(max_ref_iterations,false, 0); + referenceDeepData.createAndSetShortcut(max_ref_iterations,false, 0, useCompressedRef); } } else if (max_ref_iterations > getReferenceLength()) { if(lowPrecReferenceOrbitNeeded) { @@ -341,8 +337,8 @@ public void calculateReferencePoint(GenericComplex inputPixel, Apfloat size, boo pixel = bn; if(detectPeriod && detectPeriodAlgorithm == 0) { // referenceData.minValue = iterations == 0 ? BigNum.getMax() : referenceData.minValue; - r0 = new BigNum(size); - r = iterations == 0 ? new BigNum((BigNum) r0) : referenceData.lastRValue; + r0 = BigNum.create(size); + r = iterations == 0 ? BigNum.copy((BigNum) r0) : referenceData.lastRValue; } } else if(bigNumLib == BIGNUM_BIGINT) { @@ -440,10 +436,23 @@ else if(bigNumLib == BIGNUM_DOUBLE) { Location loc = new Location(); refPoint = inputPixel; - refPointSmall = refPoint.toComplex(); if(deepZoom) { refPointSmallDeep = loc.getMantExpComplex(refPoint); + refPointSmall = refPointSmallDeep.toComplex(); + if(isJulia) { + seedSmallDeep = loc.getMantExpComplex(c); + } + + if(lowPrecReferenceOrbitNeeded && isJulia) { + seedSmall = seedSmallDeep.toComplex(); + } + } + else { + refPointSmall = refPoint.toComplex(); + if(lowPrecReferenceOrbitNeeded && isJulia) { + seedSmall = c.toComplex(); + } } boolean isSeriesInUse = TaskDraw.APPROXIMATION_ALGORITHM == 1 && supportsSeriesApproximation(); @@ -456,6 +465,7 @@ else if(bigNumLib == BIGNUM_DOUBLE) { Complex dzdc = null; MantExpComplex mdzdc = null; + MantExp temp; MantExp mradius = null; double radius = 0; @@ -489,25 +499,34 @@ else if(bigNumLib == BIGNUM_DOUBLE) { Complex cz = null; MantExpComplex mcz = null; - calculatedReferenceIterations = 0; + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[referenceDeep.id] = new ReferenceCompressor(this, iterations == 0 ? z.toMantExpComplex() : referenceData.compressorZm, c.toMantExpComplex(), start.toMantExpComplex()); + } + if(lowPrecReferenceOrbitNeeded) { + referenceCompressor[reference.id] = new ReferenceCompressor(this, iterations == 0 ? z.toComplex() : referenceData.compressorZ, c.toComplex(), start.toComplex()); + } + } - for (; iterations < max_ref_iterations; iterations++, calculatedReferenceIterations++) { + calculatedReferenceIterations = 0; - if(lowPrecReferenceOrbitNeeded) { - cz = z.toComplex(); - if (cz.isInfinite()) { - break; - } + MantExpComplex tempmcz = null; - setArrayValue(reference, iterations, cz); - } + for (; iterations < max_ref_iterations; iterations++, calculatedReferenceIterations++) { if(deepZoom) { mcz = loc.getMantExpComplex(z); - setArrayDeepValue(referenceDeep, iterations, mcz); + tempmcz = setArrayDeepValue(referenceDeep, iterations, mcz); //ReferenceDeep[iterations] = new MantExpComplex(Reference[iterations]); } + if(lowPrecReferenceOrbitNeeded) { + cz = deepZoom ? mcz.toComplex() : z.toComplex(); + cz = setArrayValue(reference, iterations, cz); + } + + mcz = tempmcz; + if(stopReferenceCalculationOnDetectedPeriod && DetectedPeriod != 0) { break; } @@ -583,12 +602,13 @@ else if (bigNumLib == Constants.BIGNUM_DOUBLEDOUBLE) { else { if (DetectedPeriod == 0 && iterations > 0) { if (deepZoom) { - if (mradius.multiply(mdzdc.chebychevNorm()).compareToBothPositive(mcz.chebychevNorm()) > 0) { + temp = mdzdc.times(mradius).chebyshevNorm(); + if (temp.compareToBothPositiveReduced(mcz.chebyshevNorm()) > 0) { DetectedPeriod = iterations; period_mdzdc = MantExpComplex.copy(mdzdc); } } else { - if (radius * dzdc.chebychevNorm() > cz.chebychevNorm()) { + if (radius * dzdc.chebyshevNorm() > cz.chebyshevNorm()) { DetectedPeriod = iterations; period_dzdc = new Complex(dzdc); } @@ -660,6 +680,18 @@ else if (bigNumLib == Constants.BIGNUM_DOUBLEDOUBLE) { referenceData.MaxRefIteration = iterations - 1; + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[referenceDeep.id].compact(referenceDeep); + referenceData.compressorZm = referenceCompressor[referenceDeep.id].getZDeep(); + } + + if(lowPrecReferenceOrbitNeeded) { + referenceCompressor[reference.id].compact(reference); + referenceData.compressorZ = referenceCompressor[reference.id].getZ(); + } + } + if(progress != null) { progress.setValue(progress.getMaximum()); progress.setString(REFERENCE_CALCULATION_STR + " 100%"); @@ -903,7 +935,7 @@ public MantExpComplex perturbationFunction(MantExpComplex DeltaSubN, MantExpComp .add_mutable(b2b2) )); - return MantExpComplex.create().plus_mutable(DeltaSub0); + return MantExpComplex.create(Dnr, Dni).plus_mutable(DeltaSub0); } } @@ -1387,4 +1419,34 @@ public boolean supportsPeriod() { @Override public boolean supportsMpirBignum() { return true;} + + @Override + public boolean supportsReferenceCompression() { + return true; + } + + @Override + public Complex function(Complex z, Complex c) { + if(not_burning_ship) { + return z.fifth_mutable().plus_mutable(c); + } + else { + return z.abs_mutable().fifth_mutable().plus_mutable(c); + } + } + + @Override + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + if(not_burning_ship) { + return z.fifth_mutable().plus_mutable(c); + } + else { + return z.abs_mutable().fifth_mutable().plus_mutable(c); + } + } + + @Override + public double getPower() { + return 5; + } } diff --git a/src/fractalzoomer/functions/mandelbrot/MandelbrotFourth.java b/src/fractalzoomer/functions/mandelbrot/MandelbrotFourth.java index 4dd33dcb6..e81344f5c 100644 --- a/src/fractalzoomer/functions/mandelbrot/MandelbrotFourth.java +++ b/src/fractalzoomer/functions/mandelbrot/MandelbrotFourth.java @@ -67,8 +67,6 @@ public MandelbrotFourth(double xCenter, double yCenter, double size, int max_ite this.burning_ship = burning_ship; not_burning_ship = !burning_ship; - power = 4; - if(burning_ship) { type = new BurningShip(); } @@ -118,8 +116,6 @@ public MandelbrotFourth(double xCenter, double yCenter, double size, int max_ite this.burning_ship = burning_ship; not_burning_ship = !burning_ship; - power = 4; - if(burning_ship) { type = new BurningShip(); } @@ -154,8 +150,6 @@ public MandelbrotFourth(double xCenter, double yCenter, double size, int max_ite this.burning_ship = burning_ship; not_burning_ship = !burning_ship; - power = 4; - if(burning_ship) { type = new BurningShip(); } @@ -198,8 +192,6 @@ public MandelbrotFourth(double xCenter, double yCenter, double size, int max_ite this.burning_ship = burning_ship; not_burning_ship = !burning_ship; - power = 4; - if(burning_ship) { type = new BurningShip(); } @@ -242,6 +234,8 @@ public boolean shouldRecalculateForPeriodDetection(boolean deepZoom, Location ex return true; } + initializeReferenceDecompressor(); + if (deepZoom) { if(referenceData.period_mdzdc == null) { return true; @@ -249,8 +243,9 @@ public boolean shouldRecalculateForPeriodDetection(boolean deepZoom, Location ex MantExpComplex mdzdc = referenceData.period_mdzdc; MantExp mradius = externalLocation.getSize().multiply2_mutable(); + MantExp temp = mdzdc.times(mradius).chebyshevNorm(); - if (mradius.multiply(mdzdc.chebychevNorm()).compareToBothPositive(getArrayDeepValue(referenceDeep, DetectedPeriod).chebychevNorm()) > 0) { + if (temp.compareToBothPositiveReduced(getArrayDeepValue(referenceDeep, DetectedPeriod).chebyshevNorm()) > 0) { return false; } } else { @@ -261,7 +256,7 @@ public boolean shouldRecalculateForPeriodDetection(boolean deepZoom, Location ex Complex dzdc = referenceData.period_dzdc; double radius = this.size * 2; - if (radius * dzdc.chebychevNorm() > getArrayValue(reference, DetectedPeriod).chebychevNorm()) { + if (radius * dzdc.chebyshevNorm() > getArrayValue(reference, DetectedPeriod).chebyshevNorm()) { return false; } } @@ -294,17 +289,18 @@ public void calculateReferencePoint(GenericComplex inputPixel, Apfloat size, boo boolean stopReferenceCalculationOnDetectedPeriod = detectPeriod && TaskDraw.STOP_REFERENCE_CALCULATION_AFTER_DETECTED_PERIOD && userPeriod == 0 && canStopOnDetectedPeriod(); DoubleReference.SHOULD_SAVE_MEMORY = stopReferenceCalculationOnDetectedPeriod; + boolean useCompressedRef = TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE && supportsReferenceCompression(); if (iterations == 0) { if(lowPrecReferenceOrbitNeeded) { - referenceData.createAndSetShortcut(max_ref_iterations, false, 0); + referenceData.createAndSetShortcut(max_ref_iterations, false, 0, useCompressedRef); } else { referenceData.deallocate(); } if (deepZoom) { - referenceDeepData.createAndSetShortcut(max_ref_iterations, false, 0); + referenceDeepData.createAndSetShortcut(max_ref_iterations, false, 0, useCompressedRef); } } else if (max_ref_iterations > getReferenceLength()) { if(lowPrecReferenceOrbitNeeded) { @@ -341,8 +337,8 @@ public void calculateReferencePoint(GenericComplex inputPixel, Apfloat size, boo pixel = bn; if(detectPeriod && detectPeriodAlgorithm == 0) { //referenceData.minValue = iterations == 0 ? BigNum.getMax() : referenceData.minValue; - r0 = new BigNum(size); - r = iterations == 0 ? new BigNum((BigNum) r0) : referenceData.lastRValue; + r0 = BigNum.create(size); + r = iterations == 0 ? BigNum.copy((BigNum) r0) : referenceData.lastRValue; } } else if(bigNumLib == BIGNUM_BIGINT) { @@ -437,12 +433,25 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { normSquared = z.normSquared(); refPoint = inputPixel; - refPointSmall = refPoint.toComplex(); Location loc = new Location(); if(deepZoom) { refPointSmallDeep = loc.getMantExpComplex(refPoint); + refPointSmall = refPointSmallDeep.toComplex(); + if(isJulia) { + seedSmallDeep = loc.getMantExpComplex(c); + } + + if(lowPrecReferenceOrbitNeeded && isJulia) { + seedSmall = seedSmallDeep.toComplex(); + } + } + else { + refPointSmall = refPoint.toComplex(); + if(lowPrecReferenceOrbitNeeded && isJulia) { + seedSmall = c.toComplex(); + } } boolean isSeriesInUse = TaskDraw.APPROXIMATION_ALGORITHM == 1 && supportsSeriesApproximation(); @@ -487,26 +496,36 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { Complex cz = null; MantExpComplex mcz = null; + MantExp temp; - calculatedReferenceIterations = 0; + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[referenceDeep.id] = new ReferenceCompressor(this, iterations == 0 ? z.toMantExpComplex() : referenceData.compressorZm, c.toMantExpComplex(), start.toMantExpComplex()); + } + if(lowPrecReferenceOrbitNeeded) { + referenceCompressor[reference.id] = new ReferenceCompressor(this, iterations == 0 ? z.toComplex() : referenceData.compressorZ, c.toComplex(), start.toComplex()); + } + } - for (; iterations < max_ref_iterations; iterations++, calculatedReferenceIterations++) { + calculatedReferenceIterations = 0; - if(lowPrecReferenceOrbitNeeded) { - cz = z.toComplex(); - if (cz.isInfinite()) { - break; - } + MantExpComplex tempmcz = null; - setArrayValue(reference, iterations, cz); - } + for (; iterations < max_ref_iterations; iterations++, calculatedReferenceIterations++) { if(deepZoom) { - mcz = loc.getMantExpComplex(z); - setArrayDeepValue(referenceDeep, iterations, mcz); + mcz = loc.getMantExpComplex(z); + tempmcz = setArrayDeepValue(referenceDeep, iterations, mcz); //ReferenceDeep[iterations] = new MantExpComplex(Reference[iterations]); } + if(lowPrecReferenceOrbitNeeded) { + cz = deepZoom ? mcz.toComplex() : z.toComplex(); + cz = setArrayValue(reference, iterations, cz); + } + + mcz = tempmcz; + if(stopReferenceCalculationOnDetectedPeriod && DetectedPeriod != 0) { break; } @@ -582,12 +601,13 @@ else if (bigNumLib == Constants.BIGNUM_DOUBLEDOUBLE) { else { if (DetectedPeriod == 0 && iterations > 0) { if (deepZoom) { - if (mradius.multiply(mdzdc.chebychevNorm()).compareToBothPositive(mcz.chebychevNorm()) > 0) { + temp = mdzdc.times(mradius).chebyshevNorm(); + if (temp.compareToBothPositiveReduced(mcz.chebyshevNorm()) > 0) { DetectedPeriod = iterations; period_mdzdc = MantExpComplex.copy(mdzdc); } } else { - if (radius * dzdc.chebychevNorm() > cz.chebychevNorm()) { + if (radius * dzdc.chebyshevNorm() > cz.chebyshevNorm()) { DetectedPeriod = iterations; period_dzdc = new Complex(dzdc); } @@ -659,6 +679,18 @@ else if (bigNumLib == Constants.BIGNUM_DOUBLEDOUBLE) { referenceData.MaxRefIteration = iterations - 1; + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[referenceDeep.id].compact(referenceDeep); + referenceData.compressorZm = referenceCompressor[referenceDeep.id].getZDeep(); + } + + if(lowPrecReferenceOrbitNeeded) { + referenceCompressor[reference.id].compact(reference); + referenceData.compressorZ = referenceCompressor[reference.id].getZ(); + } + } + if(progress != null) { progress.setValue(progress.getMaximum()); progress.setString(REFERENCE_CALCULATION_STR + " 100%"); @@ -841,10 +873,10 @@ public MantExpComplex perturbationFunction(MantExpComplex DeltaSubN, MantExpComp MantExp i = X.getIm(); MantExp a = DeltaSubN.getRe(); MantExp b = DeltaSubN.getIm(); - MantExp r2 = r.multiply(r); - MantExp i2 = i.multiply(i); - MantExp a2 = a.multiply(a); - MantExp b2 = b.multiply(b); + MantExp r2 = r.square(); + MantExp i2 = i.square(); + MantExp a2 = a.square(); + MantExp b2 = b.square(); MantExp ar = a.multiply(r); MantExp ib = i.multiply(b); MantExp ab = a.multiply(b); @@ -854,15 +886,15 @@ public MantExpComplex perturbationFunction(MantExpComplex DeltaSubN, MantExpComp MantExp Dnr = r2.multiply(ar).add_mutable(ar.multiply(a2)).add_mutable(i2.multiply(ib)).add_mutable(ib.multiply(b2)).multiply4_mutable() .add_mutable(r2.multiply(a2).add_mutable(i2.multiply(b2)).subtract_mutable(r2.multiply(b2)).subtract_mutable(a2.multiply(i2)).subtract_mutable(a2.multiply(b2)).multiply_mutable(MantExp.SIX)) - .add_mutable(a2.multiply(a2)) - .add_mutable(b2.multiply(b2)) - .subtract_mutable(r2.multiply(ib).add_mutable(ar.multiply(i2)).add_mutable(ar.multiply(b2)).add_mutable(a2).multiply(ib).multiply_mutable(MantExp.TWELVE)) - .subtract_mutable(MantExp.TWENTYFOUR.multiply(ar).multiply_mutable(ib)); + .add_mutable(a2.square()) + .add_mutable(b2.square()) + .subtract_mutable(r2.multiply(ib).add_mutable(ar.multiply(i2)).add_mutable(ar.multiply(b2)).add_mutable(a2.multiply(ib)).multiply_mutable(MantExp.TWELVE)) + .subtract_mutable(ar.multiply(ib).multiply_mutable(MantExp.TWENTYFOUR)); MantExp Dni = MantExpComplex.DiffAbs(ri, rb.add(ai).add_mutable(ab)); - Dni = (r2.subtract(i2)).multiply_mutable(Dni) - .add_mutable(((ri.add(rb).add_mutable(ai).add_mutable(ab)).abs_mutable()).multiply_mutable(ar.subtract(ib).multiply2_mutable().add_mutable(a2).subtract_mutable(b2))).multiply4_mutable(); + Dni = r2.subtract(i2).multiply_mutable(Dni) + .add_mutable(ri.add(rb).add_mutable(ai).add_mutable(ab).abs_mutable().multiply_mutable(ar.subtract(ib).multiply2_mutable().add_mutable(a2).subtract_mutable(b2))).multiply4_mutable(); return MantExpComplex.create(Dnr, Dni).plus_mutable(DeltaSub0); } @@ -928,10 +960,10 @@ public MantExpComplex perturbationFunction(MantExpComplex DeltaSubN, int RefIter MantExp i = X.getIm(); MantExp a = DeltaSubN.getRe(); MantExp b = DeltaSubN.getIm(); - MantExp r2 = r.multiply(r); - MantExp i2 = i.multiply(i); - MantExp a2 = a.multiply(a); - MantExp b2 = b.multiply(b); + MantExp r2 = r.square(); + MantExp i2 = i.square(); + MantExp a2 = a.square(); + MantExp b2 = b.square(); MantExp ar = a.multiply(r); MantExp ib = i.multiply(b); MantExp ab = a.multiply(b); @@ -939,18 +971,17 @@ public MantExpComplex perturbationFunction(MantExpComplex DeltaSubN, int RefIter MantExp rb = r.multiply(b); MantExp ai = a.multiply(i); - MantExp Dnr = r2.multiply(ar).add_mutable(ar.multiply(a2)).add_mutable(i2.multiply(ib)).add_mutable(ib.multiply(b2)).multiply4_mutable() .add_mutable(r2.multiply(a2).add_mutable(i2.multiply(b2)).subtract_mutable(r2.multiply(b2)).subtract_mutable(a2.multiply(i2)).subtract_mutable(a2.multiply(b2)).multiply_mutable(MantExp.SIX)) - .add_mutable(a2.multiply(a2)) - .add_mutable(b2.multiply(b2)) - .subtract_mutable(r2.multiply(ib).add_mutable(ar.multiply(i2)).add_mutable(ar.multiply(b2)).add_mutable(a2).multiply(ib).multiply_mutable(MantExp.TWELVE)) - .subtract_mutable(MantExp.TWENTYFOUR.multiply(ar).multiply_mutable(ib)); + .add_mutable(a2.square()) + .add_mutable(b2.square()) + .subtract_mutable(r2.multiply(ib).add_mutable(ar.multiply(i2)).add_mutable(ar.multiply(b2)).add_mutable(a2.multiply(ib)).multiply_mutable(MantExp.TWELVE)) + .subtract_mutable(ar.multiply(ib).multiply_mutable(MantExp.TWENTYFOUR)); MantExp Dni = MantExpComplex.DiffAbs(ri, rb.add(ai).add_mutable(ab)); - Dni = (r2.subtract(i2)).multiply_mutable(Dni) - .add_mutable(((ri.add(rb).add_mutable(ai).add_mutable(ab)).abs_mutable()).multiply_mutable(ar.subtract(ib).multiply2_mutable().add_mutable(a2).subtract_mutable(b2))).multiply4_mutable(); + Dni = r2.subtract(i2).multiply_mutable(Dni) + .add_mutable(ri.add(rb).add_mutable(ai).add_mutable(ab).abs_mutable().multiply_mutable(ar.subtract(ib).multiply2_mutable().add_mutable(a2).subtract_mutable(b2))).multiply4_mutable(); return MantExpComplex.create(Dnr, Dni); } @@ -1014,10 +1045,10 @@ public MantExpComplex perturbationFunction(MantExpComplex DeltaSubN, ReferenceDe MantExp i = X.getIm(); MantExp a = DeltaSubN.getRe(); MantExp b = DeltaSubN.getIm(); - MantExp r2 = r.multiply(r); - MantExp i2 = i.multiply(i); - MantExp a2 = a.multiply(a); - MantExp b2 = b.multiply(b); + MantExp r2 = r.square(); + MantExp i2 = i.square(); + MantExp a2 = a.square(); + MantExp b2 = b.square(); MantExp ar = a.multiply(r); MantExp ib = i.multiply(b); MantExp ab = a.multiply(b); @@ -1027,15 +1058,15 @@ public MantExpComplex perturbationFunction(MantExpComplex DeltaSubN, ReferenceDe MantExp Dnr = r2.multiply(ar).add_mutable(ar.multiply(a2)).add_mutable(i2.multiply(ib)).add_mutable(ib.multiply(b2)).multiply4_mutable() .add_mutable(r2.multiply(a2).add_mutable(i2.multiply(b2)).subtract_mutable(r2.multiply(b2)).subtract_mutable(a2.multiply(i2)).subtract_mutable(a2.multiply(b2)).multiply_mutable(MantExp.SIX)) - .add_mutable(a2.multiply(a2)) - .add_mutable(b2.multiply(b2)) - .subtract_mutable(r2.multiply(ib).add_mutable(ar.multiply(i2)).add_mutable(ar.multiply(b2)).add_mutable(a2).multiply(ib).multiply_mutable(MantExp.TWELVE)) - .subtract_mutable(MantExp.TWENTYFOUR.multiply(ar).multiply_mutable(ib)); + .add_mutable(a2.square()) + .add_mutable(b2.square()) + .subtract_mutable(r2.multiply(ib).add_mutable(ar.multiply(i2)).add_mutable(ar.multiply(b2)).add_mutable(a2.multiply(ib)).multiply_mutable(MantExp.TWELVE)) + .subtract_mutable(ar.multiply(ib).multiply_mutable(MantExp.TWENTYFOUR)); MantExp Dni = MantExpComplex.DiffAbs(ri, rb.add(ai).add_mutable(ab)); - Dni = (r2.subtract(i2)).multiply_mutable(Dni) - .add_mutable(((ri.add(rb).add_mutable(ai).add_mutable(ab)).abs_mutable()).multiply_mutable(ar.subtract(ib).multiply2_mutable().add_mutable(a2).subtract_mutable(b2))).multiply4_mutable(); + Dni = r2.subtract(i2).multiply_mutable(Dni) + .add_mutable(ri.add(rb).add_mutable(ai).add_mutable(ab).abs_mutable().multiply_mutable(ar.subtract(ib).multiply2_mutable().add_mutable(a2).subtract_mutable(b2))).multiply4_mutable(); return MantExpComplex.create(Dnr, Dni); } @@ -1257,4 +1288,34 @@ public boolean supportsPeriod() { @Override public boolean supportsMpirBignum() { return true;} + @Override + public boolean supportsReferenceCompression() { + return true; + } + + @Override + public Complex function(Complex z, Complex c) { + if(not_burning_ship) { + return z.fourth_mutable().plus_mutable(c); + } + else { + return z.abs_mutable().fourth_mutable().plus_mutable(c); + } + } + + @Override + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + if(not_burning_ship) { + return z.fourth_mutable().plus_mutable(c); + } + else { + return z.abs_mutable().fourth_mutable().plus_mutable(c); + } + } + + @Override + public double getPower() { + return 4; + } + } diff --git a/src/fractalzoomer/functions/mandelbrot/MandelbrotNinth.java b/src/fractalzoomer/functions/mandelbrot/MandelbrotNinth.java index 094b41953..4bc53ad29 100644 --- a/src/fractalzoomer/functions/mandelbrot/MandelbrotNinth.java +++ b/src/fractalzoomer/functions/mandelbrot/MandelbrotNinth.java @@ -45,8 +45,6 @@ public MandelbrotNinth(double xCenter, double yCenter, double size, int max_iter super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - power = 9; - if(burning_ship) { type = new BurningShip(); } @@ -93,8 +91,6 @@ public MandelbrotNinth(double xCenter, double yCenter, double size, int max_iter super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, xJuliaCenter, yJuliaCenter); - power = 9; - if(burning_ship) { type = new BurningShip(); } @@ -126,8 +122,6 @@ public MandelbrotNinth(double xCenter, double yCenter, double size, int max_iter super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower); - power = 9; - if(burning_ship) { type = new BurningShip(); } @@ -167,8 +161,6 @@ public MandelbrotNinth(double xCenter, double yCenter, double size, int max_iter super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); - power = 9; - if(burning_ship) { type = new BurningShip(); } @@ -196,4 +188,9 @@ public void function(Complex[] complex) { type2.getValue(complex[0]); } + + @Override + public double getPower() { + return 9; + } } diff --git a/src/fractalzoomer/functions/mandelbrot/MandelbrotNth.java b/src/fractalzoomer/functions/mandelbrot/MandelbrotNth.java index b8e1144f8..2171c2065 100644 --- a/src/fractalzoomer/functions/mandelbrot/MandelbrotNth.java +++ b/src/fractalzoomer/functions/mandelbrot/MandelbrotNth.java @@ -46,8 +46,6 @@ public MandelbrotNth(double xCenter, double yCenter, double size, int max_iterat super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - power = z_exponent; - if(burning_ship) { type = new BurningShip(); } @@ -96,8 +94,6 @@ public MandelbrotNth(double xCenter, double yCenter, double size, int max_iterat super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, xJuliaCenter, yJuliaCenter); - power = z_exponent; - if(burning_ship) { type = new BurningShip(); } @@ -131,8 +127,6 @@ public MandelbrotNth(double xCenter, double yCenter, double size, int max_iterat super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower); - power = z_exponent; - if(burning_ship) { type = new BurningShip(); } @@ -174,8 +168,6 @@ public MandelbrotNth(double xCenter, double yCenter, double size, int max_iterat super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); - power = z_exponent; - if(burning_ship) { type = new BurningShip(); } @@ -205,4 +197,9 @@ public void function(Complex[] complex) { type2.getValue(complex[0]); } + + @Override + public double getPower() { + return z_exponent; + } } diff --git a/src/fractalzoomer/functions/mandelbrot/MandelbrotSeventh.java b/src/fractalzoomer/functions/mandelbrot/MandelbrotSeventh.java index b033526b1..12e283efb 100644 --- a/src/fractalzoomer/functions/mandelbrot/MandelbrotSeventh.java +++ b/src/fractalzoomer/functions/mandelbrot/MandelbrotSeventh.java @@ -45,8 +45,6 @@ public MandelbrotSeventh(double xCenter, double yCenter, double size, int max_it super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - power = 7; - if(burning_ship) { type = new BurningShip(); } @@ -93,8 +91,6 @@ public MandelbrotSeventh(double xCenter, double yCenter, double size, int max_it super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, xJuliaCenter, yJuliaCenter); - power = 7; - if(burning_ship) { type = new BurningShip(); } @@ -126,8 +122,6 @@ public MandelbrotSeventh(double xCenter, double yCenter, double size, int max_it super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower); - power = 7; - if(burning_ship) { type = new BurningShip(); } @@ -167,8 +161,6 @@ public MandelbrotSeventh(double xCenter, double yCenter, double size, int max_it super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); - power = 7; - if(burning_ship) { type = new BurningShip(); } @@ -196,4 +188,9 @@ public void function(Complex[] complex) { type2.getValue(complex[0]); } + + @Override + public double getPower() { + return 7; + } } diff --git a/src/fractalzoomer/functions/mandelbrot/MandelbrotSixth.java b/src/fractalzoomer/functions/mandelbrot/MandelbrotSixth.java index 2fd8388b6..ae0fffd6b 100644 --- a/src/fractalzoomer/functions/mandelbrot/MandelbrotSixth.java +++ b/src/fractalzoomer/functions/mandelbrot/MandelbrotSixth.java @@ -45,8 +45,6 @@ public MandelbrotSixth(double xCenter, double yCenter, double size, int max_iter super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - power = 6; - if(burning_ship) { type = new BurningShip(); } @@ -93,8 +91,6 @@ public MandelbrotSixth(double xCenter, double yCenter, double size, int max_iter super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, xJuliaCenter, yJuliaCenter); - power = 6; - if(burning_ship) { type = new BurningShip(); } @@ -126,8 +122,6 @@ public MandelbrotSixth(double xCenter, double yCenter, double size, int max_iter super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower); - power = 6; - if(burning_ship) { type = new BurningShip(); } @@ -167,8 +161,6 @@ public MandelbrotSixth(double xCenter, double yCenter, double size, int max_iter super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); - power = 6; - if(burning_ship) { type = new BurningShip(); } @@ -197,4 +189,9 @@ public void function(Complex[] complex) { } + @Override + public double getPower() { + return 6; + } + } diff --git a/src/fractalzoomer/functions/mandelbrot/MandelbrotTenth.java b/src/fractalzoomer/functions/mandelbrot/MandelbrotTenth.java index 91e28757e..9850db8a6 100644 --- a/src/fractalzoomer/functions/mandelbrot/MandelbrotTenth.java +++ b/src/fractalzoomer/functions/mandelbrot/MandelbrotTenth.java @@ -45,8 +45,6 @@ public MandelbrotTenth(double xCenter, double yCenter, double size, int max_iter super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - power = 10; - if(burning_ship) { type = new BurningShip(); } @@ -93,8 +91,6 @@ public MandelbrotTenth(double xCenter, double yCenter, double size, int max_iter super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, periodicity_checking, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, xJuliaCenter, yJuliaCenter); - power = 10; - if(burning_ship) { type = new BurningShip(); } @@ -126,8 +122,6 @@ public MandelbrotTenth(double xCenter, double yCenter, double size, int max_iter super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower); - power = 10; - if(burning_ship) { type = new BurningShip(); } @@ -167,8 +161,6 @@ public MandelbrotTenth(double xCenter, double yCenter, double size, int max_iter super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, xJuliaCenter, yJuliaCenter); - power = 10; - if(burning_ship) { type = new BurningShip(); } @@ -196,4 +188,9 @@ public void function(Complex[] complex) { type2.getValue(complex[0]); } + + @Override + public double getPower() { + return 10; + } } diff --git a/src/fractalzoomer/functions/root_finding_methods/RootFindingMethods.java b/src/fractalzoomer/functions/root_finding_methods/RootFindingMethods.java index 149652c52..6421debf5 100644 --- a/src/fractalzoomer/functions/root_finding_methods/RootFindingMethods.java +++ b/src/fractalzoomer/functions/root_finding_methods/RootFindingMethods.java @@ -46,12 +46,16 @@ public RootFindingMethods(double xCenter, double yCenter, double size, int max_i super(xCenter, yCenter, size, max_iterations, 0, 0, "", "", 0, 0, false, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - convergent_bailout = 1E-10; + setConvergentBailout(1E-10); isJulia = false; defaultInitVal = new DefaultInitialValue(); } + protected void setConvergentBailout(double val) { + convergent_bailout = TaskDraw.USER_CONVERGENT_BAILOUT > 0 ? TaskDraw.USER_CONVERGENT_BAILOUT : val; + } + //orbit public RootFindingMethods(double xCenter, double yCenter, double size, int max_iterations, ArrayList complex_orbit, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower) { @@ -197,7 +201,7 @@ public double iterateFractalArbitraryPrecision(GenericComplex[] complex, Generic setTrueColorOut(z, zold, zold2, iterations, pixelC, start, c0, pixelC); } - return out; + return getAndAccumulateHP(out); } gzold2.set(gzold); @@ -224,7 +228,7 @@ public double iterateFractalArbitraryPrecision(GenericComplex[] complex, Generic setTrueColorIn(z, zold, zold2, iterations, pixelC, start, c0, pixelC); } - return in; + return getAndAccumulateHP(in); } @@ -577,6 +581,8 @@ public double iterateFractalWithPerturbation(Complex[] complex, Complex dpixel) Complex pixel = dpixel.plus(refPointSmall); + Complex refZ; + ReferenceData data = referenceData; int MaxRefIteration = data.MaxRefIteration; @@ -616,8 +622,9 @@ public double iterateFractalWithPerturbation(Complex[] complex, Complex dpixel) //No Plane influence work //No Pre filters work if(max_iterations > 1){ - zWithoutInitVal = getArrayValue(data.ReferenceSubCp, RefIteration).plus_mutable(DeltaSubN); - complex[0] = getArrayValue(data.Reference, RefIteration).plus_mutable(DeltaSubN); + refZ = getArrayValue(data.Reference, RefIteration); + zWithoutInitVal = getArrayValue(data.ReferenceSubCp, RefIteration, refZ).plus_mutable(DeltaSubN); + complex[0] = refZ.plus_mutable(DeltaSubN); } //No Post filters work @@ -669,12 +676,10 @@ public double iterateFractalWithPerturbation(Complex[] complex, MantExpComplex d MantExpComplex[] deltas = initializePerturbation(dpixel); MantExpComplex DeltaSubN = deltas[0]; // Delta z - Complex zWithoutInitVal = new Complex(); - Complex pixel = dpixel.plus(refPointSmallDeep).toComplex(); int minExp = -1000; - int reducedExp = minExp / (int)power; + int reducedExp = minExp / (int)getPower(); DeltaSubN.Normalize(); long exp = DeltaSubN.getMinExp(); @@ -683,12 +688,15 @@ public double iterateFractalWithPerturbation(Complex[] complex, MantExpComplex d ReferenceData data = referenceData; int MaxRefIteration = data.MaxRefIteration; + MantExpComplex refZm; + boolean useFullFloatExp = useFullFloatExp(); boolean doBailCheck = useFullFloatExp || TaskDraw.CHECK_BAILOUT_DURING_DEEP_NOT_FULL_FLOATEXP_MODE; if(useFullFloatExp || (totalSkippedIterations == 0 && exp <= minExp) || (totalSkippedIterations != 0 && exp <= reducedExp)) { - MantExpComplex z = getArrayDeepValue(deepData.ReferenceSubCp, RefIteration).plus_mutable(DeltaSubN); + MantExpComplex zWithoutInitVal = MantExpComplex.create(); + MantExpComplex z = getArrayDeepValue(deepData.Reference, RefIteration).plus_mutable(DeltaSubN); MantExpComplex zoldDeep; @@ -724,16 +732,18 @@ public double iterateFractalWithPerturbation(Complex[] complex, MantExpComplex d zoldDeep = z; if (max_iterations > 1) { - z = getArrayDeepValue(deepData.ReferenceSubCp, RefIteration).plus_mutable(DeltaSubN); - complex[0] = getArrayDeepValue(deepData.Reference, RefIteration).plus_mutable(DeltaSubN).toComplex(); + refZm = getArrayDeepValue(deepData.Reference, RefIteration); + zWithoutInitVal = getArrayDeepValue(deepData.ReferenceSubCp, RefIteration, refZm).plus_mutable(DeltaSubN); + z = refZm.plus_mutable(DeltaSubN); + complex[0] = z.toComplex(); } if (statistic != null) { statistic.insert(complex[0], zold, zold2, iterations, pixel, start, c0, z , zoldDeep, null); } - if (z.norm_squared().compareToBothPositive(DeltaSubN.norm_squared()) < 0 || RefIteration >= MaxRefIteration) { - DeltaSubN = z; + if (zWithoutInitVal.norm_squared().compareToBothPositive(DeltaSubN.norm_squared()) < 0 || RefIteration >= MaxRefIteration) { + DeltaSubN = zWithoutInitVal; RefIteration = 0; deepData = secondReferenceDeepData; @@ -757,6 +767,8 @@ public double iterateFractalWithPerturbation(Complex[] complex, MantExpComplex d if(!useFullFloatExp) { Complex CDeltaSubN = DeltaSubN.toComplex(); + Complex zWithoutInitVal = new Complex(); + Complex refZ; for (; iterations < max_iterations; iterations++) { @@ -794,8 +806,9 @@ public double iterateFractalWithPerturbation(Complex[] complex, MantExpComplex d //No Plane influence work //No Pre filters work if (max_iterations > 1) { - zWithoutInitVal = getArrayValue(data.ReferenceSubCp, RefIteration).plus_mutable(CDeltaSubN); - complex[0] = getArrayValue(data.Reference, RefIteration).plus_mutable(CDeltaSubN); + refZ = getArrayValue(data.Reference, RefIteration); + zWithoutInitVal = getArrayValue(data.ReferenceSubCp, RefIteration, refZ).plus_mutable(CDeltaSubN); + complex[0] = refZ.plus_mutable(CDeltaSubN); } //No Post filters work diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy/Abbasbandy3.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy/Abbasbandy3.java index 69a0500a1..5bed5e54c 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy/Abbasbandy3.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy/Abbasbandy3.java @@ -16,16 +16,12 @@ public Abbasbandy3(double xCenter, double yCenter, double size, int max_iteratio switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy/Abbasbandy4.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy/Abbasbandy4.java index 7841cd71a..bd8af4068 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy/Abbasbandy4.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy/Abbasbandy4.java @@ -16,16 +16,12 @@ public Abbasbandy4(double xCenter, double yCenter, double size, int max_iteratio switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyCos.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyCos.java index 67e89fb6a..1ac07a558 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyCos.java @@ -16,16 +16,14 @@ public AbbasbandyCos(double xCenter, double yCenter, double size, int max_iterat switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyFormula.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyFormula.java index d47b4a92f..b4e08bbd5 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyFormula.java @@ -30,15 +30,10 @@ public AbbasbandyFormula(double xCenter, double yCenter, double size, int max_it switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyGeneralized3.java index 93b82b78c..eb48655d4 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyGeneralized3.java @@ -16,16 +16,12 @@ public AbbasbandyGeneralized3(double xCenter, double yCenter, double size, int m switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyGeneralized8.java index ae29525d3..a0c6e4158 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyGeneralized8.java @@ -16,16 +16,12 @@ public AbbasbandyGeneralized8(double xCenter, double yCenter, double size, int m switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyPoly.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyPoly.java index a7a285fbc..bfc585540 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyPoly.java @@ -38,18 +38,13 @@ public AbbasbandyPoly(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyRootFindingMethod.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyRootFindingMethod.java index 9622cb84e..1e39dce8d 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyRootFindingMethod.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandyRootFindingMethod.java @@ -32,7 +32,7 @@ public AbbasbandyRootFindingMethod(double xCenter, double yCenter, double size, super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - convergent_bailout = 1e-8; + setConvergentBailout(1e-8); } diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandySin.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandySin.java index 54ea1b95a..8d7c4ba95 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandySin.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy/AbbasbandySin.java @@ -16,16 +16,14 @@ public AbbasbandySin(double xCenter, double yCenter, double size, int max_iterat switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy23.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy23.java index ec8e822c2..e154aa91c 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy23.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy23.java @@ -37,18 +37,13 @@ public Abbasbandy23(double xCenter, double yCenter, double size, int max_iterati switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy24.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy24.java index f4195fb52..95e106f12 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy24.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy24.java @@ -37,18 +37,13 @@ public Abbasbandy24(double xCenter, double yCenter, double size, int max_iterati switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Cos.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Cos.java index 247511955..f1197324e 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Cos.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Cos.java @@ -37,16 +37,14 @@ public Abbasbandy2Cos(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Formula.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Formula.java index 0280e0c90..5c493b410 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Formula.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Formula.java @@ -48,15 +48,10 @@ public Abbasbandy2Formula(double xCenter, double yCenter, double size, int max_i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Generalized3.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Generalized3.java index 9e2a2141f..1c05239cf 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Generalized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Generalized3.java @@ -37,18 +37,13 @@ public Abbasbandy2Generalized3(double xCenter, double yCenter, double size, int switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Generalized8.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Generalized8.java index 64d2a182b..a0d60b878 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Generalized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Generalized8.java @@ -37,18 +37,13 @@ public Abbasbandy2Generalized8(double xCenter, double yCenter, double size, int switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Poly.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Poly.java index 5a38d2b88..0b4b1127e 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Poly.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Poly.java @@ -59,18 +59,13 @@ public Abbasbandy2Poly(double xCenter, double yCenter, double size, int max_iter switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Sin.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Sin.java index 41a345308..c15486281 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Sin.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy2/Abbasbandy2Sin.java @@ -33,20 +33,18 @@ public class Abbasbandy2Sin extends Abbasbandy2RootFindingMethod { public Abbasbandy2Sin(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy33.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy33.java index 5ca62118f..92fa2b2d2 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy33.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy33.java @@ -16,16 +16,12 @@ public Abbasbandy33(double xCenter, double yCenter, double size, int max_iterati switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy34.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy34.java index 56ddd132b..0ba4a2d15 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy34.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy34.java @@ -16,17 +16,14 @@ public Abbasbandy34(double xCenter, double yCenter, double size, int max_iterati switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; + } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Cos.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Cos.java index 97bf66443..00359f8ba 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Cos.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Cos.java @@ -16,16 +16,14 @@ public Abbasbandy3Cos(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Formula.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Formula.java index 6038f97f1..f37a0fa68 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Formula.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Formula.java @@ -30,15 +30,10 @@ public Abbasbandy3Formula(double xCenter, double yCenter, double size, int max_i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Generalized3.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Generalized3.java index 26924c958..f6364dace 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Generalized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Generalized3.java @@ -16,17 +16,14 @@ public Abbasbandy3Generalized3(double xCenter, double yCenter, double size, int switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; + } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Generalized8.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Generalized8.java index a9f0f2b9a..ca4aca07b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Generalized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Generalized8.java @@ -16,17 +16,14 @@ public Abbasbandy3Generalized8(double xCenter, double yCenter, double size, int switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; + } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Poly.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Poly.java index 3a9eb1a1b..7231fe6ca 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Poly.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Poly.java @@ -38,18 +38,13 @@ public Abbasbandy3Poly(double xCenter, double yCenter, double size, int max_iter switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3RootFindingMethod.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3RootFindingMethod.java index 04d7390aa..7ac59f1c1 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3RootFindingMethod.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3RootFindingMethod.java @@ -31,8 +31,8 @@ public abstract class Abbasbandy3RootFindingMethod extends RootFindingMethods { public Abbasbandy3RootFindingMethod(double xCenter, double yCenter, double size, int max_iterations, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, OrbitTrapSettings ots) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - - convergent_bailout = 1e-8; + + setConvergentBailout(1e-8); } diff --git a/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Sin.java b/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Sin.java index 0f8437ff2..415c50ab2 100644 --- a/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Sin.java +++ b/src/fractalzoomer/functions/root_finding_methods/abbasbandy3/Abbasbandy3Sin.java @@ -16,16 +16,14 @@ public Abbasbandy3Sin(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/aberth_ehrlich/AberthEhrlich3.java b/src/fractalzoomer/functions/root_finding_methods/aberth_ehrlich/AberthEhrlich3.java index dad60e256..b26b4c6ec 100644 --- a/src/fractalzoomer/functions/root_finding_methods/aberth_ehrlich/AberthEhrlich3.java +++ b/src/fractalzoomer/functions/root_finding_methods/aberth_ehrlich/AberthEhrlich3.java @@ -15,13 +15,11 @@ public AberthEhrlich3(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/aberth_ehrlich/AberthEhrlich4.java b/src/fractalzoomer/functions/root_finding_methods/aberth_ehrlich/AberthEhrlich4.java index 68731112c..f60eecf87 100644 --- a/src/fractalzoomer/functions/root_finding_methods/aberth_ehrlich/AberthEhrlich4.java +++ b/src/fractalzoomer/functions/root_finding_methods/aberth_ehrlich/AberthEhrlich4.java @@ -15,13 +15,11 @@ public AberthEhrlich4(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/aberth_ehrlich/AberthEhrlichGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/aberth_ehrlich/AberthEhrlichGeneralized3.java index 7d3e504c2..263fdb04e 100644 --- a/src/fractalzoomer/functions/root_finding_methods/aberth_ehrlich/AberthEhrlichGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/aberth_ehrlich/AberthEhrlichGeneralized3.java @@ -15,13 +15,11 @@ public AberthEhrlichGeneralized3(double xCenter, double yCenter, double size, in switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/aberth_ehrlich/AberthEhrlichGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/aberth_ehrlich/AberthEhrlichGeneralized8.java index cf390ffcb..96e8c348f 100644 --- a/src/fractalzoomer/functions/root_finding_methods/aberth_ehrlich/AberthEhrlichGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/aberth_ehrlich/AberthEhrlichGeneralized8.java @@ -15,13 +15,11 @@ public AberthEhrlichGeneralized8(double xCenter, double yCenter, double size, in switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/aberth_ehrlich/AberthEhrlichPoly.java b/src/fractalzoomer/functions/root_finding_methods/aberth_ehrlich/AberthEhrlichPoly.java index 99517f556..b3c59df9e 100644 --- a/src/fractalzoomer/functions/root_finding_methods/aberth_ehrlich/AberthEhrlichPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/aberth_ehrlich/AberthEhrlichPoly.java @@ -40,15 +40,12 @@ public AberthEhrlichPoly(double xCenter, double yCenter, double size, int max_it aberthEhrlichInitializationMethod = root_initialization_method; switch (out_coloring_algorithm) { - case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/bairstow/Bairstow3.java b/src/fractalzoomer/functions/root_finding_methods/bairstow/Bairstow3.java index fc41c621a..1a6987650 100644 --- a/src/fractalzoomer/functions/root_finding_methods/bairstow/Bairstow3.java +++ b/src/fractalzoomer/functions/root_finding_methods/bairstow/Bairstow3.java @@ -35,15 +35,12 @@ public Bairstow3(double xCenter, double yCenter, double size, int max_iterations switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/bairstow/Bairstow4.java b/src/fractalzoomer/functions/root_finding_methods/bairstow/Bairstow4.java index 0c8ec0e42..2414eba4c 100644 --- a/src/fractalzoomer/functions/root_finding_methods/bairstow/Bairstow4.java +++ b/src/fractalzoomer/functions/root_finding_methods/bairstow/Bairstow4.java @@ -35,15 +35,12 @@ public Bairstow4(double xCenter, double yCenter, double size, int max_iterations switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/bairstow/BairstowGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/bairstow/BairstowGeneralized3.java index 3f7179a5e..e2c478da6 100644 --- a/src/fractalzoomer/functions/root_finding_methods/bairstow/BairstowGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/bairstow/BairstowGeneralized3.java @@ -35,15 +35,12 @@ public BairstowGeneralized3(double xCenter, double yCenter, double size, int max switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/bairstow/BairstowGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/bairstow/BairstowGeneralized8.java index c1e64ef98..183b4a984 100644 --- a/src/fractalzoomer/functions/root_finding_methods/bairstow/BairstowGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/bairstow/BairstowGeneralized8.java @@ -35,15 +35,12 @@ public BairstowGeneralized8(double xCenter, double yCenter, double size, int max switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/bairstow/BairstowPoly.java b/src/fractalzoomer/functions/root_finding_methods/bairstow/BairstowPoly.java index 479c82c9a..223ea6b51 100644 --- a/src/fractalzoomer/functions/root_finding_methods/bairstow/BairstowPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/bairstow/BairstowPoly.java @@ -36,13 +36,11 @@ public BairstowPoly(double xCenter, double yCenter, double size, int max_iterati switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; - break; + setConvergentBailout(1E-9); + break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun13.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun13.java index 7159fb7bd..29ae8d0d3 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun13.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun13.java @@ -15,13 +15,11 @@ public ChangBumChun13(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun14.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun14.java index ac83280e1..082ac156b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun14.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun14.java @@ -15,13 +15,11 @@ public ChangBumChun14(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Cos.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Cos.java index 5e00985f5..a7590d6a3 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Cos.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Cos.java @@ -15,13 +15,11 @@ public ChangBumChun1Cos(double xCenter, double yCenter, double size, int max_ite switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Formula.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Formula.java index 24af19b69..415df43de 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Formula.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Formula.java @@ -26,15 +26,10 @@ public ChangBumChun1Formula(double xCenter, double yCenter, double size, int max switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Generalized3.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Generalized3.java index a9844b2d9..6d7bd7763 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Generalized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Generalized3.java @@ -15,13 +15,11 @@ public ChangBumChun1Generalized3(double xCenter, double yCenter, double size, in switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Generalized8.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Generalized8.java index 0d51c1d56..6cb4613cf 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Generalized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Generalized8.java @@ -15,13 +15,11 @@ public ChangBumChun1Generalized8(double xCenter, double yCenter, double size, in switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Poly.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Poly.java index a11385c2d..8d45970ab 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Poly.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Poly.java @@ -37,13 +37,11 @@ public ChangBumChun1Poly(double xCenter, double yCenter, double size, int max_it switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1RootFindingMethod.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1RootFindingMethod.java index 8c4ce8fe4..3e8ae7c3b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1RootFindingMethod.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1RootFindingMethod.java @@ -12,7 +12,7 @@ public ChangBumChun1RootFindingMethod(double xCenter, double yCenter, double siz super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - convergent_bailout = 1e-8; + setConvergentBailout(1e-8); } diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Sin.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Sin.java index 9dd0d6d33..60cfc4a54 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Sin.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun1/ChangBumChun1Sin.java @@ -15,13 +15,11 @@ public ChangBumChun1Sin(double xCenter, double yCenter, double size, int max_ite switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun23.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun23.java index 125548684..7afe0f7b0 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun23.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun23.java @@ -15,13 +15,11 @@ public ChangBumChun23(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun24.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun24.java index 628177eb7..42c41e719 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun24.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun24.java @@ -15,13 +15,11 @@ public ChangBumChun24(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Cos.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Cos.java index 71f31b1dc..8b18de35f 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Cos.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Cos.java @@ -15,13 +15,11 @@ public ChangBumChun2Cos(double xCenter, double yCenter, double size, int max_ite switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Formula.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Formula.java index 8437c3650..946243024 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Formula.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Formula.java @@ -26,15 +26,10 @@ public ChangBumChun2Formula(double xCenter, double yCenter, double size, int max switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Generalized3.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Generalized3.java index 64012aa20..b36ff3cf7 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Generalized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Generalized3.java @@ -15,13 +15,11 @@ public ChangBumChun2Generalized3(double xCenter, double yCenter, double size, in switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Generalized8.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Generalized8.java index e0f0bb272..c1f75513b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Generalized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Generalized8.java @@ -15,13 +15,11 @@ public ChangBumChun2Generalized8(double xCenter, double yCenter, double size, in switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Poly.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Poly.java index 25a4f8db0..e631cb19c 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Poly.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Poly.java @@ -37,13 +37,11 @@ public ChangBumChun2Poly(double xCenter, double yCenter, double size, int max_it switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Sin.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Sin.java index 4d60db26b..25cf37909 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Sin.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun2/ChangBumChun2Sin.java @@ -15,13 +15,11 @@ public ChangBumChun2Sin(double xCenter, double yCenter, double size, int max_ite switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun33.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun33.java index c5a38ff84..4d527e7b8 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun33.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun33.java @@ -15,13 +15,11 @@ public ChangBumChun33(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun34.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun34.java index e2bb251db..7184305e7 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun34.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun34.java @@ -15,13 +15,11 @@ public ChangBumChun34(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Cos.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Cos.java index 40de71a53..cee159936 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Cos.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Cos.java @@ -15,13 +15,11 @@ public ChangBumChun3Cos(double xCenter, double yCenter, double size, int max_ite switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Formula.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Formula.java index f2413e505..3c020a967 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Formula.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Formula.java @@ -26,15 +26,10 @@ public ChangBumChun3Formula(double xCenter, double yCenter, double size, int max switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Generalized3.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Generalized3.java index abde800db..40fa4a7f1 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Generalized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Generalized3.java @@ -15,13 +15,11 @@ public ChangBumChun3Generalized3(double xCenter, double yCenter, double size, in switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Generalized8.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Generalized8.java index a2372a084..d3c2e799a 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Generalized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Generalized8.java @@ -15,13 +15,11 @@ public ChangBumChun3Generalized8(double xCenter, double yCenter, double size, in switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Poly.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Poly.java index eadebebeb..463012167 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Poly.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Poly.java @@ -37,13 +37,11 @@ public ChangBumChun3Poly(double xCenter, double yCenter, double size, int max_it switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Sin.java b/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Sin.java index d459485ca..af01d2c4a 100644 --- a/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Sin.java +++ b/src/fractalzoomer/functions/root_finding_methods/changbum_chun3/ChangBumChun3Sin.java @@ -15,13 +15,11 @@ public ChangBumChun3Sin(double xCenter, double yCenter, double size, int max_ite switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHam3.java b/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHam3.java index a708e38f4..88a8aa78c 100644 --- a/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHam3.java +++ b/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHam3.java @@ -14,14 +14,13 @@ public ChunHam3(double xCenter, double yCenter, double size, int max_iterations, super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHam4.java b/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHam4.java index 8642b3c0a..494097de4 100644 --- a/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHam4.java +++ b/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHam4.java @@ -15,15 +15,12 @@ public ChunHam4(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamCos.java b/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamCos.java index db37f80f2..acf388494 100644 --- a/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamCos.java @@ -14,14 +14,13 @@ public ChunHamCos(double xCenter, double yCenter, double size, int max_iteration super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamFormula.java b/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamFormula.java index af70de29d..75a492244 100644 --- a/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamFormula.java @@ -26,15 +26,10 @@ public ChunHamFormula(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamGeneralized3.java index 1d3d9f3c8..23bf85fa8 100644 --- a/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamGeneralized3.java @@ -15,15 +15,12 @@ public ChunHamGeneralized3(double xCenter, double yCenter, double size, int max_ switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamGeneralized8.java index edfa23ec8..c7e946a31 100644 --- a/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamGeneralized8.java @@ -14,14 +14,13 @@ public ChunHamGeneralized8(double xCenter, double yCenter, double size, int max_ super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamPoly.java b/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamPoly.java index 4ced322af..c8a71da5c 100644 --- a/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamPoly.java @@ -36,14 +36,13 @@ public ChunHamPoly(double xCenter, double yCenter, double size, int max_iteratio } switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamRootFindingMethod.java b/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamRootFindingMethod.java index 62c22ac4d..2b1291826 100644 --- a/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamRootFindingMethod.java +++ b/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamRootFindingMethod.java @@ -12,7 +12,7 @@ public ChunHamRootFindingMethod(double xCenter, double yCenter, double size, int super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - convergent_bailout = 1e-8; + setConvergentBailout(1e-8); } diff --git a/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamSin.java b/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamSin.java index 572a77a3a..ce9526ad3 100644 --- a/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/chun_ham/ChunHamSin.java @@ -14,14 +14,13 @@ public ChunHamSin(double xCenter, double yCenter, double size, int max_iteration super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKim3.java b/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKim3.java index c84c561de..ee52d1cae 100644 --- a/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKim3.java +++ b/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKim3.java @@ -16,16 +16,12 @@ public ChunKim3(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKim4.java b/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKim4.java index a9f53a7b7..b341dd14b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKim4.java +++ b/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKim4.java @@ -16,16 +16,12 @@ public ChunKim4(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimCos.java b/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimCos.java index 8d4386237..58423d5b0 100644 --- a/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimCos.java @@ -16,16 +16,12 @@ public ChunKimCos(double xCenter, double yCenter, double size, int max_iteration switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimFormula.java b/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimFormula.java index ba4eaf8d4..f9ee8e230 100644 --- a/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimFormula.java @@ -26,15 +26,10 @@ public ChunKimFormula(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimGeneralized3.java index 639f7bdd1..d4ba2265c 100644 --- a/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimGeneralized3.java @@ -16,16 +16,12 @@ public ChunKimGeneralized3(double xCenter, double yCenter, double size, int max_ switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimGeneralized8.java index 2debb8631..c54b4e1be 100644 --- a/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimGeneralized8.java @@ -16,16 +16,12 @@ public ChunKimGeneralized8(double xCenter, double yCenter, double size, int max_ switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimPoly.java b/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimPoly.java index 19dc7b71a..9a1374265 100644 --- a/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimPoly.java @@ -38,18 +38,13 @@ public ChunKimPoly(double xCenter, double yCenter, double size, int max_iteratio switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimSin.java b/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimSin.java index 64c5c6d1b..9c0b55f18 100644 --- a/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/chun_kim/ChunKimSin.java @@ -16,16 +16,12 @@ public ChunKimSin(double xCenter, double yCenter, double size, int max_iteration switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewton3.java b/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewton3.java index 94c2cbac3..4894442e3 100644 --- a/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewton3.java +++ b/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewton3.java @@ -16,16 +16,12 @@ public ContraHarmonicNewton3(double xCenter, double yCenter, double size, int ma switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewton4.java b/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewton4.java index 4d4640075..78f88efed 100644 --- a/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewton4.java +++ b/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewton4.java @@ -16,16 +16,12 @@ public ContraHarmonicNewton4(double xCenter, double yCenter, double size, int ma switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonCos.java b/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonCos.java index a404aaa20..6b80e816e 100644 --- a/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonCos.java @@ -16,16 +16,12 @@ public ContraHarmonicNewtonCos(double xCenter, double yCenter, double size, int switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonFormula.java b/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonFormula.java index 029e63fb5..d34610ce2 100644 --- a/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonFormula.java @@ -26,15 +26,10 @@ public ContraHarmonicNewtonFormula(double xCenter, double yCenter, double size, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonGeneralized3.java index 54b65bcff..618a0a878 100644 --- a/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonGeneralized3.java @@ -16,16 +16,12 @@ public ContraHarmonicNewtonGeneralized3(double xCenter, double yCenter, double s switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonGeneralized8.java index d03f07e91..4d5798907 100644 --- a/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonGeneralized8.java @@ -16,16 +16,12 @@ public ContraHarmonicNewtonGeneralized8(double xCenter, double yCenter, double s switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonPoly.java b/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonPoly.java index 0a4c07dd3..080306745 100644 --- a/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonPoly.java @@ -38,18 +38,13 @@ public ContraHarmonicNewtonPoly(double xCenter, double yCenter, double size, int switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonSin.java b/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonSin.java index 540591b12..9828b8228 100644 --- a/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/contra_harmonic_newton/ContraHarmonicNewtonSin.java @@ -16,16 +16,12 @@ public ContraHarmonicNewtonSin(double xCenter, double yCenter, double size, int switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/durand_kerner/DurandKerner3.java b/src/fractalzoomer/functions/root_finding_methods/durand_kerner/DurandKerner3.java index c7fcbb985..ce0fe78e6 100644 --- a/src/fractalzoomer/functions/root_finding_methods/durand_kerner/DurandKerner3.java +++ b/src/fractalzoomer/functions/root_finding_methods/durand_kerner/DurandKerner3.java @@ -32,16 +32,14 @@ public class DurandKerner3 extends DurandKernerRootFindingMethod { public DurandKerner3(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, 3); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/durand_kerner/DurandKerner4.java b/src/fractalzoomer/functions/root_finding_methods/durand_kerner/DurandKerner4.java index 93fc1b1a4..1547f8d6e 100644 --- a/src/fractalzoomer/functions/root_finding_methods/durand_kerner/DurandKerner4.java +++ b/src/fractalzoomer/functions/root_finding_methods/durand_kerner/DurandKerner4.java @@ -32,16 +32,14 @@ public class DurandKerner4 extends DurandKernerRootFindingMethod { public DurandKerner4(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, 4); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/durand_kerner/DurandKernerGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/durand_kerner/DurandKernerGeneralized3.java index 03b598ef4..92881a976 100644 --- a/src/fractalzoomer/functions/root_finding_methods/durand_kerner/DurandKernerGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/durand_kerner/DurandKernerGeneralized3.java @@ -32,16 +32,14 @@ public class DurandKernerGeneralized3 extends DurandKernerRootFindingMethod { public DurandKernerGeneralized3(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, 3); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/durand_kerner/DurandKernerGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/durand_kerner/DurandKernerGeneralized8.java index 8e5b57920..7c3f60888 100644 --- a/src/fractalzoomer/functions/root_finding_methods/durand_kerner/DurandKernerGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/durand_kerner/DurandKernerGeneralized8.java @@ -32,16 +32,14 @@ public class DurandKernerGeneralized8 extends DurandKernerRootFindingMethod { public DurandKernerGeneralized8(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, 8); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/durand_kerner/DurandKernerPoly.java b/src/fractalzoomer/functions/root_finding_methods/durand_kerner/DurandKernerPoly.java index ff371cc0a..f784b299a 100644 --- a/src/fractalzoomer/functions/root_finding_methods/durand_kerner/DurandKernerPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/durand_kerner/DurandKernerPoly.java @@ -60,15 +60,12 @@ public DurandKernerPoly(double xCenter, double yCenter, double size, int max_ite durandKernerInitializationMethod = root_initialization_method; switch (out_coloring_algorithm) { - case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; - break; + setConvergentBailout(1E-9); + break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshev3.java b/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshev3.java index 80e44cb0c..f5b6eab79 100644 --- a/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshev3.java +++ b/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshev3.java @@ -37,16 +37,12 @@ public EulerChebyshev3(double xCenter, double yCenter, double size, int max_iter switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshev4.java b/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshev4.java index 173df4555..168e1d17e 100644 --- a/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshev4.java +++ b/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshev4.java @@ -37,16 +37,12 @@ public EulerChebyshev4(double xCenter, double yCenter, double size, int max_iter switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevCos.java b/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevCos.java index 1ba76fb79..65b534300 100644 --- a/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevCos.java @@ -37,16 +37,14 @@ public EulerChebyshevCos(double xCenter, double yCenter, double size, int max_it switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevFormula.java b/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevFormula.java index 3c772a1b0..fac5296ba 100644 --- a/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevFormula.java @@ -48,15 +48,10 @@ public EulerChebyshevFormula(double xCenter, double yCenter, double size, int ma switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevGeneralized3.java index 82c6521ea..489303826 100644 --- a/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevGeneralized3.java @@ -37,16 +37,12 @@ public EulerChebyshevGeneralized3(double xCenter, double yCenter, double size, i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevGeneralized8.java index 3901665d8..eaae60ede 100644 --- a/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevGeneralized8.java @@ -37,16 +37,12 @@ public EulerChebyshevGeneralized8(double xCenter, double yCenter, double size, i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevPoly.java b/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevPoly.java index 04b2793b1..f7692f613 100644 --- a/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevPoly.java @@ -59,16 +59,12 @@ public EulerChebyshevPoly(double xCenter, double yCenter, double size, int max_i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevSin.java b/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevSin.java index fa68780c4..0526117c2 100644 --- a/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/euler_chebyshev/EulerChebyshevSin.java @@ -33,20 +33,18 @@ public class EulerChebyshevSin extends EulerChebyshevRootFindingMethod { public EulerChebyshevSin(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki13.java b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki13.java index 823d54235..20371d3d7 100644 --- a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki13.java +++ b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki13.java @@ -15,13 +15,11 @@ public EzzatiSaleki13(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki14.java b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki14.java index d786f4841..12f9e4778 100644 --- a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki14.java +++ b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki14.java @@ -15,13 +15,11 @@ public EzzatiSaleki14(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Cos.java b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Cos.java index cc41ac482..625756b8d 100644 --- a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Cos.java +++ b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Cos.java @@ -15,13 +15,11 @@ public EzzatiSaleki1Cos(double xCenter, double yCenter, double size, int max_ite switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Formula.java b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Formula.java index 84037fddd..9696d2c28 100644 --- a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Formula.java +++ b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Formula.java @@ -26,15 +26,10 @@ public EzzatiSaleki1Formula(double xCenter, double yCenter, double size, int max switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Generalized3.java b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Generalized3.java index 76fd61799..feac7165c 100644 --- a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Generalized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Generalized3.java @@ -15,13 +15,11 @@ public EzzatiSaleki1Generalized3(double xCenter, double yCenter, double size, in switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Generalized8.java b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Generalized8.java index 2630c4627..44a014360 100644 --- a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Generalized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Generalized8.java @@ -15,13 +15,11 @@ public EzzatiSaleki1Generalized8(double xCenter, double yCenter, double size, in switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Poly.java b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Poly.java index 5e94920e2..9f2f7673c 100644 --- a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Poly.java +++ b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Poly.java @@ -37,13 +37,11 @@ public EzzatiSaleki1Poly(double xCenter, double yCenter, double size, int max_it switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Sin.java b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Sin.java index 49832bc9b..669566839 100644 --- a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Sin.java +++ b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki1/EzzatiSaleki1Sin.java @@ -15,13 +15,11 @@ public EzzatiSaleki1Sin(double xCenter, double yCenter, double size, int max_ite switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki23.java b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki23.java index 4c19ca769..d103e490e 100644 --- a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki23.java +++ b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki23.java @@ -15,13 +15,11 @@ public EzzatiSaleki23(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki24.java b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki24.java index 2dda7fd28..0fd086cf6 100644 --- a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki24.java +++ b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki24.java @@ -15,13 +15,11 @@ public EzzatiSaleki24(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Cos.java b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Cos.java index 0856598c0..4a300b71f 100644 --- a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Cos.java +++ b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Cos.java @@ -15,13 +15,11 @@ public EzzatiSaleki2Cos(double xCenter, double yCenter, double size, int max_ite switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Formula.java b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Formula.java index f44212ac1..b2d7091a5 100644 --- a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Formula.java +++ b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Formula.java @@ -26,15 +26,10 @@ public EzzatiSaleki2Formula(double xCenter, double yCenter, double size, int max switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Generalized3.java b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Generalized3.java index 404d41d70..07b86d0f1 100644 --- a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Generalized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Generalized3.java @@ -15,13 +15,11 @@ public EzzatiSaleki2Generalized3(double xCenter, double yCenter, double size, in switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Generalized8.java b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Generalized8.java index ae97d1c09..7d31e603a 100644 --- a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Generalized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Generalized8.java @@ -15,13 +15,11 @@ public EzzatiSaleki2Generalized8(double xCenter, double yCenter, double size, in switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Poly.java b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Poly.java index c31d07e63..88e8f3a4f 100644 --- a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Poly.java +++ b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Poly.java @@ -37,13 +37,11 @@ public EzzatiSaleki2Poly(double xCenter, double yCenter, double size, int max_it switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2RootFindingMethod.java b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2RootFindingMethod.java index 972d0bbf3..8060b4341 100644 --- a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2RootFindingMethod.java +++ b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2RootFindingMethod.java @@ -12,7 +12,7 @@ public EzzatiSaleki2RootFindingMethod(double xCenter, double yCenter, double siz super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - convergent_bailout = 1e-8; + setConvergentBailout(1e-8); } diff --git a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Sin.java b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Sin.java index 3fc680c16..b2ae38e53 100644 --- a/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Sin.java +++ b/src/fractalzoomer/functions/root_finding_methods/ezzati_saleki2/EzzatiSaleki2Sin.java @@ -15,13 +15,11 @@ public EzzatiSaleki2Sin(double xCenter, double yCenter, double size, int max_ite switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/feng/Feng3.java b/src/fractalzoomer/functions/root_finding_methods/feng/Feng3.java index 52d4e8e78..52f29faff 100644 --- a/src/fractalzoomer/functions/root_finding_methods/feng/Feng3.java +++ b/src/fractalzoomer/functions/root_finding_methods/feng/Feng3.java @@ -15,13 +15,11 @@ public Feng3(double xCenter, double yCenter, double size, int max_iterations, in switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/feng/Feng4.java b/src/fractalzoomer/functions/root_finding_methods/feng/Feng4.java index 7b0fb1389..8542a5af4 100644 --- a/src/fractalzoomer/functions/root_finding_methods/feng/Feng4.java +++ b/src/fractalzoomer/functions/root_finding_methods/feng/Feng4.java @@ -15,13 +15,11 @@ public Feng4(double xCenter, double yCenter, double size, int max_iterations, in switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/feng/FengCos.java b/src/fractalzoomer/functions/root_finding_methods/feng/FengCos.java index 91799be12..136bcd00f 100644 --- a/src/fractalzoomer/functions/root_finding_methods/feng/FengCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/feng/FengCos.java @@ -15,13 +15,11 @@ public FengCos(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/feng/FengFormula.java b/src/fractalzoomer/functions/root_finding_methods/feng/FengFormula.java index 812979e10..5725ef5d2 100644 --- a/src/fractalzoomer/functions/root_finding_methods/feng/FengFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/feng/FengFormula.java @@ -24,15 +24,10 @@ public FengFormula(double xCenter, double yCenter, double size, int max_iteratio super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { - case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/feng/FengGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/feng/FengGeneralized3.java index 9603b51b3..259638a8b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/feng/FengGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/feng/FengGeneralized3.java @@ -15,13 +15,11 @@ public FengGeneralized3(double xCenter, double yCenter, double size, int max_ite switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/feng/FengGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/feng/FengGeneralized8.java index 9009473e0..6c56abf8c 100644 --- a/src/fractalzoomer/functions/root_finding_methods/feng/FengGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/feng/FengGeneralized8.java @@ -15,13 +15,11 @@ public FengGeneralized8(double xCenter, double yCenter, double size, int max_ite switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/feng/FengPoly.java b/src/fractalzoomer/functions/root_finding_methods/feng/FengPoly.java index 24427771e..7d8a5a613 100644 --- a/src/fractalzoomer/functions/root_finding_methods/feng/FengPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/feng/FengPoly.java @@ -37,13 +37,11 @@ public FengPoly(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/feng/FengSin.java b/src/fractalzoomer/functions/root_finding_methods/feng/FengSin.java index 31684e995..806bdfb7f 100644 --- a/src/fractalzoomer/functions/root_finding_methods/feng/FengSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/feng/FengSin.java @@ -15,13 +15,11 @@ public FengSin(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/halley/Halley3.java b/src/fractalzoomer/functions/root_finding_methods/halley/Halley3.java index b4d19e22e..20e16dc49 100644 --- a/src/fractalzoomer/functions/root_finding_methods/halley/Halley3.java +++ b/src/fractalzoomer/functions/root_finding_methods/halley/Halley3.java @@ -37,16 +37,12 @@ public Halley3(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/halley/Halley4.java b/src/fractalzoomer/functions/root_finding_methods/halley/Halley4.java index d9600d380..89816c83f 100644 --- a/src/fractalzoomer/functions/root_finding_methods/halley/Halley4.java +++ b/src/fractalzoomer/functions/root_finding_methods/halley/Halley4.java @@ -37,18 +37,13 @@ public Halley4(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/halley/HalleyCos.java b/src/fractalzoomer/functions/root_finding_methods/halley/HalleyCos.java index 4a1866635..9c56b344f 100644 --- a/src/fractalzoomer/functions/root_finding_methods/halley/HalleyCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/halley/HalleyCos.java @@ -33,20 +33,18 @@ public class HalleyCos extends HalleyRootFindingMethod { public HalleyCos(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/halley/HalleyFormula.java b/src/fractalzoomer/functions/root_finding_methods/halley/HalleyFormula.java index ce4fe1f26..ec12a1ce3 100644 --- a/src/fractalzoomer/functions/root_finding_methods/halley/HalleyFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/halley/HalleyFormula.java @@ -46,17 +46,11 @@ public HalleyFormula(double xCenter, double yCenter, double size, int max_iterat super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { - case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/halley/HalleyGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/halley/HalleyGeneralized3.java index e4853144f..601373e78 100644 --- a/src/fractalzoomer/functions/root_finding_methods/halley/HalleyGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/halley/HalleyGeneralized3.java @@ -37,18 +37,13 @@ public HalleyGeneralized3(double xCenter, double yCenter, double size, int max_i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/halley/HalleyGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/halley/HalleyGeneralized8.java index f0f0970c9..d0dfabc5e 100644 --- a/src/fractalzoomer/functions/root_finding_methods/halley/HalleyGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/halley/HalleyGeneralized8.java @@ -37,18 +37,13 @@ public HalleyGeneralized8(double xCenter, double yCenter, double size, int max_i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/halley/HalleyPoly.java b/src/fractalzoomer/functions/root_finding_methods/halley/HalleyPoly.java index 8af274b78..c539956df 100644 --- a/src/fractalzoomer/functions/root_finding_methods/halley/HalleyPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/halley/HalleyPoly.java @@ -59,18 +59,13 @@ public HalleyPoly(double xCenter, double yCenter, double size, int max_iteration switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/halley/HalleySin.java b/src/fractalzoomer/functions/root_finding_methods/halley/HalleySin.java index 004a76dad..1acf140e0 100644 --- a/src/fractalzoomer/functions/root_finding_methods/halley/HalleySin.java +++ b/src/fractalzoomer/functions/root_finding_methods/halley/HalleySin.java @@ -33,20 +33,18 @@ public class HalleySin extends HalleyRootFindingMethod { public HalleySin(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewton3.java b/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewton3.java index c50f804b5..292c4008f 100644 --- a/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewton3.java +++ b/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewton3.java @@ -16,16 +16,12 @@ public HarmonicSimpsonNewton3(double xCenter, double yCenter, double size, int m switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewton4.java b/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewton4.java index 7b73d3b4c..7ecc0562a 100644 --- a/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewton4.java +++ b/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewton4.java @@ -16,16 +16,12 @@ public HarmonicSimpsonNewton4(double xCenter, double yCenter, double size, int m switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonCos.java b/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonCos.java index 5cf5e78d8..25ef7e48e 100644 --- a/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonCos.java @@ -16,16 +16,12 @@ public HarmonicSimpsonNewtonCos(double xCenter, double yCenter, double size, int switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonFormula.java b/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonFormula.java index ee86140f8..a382621c5 100644 --- a/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonFormula.java @@ -26,15 +26,10 @@ public HarmonicSimpsonNewtonFormula(double xCenter, double yCenter, double size, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonGeneralized3.java index 55e9cd6af..798a76458 100644 --- a/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonGeneralized3.java @@ -16,16 +16,12 @@ public HarmonicSimpsonNewtonGeneralized3(double xCenter, double yCenter, double switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonGeneralized8.java index 480bc642e..605fb71b1 100644 --- a/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonGeneralized8.java @@ -16,16 +16,12 @@ public HarmonicSimpsonNewtonGeneralized8(double xCenter, double yCenter, double switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonPoly.java b/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonPoly.java index 8da5fa32d..02e72bc6b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonPoly.java @@ -38,18 +38,13 @@ public HarmonicSimpsonNewtonPoly(double xCenter, double yCenter, double size, in switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonSin.java b/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonSin.java index c21a35e35..9e78aa40b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/harmonic_simpson_newton/HarmonicSimpsonNewtonSin.java @@ -16,16 +16,12 @@ public HarmonicSimpsonNewtonSin(double xCenter, double yCenter, double size, int switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier13.java b/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier13.java index 16d2c496c..7176db16b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier13.java +++ b/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier13.java @@ -16,16 +16,12 @@ public Homeier13(double xCenter, double yCenter, double size, int max_iterations switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier14.java b/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier14.java index c0a2a84e8..90724709b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier14.java +++ b/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier14.java @@ -16,16 +16,12 @@ public Homeier14(double xCenter, double yCenter, double size, int max_iterations switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Cos.java b/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Cos.java index 068be4cab..40f02edab 100644 --- a/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Cos.java +++ b/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Cos.java @@ -16,16 +16,12 @@ public Homeier1Cos(double xCenter, double yCenter, double size, int max_iteratio switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Formula.java b/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Formula.java index 1232c6c81..25ac5b858 100644 --- a/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Formula.java +++ b/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Formula.java @@ -26,15 +26,10 @@ public Homeier1Formula(double xCenter, double yCenter, double size, int max_iter switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Generalized3.java b/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Generalized3.java index 693421dc0..b28356eec 100644 --- a/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Generalized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Generalized3.java @@ -16,16 +16,12 @@ public Homeier1Generalized3(double xCenter, double yCenter, double size, int max switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Generalized8.java b/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Generalized8.java index 94e313964..b4f1890e9 100644 --- a/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Generalized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Generalized8.java @@ -16,16 +16,12 @@ public Homeier1Generalized8(double xCenter, double yCenter, double size, int max switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Poly.java b/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Poly.java index e4a60bc89..469d45014 100644 --- a/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Poly.java +++ b/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Poly.java @@ -38,18 +38,13 @@ public Homeier1Poly(double xCenter, double yCenter, double size, int max_iterati switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Sin.java b/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Sin.java index 0d161ff6a..b65253d78 100644 --- a/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Sin.java +++ b/src/fractalzoomer/functions/root_finding_methods/homeier1/Homeier1Sin.java @@ -16,16 +16,12 @@ public Homeier1Sin(double xCenter, double yCenter, double size, int max_iteratio switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier23.java b/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier23.java index b7c76806e..84b047a13 100644 --- a/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier23.java +++ b/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier23.java @@ -16,16 +16,12 @@ public Homeier23(double xCenter, double yCenter, double size, int max_iterations switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier24.java b/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier24.java index c6b00d9ce..af1ac63f7 100644 --- a/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier24.java +++ b/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier24.java @@ -16,16 +16,12 @@ public Homeier24(double xCenter, double yCenter, double size, int max_iterations switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Cos.java b/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Cos.java index ceffaab15..6b4b67666 100644 --- a/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Cos.java +++ b/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Cos.java @@ -16,16 +16,12 @@ public Homeier2Cos(double xCenter, double yCenter, double size, int max_iteratio switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Formula.java b/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Formula.java index 656d6397a..47e5b30ef 100644 --- a/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Formula.java +++ b/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Formula.java @@ -26,15 +26,10 @@ public Homeier2Formula(double xCenter, double yCenter, double size, int max_iter switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Generalized3.java b/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Generalized3.java index 167f3580f..0978bca95 100644 --- a/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Generalized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Generalized3.java @@ -16,16 +16,12 @@ public Homeier2Generalized3(double xCenter, double yCenter, double size, int max switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Generalized8.java b/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Generalized8.java index 81ef776df..dd74aa1ee 100644 --- a/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Generalized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Generalized8.java @@ -16,16 +16,12 @@ public Homeier2Generalized8(double xCenter, double yCenter, double size, int max switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Poly.java b/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Poly.java index 623aad7e4..b38dabc4f 100644 --- a/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Poly.java +++ b/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Poly.java @@ -38,18 +38,13 @@ public Homeier2Poly(double xCenter, double yCenter, double size, int max_iterati switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Sin.java b/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Sin.java index e688c7323..d5f414f89 100644 --- a/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Sin.java +++ b/src/fractalzoomer/functions/root_finding_methods/homeier2/Homeier2Sin.java @@ -16,16 +16,12 @@ public Homeier2Sin(double xCenter, double yCenter, double size, int max_iteratio switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/householder/Householder3.java b/src/fractalzoomer/functions/root_finding_methods/householder/Householder3.java index 28bf1fbe8..9044fbe39 100644 --- a/src/fractalzoomer/functions/root_finding_methods/householder/Householder3.java +++ b/src/fractalzoomer/functions/root_finding_methods/householder/Householder3.java @@ -37,16 +37,12 @@ public Householder3(double xCenter, double yCenter, double size, int max_iterati switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/householder/Householder4.java b/src/fractalzoomer/functions/root_finding_methods/householder/Householder4.java index 3b300007b..db7714e0c 100644 --- a/src/fractalzoomer/functions/root_finding_methods/householder/Householder4.java +++ b/src/fractalzoomer/functions/root_finding_methods/householder/Householder4.java @@ -37,16 +37,12 @@ public Householder4(double xCenter, double yCenter, double size, int max_iterati switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderCos.java b/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderCos.java index 3a0186c5f..cb7551c70 100644 --- a/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderCos.java @@ -33,20 +33,18 @@ public class HouseholderCos extends HouseholderRootFindingMethod { public HouseholderCos(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderFormula.java b/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderFormula.java index 771915bb8..bf8addf60 100644 --- a/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderFormula.java @@ -48,15 +48,10 @@ public HouseholderFormula(double xCenter, double yCenter, double size, int max_i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderGeneralized3.java index 162038328..f94156042 100644 --- a/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderGeneralized3.java @@ -37,16 +37,12 @@ public HouseholderGeneralized3(double xCenter, double yCenter, double size, int switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderGeneralized8.java index 54e5d0a16..c5831dd34 100644 --- a/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderGeneralized8.java @@ -37,16 +37,12 @@ public HouseholderGeneralized8(double xCenter, double yCenter, double size, int switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderPoly.java b/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderPoly.java index ddbb375b6..7ca547fa1 100644 --- a/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderPoly.java @@ -59,16 +59,12 @@ public HouseholderPoly(double xCenter, double yCenter, double size, int max_iter switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderSin.java b/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderSin.java index 2df164a0c..ba83925f6 100644 --- a/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/householder/HouseholderSin.java @@ -33,20 +33,18 @@ public class HouseholderSin extends HouseholderRootFindingMethod { public HouseholderSin(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/householder3/Householder33.java b/src/fractalzoomer/functions/root_finding_methods/householder3/Householder33.java index 1e519e7e0..345fc6822 100644 --- a/src/fractalzoomer/functions/root_finding_methods/householder3/Householder33.java +++ b/src/fractalzoomer/functions/root_finding_methods/householder3/Householder33.java @@ -16,17 +16,14 @@ public Householder33(double xCenter, double yCenter, double size, int max_iterat switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; + } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/householder3/Householder34.java b/src/fractalzoomer/functions/root_finding_methods/householder3/Householder34.java index 94da4435c..defd04aef 100644 --- a/src/fractalzoomer/functions/root_finding_methods/householder3/Householder34.java +++ b/src/fractalzoomer/functions/root_finding_methods/householder3/Householder34.java @@ -16,17 +16,14 @@ public Householder34(double xCenter, double yCenter, double size, int max_iterat switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; + } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Cos.java b/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Cos.java index 06ede6855..aa3c44411 100644 --- a/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Cos.java +++ b/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Cos.java @@ -16,16 +16,14 @@ public Householder3Cos(double xCenter, double yCenter, double size, int max_iter switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Formula.java b/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Formula.java index cfe860f6e..544ccbce0 100644 --- a/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Formula.java +++ b/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Formula.java @@ -30,15 +30,10 @@ public Householder3Formula(double xCenter, double yCenter, double size, int max_ switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Generalized3.java b/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Generalized3.java index 49e15203a..05ff1f4fe 100644 --- a/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Generalized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Generalized3.java @@ -16,17 +16,14 @@ public Householder3Generalized3(double xCenter, double yCenter, double size, int switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; + } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Generalized8.java b/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Generalized8.java index 0786f0b73..158dfeb75 100644 --- a/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Generalized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Generalized8.java @@ -16,17 +16,14 @@ public Householder3Generalized8(double xCenter, double yCenter, double size, int switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; + } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Poly.java b/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Poly.java index 452904659..ff1a0d230 100644 --- a/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Poly.java +++ b/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Poly.java @@ -38,16 +38,12 @@ public Householder3Poly(double xCenter, double yCenter, double size, int max_ite switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3RootFindingMethod.java b/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3RootFindingMethod.java index a33a2d539..bfb1e9b47 100644 --- a/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3RootFindingMethod.java +++ b/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3RootFindingMethod.java @@ -32,7 +32,7 @@ public Householder3RootFindingMethod(double xCenter, double yCenter, double size super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - convergent_bailout = 1e-8; + setConvergentBailout(1e-8); } diff --git a/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Sin.java b/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Sin.java index 8ac8d204f..d1e64dc5e 100644 --- a/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Sin.java +++ b/src/fractalzoomer/functions/root_finding_methods/householder3/Householder3Sin.java @@ -16,16 +16,14 @@ public Householder3Sin(double xCenter, double yCenter, double size, int max_iter switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/jaratt/Jaratt3.java b/src/fractalzoomer/functions/root_finding_methods/jaratt/Jaratt3.java index 1e03959dd..202323b16 100644 --- a/src/fractalzoomer/functions/root_finding_methods/jaratt/Jaratt3.java +++ b/src/fractalzoomer/functions/root_finding_methods/jaratt/Jaratt3.java @@ -16,16 +16,12 @@ public Jaratt3(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/jaratt/Jaratt4.java b/src/fractalzoomer/functions/root_finding_methods/jaratt/Jaratt4.java index fb4aaf779..f8d3cb6d5 100644 --- a/src/fractalzoomer/functions/root_finding_methods/jaratt/Jaratt4.java +++ b/src/fractalzoomer/functions/root_finding_methods/jaratt/Jaratt4.java @@ -16,16 +16,12 @@ public Jaratt4(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattCos.java b/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattCos.java index 493f56826..9cfca99df 100644 --- a/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattCos.java @@ -16,16 +16,12 @@ public JarattCos(double xCenter, double yCenter, double size, int max_iterations switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattFormula.java b/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattFormula.java index ae97b4e47..6df76812e 100644 --- a/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattFormula.java @@ -24,17 +24,11 @@ public JarattFormula(double xCenter, double yCenter, double size, int max_iterat super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { - case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattGeneralized3.java index 62ebb98d7..e8cbc0409 100644 --- a/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattGeneralized3.java @@ -16,16 +16,12 @@ public JarattGeneralized3(double xCenter, double yCenter, double size, int max_i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattGeneralized8.java index 6a2d9bd5c..37c2ce524 100644 --- a/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattGeneralized8.java @@ -16,16 +16,12 @@ public JarattGeneralized8(double xCenter, double yCenter, double size, int max_i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattPoly.java b/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattPoly.java index da9e5e63e..b3b84e406 100644 --- a/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattPoly.java @@ -38,18 +38,13 @@ public JarattPoly(double xCenter, double yCenter, double size, int max_iteration switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattRootFindingMethod.java b/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattRootFindingMethod.java index 20bd0109a..d6d563311 100644 --- a/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattRootFindingMethod.java +++ b/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattRootFindingMethod.java @@ -11,8 +11,8 @@ public abstract class JarattRootFindingMethod extends RootFindingMethods { public JarattRootFindingMethod(double xCenter, double yCenter, double size, int max_iterations, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, OrbitTrapSettings ots) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - - convergent_bailout = 1e-8; + + setConvergentBailout(1e-8); } diff --git a/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattSin.java b/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattSin.java index ae787096f..7bbda059f 100644 --- a/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/jaratt/JarattSin.java @@ -16,16 +16,12 @@ public JarattSin(double xCenter, double yCenter, double size, int max_iterations switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt23.java b/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt23.java index 47d5caba5..6fb498abc 100644 --- a/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt23.java +++ b/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt23.java @@ -16,16 +16,12 @@ public Jaratt23(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt24.java b/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt24.java index 8742369ab..2d722dc8f 100644 --- a/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt24.java +++ b/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt24.java @@ -16,16 +16,12 @@ public Jaratt24(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Cos.java b/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Cos.java index 8c810f98d..06b34215e 100644 --- a/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Cos.java +++ b/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Cos.java @@ -16,16 +16,12 @@ public Jaratt2Cos(double xCenter, double yCenter, double size, int max_iteration switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Formula.java b/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Formula.java index 784419f1f..3d26f71a5 100644 --- a/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Formula.java +++ b/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Formula.java @@ -24,17 +24,11 @@ public Jaratt2Formula(double xCenter, double yCenter, double size, int max_itera super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { - case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Generalized3.java b/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Generalized3.java index 27d247f9d..3fb7dcfe9 100644 --- a/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Generalized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Generalized3.java @@ -16,16 +16,12 @@ public Jaratt2Generalized3(double xCenter, double yCenter, double size, int max_ switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Generalized8.java b/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Generalized8.java index b7cd4bb7f..2a1fcf2c8 100644 --- a/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Generalized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Generalized8.java @@ -16,16 +16,12 @@ public Jaratt2Generalized8(double xCenter, double yCenter, double size, int max_ switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Poly.java b/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Poly.java index 3035c76f4..efb2e5d3f 100644 --- a/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Poly.java +++ b/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Poly.java @@ -38,18 +38,13 @@ public Jaratt2Poly(double xCenter, double yCenter, double size, int max_iteratio switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2RootFindingMethod.java b/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2RootFindingMethod.java index 91ca8318d..e296d3563 100644 --- a/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2RootFindingMethod.java +++ b/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2RootFindingMethod.java @@ -12,7 +12,7 @@ public Jaratt2RootFindingMethod(double xCenter, double yCenter, double size, int super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - convergent_bailout = 1e-8; + setConvergentBailout(1e-8); } diff --git a/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Sin.java b/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Sin.java index 663defca2..775942f4a 100644 --- a/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Sin.java +++ b/src/fractalzoomer/functions/root_finding_methods/jaratt2/Jaratt2Sin.java @@ -16,16 +16,12 @@ public Jaratt2Sin(double xCenter, double yCenter, double size, int max_iteration switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChun3.java b/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChun3.java index a0518c088..5677c324f 100644 --- a/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChun3.java +++ b/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChun3.java @@ -16,16 +16,12 @@ public KimChun3(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChun4.java b/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChun4.java index edba52005..28e513285 100644 --- a/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChun4.java +++ b/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChun4.java @@ -16,16 +16,12 @@ public KimChun4(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunCos.java b/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunCos.java index 2ea902493..a0497d0e7 100644 --- a/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunCos.java @@ -16,16 +16,12 @@ public KimChunCos(double xCenter, double yCenter, double size, int max_iteration switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunFormula.java b/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunFormula.java index f62896108..6ae26e65b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunFormula.java @@ -26,15 +26,10 @@ public KimChunFormula(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunGeneralized3.java index 2fa3c4801..9eebc7f74 100644 --- a/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunGeneralized3.java @@ -16,16 +16,12 @@ public KimChunGeneralized3(double xCenter, double yCenter, double size, int max_ switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunGeneralized8.java index ee9c7e337..763ec9099 100644 --- a/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunGeneralized8.java @@ -16,16 +16,12 @@ public KimChunGeneralized8(double xCenter, double yCenter, double size, int max_ switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunPoly.java b/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunPoly.java index f39784663..0534824dc 100644 --- a/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunPoly.java @@ -38,18 +38,13 @@ public KimChunPoly(double xCenter, double yCenter, double size, int max_iteratio switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunSin.java b/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunSin.java index 9bccede9f..b13d4a0ee 100644 --- a/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/kim_chun/KimChunSin.java @@ -16,16 +16,12 @@ public KimChunSin(double xCenter, double yCenter, double size, int max_iteration switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/king1/King13.java b/src/fractalzoomer/functions/root_finding_methods/king1/King13.java index 7ee51d8ce..2590b0f5d 100644 --- a/src/fractalzoomer/functions/root_finding_methods/king1/King13.java +++ b/src/fractalzoomer/functions/root_finding_methods/king1/King13.java @@ -15,13 +15,11 @@ public King13(double xCenter, double yCenter, double size, int max_iterations, i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/king1/King14.java b/src/fractalzoomer/functions/root_finding_methods/king1/King14.java index 57c38e9f4..937fa3da4 100644 --- a/src/fractalzoomer/functions/root_finding_methods/king1/King14.java +++ b/src/fractalzoomer/functions/root_finding_methods/king1/King14.java @@ -14,14 +14,13 @@ public King14(double xCenter, double yCenter, double size, int max_iterations, i super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/king1/King1Cos.java b/src/fractalzoomer/functions/root_finding_methods/king1/King1Cos.java index d73f791cf..a3c1bddfe 100644 --- a/src/fractalzoomer/functions/root_finding_methods/king1/King1Cos.java +++ b/src/fractalzoomer/functions/root_finding_methods/king1/King1Cos.java @@ -14,14 +14,13 @@ public King1Cos(double xCenter, double yCenter, double size, int max_iterations, super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/king1/King1Formula.java b/src/fractalzoomer/functions/root_finding_methods/king1/King1Formula.java index cf492fed0..8df05a45a 100644 --- a/src/fractalzoomer/functions/root_finding_methods/king1/King1Formula.java +++ b/src/fractalzoomer/functions/root_finding_methods/king1/King1Formula.java @@ -24,17 +24,11 @@ public King1Formula(double xCenter, double yCenter, double size, int max_iterati super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { - case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/king1/King1Generalized3.java b/src/fractalzoomer/functions/root_finding_methods/king1/King1Generalized3.java index c88f73c60..a4b6ec4ab 100644 --- a/src/fractalzoomer/functions/root_finding_methods/king1/King1Generalized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/king1/King1Generalized3.java @@ -15,13 +15,11 @@ public King1Generalized3(double xCenter, double yCenter, double size, int max_it switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/king1/King1Generalized8.java b/src/fractalzoomer/functions/root_finding_methods/king1/King1Generalized8.java index 724d2e9ed..f1ed71eff 100644 --- a/src/fractalzoomer/functions/root_finding_methods/king1/King1Generalized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/king1/King1Generalized8.java @@ -14,14 +14,13 @@ public King1Generalized8(double xCenter, double yCenter, double size, int max_it super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/king1/King1Poly.java b/src/fractalzoomer/functions/root_finding_methods/king1/King1Poly.java index f43ccd6b0..f3b7a0bd9 100644 --- a/src/fractalzoomer/functions/root_finding_methods/king1/King1Poly.java +++ b/src/fractalzoomer/functions/root_finding_methods/king1/King1Poly.java @@ -37,13 +37,11 @@ public King1Poly(double xCenter, double yCenter, double size, int max_iterations switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/king1/King1RootFindingMethod.java b/src/fractalzoomer/functions/root_finding_methods/king1/King1RootFindingMethod.java index 5506f8429..3f758263e 100644 --- a/src/fractalzoomer/functions/root_finding_methods/king1/King1RootFindingMethod.java +++ b/src/fractalzoomer/functions/root_finding_methods/king1/King1RootFindingMethod.java @@ -11,7 +11,7 @@ public abstract class King1RootFindingMethod extends RootFindingMethods { public King1RootFindingMethod(double xCenter, double yCenter, double size, int max_iterations, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, OrbitTrapSettings ots) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - convergent_bailout = 1e-8; + setConvergentBailout(1e-8); } diff --git a/src/fractalzoomer/functions/root_finding_methods/king1/King1Sin.java b/src/fractalzoomer/functions/root_finding_methods/king1/King1Sin.java index f4e66bb56..9b21c4324 100644 --- a/src/fractalzoomer/functions/root_finding_methods/king1/King1Sin.java +++ b/src/fractalzoomer/functions/root_finding_methods/king1/King1Sin.java @@ -15,13 +15,11 @@ public King1Sin(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/king3/King33.java b/src/fractalzoomer/functions/root_finding_methods/king3/King33.java index abd530eb2..0c6fd4aad 100644 --- a/src/fractalzoomer/functions/root_finding_methods/king3/King33.java +++ b/src/fractalzoomer/functions/root_finding_methods/king3/King33.java @@ -15,13 +15,11 @@ public King33(double xCenter, double yCenter, double size, int max_iterations, i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/king3/King34.java b/src/fractalzoomer/functions/root_finding_methods/king3/King34.java index 3a0182183..73417da1b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/king3/King34.java +++ b/src/fractalzoomer/functions/root_finding_methods/king3/King34.java @@ -14,14 +14,13 @@ public King34(double xCenter, double yCenter, double size, int max_iterations, i super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/king3/King3Cos.java b/src/fractalzoomer/functions/root_finding_methods/king3/King3Cos.java index ac3047437..8e65d7fb7 100644 --- a/src/fractalzoomer/functions/root_finding_methods/king3/King3Cos.java +++ b/src/fractalzoomer/functions/root_finding_methods/king3/King3Cos.java @@ -14,14 +14,13 @@ public King3Cos(double xCenter, double yCenter, double size, int max_iterations, super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/king3/King3Formula.java b/src/fractalzoomer/functions/root_finding_methods/king3/King3Formula.java index e0c03d204..041bf576c 100644 --- a/src/fractalzoomer/functions/root_finding_methods/king3/King3Formula.java +++ b/src/fractalzoomer/functions/root_finding_methods/king3/King3Formula.java @@ -24,17 +24,11 @@ public King3Formula(double xCenter, double yCenter, double size, int max_iterati super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { - case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/king3/King3Generalized3.java b/src/fractalzoomer/functions/root_finding_methods/king3/King3Generalized3.java index c8eda8477..dfdf76e80 100644 --- a/src/fractalzoomer/functions/root_finding_methods/king3/King3Generalized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/king3/King3Generalized3.java @@ -15,13 +15,11 @@ public King3Generalized3(double xCenter, double yCenter, double size, int max_it switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/king3/King3Generalized8.java b/src/fractalzoomer/functions/root_finding_methods/king3/King3Generalized8.java index 87bc21e18..db990d8ed 100644 --- a/src/fractalzoomer/functions/root_finding_methods/king3/King3Generalized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/king3/King3Generalized8.java @@ -15,13 +15,11 @@ public King3Generalized8(double xCenter, double yCenter, double size, int max_it switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/king3/King3Poly.java b/src/fractalzoomer/functions/root_finding_methods/king3/King3Poly.java index de1aebdae..134c70f80 100644 --- a/src/fractalzoomer/functions/root_finding_methods/king3/King3Poly.java +++ b/src/fractalzoomer/functions/root_finding_methods/king3/King3Poly.java @@ -37,13 +37,11 @@ public King3Poly(double xCenter, double yCenter, double size, int max_iterations switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/king3/King3RootFindingMethod.java b/src/fractalzoomer/functions/root_finding_methods/king3/King3RootFindingMethod.java index 6c7b74227..6f9bcb89f 100644 --- a/src/fractalzoomer/functions/root_finding_methods/king3/King3RootFindingMethod.java +++ b/src/fractalzoomer/functions/root_finding_methods/king3/King3RootFindingMethod.java @@ -12,7 +12,7 @@ public King3RootFindingMethod(double xCenter, double yCenter, double size, int m super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - convergent_bailout = 1e-8; + setConvergentBailout(1e-8); } diff --git a/src/fractalzoomer/functions/root_finding_methods/king3/King3Sin.java b/src/fractalzoomer/functions/root_finding_methods/king3/King3Sin.java index c32ba54b9..3a943acf9 100644 --- a/src/fractalzoomer/functions/root_finding_methods/king3/King3Sin.java +++ b/src/fractalzoomer/functions/root_finding_methods/king3/King3Sin.java @@ -15,17 +15,14 @@ public King3Sin(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } - OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); InColoringAlgorithmFactory(in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang13.java b/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang13.java index 2ac3a7e99..1c0b581c3 100644 --- a/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang13.java +++ b/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang13.java @@ -15,13 +15,11 @@ public KouLiWang13(double xCenter, double yCenter, double size, int max_iteratio switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang14.java b/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang14.java index 1c3d95784..acd4af69b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang14.java +++ b/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang14.java @@ -15,13 +15,11 @@ public KouLiWang14(double xCenter, double yCenter, double size, int max_iteratio switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Cos.java b/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Cos.java index 4969cc004..84d8b2a10 100644 --- a/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Cos.java +++ b/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Cos.java @@ -15,13 +15,11 @@ public KouLiWang1Cos(double xCenter, double yCenter, double size, int max_iterat switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Formula.java b/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Formula.java index 71b454f30..01b16eb08 100644 --- a/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Formula.java +++ b/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Formula.java @@ -26,15 +26,10 @@ public KouLiWang1Formula(double xCenter, double yCenter, double size, int max_it switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Generalized3.java b/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Generalized3.java index 343fdc7f5..3b2521c0a 100644 --- a/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Generalized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Generalized3.java @@ -15,13 +15,11 @@ public KouLiWang1Generalized3(double xCenter, double yCenter, double size, int m switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Generalized8.java b/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Generalized8.java index 02e85cebd..2f17af186 100644 --- a/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Generalized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Generalized8.java @@ -15,13 +15,11 @@ public KouLiWang1Generalized8(double xCenter, double yCenter, double size, int m switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Poly.java b/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Poly.java index 25909d426..44f3bf082 100644 --- a/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Poly.java +++ b/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Poly.java @@ -37,13 +37,11 @@ public KouLiWang1Poly(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Sin.java b/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Sin.java index 8c83fa857..0a4f19430 100644 --- a/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Sin.java +++ b/src/fractalzoomer/functions/root_finding_methods/kou_li_wang1/KouLiWang1Sin.java @@ -15,13 +15,11 @@ public KouLiWang1Sin(double xCenter, double yCenter, double size, int max_iterat switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/laguerre/Laguerre3.java b/src/fractalzoomer/functions/root_finding_methods/laguerre/Laguerre3.java index 8f60b82ae..8948f2975 100644 --- a/src/fractalzoomer/functions/root_finding_methods/laguerre/Laguerre3.java +++ b/src/fractalzoomer/functions/root_finding_methods/laguerre/Laguerre3.java @@ -37,16 +37,12 @@ public Laguerre3(double xCenter, double yCenter, double size, int max_iterations switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/laguerre/Laguerre4.java b/src/fractalzoomer/functions/root_finding_methods/laguerre/Laguerre4.java index c0d7583bb..24747b093 100644 --- a/src/fractalzoomer/functions/root_finding_methods/laguerre/Laguerre4.java +++ b/src/fractalzoomer/functions/root_finding_methods/laguerre/Laguerre4.java @@ -37,18 +37,13 @@ public Laguerre4(double xCenter, double yCenter, double size, int max_iterations switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerreCos.java b/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerreCos.java index 6c2d7dab3..acf903a52 100644 --- a/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerreCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerreCos.java @@ -33,20 +33,18 @@ public class LaguerreCos extends LaguerreRootFindingMethod { public LaguerreCos(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, new double[] {50, 0}, ots); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerreFormula.java b/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerreFormula.java index 1e829bc83..730b19fcd 100644 --- a/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerreFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerreFormula.java @@ -48,15 +48,10 @@ public LaguerreFormula(double xCenter, double yCenter, double size, int max_iter switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerreGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerreGeneralized3.java index 8de4ea9b5..cf0f63dbc 100644 --- a/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerreGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerreGeneralized3.java @@ -37,18 +37,13 @@ public LaguerreGeneralized3(double xCenter, double yCenter, double size, int max switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerreGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerreGeneralized8.java index 10655274f..23c390c07 100644 --- a/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerreGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerreGeneralized8.java @@ -37,18 +37,13 @@ public LaguerreGeneralized8(double xCenter, double yCenter, double size, int max switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerrePoly.java b/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerrePoly.java index 72b48ce21..9a531682e 100644 --- a/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerrePoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerrePoly.java @@ -59,18 +59,13 @@ public LaguerrePoly(double xCenter, double yCenter, double size, int max_iterati switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerreSin.java b/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerreSin.java index d63728f8e..d3caef4c6 100644 --- a/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerreSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/laguerre/LaguerreSin.java @@ -33,20 +33,18 @@ public class LaguerreSin extends LaguerreRootFindingMethod { public LaguerreSin(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, new double[] {50, 0}, ots); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/maheshweri/Maheshweri3.java b/src/fractalzoomer/functions/root_finding_methods/maheshweri/Maheshweri3.java index 53bc46ac5..3d6a9005e 100644 --- a/src/fractalzoomer/functions/root_finding_methods/maheshweri/Maheshweri3.java +++ b/src/fractalzoomer/functions/root_finding_methods/maheshweri/Maheshweri3.java @@ -14,14 +14,13 @@ public Maheshweri3(double xCenter, double yCenter, double size, int max_iteratio super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/maheshweri/Maheshweri4.java b/src/fractalzoomer/functions/root_finding_methods/maheshweri/Maheshweri4.java index ba25b70bb..00cdd4e23 100644 --- a/src/fractalzoomer/functions/root_finding_methods/maheshweri/Maheshweri4.java +++ b/src/fractalzoomer/functions/root_finding_methods/maheshweri/Maheshweri4.java @@ -14,14 +14,13 @@ public Maheshweri4(double xCenter, double yCenter, double size, int max_iteratio super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriCos.java b/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriCos.java index cdac9a8ee..0cb40d010 100644 --- a/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriCos.java @@ -14,14 +14,13 @@ public MaheshweriCos(double xCenter, double yCenter, double size, int max_iterat super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriFormula.java b/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriFormula.java index fdab8fff1..f9c57baf4 100644 --- a/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriFormula.java @@ -26,15 +26,10 @@ public MaheshweriFormula(double xCenter, double yCenter, double size, int max_it switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriGeneralized3.java index 50d9292e8..5b911ef52 100644 --- a/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriGeneralized3.java @@ -14,14 +14,13 @@ public MaheshweriGeneralized3(double xCenter, double yCenter, double size, int m super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriGeneralized8.java index 99e06e918..cf45d72c4 100644 --- a/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriGeneralized8.java @@ -14,14 +14,13 @@ public MaheshweriGeneralized8(double xCenter, double yCenter, double size, int m super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriPoly.java b/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriPoly.java index 037004f88..8e4b8dbd2 100644 --- a/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriPoly.java @@ -36,14 +36,13 @@ public MaheshweriPoly(double xCenter, double yCenter, double size, int max_itera } switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriRootFindingMethod.java b/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriRootFindingMethod.java index 000c7414f..3254eb1d7 100644 --- a/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriRootFindingMethod.java +++ b/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriRootFindingMethod.java @@ -11,7 +11,7 @@ public abstract class MaheshweriRootFindingMethod extends RootFindingMethods { public MaheshweriRootFindingMethod(double xCenter, double yCenter, double size, int max_iterations, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, OrbitTrapSettings ots) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - convergent_bailout = 1e-8; + setConvergentBailout(1e-8); } //orbit diff --git a/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriSin.java b/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriSin.java index 2788659de..eab0d73d2 100644 --- a/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/maheshweri/MaheshweriSin.java @@ -14,14 +14,13 @@ public MaheshweriSin(double xCenter, double yCenter, double size, int max_iterat super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/midpoint/Midpoint3.java b/src/fractalzoomer/functions/root_finding_methods/midpoint/Midpoint3.java index 9ac572bc1..ab1be8e7e 100644 --- a/src/fractalzoomer/functions/root_finding_methods/midpoint/Midpoint3.java +++ b/src/fractalzoomer/functions/root_finding_methods/midpoint/Midpoint3.java @@ -16,16 +16,12 @@ public Midpoint3(double xCenter, double yCenter, double size, int max_iterations switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/midpoint/Midpoint4.java b/src/fractalzoomer/functions/root_finding_methods/midpoint/Midpoint4.java index 8a3a48beb..3d1833fc6 100644 --- a/src/fractalzoomer/functions/root_finding_methods/midpoint/Midpoint4.java +++ b/src/fractalzoomer/functions/root_finding_methods/midpoint/Midpoint4.java @@ -16,16 +16,12 @@ public Midpoint4(double xCenter, double yCenter, double size, int max_iterations switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointCos.java b/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointCos.java index 645a1529c..e1476559e 100644 --- a/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointCos.java @@ -16,16 +16,12 @@ public MidpointCos(double xCenter, double yCenter, double size, int max_iteratio switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointFormula.java b/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointFormula.java index e8d0fdd8d..dbcd65aa6 100644 --- a/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointFormula.java @@ -26,15 +26,10 @@ public MidpointFormula(double xCenter, double yCenter, double size, int max_iter switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointGeneralized3.java index c0a314126..43aa1f4cb 100644 --- a/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointGeneralized3.java @@ -16,16 +16,12 @@ public MidpointGeneralized3(double xCenter, double yCenter, double size, int max switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointGeneralized8.java index 69e2087f6..64404c417 100644 --- a/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointGeneralized8.java @@ -16,16 +16,12 @@ public MidpointGeneralized8(double xCenter, double yCenter, double size, int max switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointPoly.java b/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointPoly.java index 76ac173d7..0cd10714b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointPoly.java @@ -38,18 +38,13 @@ public MidpointPoly(double xCenter, double yCenter, double size, int max_iterati switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointSin.java b/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointSin.java index 712595ca8..05f0be101 100644 --- a/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/midpoint/MidpointSin.java @@ -16,16 +16,12 @@ public MidpointSin(double xCenter, double yCenter, double size, int max_iteratio switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/muller/Muller3.java b/src/fractalzoomer/functions/root_finding_methods/muller/Muller3.java index 9b1cd6218..0d73dbc13 100644 --- a/src/fractalzoomer/functions/root_finding_methods/muller/Muller3.java +++ b/src/fractalzoomer/functions/root_finding_methods/muller/Muller3.java @@ -34,17 +34,11 @@ public Muller3(double xCenter, double yCenter, double size, int max_iterations, super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { - case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/muller/Muller4.java b/src/fractalzoomer/functions/root_finding_methods/muller/Muller4.java index 598abebaf..28b63fe0f 100644 --- a/src/fractalzoomer/functions/root_finding_methods/muller/Muller4.java +++ b/src/fractalzoomer/functions/root_finding_methods/muller/Muller4.java @@ -34,17 +34,11 @@ public Muller4(double xCenter, double yCenter, double size, int max_iterations, super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { - case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/muller/MullerCos.java b/src/fractalzoomer/functions/root_finding_methods/muller/MullerCos.java index ee023ebf8..99fee9bd7 100644 --- a/src/fractalzoomer/functions/root_finding_methods/muller/MullerCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/muller/MullerCos.java @@ -34,17 +34,11 @@ public MullerCos(double xCenter, double yCenter, double size, int max_iterations super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { - case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/muller/MullerFormula.java b/src/fractalzoomer/functions/root_finding_methods/muller/MullerFormula.java index 6446702e9..bbb830dee 100644 --- a/src/fractalzoomer/functions/root_finding_methods/muller/MullerFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/muller/MullerFormula.java @@ -41,17 +41,11 @@ public MullerFormula(double xCenter, double yCenter, double size, int max_iterat super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { - case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/muller/MullerGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/muller/MullerGeneralized3.java index 88b1dc225..8c429b4cc 100644 --- a/src/fractalzoomer/functions/root_finding_methods/muller/MullerGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/muller/MullerGeneralized3.java @@ -34,17 +34,11 @@ public MullerGeneralized3(double xCenter, double yCenter, double size, int max_i super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { - case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/muller/MullerGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/muller/MullerGeneralized8.java index 739e3fafc..ce7f3ebe4 100644 --- a/src/fractalzoomer/functions/root_finding_methods/muller/MullerGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/muller/MullerGeneralized8.java @@ -34,17 +34,11 @@ public MullerGeneralized8(double xCenter, double yCenter, double size, int max_i super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { - case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/muller/MullerPoly.java b/src/fractalzoomer/functions/root_finding_methods/muller/MullerPoly.java index faa502509..dbfbae0a9 100644 --- a/src/fractalzoomer/functions/root_finding_methods/muller/MullerPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/muller/MullerPoly.java @@ -55,17 +55,11 @@ public MullerPoly(double xCenter, double yCenter, double size, int max_iteration } switch (out_coloring_algorithm) { - case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/muller/MullerSin.java b/src/fractalzoomer/functions/root_finding_methods/muller/MullerSin.java index 973513302..8a5c9006c 100644 --- a/src/fractalzoomer/functions/root_finding_methods/muller/MullerSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/muller/MullerSin.java @@ -34,17 +34,11 @@ public MullerSin(double xCenter, double yCenter, double size, int max_iterations super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { - case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/nedzhibov/Nedzhibov3.java b/src/fractalzoomer/functions/root_finding_methods/nedzhibov/Nedzhibov3.java index 8277b10ea..9fcd54637 100644 --- a/src/fractalzoomer/functions/root_finding_methods/nedzhibov/Nedzhibov3.java +++ b/src/fractalzoomer/functions/root_finding_methods/nedzhibov/Nedzhibov3.java @@ -16,16 +16,12 @@ public Nedzhibov3(double xCenter, double yCenter, double size, int max_iteration switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/nedzhibov/Nedzhibov4.java b/src/fractalzoomer/functions/root_finding_methods/nedzhibov/Nedzhibov4.java index 3db0e04f2..4d3c9e6ab 100644 --- a/src/fractalzoomer/functions/root_finding_methods/nedzhibov/Nedzhibov4.java +++ b/src/fractalzoomer/functions/root_finding_methods/nedzhibov/Nedzhibov4.java @@ -16,16 +16,12 @@ public Nedzhibov4(double xCenter, double yCenter, double size, int max_iteration switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovCos.java b/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovCos.java index aa66c63b1..574a85a62 100644 --- a/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovCos.java @@ -16,16 +16,12 @@ public NedzhibovCos(double xCenter, double yCenter, double size, int max_iterati switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovFormula.java b/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovFormula.java index 48c39e759..6bb925dc5 100644 --- a/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovFormula.java @@ -26,15 +26,10 @@ public NedzhibovFormula(double xCenter, double yCenter, double size, int max_ite switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovGeneralized3.java index 505285935..004525fe6 100644 --- a/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovGeneralized3.java @@ -16,16 +16,12 @@ public NedzhibovGeneralized3(double xCenter, double yCenter, double size, int ma switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovGeneralized8.java index a6b954547..35249b067 100644 --- a/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovGeneralized8.java @@ -16,16 +16,12 @@ public NedzhibovGeneralized8(double xCenter, double yCenter, double size, int ma switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovPoly.java b/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovPoly.java index 4600a290b..045bc2a82 100644 --- a/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovPoly.java @@ -38,18 +38,13 @@ public NedzhibovPoly(double xCenter, double yCenter, double size, int max_iterat switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovSin.java b/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovSin.java index fa5a066c4..c673adf01 100644 --- a/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/nedzhibov/NedzhibovSin.java @@ -16,16 +16,12 @@ public NedzhibovSin(double xCenter, double yCenter, double size, int max_iterati switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/newton/Newton3.java b/src/fractalzoomer/functions/root_finding_methods/newton/Newton3.java index e95d9055c..05998d913 100644 --- a/src/fractalzoomer/functions/root_finding_methods/newton/Newton3.java +++ b/src/fractalzoomer/functions/root_finding_methods/newton/Newton3.java @@ -19,6 +19,7 @@ import fractalzoomer.core.*; import fractalzoomer.core.location.Location; +import fractalzoomer.fractal_options.initial_value.InitialValue; import fractalzoomer.main.Constants; import fractalzoomer.main.MainWindow; import fractalzoomer.main.app_settings.OrbitTrapSettings; @@ -27,6 +28,7 @@ import javax.swing.*; import java.util.ArrayList; +import java.util.function.Function; import static fractalzoomer.main.Constants.REFERENCE_CALCULATION_STR; @@ -42,19 +44,15 @@ public Newton3(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } - power = 3; - OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); InColoringAlgorithmFactory(in_coloring_algorithm, user_in_coloring_algorithm, incoloring_formula, user_incoloring_conditions, user_incoloring_condition_formula, plane_transform_center); @@ -62,6 +60,8 @@ public Newton3(double xCenter, double yCenter, double size, int max_iterations, if(sts.statistic) { StatisticFactory(sts, plane_transform_center); } + + defaultInitVal = new InitialValue(1, 0); } //orbit @@ -69,7 +69,7 @@ public Newton3(double xCenter, double yCenter, double size, int max_iterations, super(xCenter, yCenter, size, max_iterations, complex_orbit, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower); - power = 3; + defaultInitVal = new InitialValue(1, 0); } @@ -96,7 +96,7 @@ public Complex perturbationFunction(Complex z, int RefIteration) { Complex Z = getArrayValue(reference, RefIteration); Complex temp = Z.times2().plus_mutable(z).times_mutable(z).times_mutable(Z.square()); - return temp.plus(getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration)).sub_mutable(z.times(0.5)).times_mutable(z).divide_mutable(temp.plus(Z.fourth()).times_mutable(1.5)); + return temp.plus(getArrayValue(referenceData.PrecalculatedTerms[0], RefIteration, Z)).sub_mutable(z.times(0.5)).times_mutable(z).divide_mutable(temp.plus(Z.fourth()).times_mutable(1.5)); } @@ -106,7 +106,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, int RefIteration) { MantExpComplex Z = getArrayDeepValue(referenceDeep, RefIteration); MantExpComplex temp = Z.times2().plus_mutable(z).times_mutable(z).times_mutable(Z.square()); - return temp.plus(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration)).sub_mutable(z.divide2()).times_mutable(z).divide_mutable(temp.plus(Z.fourth()).times_mutable(MantExp.ONEPOINTFIVE)); + return temp.plus(getArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], RefIteration, Z)).sub_mutable(z.divide2()).times_mutable(z).divide_mutable(temp.plus(Z.fourth()).times_mutable(MantExp.ONEPOINTFIVE)); } @Override @@ -115,7 +115,7 @@ public Complex perturbationFunction(Complex z, ReferenceData data, int RefIterat Complex Z = getArrayValue(data.Reference, RefIteration); Complex temp = Z.times2().plus_mutable(z).times_mutable(z).times_mutable(Z.square()); - return temp.plus(getArrayValue(data.PrecalculatedTerms[0], RefIteration)).sub_mutable(z.times(0.5)).times_mutable(z).divide_mutable(temp.plus(Z.fourth()).times_mutable(1.5)); + return temp.plus(getArrayValue(data.PrecalculatedTerms[0], RefIteration, Z)).sub_mutable(z.times(0.5)).times_mutable(z).divide_mutable(temp.plus(Z.fourth()).times_mutable(1.5)); } @@ -125,7 +125,7 @@ public MantExpComplex perturbationFunction(MantExpComplex z, ReferenceDeepData d MantExpComplex Z = getArrayDeepValue(data.Reference, RefIteration); MantExpComplex temp = Z.times2().plus_mutable(z).times_mutable(z).times_mutable(Z.square()); - return temp.plus(getArrayDeepValue(data.PrecalculatedTerms[0], RefIteration)).sub_mutable(z.divide2()).times_mutable(z).divide_mutable(temp.plus(Z.fourth()).times_mutable(MantExp.ONEPOINTFIVE)); + return temp.plus(getArrayDeepValue(data.PrecalculatedTerms[0], RefIteration, Z)).sub_mutable(z.divide2()).times_mutable(z).divide_mutable(temp.plus(Z.fourth()).times_mutable(MantExp.ONEPOINTFIVE)); } @Override @@ -138,6 +138,23 @@ public void function(GenericComplex[] complex) { } } + @Override + protected int[] getNeededPrecalculatedTermsIndexes() { + return new int[] {0}; + } + + @Override + protected Function[] getPrecalculatedTermsFunctions(Complex c) { + Function f1 = x -> x.fourth().sub_mutable(x); + return new Function[] {f1}; + } + + @Override + protected Function[] getPrecalculatedTermsFunctionsDeep(MantExpComplex c) { + Function f1 = x -> x.fourth().sub_mutable(x); + return new Function[] {f1}; + } + @Override public void calculateReferencePoint(GenericComplex inputPixel, Apfloat size, boolean deepZoom, int[] Iterations, int[] juliaIterations, Location externalLocation, JProgressBar progress) { @@ -159,17 +176,19 @@ public void calculateReferencePoint(GenericComplex inputPixel, Apfloat size, boo boolean lowPrecReferenceOrbitNeeded = !needsOnlyExtendedReferenceOrbit(deepZoom, false); DoubleReference.SHOULD_SAVE_MEMORY = false; + boolean useCompressedRef = TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE && supportsReferenceCompression(); + int[] preCalcIndexes = getNeededPrecalculatedTermsIndexes(); if(iterations == 0) { if(lowPrecReferenceOrbitNeeded) { - referenceData.createAndSetShortcut(max_ref_iterations,true, 1); + referenceData.createAndSetShortcut(max_ref_iterations,true, preCalcIndexes, useCompressedRef); } else { referenceData.deallocate(); } if (deepZoom) { - referenceDeepData.createAndSetShortcut(max_ref_iterations,true, 1); + referenceDeepData.createAndSetShortcut(max_ref_iterations,true, preCalcIndexes, useCompressedRef); } } else if (max_ref_iterations > getReferenceLength()){ @@ -187,32 +206,14 @@ else if (max_ref_iterations > getReferenceLength()){ } //Due to zero, all around zero will not work - if(inputPixel instanceof BigComplex && ((BigComplex)inputPixel).norm().compareTo(new MyApfloat(1e-4)) < 0) { - inputPixel = new BigComplex(1e-4, 1e-4); - } - else if(inputPixel instanceof MpfrBigNumComplex && ((MpfrBigNumComplex)inputPixel).norm().compare(1e-4) < 0) { - inputPixel = new MpfrBigNumComplex(1e-4, 1e-4); - } - else if(inputPixel instanceof MpirBigNumComplex && ((MpirBigNumComplex)inputPixel).norm().compare(1e-4) < 0) { - inputPixel = new MpirBigNumComplex(1e-4, 1e-4); - } - else if(inputPixel instanceof DDComplex && ((DDComplex)inputPixel).norm().compareTo(new DoubleDouble(1e-4)) < 0) { - inputPixel = new DDComplex(1e-4, 1e-4); - } - else if(inputPixel instanceof BigIntNumComplex && ((BigIntNumComplex)inputPixel).norm().compare(new BigIntNum(1e-4)) < 0) { - inputPixel = new BigIntNumComplex(1e-4, 1e-4); - } - else if(inputPixel instanceof Complex && ((Complex)inputPixel).norm() < 1e-4) { - inputPixel = new Complex(1e-4, 1e-4); - } - + inputPixel = sanitizeInputPixel(inputPixel); int bigNumLib = TaskDraw.getBignumLibrary(size, this); GenericComplex z, zold, zold2, start, pixel, initVal; if(bigNumLib == Constants.BIGNUM_MPFR) { - initVal = new MpfrBigNumComplex(1, 0); + initVal = new MpfrBigNumComplex(defaultInitVal.getValue(null)); MpfrBigNumComplex bn = new MpfrBigNumComplex(inputPixel.toMpfrBigNumComplex()); z = iterations == 0 ? bn : referenceData.lastZValue; zold = iterations == 0 ? new MpfrBigNumComplex() : referenceData.secondTolastZValue; @@ -221,7 +222,7 @@ else if(inputPixel instanceof Complex && ((Complex)inputPixel).norm() < 1e-4) { pixel = new MpfrBigNumComplex(bn); } else if(bigNumLib == Constants.BIGNUM_MPIR) { - initVal = new MpirBigNumComplex(1, 0); + initVal = new MpirBigNumComplex(defaultInitVal.getValue(null)); MpirBigNumComplex bn = new MpirBigNumComplex(inputPixel.toMpirBigNumComplex()); z = iterations == 0 ? bn : referenceData.lastZValue; zold = iterations == 0 ? new MpirBigNumComplex() : referenceData.secondTolastZValue; @@ -230,7 +231,7 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { pixel = new MpirBigNumComplex(bn); } else if(bigNumLib == Constants.BIGNUM_DOUBLEDOUBLE) { - initVal = new DDComplex(1, 0); + initVal = new DDComplex(defaultInitVal.getValue(null)); DDComplex ddn = inputPixel.toDDComplex(); z = iterations == 0 ? ddn : referenceData.lastZValue; zold = iterations == 0 ? new DDComplex() : referenceData.secondTolastZValue; @@ -239,7 +240,7 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLEDOUBLE) { pixel = ddn; } else if(bigNumLib == Constants.BIGNUM_BIGINT) { - initVal = new BigIntNumComplex(1, 0); + initVal = new BigIntNumComplex(defaultInitVal.getValue(null)); BigIntNumComplex bin = inputPixel.toBigIntNumComplex(); z = iterations == 0 ? bin : referenceData.lastZValue; zold = iterations == 0 ? new BigIntNumComplex() : referenceData.secondTolastZValue; @@ -248,7 +249,7 @@ else if(bigNumLib == Constants.BIGNUM_BIGINT) { pixel = bin; } else if(bigNumLib == Constants.BIGNUM_DOUBLE) { - initVal = new Complex(1, 0); + initVal = new Complex(defaultInitVal.getValue(null)); Complex bn = inputPixel.toComplex(); z = iterations == 0 ? bn : referenceData.lastZValue; zold = iterations == 0 ? new Complex() : referenceData.secondTolastZValue; @@ -257,7 +258,7 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { pixel = new Complex(bn); } else { - initVal = new BigComplex(1, 0); + initVal = new BigComplex(defaultInitVal.getValue(null)); z = iterations == 0 ? inputPixel : referenceData.lastZValue; zold = iterations == 0 ? new BigComplex() : referenceData.secondTolastZValue; zold2 = iterations == 0 ? new BigComplex() : referenceData.thirdTolastZValue; @@ -269,28 +270,67 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { refPoint = inputPixel; - refPointSmall = refPoint.toComplex(); - if(deepZoom) { refPointSmallDeep = loc.getMantExpComplex(refPoint); + refPointSmall = refPointSmallDeep.toComplex(); + + seedSmallDeep = MantExpComplex.create(); + + if(lowPrecReferenceOrbitNeeded) { + seedSmall = new Complex(); + } + } + else { + refPointSmall = refPoint.toComplex(); + + if(lowPrecReferenceOrbitNeeded) { + seedSmall = new Complex(); + } } RefType = getRefType(); convergent_bailout_algorithm.setReferenceMode(true); - calculatedReferenceIterations = 0; - - for (; iterations < max_ref_iterations; iterations++, calculatedReferenceIterations++) { - + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[referenceDeep.id] = new ReferenceCompressor(this, iterations == 0 ? z.toMantExpComplex() : referenceData.compressorZm, MantExpComplex.create(), start.toMantExpComplex()); + + MantExpComplex cp = initVal.toMantExpComplex(); + Function f = x -> x.sub(cp); + functions[referenceDeepData.ReferenceSubCp.id] = f; + subexpressionsCompressor[referenceDeepData.ReferenceSubCp.id] = new ReferenceCompressor(f, true); + + Function[] fs = getPrecalculatedTermsFunctionsDeep(null); + for(int i = 0; i < preCalcIndexes.length; i++) { + int id = referenceDeepData.PrecalculatedTerms[preCalcIndexes[i]].id; + functions[id] = fs[i]; + subexpressionsCompressor[id] = new ReferenceCompressor(fs[i], true); + } + } if(lowPrecReferenceOrbitNeeded) { - Complex cz = z.toComplex(); - if (cz.isInfinite()) { - break; + referenceCompressor[reference.id] = new ReferenceCompressor(this, iterations == 0 ? z.toComplex() : referenceData.compressorZ, new Complex(), start.toComplex()); + + Complex cp = initVal.toComplex(); + Function f = x -> x.sub(cp); + functions[referenceData.ReferenceSubCp.id] = f; + subexpressionsCompressor[referenceData.ReferenceSubCp.id] = new ReferenceCompressor(f); + + Function[] fs = getPrecalculatedTermsFunctions(null); + for(int i = 0; i < preCalcIndexes.length; i++) { + int id = referenceData.PrecalculatedTerms[preCalcIndexes[i]].id; + functions[id] = fs[i]; + subexpressionsCompressor[id] = new ReferenceCompressor(fs[i]); } - - setArrayValue(reference, iterations, cz); } + } + + calculatedReferenceIterations = 0; + + MantExpComplex tempmcz = null; + Complex cz = null; + + for (; iterations < max_ref_iterations; iterations++, calculatedReferenceIterations++) { GenericComplex zsubcp; if(bigNumLib == Constants.BIGNUM_MPFR) { @@ -303,13 +343,6 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { zsubcp = z.sub(initVal); } - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.ReferenceSubCp, iterations, zsubcp.toComplex()); - } - if(deepZoom) { - setArrayDeepValue(referenceDeepData.ReferenceSubCp, iterations, loc.getMantExpComplex(zsubcp)); - } - GenericComplex zcubes1; if(bigNumLib != Constants.BIGNUM_APFLOAT) { @@ -322,13 +355,39 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { GenericComplex preCalc; preCalc = zcubes1.times(z); //Z^4-Z for catastrophic cancelation + MantExpComplex czm = null; + MantExpComplex precalcM = null; + MantExpComplex zsubcpm = null; + + if(deepZoom) { + czm = loc.getMantExpComplex(z); + if (czm.isInfinite() || czm.isNaN()) { + break; + } + tempmcz = setArrayDeepValue(referenceDeep, iterations, czm); + } + if(lowPrecReferenceOrbitNeeded) { - setArrayValue(referenceData.PrecalculatedTerms[0], iterations, preCalc.toComplex()); + cz = deepZoom ? czm.toComplex() : z.toComplex(); + if (cz.isInfinite() || cz.isNaN()) { + break; + } + + cz = setArrayValue(reference, iterations, cz); } + czm = tempmcz; + if(deepZoom) { - setArrayDeepValue(referenceDeep, iterations, loc.getMantExpComplex(z)); - setArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], iterations, loc.getMantExpComplex(preCalc)); + precalcM = loc.getMantExpComplex(preCalc); + zsubcpm = loc.getMantExpComplex(zsubcp); + setArrayDeepValue(referenceDeepData.PrecalculatedTerms[0], iterations, precalcM, czm); + setArrayDeepValue(referenceDeepData.ReferenceSubCp, iterations, zsubcpm, czm); + } + + if(lowPrecReferenceOrbitNeeded) { + setArrayValue(referenceData.PrecalculatedTerms[0], iterations, deepZoom ? precalcM.toComplex() : preCalc.toComplex(), cz); + setArrayValue(referenceData.ReferenceSubCp, iterations, deepZoom ? zsubcpm.toComplex() : zsubcp.toComplex(), cz); } if (iterations > 0 && convergent_bailout_algorithm.Converged(z, zold, zold2, iterations, pixel, start, pixel, pixel)) { @@ -365,6 +424,30 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { referenceData.MaxRefIteration = iterations - 1; + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[referenceDeep.id].compact(referenceDeep); + referenceData.compressorZm = referenceCompressor[referenceDeep.id].getZDeep(); + + subexpressionsCompressor[referenceDeepData.ReferenceSubCp.id].compact(referenceDeepData.ReferenceSubCp); + + for(int i = 0; i < preCalcIndexes.length; i++) { + subexpressionsCompressor[referenceDeepData.PrecalculatedTerms[preCalcIndexes[i]].id].compact(referenceDeepData.PrecalculatedTerms[preCalcIndexes[i]]); + } + } + + if(lowPrecReferenceOrbitNeeded) { + referenceCompressor[reference.id].compact(reference); + referenceData.compressorZ = referenceCompressor[reference.id].getZ(); + + subexpressionsCompressor[referenceData.ReferenceSubCp.id].compact(referenceData.ReferenceSubCp); + + for(int i = 0; i < preCalcIndexes.length; i++) { + subexpressionsCompressor[referenceData.PrecalculatedTerms[preCalcIndexes[i]].id].compact(referenceData.PrecalculatedTerms[preCalcIndexes[i]]); + } + } + } + SAskippedIterations = 0; if(progress != null) { @@ -399,17 +482,19 @@ protected void calculateSecondReferencePoint(GenericComplex inputPixel, Apfloat } boolean lowPrecReferenceOrbitNeeded = !needsOnlyExtendedReferenceOrbit(deepZoom, false); + boolean useCompressedRef = TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE && supportsReferenceCompression(); + int[] preCalcIndexes = getNeededPrecalculatedTermsIndexes(); if (iterations == 0) { if(lowPrecReferenceOrbitNeeded) { - secondReferenceData.create(max_ref_iterations,true, 1); + secondReferenceData.create(max_ref_iterations,true, preCalcIndexes, useCompressedRef); } else { secondReferenceData.deallocate(); } if (deepZoom) { - secondReferenceDeepData.create(max_ref_iterations,true, 1); + secondReferenceDeepData.create(max_ref_iterations,true, preCalcIndexes, useCompressedRef); } } else if (max_ref_iterations > getSecondReferenceLength()) { if(lowPrecReferenceOrbitNeeded) { @@ -426,12 +511,12 @@ protected void calculateSecondReferencePoint(GenericComplex inputPixel, Apfloat Location loc = new Location(); - GenericComplex z, c, zold, zold2, start, c0, pixel, initVal; + GenericComplex z, zold, zold2, start, pixel, initVal; int bigNumLib = TaskDraw.getBignumLibrary(size, this); if(bigNumLib == Constants.BIGNUM_MPFR) { - initVal = new MpfrBigNumComplex(1, 0); + initVal = new MpfrBigNumComplex(defaultInitVal.getValue(null)); MpfrBigNumComplex bn = new MpfrBigNumComplex(inputPixel.toMpfrBigNumComplex()); z = iterations == 0 ? initVal : secondReferenceData.lastZValue; zold = iterations == 0 ? new MpfrBigNumComplex() : secondReferenceData.secondTolastZValue; @@ -440,7 +525,7 @@ protected void calculateSecondReferencePoint(GenericComplex inputPixel, Apfloat pixel = new MpfrBigNumComplex(bn); } else if(bigNumLib == Constants.BIGNUM_MPIR) { - initVal = new MpirBigNumComplex(1, 0); + initVal = new MpirBigNumComplex(defaultInitVal.getValue(null)); MpirBigNumComplex bn = new MpirBigNumComplex(inputPixel.toMpirBigNumComplex()); z = iterations == 0 ? initVal : secondReferenceData.lastZValue; zold = iterations == 0 ? new MpirBigNumComplex() : secondReferenceData.secondTolastZValue; @@ -449,7 +534,7 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { pixel = new MpirBigNumComplex(bn); } else if(bigNumLib == Constants.BIGNUM_DOUBLEDOUBLE) { - initVal = new DDComplex(1, 0); + initVal = new DDComplex(defaultInitVal.getValue(null)); DDComplex ddn = inputPixel.toDDComplex(); z = iterations == 0 ? initVal : secondReferenceData.lastZValue; zold = iterations == 0 ? new DDComplex() : secondReferenceData.secondTolastZValue; @@ -458,7 +543,7 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLEDOUBLE) { pixel = ddn; } else if(bigNumLib == Constants.BIGNUM_BIGINT) { - initVal = new BigIntNumComplex(1, 0); + initVal = new BigIntNumComplex(defaultInitVal.getValue(null)); BigIntNumComplex bin = inputPixel.toBigIntNumComplex(); z = iterations == 0 ? initVal : secondReferenceData.lastZValue; zold = iterations == 0 ? new BigIntNumComplex() : secondReferenceData.secondTolastZValue; @@ -467,7 +552,7 @@ else if(bigNumLib == Constants.BIGNUM_BIGINT) { pixel = bin; } else if(bigNumLib == Constants.BIGNUM_DOUBLE) { - initVal = new Complex(1, 0); + initVal = new Complex(defaultInitVal.getValue(null)); Complex bn = inputPixel.toComplex(); z = iterations == 0 ? initVal : secondReferenceData.lastZValue; zold = iterations == 0 ? new Complex() : secondReferenceData.secondTolastZValue; @@ -476,7 +561,7 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { pixel = new Complex(bn); } else { - initVal = new BigComplex(1, 0); + initVal = new BigComplex(defaultInitVal.getValue(null)); z = iterations == 0 ? initVal : secondReferenceData.lastZValue; zold = iterations == 0 ? new BigComplex() : secondReferenceData.secondTolastZValue; zold2 = iterations == 0 ? new BigComplex() : secondReferenceData.thirdTolastZValue; @@ -484,19 +569,45 @@ else if(bigNumLib == Constants.BIGNUM_DOUBLE) { pixel = inputPixel; } + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[secondReferenceDeepData.Reference.id] = new ReferenceCompressor(this, iterations == 0 ? z.toMantExpComplex() : secondReferenceData.compressorZm, MantExpComplex.create(), start.toMantExpComplex()); + + MantExpComplex cp = initVal.toMantExpComplex(); + Function f = x -> x.sub(cp); + functions[secondReferenceDeepData.ReferenceSubCp.id] = f; + subexpressionsCompressor[secondReferenceDeepData.ReferenceSubCp.id] = new ReferenceCompressor(f, true); + + Function[] fs = getPrecalculatedTermsFunctionsDeep(null); + for(int i = 0; i < preCalcIndexes.length; i++) { + int id = secondReferenceDeepData.PrecalculatedTerms[preCalcIndexes[i]].id; + functions[id] = fs[i]; + subexpressionsCompressor[id] = new ReferenceCompressor(fs[i], true); + } + } + if(lowPrecReferenceOrbitNeeded) { + referenceCompressor[secondReferenceData.Reference.id] = new ReferenceCompressor(this, iterations == 0 ? z.toComplex() : secondReferenceData.compressorZ, new Complex(), start.toComplex()); + + Complex cp = initVal.toComplex(); + Function f = x -> x.sub(cp); + functions[secondReferenceData.ReferenceSubCp.id] = f; + subexpressionsCompressor[secondReferenceData.ReferenceSubCp.id] = new ReferenceCompressor(f); + + Function[] fs = getPrecalculatedTermsFunctions(null); + for(int i = 0; i < preCalcIndexes.length; i++) { + int id = secondReferenceData.PrecalculatedTerms[preCalcIndexes[i]].id; + functions[id] = fs[i]; + subexpressionsCompressor[id] = new ReferenceCompressor(fs[i]); + } + } + } convergent_bailout_algorithm.setReferenceMode(true); - for (; iterations < max_ref_iterations; iterations++) { - - if(lowPrecReferenceOrbitNeeded) { - Complex cz = z.toComplex(); - if (cz.isInfinite()) { - break; - } + MantExpComplex tempmcz = null; + Complex cz = null; - setArrayValue(secondReferenceData.Reference, iterations, cz); - } + for (; iterations < max_ref_iterations; iterations++) { GenericComplex zsubcp; if(bigNumLib == Constants.BIGNUM_MPFR) { @@ -509,13 +620,6 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { zsubcp = z.sub(initVal); } - if(lowPrecReferenceOrbitNeeded) { - setArrayValue(secondReferenceData.ReferenceSubCp, iterations, zsubcp.toComplex()); - } - if(deepZoom) { - setArrayDeepValue(secondReferenceDeepData.ReferenceSubCp, iterations, loc.getMantExpComplex(zsubcp)); - } - GenericComplex zcubes1; if(bigNumLib != Constants.BIGNUM_APFLOAT) { @@ -528,15 +632,41 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { GenericComplex preCalc; preCalc = zcubes1.times(z); //Z^4-Z for catastrophic cancelation + MantExpComplex czm = null; + MantExpComplex precalcm = null; + MantExpComplex zsubcpm = null; + if(deepZoom) { + czm = loc.getMantExpComplex(z); + if (czm.isInfinite() || czm.isNaN()) { + break; + } + tempmcz = setArrayDeepValue(secondReferenceDeepData.Reference, iterations, czm); + } + if(lowPrecReferenceOrbitNeeded) { - setArrayValue(secondReferenceData.PrecalculatedTerms[0], iterations, preCalc.toComplex()); + cz = deepZoom ? czm.toComplex() : z.toComplex(); + if (cz.isInfinite() || cz.isNaN()) { + break; + } + + cz = setArrayValue(secondReferenceData.Reference, iterations, cz); } + czm = tempmcz; + if(deepZoom) { - setArrayDeepValue(secondReferenceDeepData.Reference, iterations, loc.getMantExpComplex(z)); - setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[0], iterations, loc.getMantExpComplex(preCalc)); + precalcm = loc.getMantExpComplex(preCalc); + zsubcpm = loc.getMantExpComplex(zsubcp); + setArrayDeepValue(secondReferenceDeepData.PrecalculatedTerms[0], iterations, precalcm, czm); + setArrayDeepValue(secondReferenceDeepData.ReferenceSubCp, iterations, zsubcpm, czm); } + if(lowPrecReferenceOrbitNeeded) { + setArrayValue(secondReferenceData.PrecalculatedTerms[0], iterations, deepZoom ? precalcm.toComplex() : preCalc.toComplex(), cz); + setArrayValue(secondReferenceData.ReferenceSubCp, iterations, deepZoom ? zsubcpm.toComplex() : zsubcp.toComplex(), cz); + } + + if (iterations > 0 && convergent_bailout_algorithm.Converged(z, zold, zold2, iterations, pixel, start, pixel, pixel)) { break; } @@ -571,6 +701,30 @@ else if(bigNumLib == Constants.BIGNUM_MPIR) { secondReferenceData.MaxRefIteration = iterations - 1; + if(useCompressedRef) { + if(deepZoom) { + referenceCompressor[secondReferenceDeepData.Reference.id].compact(secondReferenceDeepData.Reference); + secondReferenceData.compressorZm = referenceCompressor[secondReferenceDeepData.Reference.id].getZDeep(); + + subexpressionsCompressor[secondReferenceDeepData.ReferenceSubCp.id].compact(secondReferenceDeepData.ReferenceSubCp); + + for(int i = 0; i < preCalcIndexes.length; i++) { + subexpressionsCompressor[secondReferenceDeepData.PrecalculatedTerms[preCalcIndexes[i]].id].compact(secondReferenceDeepData.PrecalculatedTerms[preCalcIndexes[i]]); + } + } + + if(lowPrecReferenceOrbitNeeded) { + referenceCompressor[secondReferenceData.Reference.id].compact(secondReferenceData.Reference); + secondReferenceData.compressorZ = referenceCompressor[secondReferenceData.Reference.id].getZ(); + + subexpressionsCompressor[secondReferenceData.ReferenceSubCp.id].compact(secondReferenceData.ReferenceSubCp); + + for(int i = 0; i < preCalcIndexes.length; i++) { + subexpressionsCompressor[secondReferenceData.PrecalculatedTerms[preCalcIndexes[i]].id].compact(secondReferenceData.PrecalculatedTerms[preCalcIndexes[i]]); + } + } + } + if(progress != null) { progress.setValue(progress.getMaximum()); progress.setString(REFERENCE_CALCULATION_STR + " 100%"); @@ -606,7 +760,7 @@ public double getDoubleDoubleLimit() { return super.getDoubleDoubleLimit(); } - return 1.0e-20; + return 1.0e-18; } @Override @@ -619,4 +773,28 @@ public boolean supportsBigIntnum() { return true; } + @Override + public boolean supportsReferenceCompression() { + return true; + } + + @Override + public Complex function(Complex z, Complex c) { + return z.sub_mutable(z.cube().sub_mutable(1).divide_mutable(z.square().times_mutable(3))); + } + + @Override + public MantExpComplex function(MantExpComplex z, MantExpComplex c) { + return z.sub_mutable(z.cube().sub_mutable(MantExp.ONE).divide_mutable(z.square().times_mutable(MantExp.THREE))); + } + + @Override + protected boolean needsRefSubCp() { + return true; + } + + @Override + public double getPower() { + return 3; + } } diff --git a/src/fractalzoomer/functions/root_finding_methods/newton/Newton4.java b/src/fractalzoomer/functions/root_finding_methods/newton/Newton4.java index 68c5e6967..305cf703e 100644 --- a/src/fractalzoomer/functions/root_finding_methods/newton/Newton4.java +++ b/src/fractalzoomer/functions/root_finding_methods/newton/Newton4.java @@ -37,13 +37,11 @@ public Newton4(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; - break; + setConvergentBailout(1E-9); + break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/newton/NewtonCos.java b/src/fractalzoomer/functions/root_finding_methods/newton/NewtonCos.java index d166b8822..510919d8d 100644 --- a/src/fractalzoomer/functions/root_finding_methods/newton/NewtonCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/newton/NewtonCos.java @@ -37,13 +37,13 @@ public NewtonCos(double xCenter, double yCenter, double size, int max_iterations switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/newton/NewtonFormula.java b/src/fractalzoomer/functions/root_finding_methods/newton/NewtonFormula.java index 1a9e82fc7..c1b8ff652 100644 --- a/src/fractalzoomer/functions/root_finding_methods/newton/NewtonFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/newton/NewtonFormula.java @@ -44,17 +44,11 @@ public NewtonFormula(double xCenter, double yCenter, double size, int max_iterat super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { - case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/newton/NewtonGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/newton/NewtonGeneralized3.java index 870bb62d9..b19596bb5 100644 --- a/src/fractalzoomer/functions/root_finding_methods/newton/NewtonGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/newton/NewtonGeneralized3.java @@ -37,13 +37,11 @@ public NewtonGeneralized3(double xCenter, double yCenter, double size, int max_i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; - break; + setConvergentBailout(1E-9); + break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/newton/NewtonGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/newton/NewtonGeneralized8.java index eddc9a588..194ddf1de 100644 --- a/src/fractalzoomer/functions/root_finding_methods/newton/NewtonGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/newton/NewtonGeneralized8.java @@ -37,13 +37,11 @@ public NewtonGeneralized8(double xCenter, double yCenter, double size, int max_i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/newton/NewtonPoly.java b/src/fractalzoomer/functions/root_finding_methods/newton/NewtonPoly.java index 81ac67ae9..0967818df 100644 --- a/src/fractalzoomer/functions/root_finding_methods/newton/NewtonPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/newton/NewtonPoly.java @@ -59,13 +59,11 @@ public NewtonPoly(double xCenter, double yCenter, double size, int max_iteration switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; - break; + setConvergentBailout(1E-9); + break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/newton/NewtonSin.java b/src/fractalzoomer/functions/root_finding_methods/newton/NewtonSin.java index 2f1849201..a0d29c5c6 100644 --- a/src/fractalzoomer/functions/root_finding_methods/newton/NewtonSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/newton/NewtonSin.java @@ -33,17 +33,17 @@ public class NewtonSin extends NewtonRootFindingMethod { public NewtonSin(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; + setConvergentBailout(1E-4); + break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHines3.java b/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHines3.java index fde610bb7..ea50b90b0 100644 --- a/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHines3.java +++ b/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHines3.java @@ -36,13 +36,11 @@ public NewtonHines3(double xCenter, double yCenter, double size, int max_iterati switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHines4.java b/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHines4.java index 68c9c68f6..39cc47367 100644 --- a/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHines4.java +++ b/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHines4.java @@ -35,15 +35,12 @@ public NewtonHines4(double xCenter, double yCenter, double size, int max_iterati super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { - case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; - break; + setConvergentBailout(1E-9); + break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesCos.java b/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesCos.java index a17277487..e324c9be9 100644 --- a/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesCos.java @@ -33,17 +33,17 @@ public class NewtonHinesCos extends NewtonHinesRootFindingMethod { public NewtonHinesCos(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; + setConvergentBailout(1E-4); + break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesFormula.java b/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesFormula.java index 24c56cc61..68b9bdc9a 100644 --- a/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesFormula.java @@ -46,15 +46,10 @@ public NewtonHinesFormula(double xCenter, double yCenter, double size, int max_i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesGeneralized3.java index 10481ac8f..4e39dca2e 100644 --- a/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesGeneralized3.java @@ -35,15 +35,12 @@ public NewtonHinesGeneralized3(double xCenter, double yCenter, double size, int super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { - case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; - break; + setConvergentBailout(1E-9); + break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesGeneralized8.java index 766d6bda9..3ec40dc6d 100644 --- a/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesGeneralized8.java @@ -35,15 +35,12 @@ public NewtonHinesGeneralized8(double xCenter, double yCenter, double size, int super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { - case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesPoly.java b/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesPoly.java index 851454919..87b72de16 100644 --- a/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesPoly.java @@ -57,15 +57,12 @@ public NewtonHinesPoly(double xCenter, double yCenter, double size, int max_iter } switch (out_coloring_algorithm) { - case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; - break; + setConvergentBailout(1E-9); + break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesSin.java b/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesSin.java index 3a337c55f..158cf0570 100644 --- a/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/newton_hines/NewtonHinesSin.java @@ -33,17 +33,17 @@ public class NewtonHinesSin extends NewtonHinesRootFindingMethod { public NewtonHinesSin(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; + setConvergentBailout(1E-4); + break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGupta3.java b/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGupta3.java index 71dafc7b2..217a69ce3 100644 --- a/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGupta3.java +++ b/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGupta3.java @@ -14,14 +14,13 @@ public NoorGupta3(double xCenter, double yCenter, double size, int max_iteration super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGupta4.java b/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGupta4.java index fa44c5f27..d1f9e11d8 100644 --- a/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGupta4.java +++ b/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGupta4.java @@ -14,14 +14,13 @@ public NoorGupta4(double xCenter, double yCenter, double size, int max_iteration super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaCos.java b/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaCos.java index 6699c41d9..e16e50f08 100644 --- a/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaCos.java @@ -14,14 +14,13 @@ public NoorGuptaCos(double xCenter, double yCenter, double size, int max_iterati super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaFormula.java b/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaFormula.java index 84c1c5ac2..bba9be3a6 100644 --- a/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaFormula.java @@ -26,15 +26,10 @@ public NoorGuptaFormula(double xCenter, double yCenter, double size, int max_ite switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaGeneralized3.java index de3430de0..4a268de18 100644 --- a/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaGeneralized3.java @@ -14,14 +14,13 @@ public NoorGuptaGeneralized3(double xCenter, double yCenter, double size, int ma super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaGeneralized8.java index 8c08a1199..35945e332 100644 --- a/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaGeneralized8.java @@ -14,14 +14,13 @@ public NoorGuptaGeneralized8(double xCenter, double yCenter, double size, int ma super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaPoly.java b/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaPoly.java index 4fa97cc18..b7eabbbb0 100644 --- a/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaPoly.java @@ -36,14 +36,13 @@ public NoorGuptaPoly(double xCenter, double yCenter, double size, int max_iterat } switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaSin.java b/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaSin.java index f8a5cb28a..173db9ef7 100644 --- a/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/noor_gupta/NoorGuptaSin.java @@ -14,14 +14,13 @@ public NoorGuptaSin(double xCenter, double yCenter, double size, int max_iterati super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/parhalley/Parhalley3.java b/src/fractalzoomer/functions/root_finding_methods/parhalley/Parhalley3.java index 6f1c08a47..be270882a 100644 --- a/src/fractalzoomer/functions/root_finding_methods/parhalley/Parhalley3.java +++ b/src/fractalzoomer/functions/root_finding_methods/parhalley/Parhalley3.java @@ -37,16 +37,12 @@ public Parhalley3(double xCenter, double yCenter, double size, int max_iteration switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/parhalley/Parhalley4.java b/src/fractalzoomer/functions/root_finding_methods/parhalley/Parhalley4.java index 73af29694..b4bed1abb 100644 --- a/src/fractalzoomer/functions/root_finding_methods/parhalley/Parhalley4.java +++ b/src/fractalzoomer/functions/root_finding_methods/parhalley/Parhalley4.java @@ -37,18 +37,13 @@ public Parhalley4(double xCenter, double yCenter, double size, int max_iteration switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleyCos.java b/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleyCos.java index 850b91270..b82a8aef6 100644 --- a/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleyCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleyCos.java @@ -33,20 +33,18 @@ public class ParhalleyCos extends ParhalleyRootFindingMethod { public ParhalleyCos(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleyFormula.java b/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleyFormula.java index 9b1e8c06c..61fcc0056 100644 --- a/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleyFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleyFormula.java @@ -48,15 +48,10 @@ public ParhalleyFormula(double xCenter, double yCenter, double size, int max_ite switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleyGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleyGeneralized3.java index fe3b9c110..fa785c24b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleyGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleyGeneralized3.java @@ -37,18 +37,13 @@ public ParhalleyGeneralized3(double xCenter, double yCenter, double size, int ma switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleyGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleyGeneralized8.java index c75de0513..14000abfc 100644 --- a/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleyGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleyGeneralized8.java @@ -37,18 +37,13 @@ public ParhalleyGeneralized8(double xCenter, double yCenter, double size, int ma switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleyPoly.java b/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleyPoly.java index 667625265..34e0882dd 100644 --- a/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleyPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleyPoly.java @@ -59,18 +59,13 @@ public ParhalleyPoly(double xCenter, double yCenter, double size, int max_iterat switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleySin.java b/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleySin.java index fe9a4afdc..585e11e69 100644 --- a/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleySin.java +++ b/src/fractalzoomer/functions/root_finding_methods/parhalley/ParhalleySin.java @@ -33,20 +33,18 @@ public class ParhalleySin extends ParhalleyRootFindingMethod { public ParhalleySin(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski13.java b/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski13.java index 48edf0f5b..edd4ee09f 100644 --- a/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski13.java +++ b/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski13.java @@ -37,18 +37,13 @@ public Popovski13(double xCenter, double yCenter, double size, int max_iteration switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski14.java b/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski14.java index 7d6c3ae61..531dfdf9b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski14.java +++ b/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski14.java @@ -37,18 +37,13 @@ public Popovski14(double xCenter, double yCenter, double size, int max_iteration switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Cos.java b/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Cos.java index ccfff9184..3d76cd175 100644 --- a/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Cos.java +++ b/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Cos.java @@ -33,20 +33,18 @@ public class Popovski1Cos extends Popovski1RootFindingMethod { public Popovski1Cos(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Formula.java b/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Formula.java index 7d3b97618..76d9cc16f 100644 --- a/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Formula.java +++ b/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Formula.java @@ -48,15 +48,10 @@ public Popovski1Formula(double xCenter, double yCenter, double size, int max_ite switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Generalized3.java b/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Generalized3.java index 0ba41c922..b386efbed 100644 --- a/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Generalized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Generalized3.java @@ -37,18 +37,13 @@ public Popovski1Generalized3(double xCenter, double yCenter, double size, int ma switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Generalized8.java b/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Generalized8.java index e0c2c5100..42e7e7edd 100644 --- a/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Generalized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Generalized8.java @@ -37,18 +37,13 @@ public Popovski1Generalized8(double xCenter, double yCenter, double size, int ma switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Poly.java b/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Poly.java index 70fa074d9..653b46a51 100644 --- a/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Poly.java +++ b/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Poly.java @@ -59,18 +59,13 @@ public Popovski1Poly(double xCenter, double yCenter, double size, int max_iterat switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Sin.java b/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Sin.java index 556800a32..9e9fc209b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Sin.java +++ b/src/fractalzoomer/functions/root_finding_methods/popovski1/Popovski1Sin.java @@ -33,20 +33,18 @@ public class Popovski1Sin extends Popovski1RootFindingMethod { public Popovski1Sin(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullah3.java b/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullah3.java index f7ebe5932..d9138ba20 100644 --- a/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullah3.java +++ b/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullah3.java @@ -16,16 +16,12 @@ public RafisRafiullah3(double xCenter, double yCenter, double size, int max_iter switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullah4.java b/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullah4.java index 9ad9e83d1..7e76a619a 100644 --- a/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullah4.java +++ b/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullah4.java @@ -16,16 +16,12 @@ public RafisRafiullah4(double xCenter, double yCenter, double size, int max_iter switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahCos.java b/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahCos.java index 639ea7530..2439b4e82 100644 --- a/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahCos.java @@ -16,16 +16,12 @@ public RafisRafiullahCos(double xCenter, double yCenter, double size, int max_it switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahFormula.java b/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahFormula.java index af46e2ee3..0ee8d1e2f 100644 --- a/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahFormula.java @@ -29,15 +29,10 @@ public RafisRafiullahFormula(double xCenter, double yCenter, double size, int ma switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahGeneralized3.java index ec5be469b..74d456d58 100644 --- a/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahGeneralized3.java @@ -16,16 +16,12 @@ public RafisRafiullahGeneralized3(double xCenter, double yCenter, double size, i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahGeneralized8.java index c61ae8e8a..918a475c6 100644 --- a/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahGeneralized8.java @@ -16,16 +16,12 @@ public RafisRafiullahGeneralized8(double xCenter, double yCenter, double size, i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahPoly.java b/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahPoly.java index 3e1bd430e..e9b36f2ea 100644 --- a/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahPoly.java @@ -38,18 +38,13 @@ public RafisRafiullahPoly(double xCenter, double yCenter, double size, int max_i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahSin.java b/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahSin.java index 3b33c2aec..cc5594d8e 100644 --- a/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/rafis_rafiullah/RafisRafiullahSin.java @@ -16,16 +16,12 @@ public RafisRafiullahSin(double xCenter, double yCenter, double size, int max_it switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah13.java b/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah13.java index dc2824d0c..ff4c4241b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah13.java +++ b/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah13.java @@ -16,16 +16,12 @@ public Rafiullah13(double xCenter, double yCenter, double size, int max_iteratio switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah14.java b/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah14.java index 0e3fe2764..a2f16ffec 100644 --- a/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah14.java +++ b/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah14.java @@ -16,16 +16,12 @@ public Rafiullah14(double xCenter, double yCenter, double size, int max_iteratio switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Cos.java b/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Cos.java index 04044b2b4..7456e7e4b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Cos.java +++ b/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Cos.java @@ -16,16 +16,12 @@ public Rafiullah1Cos(double xCenter, double yCenter, double size, int max_iterat switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Formula.java b/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Formula.java index de064b7fb..a3c1194e6 100644 --- a/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Formula.java +++ b/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Formula.java @@ -26,15 +26,10 @@ public Rafiullah1Formula(double xCenter, double yCenter, double size, int max_it switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Generalized3.java b/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Generalized3.java index 11d5ded76..0410cc8c4 100644 --- a/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Generalized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Generalized3.java @@ -16,16 +16,12 @@ public Rafiullah1Generalized3(double xCenter, double yCenter, double size, int m switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Generalized8.java b/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Generalized8.java index a8e6c2ed6..996261840 100644 --- a/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Generalized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Generalized8.java @@ -16,16 +16,12 @@ public Rafiullah1Generalized8(double xCenter, double yCenter, double size, int m switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Poly.java b/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Poly.java index a17fc671a..247b4ba6f 100644 --- a/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Poly.java +++ b/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Poly.java @@ -38,18 +38,13 @@ public Rafiullah1Poly(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Sin.java b/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Sin.java index 6f341005d..fd98efd8b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Sin.java +++ b/src/fractalzoomer/functions/root_finding_methods/rafiullah1/Rafiullah1Sin.java @@ -16,16 +16,12 @@ public Rafiullah1Sin(double xCenter, double yCenter, double size, int max_iterat switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/schroder/Schroder3.java b/src/fractalzoomer/functions/root_finding_methods/schroder/Schroder3.java index 749d98b78..60c9c97fd 100644 --- a/src/fractalzoomer/functions/root_finding_methods/schroder/Schroder3.java +++ b/src/fractalzoomer/functions/root_finding_methods/schroder/Schroder3.java @@ -37,13 +37,11 @@ public Schroder3(double xCenter, double yCenter, double size, int max_iterations switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-6; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-6; - break; + setConvergentBailout(1E-6); + break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/schroder/Schroder4.java b/src/fractalzoomer/functions/root_finding_methods/schroder/Schroder4.java index 899e778f0..6e7a0c67e 100644 --- a/src/fractalzoomer/functions/root_finding_methods/schroder/Schroder4.java +++ b/src/fractalzoomer/functions/root_finding_methods/schroder/Schroder4.java @@ -37,13 +37,11 @@ public Schroder4(double xCenter, double yCenter, double size, int max_iterations switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-6; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-6; - break; + setConvergentBailout(1E-6); + break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderCos.java b/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderCos.java index 18be99d1b..2afe88d4b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderCos.java @@ -33,17 +33,17 @@ public class SchroderCos extends SchroderRootFindingMethod { public SchroderCos(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-6; - break; + setConvergentBailout(1E-6); + break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderFormula.java b/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderFormula.java index b08d0aaab..b11341791 100644 --- a/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderFormula.java @@ -48,15 +48,10 @@ public SchroderFormula(double xCenter, double yCenter, double size, int max_iter switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderGeneralized3.java index 1221efe54..5745322ca 100644 --- a/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderGeneralized3.java @@ -37,13 +37,11 @@ public SchroderGeneralized3(double xCenter, double yCenter, double size, int max switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-6; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-6; - break; + setConvergentBailout(1E-6); + break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderGeneralized8.java index 195cfce2b..32e3b9e76 100644 --- a/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderGeneralized8.java @@ -37,13 +37,11 @@ public SchroderGeneralized8(double xCenter, double yCenter, double size, int max switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-6; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-6; + setConvergentBailout(1E-6); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderPoly.java b/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderPoly.java index f627f0ecd..6ee5c1453 100644 --- a/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderPoly.java @@ -59,13 +59,11 @@ public SchroderPoly(double xCenter, double yCenter, double size, int max_iterati switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-6; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-6; - break; + setConvergentBailout(1E-6); + break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderSin.java b/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderSin.java index 3d4d14701..a2618d363 100644 --- a/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/schroder/SchroderSin.java @@ -33,17 +33,17 @@ public class SchroderSin extends SchroderRootFindingMethod { public SchroderSin(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-6; - break; + setConvergentBailout(1E-6); + break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/secant/Secant3.java b/src/fractalzoomer/functions/root_finding_methods/secant/Secant3.java index 9a8f61b9e..000d51b6b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/secant/Secant3.java +++ b/src/fractalzoomer/functions/root_finding_methods/secant/Secant3.java @@ -36,7 +36,7 @@ public Secant3(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1e-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/secant/Secant4.java b/src/fractalzoomer/functions/root_finding_methods/secant/Secant4.java index 96deb605d..2abf673dc 100644 --- a/src/fractalzoomer/functions/root_finding_methods/secant/Secant4.java +++ b/src/fractalzoomer/functions/root_finding_methods/secant/Secant4.java @@ -36,7 +36,7 @@ public Secant4(double xCenter, double yCenter, double size, int max_iterations, switch (out_coloring_algorithm) { case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1e-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/secant/SecantCos.java b/src/fractalzoomer/functions/root_finding_methods/secant/SecantCos.java index 0c34e00b9..1b8b2ed0a 100644 --- a/src/fractalzoomer/functions/root_finding_methods/secant/SecantCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/secant/SecantCos.java @@ -36,13 +36,11 @@ public SecantCos(double xCenter, double yCenter, double size, int max_iterations switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-6; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-6; + setConvergentBailout(1E-6); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/secant/SecantFormula.java b/src/fractalzoomer/functions/root_finding_methods/secant/SecantFormula.java index 143ced222..95fd2591a 100644 --- a/src/fractalzoomer/functions/root_finding_methods/secant/SecantFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/secant/SecantFormula.java @@ -43,15 +43,10 @@ public SecantFormula(double xCenter, double yCenter, double size, int max_iterat switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/secant/SecantGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/secant/SecantGeneralized3.java index 9e04d3617..5b70d03f0 100644 --- a/src/fractalzoomer/functions/root_finding_methods/secant/SecantGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/secant/SecantGeneralized3.java @@ -36,7 +36,7 @@ public SecantGeneralized3(double xCenter, double yCenter, double size, int max_i switch (out_coloring_algorithm) { case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1e-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/secant/SecantGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/secant/SecantGeneralized8.java index 60db52ce7..fcf6b8473 100644 --- a/src/fractalzoomer/functions/root_finding_methods/secant/SecantGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/secant/SecantGeneralized8.java @@ -36,7 +36,7 @@ public SecantGeneralized8(double xCenter, double yCenter, double size, int max_i switch (out_coloring_algorithm) { case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1e-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/secant/SecantPoly.java b/src/fractalzoomer/functions/root_finding_methods/secant/SecantPoly.java index b09e805d2..f632a52a6 100644 --- a/src/fractalzoomer/functions/root_finding_methods/secant/SecantPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/secant/SecantPoly.java @@ -57,7 +57,7 @@ public SecantPoly(double xCenter, double yCenter, double size, int max_iteration switch (out_coloring_algorithm) { case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1e-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewton3.java b/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewton3.java index 807083060..dc1d61105 100644 --- a/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewton3.java +++ b/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewton3.java @@ -16,17 +16,14 @@ public SimpsonNewton3(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; + } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewton4.java b/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewton4.java index 987a55cb8..367307564 100644 --- a/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewton4.java +++ b/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewton4.java @@ -16,17 +16,14 @@ public SimpsonNewton4(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; + } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonCos.java b/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonCos.java index 17e3464df..e4156499d 100644 --- a/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonCos.java @@ -16,17 +16,14 @@ public SimpsonNewtonCos(double xCenter, double yCenter, double size, int max_ite switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; + } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonFormula.java b/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonFormula.java index 7f7031346..c01aa1c92 100644 --- a/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonFormula.java @@ -26,15 +26,10 @@ public SimpsonNewtonFormula(double xCenter, double yCenter, double size, int max switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonGeneralized3.java index e9d00e4d0..c4e1f2a7d 100644 --- a/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonGeneralized3.java @@ -16,17 +16,14 @@ public SimpsonNewtonGeneralized3(double xCenter, double yCenter, double size, in switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; + } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonGeneralized8.java index c8bed758a..df2edcced 100644 --- a/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonGeneralized8.java @@ -16,17 +16,14 @@ public SimpsonNewtonGeneralized8(double xCenter, double yCenter, double size, in switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; + } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonPoly.java b/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonPoly.java index d48d3cd17..3aadea9a1 100644 --- a/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonPoly.java @@ -38,16 +38,12 @@ public SimpsonNewtonPoly(double xCenter, double yCenter, double size, int max_it switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonSin.java b/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonSin.java index 3d4d26d19..8c4afe4e6 100644 --- a/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/simpson_newton/SimpsonNewtonSin.java @@ -16,17 +16,14 @@ public SimpsonNewtonSin(double xCenter, double yCenter, double size, int max_ite switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; + } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/steffensen/Steffensen3.java b/src/fractalzoomer/functions/root_finding_methods/steffensen/Steffensen3.java index 71f90157a..afee1c0e7 100644 --- a/src/fractalzoomer/functions/root_finding_methods/steffensen/Steffensen3.java +++ b/src/fractalzoomer/functions/root_finding_methods/steffensen/Steffensen3.java @@ -37,13 +37,11 @@ public Steffensen3(double xCenter, double yCenter, double size, int max_iteratio switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; - break; + setConvergentBailout(1E-9); + break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/steffensen/Steffensen4.java b/src/fractalzoomer/functions/root_finding_methods/steffensen/Steffensen4.java index c8b2de94e..4480aebbc 100644 --- a/src/fractalzoomer/functions/root_finding_methods/steffensen/Steffensen4.java +++ b/src/fractalzoomer/functions/root_finding_methods/steffensen/Steffensen4.java @@ -37,13 +37,11 @@ public Steffensen4(double xCenter, double yCenter, double size, int max_iteratio switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; - break; + setConvergentBailout(1E-9); + break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/steffensen/SteffensenFormula.java b/src/fractalzoomer/functions/root_finding_methods/steffensen/SteffensenFormula.java index f90a85299..385a1309a 100644 --- a/src/fractalzoomer/functions/root_finding_methods/steffensen/SteffensenFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/steffensen/SteffensenFormula.java @@ -43,15 +43,10 @@ public SteffensenFormula(double xCenter, double yCenter, double size, int max_it switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/steffensen/SteffensenGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/steffensen/SteffensenGeneralized3.java index 64aab46d8..99cf6208c 100644 --- a/src/fractalzoomer/functions/root_finding_methods/steffensen/SteffensenGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/steffensen/SteffensenGeneralized3.java @@ -37,13 +37,11 @@ public SteffensenGeneralized3(double xCenter, double yCenter, double size, int m switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; - break; + setConvergentBailout(1E-9); + break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/steffensen/SteffensenPoly.java b/src/fractalzoomer/functions/root_finding_methods/steffensen/SteffensenPoly.java index abb00ebd1..566f0d481 100644 --- a/src/fractalzoomer/functions/root_finding_methods/steffensen/SteffensenPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/steffensen/SteffensenPoly.java @@ -58,13 +58,11 @@ public SteffensenPoly(double xCenter, double yCenter, double size, int max_itera switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; - break; + setConvergentBailout(1E-9); + break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/stirling/Stirling3.java b/src/fractalzoomer/functions/root_finding_methods/stirling/Stirling3.java index 378d0701a..b7fb8ca4b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/stirling/Stirling3.java +++ b/src/fractalzoomer/functions/root_finding_methods/stirling/Stirling3.java @@ -14,14 +14,13 @@ public Stirling3(double xCenter, double yCenter, double size, int max_iterations super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/stirling/Stirling4.java b/src/fractalzoomer/functions/root_finding_methods/stirling/Stirling4.java index b1e3c30ce..74ba674d2 100644 --- a/src/fractalzoomer/functions/root_finding_methods/stirling/Stirling4.java +++ b/src/fractalzoomer/functions/root_finding_methods/stirling/Stirling4.java @@ -14,14 +14,13 @@ public Stirling4(double xCenter, double yCenter, double size, int max_iterations super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingCos.java b/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingCos.java index 97f815e91..7072accea 100644 --- a/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingCos.java @@ -14,14 +14,13 @@ public StirlingCos(double xCenter, double yCenter, double size, int max_iteratio super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingFormula.java b/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingFormula.java index 8a86451a2..4fef21988 100644 --- a/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingFormula.java @@ -26,15 +26,10 @@ public StirlingFormula(double xCenter, double yCenter, double size, int max_iter switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingGeneralized3.java index 43ee402b8..9de8c9df5 100644 --- a/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingGeneralized3.java @@ -14,14 +14,13 @@ public StirlingGeneralized3(double xCenter, double yCenter, double size, int max super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingGeneralized8.java index ebaf03ca9..9f42494e5 100644 --- a/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingGeneralized8.java @@ -14,14 +14,13 @@ public StirlingGeneralized8(double xCenter, double yCenter, double size, int max super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingPoly.java b/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingPoly.java index 9ff99f675..8735e9810 100644 --- a/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingPoly.java @@ -37,13 +37,11 @@ public StirlingPoly(double xCenter, double yCenter, double size, int max_iterati switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingSin.java b/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingSin.java index e7af43b61..cd5bb5ee0 100644 --- a/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/stirling/StirlingSin.java @@ -14,14 +14,13 @@ public StirlingSin(double xCenter, double yCenter, double size, int max_iteratio super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); switch (out_coloring_algorithm) { + case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalley3.java b/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalley3.java index 4fb00f328..4b74f0d81 100644 --- a/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalley3.java +++ b/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalley3.java @@ -37,17 +37,14 @@ public SuperHalley3(double xCenter, double yCenter, double size, int max_iterati switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; + } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalley4.java b/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalley4.java index 5a370a8a0..be05d4479 100644 --- a/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalley4.java +++ b/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalley4.java @@ -37,16 +37,12 @@ public SuperHalley4(double xCenter, double yCenter, double size, int max_iterati switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleyCos.java b/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleyCos.java index 1304cbefc..419d03962 100644 --- a/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleyCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleyCos.java @@ -33,20 +33,18 @@ public class SuperHalleyCos extends SuperHalleyRootFindingMethod { public SuperHalleyCos(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleyFormula.java b/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleyFormula.java index 08a9fc2c2..125584810 100644 --- a/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleyFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleyFormula.java @@ -48,15 +48,10 @@ public SuperHalleyFormula(double xCenter, double yCenter, double size, int max_i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleyGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleyGeneralized3.java index b6d6b0ce0..502b067db 100644 --- a/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleyGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleyGeneralized3.java @@ -37,16 +37,12 @@ public SuperHalleyGeneralized3(double xCenter, double yCenter, double size, int switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleyGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleyGeneralized8.java index e2a20ac26..bd1d602d4 100644 --- a/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleyGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleyGeneralized8.java @@ -37,16 +37,12 @@ public SuperHalleyGeneralized8(double xCenter, double yCenter, double size, int switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleyPoly.java b/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleyPoly.java index 56649fd00..eb39e21f9 100644 --- a/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleyPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleyPoly.java @@ -59,16 +59,12 @@ public SuperHalleyPoly(double xCenter, double yCenter, double size, int max_iter switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleySin.java b/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleySin.java index 0c6450ddf..b476e7a14 100644 --- a/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleySin.java +++ b/src/fractalzoomer/functions/root_finding_methods/super_halley/SuperHalleySin.java @@ -33,20 +33,18 @@ public class SuperHalleySin extends SuperHalleyRootFindingMethod { public SuperHalleySin(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewton3.java b/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewton3.java index 0a5bc4afe..c82e83ab3 100644 --- a/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewton3.java +++ b/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewton3.java @@ -15,13 +15,11 @@ public ThirdOrderNewton3(double xCenter, double yCenter, double size, int max_it switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewton4.java b/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewton4.java index 6c0b46148..ea9e45ddd 100644 --- a/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewton4.java +++ b/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewton4.java @@ -15,13 +15,11 @@ public ThirdOrderNewton4(double xCenter, double yCenter, double size, int max_it switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonCos.java b/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonCos.java index 4a3791b58..5210fb898 100644 --- a/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonCos.java @@ -15,13 +15,11 @@ public ThirdOrderNewtonCos(double xCenter, double yCenter, double size, int max_ switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonFormula.java b/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonFormula.java index 26db2e15d..cab1607a4 100644 --- a/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonFormula.java @@ -26,15 +26,10 @@ public ThirdOrderNewtonFormula(double xCenter, double yCenter, double size, int switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonGeneralized3.java index 1b8552ee8..b2cc4fd81 100644 --- a/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonGeneralized3.java @@ -15,13 +15,11 @@ public ThirdOrderNewtonGeneralized3(double xCenter, double yCenter, double size, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonGeneralized8.java index 2930fd67c..46453d173 100644 --- a/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonGeneralized8.java @@ -15,13 +15,11 @@ public ThirdOrderNewtonGeneralized8(double xCenter, double yCenter, double size, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonPoly.java b/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonPoly.java index f3380f642..341d75f75 100644 --- a/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonPoly.java @@ -37,13 +37,11 @@ public ThirdOrderNewtonPoly(double xCenter, double yCenter, double size, int max switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonRootFindingMethod.java b/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonRootFindingMethod.java index 545d0e6b6..26b356d09 100644 --- a/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonRootFindingMethod.java +++ b/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonRootFindingMethod.java @@ -12,7 +12,7 @@ public ThirdOrderNewtonRootFindingMethod(double xCenter, double yCenter, double super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - convergent_bailout = 1e-8; + setConvergentBailout(1e-8); } diff --git a/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonSin.java b/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonSin.java index 357c87c62..fef8da123 100644 --- a/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/third_order_newton/ThirdOrderNewtonSin.java @@ -15,13 +15,11 @@ public ThirdOrderNewtonSin(double xCenter, double yCenter, double size, int max_ switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowski3.java b/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowski3.java index cc2a01c75..2bb47cdae 100644 --- a/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowski3.java +++ b/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowski3.java @@ -15,13 +15,11 @@ public TraubOstrowski3(double xCenter, double yCenter, double size, int max_iter switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowski4.java b/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowski4.java index e64515ff1..ad28e23bf 100644 --- a/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowski4.java +++ b/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowski4.java @@ -15,13 +15,11 @@ public TraubOstrowski4(double xCenter, double yCenter, double size, int max_iter switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiCos.java b/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiCos.java index de8bc96fe..933617a57 100644 --- a/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiCos.java @@ -15,13 +15,11 @@ public TraubOstrowskiCos(double xCenter, double yCenter, double size, int max_it switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiFormula.java b/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiFormula.java index 5d0c6bb91..33ab6ad8a 100644 --- a/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiFormula.java @@ -26,15 +26,10 @@ public TraubOstrowskiFormula(double xCenter, double yCenter, double size, int ma switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiGeneralized3.java index f69d0525c..47f3cde50 100644 --- a/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiGeneralized3.java @@ -15,13 +15,11 @@ public TraubOstrowskiGeneralized3(double xCenter, double yCenter, double size, i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiGeneralized8.java index 62165ed94..0ec94f5ec 100644 --- a/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiGeneralized8.java @@ -15,13 +15,11 @@ public TraubOstrowskiGeneralized8(double xCenter, double yCenter, double size, i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiPoly.java b/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiPoly.java index 045c347b9..aa670d41d 100644 --- a/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiPoly.java @@ -37,13 +37,11 @@ public TraubOstrowskiPoly(double xCenter, double yCenter, double size, int max_i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiRootFindingMethod.java b/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiRootFindingMethod.java index 64441ac9c..aa014a026 100644 --- a/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiRootFindingMethod.java +++ b/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiRootFindingMethod.java @@ -32,7 +32,7 @@ public TraubOstrowskiRootFindingMethod(double xCenter, double yCenter, double si super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - convergent_bailout = 1E-8; + setConvergentBailout(1E-8); } diff --git a/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiSin.java b/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiSin.java index 3f950e01f..051478b26 100644 --- a/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/traub_ostrowski/TraubOstrowskiSin.java @@ -15,13 +15,11 @@ public TraubOstrowskiSin(double xCenter, double yCenter, double size, int max_it switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-9; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernando3.java b/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernando3.java index a82b56b34..b0d6acf63 100644 --- a/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernando3.java +++ b/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernando3.java @@ -16,16 +16,12 @@ public WeerakoonFernando3(double xCenter, double yCenter, double size, int max_i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernando4.java b/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernando4.java index 2ada3aaab..b477c02d6 100644 --- a/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernando4.java +++ b/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernando4.java @@ -16,16 +16,12 @@ public WeerakoonFernando4(double xCenter, double yCenter, double size, int max_i switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoCos.java b/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoCos.java index 5a5d34cc1..543a99b0a 100644 --- a/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoCos.java @@ -16,16 +16,12 @@ public WeerakoonFernandoCos(double xCenter, double yCenter, double size, int max switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoFormula.java b/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoFormula.java index 423e82a6d..9eab6bee3 100644 --- a/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoFormula.java @@ -26,15 +26,10 @@ public WeerakoonFernandoFormula(double xCenter, double yCenter, double size, int switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoGeneralized3.java index 1855c537d..35b8cc47a 100644 --- a/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoGeneralized3.java @@ -16,16 +16,12 @@ public WeerakoonFernandoGeneralized3(double xCenter, double yCenter, double size switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoGeneralized8.java index 6073fa556..9ad53b11a 100644 --- a/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoGeneralized8.java @@ -16,16 +16,12 @@ public WeerakoonFernandoGeneralized8(double xCenter, double yCenter, double size switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoPoly.java b/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoPoly.java index 4d05d511a..acd4834b2 100644 --- a/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoPoly.java @@ -38,18 +38,13 @@ public WeerakoonFernandoPoly(double xCenter, double yCenter, double size, int ma switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoRootFindingMethod.java b/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoRootFindingMethod.java index d6a5c2c55..2cfe964aa 100644 --- a/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoRootFindingMethod.java +++ b/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoRootFindingMethod.java @@ -12,7 +12,7 @@ public WeerakoonFernandoRootFindingMethod(double xCenter, double yCenter, double super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - convergent_bailout = 1e-8; + setConvergentBailout(1e-8); } diff --git a/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoSin.java b/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoSin.java index 59b89ab54..18d798899 100644 --- a/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/weerakoon_fernando/WeerakoonFernandoSin.java @@ -16,16 +16,12 @@ public WeerakoonFernandoSin(double xCenter, double yCenter, double size, int max switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/whittaker/Whittaker3.java b/src/fractalzoomer/functions/root_finding_methods/whittaker/Whittaker3.java index bbc04712a..009368841 100644 --- a/src/fractalzoomer/functions/root_finding_methods/whittaker/Whittaker3.java +++ b/src/fractalzoomer/functions/root_finding_methods/whittaker/Whittaker3.java @@ -37,16 +37,12 @@ public Whittaker3(double xCenter, double yCenter, double size, int max_iteration switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/whittaker/Whittaker4.java b/src/fractalzoomer/functions/root_finding_methods/whittaker/Whittaker4.java index be184e9af..9dddd4ae3 100644 --- a/src/fractalzoomer/functions/root_finding_methods/whittaker/Whittaker4.java +++ b/src/fractalzoomer/functions/root_finding_methods/whittaker/Whittaker4.java @@ -37,18 +37,13 @@ public Whittaker4(double xCenter, double yCenter, double size, int max_iteration switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerCos.java b/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerCos.java index a4ccf8f4d..8a376a2b3 100644 --- a/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerCos.java @@ -33,20 +33,18 @@ public class WhittakerCos extends WhittakerRootFindingMethod { public WhittakerCos(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerFormula.java b/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerFormula.java index 57ccf78fc..467744c30 100644 --- a/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerFormula.java @@ -48,15 +48,10 @@ public WhittakerFormula(double xCenter, double yCenter, double size, int max_ite switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerGeneralized3.java index 3df0430ac..e516de757 100644 --- a/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerGeneralized3.java @@ -37,18 +37,13 @@ public WhittakerGeneralized3(double xCenter, double yCenter, double size, int ma switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerGeneralized8.java index edf5793cb..f17389a01 100644 --- a/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerGeneralized8.java @@ -37,18 +37,13 @@ public WhittakerGeneralized8(double xCenter, double yCenter, double size, int ma switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerPoly.java b/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerPoly.java index 299fd7f94..fbb889d50 100644 --- a/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerPoly.java @@ -59,18 +59,13 @@ public WhittakerPoly(double xCenter, double yCenter, double size, int max_iterat switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerSin.java b/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerSin.java index 3535e3866..eeb88d817 100644 --- a/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/whittaker/WhittakerSin.java @@ -37,16 +37,14 @@ public WhittakerSin(double xCenter, double yCenter, double size, int max_iterati switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvex3.java b/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvex3.java index fd06a97fe..b208b3ba8 100644 --- a/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvex3.java +++ b/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvex3.java @@ -37,16 +37,12 @@ public WhittakerDoubleConvex3(double xCenter, double yCenter, double size, int m switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvex4.java b/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvex4.java index 84e8ceae3..ed459aab5 100644 --- a/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvex4.java +++ b/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvex4.java @@ -37,18 +37,13 @@ public WhittakerDoubleConvex4(double xCenter, double yCenter, double size, int m switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexCos.java b/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexCos.java index 70ad92ccc..9266a146d 100644 --- a/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexCos.java +++ b/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexCos.java @@ -33,20 +33,18 @@ public class WhittakerDoubleConvexCos extends WhittakerDoubleConvexRootFindingMe public WhittakerDoubleConvexCos(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexFormula.java b/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexFormula.java index a7afbbb3f..3ba5f6f7b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexFormula.java +++ b/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexFormula.java @@ -48,15 +48,10 @@ public WhittakerDoubleConvexFormula(double xCenter, double yCenter, double size, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexGeneralized3.java b/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexGeneralized3.java index 0462884b3..23475b23b 100644 --- a/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexGeneralized3.java +++ b/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexGeneralized3.java @@ -37,18 +37,13 @@ public WhittakerDoubleConvexGeneralized3(double xCenter, double yCenter, double switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexGeneralized8.java b/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexGeneralized8.java index e4b5bab74..8c820c05a 100644 --- a/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexGeneralized8.java +++ b/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexGeneralized8.java @@ -37,18 +37,13 @@ public WhittakerDoubleConvexGeneralized8(double xCenter, double yCenter, double switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexPoly.java b/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexPoly.java index e9a2101ed..14aa06b19 100644 --- a/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexPoly.java +++ b/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexPoly.java @@ -59,18 +59,13 @@ public WhittakerDoubleConvexPoly(double xCenter, double yCenter, double size, in switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-4; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexSin.java b/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexSin.java index 29b375ff3..92b4227d7 100644 --- a/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexSin.java +++ b/src/fractalzoomer/functions/root_finding_methods/whittaker_double_convex/WhittakerDoubleConvexSin.java @@ -33,20 +33,18 @@ public class WhittakerDoubleConvexSin extends WhittakerDoubleConvexRootFindingMe public WhittakerDoubleConvexSin(double xCenter, double yCenter, double size, int max_iterations, int out_coloring_algorithm, int user_out_coloring_algorithm, String outcoloring_formula, String[] user_outcoloring_conditions, String[] user_outcoloring_condition_formula, int in_coloring_algorithm, int user_in_coloring_algorithm, String incoloring_formula, String[] user_incoloring_conditions, String[] user_incoloring_condition_formula, boolean smoothing, int plane_type, double[] rotation_vals, double[] rotation_center, String user_plane, int user_plane_algorithm, String[] user_plane_conditions, String[] user_plane_condition_formula, double[] plane_transform_center, double plane_transform_angle, double plane_transform_radius, double[] plane_transform_scales, double[] plane_transform_wavelength, int waveType, double plane_transform_angle2, int plane_transform_sides, double plane_transform_amount, ArrayList inflections_re, ArrayList inflections_im, double inflectionsPower, int converging_smooth_algorithm, OrbitTrapSettings ots, StatisticsSettings sts) { super(xCenter, yCenter, size, max_iterations, plane_type, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots); - + switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-2; + setConvergentBailout(1E-2); break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-4; - break; case MainWindow.ESCAPE_TIME_ALGORITHM: - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/functions/user_formulas/UserFormulaConditionalConverging.java b/src/fractalzoomer/functions/user_formulas/UserFormulaConditionalConverging.java index 8407d13d9..a05b2f691 100644 --- a/src/fractalzoomer/functions/user_formulas/UserFormulaConditionalConverging.java +++ b/src/fractalzoomer/functions/user_formulas/UserFormulaConditionalConverging.java @@ -98,18 +98,11 @@ public UserFormulaConditionalConverging(double xCenter, double yCenter, double s switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; - case MainWindow.BANDED: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + case MainWindow.BANDED: + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/user_formulas/UserFormulaConverging.java b/src/fractalzoomer/functions/user_formulas/UserFormulaConverging.java index bafba79af..8411c77d2 100644 --- a/src/fractalzoomer/functions/user_formulas/UserFormulaConverging.java +++ b/src/fractalzoomer/functions/user_formulas/UserFormulaConverging.java @@ -89,18 +89,11 @@ public UserFormulaConverging(double xCenter, double yCenter, double size, int ma switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; - case MainWindow.BANDED: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + case MainWindow.BANDED: + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/user_formulas/UserFormulaCoupledConverging.java b/src/fractalzoomer/functions/user_formulas/UserFormulaCoupledConverging.java index d2a231df0..a77e51b50 100644 --- a/src/fractalzoomer/functions/user_formulas/UserFormulaCoupledConverging.java +++ b/src/fractalzoomer/functions/user_formulas/UserFormulaCoupledConverging.java @@ -110,18 +110,11 @@ public UserFormulaCoupledConverging(double xCenter, double yCenter, double size, switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; - case MainWindow.BANDED: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + case MainWindow.BANDED: + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/user_formulas/UserFormulaIterationBasedConverging.java b/src/fractalzoomer/functions/user_formulas/UserFormulaIterationBasedConverging.java index 8236984b8..d58f61055 100644 --- a/src/fractalzoomer/functions/user_formulas/UserFormulaIterationBasedConverging.java +++ b/src/fractalzoomer/functions/user_formulas/UserFormulaIterationBasedConverging.java @@ -89,18 +89,11 @@ public UserFormulaIterationBasedConverging(double xCenter, double yCenter, doubl switch (out_coloring_algorithm) { case MainWindow.BINARY_DECOMPOSITION: - convergent_bailout = 1E-7; - break; case MainWindow.BINARY_DECOMPOSITION2: - convergent_bailout = 1E-7; - break; case MainWindow.BANDED: - convergent_bailout = 1E-7; - break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; - } OutColoringAlgorithmFactory(out_coloring_algorithm, smoothing, converging_smooth_algorithm, user_out_coloring_algorithm, outcoloring_formula, user_outcoloring_conditions, user_outcoloring_condition_formula, plane_transform_center); diff --git a/src/fractalzoomer/functions/user_formulas/UserFormulaNova.java b/src/fractalzoomer/functions/user_formulas/UserFormulaNova.java index 0e32af58b..2bbfca831 100644 --- a/src/fractalzoomer/functions/user_formulas/UserFormulaNova.java +++ b/src/fractalzoomer/functions/user_formulas/UserFormulaNova.java @@ -116,7 +116,7 @@ public UserFormulaNova(double xCenter, double yCenter, double size, int max_iter //Todo: Check which other methods need this if(nova_method == MainWindow.NOVA_TRAUB_OSTROWSKI) { - convergent_bailout = 1E-8; + setConvergentBailout(1E-8); } this.nova_method = nova_method; @@ -194,7 +194,7 @@ public UserFormulaNova(double xCenter, double yCenter, double size, int max_iter super(xCenter, yCenter, size, max_iterations, bailout_test_algorithm, bailout, bailout_test_user_formula, bailout_test_user_formula2, bailout_test_comparison, n_norm, false, plane_type, apply_plane_on_julia, apply_plane_on_julia_seed, rotation_vals, rotation_center, user_plane, user_plane_algorithm, user_plane_conditions, user_plane_condition_formula, plane_transform_center, plane_transform_angle, plane_transform_radius, plane_transform_scales, plane_transform_wavelength, waveType, plane_transform_angle2, plane_transform_sides, plane_transform_amount, inflections_re, inflections_im, inflectionsPower, ots, xJuliaCenter, yJuliaCenter); if(nova_method == MainWindow.NOVA_TRAUB_OSTROWSKI) { - convergent_bailout = 1E-8; + setConvergentBailout(1E-8); } this.nova_method = nova_method; @@ -228,15 +228,15 @@ public UserFormulaNova(double xCenter, double yCenter, double size, int max_iter case MainWindow.BINARY_DECOMPOSITION2: case MainWindow.BANDED: if (nova_method == MainWindow.NOVA_HALLEY || nova_method == MainWindow.NOVA_HOUSEHOLDER || nova_method == MainWindow.NOVA_WHITTAKER || nova_method == MainWindow.NOVA_WHITTAKER_DOUBLE_CONVEX || nova_method == MainWindow.NOVA_SUPER_HALLEY) { - convergent_bailout = 1E-4; + setConvergentBailout(1E-4); } else if (nova_method == MainWindow.NOVA_NEWTON || nova_method == MainWindow.NOVA_STEFFENSEN) { - convergent_bailout = 1E-9; + setConvergentBailout(1E-9); } else if (nova_method == MainWindow.NOVA_SCHRODER) { - convergent_bailout = 1E-6; + setConvergentBailout(1E-6); } break; case MainWindow.USER_OUTCOLORING_ALGORITHM: - convergent_bailout = 1E-7; + setConvergentBailout(1E-7); break; } diff --git a/src/fractalzoomer/gui/CenterSizeDialog.java b/src/fractalzoomer/gui/CenterSizeDialog.java index 1cdc0cfe1..0d7628b2c 100644 --- a/src/fractalzoomer/gui/CenterSizeDialog.java +++ b/src/fractalzoomer/gui/CenterSizeDialog.java @@ -175,9 +175,9 @@ public void windowClosing(WindowEvent we) { try { if(MyApfloat.setAutomaticPrecision) { - long precision = MyApfloat.getAutomaticPrecision(new String[]{field_size.getText(), field_real.getText(), field_imaginary.getText()}, new boolean[] {true, false, false}); + long precision = MyApfloat.getAutomaticPrecision(new String[]{field_size.getText(), field_real.getText(), field_imaginary.getText()}, new boolean[] {true, false, false}, s.fns.function); - if (MyApfloat.shouldSetPrecision(precision, MyApfloat.alwaysCheckForDecrease)) { + if (MyApfloat.shouldSetPrecision(precision, MyApfloat.alwaysCheckForDecrease, s.fns.function)) { Fractal.clearReferences(true, true); MyApfloat.setPrecision(precision, s); } diff --git a/src/fractalzoomer/gui/CenterSizeJuliaDialog.java b/src/fractalzoomer/gui/CenterSizeJuliaDialog.java index c5b0164eb..54ce4baf0 100644 --- a/src/fractalzoomer/gui/CenterSizeJuliaDialog.java +++ b/src/fractalzoomer/gui/CenterSizeJuliaDialog.java @@ -258,9 +258,9 @@ public void windowClosing(WindowEvent we) { try { if(MyApfloat.setAutomaticPrecision) { - long precision = MyApfloat.getAutomaticPrecision(new String[] {field_size.getText(), field_real.getText(), field_imaginary.getText(), real_seed.getText(), imag_seed.getText()}, new boolean[] {true, false, false, false, false}); + long precision = MyApfloat.getAutomaticPrecision(new String[] {field_size.getText(), field_real.getText(), field_imaginary.getText(), real_seed.getText(), imag_seed.getText()}, new boolean[] {true, false, false, false, false}, s.fns.function); - if (MyApfloat.shouldSetPrecision(precision, MyApfloat.alwaysCheckForDecrease)) { + if (MyApfloat.shouldSetPrecision(precision, MyApfloat.alwaysCheckForDecrease, s.fns.function)) { Fractal.clearReferences(true, true); MyApfloat.setPrecision(precision, s); } diff --git a/src/fractalzoomer/gui/ColorCyclingDialog.java b/src/fractalzoomer/gui/ColorCyclingDialog.java index 30ada5cc0..548d41e94 100644 --- a/src/fractalzoomer/gui/ColorCyclingDialog.java +++ b/src/fractalzoomer/gui/ColorCyclingDialog.java @@ -17,6 +17,7 @@ package fractalzoomer.gui; import fractalzoomer.main.MainWindow; +import fractalzoomer.main.app_settings.ColorCyclingSettings; import javax.swing.*; import java.awt.*; @@ -33,7 +34,7 @@ public class ColorCyclingDialog extends JDialog { private MainWindow ptra; private JOptionPane optionPane; - public ColorCyclingDialog(MainWindow ptr, boolean cycle_colors, boolean cycle_gradient, boolean cycle_lights, int color_cycling_speed, int color_cycling_adjusting_value) { + public ColorCyclingDialog(MainWindow ptr, ColorCyclingSettings ccs) { super(ptr); @@ -43,22 +44,7 @@ public ColorCyclingDialog(MainWindow ptr, boolean cycle_colors, boolean cycle_gr setModal(true); setIconImage(MainWindow.getIcon("mandel2.png").getImage()); - JCheckBox cycleColors = new JCheckBox("Cycle Colors"); - cycleColors.setFocusable(false); - cycleColors.setSelected(cycle_colors); - cycleColors.setToolTipText("Cycles through the palette."); - - JCheckBox cycleGradient = new JCheckBox("Cycle Gradient"); - cycleGradient.setFocusable(false); - cycleGradient.setSelected(cycle_gradient); - cycleGradient.setToolTipText("Cycles through the gradient."); - - JCheckBox cycleLights = new JCheckBox("Cycle Lights"); - cycleLights.setFocusable(false); - cycleLights.setSelected(cycle_lights); - cycleColors.setToolTipText("Rotates the light (Light/Bump Mapping)."); - - final JSlider speed_slid = new JSlider(JSlider.HORIZONTAL, 0, 1000, 1000 - color_cycling_speed); + final JSlider speed_slid = new JSlider(JSlider.HORIZONTAL, 0, 1000, 1000 - ccs.color_cycling_speed); speed_slid.setPreferredSize(new Dimension(200, 35)); @@ -73,25 +59,39 @@ public ColorCyclingDialog(MainWindow ptr, boolean cycle_colors, boolean cycle_gr labelTable.put(speed_slid.getMaximum(), new JLabel("Fast")); speed_slid.setLabelTable(labelTable); - JTextField field = new JTextField(); - field.addAncestorListener(new RequestFocusListener()); - field.setText("" + color_cycling_adjusting_value); + JTextField field_color_cycle_adjust = new JTextField(); + field_color_cycle_adjust.addAncestorListener(new RequestFocusListener()); + field_color_cycle_adjust.setText("" + ccs.color_cycling_adjusting_value); + + JTextField field_gradient_cycle_adjust = new JTextField(); + field_gradient_cycle_adjust.setText("" + ccs.gradient_cycling_adjusting_value); + + JTextField field_light_cycle_adjust = new JTextField(); + field_light_cycle_adjust.setText("" + ccs.light_cycling_adjusting_value); + + JTextField field_bump_cycle_adjust = new JTextField(); + field_bump_cycle_adjust.setText("" + ccs.bump_cycling_adjusting_value); + + JTextField field_slope_cycle_adjust = new JTextField(); + field_slope_cycle_adjust.setText("" + ccs.slope_cycling_adjusting_value); Object[] message3 = { - " ", - "Set the cycling modes.", - "Modes:", - cycleColors, - cycleGradient, - cycleLights, " ", "Set the color cycling speed.", "Speed:", speed_slid, " ", - "Set the color cycling adjusting value.", - "Adjusting Value:", - field, + "Set the cycling adjusting values.", + "Color Cycling:", + field_color_cycle_adjust, + "Gradient Cycling:", + field_gradient_cycle_adjust, + "Light Cycling:", + field_light_cycle_adjust, + "Bump-Mapping Cycling:", + field_bump_cycle_adjust, + "Slope Cycling:", + field_slope_cycle_adjust, " ",}; optionPane = new JOptionPane(message3, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null, null, null); @@ -129,14 +129,42 @@ public void windowClosing(WindowEvent we) { } try { - int temp = Integer.parseInt(field.getText()); + int temp = Integer.parseInt(field_color_cycle_adjust.getText()); + int temp2 = Integer.parseInt(field_gradient_cycle_adjust.getText()); + int temp3 = Integer.parseInt(field_light_cycle_adjust.getText()); + int temp4 = Integer.parseInt(field_bump_cycle_adjust.getText()); + int temp5 = Integer.parseInt(field_slope_cycle_adjust.getText()); + + if(temp < -50 || temp > 50) { + JOptionPane.showMessageDialog(ptra, "The color cycling adjusting value must be in the range of [-50, 50].", "Error!", JOptionPane.ERROR_MESSAGE); + return; + } + + if(temp2 < -50 || temp2 > 50) { + JOptionPane.showMessageDialog(ptra, "The gradient cycling adjusting value must be in the range of [-50, 50].", "Error!", JOptionPane.ERROR_MESSAGE); + return; + } + + if(temp3 < -50 || temp3 > 50) { + JOptionPane.showMessageDialog(ptra, "The light cycling adjusting value must be in the range of [-50, 50].", "Error!", JOptionPane.ERROR_MESSAGE); + return; + } + + if(temp4 < -50 || temp4 > 50) { + JOptionPane.showMessageDialog(ptra, "The bump-mapping cycling adjusting value must be in the range of [-50, 50].", "Error!", JOptionPane.ERROR_MESSAGE); + return; + } - if(temp < 1 || temp > 50) { - JOptionPane.showMessageDialog(ptra, "The color cycling adjusting value must be in the range of [1, 50].", "Error!", JOptionPane.ERROR_MESSAGE); + if(temp5 < -50 || temp5 > 50) { + JOptionPane.showMessageDialog(ptra, "The slope cycling adjusting value must be in the range of [-50, 50].", "Error!", JOptionPane.ERROR_MESSAGE); return; } - ptra.setColorCyclingOptionsPost(cycleColors.isSelected(), cycleGradient.isSelected(), cycleLights.isSelected(), speed_slid.getMaximum() - speed_slid.getValue(), temp); + ccs.color_cycling_adjusting_value = temp; + ccs.gradient_cycling_adjusting_value = temp2; + ccs.light_cycling_adjusting_value = temp3; + ccs.bump_cycling_adjusting_value = temp4; + ccs.slope_cycling_adjusting_value = temp5; } catch (Exception ex) { JOptionPane.showMessageDialog(ptra, "Illegal Argument: " + ex.getMessage(), "Error!", JOptionPane.ERROR_MESSAGE); return; diff --git a/src/fractalzoomer/gui/ColorDensityDialog.java b/src/fractalzoomer/gui/ColorDensityDialog.java index 013589528..3d721b7aa 100644 --- a/src/fractalzoomer/gui/ColorDensityDialog.java +++ b/src/fractalzoomer/gui/ColorDensityDialog.java @@ -89,8 +89,8 @@ public void windowClosing(WindowEvent we) { try { double temp = Double.parseDouble(field.getText()); - if (temp < - 280 || temp > 280) { - JOptionPane.showMessageDialog(ptra, "The density value must be in the range [-280, 280].", "Error!", JOptionPane.ERROR_MESSAGE); + if (temp < - 300 || temp > 300) { + JOptionPane.showMessageDialog(ptra, "The density value must be in the range [-300, 300].", "Error!", JOptionPane.ERROR_MESSAGE); return; } @@ -106,7 +106,7 @@ public void windowClosing(WindowEvent we) { } dispose(); - ptr.updateColors(false); + ptr.updateColors(false, false); } }); diff --git a/src/fractalzoomer/gui/ColorIntensityDialog.java b/src/fractalzoomer/gui/ColorIntensityDialog.java index 79bc43db9..3a3654ea3 100644 --- a/src/fractalzoomer/gui/ColorIntensityDialog.java +++ b/src/fractalzoomer/gui/ColorIntensityDialog.java @@ -106,7 +106,7 @@ public void windowClosing(WindowEvent we) { } dispose(); - ptr.updateColors(false); + ptr.updateColors(false, false); } }); diff --git a/src/fractalzoomer/gui/ColorPaletteEditorPanel.java b/src/fractalzoomer/gui/ColorPaletteEditorPanel.java index 10841b5dc..3805de70c 100644 --- a/src/fractalzoomer/gui/ColorPaletteEditorPanel.java +++ b/src/fractalzoomer/gui/ColorPaletteEditorPanel.java @@ -648,7 +648,7 @@ public void mouseExited(MouseEvent e) { paletteLength = new JLabel("" + getTotalColors()); } - String[] random_palette_alg_str = {"Golden Ratio", "Waves", "Distance", "Triad", "Tetrad", "Google Material", "ColorBrewer 1", "ColorBrewer 2", "Google-ColorBrewer", "Cubehelix", "IQ-Cosines", "Perlin", "Simplex", "Perlin+Simplex", "Random Walk"}; + String[] random_palette_alg_str = {"Golden Ratio", "Waves", "Distance", "Triad", "Tetrad", "Google Material", "ColorBrewer 1", "ColorBrewer 2", "Google-ColorBrewer", "Cubehelix", "IQ-Cosines", "Perlin", "Simplex", "Perlin+Simplex", "Random Walk", "Simple Random"}; combo_box_random_palette_alg = new JComboBox<>(random_palette_alg_str); diff --git a/src/fractalzoomer/gui/ContourFactorDialog.java b/src/fractalzoomer/gui/ContourFactorDialog.java index e9214680c..ec8e45106 100644 --- a/src/fractalzoomer/gui/ContourFactorDialog.java +++ b/src/fractalzoomer/gui/ContourFactorDialog.java @@ -102,7 +102,7 @@ public void windowClosing(WindowEvent we) { } dispose(); - ptr.updateColors(false); + ptr.updateColors(false, false); } }); diff --git a/src/fractalzoomer/gui/ConvergentBailoutDialog.java b/src/fractalzoomer/gui/ConvergentBailoutDialog.java new file mode 100644 index 000000000..4f1b24746 --- /dev/null +++ b/src/fractalzoomer/gui/ConvergentBailoutDialog.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2020 hrkalona2 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package fractalzoomer.gui; + +import fractalzoomer.main.MainWindow; +import fractalzoomer.main.app_settings.Settings; + +import javax.swing.*; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +/** + * + * @author hrkalona2 + */ +public class ConvergentBailoutDialog extends JDialog { + + private MainWindow ptra; + private JOptionPane optionPane; + + public ConvergentBailoutDialog(MainWindow ptr, Settings s) { + super(ptr); + + ptra = ptr; + + setTitle("Convergent Bailout Number"); + setModal(true); + setIconImage(MainWindow.getIcon("mandel2.png").getImage()); + + JTextField field = new JTextField(10); + field.setText("" + s.fns.convergent_bailout); + field.addAncestorListener(new RequestFocusListener()); + + Object[] message3 = { + " ", + "You are using " + s.fns.convergent_bailout + " for convergent bailout number.\nA value of zero will set the convergent bailout to the default value for each function.\nInsert the new convergent bailout number.", + field, + " ",}; + + optionPane = new JOptionPane(message3, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null, null, null); + + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent we) { + optionPane.setValue(JOptionPane.CLOSED_OPTION); + } + }); + + optionPane.addPropertyChangeListener( + e -> { + String prop = e.getPropertyName(); + + if (isVisible() && (e.getSource() == optionPane) && (prop.equals(JOptionPane.VALUE_PROPERTY))) { + + Object value = optionPane.getValue(); + + if (value == JOptionPane.UNINITIALIZED_VALUE) { + //ignore reset + return; + } + + //Reset the JOptionPane's value. + //If you don't do this, then if the user + //presses the same button next time, no + //property change event will be fired. + optionPane.setValue(JOptionPane.UNINITIALIZED_VALUE); + + if ((Integer) value == JOptionPane.CANCEL_OPTION || (Integer) value == JOptionPane.NO_OPTION || (Integer) value == JOptionPane.CLOSED_OPTION) { + dispose(); + return; + } + + try { + double temp = Double.parseDouble(field.getText()); + + if (temp < 0) { + JOptionPane.showMessageDialog(ptra, "The convergent bailout value must be greater or equal 0.", "Error!", JOptionPane.ERROR_MESSAGE); + return; + } + + s.fns.convergent_bailout = temp; + } catch (Exception ex) { + JOptionPane.showMessageDialog(ptra, "Illegal Argument: " + ex.getMessage(), "Error!", JOptionPane.ERROR_MESSAGE); + return; + } + + dispose(); + ptr.setConvergentBailoutPost(); + } + }); + + //Make this dialog display it. + setContentPane(optionPane); + + pack(); + + setResizable(false); + setLocation((int) (ptra.getLocation().getX() + ptra.getSize().getWidth() / 2) - (getWidth() / 2), (int) (ptra.getLocation().getY() + ptra.getSize().getHeight() / 2) - (getHeight() / 2)); + setVisible(true); + + } + +} diff --git a/src/fractalzoomer/gui/CornersDialog.java b/src/fractalzoomer/gui/CornersDialog.java index 5609d167b..a18f6bb60 100644 --- a/src/fractalzoomer/gui/CornersDialog.java +++ b/src/fractalzoomer/gui/CornersDialog.java @@ -51,9 +51,9 @@ public CornersDialog(MainWindow ptr, Settings s, JTextArea field_real, JTextArea Apfloat tempx, tempy, tempSize; try { if(MyApfloat.setAutomaticPrecision) { - long precision = MyApfloat.getAutomaticPrecision(new String[] {field_size.getText(), field_real.getText(), field_imaginary.getText()}, new boolean[] {true, false, false}); + long precision = MyApfloat.getAutomaticPrecision(new String[] {field_size.getText(), field_real.getText(), field_imaginary.getText()}, new boolean[] {true, false, false}, s.fns.function); - if (MyApfloat.shouldSetPrecision(precision, MyApfloat.alwaysCheckForDecrease)) { + if (MyApfloat.shouldSetPrecision(precision, MyApfloat.alwaysCheckForDecrease, s.fns.function)) { Fractal.clearReferences(true, true); MyApfloat.setPrecision(precision, s); } @@ -188,9 +188,9 @@ public void windowClosing(WindowEvent we) { try { if(MyApfloat.setAutomaticPrecision) { - long precision = MyApfloat.getAutomaticPrecision(new String[] {corner1_real.getText(), corner1_imag.getText(), corner2_real.getText(), corner2_imag.getText()}, new boolean[] {false, false, false, false}); + long precision = MyApfloat.getAutomaticPrecision(new String[] {corner1_real.getText(), corner1_imag.getText(), corner2_real.getText(), corner2_imag.getText()}, new boolean[] {false, false, false, false}, s.fns.function); - if (MyApfloat.shouldSetPrecision(precision, MyApfloat.alwaysCheckForDecrease)) { + if (MyApfloat.shouldSetPrecision(precision, MyApfloat.alwaysCheckForDecrease, s.fns.function)) { Fractal.clearReferences(true, true); MyApfloat.setPrecision(precision, s); } diff --git a/src/fractalzoomer/gui/CustomPaletteEditorFrame.java b/src/fractalzoomer/gui/CustomPaletteEditorFrame.java index 58a72c5dc..dc1094b35 100644 --- a/src/fractalzoomer/gui/CustomPaletteEditorFrame.java +++ b/src/fractalzoomer/gui/CustomPaletteEditorFrame.java @@ -679,6 +679,9 @@ public void actionPerformed(ActionEvent e) ptra2.setEnabled(true); palette[palette_id].setSelected(color_choice == palette_id); + equal_hues = same_hues.isSelected(); + random_palette_algorithm = combo_box_random_palette_alg.getSelectedIndex(); + pastel = pastel_cb.isSelected(); dispose(); }); @@ -1045,7 +1048,7 @@ public void changedUpdate(DocumentEvent e) { color_interp_panel.add(combo_box_color_interp); - String[] random_palette_alg_str = {"Golden Ratio", "Waves", "Distance", "Triad", "Tetrad", "Google Material", "ColorBrewer 1", "ColorBrewer 2", "Google-ColorBrewer", "Cubehelix", "IQ-Cosines", "Perlin", "Simplex", "Perlin+Simplex", "Random Walk"}; + String[] random_palette_alg_str = {"Golden Ratio", "Waves", "Distance", "Triad", "Tetrad", "Google Material", "ColorBrewer 1", "ColorBrewer 2", "Google-ColorBrewer", "Cubehelix", "IQ-Cosines", "Perlin", "Simplex", "Perlin+Simplex", "Random Walk", "Simple Random"}; combo_box_random_palette_alg = new JComboBox<>(random_palette_alg_str); combo_box_random_palette_alg.setSelectedIndex(random_palette_algorithm); @@ -2250,7 +2253,7 @@ public static Color[] randomPalette(Random generator, boolean createFullPalette, if (color_space == MainWindow.COLOR_SPACE_LCH_ab) { res = ColorSpaceConverter.LCH_abtoRGB(brightness * 100.0, generator.nextDouble() * 140.0, generator.nextDouble() * 360.0); } else if (color_space == MainWindow.COLOR_SPACE_LAB) { - res = ColorSpaceConverter.LABtoRGB(brightness * 100.0, (2 * generator.nextDouble() - 1) * 100, (2 * generator.nextDouble() - 1) * 100); + res = ColorSpaceConverter.LABtoRGB(brightness * 100.0, generator.nextDouble() * 184.43 - 86.17, generator.nextDouble() * 202.33 - 107.85); } else if (color_space == MainWindow.COLOR_SPACE_HSL){ res = ColorSpaceConverter.HSLtoRGB(generator.nextDouble(), generator.nextDouble(), brightness); } @@ -2295,7 +2298,7 @@ else if (color_space == MainWindow.COLOR_SPACE_HSL) { else if (color_space == MainWindow.COLOR_SPACE_RYB) { res = ColorSpaceConverter.RYBtoRGB((0.5 * (Math.sin(Math.PI / a_coeff * (m + 1) + random_a) + 1)), (0.5 * (Math.sin(Math.PI / b_coeff * (m + 1) + random_b) + 1)), (0.5 * (Math.sin(Math.PI / c_coeff * (m + 1) + random_c) + 1))); } else if (color_space == MainWindow.COLOR_SPACE_LAB) { - res = ColorSpaceConverter.LABtoRGB((50 * (Math.sin(Math.PI / a_coeff * (m + 1) + random_a) + 1)), (100 * (Math.sin(Math.PI / b_coeff * (m + 1) + random_b))), (100 * (Math.sin(Math.PI / c_coeff * (m + 1) + random_c)))); + res = ColorSpaceConverter.LABtoRGB((50 * (Math.sin(Math.PI / a_coeff * (m + 1) + random_a) + 1)), (184.43 * ((Math.sin(Math.PI / b_coeff * (m + 1) + random_b) + 1) * 0.5) - 86.17), (202.33 * ((Math.sin(Math.PI / c_coeff * (m + 1) + random_c)+ 1) * 0.5) - 107.85)); } else if (color_space == MainWindow.COLOR_SPACE_XYZ) { res = ColorSpaceConverter.XYZtoRGB((50 * (Math.sin(Math.PI / a_coeff * (m + 1) + random_a) + 1)), (50 * (Math.sin(Math.PI / b_coeff * (m + 1) + random_b) + 1)), (50 * (Math.sin(Math.PI / c_coeff * (m + 1) + random_c) + 1))); } else if (color_space == MainWindow.COLOR_SPACE_LCH_ab) { @@ -2708,21 +2711,20 @@ else if (random_palette_alg == 10) { double a = 0, incr = (Math.PI * 2) / palette.length; - Random r = new Random(); - PerlinNoiseGenerator gen_red = PerlinNoiseGenerator.newBuilder().setSeed(r.nextInt(1000000)).setInterpolation(Interpolation.LINEAR).setFadeFunction(FadeFunction.QUINTIC_POLY).build(); + PerlinNoiseGenerator gen_red = PerlinNoiseGenerator.newBuilder().setSeed(generator.nextInt(1000000)).setInterpolation(Interpolation.LINEAR).setFadeFunction(FadeFunction.QUINTIC_POLY).build(); - PerlinNoiseGenerator gen_green = PerlinNoiseGenerator.newBuilder().setSeed(r.nextInt(1000000)).setInterpolation(Interpolation.LINEAR).setFadeFunction(FadeFunction.QUINTIC_POLY).build(); + PerlinNoiseGenerator gen_green = PerlinNoiseGenerator.newBuilder().setSeed(generator.nextInt(1000000)).setInterpolation(Interpolation.LINEAR).setFadeFunction(FadeFunction.QUINTIC_POLY).build(); - PerlinNoiseGenerator gen_blue = PerlinNoiseGenerator.newBuilder().setSeed(r.nextInt(1000000)).setInterpolation(Interpolation.LINEAR).setFadeFunction(FadeFunction.QUINTIC_POLY).build(); + PerlinNoiseGenerator gen_blue = PerlinNoiseGenerator.newBuilder().setSeed(generator.nextInt(1000000)).setInterpolation(Interpolation.LINEAR).setFadeFunction(FadeFunction.QUINTIC_POLY).build(); - double noise_max_red = r.nextDouble() * 3 + 0.2; - double noise_max_green = r.nextDouble() * 3 + 0.2; - double noise_max_blue = r.nextDouble() * 3 + 0.2; + double noise_max_red = generator.nextDouble() * 3 + 0.2; + double noise_max_green = generator.nextDouble() * 3 + 0.2; + double noise_max_blue = generator.nextDouble() * 3 + 0.2; - double phase_red = r.nextDouble() * 10; - double phase_green = r.nextDouble() * 10; - double phase_blue = r.nextDouble() * 10; + double phase_red = generator.nextDouble() * 10; + double phase_green = generator.nextDouble() * 10; + double phase_blue = generator.nextDouble() * 10; double[] noise_red = new double[palette.length]; double[] noise_green = new double[palette.length]; @@ -2802,21 +2804,19 @@ else if (random_palette_alg == 12) { double a = 0, incr = (Math.PI * 2) / palette.length; - Random r = new Random(); - - FastSimplexNoiseGenerator gen_red = FastSimplexNoiseGenerator.newBuilder().setSeed(r.nextInt(1000000)).build(); + FastSimplexNoiseGenerator gen_red = FastSimplexNoiseGenerator.newBuilder().setSeed(generator.nextInt(1000000)).build(); - FastSimplexNoiseGenerator gen_green = FastSimplexNoiseGenerator.newBuilder().setSeed(r.nextInt(1000000)).build(); + FastSimplexNoiseGenerator gen_green = FastSimplexNoiseGenerator.newBuilder().setSeed(generator.nextInt(1000000)).build(); - FastSimplexNoiseGenerator gen_blue = FastSimplexNoiseGenerator.newBuilder().setSeed(r.nextInt(1000000)).build(); + FastSimplexNoiseGenerator gen_blue = FastSimplexNoiseGenerator.newBuilder().setSeed(generator.nextInt(1000000)).build(); - double noise_max_red = r.nextDouble() * 3 + 0.2; - double noise_max_green = r.nextDouble() * 3 + 0.2; - double noise_max_blue = r.nextDouble() * 3 + 0.2; + double noise_max_red = generator.nextDouble() * 3 + 0.2; + double noise_max_green = generator.nextDouble() * 3 + 0.2; + double noise_max_blue = generator.nextDouble() * 3 + 0.2; - double phase_red = r.nextDouble() * 10; - double phase_green = r.nextDouble() * 10; - double phase_blue = r.nextDouble() * 10; + double phase_red = generator.nextDouble() * 10; + double phase_green = generator.nextDouble() * 10; + double phase_blue = generator.nextDouble() * 10; double[] noise_red = new double[palette.length]; double[] noise_green = new double[palette.length]; @@ -2896,36 +2896,35 @@ else if (random_palette_alg == 13) { double a = 0, incr = (Math.PI * 2) / palette.length; - Random r = new Random(); - FastSimplexNoiseGenerator gen_red = FastSimplexNoiseGenerator.newBuilder().setSeed(r.nextInt(1000000)).build(); + FastSimplexNoiseGenerator gen_red = FastSimplexNoiseGenerator.newBuilder().setSeed(generator.nextInt(1000000)).build(); - FastSimplexNoiseGenerator gen_green = FastSimplexNoiseGenerator.newBuilder().setSeed(r.nextInt(1000000)).build(); + FastSimplexNoiseGenerator gen_green = FastSimplexNoiseGenerator.newBuilder().setSeed(generator.nextInt(1000000)).build(); - FastSimplexNoiseGenerator gen_blue = FastSimplexNoiseGenerator.newBuilder().setSeed(r.nextInt(1000000)).build(); + FastSimplexNoiseGenerator gen_blue = FastSimplexNoiseGenerator.newBuilder().setSeed(generator.nextInt(1000000)).build(); - PerlinNoiseGenerator gen_red2 = PerlinNoiseGenerator.newBuilder().setSeed(r.nextInt(1000000)).setInterpolation(Interpolation.LINEAR).setFadeFunction(FadeFunction.QUINTIC_POLY).build(); + PerlinNoiseGenerator gen_red2 = PerlinNoiseGenerator.newBuilder().setSeed(generator.nextInt(1000000)).setInterpolation(Interpolation.LINEAR).setFadeFunction(FadeFunction.QUINTIC_POLY).build(); - PerlinNoiseGenerator gen_green2 = PerlinNoiseGenerator.newBuilder().setSeed(r.nextInt(1000000)).setInterpolation(Interpolation.LINEAR).setFadeFunction(FadeFunction.QUINTIC_POLY).build(); + PerlinNoiseGenerator gen_green2 = PerlinNoiseGenerator.newBuilder().setSeed(generator.nextInt(1000000)).setInterpolation(Interpolation.LINEAR).setFadeFunction(FadeFunction.QUINTIC_POLY).build(); - PerlinNoiseGenerator gen_blue2 = PerlinNoiseGenerator.newBuilder().setSeed(r.nextInt(1000000)).setInterpolation(Interpolation.LINEAR).setFadeFunction(FadeFunction.QUINTIC_POLY).build(); + PerlinNoiseGenerator gen_blue2 = PerlinNoiseGenerator.newBuilder().setSeed(generator.nextInt(1000000)).setInterpolation(Interpolation.LINEAR).setFadeFunction(FadeFunction.QUINTIC_POLY).build(); - double noise_max_red = r.nextDouble() * 3 + 0.2; - double noise_max_green = r.nextDouble() * 3 + 0.2; - double noise_max_blue = r.nextDouble() * 3 + 0.2; + double noise_max_red = generator.nextDouble() * 3 + 0.2; + double noise_max_green = generator.nextDouble() * 3 + 0.2; + double noise_max_blue = generator.nextDouble() * 3 + 0.2; - double phase_red = r.nextDouble() * 10; - double phase_green = r.nextDouble() * 10; - double phase_blue = r.nextDouble() * 10; + double phase_red = generator.nextDouble() * 10; + double phase_green = generator.nextDouble() * 10; + double phase_blue = generator.nextDouble() * 10; - double noise_max_red2 = r.nextDouble() * 3 + 0.2; - double noise_max_green2 = r.nextDouble() * 3 + 0.2; - double noise_max_blue2 = r.nextDouble() * 3 + 0.2; + double noise_max_red2 = generator.nextDouble() * 3 + 0.2; + double noise_max_green2 = generator.nextDouble() * 3 + 0.2; + double noise_max_blue2 = generator.nextDouble() * 3 + 0.2; - double phase_red2 = r.nextDouble() * 10; - double phase_green2 = r.nextDouble() * 10; - double phase_blue2 = r.nextDouble() * 10; + double phase_red2 = generator.nextDouble() * 10; + double phase_green2 = generator.nextDouble() * 10; + double phase_blue2 = generator.nextDouble() * 10; double[] noise_red = new double[palette.length]; double[] noise_green = new double[palette.length]; @@ -3012,21 +3011,20 @@ else if (random_palette_alg == 13) { } } else if(random_palette_alg == 14) { - Random r = new Random(); - int red = r.nextInt(256); - int green = r.nextInt(256); - int blue = r.nextInt(256); + int red = generator.nextInt(256); + int green = generator.nextInt(256); + int blue = generator.nextInt(256); int [] vals = new int[] {30, 15, 20, 10, 25}; for (int m = 0; m < palette.length; m++) { palette[m][0] = same_hues ? hues : generator.nextInt(12) + 7; - int val = vals[r.nextInt(vals.length)]; + int val = vals[generator.nextInt(vals.length)]; - red += r.nextBoolean() ? val : -val; - green += r.nextBoolean() ? val : -val; - blue += r.nextBoolean() ? val : -val; + red += generator.nextBoolean() ? val : -val; + green += generator.nextBoolean() ? val : -val; + blue += generator.nextBoolean() ? val : -val; if(red < 0) { red += 2*val; @@ -3069,6 +3067,94 @@ else if(random_palette_alg == 14) { c = CustomPalette.getPalette(palette, color_interpolation, color_space, reverse_palette, color_cycling, processing_val, processing_alg); } } + else if(random_palette_alg == 15) { + + int type = generator.nextInt(11); + + for (int m = 0; m < palette.length; m++) { + palette[m][0] = same_hues ? hues : generator.nextInt(12) + 7; + + int red, green, blue; + if(type == 1) { + int[] rgb = ColorSpaceConverter.HSBtoRGB(generator.nextDouble(), generator.nextDouble(), generator.nextDouble()); + red = rgb[0]; + green = rgb[1]; + blue = rgb[2]; + } + else if(type == 2) { + int[] rgb = ColorSpaceConverter.HSLtoRGB(generator.nextDouble(), generator.nextDouble(), generator.nextDouble()); + red = rgb[0]; + green = rgb[1]; + blue = rgb[2]; + } + else if(type == 3) { + int[] rgb = ColorSpaceConverter.RYBtoRGB(generator.nextDouble(), generator.nextDouble(), generator.nextDouble()); + red = rgb[0]; + green = rgb[1]; + blue = rgb[2]; + } + else if(type == 4) { + int[] rgb = ColorSpaceConverter.HWBtoRGB(generator.nextDouble(), generator.nextDouble(), generator.nextDouble()); + red = rgb[0]; + green = rgb[1]; + blue = rgb[2]; + } + else if(type == 5) { + int[] rgb = ColorSpaceConverter.LCH_abtoRGB(generator.nextDouble() * 100.0, generator.nextDouble() * 140.0, generator.nextDouble() * 360.0); + red = rgb[0]; + green = rgb[1]; + blue = rgb[2]; + } + else if(type == 6) { + int[] rgb = ColorSpaceConverter.LCH_oklabtoRGB(generator.nextDouble(), generator.nextDouble() * 0.3224, generator.nextDouble() * 360); + red = rgb[0]; + green = rgb[1]; + blue = rgb[2]; + } + else if(type == 7) { + int[] rgb = ColorSpaceConverter.LCH_uvtoRGB(generator.nextDouble() * 100, generator.nextDouble() * 179.08, generator.nextDouble() * 360); + red = rgb[0]; + green = rgb[1]; + blue = rgb[2]; + } + else if(type == 8) { + int[] rgb = ColorSpaceConverter.HSL_uvtoRGB(generator.nextDouble() * 360, generator.nextDouble() * 128, generator.nextDouble() * 100); + red = rgb[0]; + green = rgb[1]; + blue = rgb[2]; + } + else if(type == 9) { + int[] rgb = ColorSpaceConverter.XYZtoRGB(generator.nextDouble() * 100, generator.nextDouble() * 100, generator.nextDouble() * 100); + red = rgb[0]; + green = rgb[1]; + blue = rgb[2]; + } + else if(type == 9) { + int[] rgb = ColorSpaceConverter.LABtoRGB(generator.nextDouble() * 100, generator.nextDouble() * 184.43 - 86.17, generator.nextDouble() * 202.33 - 107.85); + red = rgb[0]; + green = rgb[1]; + blue = rgb[2]; + } + else { + red = generator.nextInt(256); + green = generator.nextInt(256); + blue = generator.nextInt(256); + } + + palette[m][1] = red; + palette[m][2] = green; + palette[m][3] = blue; + + + palette[m][1] = pastel ? ColorSpaceConverter.pastel(palette[m][1], 0) : palette[m][1]; + palette[m][2] = pastel ? ColorSpaceConverter.pastel(palette[m][2], 1) : palette[m][2]; + palette[m][3] = pastel ? ColorSpaceConverter.pastel(palette[m][3], 2) : palette[m][3]; + } + + if (createFullPalette) { + c = CustomPalette.getPalette(palette, color_interpolation, color_space, reverse_palette, color_cycling, processing_val, processing_alg); + } + } return c; diff --git a/src/fractalzoomer/gui/D3Dialog.java b/src/fractalzoomer/gui/D3Dialog.java index 951dfae3f..49722f5c9 100644 --- a/src/fractalzoomer/gui/D3Dialog.java +++ b/src/fractalzoomer/gui/D3Dialog.java @@ -169,12 +169,6 @@ public D3Dialog(MainWindow ptr, Settings s) { gaussian_scaling_opt.setEnabled(!bilateral_scaling_opt.isSelected()); }); - - /*final JCheckBox histogram_opt = new JCheckBox("Histogram Equalization"); - histogram_opt.setSelected(s.d3s.histogram_equalization); - histogram_opt.setFocusable(false); - histogram_opt.setToolTipText("Enables the histogram equalization.");*/ - JSlider color_blend = new JSlider(JSlider.HORIZONTAL, 0, 100, ((int) (s.d3s.color_3d_blending * 100))); color_blend.setPreferredSize(new Dimension(270, 35)); color_blend.setMajorTickSpacing(25); @@ -365,32 +359,6 @@ public D3Dialog(MainWindow ptr, Settings s) { temp_p4.add(field2); temp_p4.add(invert_orientation); - - /*final JTextField field_granularity = new JTextField(); - field_granularity.setText("" + s.d3s.histogram_granularity); - field_granularity.setEnabled(s.d3s.histogram_equalization); - - final JTextField field_density = new JTextField(); - field_density.setText("" + s.d3s.histogram_density); - field_density.setEnabled(s.d3s.histogram_equalization);*/ - - /*JPanel temp_p4 = new JPanel(); - temp_p4.setLayout(new GridLayout(2, 2)); - temp_p4.add(new JLabel("Bin Granularity:", SwingConstants.HORIZONTAL)); - temp_p4.add(new JLabel("Density:", SwingConstants.HORIZONTAL)); - temp_p4.add(field_granularity); - temp_p4.add(field_density);*/ - - /*histogram_opt.addActionListener(e -> { - if (histogram_opt.isSelected()) { - field_granularity.setEnabled(true); - field_density.setEnabled(true); - } else { - field_granularity.setEnabled(false); - field_density.setEnabled(false); - } - });*/ - JButton d3Pbutton = new MyButton("Processing 3D"); d3Pbutton.setFocusable(false); d3Pbutton.setIcon(MainWindow.getIcon("3d.png")); @@ -422,9 +390,6 @@ public D3Dialog(MainWindow ptr, Settings s) { "Select the gaussian/bilateral smoothing sigma and kernel length.", p40, temp_p, - //"Select histogram height equalization parameters.", - //histogram_opt, - //temp_p4, " ", tabbedPane,}; @@ -506,20 +471,6 @@ public void windowClosing(WindowEvent we) { return; } - /*if(temp5 < 1) { - JOptionPane.showMessageDialog(ptra, "The histogram bin granularity must be greater than 0.", "Error!", JOptionPane.ERROR_MESSAGE); - return; - } - - if(temp5 > 50) { - JOptionPane.showMessageDialog(ptra, "The histogram bin granularity must be lower than 51.", "Error!", JOptionPane.ERROR_MESSAGE); - return; - } - - if (temp6 <= 0) { - JOptionPane.showMessageDialog(ptra, "The histogram density must be greater than 0.", "Error!", JOptionPane.ERROR_MESSAGE); - return; - }*/ s.d3s.detail = temp; s.d3s.d3_height_scale = temp2; @@ -547,9 +498,6 @@ public void windowClosing(WindowEvent we) { //d3_draw_method = draw_choice.getSelectedIndex(); s.d3s.color_3d_blending = color_blend.getValue() / 100.0; - //s.d3s.histogram_equalization = histogram_opt.isSelected(); - //s.d3s.histogram_granularity = temp5; - //s.d3s.histogram_density = temp6; s.d3s.preHeightScaling = preHeightScaling.isSelected(); TaskDraw.D3_APPLY_AVERAGE_TO_TRIANGLE_COLORS = triangle_coloring.getSelectedIndex(); diff --git a/src/fractalzoomer/gui/DomainColoringFrame.java b/src/fractalzoomer/gui/DomainColoringFrame.java index 98469a112..7f5654b6f 100644 --- a/src/fractalzoomer/gui/DomainColoringFrame.java +++ b/src/fractalzoomer/gui/DomainColoringFrame.java @@ -270,6 +270,7 @@ public void windowClosing(WindowEvent e) { s.ds = CustomDomainColoringFrame.getSettings(); + s.old_max_iterations = s.max_iterations; s.max_iterations = tempIterations; if (presetButton.isSelected()) { diff --git a/src/fractalzoomer/gui/DrawingAlgorithmsFrame.java b/src/fractalzoomer/gui/DrawingAlgorithmsFrame.java index 138d9f0ef..61439ea10 100644 --- a/src/fractalzoomer/gui/DrawingAlgorithmsFrame.java +++ b/src/fractalzoomer/gui/DrawingAlgorithmsFrame.java @@ -18,6 +18,7 @@ import fractalzoomer.core.TaskDraw; import fractalzoomer.core.drawing_algorithms.CircularBruteForceDraw; +import fractalzoomer.core.drawing_algorithms.CircularSuccessiveRefinementGuessing2Draw; import fractalzoomer.core.drawing_algorithms.CircularSuccessiveRefinementGuessingDraw; import fractalzoomer.main.ImageExpanderWindow; import fractalzoomer.main.MainWindow; @@ -38,9 +39,13 @@ public class DrawingAlgorithmsFrame extends JFrame { private JFrame this_frame; private JRadioButton successive_refinement; private JRadioButton circular_successive_refinement; + + private JRadioButton divide_and_conquer_algorithm; private JCheckBox greedy_algorithm_opt; + private JComboBox mix_squares_and_rectangles; private JComboBox guessess; + private JCheckBox twoPassSuccessiveRefinement; public DrawingAlgorithmsFrame(Component ptra, boolean greedy_algorithm, int greedy_algorithm_selection, int brute_force_alg, int guesses_selection) { @@ -50,7 +55,7 @@ public DrawingAlgorithmsFrame(Component ptra, boolean greedy_algorithm, int gree ptra2.setEnabled(false); int color_window_width = 800; - int color_window_height = 520; + int color_window_height = 550; setTitle("Drawing Algorithms"); setSize(color_window_width, color_window_height); setIconImage(MainWindow.getIcon("greedy_algorithm.png").getImage()); @@ -68,12 +73,12 @@ public void windowClosing(WindowEvent e) { }); JPanel options_panel = new JPanel(); - options_panel.setPreferredSize(new Dimension(700, 260)); + options_panel.setPreferredSize(new Dimension(700, 290)); options_panel.setBackground(MainWindow.bg_color); options_panel.setLayout(new FlowLayout()); JPanel options_panel2 = new JPanel(); - options_panel2.setPreferredSize(new Dimension(680, 220)); + options_panel2.setPreferredSize(new Dimension(680, 250)); options_panel2.setBackground(MainWindow.bg_color); options_panel2.setLayout(new GridLayout(2, 1)); @@ -103,7 +108,7 @@ public void windowClosing(WindowEvent e) { boundary_tracing_opt.setToolTipText("Calculates only the boundaries of the image."); boundary_tracing_opt.setBackground(MainWindow.bg_color); - final JRadioButton divide_and_conquer_algorithm = new JRadioButton("Mariani/Silver"); + divide_and_conquer_algorithm = new JRadioButton("Mariani/Silver"); divide_and_conquer_algorithm.setFocusable(false); divide_and_conquer_algorithm.setToolTipText("Divides the image in halves and skips rectangles with the same boundary."); divide_and_conquer_algorithm.setBackground(MainWindow.bg_color); @@ -113,9 +118,9 @@ public void windowClosing(WindowEvent e) { successive_refinement.setToolTipText("Successively increases the resolution and performs guessing."); successive_refinement.setBackground(MainWindow.bg_color); - circular_successive_refinement = new JRadioButton("Circular Successive Refinement"); + circular_successive_refinement = new JRadioButton("Patterned Successive Refinement"); circular_successive_refinement.setFocusable(false); - circular_successive_refinement.setToolTipText("Successively increases the resolution and performs guessing, using a circular rendering method."); + circular_successive_refinement.setToolTipText("Successively increases the resolution and performs guessing, using a patterned rendering method."); circular_successive_refinement.setBackground(MainWindow.bg_color); final JCheckBox trace_iter_data = new JCheckBox("Use Iteration Data"); @@ -124,7 +129,19 @@ public void windowClosing(WindowEvent e) { trace_iter_data.setBackground(MainWindow.bg_color); trace_iter_data.setSelected(TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA); - guessess = new JComboBox<>(new String[] {"No", "1x1", "<= 2x2", "<= 4x4", "<= 8x8", "<= 16x16", "<= 32x32", "<= 64x64"}); + mix_squares_and_rectangles = new JComboBox<>(new String[]{"Square", "Square/Rectangle H", "Square/Rectangle V", "Square/Rectangle HV", "Square/Rectangle VH"}); + mix_squares_and_rectangles.setFocusable(false); + mix_squares_and_rectangles.setToolTipText("Configure how the successive refinement algorithm will split the area."); + mix_squares_and_rectangles.setBackground(MainWindow.bg_color); + mix_squares_and_rectangles.setSelectedIndex(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM); + + twoPassSuccessiveRefinement = new JCheckBox("2 Steps"); + twoPassSuccessiveRefinement.setFocusable(false); + twoPassSuccessiveRefinement.setToolTipText("Changes the successive refinement algorithms to used two steps."); + twoPassSuccessiveRefinement.setSelected(TaskDraw.TWO_PASS_SUCCESSIVE_REFINEMENT); + twoPassSuccessiveRefinement.setBackground(MainWindow.bg_color); + + guessess = new JComboBox<>(new String[] {"No", "1x", "<= 2x", "<= 4x", "<= 8x", "<= 16x", "<= 32x", "<= 64x"}); guessess.setSelectedIndex(guesses_selection); guessess.setFocusable(false); guessess.setToolTipText("Sets the blocks to be guessed by the successive refinement algorithms."); @@ -134,9 +151,25 @@ public void windowClosing(WindowEvent e) { greedy_algorithm_button_group.add(successive_refinement); greedy_algorithm_button_group.add(circular_successive_refinement); - circular_successive_refinement.addItemListener(e->guessess.setEnabled(circular_successive_refinement.isSelected() || successive_refinement.isSelected())); + circular_successive_refinement.addItemListener(e-> + { + guessess.setEnabled(circular_successive_refinement.isSelected() || successive_refinement.isSelected()); + mix_squares_and_rectangles.setEnabled(divide_and_conquer_algorithm.isSelected() || successive_refinement.isSelected() || circular_successive_refinement.isSelected()); + twoPassSuccessiveRefinement.setEnabled(circular_successive_refinement.isSelected() || successive_refinement.isSelected()); + }); + + successive_refinement.addItemListener(e-> { + guessess.setEnabled(circular_successive_refinement.isSelected() || successive_refinement.isSelected()); + mix_squares_and_rectangles.setEnabled(divide_and_conquer_algorithm.isSelected() || successive_refinement.isSelected() || circular_successive_refinement.isSelected()); + twoPassSuccessiveRefinement.setEnabled(circular_successive_refinement.isSelected() || successive_refinement.isSelected()); + } + ); - successive_refinement.addItemListener(e->guessess.setEnabled(circular_successive_refinement.isSelected() || successive_refinement.isSelected())); + divide_and_conquer_algorithm.addItemListener(e-> { + mix_squares_and_rectangles.setEnabled(divide_and_conquer_algorithm.isSelected() || successive_refinement.isSelected() || circular_successive_refinement.isSelected()); + twoPassSuccessiveRefinement.setEnabled(circular_successive_refinement.isSelected() || successive_refinement.isSelected()); + } + ); if(greedy_algorithm_selection == MainWindow.BOUNDARY_TRACING) { boundary_tracing_opt.setSelected(true); @@ -153,18 +186,32 @@ else if(greedy_algorithm_selection == MainWindow.CIRCULAR_SUCCESSIVE_REFINEMENT) JPanel p1 = new JPanel(); p1.setBackground(MainWindow.bg_color); - p1.setLayout(new GridLayout(2, 2)); + p1.setLayout(new GridLayout(4, 1)); p1.add(boundary_tracing_opt); p1.add(divide_and_conquer_algorithm); p1.add(successive_refinement); p1.add(circular_successive_refinement); greedy_algorithm_panel.add(p1); - greedy_algorithm_panel.add(trace_iter_data); + + + + JPanel p11 = new JPanel(); + p11.setBackground(MainWindow.bg_color); + p11.add(mix_squares_and_rectangles); + + JPanel p7 = new JPanel(); + p7.setBackground(MainWindow.bg_color); + p7.setLayout(new GridLayout(2, 1)); + p7.add(trace_iter_data); + p7.add(twoPassSuccessiveRefinement); + + + greedy_algorithm_panel.add(p7); JPanel p2 = new JPanel(); p2.setBackground(MainWindow.bg_color); - p2.setLayout(new GridLayout(2, 1)); + p2.setLayout(new GridLayout(3, 1)); JPanel p3 = new JPanel(); p3.setBackground(MainWindow.bg_color); @@ -175,6 +222,7 @@ else if(greedy_algorithm_selection == MainWindow.CIRCULAR_SUCCESSIVE_REFINEMENT) p4.add(new JLabel("Guess Blocks:")); p2.add(p4); p2.add(p3); + p2.add(p11); greedy_algorithm_panel.add(p2); @@ -280,17 +328,31 @@ public void mouseExited(MouseEvent e) { panel3.setBackground(MainWindow.bg_color); panel3.setPreferredSize(new Dimension(704, 60)); - JComboBox brute_force_alg_opt = new JComboBox<>(new String[] {"Chunks", "Thread Split", "Circular Chunks"}); + JComboBox brute_force_alg_opt = new JComboBox<>(new String[] {"Chunks", "Thread Split", "Patterned Chunks", "Interleaved"}); brute_force_alg_opt.setSelectedIndex(brute_force_alg); brute_force_alg_opt.setFocusable(false); brute_force_alg_opt.setToolTipText("Sets the brute force algorithm."); brute_force_alg_opt.setEnabled(!greedy_algorithm_opt.isSelected()); - greedy_algorithm_opt.addActionListener(e -> brute_force_alg_opt.setEnabled(!greedy_algorithm_opt.isSelected())); + JCheckBox chunksPerRow = new JCheckBox("1 Chunk per row"); + chunksPerRow.setFocusable(false); + chunksPerRow.setSelected(TaskDraw.CHUNK_SIZE_PER_ROW); + chunksPerRow.setBackground(MainWindow.bg_color); + + chunksPerRow.setEnabled(!greedy_algorithm_opt.isSelected() && brute_force_alg_opt.getSelectedIndex() == 0); + + greedy_algorithm_opt.addActionListener(e -> { + brute_force_alg_opt.setEnabled(!greedy_algorithm_opt.isSelected()); + chunksPerRow.setEnabled(!greedy_algorithm_opt.isSelected() && brute_force_alg_opt.getSelectedIndex() == 0); + } + ); + + brute_force_alg_opt.addActionListener(e -> chunksPerRow.setEnabled(!greedy_algorithm_opt.isSelected() && brute_force_alg_opt.getSelectedIndex() == 0)); panel3.add(new JLabel("Brute Force Algorithm: ")); panel3.add(brute_force_alg_opt); + panel3.add(chunksPerRow); panel3.setBorder(BorderFactory.createTitledBorder(BorderFactory.createCompoundBorder(BorderFactory.createRaisedBevelBorder(), BorderFactory.createLoweredBevelBorder()), "Brute Force Options", TitledBorder.DEFAULT_POSITION, TitledBorder.DEFAULT_POSITION)); @@ -299,10 +361,10 @@ public void mouseExited(MouseEvent e) { panel4.setBackground(MainWindow.bg_color); panel4.setPreferredSize(new Dimension(704, 60)); - JComboBox circular_pattern = new JComboBox<>(new String[] {"Circle", "Square", "Rhombus", "N-Norm", "Random", "Rectangle (Columns)", "Rectangle (Rows)", "Angle", "Double Angle", "Columns", "Rows", "Diagonal Top", "Diagonal Bottom", "Hourglass", "Star", "Cross"}); + JComboBox circular_pattern = new JComboBox<>(new String[] {"Circle", "Square", "Rhombus", "N-Norm", "Random", "Rectangle (Columns)", "Rectangle (Rows)", "Angle", "Double Angle", "Columns", "Rows", "Diagonal Top", "Diagonal Bottom", "Hourglass", "Star", "Cross", "Interleaved"}); circular_pattern.setSelectedIndex(TaskDraw.CIRCULAR_COMPARE_ALG); circular_pattern.setFocusable(false); - circular_pattern.setToolTipText("Sets the circular drawing pattern."); + circular_pattern.setToolTipText("Sets the drawing pattern."); JTextField nnorm = new JTextField(6); nnorm.setText("" + TaskDraw.CIRCULAR_N); @@ -326,15 +388,15 @@ public void mouseExited(MouseEvent e) { // pattern_follows_zoom_center.setFocusable(false); // pattern_follows_zoom_center.setToolTipText("If zoom on mouse cursor is enabled then, by enabling this the drawing pattern will initiate from the selected point (Requires sorting every time)."); - revert_pattern.setEnabled(circular_pattern.getSelectedIndex() != 4); - repeat_pattern.setEnabled(circular_pattern.getSelectedIndex() != 4); + revert_pattern.setEnabled(circular_pattern.getSelectedIndex() != 4 && circular_pattern.getSelectedIndex() != 16); + repeat_pattern.setEnabled(circular_pattern.getSelectedIndex() != 4 && circular_pattern.getSelectedIndex() != 16); // pattern_follows_zoom_center.setEnabled(ptra instanceof MainWindow && circular_pattern.getSelectedIndex() != 4); circular_pattern.addActionListener( e -> {nnorm.setEnabled(circular_pattern.getSelectedIndex() == 3); - revert_pattern.setEnabled(circular_pattern.getSelectedIndex() != 4); - repeat_pattern.setEnabled(circular_pattern.getSelectedIndex() != 4); + revert_pattern.setEnabled(circular_pattern.getSelectedIndex() != 4 && circular_pattern.getSelectedIndex() != 16); + repeat_pattern.setEnabled(circular_pattern.getSelectedIndex() != 4 && circular_pattern.getSelectedIndex() != 16); // pattern_follows_zoom_center.setEnabled(ptra instanceof MainWindow && circular_pattern.getSelectedIndex() != 4); }); @@ -346,7 +408,7 @@ public void mouseExited(MouseEvent e) { panel4.add(revert_pattern); // panel4.add(pattern_follows_zoom_center); - panel4.setBorder(BorderFactory.createTitledBorder(BorderFactory.createCompoundBorder(BorderFactory.createRaisedBevelBorder(), BorderFactory.createLoweredBevelBorder()), "Circular Pattern Options", TitledBorder.DEFAULT_POSITION, TitledBorder.DEFAULT_POSITION)); + panel4.setBorder(BorderFactory.createTitledBorder(BorderFactory.createCompoundBorder(BorderFactory.createRaisedBevelBorder(), BorderFactory.createLoweredBevelBorder()), "Pattern Options", TitledBorder.DEFAULT_POSITION, TitledBorder.DEFAULT_POSITION)); JButton ok = new MyButton("Ok"); @@ -397,49 +459,50 @@ else if(circular_successive_refinement.isSelected()) { TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA = trace_iter_data.isSelected(); TaskDraw.GUESS_BLOCKS_SELECTION = guessess.getSelectedIndex(); + int oldSuccessiveRefinementSplit = TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM; + TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM = mix_squares_and_rectangles.getSelectedIndex(); + TaskDraw.CHUNK_SIZE_PER_ROW = chunksPerRow.isSelected(); + TaskDraw.TWO_PASS_SUCCESSIVE_REFINEMENT = twoPassSuccessiveRefinement.isSelected(); + + if(oldSuccessiveRefinementSplit != TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM) { + TaskDraw.setSuccessiveRefinementChunks(); + CircularBruteForceDraw.clear(); + CircularBruteForceDraw.clearFastJulia(); + } + int oldCircularAlg = TaskDraw.CIRCULAR_COMPARE_ALG; TaskDraw.CIRCULAR_COMPARE_ALG = circular_pattern.getSelectedIndex(); if(oldCircularAlg != TaskDraw.CIRCULAR_COMPARE_ALG) { - CircularBruteForceDraw.coordinates = null; - CircularBruteForceDraw.coordinatesFastJulia = null; - CircularSuccessiveRefinementGuessingDraw.CoordinatesPerLevel = null; - CircularSuccessiveRefinementGuessingDraw.CoordinatesPerLevelFastJulia = null; + CircularBruteForceDraw.clear(); + CircularBruteForceDraw.clearFastJulia(); } boolean oldRevertPattern = TaskDraw.CIRCULAR_REVERT_ALG; TaskDraw.CIRCULAR_REVERT_ALG = revert_pattern.isSelected(); if(oldRevertPattern != TaskDraw.CIRCULAR_REVERT_ALG) { - CircularBruteForceDraw.coordinates = null; - CircularBruteForceDraw.coordinatesFastJulia = null; - CircularSuccessiveRefinementGuessingDraw.CoordinatesPerLevel = null; - CircularSuccessiveRefinementGuessingDraw.CoordinatesPerLevelFastJulia = null; + CircularBruteForceDraw.clear(); + CircularBruteForceDraw.clearFastJulia(); } boolean oldRepeatPattern = TaskDraw.CIRCULAR_REPEAT_ALG; TaskDraw.CIRCULAR_REPEAT_ALG = repeat_pattern.isSelected(); if(oldRepeatPattern != TaskDraw.CIRCULAR_REPEAT_ALG) { - CircularBruteForceDraw.coordinates = null; - CircularBruteForceDraw.coordinatesFastJulia = null; - CircularSuccessiveRefinementGuessingDraw.CoordinatesPerLevel = null; - CircularSuccessiveRefinementGuessingDraw.CoordinatesPerLevelFastJulia = null; + CircularBruteForceDraw.clear(); + CircularBruteForceDraw.clearFastJulia(); } double oldNnorm = TaskDraw.CIRCULAR_N; TaskDraw.CIRCULAR_N = temp; if(TaskDraw.CIRCULAR_N != oldNnorm) { - CircularBruteForceDraw.coordinates = null; - CircularBruteForceDraw.coordinatesFastJulia = null; - CircularSuccessiveRefinementGuessingDraw.CoordinatesPerLevel = null; - CircularSuccessiveRefinementGuessingDraw.CoordinatesPerLevelFastJulia = null; + CircularBruteForceDraw.clear(); + CircularBruteForceDraw.clearFastJulia(); } // boolean oldFollowZoom = MainWindow.CIRCULAR_DRAW_FOLLOWS_ZOOM_TO_CURSOR; // MainWindow.CIRCULAR_DRAW_FOLLOWS_ZOOM_TO_CURSOR = pattern_follows_zoom_center.isSelected(); // if(MainWindow.CIRCULAR_DRAW_FOLLOWS_ZOOM_TO_CURSOR != oldFollowZoom) { -// CircularBruteForceDraw.coordinates = null; -// CircularBruteForceDraw.coordinatesFastJulia = null; -// CircularSuccessiveRefinementGuessingDraw.CoordinatesPerLevel = null; -// CircularSuccessiveRefinementGuessingDraw.CoordinatesPerLevelFastJulia = null; +// CircularBruteForceDraw.clear(); +// CircularBruteForceDraw.clearFastJulia(); // } if(ptra2 instanceof MainWindow) { @@ -493,7 +556,10 @@ public void actionPerformed(ActionEvent e) options_border.setState(greedy_algorithm_opt.isSelected()); guessess.setEnabled(greedy_algorithm_opt.isSelected() && (circular_successive_refinement.isSelected() || successive_refinement.isSelected())); - + mix_squares_and_rectangles.setEnabled(greedy_algorithm_opt.isSelected() && (divide_and_conquer_algorithm.isSelected() || successive_refinement.isSelected() || circular_successive_refinement.isSelected())); + + twoPassSuccessiveRefinement.setEnabled(greedy_algorithm_opt.isSelected() && (circular_successive_refinement.isSelected() || successive_refinement.isSelected())); + JPanel buttons = new JPanel(); buttons.setBackground(MainWindow.bg_color); @@ -502,7 +568,7 @@ public void actionPerformed(ActionEvent e) RoundedPanel round_panel = new RoundedPanel(true, true, true, 15); round_panel.setBackground(MainWindow.bg_color); - round_panel.setPreferredSize(new Dimension(730, 440)); + round_panel.setPreferredSize(new Dimension(730, 470)); round_panel.setLayout(new GridBagLayout()); GridBagConstraints con = new GridBagConstraints(); @@ -551,6 +617,8 @@ public void toggled(boolean toggled) { } guessess.setEnabled(greedy_algorithm_opt.isSelected() && (circular_successive_refinement.isSelected() || successive_refinement.isSelected())); + mix_squares_and_rectangles.setEnabled(greedy_algorithm_opt.isSelected() && (divide_and_conquer_algorithm.isSelected() || successive_refinement.isSelected() || circular_successive_refinement.isSelected())); + twoPassSuccessiveRefinement.setEnabled(greedy_algorithm_opt.isSelected() && (circular_successive_refinement.isSelected() || successive_refinement.isSelected())); } } diff --git a/src/fractalzoomer/gui/FileMenu.java b/src/fractalzoomer/gui/FileMenu.java index e34d2c171..19cf94246 100644 --- a/src/fractalzoomer/gui/FileMenu.java +++ b/src/fractalzoomer/gui/FileMenu.java @@ -140,7 +140,7 @@ public FileMenu(MainWindow ptr2, String name) { starting_position.addActionListener(e -> ptr.startingPosition()); - repaint_opt.addActionListener(e -> ptr.redraw()); + repaint_opt.addActionListener(e -> ptr.redraw(false)); go_to.addActionListener(e -> ptr.goTo()); diff --git a/src/fractalzoomer/gui/FractalFunctionsMenu.java b/src/fractalzoomer/gui/FractalFunctionsMenu.java index 2f23a5af2..42ca75abf 100644 --- a/src/fractalzoomer/gui/FractalFunctionsMenu.java +++ b/src/fractalzoomer/gui/FractalFunctionsMenu.java @@ -476,6 +476,7 @@ public class FractalFunctionsMenu extends MyMenu { functionNames[MainWindow.PERPENDICULAR_BURNING_SHIP] = "Perpendicular Burning Ship"; functionNames[MainWindow.PERPENDICULAR_CELTIC_MANDELBROT] = "Perpendicular Celtic Mandelbrot"; functionNames[MainWindow.PERPENDICULAR_BUFFALO_MANDELBROT] = "Perpendicular Buffalo Mandelbrot"; + functionNames[MainWindow.FORMULA48] = "z = c(z^2 + z^-2)"; } public FractalFunctionsMenu(MainWindow ptr2, String name, int function) { @@ -710,6 +711,11 @@ public FractalFunctionsMenu(MainWindow ptr2, String name, int function) { c_azb_dze_type_functions.add(fractal_functions[MainWindow.FORMULA2]); functions_button_group.add(fractal_functions[MainWindow.FORMULA2]); + fractal_functions[MainWindow.FORMULA48] = new JRadioButtonMenuItem(functionNames[MainWindow.FORMULA48]); + fractal_functions[MainWindow.FORMULA48].addActionListener(e -> ptr.setFunction(MainWindow.FORMULA48)); + c_azb_dze_type_functions.add(fractal_functions[MainWindow.FORMULA48]); + functions_button_group.add(fractal_functions[MainWindow.FORMULA48]); + fractal_functions[MainWindow.FORMULA3] = new JRadioButtonMenuItem(functionNames[MainWindow.FORMULA3]); fractal_functions[MainWindow.FORMULA3].addActionListener(e -> ptr.setFunction(MainWindow.FORMULA3)); c_azb_dze_type_functions.add(fractal_functions[MainWindow.FORMULA3]); diff --git a/src/fractalzoomer/gui/HighPrecisionDialog.java b/src/fractalzoomer/gui/HighPrecisionDialog.java index efe7588b1..2a2dbd09e 100644 --- a/src/fractalzoomer/gui/HighPrecisionDialog.java +++ b/src/fractalzoomer/gui/HighPrecisionDialog.java @@ -73,6 +73,9 @@ public HighPrecisionDialog(Component ptr, Settings s) { automatic_precision.setSelected(MyApfloat.setAutomaticPrecision); automatic_precision.setFocusable(false); + final JCheckBox gatherHpStatistics = new JCheckBox("Display Statistics"); + gatherHpStatistics.setSelected(TaskDraw.GATHER_HIGHPRECISION_STATISTICS); + gatherHpStatistics.setFocusable(false); JTextField precision = new JTextField(); @@ -117,6 +120,8 @@ public HighPrecisionDialog(Component ptr, Settings s) { automaticBignumPrecision, "BigNum bits precision:", bignumPrecision, + " ", + gatherHpStatistics, " "}; optionPane = new JOptionPane(message3, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null, null, null); @@ -192,6 +197,7 @@ else if(tempAuto && !TaskDraw.BIGNUM_AUTOMATIC_PRECISION && tempPrecision == MyA MyApfloat.setAutomaticPrecision = automatic_precision.isSelected(); TaskDraw.HIGH_PRECISION_CALCULATION = enable_high_precision.isSelected(); + TaskDraw.GATHER_HIGHPRECISION_STATISTICS = gatherHpStatistics.isSelected(); TaskDraw.HIGH_PRECISION_LIB = arbitraryLibs.getSelectedIndex(); diff --git a/src/fractalzoomer/gui/HistogramColoringDialog.java b/src/fractalzoomer/gui/HistogramColoringDialog.java index e4beaafa7..d3ce46062 100644 --- a/src/fractalzoomer/gui/HistogramColoringDialog.java +++ b/src/fractalzoomer/gui/HistogramColoringDialog.java @@ -34,6 +34,7 @@ public class HistogramColoringDialog extends JDialog { private MainWindow ptra; private JOptionPane optionPane; + private final JScrollPane scrollPane; public HistogramColoringDialog(MainWindow ptr, Settings s, boolean greedy_algorithm, boolean julia_map) { @@ -41,6 +42,9 @@ public HistogramColoringDialog(MainWindow ptr, Settings s, boolean greedy_algori ptra = ptr; + scrollPane = new JScrollPane(); + scrollPane.setPreferredSize(new Dimension(700, 700)); + setTitle("Histogram Coloring"); setModal(true); setIconImage(MainWindow.getIcon("mandel2.png").getImage()); @@ -78,6 +82,11 @@ public HistogramColoringDialog(MainWindow ptr, Settings s, boolean greedy_algori outliersAlgorithm.setFocusable(false); outliersAlgorithm.setToolTipText("Sets the outlier removal method."); + JComboBox rankOrderDigitGrouping = new JComboBox<>(new String[] {"1", "2", "3", "4", "5", "6", "7", "8"}); + rankOrderDigitGrouping.setSelectedIndex(s.pps.hss.rank_order_digits_grouping); + rankOrderDigitGrouping.setFocusable(false); + rankOrderDigitGrouping.setToolTipText("Sets the fractional digits grouping for rank order."); + outliersAlgorithm.setEnabled(removeOutliers.isSelected()); removeOutliers.addActionListener(e -> outliersAlgorithm.setEnabled(removeOutliers.isSelected())); @@ -104,8 +113,11 @@ public HistogramColoringDialog(MainWindow ptr, Settings s, boolean greedy_algori mapping.addActionListener(e -> { density_field.setEnabled(mapping.getSelectedIndex() == 0); granularity_field.setEnabled(mapping.getSelectedIndex() == 0); + rankOrderDigitGrouping.setEnabled(mapping.getSelectedIndex() == 6); }); + rankOrderDigitGrouping.setEnabled(mapping.getSelectedIndex() == 6); + Object[] message = { " ", enable_histogram_coloring, @@ -120,6 +132,10 @@ public HistogramColoringDialog(MainWindow ptr, Settings s, boolean greedy_algori "Set the histogram bin granularity/density.", temp_p4, " ", + "Set the rank order fractional digits grouping.", + "Fractional Digits Grouping:", + rankOrderDigitGrouping, + " ", "Set the scaling range.", "Scaling Range:", scale_range, @@ -202,6 +218,7 @@ public void windowClosing(WindowEvent we) { s.pps.hss.hmapping = mapping.getSelectedIndex(); s.pps.hss.hs_remove_outliers = removeOutliers.isSelected(); s.pps.hss.hs_outliers_method = outliersAlgorithm.getSelectedIndex(); + s.pps.hss.rank_order_digits_grouping = rankOrderDigitGrouping.getSelectedIndex(); } catch (Exception ex) { JOptionPane.showMessageDialog(ptra, "Illegal Argument: " + ex.getMessage(), "Error!", JOptionPane.ERROR_MESSAGE); return; @@ -218,7 +235,8 @@ public void windowClosing(WindowEvent we) { }); //Make this dialog display it. - setContentPane(optionPane); + scrollPane.setViewportView(optionPane); + setContentPane(scrollPane); pack(); diff --git a/src/fractalzoomer/gui/HueGeneratedPalettes.java b/src/fractalzoomer/gui/HueGeneratedPalettes.java index 04a59dfe6..af564d1af 100644 --- a/src/fractalzoomer/gui/HueGeneratedPalettes.java +++ b/src/fractalzoomer/gui/HueGeneratedPalettes.java @@ -195,7 +195,7 @@ public void windowClosing(WindowEvent we) { TaskDraw.setAlgorithmColors(); ptr.updateColorPalettesMenu(); - ptr.updateColors(false); + ptr.updateColors(false, false); } catch (Exception ex) { JOptionPane.showMessageDialog(ptra, "Illegal Argument: " + ex.getMessage(), "Error!", JOptionPane.ERROR_MESSAGE); return; diff --git a/src/fractalzoomer/gui/IterationDialog.java b/src/fractalzoomer/gui/IterationDialog.java index 4cd3a5aef..35c9926fc 100644 --- a/src/fractalzoomer/gui/IterationDialog.java +++ b/src/fractalzoomer/gui/IterationDialog.java @@ -97,14 +97,15 @@ public void windowClosing(WindowEvent we) { return; } + s.old_max_iterations = s.max_iterations; s.max_iterations = (int)temp; } catch (Exception ex) { JOptionPane.showMessageDialog(ptra, "Illegal Argument: " + ex.getMessage(), "Error!", JOptionPane.ERROR_MESSAGE); return; } + ptr.onIterationsChange(); dispose(); - ptr.redraw(); } }); diff --git a/src/fractalzoomer/gui/JuliaSeedDialog.java b/src/fractalzoomer/gui/JuliaSeedDialog.java index f55649383..aeb5f008c 100644 --- a/src/fractalzoomer/gui/JuliaSeedDialog.java +++ b/src/fractalzoomer/gui/JuliaSeedDialog.java @@ -171,9 +171,9 @@ public void windowClosing(WindowEvent we) { try { if(MyApfloat.setAutomaticPrecision) { - long precision = MyApfloat.getAutomaticPrecision(new String[]{real_seed.getText(), imag_seed.getText()}, new boolean[] {false, false}); + long precision = MyApfloat.getAutomaticPrecision(new String[]{real_seed.getText(), imag_seed.getText()}, new boolean[] {false, false}, s.fns.function); - if (MyApfloat.shouldSetPrecision(precision, MyApfloat.alwaysCheckForDecrease)) { + if (MyApfloat.shouldSetPrecision(precision, MyApfloat.alwaysCheckForDecrease, s.fns.function)) { Fractal.clearReferences(true, true); MyApfloat.setPrecision(precision, s); } diff --git a/src/fractalzoomer/gui/MagnificationDialog.java b/src/fractalzoomer/gui/MagnificationDialog.java index bf64125f3..43be57c03 100644 --- a/src/fractalzoomer/gui/MagnificationDialog.java +++ b/src/fractalzoomer/gui/MagnificationDialog.java @@ -52,9 +52,9 @@ public MagnificationDialog(MainWindow ptr, Settings s, JTextArea field_size) { try { if(MyApfloat.setAutomaticPrecision) { - long precision = MyApfloat.getAutomaticPrecision(new String[]{field_size.getText()}, new boolean[] {true}); + long precision = MyApfloat.getAutomaticPrecision(new String[]{field_size.getText()}, new boolean[] {true}, s.fns.function); - if (MyApfloat.shouldSetPrecision(precision, MyApfloat.alwaysCheckForDecrease)) { + if (MyApfloat.shouldSetPrecision(precision, MyApfloat.alwaysCheckForDecrease, s.fns.function)) { Fractal.clearReferences(true, true); MyApfloat.setPrecision(precision, s); } @@ -127,9 +127,9 @@ public void windowClosing(WindowEvent we) { try { if(MyApfloat.setAutomaticPrecision) { - long precision = MyApfloat.getAutomaticPrecision(new String[]{magnification.getText()}, new boolean[] {true}); + long precision = MyApfloat.getAutomaticPrecision(new String[]{magnification.getText()}, new boolean[] {true}, s.fns.function); - if (MyApfloat.shouldSetPrecision(precision, MyApfloat.alwaysCheckForDecrease)) { + if (MyApfloat.shouldSetPrecision(precision, MyApfloat.alwaysCheckForDecrease, s.fns.function)) { Fractal.clearReferences(true, true); MyApfloat.setPrecision(precision, s); } diff --git a/src/fractalzoomer/gui/MainPanel.java b/src/fractalzoomer/gui/MainPanel.java index 9c6fd8c7b..35e447797 100644 --- a/src/fractalzoomer/gui/MainPanel.java +++ b/src/fractalzoomer/gui/MainPanel.java @@ -22,6 +22,8 @@ import javax.swing.*; import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.image.BufferedImage; @@ -29,13 +31,54 @@ * * @author hrkalona2 */ -public class MainPanel extends JPanel { +public class MainPanel extends JPanel implements ActionListener { private static final long serialVersionUID = 1059117419848617111L; private MainWindow ptr; + private Timer timer; + + public static int REPAINT_SLEEP_TIME = 24; public MainPanel(MainWindow ptr) { this.ptr = ptr; } + + public void setTimer(boolean quickDrawAndRefinement, TaskDraw[][] drawThreads) { + if(timer == null) { + timer = new Timer(REPAINT_SLEEP_TIME, this); + timer.start(); + } + else { + timer.stop(); + timer = null; + timer = new Timer(REPAINT_SLEEP_TIME, this); + } + + ptr.setWholeImageDone(!quickDrawAndRefinement); + if(!quickDrawAndRefinement) { + boolean isJulia = drawThreads[0][0].isJulia(); + boolean isJuliaMap = drawThreads[0][0].isJuliaMap(); + boolean isDomainColoring = drawThreads[0][0].isDomainColoring(); + boolean isNonJulia = drawThreads[0][0].isNonJulia(); + + if(isJulia || isNonJulia || isJuliaMap || isDomainColoring) { + ptr.reloadTitle(); + TaskDraw.updateMode(ptr, false, isJulia, isJuliaMap, isDomainColoring); + } + repaint(); + } + } + + @Override + public void actionPerformed(ActionEvent e) { + repaint(); + } + + public void stopTimer() { + if(timer != null) { + timer.stop(); + timer = null; + } + } @Override public void paintComponent(Graphics g) { diff --git a/src/fractalzoomer/gui/OptionsMenu.java b/src/fractalzoomer/gui/OptionsMenu.java index 9ae030367..dbc20fc4e 100644 --- a/src/fractalzoomer/gui/OptionsMenu.java +++ b/src/fractalzoomer/gui/OptionsMenu.java @@ -56,6 +56,7 @@ public class OptionsMenu extends MyMenu { private JMenuItem increase_rotation; private JMenuItem decrease_rotation; private JMenuItem bailout_number; + private JMenuItem convergent_bailout_number; private JMenuItem change_zooming_factor; private JMenuItem point_opt; private JMenuItem variables_opt; @@ -106,6 +107,9 @@ public OptionsMenu(MainWindow ptr2, String name, PaletteSettings ps, PaletteSett convergent_bailout_condition_menu = new ConvergentBailoutConditionsMenu(ptr, "Convergent Bailout Condition", convergent_bailout_test_algorithm); bailout_number = new MyMenuItem("Bailout", MainWindow.getIcon("bailout.png")); + convergent_bailout_number = new MyMenuItem("Convergent Bailout", MainWindow.getIcon("convergent_bailout.png")); + + convergent_bailout_number.setEnabled(false); rotation_menu = new MyMenu("Rotation"); rotation_menu.setIcon(MainWindow.getIcon("rotate.png")); @@ -165,6 +169,7 @@ public OptionsMenu(MainWindow ptr2, String name, PaletteSettings ps, PaletteSett decrease_iterations.setToolTipText("Decreases the maximum iterations number by one."); double_iterations.setToolTipText("Doubles the maximum iterations."); bailout_number.setToolTipText("Sets the bailout. Above this number the norm of a complex numbers is not bounded."); + convergent_bailout_number.setToolTipText("Sets the convergent bailout. This defines the acceptable error for converging functions."); set_rotation.setToolTipText("Sets the rotation in degrees."); point_opt.setToolTipText("A point picked by the user, for the point variable."); variables_opt.setToolTipText("Sets the values for the variables v1-v30."); @@ -193,6 +198,7 @@ public OptionsMenu(MainWindow ptr2, String name, PaletteSettings ps, PaletteSett decrease_iterations.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, ActionEvent.ALT_MASK)); double_iterations.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_2, ActionEvent.CTRL_MASK)); bailout_number.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_U, ActionEvent.ALT_MASK)); + convergent_bailout_number.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, ActionEvent.ALT_MASK)); set_rotation.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, ActionEvent.ALT_MASK)); increase_rotation.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, ActionEvent.CTRL_MASK)); decrease_rotation.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, ActionEvent.CTRL_MASK)); @@ -225,6 +231,7 @@ public OptionsMenu(MainWindow ptr2, String name, PaletteSettings ps, PaletteSett double_iterations.addActionListener(e -> ptr.doubleIterations()); bailout_number.addActionListener(e -> ptr.setBailout()); + convergent_bailout_number.addActionListener(e -> ptr.setConvergentBailout()); set_rotation.addActionListener(e -> ptr.setRotation()); @@ -300,6 +307,7 @@ public OptionsMenu(MainWindow ptr2, String name, PaletteSettings ps, PaletteSett add(bailout_condition_menu); add(bailout_number); add(convergent_bailout_condition_menu); + add(convergent_bailout_number); addSeparator(); add(rotation_menu); addSeparator(); @@ -481,6 +489,12 @@ public JRadioButtonMenuItem getLine() { } + public JRadioButtonMenuItem getLine2() { + + return tools_options_menu.getLine2(); + + } + public JRadioButtonMenuItem getDot() { return tools_options_menu.getDot(); @@ -517,6 +531,12 @@ public JMenuItem getBailout() { } + public JMenuItem getConvergentBailout() { + + return convergent_bailout_number; + + } + public BailoutConditionsMenu getBailoutConditionMenu() { return bailout_condition_menu; diff --git a/src/fractalzoomer/gui/PeriodDialog.java b/src/fractalzoomer/gui/PeriodDialog.java index 5310a0030..ef498f9f1 100644 --- a/src/fractalzoomer/gui/PeriodDialog.java +++ b/src/fractalzoomer/gui/PeriodDialog.java @@ -117,6 +117,7 @@ public void windowClosing(WindowEvent we) { return; } + s.old_max_iterations = s.max_iterations; s.max_iterations = (int) temp2; if(s.fns.period != temp && s.supportsPeriod() && (TaskDraw.APPROXIMATION_ALGORITHM == 3 || (TaskDraw.DETECT_PERIOD && TaskDraw.STOP_REFERENCE_CALCULATION_AFTER_DETECTED_PERIOD))) { @@ -130,7 +131,7 @@ public void windowClosing(WindowEvent we) { } dispose(); - ptr.redraw(); + ptr.onPeriodChange(); } }); diff --git a/src/fractalzoomer/gui/PerturbationTheoryDialog.java b/src/fractalzoomer/gui/PerturbationTheoryDialog.java index 59c75c786..54421ab40 100644 --- a/src/fractalzoomer/gui/PerturbationTheoryDialog.java +++ b/src/fractalzoomer/gui/PerturbationTheoryDialog.java @@ -100,6 +100,13 @@ public PerturbationTheoryDialog(Component ptr, Settings s) { automatic_precision.setSelected(MyApfloat.setAutomaticPrecision); automatic_precision.setFocusable(false); + final JCheckBox compress_reference = new JCheckBox("Compress Reference"); + compress_reference.setSelected(TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE); + compress_reference.setFocusable(false); + + JTextField compressionError = new JTextField(); + compressionError.setText("" + ReferenceCompressor.CompressionError); + final JCheckBox alwaysCheckForPrecisionDecrease = new JCheckBox("Check for Reduction"); alwaysCheckForPrecisionDecrease.setSelected(MyApfloat.alwaysCheckForDecrease); alwaysCheckForPrecisionDecrease.setFocusable(false); @@ -113,6 +120,10 @@ public PerturbationTheoryDialog(Component ptr, Settings s) { use_threads_for_bla.setSelected(TaskDraw.USE_THREADS_FOR_BLA); use_threads_for_bla.setFocusable(false); + final JCheckBox use_threads_for_bla2 = new JCheckBox("Use Threads for BLA"); + use_threads_for_bla2.setSelected(TaskDraw.USE_THREADS_FOR_BLA2); + use_threads_for_bla2.setFocusable(false); + final JSlider bla_starting_level_slid = new JSlider(JSlider.HORIZONTAL, 1, 32, TaskDraw.BLA_STARTING_LEVEL); bla_starting_level_slid.setPreferredSize(new Dimension(300, 55)); @@ -310,6 +321,9 @@ public PerturbationTheoryDialog(Component ptr, Settings s) { JPanel blaThreadsPAnel = new JPanel(new FlowLayout(FlowLayout.LEFT)); blaThreadsPAnel.add(use_threads_for_bla); + JPanel bla2ThreadsPAnel = new JPanel(new FlowLayout(FlowLayout.LEFT)); + bla2ThreadsPAnel.add(use_threads_for_bla2); + JPanel blaSkipLevel1PAnelLabel = new JPanel(new FlowLayout(FlowLayout.LEFT)); blaSkipLevel1PAnelLabel.add(blaLevel); @@ -383,6 +397,9 @@ public PerturbationTheoryDialog(Component ptr, Settings s) { JTextField double_threshold = new JTextField(); double_threshold.setText("" + LAReference.doubleThresholdLimit.toDouble()); + JTextField period_divisor = new JTextField(); + period_divisor.setText("" + LAReference.periodDivisor); + bla2Thresholds.add(stage0); bla2Thresholds.add(plimit); @@ -414,16 +431,19 @@ public PerturbationTheoryDialog(Component ptr, Settings s) { plimit1.setEnabled(bla2DetectionMethod.getSelectedIndex() == 1); }); - JPanel panel3 = new JPanel(new FlowLayout(FlowLayout.LEFT)); - panel3.add(new JLabel("Double Threshold Limit:")); + JPanel panel3 = new JPanel(new GridLayout(2, 2)); + panel3.add(new JLabel("Double Threshold Limit:", SwingConstants.HORIZONTAL)); + panel3.add(new JLabel("Period Divisor:", SwingConstants.HORIZONTAL)); + panel3.add(double_threshold); + panel3.add(period_divisor); BLA2panel.add(detectionPanel); BLA2panel.add(bla2DetectionMethod); BLA2panel.add(new JLabel(" ")); BLA2panel.add(bla2Thresholds); BLA2panel.add(panel3); - BLA2panel.add(double_threshold); BLA2panel.add(new JLabel(" ")); + BLA2panel.add(bla2ThreadsPAnel); reset_approximation.addActionListener(e -> { @@ -450,6 +470,8 @@ public PerturbationTheoryDialog(Component ptr, Settings s) { blaBits.setValue(ApproximationDefaultSettings.BLA_BITS); bla_starting_level_slid.setValue(ApproximationDefaultSettings.BLA_STARTING_LEVEL); + period_divisor.setText("" + ApproximationDefaultSettings.PeriodDivisor); + }); @@ -487,6 +509,11 @@ public PerturbationTheoryDialog(Component ptr, Settings s) { bignumPrecision, " ", statsPanel, + " ", + compress_reference, + "Compression Error:", + compressionError, + " ", appr, approximation_alg, " ", @@ -549,6 +576,9 @@ public void windowClosing(WindowEvent we) { double temp10 = Double.parseDouble(lacscale.getText()); double double_t_l = Double.parseDouble(double_threshold.getText()); + double temp11 = Double.parseDouble(compressionError.getText()); + double temp12 = Double.parseDouble(period_divisor.getText()); + if(temp5 <= 0 || temp6 <= 0 || temp7 <= 0 || temp8 <= 0) { JOptionPane.showMessageDialog(ptra, "The stage 0 and period limit values must be greater than 0.", "Error!", JOptionPane.ERROR_MESSAGE); return; @@ -569,6 +599,11 @@ public void windowClosing(WindowEvent we) { return; } + if(temp12 <= 0) { + JOptionPane.showMessageDialog(ptra, "The LA period divisor must be greater than 0.", "Error!", JOptionPane.ERROR_MESSAGE); + return; + } + if (tempPrecision < 1) { JOptionPane.showMessageDialog(ptra, "Precision number must be greater than 0.", "Error!", JOptionPane.ERROR_MESSAGE); return; @@ -584,6 +619,11 @@ public void windowClosing(WindowEvent we) { return; } + if(temp11 <= 0) { + JOptionPane.showMessageDialog(ptra, "The compression error must be greater than 0.", "Error!", JOptionPane.ERROR_MESSAGE); + return; + } + TaskDraw.PERTURBATION_THEORY = enable_perturbation.isSelected(); if(!TaskDraw.PERTURBATION_THEORY || tempPrecision != MyApfloat.precision) { @@ -686,6 +726,19 @@ else if(tempAuto && !TaskDraw.BIGNUM_AUTOMATIC_PRECISION && tempPrecision == MyA Fractal.clearReferences(true, true); } + boolean oldCompressReference = TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE; + TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE = compress_reference.isSelected(); + if(oldCompressReference != TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE) { + Fractal.clearReferences(true, true); + } + + double oldCompressionError = ReferenceCompressor.CompressionError; + ReferenceCompressor.CompressionError = temp11; + ReferenceCompressor.setCompressionError(); + if(oldCompressionError != ReferenceCompressor.CompressionError) { + Fractal.clearReferences(true, true); + } + MyApfloat.setAutomaticPrecision = automatic_precision.isSelected(); MyApfloat.alwaysCheckForDecrease = alwaysCheckForPrecisionDecrease.isSelected(); @@ -697,6 +750,7 @@ else if(tempAuto && !TaskDraw.BIGNUM_AUTOMATIC_PRECISION && tempPrecision == MyA TaskDraw.BLA_BITS = blaBits.getValue(); TaskDraw.BLA_STARTING_LEVEL = bla_starting_level_slid.getValue(); TaskDraw.USE_THREADS_FOR_BLA = use_threads_for_bla.isSelected(); + TaskDraw.USE_THREADS_FOR_BLA2 = use_threads_for_bla2.isSelected(); LAInfo.DETECTION_METHOD = bla2DetectionMethod.getSelectedIndex(); LAInfo.Stage0PeriodDetectionThreshold = temp5; @@ -713,6 +767,7 @@ else if(tempAuto && !TaskDraw.BIGNUM_AUTOMATIC_PRECISION && tempPrecision == MyA LAInfoDeep.LAThresholdScale = new MantExp(temp9); LAInfoDeep.LAThresholdCScale = new MantExp(temp10); LAReference.doubleThresholdLimit = new MantExp(double_t_l); + LAReference.periodDivisor = temp12; if(ptra instanceof MainWindow) { ((MainWindow)ptra).setPerturbationTheoryPost(); diff --git a/src/fractalzoomer/gui/PerturbationTheoryHelpDialog.java b/src/fractalzoomer/gui/PerturbationTheoryHelpDialog.java index a2452cfa2..1d843ef7b 100644 --- a/src/fractalzoomer/gui/PerturbationTheoryHelpDialog.java +++ b/src/fractalzoomer/gui/PerturbationTheoryHelpDialog.java @@ -41,6 +41,7 @@ public PerturbationTheoryHelpDialog(JDialog dialog) { "
  • Magnet 1
  • " + "
  • Magnet Pataki (2-5) powers
  • " + "
  • z = z^2 + c^2
  • " + + "
  • z = c * (z^2 + z^-2)" + "
  • Buffalo Mandelbrot
  • " + "
  • Celtic Mandelbrot
  • " + "
  • Perpendicular Mandelbrot
  • " + @@ -52,12 +53,15 @@ public PerturbationTheoryHelpDialog(JDialog dialog) { "
  • Newton 3 (No Julia Set available)
  • " + "" + "

    "+ + "Reference compression will reduce the memory footprint when saving the reference data, by only allowing some" + + " waypoint data to be saved when the defined compression error is exceeded." + + "

    "+ "Series Approximation is another useful feature of perturbation theory as it can approximate the iteration values for " + "a number of iterations and skip them. This feature is only implemented for the Mandelbrot (2-5) powers (Not supported with burning ship or Julia sets). " + "Mandelbrot (2) can use up to 257 terms, and there rest of the available powers can use up to 5 terms. " + "You can also set how aggressive the series approximation can be by changing the orders of magnitude difference to a lower value.

    " + "If you zoom deeper than e-300, doubles cannot store the differences anymore so a custom type of FloatExp is used " + - "which stores a mantissa and a extended exponent. You can choose to do all the iterations using this type on deep zooms, " + + "which stores a mantissa and an extended exponent. You can choose to do all the iterations using this type on deep zooms, " + "or switch back to double precision when is appropriate.

    " + "Some options like Plane Influence, Pre/Post Function Filters, Initial Value, Perturbation, Equicontinuity will be ignored if perturbation theory " + "is enabled and the current function supports it. Perturbation theory will not work on Julia sets with Juliter enabled (The low precision calculations will be used).

    " + diff --git a/src/fractalzoomer/gui/PolarProjectionDialog.java b/src/fractalzoomer/gui/PolarProjectionDialog.java index b4a5b7f49..86a8d3ba2 100644 --- a/src/fractalzoomer/gui/PolarProjectionDialog.java +++ b/src/fractalzoomer/gui/PolarProjectionDialog.java @@ -182,9 +182,9 @@ public void windowClosing(WindowEvent we) { try { if(MyApfloat.setAutomaticPrecision) { - long precision = MyApfloat.getAutomaticPrecision(new String[]{field_size.getText(), field_real.getText(), field_imaginary.getText()}, new boolean[] {true, false, false}); + long precision = MyApfloat.getAutomaticPrecision(new String[]{field_size.getText(), field_real.getText(), field_imaginary.getText()}, new boolean[] {true, false, false}, s.fns.function); - if (MyApfloat.shouldSetPrecision(precision, MyApfloat.alwaysCheckForDecrease)) { + if (MyApfloat.shouldSetPrecision(precision, MyApfloat.alwaysCheckForDecrease, s.fns.function)) { Fractal.clearReferences(true, true); MyApfloat.setPrecision(precision, s); } diff --git a/src/fractalzoomer/gui/RotationDialog.java b/src/fractalzoomer/gui/RotationDialog.java index b6682ca03..c7fc57fa2 100644 --- a/src/fractalzoomer/gui/RotationDialog.java +++ b/src/fractalzoomer/gui/RotationDialog.java @@ -256,9 +256,9 @@ public void windowClosing(WindowEvent we) { try { if(MyApfloat.setAutomaticPrecision) { - long precision = MyApfloat.getAutomaticPrecision(new String[]{field_real.getText(), field_imaginary.getText()}, new boolean[] {false, false}); + long precision = MyApfloat.getAutomaticPrecision(new String[]{field_real.getText(), field_imaginary.getText()}, new boolean[] {false, false}, s.fns.function); - if (MyApfloat.shouldSetPrecision(precision, MyApfloat.alwaysCheckForDecrease)) { + if (MyApfloat.shouldSetPrecision(precision, MyApfloat.alwaysCheckForDecrease, s.fns.function)) { Fractal.clearReferences(true, true); MyApfloat.setPrecision(precision, s); } diff --git a/src/fractalzoomer/gui/SequenceRenderDialog.java b/src/fractalzoomer/gui/SequenceRenderDialog.java index ec1bc3eca..1c4b1d2be 100644 --- a/src/fractalzoomer/gui/SequenceRenderDialog.java +++ b/src/fractalzoomer/gui/SequenceRenderDialog.java @@ -16,17 +16,28 @@ */ package fractalzoomer.gui; +import com.fasterxml.jackson.databind.ObjectMapper; import fractalzoomer.core.MyApfloat; import fractalzoomer.functions.Fractal; +import fractalzoomer.main.CommonFunctions; import fractalzoomer.main.ImageExpanderWindow; import fractalzoomer.main.MainWindow; import fractalzoomer.main.app_settings.Settings; +import fractalzoomer.main.app_settings.ZoomSequenceSettings; import org.apfloat.Apfloat; import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import javax.swing.plaf.basic.BasicFileChooserUI; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.PrintWriter; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import static fractalzoomer.gui.CenterSizeDialog.TEMPLATE_TFIELD; @@ -40,8 +51,31 @@ public class SequenceRenderDialog extends JDialog { private JOptionPane optionPane; private final JScrollPane scrollPane; + private JTextArea field_size; + private JComboBox zoooming_mode; - public SequenceRenderDialog(ImageExpanderWindow ptr, Settings s, double zoom_factor, int zooming_mode, Apfloat size, double rotation_adjusting_value, int color_cycling_adjusting_value, double light_light_direction_adjusting_value, double bump_light_direction_adjusting_value, int zoom_every_n_frame, int gradient_color_cycling_adjusting_value, boolean flipSequenceIndexing, long startAtSequenceIndex, double slope_light_direction_adjusting_value) { + private MyJSpinner fieldZoom; + + private MyJSpinner fieldRotation; + + private MyJSpinner fieldColorCycling; + + private MyJSpinner fieldGradientColorCycling; + + private MyJSpinner fieldLightCycling; + + private MyJSpinner fieldSlopesCycling; + + private MyJSpinner filedBumpLightCycling; + + private MyJSpinner fieldZoomEveryNFrame; + + private JCheckBox flipIndex; + + private JTextField startAtIndex; + private JTextField aspectRatio; + + public SequenceRenderDialog(ImageExpanderWindow ptr, Settings s, ZoomSequenceSettings zss) { super(ptr); @@ -54,18 +88,38 @@ public SequenceRenderDialog(ImageExpanderWindow ptr, Settings s, double zoom_fac setModal(true); setIconImage(MainWindow.getIcon("mandel2.png").getImage()); - final JComboBox zoooming_mode = new JComboBox<>(new String[] {"Zoom-In", "Zoom-Out"}); - zoooming_mode.setSelectedIndex(zooming_mode); + JButton load = new MyButton("Load"); + load.setToolTipText("Loads some saved zoom sequence settings."); + load.setFocusable(false); + load.setIcon(MainWindow.getIcon("load_small.png")); + + load.addActionListener(e -> load(s)); + + + JButton reset = new MyButton("Reset"); + reset.setToolTipText("Resets the zoom sequence settings."); + reset.setFocusable(false); + reset.setIcon(MainWindow.getIcon("reset_small.png")); + + reset.addActionListener(e -> reset()); + + JPanel action_panel = new JPanel(); + action_panel.setLayout(new FlowLayout()); + action_panel.add(load); + action_panel.add(reset); + + zoooming_mode = new JComboBox<>(new String[] {"Zoom-In", "Zoom-Out"}); + zoooming_mode.setSelectedIndex(zss.zooming_mode); zoooming_mode.setFocusable(false); zoooming_mode.setToolTipText("Sets zooming mode."); zoooming_mode.setPreferredSize(new Dimension(150, 20)); - JTextArea field_size = new JTextArea(3, 50); + field_size = new JTextArea(3, 50); field_size.setLineWrap(true); field_size.setFont(TEMPLATE_TFIELD.getFont()); - field_size.setText("" + size); + field_size.setText("" + zss.size); JScrollPane scrollSize = new JScrollPane (field_size, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); @@ -93,33 +147,38 @@ public SequenceRenderDialog(ImageExpanderWindow ptr, Settings s, double zoom_fac }); - MyJSpinner fieldZoom = new MyJSpinner(new SpinnerNumberModel(zoom_factor, 1.05, 32.0, 0.5)); + fieldZoom = new MyJSpinner(new SpinnerNumberModel(zss.zoom_factor, 1.001, 32.0, 0.5)); - MyJSpinner fieldRotation = new MyJSpinner(new SpinnerNumberModel(rotation_adjusting_value, -90.0, 90.0, 1)); + fieldRotation = new MyJSpinner(new SpinnerNumberModel(zss.rotation_adjusting_value, -90.0, 90.0, 1)); - MyJSpinner fieldColorCycling = new MyJSpinner(new SpinnerNumberModel(color_cycling_adjusting_value, 0, 10000, 1)); + fieldColorCycling = new MyJSpinner(new SpinnerNumberModel(zss.color_cycling_adjusting_value, -10000, 10000, 1)); - MyJSpinner fieldGradientColorCycling = new MyJSpinner(new SpinnerNumberModel(gradient_color_cycling_adjusting_value, 0, 10000, 1)); + fieldGradientColorCycling = new MyJSpinner(new SpinnerNumberModel(zss.gradient_color_cycling_adjusting_value, -10000, 10000, 1)); - MyJSpinner fieldLightCycling = new MyJSpinner(new SpinnerNumberModel(light_light_direction_adjusting_value, -90.0, 90.0, 1)); + fieldLightCycling = new MyJSpinner(new SpinnerNumberModel(zss.light_direction_adjusting_value, -90.0, 90.0, 1)); - MyJSpinner fieldSlopesCycling = new MyJSpinner(new SpinnerNumberModel(slope_light_direction_adjusting_value, -90.0, 90.0, 1)); + fieldSlopesCycling = new MyJSpinner(new SpinnerNumberModel(zss.slopes_direction_adjusting_value, -90.0, 90.0, 1)); - MyJSpinner filedBumpLightCycling = new MyJSpinner(new SpinnerNumberModel(bump_light_direction_adjusting_value, -90.0, 90.0, 1)); + filedBumpLightCycling = new MyJSpinner(new SpinnerNumberModel(zss.bump_direction_adjusting_value, -90.0, 90.0, 1)); - MyJSpinner fieldZoomEveryNFrame = new MyJSpinner(new SpinnerNumberModel(zoom_every_n_frame, 1, 20, 1)); + fieldZoomEveryNFrame = new MyJSpinner(new SpinnerNumberModel(zss.zoom_every_n_frame, 1, 20, 1)); - JCheckBox flipIndex = new JCheckBox("Flip Sequence Indexing"); + flipIndex = new JCheckBox("Flip Sequence Indexing"); flipIndex.setFocusable(false); - flipIndex.setSelected(flipSequenceIndexing); + flipIndex.setSelected(zss.flipSequenceIndexing); flipIndex.setToolTipText("Changes the indexing of the name to start backwards."); - JTextField startAtIndex = new JTextField(); - startAtIndex.setText("" + startAtSequenceIndex); + startAtIndex = new JTextField(); + startAtIndex.setText("" + zss.startAtSequenceIndex); + + aspectRatio = new JTextField(); + aspectRatio.setText("" + zss.aspect_ratio); Object[] message = { " ", + action_panel, + " ", "Set the Zooming Mode.", "Zooming Mode:", zoooming_mode, @@ -152,6 +211,10 @@ public SequenceRenderDialog(ImageExpanderWindow ptr, Settings s, double zoom_fac flipIndex, "Start Rendering at Sequence Index:", startAtIndex, + " ", + "Set the output image aspect ratio.", + "Aspect Ratio:", + aspectRatio, " "}; @@ -199,11 +262,12 @@ public void windowClosing(WindowEvent we) { int tempZoomNFrame = Integer.parseInt(fieldZoomEveryNFrame.getText()); int tempGradientColorCycling = Integer.parseInt(fieldGradientColorCycling.getText()); long startAtIdx = Long.parseLong(startAtIndex.getText()); + double tempAspectRatio = Double.parseDouble(aspectRatio.getText()); if(MyApfloat.setAutomaticPrecision) { - long precision = MyApfloat.getAutomaticPrecision(new String[]{field_size.getText(), s.size.toString()}, new boolean[]{true, true}); + long precision = MyApfloat.getAutomaticPrecision(new String[]{field_size.getText(), s.size.toString()}, new boolean[]{true, true}, s.fns.function); - if (MyApfloat.shouldSetPrecision(precision, MyApfloat.alwaysCheckForDecrease)) { + if (MyApfloat.shouldSetPrecision(precision, MyApfloat.alwaysCheckForDecrease, s.fns.function)) { Fractal.clearReferences(true, true); MyApfloat.setPrecision(precision, s); } @@ -216,18 +280,18 @@ public void windowClosing(WindowEvent we) { return; } - if (tempZoomFactor < 1.05 || tempZoomFactor > 32) { - JOptionPane.showMessageDialog(ptra, "Zooming factor must be in the range [1.05, 32].", "Error!", JOptionPane.ERROR_MESSAGE); + if (tempZoomFactor < 1.001 || tempZoomFactor > 32) { + JOptionPane.showMessageDialog(ptra, "Zooming factor must be in the range [1.001, 32].", "Error!", JOptionPane.ERROR_MESSAGE); return; } - if(tempColorCycling < 0 || tempColorCycling > 10000) { - JOptionPane.showMessageDialog(ptra, "The color cycling adjusting value must be in the range [0, 10000].", "Error!", JOptionPane.ERROR_MESSAGE); + if(tempColorCycling < -10000 || tempColorCycling > 10000) { + JOptionPane.showMessageDialog(ptra, "The color cycling adjusting value must be in the range [-10000, 10000].", "Error!", JOptionPane.ERROR_MESSAGE); return; } - if(tempGradientColorCycling < 0 || tempGradientColorCycling > 10000) { - JOptionPane.showMessageDialog(ptra, "The gradient color cycling adjusting value must be in the range [0, 10000].", "Error!", JOptionPane.ERROR_MESSAGE); + if(tempGradientColorCycling < -10000 || tempGradientColorCycling > 10000) { + JOptionPane.showMessageDialog(ptra, "The gradient color cycling adjusting value must be in the range [-10000, 10000].", "Error!", JOptionPane.ERROR_MESSAGE); return; } @@ -261,7 +325,27 @@ public void windowClosing(WindowEvent we) { return; } - ptr.startSequenceRender(tempSize, tempZoomFactor, zoooming_mode.getSelectedIndex(), tempRotation, tempColorCycling, tempLight, tempBumpLight, tempZoomNFrame, tempGradientColorCycling, flipIndex.isSelected(), startAtIdx, tempSlopes); + if(tempAspectRatio <= 0) { + JOptionPane.showMessageDialog(ptra, "The aspect ratio must be greater than 0.", "Error!", JOptionPane.ERROR_MESSAGE); + return; + } + + zss.zooming_mode = zoooming_mode.getSelectedIndex(); + zss.zoom_factor = tempZoomFactor; + zss.rotation_adjusting_value = tempRotation; + zss.color_cycling_adjusting_value = tempColorCycling; + zss.light_direction_adjusting_value = tempLight; + zss.bump_direction_adjusting_value = tempBumpLight; + zss.zoom_every_n_frame = tempZoomNFrame; + zss.gradient_color_cycling_adjusting_value = tempGradientColorCycling; + zss.flipSequenceIndexing = flipIndex.isSelected(); + zss.startAtSequenceIndex = startAtIdx; + zss.slopes_direction_adjusting_value = tempSlopes; + zss.size = tempSize; + zss.sizeStr = tempSize.toString(); + zss.aspect_ratio = tempAspectRatio; + + ptr.startSequenceRender(); } catch (Exception ex) { JOptionPane.showMessageDialog(ptra, "Illegal Argument: " + ex.getMessage(), "Error!", JOptionPane.ERROR_MESSAGE); @@ -292,4 +376,70 @@ public static void disableKeys(InputMap inputMap) { } } + private void load(Settings s) { + + JFileChooser file_chooser = new JFileChooser(ImageExpanderWindow.outputDirectory); + + file_chooser.setAcceptAllFileFilterUsed(false); + file_chooser.setDialogType(JFileChooser.OPEN_DIALOG); + + file_chooser.addChoosableFileFilter(new FileNameExtensionFilter("Zoom Sequence Settings (*.json)", "json")); + + file_chooser.addPropertyChangeListener(JFileChooser.FILE_FILTER_CHANGED_PROPERTY, evt -> { + String file_name = ((BasicFileChooserUI) file_chooser.getUI()).getFileName(); + file_chooser.setSelectedFile(new File(file_name)); + }); + + int returnVal = file_chooser.showDialog(this, "Load Zoom Sequence Settings"); + + if (returnVal == JFileChooser.APPROVE_OPTION) { + File file = file_chooser.getSelectedFile(); + + ObjectMapper objectMapper = new ObjectMapper(); + try { + ZoomSequenceSettings zss = objectMapper.readValue(file, ZoomSequenceSettings.class); + + if(MyApfloat.setAutomaticPrecision) { + long precision = MyApfloat.getAutomaticPrecision(new String[]{zss.sizeStr, s.size.toString()}, new boolean[]{true, true}, s.fns.function); + + if (MyApfloat.shouldSetPrecision(precision, MyApfloat.alwaysCheckForDecrease, s.fns.function)) { + Fractal.clearReferences(true, true); + MyApfloat.setPrecision(precision, s); + } + } + + zss.size = new MyApfloat(zss.sizeStr); + + setFromSettings(zss); + } catch (IOException ex) { + JOptionPane.showMessageDialog(this, "Error while loading the file.", "Error!", JOptionPane.ERROR_MESSAGE); + } + } + + } + + private void reset() { + + setFromSettings(new ZoomSequenceSettings()); + + } + + private void setFromSettings(ZoomSequenceSettings zss) { + zoooming_mode.setSelectedIndex(zss.zooming_mode); + + field_size.setText("" + zss.size); + + fieldZoom.setValue(zss.zoom_factor); + fieldRotation.setValue(zss.rotation_adjusting_value); + fieldColorCycling.setValue(zss.color_cycling_adjusting_value); + fieldGradientColorCycling.setValue(zss.gradient_color_cycling_adjusting_value); + fieldLightCycling.setValue(zss.light_direction_adjusting_value); + fieldSlopesCycling.setValue(zss.slopes_direction_adjusting_value); + filedBumpLightCycling.setValue(zss.bump_direction_adjusting_value); + fieldZoomEveryNFrame.setValue(zss.zoom_every_n_frame); + flipIndex.setSelected(zss.flipSequenceIndexing); + startAtIndex.setText("" + zss.startAtSequenceIndex); + aspectRatio.setText("" + zss.aspect_ratio); + } + } diff --git a/src/fractalzoomer/gui/SplashFrame.java b/src/fractalzoomer/gui/SplashFrame.java index c4852a599..615a50324 100644 --- a/src/fractalzoomer/gui/SplashFrame.java +++ b/src/fractalzoomer/gui/SplashFrame.java @@ -50,11 +50,14 @@ public SplashFrame(int version) { thread = new Thread(new SplashTask(image, l1, version, 155)); thread.start(); } - - public boolean isAnimating() { - - return thread.isAlive(); - + + @Override + public void dispose() { + try { + thread.join(); + } + catch (Exception ex) {} + super.dispose(); } private BufferedImage convertToBufferedImage(Image image) { diff --git a/src/fractalzoomer/gui/ToolsOptionsMenu.java b/src/fractalzoomer/gui/ToolsOptionsMenu.java index a1eb552bc..0f4ad2254 100644 --- a/src/fractalzoomer/gui/ToolsOptionsMenu.java +++ b/src/fractalzoomer/gui/ToolsOptionsMenu.java @@ -43,6 +43,8 @@ public class ToolsOptionsMenu extends MyMenu { private JMenuItem zoom_window_color_opt; private JRadioButtonMenuItem line; private JRadioButtonMenuItem dot; + + private JRadioButtonMenuItem line2; private JRadioButtonMenuItem zoom_window_dashed_line; private JRadioButtonMenuItem zoom_window_line; private JCheckBoxMenuItem fast_julia_filters_opt; @@ -137,22 +139,28 @@ public ToolsOptionsMenu(MainWindow ptr2, String name, boolean show_orbit_converg zoom_window_line_button_group.add(zoom_window_line); line = new JRadioButtonMenuItem("Line"); - line.setToolTipText("Sets the orbit style to line."); + line.setToolTipText("Sets the orbit style to line with dots."); dot = new JRadioButtonMenuItem("Dot"); dot.setToolTipText("Sets the orbit style to dot."); + line2 = new JRadioButtonMenuItem("Line (No Dots)"); + line2.setToolTipText("Sets the orbit style to line without dots."); + + line.addActionListener(e -> ptr.setOrbitStyle(0)); - line.addActionListener(e -> ptr.setLine()); + dot.addActionListener(e -> ptr.setOrbitStyle(1)); - dot.addActionListener(e -> ptr.setDot()); + line2.addActionListener(e -> ptr.setOrbitStyle(2)); show_orbit_converging_point_opt.addActionListener(e -> ptr.setShowOrbitConvergingPoint()); orbit_style_menu.add(line); orbit_style_menu.add(dot); + orbit_style_menu.add(line2); ButtonGroup orbit_style_button_group = new ButtonGroup(); orbit_style_button_group.add(line); orbit_style_button_group.add(dot); + orbit_style_button_group.add(line2); line.setSelected(true); @@ -222,6 +230,12 @@ public JRadioButtonMenuItem getDot() { return dot; } + + public JRadioButtonMenuItem getLine2() { + + return line2; + + } public JRadioButtonMenuItem getZoomWindowLine() { diff --git a/src/fractalzoomer/gui/VariablesDialog.java b/src/fractalzoomer/gui/VariablesDialog.java index 2c6302789..6450ea4cc 100644 --- a/src/fractalzoomer/gui/VariablesDialog.java +++ b/src/fractalzoomer/gui/VariablesDialog.java @@ -163,7 +163,7 @@ public void windowClosing(WindowEvent we) { } dispose(); - ptr.redraw(); + ptr.redraw(false); } }); diff --git a/src/fractalzoomer/gui/ZoomingFactorDialog.java b/src/fractalzoomer/gui/ZoomingFactorDialog.java index 107b7e7c9..854fba01a 100644 --- a/src/fractalzoomer/gui/ZoomingFactorDialog.java +++ b/src/fractalzoomer/gui/ZoomingFactorDialog.java @@ -88,8 +88,8 @@ public void windowClosing(WindowEvent we) { try { Double temp = Double.parseDouble(field.getText()); - if (temp < 1.05 || temp > 32) { - JOptionPane.showMessageDialog(ptra, "Zooming factor must be in the range [1.05, 32].", "Error!", JOptionPane.ERROR_MESSAGE); + if (temp < 1.001 || temp > 32) { + JOptionPane.showMessageDialog(ptra, "Zooming factor must be in the range [1.001, 32].", "Error!", JOptionPane.ERROR_MESSAGE); return; } diff --git a/src/fractalzoomer/help/Fractal_Zoomer_Help.chm b/src/fractalzoomer/help/Fractal_Zoomer_Help.chm index e83af14f320601ab4f29cc5c9a09b51750d68be5..6293a2da83b32c3dd8cc7044ef673afea30e567d 100644 GIT binary patch literal 368092 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

    t6%Lbi!zM9k#dhVGR?8o11|*eZl!)_Xa7m$ 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

    EIj#wF|Z14x2bZhS0GrcovP2%Bd@l+%G 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%0D02u>9Xg`{(a}f$brIraymehE{%t|Lcj@%FNXN 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

    Cdo0X$6*>5T(S-a@W2<7 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
    _oO4Tr$B38m7v2Q0AS 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%0A<^27d|NEH<}4;~yLC*!JIl4iEWR|6s%QPXl#N4 zY@_v+d$9=})st422=fC*wd)Mo&IT4q1``ci(*jiX7(_P@?C07*c$zw_}1 zBmIJ%pZuZdtN!vEcXC$cLAYY^gkBQ)UdgAcSb`AR1iwvQPRo6KNQMq?rG$qbSszR9 zDcNWjL5INXi8un+ztyQfnC2z!aVdRudwGoI0eyaXRm5+CCV$;^PoG+aDCL9Y0z}1Wmk_3*f1wjT2bv}>m z?LBLO5oeLY!YFn96BBRExX7@A_ZBy}t#N7h4_)>&BtA>DpDt$T zoy>dKZFtTLxI>CnGHC^IgUpi=S$XbVJcBz>ByOAUnZQEMynPvF?u#THFQK!dlSy}M zQrL#N`#YItpevf`n{pNPg2O)vUW0ZhC*gSpD(;bW9nPtEr;Z|7o0{94kI}`g{4m4A zAgY6`?1QtPD|V#2PtjPt@GSunmv|`+K;JC;+vg_yQ0%R)55M-s*j&_lX~&&DdhvXU zhc9)WVR?5=<|trMsCO8nQ}`0GA@m=4kyeYtQ_&8pePf%X_<+EuXSsM!(Fds`A+mt` z7t(F($P$;bh^yzOwfX_3liZ7q3NX z1@yDlKufUI*i2PD{N~UDjB?GEkE)pH$PpOum!WLNljRu-+^-(@l35EePbT+<*W|x> z(j5;9^&JZkFFwn-ZZ4%=D-kV34&mDM7*+tyex7qHM> z{X_5w)~#4VCVU-o)zn=4Pp|6bQc!qa4e+5|aik%QBIr1m$e%6)i2A{lDp?{Kx$Yk@ zTaI*6DtShac|upIIp$E~oFOJ)l!j^n@GERK__zCKQ02)z#yUKZ%56^icBEd-Tf@OF z)}|iaX}oR4gknTU{5L3fd2U~h8qN+Cl0*3wU#E)7sEwoPG@K1dDE*an8If$l7+xXL z53Y{!Bb7%V^?O0OlrxXcin&%u|0aoMvb6J?8!`7iNNeVb2hzJfB@eT2D+{^@6$kxt z>j?4THe_wnu>rkw`p&TO; zWHH!Lm>kTf0~`a<>G^?xCKjiWCe7fZ2ERgB0?x0J=NRDMIxS+%Y#3TTuX6oaY zo}!N%2;I73gxN^h{`j* zA!)S~k{zwQjWSX^Fr77V${tQl+mae|Sjv_82`70JQxs#Xqrfl@xeFsa>shy-sVF(t z?ACLP9ohKr!tC0rA^Zwjy|7I9x^!FJIZ_#L1q)B^lN>-ZZ*_SMmL5~I5=ps@np;#qKFgC zYy0bi_YDL9_ci{UR;S12Rv-W}g#`?YK+pX!jn)6laXB9p2jHapg$0^2eQu$(_0Kf8 z7pONm=T{}x7$+fGaEIiN0aCC3H#!F7Tg!eD;y(Wi$R6L_r~I^GxBd(ck(5@0`40TI zYPqbR1=bgIL;4iX2`uCWdM{R0p+-6^FvJg17eMRp6bbY)ktWXjI3y=BWe7;rtEZ4&`M93jPbnh+ZsbM?~@+@$w@Tpi&<1rQ^&h?LPoQXooUNDftng8wwxHcr9j zLM&79kK~BiiSNSKvmxvr@hSWxX2lI%sjh$xj{t=k?>XAe--YZVl>Yj9utMQb#lyZ0 z*g=){vx7h^+*SJR@Th}?xMK=+6sq|s?yER2LWF!02Q`G*3S?rEW=P*eftDE2YAM^H ze{s+bI^22j);_jnxU^W;q|wVk(+Ct*GmBBm*4s3>#5^e%3~^5dkQOO;#(1O$4FkOw z-Wcc4D*eQ-VykxQ@7+O{i3&h5VgdZBCIZt24Jios>7ftRn3Sd49rA^zxcz+^`Q zVBoDPAvTlDx0C4O+xcR1`9!gUb-A$@Brh6;lq4SF63i+2BRx+TYt5A_^o^n?cg}tg zg9#KxXYnPiO%6wxt5zbBvZDIH1-l||*`gq9-+A#%#JUMDBr!HXbI0~{u=VI!o6;g* z1y(wB!X`&PY99B!jN=-C&}OaZb})f|Xw~DL*u-wgSEWfsFMnA`*xxM>(@Vr`5%lNQ zM0gH1XSgysT|%eESM>rk}z4=*HulbWg$9x_EN& zAB4$g$j|X=nY4HnaYO?QKRjOegWAd{#tlsx_$dIKe8H~3)U>Yej0*UMBEPrSVWD&B zxlBd;Ae`jr93cQj2m1bEU$c??cYt}}&_fS9Wr+I-uL1}aZbx$1$-&<)Nvx%#ua$n3 zjc{t*K_HONH@Ihpza7?eAZ1y2*m#nAxQ+W(UYV*6Bzn_P|8N7gy$hIK z3Ums+JM`(We34KQ>Wo*{ad+;&DcL7O52c^@;TH@?#LD?Bovc+&%O-!oz`bg%I7dPj z2a1W2t?f|S*uxfg{EhTNNnVBvma{}-Q?N3bli62x@-eA60l>y??! zDh(D!)?E<%9t^%f0{CFsvg7%XmIX45n_hk?0|cb%4}d)o>SRYaEF}Pn;R1xy&}kq( z4_!n_4JTTR;Z62h@tkvi=C74C^nP$)0}r8qoHo6ULqjYAzj|{`55Z zm8_8gO*^~fh^4qqQ}s$>&h~?MKwrI>JV8lC?A})^el%LM`X6=yd^^pwEhAU8=D0n3 z@@2l;fOThTdKyD-*^R?Fqtdj{~k!phep~H^OWE6G*q{G0p;s}n*Qba3Uf7HMv z(Ra)C5nS#Lw{(3miY|MS+NCFzOj8dk8|>p*`%^DH%F8!*W$Y5OPv7qqL!P7s3m6a1q$ z5_`QYO@zvi;$xRVZA>7Ow9>|$T zwlf}4!a{6!nW&F4%ccZXT{gyrG8p9)oa)AyGK`1}>F}1HqcTlg%B}9o240>H#{BO} z0zu)Rf=j`yPi*&k$`xBlKa(=sUSRG)7p7pjLorYet9+S-6lM?|dvzgsal!&OQ-|_@sWNCsikfSk>|-j8 zQDpb3ktlkN6Fx@hbBx(46^^j>wp#y$ z>TmWXRt7e|yO26I=i?@z=61_zytb;F@0e{gpNxA_{ucy;ok=1U)cK$623}E|0+f-Y z>qjS{dkxUNY=jX)rVNblx)c^h1seBso!&MHgBlL_EmRp$Plm5(tKpbiqr9S8fWuVL ztj9HUU+h+SEb5^wj;sWLE?kdMEizeq&w0TunONW4hY)U=T=OFS_y_ydw-NWXVu67v z;CmGnQV3&%>&b@K|B6Mevo0?3IDopyi7*TYcf*MOX^A_8xs^Ex9&10Q{5|`UmvMb5 z*qL3L9yTv?B453teSWRB#>~X8p zm{%0|{K0Vf9gw-RErO0e!IJzG*TgUCm#9Cq|2VsEKi@LN@BXmY{eH9`uE=pzg&K8D z*5J;B^a8Ye){F7PoF7C9=j9InzLcDy+Vd?%i20Yz`SQ2eXMcYa%0SHh`}qD*;z#lL z)`#EZjgIZAG_j2R&n@8$3{&1zK}D>0wONcNtzT@YEl5Cy=LEuI_UBs9y(0)EJ)j(Q z-qp^cz<2uCZiMNh%>W<@=NDA;-`dZs5yPW$DXE==j{lx;V_#S|Rt0P4cP+HZ)-PGt z`F2mREBC+q%Kpz)T6TcI4XGKb1X7kXp*=R-0q0^#CKm^W=ZAQxVPoiE(|V z)6w|lJrJL4{DMYVFaZC_p1N#(^x^EQ{|vh8*{MWYFkn9gB}}$5`ey)X8v$%d`OJ@- zxr!_Nf!V3bzuvI+(ZQi88r>1|9c=!4M0(kpyGu3}pHNgWU@cNJ6@I@)d4 zkuW>nP#%B--xw%xKf2?@|Cz+3IEwso0E0>YIzahvMvQAA<7>Mn*X0QK)jJio+3d>=3f(d z{-<6Vvr>~N?deU1>vG4va9-s6(=HYp$2u#SOt30ccA&3tzI@l6o74AA`7mWqcLVg0 z0?d+98b{V?%gKhOX1?v$vg@uv3~O72oMN6HA!lG_F}4tko`_CD)$GXqYQb~Wxa7Doq!!?FJs3%h*N6rLPi2HN@n zK@&M#M#Z-ZlnueqCuM8p+Y+N5r@lR9njaMLai`LtP*37rPf= z^Usv`tnTYj3`ECV5?@QDcp$UjBMp6$(DpSxchNb}nWvdW$3quKxGe8^da0$kqF1yrr3e53D#V8^Nx zR=uzI^~~?~eLFgtHNQBCgCA9&|M^r^Ge`~WNUi-^o6&RE*7ZgnYDKeaNp0`_98Vom zfHesLViUE^t!Gv1am2=x+WB9Piwam*XOP`%?C*=Osowl^JEB7DI7o?H8s(jm%={gC z+H#6uwg0EVZ<)7Mj<#tJ{st-!Z*>Nm&3mNWh-;`br2 z+mh{MgVwyWu_gW_AwASD(bOqu;K3Ioi=fsW2cW!4((=-q+h%u#td_i<^Xlq34i@(-0#qAmw_zL$KoG-x=itm|19jA=fL8mL~Li=Sb3Gd6YQ>uS!;3R856 z+S_2Ru16NSGJ3r_Jo#ugeEd|w-k|@w*tA$^g9~Z@9<}DWeyKtbUnLD4976^NUi17>&hV%oP7%3_T|nscAWxgGy2 zytMHrMWI5?-{-#TEb7A3p}m9hxKBmx+U23hO}xrg@oWDbI%NX(q@~W&2OPM)0L0V1-~EO$*DjZF2wlc=NuV^t3<| z^wS+)MEz0ag1{4P>iXA??t=(mgptCLR%?-zM6{i$CTnV+f*xC9%y)}kr}cKX^!&G* zrQ7EIK4LAv6Qg%OV4Ph5Hm|zFP!&wR4|-(ViH$uUA>>$fe~f9gAAP(dW$U~Ny8kiv z&NZj+Ltp|Ro6TRLuMEK70|1|E+knM?bQhbeJO3NAUf+<)s5Y7}PGK7T{w$C%{@vr0 zo*spakmU_9vS)h9^}h~G5u3xmfsX|I^j^-QHbEAZ&ig1gp(H=zm_UM0V2YnPQ`csD zLG5?jWqLk;XZMC1SM}4~MAsqYzr2y(@u;4kVEtzJZTFWqaZkJXeR|$g*opmNjh@p( z(~_&hh@JqUwTt=~a$Zs6_oy!kC;3u)rS#IO3tH>YbAhp}$32IfVN7tQ)nf7A8H?{u zk+O(ZvaSU5%M=>yAQo-eZ?nh|vN1)e9b6w2f5N44j{<>pt*V znI-pB=OHaeRt4vb^yA?l*Y;ByLYL+T8On7wGM>_^Y|up+Mw)EklB%+OzDXws^Za_- z{?OdheXJp$ZYGSPkrzYL)Qv#&*%?x3)#PYz!;Q>h; zZ|_CcPW8AOUm^D@9)e}Q_Lryob9T2J`b*25&7INk!px|II#r|(=I0vAt)r%N927ft z0BN$*9mNYKxb3Vbw5#&YGJdQ6U%`Hwyg zn^7l}Vbsl{vIOBhTjsP6J{)BKh#qdL;iO!MZMDH)#>4M-UQzh;*-psnlW+T{R=GuG z7<@-{!UylQ2jT&ZNIn$Mjwp)D&wuKC{EBAjN!`0hy3i*9%88u7DnbcaE~MzQx}W*m zk@3UrTsDb}m40LI zzaN0s!c^E!H0dYzKbPj`X^-Uha?`WLo3Ka}Z|1wStuXMo=kz6*-r?;+^tC$l>?0L5 zMvTzf)#6B=cG8nu@*8`?;mI{&7k!j&i;~$YxOXRWJ7mY+#uxrIg(e^FnrA!DVrVsX?OKet)8iQN^6|+E^JXw0$6Tzk z{k$3kl!Oi|l?`JRe|1lvJZD0X|FZ#eq)$kGRo6d%#itEMNvq&G2xlx^x*2(?+CSwf zbF~~x6;yM=_+%;J@6n@CA{n3EdMw}ifnwn=mCD$WR8~6st+&1CMUpFWvbvF`%C?Kp zuRWHAJ@BetKJwtnGJwqR4cH8$o1|4p9nIZW`(!^wdcd^!fW_KmpMji&m-+72*d)X} z%g*GO9p_&AjNvq|(6D!GtaUNjk4B=V5He9>Uk#28N@zN1rg_8)J-S>!f|={6c#|J9 z>#^wo#m+xFR}kCUW3$d3;vV0!%S)@|%94zN)9p2pNq~AMk2>d;V5(=}4eJdu3d)v1 z)8IZRIrs1Sm}}!-F0t&Q7fDC9D=#x2ru&=t+RDxd`o^QRDPswQZe@Z1!Y4Xl(x+9W3U*pc3%xf66E$XOGC;i1UNoVqlAsF zuCcZDQZawXGVE0r*UaDXMntF_g`g9vtJ)oGH``dfBD;x(#Guj3);Zf~A20D`qg?9q zzYC_F!WZXM7XHF+uUkI_7tgIQ{3v~e0|?O4u>{i9ycJc#)4ln43g-VaJDw|oP9Mnx zAU{_3Solia-RtN%y+dT*9zN0eu-~b}I5#7=!-~j?rConih6IEwF(;3{_GK-64HG5w z9{|l7y3Kyy2NMkD$w0ZPKGlP^1t;X+72(H}0c1Q6e3epFemr+--?SJGSY;_!fmt=@ zx(jmOXQLEsIq*@4D>auL1*=ocGoi>UVT|`HtQY?F-QHx_{D65Ufs!pdI@x zLT*@##rxM<2uwXaw2mVCKFue5Jk)`FLE~P0oKGe{pvv9A^v>(;)64$Nh7wAu~^<5yIj+zxtGib6fW z$RRq@t+Zk)4*aY%I6>{6A_EO=rVpKKS&d>1!PezN>m%-Gd*HT2*%F2fO6S4nhzfZ96 zh~N3djQ@L0D+1IIN`VL2KjMJIf}F{SH(d2esV6$%Zm+D&sE&8VKbz>C^UM*FzUPB@ z<@g49Cs33+JbT-bB*soF{szu}Is^SR>jCfD9P7#dt1l-4gJZaPK8iF<0RSih>)rHv z+hcY!2sHfx8F*T&@0H2FWPgBw(?5pc&+iqSKR3kWEK2pcIi49Zv8iwhe?-T^|Iq;Dc=>JY@;Ax| z(f{xC#{OMORVDY@uOy&)DPpKp#IW(mPjd97q%G~m1T#PoCrJcU+y>qwl0No6?)K;( zyM7ULU@4$Ui@9MCONvi`9|*N&nwR2?x})}& zFmNPfzLI{+z|9ctS_r6+9EjH=VM3wDHpO{x73c|3-!|eK$g|p`f0}4|xZ^=h4wx!em?zRnxwOk#!t`2+^D}Ue*rj z_sEiz&K|yhmRbk_igDnVM;Px~Pp*m%RE5!gIOhPzhm6+udB>;@$(mDMSqU+0`i!p(oyOr{6<|6<~8KnQ)=-LvZ!ZpxZ7|sXk(;K z25v;D%~sg&g*mbQg*CplUy$9he=bS+g6Sz4mYabS)~1ruPAO=7rpW zF^LR2vAiOj+C7tF&Cj)K)r86^8x#hDc~wdXHfv@|AcG9{{l)_5lY<*uGL+qecwaUl4d}Myg?P^ z$31u1?@{x)<)JOBFRi#-%dGRiP&|751H-)i0+-)Z3Ozk9(I(pYt?n#L))mDAwu#jw zp9f2v^U7=el0{1$l4aEkLU>}*vIWVceLCMpePBzR(3;nP}H14A?$}~ zg{G5_(EwCGErrE@#HWk7YQIVMcY=z&c-=v@eUWGN?z#ylR`s#-4mH#3T=!tEW8+Ee z*nqbOhlyhSg4b~MTi^4Tu{G<9!2cP}gkOje4~Ex=99uR{I~KK_ zbpNZy|ApKVm`-nEC@zCiFK#hY2vRIIAC>Hl8_3AL5!?<#!)C+2sz%eU8WcqG{8hD1 zz0cuIbn*JsI?I|GnAy8A(&h-!T29mD=2iMgT#MP~-+M6#tdjhBX`nwyHObqwr0g~S z6Oo4$RJ{Y?^8_$!u(m8{htY*gut!MQjfvy>?@!-*2J)>6Vyo!T^N{m~DhyO5RSGp; za!8Aj`Otv)fV(xMxTllD>Hz;JzGN_P9dL=0TaRH5*!NKl)g;h1C(|eG4G}4dRaQS% zpyQmJ${v)kto%V~e4SD20u$BBOb)byKio8{heF`lP8QxUoao0l_64zLAe(SxUcfVl zt+L0Q7!s<{2a7@RYvM&xz>Z#FI&G?U;{N=|!H81q6f&p%)yqD)t4cjfQ|KJIRite! zSyeNwr%ROPH3@APIi2$1M6je^@n}m(-ck6W{cab~7*TXbz!X!pu3p^?vUvY7L$5zr z#+ns&J55t0$jXiH&ZGc&yv=)|)OfwrEk`<(LE&dzjSstfyRee3R<~p{QT=5l>i*+s zBouW}ffY;bzD?xCq=h)xH zHH5D(e9A}8FgJX%*X5+}sv|xlwS((X8Rp*X)PU@FFE~r@n)V=_9Is`@R}w9kWyhnt z=%t(E5r)9H{Os9|3S>F>{G~MhXG4JlMRG?%T>R6ZNdE5l^eRsAIfLv)N5E0;$7T2t zt9>_jcbxCoMnAtZn~Y|T!arF;y|A=mv5{|*Ju{eqFht4cq9fC7rFg|A-kVal7m?Zo zc%3*8vouY#acY~8?8TqjY`}3Kb#$Lb<@N0`O*kst-!!;}wIeD3VYu={NiapWD|N6Q z+o1PaI^30A_yP^6&-Pe787nm_Rk$MHxx`2@$DumtJU$EK)xS@Ceud?Il1)$*$d?rs zD;Oaa5t;ABCTH>NQo&|a5P92Ffr*@ZM$g2y+~g4OxIZAV6=BSc%WO43_MPmg#8oJv zuxR4$Wd3cezsSDL-k4>t5J#nQn^(#fg-5XFNGb2GLc84;4A@4w&bi{>eqMZJq1cjS z(!Cy2%43X7o`UuKfq+Adx#4z654DtJd;>SS@7d5yM&pQB*Vt$Bj$Uz`256t~3{s%i zLrMA?fHmf9Zm27G7&mUVhR@e3>-%}SK~}z&Q|x(>L$+4p!@Oz3;ry|hz}?X$u&LX; zMUy?izJhI8o_S|W+2GEC`>$}WWvrAr^LISwGqulD>3c&=#AcZPV=F{Q$Y|Jrn%{SD zuEQEGWx@r-Eh^;5-DwQgA){4~tVOC`%SCkpm+lDhw>u!-ZlL7ITHsOjvYks65U?IE zak7@=$VDYRXh20Uv%lm4k0{NVz+J*auz+?{U#W(t=)=LzPU3m@fbyN#o1yw71sckLW zQYxN&|MiUe+sT$(>yM>Hp5R;DZNnPQ?gU}CFd#<4DA=y)Axc(sBq_F)%o4@?&p2Uo zW%$eLDxCK-exD`*SDOAQeYsaP;Org#Eh_$R4~?D5XDA|W0MbW*i^%tWYX?R{2R{kVfb<)U`V7MAg8#qK>G2Md`ClTg+2!F| zJFPzuvTTO*w6gD)MtM_u6ebTI!}xrD+=R<65M6!fq4x7kj=T{F)O?phh{=AQv1xxI z%-GcBrj`Wa!y$uye}{Sxw&NCm!LNk7y4%Y|{boSFS9P}rhPwoxdGE?mr-tk(=Tv?6 z+!rh%pU#X~PuM?C6yY-J4ec0hu2Gf*H;xj5(9T=>4ZwJ3sG7-Gx&Us0K+2snt^ovtq24Mr6cfJ!`N6TTFkNIQS(`&bf8rPd~ zv|{6@P6bXVz7hdU3xaP@Bs;`PJg5jT*-RU0(DZwyWps?YRZXP&FSg>uAv;oP|*P7!kz)^hyrK@5bW&B~>XdKM3Aa?)? zf(5zk7tbSAWLgy#5$%(WRnFmm~CJqp3)#vVB)ABunO3V`<06U7`i(~H)483 zgBThy&Jz9Uys!in+}eLsX)bDtm&Ru5_&QUbH$MNZ7=#ss`)8;!(`2aLH-WWYg&kW^ z<6|QvX2gNq0pSeg_Nzs|bP--Cjo5`ogQ}1mmw_m>p2_e?7Rkt zBwpgZMQN9a5v;6b0IYSK-PBRhd-t@);^Gk1A21GTOba;C)>q3;UQ4hB0+<>TFZOB@@2{Yl5nk`O?ixSj0sgKq~ZNpw2D=^$O}P zPkc4WskRESX&e5~9+Z7+J>fC)T|i4D%XBv9%mknW?rpJ?0er5@;?6_+Q~ zH|ACmXir~j8{p~kR2yYq#bg*&0&;Y{?aVHe7vozHaEas^c{wy*UOH=Z^m(CoR#zsU*qKM}Ol- zMIjW#ED&)VJ@8w=9OG3DqAlA)cQw&^($2w*uo$W+6R`lq2IeJgA@TK2-V;g@Zq_yk ztK%d8)03zn7hPY%@2pQv7fiWKEE`3J?Z{3u<)4nK@xm9Y;Zdq$*Oa<1gP@1c-}Y=U zU}C%nil-;Z0fRCUcQQM#+XZS$7WuF*3v>V69Y(GarF_Cfa9>$J{3;lh|5S!lrd+sx zdu^-g5_~S5EsHX*ZQUs7bh=bji3yLCy%h8D63cP)qLlBa%%Q_SAEjU zD1jqgd73gXwdfD5^5r)(i*0g~uwaS*Uj#x%E=q0{z~A|eMsqT$Mme>CmzPFLZ zH}@56cJ{WBA4l!b<-iWaNKpZP<=O4LxahuFlU(MoFpk@tDDMYb4$dyGVOdW#|3t}< z=IxlTSaTM^HnRo|mn*Wcs7-U3{J2l@<^6YsLHfxeZz|8z!_^YR|DQ~v>HYs3N%&6= z=gHUN&MrN40a@a~HX=*EaD3rRluCEMe6WBZ7)G_Nt4fCeH*^Z+xP`0?h(cgqex-<( znFJ;CnMI9&VwaAoBKRvIEBf=>>M<}6vRaz;bokhun=%atd1NrK+;5#WWHvOMjiWyq+g}2GizJ5uWg33qV<%!)OeravA&B)U3`b2A(}vQm&6$B^9QT`5qKz z4wf9k1IV&Bt2FK&FRsaYKod>1Qzh3rO(86C#(DXg2H(o{J8dHtGM7f>Of?4<1XNuY zZ~GTGFr`dry3ofndL6Iv3aLqzK7lyk8?daRWY+!rTK{&ggvsLid64Ma9>_iB%A`?= zCt;Wd8dk?f-j&)Vyn|EY4&IrNu4zehW>61MSrqAUXSh}?kQ$`pjz*<1le55Rh>r10 zV<7&J6)&uZ?2gan>^CLHRiSjH*=;9O{enQny=5s&J>9&aaH9D^3}E9PlXg+QdB6jx z;Uyh6Ei4Q`K6?TX0>E1c=!P{E;sLPAUg~ZWB%M&6WgMyT&7CmbVy$H(vK0WKvFrft zF1di_&#%J-Ow(fvTsEao{W1e1^-Y=4CapeV)^PY<0qDRZe<{8>R-2BP_L@|lOl!Hr zz(X6T!x7ZIJUq zvzWfgkOkxUNGO1caZ8AeF6;gzrKt=lk}(*o9L%}TBnCxSs8c-nb38fMVhZ!@F}}g6 zpTbBpYg02S-_g$rZd4cxZnPE|d>XB$%i1)ZLuSOO&i&`pLG(#~j17r31(!#zf3^V! zSfmBBGfJOYcidAxdV|l4?O~zUfXN4L39uJ;TnIR|F-{h@M}ce?#b%gJ+nsP5Bk8+G zM{2Qv?|eW!8~0PRdO^EFZ&>y;lz*B0bjJ&EUwS#JI}`{Aq_XV?YDO@TK4IiR!S)Oe zA}&X)_StvRLX{<6Ip1dwtaw}Oc)5n;o6Xjm_a$FYDrb%u%Mg)!{M7yP851o1oa209 zV|4LZ+s69Fd|evkp7|!85+H25&)_VXQKb+XagV5!XiyJUpN=*tmyJE32VUfJ7CXzq zb7T)9zcU2^JGXNnh_3EEh^m+YK7nMBc$^+RU{^i-5S)1683Xg+53J`^bQo-3OiNFz zC3dj#wXie_T}Mmc9AKbdc!V)78A>ufW7jQ7#r@y9RoZ(cEDQCQJ#IE0@M)Ulw?6U$ z8%E)yP9L`6@$c=y<_`$(g+ccDrxZIO*N9<4hSoD(9TacHVW8zbpcf}LNXg?q;MQgoj9l|n`L4=i$v zv4H?k1kVdy@OA-!80I3h&pj$eC%Ye`{EEm^9qs@WhZ0TyhVua~)Zk5nKu6Hp@n-bK zH_&_)xe@L~CspL8FuEpQj{1+o^Lfr`jgC>;bd^pvEHVwjXQ7xYJ)wSzN~eb1(gqI( zJ%S?wEnsJw=*|n^c7R}6A+4Bt;rCzx#)CH*P1m-yxyW zcX3yr%$57=yq9KR&_rHrAka;9Cv`s*A zK*uLi3X(3($aJ`STo}*SoKnx!Fq8*$0e#{EC3dZT?9qjYxT=+%Mo_O^SZpvE^r;R4Ea)W`sL>(P2}- z7%9mmR;2jP*FVwS(2yUPImj@@Z zq5)zRNvXKMqwU`-JoIPGgC!rrJ7}ZM#@3Vq0rEO8b2u}T}bujUs;*cBTs0Dh~Z##AbfXFLY*dH;2S%jfDP^y zPW=S)vCM=1^%sF=SYTxk+k1?~SB~{j7w?c2(DK6yX6}#WrKb^QM9)+))U8eGNNV2s ziy%;5~0dhXYw5-&POHyd3*uLk40jUPC-XgBB z*;QEzwcFqC3t0o6hcQ^)UQ|!e8xQ|YpQuvtM zS6ao31}lT#fN0ftt0WGemFgA~J6njLtg6>wDq`Rm0|P~?m5MF@L!^Q2C9Ogdoa2-f zUC?#fyf?>)0%MVDa>Uoo8kr_8V zAlak!>s#Z|W~bWFqAzHaI%d^9*qHif3MiQt$;vh~qsrdbs0v!3#5%vU$%`H8QVU4X$Z z$dVu(U$%gzPZl7n^L5jb(jrft;WvAxis=(`V1?rjEd}6@IS%u?0TNJ#EPJR47!TXVfe+Fup&E12H+kJ8shj)p=CShd^jeV52}sV$Y1YG(&^Uy>~~8`)bSChK|*PM)U%`X)w^07Wkta#ykiPLThxf!~*$Yq@x$n|t== z@HMLuR(TE8Tp?kX#xvV|2&AD23{O?1W?WQ8=FMSylV~|n!{~n0?M9_kCoAT#^FZ)i zHrlM`n3c*sqU;94LC+-vhk(0&CX8nQTD7t5x5JKL-n6pgQqM%IbN~YldyUw<#sN5r zFSgwyml9U6cYRM}QDV8k)`{(*3ht7^MyuS^a+J61Dx%iSDa7qBq1^ecew&;^V(}#_ zO`+ZZchlT~Yj8j$3k|=yF0I}%PtJ@~U!m<4pEfTXK8r#8I+Z=Je6Sqp+|yyoSW1nM zA5IyP6pQlPaWf@R3d)7OkOLufXyT8!PCM28Bj3{bkH^oDd(S-%J3KrMXeFrbUypaIwC zslL;p1gp8lB}9xhcCw4sA@fMPw5as<{XT;bXOO-ym+)sllOQ_`E>FnKU@$?p@*q)GwMjxIFb#pyL4M09 zIMwUx^2R<$O9wd>x?@*@x^ULhEx<;VGqteGO07kMuUXhSw0{jW*x@%rV=-muUw~dQ zZb|#_y;17mws4fAWhX98tFtpdis#5;z}!OHQ^{Z1k~Q}#%M}xPcl<1VmOkj8KkZ$@mZzgtO&F*F?2COt!3?P2ep1(aAj;f5yn~JzzQ$4lU%{_-Ztl0U7FQ5`~ z=mCV;ML{5Soh*uRb?Agz6k7FW2u$-AROeI&_;@3FmtG=CK!S+0{Aax8~x)Iaq`}-s-7kt8dT%BY>KaP z&o_sBbQ=rU=lv?y6~mfORjinttFpoiYL&ZqQN&|7TJIIZg~y``+sjdyQf46C2zJ>q zzBd=83GT!@~B8(~>pIAHBlORuFH5kW*6mu^vqkNEZ&H0(3L#S-a>*RlNs=>~^> z`W2-qo`bZM0+~9o(b=$%7t>KJV}U*<@h!3I;7ncPF{z5~7ok8pO_rxu=!N(qcWDO^ zUzhdOGrjEP4JdUW+bYAe6kY_!Yz+(89A|C)3A^{|^w1M++&E8{Hph^dYdhqr&3fb0 zGG`6@kIP5}N9GM(;;%j%P)L1^^bU7p`vF2{z!DbB+ceYb!aGt0EkC_ zC_69u`Z;v~pbMaKn((4129(;uxP2Niz23rCv#O)P*GfY>4E?S4_^iWB(4gF}W3a5d zjkb-jySTv{zs6!`VSN)MY1BG^gTdQW%w~JAC=O}*f3^v`TaZ57IE+by^v6hbpkyE_ zP$zJ8%}`0JPsQl>6XE?UB<(YG$|(RxK)Ao_^m9roD&q1VN@$e-O}XcLBpZv2=Z-D? z&!Ay&qSl-0mNgz`qj_`ZRLC~}h*&D4OGz_QXQ)hXkal7Yn zedyy-+_d+Y-}BQ1=9J|3eM;BwDN`59oigAja0+~jcYG!3V? zB32%Ey463F#8#lD3tJhUWb|*ef_S>gnr{)BaB1+CX8S4VrKe(5op9{}f#t@hn=OaT z;6>9QU|0;EsX4FI=e73?^{wcyc{KzBlK`;vITKh+JOQX59&@q$y8gK3?ut7OpQm*O z#Q6z)Z}j8)Mnqc#Xr5t&)=!OQ7lzvFS&P}%dA<=zHU3AfEGRa< z+fOuh%ff6_faso`v?DpRnjh9Ggc*q89ZjNi6k2dfU`@Evh-N(;8!5f)7f`4!% zvJf(;+HDoUmB<}vl45pt65`fTx74B90yirYvHF4c>LBo4L0ncnrGM`SC+=%KL$L1| z&K3k9RhM!ymcCd7y@J2&O+rc!3R)ugL&CxGRx6xU0Tb#6_Pm|8O5wb{Bt{v|ltW(p zQG~7D&8E)~X61$H^DT>3FwOmk@d*GHUHTgLR|WaUqHh=2YoVuyr@Jb5F$xYJ|IX#S z6`qLbj*>Mar+XI3J{=M=tkN;%h1iAm4-@9F=OaGfTYF=XuQtm;LB7tK! zAnlAq0-x}WVLqbLt}b!{-KuKfM`Dp+zw?`7u>HdAcoSTd&BP5+(NP+?Q0=r;!$HBt z$-A_m13BM9-?nWwExN0Z-yYe-N5jMb{9UoxjY%M2q7s6TB2Q77R33VLdDF)(P4iP} zIA6&=B1Kq9h(~hsZYABMgUNI3f7EzMbP#`BRIc@Yq&R@^CKP?* zrqF{T29I67&b=$(2#;1Ht!v z$}kNMu7I|>j8!Jw2{nPLW}S#23kSeEOYv0lk}QJbXJk#sYYr!>LReQevDL$~Hzz z7d%8Haf%16ynB-=*!A7&*!|GAI#IlyV{h{*eRzwHda=ILw1JHNvG7DSZ^wwRe`l|P zzarAm(~`2@@e*{$6b8r>Y|t1+atd`}jS3-H*8i#QX8czvq2B!}rDK8Og+=ckVQi7G>z&Rgwdl{x~+K_ysBqB@0HBOz!zs+x?~XAzS#LW&@#vDF6d8XHo6i&^Dk-| zwpI;vA;VAs;n{hq%|;(U;F}#;{kP>#6Yfw$8ftb}dK{NVfqYiKes;DsvDQJd!p1LJ z4$^2{$_>XhvuIBqX3o}<^>*@Wra!Zdf=P*Px;FH%GE5pT$5!0~(i4yS6m`6IeObIX#sSZ&?Z-3RVCLphfL>-*lacdR=wRK-;>qH+?c zPJN9=Zo>~VPDLmvt-UZXX>JH+uQitmku+`!%HC%ckxRc&uu^ zGfxKA{7c4e1RIR%6LHO6gkO7v)(ByJ?8&!B0Ci#PGfibVp!v@HTJ6LF3vto13^1E^ zx6uf1xX0(34UcN>=aS2o-J!I;gCFWSec-48&sO!+p^^rckw73C$aJ$?-`!vsu}9?b zNcW|(-}0mxUpdaJP=pBj$?CPvbqeT`Q)Sqino6{7Ly;OgW$jfw8{&Po9P`xoKj~x0 z4Gn$2mNCH*VH^!X-dq$R1zT89LZB@8lPJQ%p-R>5u{q{36%|&;es(2{?Jrr9ovrpf zi>D4nKELcb2EHXD6K&0j0k8Fm%$|;UJ&ai=4NCp}#4m{nAXu`eH)TjKw3zv<6uf^~ zJz`M*IRH<9fx%{~U>zrr|5p|m^>}noBa={sQY@bj%22+^p>kOG=|R6J@`6xe^7Rqf zIzJ;nWTUn&(UfMUR0t$`RmzO*6@~)}^q-%4z)1)QQJ#H6ZEdN`T7#dR9u1%)rXV@S zj#$uqHQN~+<7>FA__RE*TZdh*eZ#@W-ax#9Oswa+P>0Ji`|`QuH)MRYI=8gJn;G4`{Mo$l!3 zr|R(2u;h*4PNK5FqO94`gQn;qTTTtcp@JYQFVR=onuI2G*%miJx&A5#l*@4sRrAA4 z*D)ND#XU@sRZv6Lw5wz%^K+C2(a!ZiNF9#JkoFK3w(lY%cvG?1F(gN&suxnr$YwUn zR6N@0jr6iu&#QQso+PU9f^iDzLgoBnQ6xn-bO`E9CrG?Z!6%2<3*yw?W0p;@<;THB?pSRw~v%^4BF4g*8P%S)m0Y0|9_jX*KUk9rEwhIk3c1`bm_!2!F zAQdNwn}d2F%l7QP_WRr8mfv^+Fdih1Fk6<-ff2t3>5Tc?MP_>+nu;5sD^Z`AuV*u; z09MhSz2iplhTgO$xJLHVr9fnU5K{W3=3!b#l?{jknB0g}y_-5Urb>e|XUdsuLDXeW zFXhqiNY2T|Pei(u+h%_)hdXNlplZ0E!q>&APBl|PinT48+`x~9wM}rrzV_J63}X%-m`b(L_(F#_q;+doHv(s z0s@RWl_K5uj7H}?MFhEXLli(q=2L>bk!*Eo2hPoCPZ2=0aR0N&FFz8< z{ATCn6l>wmqY5s6Z??R*=M%E+<&L0G=)67p2qt@GGBr=v%S1?CS1=z>$H%Y7<>zgb zNY!l!MAZX_4C(Cxj|?ssX!qVoCVp2jRTOzAPz_#J7IjcuZ6`cfT^c4D4hMTqThb1; zKjP7^{R{3y2vO5$Df^$5Hy5v&?Tn~ruD!2gQRKWoDq2w5yV}Zw)%r4NZzZ%IX8?Jq z!Dr^=)Gn@y#f?l>Sdu|V2!U?3o|J)$6Kqg-ZTmeiYYL{|F`YmFv6fFDv>?Ls)0Du^ zg)>7i%X^aNm>m&Bvx?gxOKMpf{~O(7evEXvCc>hXg_zsgU=awp8zkpw3GQrEBhkZvfmD!q6O@0Xm8vb8uFL}0gVGOO#5Y81 zUe0NCR0Ku{)9PtSLLGp6-F*CjHA+8n4brWr(P>T8XCOTYR0L-3Pz~tn=iLEmxFL{e zv@gqIR%YqdS~r`$Dz6s-4Ls;W6(nNoJ+P+kyMrJ&)sr)~(^8m?{(T{sII0Qc+x4@2WW>%qIa>`> zMvo4O2h%I;i}bcz;{eYu&xUir!Z41<*@Pac{Xy~$D?dr~XrK`^7O4v*f?S_p<; z4H153XkSmF2n~&kRAJJtfq_jJ-&NI*C&$pz=iROFFl}~Okg8wp)ei7t#`LQK*p!45 zL~x})b_yFUq=Zu>y*Cr2SMi3uz-k?VhJQ$EOW}FbBdn_VR7yR-Eiw1+zvbR(VA*PY z0ojQf7o<-NHE5t1S3nmuvIm{{b=YCostc>Tk8KOv=t~p>7u++jo*74mj6FlCEg4?3 zW`j|hbdBXNA(U`kQ`B~G4G#vc3@kJ_006Eme)MOz)FH=q4{}jtH332@-50SWM4&p7 zQVWG}7tbf__BPyx(gi+5+29>*e7Z68b7R(pFny9Zt`@f2c8o_>#K_`Ka>HQn{T@MX zF8#9^Yuc^^YiM3~_A-6HR=^2y7_9V8KpZW zPFr9a18RJN8(0l4$nj{?lOC120@@8H8GqiM6Q{e94UA;}v?KtBz&rtOQd|iEyW6(r z6->lgyjy*0%VqYS4%ZR{^xdVUqO1(-Iv;C4zlWKB{2fUtyZSvBV8N+O#`MSk7HL&I zg-Uqa>1qh;Z36ET@<5=3xDVaYE6MHM9XuqLEz&wvh!etn-(exoboEFZ2N2TnS-J{Q z=wE~twvXU0*&hgh9A7}4?^>YLf-|}4SGMAeI%ZaM;^FG*vcS*`b2&Ma>aE)S+LX7H zi&mQ|2$@8O%e^i^)5GA;$urhk< znBsOBK)FMUU?f^m2Fdy%l?eiH&ix@)sZE$Mx9g#vv)Zey&jTfX6*GyjBGuvz)X#Cs zAWMT9GWMT7hMOD$h9Sw^|ZjAuF~P&-&!Ta|Bsh zWLFEuKU30gO;rKh^ngv#>>YvL4n(3y9?p$7$cUw& z9y)$QeFKsCC#!eAKawteqb*`5_*AThrk>S0%(`huKZrYAUYP!n-tY-zU@zn_QsWU- zt(j7p7=~N3^iPYBy{Eq%pIt zMz2%S=*&GO6;^3;+XhwvSQ03f3?u#1Mo{+0J_&Z@Lr=3(d&c0chv`qwFSwsBmP1>R z4FkyBu=mp!3$p=hR)x`nTFYr&RJ}e#X@o7@EUw!AFMtIBLID>3(V7}6*13aN1;F|u zYgOee25C5bU1$FfPVaC;ZV|11zg9-iO>?gqp&o?X)6W8M`h0lYe5v9xYVHNR3jw>M zqRmu+yFS{jiGaV!tf~YP_Od(>YMt?(GZ%EoKeJ@86d4KRY4|RNF!d_|Pnll=h>}FH zEr__bFaRwvGXh6qOrkZ#aX-&)6P?DGvh-N>+eNFGfJ@!Qv=I~pD%ukZ;y8IEYxP{f z*S!5um9Qst1kdS_!GxxZz|xQLe-I!Ds0k~&$&7eG)1)Y=ks=4XjU~+BK*yZ5QlBnY zF=P(MgCif(Mhm2YBfds+vRSocU81=kuSNCzYV`f;Ez3xyIco9huOSb7b3M|}78i_3 zQUSM>P}6|L<_Rk7)Fe9Pv(W9f41@X$8+fTYkdJwj)2hc~j3ko|gfAX`x#d68*3CybY!}{wc z8zl%2RI;FmUARacd+0?ms7RTocjJ>8L$+*yBtks*K1%{u^0E@24t|CW%jkypL3<*y zuMi{;1c}I!se{X=)FT9-sc5Mk%cyX+b#ydrthn^_pzw^}K)776jj)=(TDZoJ_H%zp z9`%(0yo3T037h^10*P-bSZBSSwtBnP*=~kyots?8E;mI8{eDGk?Q^n5Qk)+l#H^j4 zZp&lnUI(3jroS1#Sz6ZLRO&^qKCB~ms|K<*-U7s66H4_wddx%cM1=BUEp}GRoMvGw z+L=0P(oSk(~^}S zMD9Rkfl2}u{ash!X5fGhjDYYUh<>&*gL+Q>+`!!W-KAbzt8Gy||6s|7?9UI+BqaNl`TNDqMlr)=K9w`;l7ib*@ zdH4D7V^jl1MdVo0G$?3!mnKrwwwnxkUVJjm+nN>`QPOwBNK+t*G-a2g_m_9(F4F#Y>q;p*1$FDvz%ChCIZ z3$CcWB*ntSq*b$~0jcH`tP5c_drT$a|&R!$$(eqSQGKdATR^ zAqUAoY>-njmtq%K z={vxR9n#pjuj7csihHu_4hEv8>}fw;3jpXaM5l6~LcBpQ6JXKTLuzReO-J(leQ7A~ zy||wx_~<+Xv6pp2Z2s+btIIedO>o(i0vzVaLfb(nj zoV-!hJr8^hVWy;VE-j+68)|dNfFE<2ylYa=hAknsnHubGKizy_w+5_&!cYW-|e?%Ny=g7bd|ki|sj z08jv|iovq=Ct5~Yw&@##h-{|qNr^0lb)Yxo7iff1wynR-@$5Ohi-QOST^WO}8L8n- zkpaqpqnNQO)P)?-jO25R)QfWg4TI?3^mWi@3()W5v4`k1y?#BL81{v%iO<1o77m7P z0~WluEj^R<%WbYa$fdZ%m$o4VvX-*9%1rzPa@Z3-CqEY#V9 zzbkB3a$4vNmJN4{^@pekEg}=WQFe2L*o3J1cOYok3LV3UyD2_x;_fU>|7nkC+dO-# zK*ZHH)f&cbL&g+ zzSOBb0XY|3k^6B4`e{+eBUn<`PqYLc=)IuED^Kc;ap~ukQ~_yc{fx5$={23*Q115vfgs%2ET3+Pl3Ife0%;KM70PiS#1l6ahBlIbT!>N~UE7qFMz}BC}nV}FX7K5>RA24h1o#f?jfiK;aZ)t}E@*Bz>GM?wG za%KMevPt^XA(`qRGa_C3?6vwK2{$NT#ktvb}7SW+T_6!GcnVz17gZq%99Nb7f z#?zqw12NaNZQ-EwFfgZS?8sTt^#anHl4XDA2t2fw7Fi_lsTo3yqrEg-{hPC&p%W`o zL(5I@2Qw58suh6K^<4#uj|RsnugXcXh5plo8umYL{BS5BN7g}V0qnG(JvR5f&~;~k zm1|vHF_iv!B)u?FFHek#vYkP;IOc^+rC}Dc0IrBZ z?7$iUPgM(k{y89S;K!h&WukjPnVrjQ>wy}wc4@k;7Q>tMAu1V$Jho>cYiM2mY|_%P zoN0)G0_9+9P(dLzq2^E9i24J?PNr2AJ=zJiBKYi+@03gMQ}hy=^3&W^x? z5M;c@#RDVbNfaJSigCxTVt`?C{_`8Atbeg4%(vZ3lsVbLL-^G89-6xvGiBB>Y8vKs zYMh6hjxX_$2cM&iP9+{D8zlJ7m2{Hf`dtw75Ht3Wy~qVHD!Y>oAO#3EiD*x?VD9{I z)Q%_J)b95hzb9*QXF!V@oPgyZEI>I{X#VW8zuducat@~u?{lvPB7o4?^~oy&WS;1!*4z-F^6K=u(|G4i zGYbM_S_K#8)5o(3u+LhW5w~HH3R>17Msr>`$e+uqL;~`2zjctcA+RCI2Gi+LZvY1e zGqPv+dx6!k(I*{sfj*pT8l>kJ6?k2RJ-HNG;kC>t3tEfL0COBrgml`pMlEbqnrOcT z+y`-Id~etk{}#dlUDK~KHMT`XbUh95z~W#kl(ldcHUsXYI3D3QL)fSw90g}ZGuR-y zFw1S9BTgHTWKc=2#vA0U_$44H@pj^?xH&R*o+?p1VPB(>f*-|I=6c)AEIQVEmhGk4 zK9ZeN%T6N(fd@s^_?*WRYLNH8cz~5Md9}(OMF55h2FQ}@wU=Vemso|4_mD%P?J{~k z#K<@pk6}hLW799m+FyY%IibNEz6I7e)HeSdUWy)0c_~C%+)yLv{S3>#hH8{amJ@u@Wf% z;c5#mV`|v~A-L;+*LSKp?wLp8Vt|?0?bk!B-Zv$f(!ypso}NxZBmsoP z3c+r*ug$cv;RzDC@$97(Z+1U+LFhwVI>>a?aD1*ow3b0!@4YErx-tEjg+wbgpx4ad zP@HPH|7M!7kG=$4g{nN6ouEtXF{3UUkN+`Srwxr}oBSKH#*a?M;3|B9x^UZB$8+ut zs8yD|Xjvd0Geeq)ra(QI1)U#s&!$cg7EE*?&kDE@#-RdT4_DR(uSCt*q z|8j~7Dsl^+i{vV*bOX^1OoZcvSb>qgqbl6~nhdJYlUPR`qpOegyBm%&A*q00lvY7d zG$j??w^PQZz)nMt9H5n-hGk6!78Rzq5Ll$1!HP1;4dLAP<6u%46TLG#H-md0!f3>Q_ zn}}}s{iz0yQi7T9NalUGA24y;>gMfc+0+*hKwFv5#pU$0jb$Q38SmutTWypGVn=j0 z$8cx|))ZWXHAFjX-Jo$){Ixqa>(T#U+HOQ)5(Az zH6OGiqN@5M%>QSzlUtAqEuxQgS}mCfs#axGx;M=@c=ghI_B%#oIqH_3qlS7^!f*U$wJVv&F+ zR*FK$oCUmWeQGaFj1}0VI8am~@f{m$A85^66ax}gM?g(q(_I-_i&(v{w=+!_KkQXB zbyfhJv?&4Dn-Ue~0$D|suO?a_?tWloW|NeG4#5d42+~rOnc(@Fyn_VO0t(uc#R|%m z?=ee_he!$NfQ^dx2j!IgiJlq-xr4y_GFGEtW`;&X-huN9n1fcIGk_|9G7uKfc=*~0ShcK0YIJwd~jB59-GS4vQjN$I;KaN=N=+ObV{`Eh&I1NW@IGLo2yZ=7W?4t z*^61BtHhz;b0kq4NDI&*Muv~9!*Vxa*aJFlUs%pNYZ{2N=U#MQXsaE~RY;SGtQ|)1 zL~X~`B|$-rb*=y`o;-pJdSr`m(u;NKy3zfBad=(69S$J0px#ZxJ>!gOd=6k045Q|t z<|XH0JARsarY$&=0*g@yOJHYMMO`=`YLg5rjU$imuybY>4t+2_gn3=IE@A_!tfJdg zP^j&V2T?D%qne(rL}K%CJc!rEm!mJZma@bCv5!wYqiNfC(Q;gI zF$6xk8JI$hY259X;gn^B3#bAh4MZbND z+Nhhd7VaW7Hj?ut4^u>=k~pPJh3b}^JOJ!iGb*9}mErgVN^~)&ljzMqEWMv6$d&GjtTPko)r^~f_2kgkYvC;fCBed1h$kbOnRS-);fKa)Sh(PJo-7HD-2K8{E!c)6ev))pCncJ&qSE%XQ?Y)a8JK#Mv$yOrFWvz^!2Yk z4ZuZy%IA@SQ8g}Upz~Slq;p8*j;acy|jW&+LYO4JV{)Ta< zp6Kib9-Iv)7xnJu)yynuWnsIwdYeK*Mn;C)j9UFJhs=O>(NLGBwqthG{Au?&1Ap=6 zMx!vRa55vV*G`Yw&Rw6Z%#rQ^i^fTv7B4Y%@nM6}C5>E|sqDQn>bAkgZ&{6#(E z8|ubLFV-pVN|ziHw1G_N+l}K(=VK-jO;uu)29&-plwUQ+XZBglvS0%j69RaFGtel> z&9Q2%Ul`4OQM#A()17hpma)1S7k}z2b!*f_19bz`3~XQg1?QJ@Veo_Y9dY@>Gyidq zAL8%4J?}uS2+93(X78!*N}XQCH56xNaWhGLhBEyFsjn*L-Q^EL)sno)$SQZ`H~jwX zG_*M|`WI8qrjFGSE~rO$%vNkkC7^1r_dANkl<%pEMJC-d1V)s1Z@M)QuY$!2xgRxo zYS{g!sxuHj9=(^kOw}@wZ|d9Lt${xQKb32kLC64U9O!g2I3Brnn6(;HzYS=I(1|M` zEZfZ>_o#4g6mtpdSPwYTUqM@pgPa|l6^_$1TP=`_9e6G*0-4*t>>)l$_j6Il4C3dv zc0xpX;>Y<&G>SIkt|V*K0XR3%ve7mqMHN!c#0N-2`qxFR9w{zby!lQH)j&v_- zNNw~n=2PU12FBIC?34#k@#NZbpvVWRFFud_pD~4Kaf(boK zr60Y0Sgo3q{M&+b;A8u}P2`9gpnSUW@a#TT%q{yxD&Ab8#ihknJ5N`R2Wp+@^Zg)adwAT7e$3oQ>Op-cR>8CceBy57$60(TG=nQbrVX zKf3P+K1>^P>cNV*)#ukP3#!Duy<43nis$moD{Le8uL%)Q>V00QvOV4KdKg;Wm)Q>G zv436|3wfX%SKnRO)}KwY1L9){=Dsc$|BUDYEC%AkTs-ui{xjCSY~k*=+YwTv zK1H?fK&YHS@D3C7@em5K?^PB)gzOl!6a6_oJlZR<{&p%-!k#=5iHWA$73$GS6wQW9 zi#;;*MJAX2q9sGrpIXha%;IwW;V&4?3s<{l@>tErF`&cZe;&r#{|M`JeY}Y8ZB3pJ zp#YYFg#=_Bp`JdNkcu$brFEJ$PQx&bFgNltyeqW$e9=2UtaH@x2h0ufG}IV zh(E1T=)TGfsNiF35utL)H2sz0e5X%LbrUT{riXfx#@;q1H0XcAqF_V9F;Zd@3)=Ch zxw(hS;CEnI7aMM|VeCK7iOaH6UU^YTK)RhhHE$2B2LZ5GIp+x-0;C6wg-KVxGk8dX zK|kVvpB{NFvN}99CZPSR@uDlwV;M<^hOqGXrJ@uejrPd6SX#YknW*`JWv^katB@+c zs8HYnT2;x^MMKH+j3)%P*S;ZWWVmY80y82AnhdHZ=OpW}fB~}rPb%tGabWalgrDK> zfp-T|u~FNR6D{V(JaW+pM@$8);n=dhd*dc6UJG2X!7Nw>u&H43MS8V6>lD7QGmjl%s#PWae+m&r=FE9fcqN?4`q z3#rA=KC$9-tQ9slv7}jG6c?z+U8rlQI}QUAg_fZM>$TmbZb?jNl7}08{W8TCwkPob~Z89n7 z)@ydeyoP-k%gyd)vmZd$;Mj6M1=POzW?hb?Z2}v+y483=0rsh#tv`vAal;lQdw1Rpd>b`-bHQ}TAtT@l40PBH4|O%3}q z=*=W4f~5>kQ2b4^;QA_MwaG0~RRo}Bm`a-9jF=2NL@9AbInC}_0ls5{khVT`4?!>t zj)>I5wSx2rB)WUoqs@Q6)u6U;4rWI?dHF^pZ-QaSf%25Nl$=T2jlPiPgRD-=Bt9<~ zR05_DG`CVKS47E65%lX5NGEAWWXa;mf%DZPo$H#)Jk&eA#2s;f2S>JMxfL)B>)vT4 zi$m(KcjrIKZtTbzY?w~bWEerfPWo)5ZP3 zl1`=8E>OFK^YZMootA)RyBv!qpNGm0!q&U)d?W{Hn7>@_|0?Y}P`(j5Z3Wx?kYA$- zaNm5Bl>H-e%Q?8Ok;@jeS&~n{JJ*K&FxDrysDS5is13d*irg*~`$iT!2yT`OMstNY zp`b5EKwUCwYa-8|m{J>#z?$1aqi<1HCBoJ2{OODMBDwpVYNT+~YgoLe-o=k*Q3}yf z*u|#~6x0eQ<0y=i?TOjm@%$6<#7M>NwZ^tjD4oEHYm@a@oNj~I`W5dSLuiF9yPtZQP)#p7TwDn$Ci~g5*W>)| zTZ;&P6zE~bcgM~+JorV-s8Yo0$q3XSWMxEmP#@#}Zb@z`NseJ8Vn-wh66O*T0*w;% z?vDb}Y0<1Me640~F3eC4;`XWVuYS0GmfjF>ls8IImy!H%KSCzFwyhtz=XLIEkiSu_ zXJ&&j=rx)s*vPk2^b%hkSm6g9z&_xjumPpt?OV7mP$H8VMAbECF3w#}{GB6daN@*8 zkoa?oI*n<8uqfaPolwwM)F}F7!uY}^y{Y!#tiu^#!oXxYBYJA!O@OrupJ5t5>?BQw z32T&=j{7_|&5rdh{abj}7}cA&y#gJ8T2q&7mr;kVO_MdCw#$sWl9Z59ME8%v9iYGV zXEr0V#7w^c9NQRbK5cej)EK#M#~fOq-%p;FXr;H71q*)d!vjJ}#?`eP}O1 za3dIyhCipnq9oF(@Chmc0t2YfBgrx66MFioNp9wdR0~+;(9CF&2Dks{NvDHTi?u2!s%NZH+GM0b@o~Wv z;mkkYxzsJpN-`LM(BPHU+kwdJ;!>%xsNB?K6$rClm2Q~8eKcyx^p9=KgZA*XP#Cyf zr#BH&q(>c{vabcg#?tnjgTRGy=cFbHhrD8R-Sj%YIV{!j18;*OfFiMa2;xm_`%#c) z!wb)BT!KVFyc&%RMjXHy|3h#=MqRS6&cU~T3Byij z4=uf12}*Lt7ay&1`#o;zSI}Ousbk?A^Y!PhAZ_7NQMlXYb#H`9cm4Fr+y69Ap@9U2 z7ckPE>BQP=H_J!<_NZN-s)8i~r4`x|sJ^lsIN=G76e&n_E&R;WgVDH8=i@g^?tvOJ z^a96AvTq`Gy9t8U^rympc%toNV44f6af>IM6q&nSnXof-b0~W(3`ulZ5sVpFPz%SK z4-b^7ghA#Ol`F6eGkxOWZ9DVfl_{rI6DLHSAhTG>;unq`Sdl}<8QNxFEIs&uk$;t> z=f$;PkzZe<9O%LJ!wO>|)pZCWn6KDoyc+!V-K^uN@Q5o_2Y9A1WTeFV4ctLS*6?{Q z3>%n0R6&;g$2=fZ9|@Uw&P-z87TtN+ykSXV|eR|g-)UR@I8$O8R-c7VUivly?v zKf3rmKX<0ZtS_YNt1zw%SgH0<)z|7^&0>b0DMv9gvV_*NuryA9LiPaDLqYHqqCn`Ks-|t^tz@NLJ^|60?DZuwGn>`7> zO$*hacK|a{8t1^?BS}CJ(74NI^T2=R@W5}c;SW~TonMbUc)0K{Hc_89;OK=N$-nmh{!KolUThTbNrpDFGgMZw3gwUviHX&;KFw{?~|w_iuI)NBmFbylBwK zcu|@ltmOAa1A_mO@xomBCusvo@p{5UyCtZ`&&mTW3du)M|3G`+j8xPVb1G*7#C?=9 zFCSn3iDar|NIWDscn%TyVLfEpFCCOV?c0T2Q7Ihxx>vmU%qiBvzTv;}cF(`2-#8%B z<@`kqZ+ZpJ2Gi)IJt(gkr1!OyGx{h&G=78%KGVTLRBCyRBblcbM0}}PW)*Rk%T2Kq zE4yIlBqM9?WMsNJU95|5{|FfSM4Ro6Sbi#C){ zwMg|vvN^?HXNG%V@KEj05h)kC({00zF{qtXzjokUHs=b*+iF#VZwv1})q~W?SfKU^ zxK)+>R!=*((uw}13j7i33ih@(FrJAD<&_HZ<|{=g^3nso)PG_2o@i;M(4G5W!BkvQ zekDQlnV)q7CqR65R)g?}*yp9}rIt6$f>-uT~` zHmKA^k59snngFY%@AhZ8r$FPdloJ!A8eps8;jiza=JY|-XTE1q)kC!OKyMZxS~#ee zJl(ea4KXIrGcC8Q*w1wA>ad5}Hq;<#JSkk_T$?$M;{{>k!Hj$aTOqqq%{#Y^uBm{- zz>j$AR%3=3dBYxZ`P@8)*5f+QN%8LLxw`OG8X*Do=yjC>i}hhA*i~VG=}? zPHppPdPxSFK5=Hg=GDNig}cs<#p3j9 z5v`rIb&)p<@1R|k&Kq3+C1a%9h?G)kcF5jK9lUfcvu#kI4Q0 zdzyZ_k^2`!(hx>XnC(>^{qw&uw2@BI0D*+rbP}Iqp43N7ethKExHXltY3|Xd}j|8{u_dt;B^}K zCKgc!59yb-z4B$;fRIfkHI~8sg9Ds&k!P>(toJH9JaJd3;2I?1YVa8wKvMAI6SF6> zn6m-)bJCWxqZU-Wt3zY8Nj5r{jhfUD6LP-swJEm z?i=c7b8{fuIs;^XlVvfP_ov_;^8d$`_H>1uH2;`~r*W;bZ^t43{~(t*;|lN)1u!^h zj~AOtbP|2g#1i`@EZb-#8624Ftx6?#JXD*0k;VtTU3uE{|v@*MuTh9C_TpcX-e zK~@}a!E@s3g2MUbr}T5R;<*p*McskaWo_#lhk0Cn7y^sN7aiQcm_&I0i*|lo{kD`a zdEb4i@_*6-qW-syS_bk%aDqRO5FV<_JUMMafnczQ>=}hh=r=HVPaRA9Uq$*u_7lIP z4#$>Vm%8`jm;oXE`s@!ym5+ox{1{b9!MVJ_tGzIjBiYyf$=%Dz^NP^QX~sjjqRX~v zJMAu~_N*_gP6uuyEGH}%v~;Rc@tzKmaCG8ub-<}dS&N=8K3%8xQ@UT}a2n(a#f*+J zK?psJOzbi%{*_*RB;O;?XWlIXzXd>>ztat)4X;Obnq7S$q=6V04%73VCJ?;Zz?3%K zd4|p?Z##Phfy+hetHQ^3)8UUZQ7vV;+35|GTPx+C)iR`89p|!h!uW$y0?JyS-}a!c zpz)Kli<-dq5#?*|J@*JMyWfotTwc9{dP~K313{|7|D_IW`|WmsMEK`^HBv1lXEJ=D z3>arjubtA-QwrI0@a_~Fp9NC62W^+Lg7kdMB&v7r_-`J1El}QHE>eVdZM3Cq$!pwa z9Zel=w?;9*jlQdF+4TlKMiF{X%tbxW`KL(#b?-7+p(7GyYvH%UB%!SEJxf?4aWBhu zw19zuZZ|SNkU=Zq07jVDVSefiSq7=)v@7La!%hK^CnnVA7!cyUNS@@cm~+lza-H5v z9f@hQD0JRydtz(E4T=RD^OnvSdO^n|b*sb|4D*;u)zYAbHP7Et`szTk^}XnU=dou+ zV#e7Yb4Z`rxD`g)?W_vD3i8G#2xz(W3n~x9^~_Oa&f?_0xNotaNi&7|qnbr+j*CNR z=wHKwtn-tFskL#AD>ji8)<&#MDHQR%0MpfjA~uvVkh!x3`XPK)qjj#ZmI*f2sRL+;l(+UTnZXskzPjE!cI}N9hO$IjGVvSkynT|k@M3+`|;b?hKhLcxde$Mq^U^+ z+qd`lDdzzpW`~e_R2#0~XTFHbO`kpVn)8|G>N#mCu3)J^VG^~;%M~`En4j3+K0*}1 z`}YQ(!i>QhR3^v0Z)Ii>KhzWoX2>6#D)8Ti7R+qvzqaGg3{Wf(kPwkN=a3onnSZd9 zg2OG8Lizhth^=90T7n{O>Zc}9wIY@Mii&=0$SUMnB(#!Ow?z${)iUTQBdwptf{aK6 z<#3J|btp*x6&m<2Eb)1@tM1sc0rY z7&RF?t^Ncamv%iIOj}vy%0DgD4uDM%l-Welh-yIGqJErzfr>iUye750dUo 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 rKExFb{B! zlW%Lt!nyW#AKO6?WG@X42nBbl>7v+xU)SdYD7aN8hDDH}XgsXdX`+Z293~UAIE)*K zCWzEJ!sSBwa?ij#x|&GM&6^I@e}5yeLnZmwEx^V`}F=)``Ihg`&_ETqi0Eo?s=XPS*uxi=SC)2prF`Y@{6oj_4bQ9_8raP@cf|b*-+Ls(qTJP8 z1=~3sjdr-+x@B3?@937~zJ^;3GSHm{tC0m9BFVmk17B?qprRDamzPxa}n63g_k4 zzE3SL-@PQg891+RWoY#H_DivInw!=(R#RoB*^^SJTM`(+1ZrggT3_jchGvYOTm7c`ZVb-kC-r8y35`Zj42 zJ-F|x;qC)L-Lw?zf+_qHoe6Es;}MVK-)@V%8?sfI>YjFF@rAGTk@wEmL>|2p*;~+; z{N<)oS@*=(7f&tSJT;W+wm;MENGY`_+`T4X*Nb+S{_(YiwA=;9>?VsGLz3*i>rNWD z^hABVt!GERL#ky3P2U<;LQ7nJRP=O?47cHi3_D^l;s+==JER7-caPD)vs)XLaQtDcT{wB zclCEQ_e*YdJ+Un~t2?7D3uS_~iz7gLMaUM26&e*C#WZr9Zd7SO-$9Vq9HSOhtiefG zjw=bZg!bfIB@HGp3GFkUj49Ll7L^L11F@BVR5T z3E4Ok;b9nxa5-`gBI2Paf<>`WJ|@R`3a(%TlvJ%JQMCd$K>=_&0dP1ti^oyOF@(j$ zIS7}}6(VwhP=pBiA{LHuxE!urJ_2HqjsRVW#*B>01cd=8p%CMu7)yZ&Fdh%#ibN

    N#l9g@35`u>zLkW;pkx#< z05d?SF-^Sw?NS(_!k3V!iBFb*#T4>*e6~oy6>)fjuFQx_ah)FYq6wA7q;t4tb5mi& zARRz0YU)$~V3vby#Qr)QB{jM*jV4AyGeN*6%i(1i7$^)S(Eyah0VtEr6*D;`3E>jFC=V|XhZ;tRz3Pkx5#@K3sc;SWyUi{B4)eW2^T z7Z#y_7$6*Z++!ySIlaTn+vK#e<`g=$g+}aLlri&z~Cr4Vb=rD-LA? z$w%7YNIe9No@lx(pk2Es1EDP`l?B>9w47+~;cUI2wGM(tHA@40!-Uri**E4pDV?qq z<|Qa|@|w1uI?FkCY5J*xpZeGb2nWBgG{oP;IYlR8=iuR6y(0c`5lj@ zO}9|^Y=!;cy)`wd54$es?YXY;2t! z+PU4id(Euu)rnb|b2>$@T6y0-jcjp!eMBd_cgA*Qz{wU@Mn#1#E5~wUXJ_ZVLe1-E zE3S>}jeq&#LGFOArSbe9?LO0}RsyJadiA1Y@onMrx{{*qlmTlh6n%2pOA;AK`YERE zwc2`8$rk}7w0r*9Zt3jQ$97{KJa0`aI|sSMMU<+}{hr|Bb)&lBL`G4K^3UIHY@q(U zA}qsZY_qDhp>Zws&Sc}Wo+lhKla*Icr zkEeBQ-_5Z;-i0mvF_u|V|6NituD!jb{aW+v;>1sWK9o9f%GCY)PM@}&of-5gdsVtB zGRL~!z~b?&TVCGmDR94k&Er>mw`A?d^|mSZ_%UHKZ$BSBdi1=*Vb8v@(ChWzs<$Z zsaBU`$JECD7{hm?j5=|*_=}SIKQd|EUX_8K$#^8Cnwo?A=HR5k;Ff=VQ%Az(*z|SY zh0-jn)RJ1;9Y?j&I@vnaei@p!f4{ph({i4tM^WlN%C3WMlue(Mm6bKd+CZ(n{c%pU z(cF)pdW~ypYTCPlHm17#_UgRM_MIsyDQold^Gh5jO)AXD$moW$6dQ?Mu4y$i!wNy! zg$s2aMW38fm9VZf7au#e^w*9Kd&qGk79E{>d-cg4<7kM9RXnsfOaj1u!H>4FCWD literal 0 HcmV?d00001 diff --git a/src/fractalzoomer/main/CommonFunctions.java b/src/fractalzoomer/main/CommonFunctions.java index c0dd40992..dfa623f3c 100644 --- a/src/fractalzoomer/main/CommonFunctions.java +++ b/src/fractalzoomer/main/CommonFunctions.java @@ -22,14 +22,14 @@ import fractalzoomer.functions.root_finding_methods.durand_kerner.DurandKernerRootFindingMethod; import fractalzoomer.functions.root_finding_methods.newton_hines.NewtonHinesRootFindingMethod; import fractalzoomer.gui.*; -import fractalzoomer.main.app_settings.GradientSettings; -import fractalzoomer.main.app_settings.Settings; +import fractalzoomer.main.app_settings.*; import fractalzoomer.palettes.CustomPalette; import fractalzoomer.palettes.PresetPalette; import fractalzoomer.parser.Parser; import fractalzoomer.parser.ParserException; import fractalzoomer.utils.ColorSpaceConverter; import fractalzoomer.utils.MathUtils; +import org.apfloat.Apfloat; import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; @@ -2121,7 +2121,7 @@ public static BufferedImage getOutColoringPalettePreview(Settings s, int color_c boolean isSmooth = false; Color[] c = null; if (s.ds.domain_coloring && s.ds.domain_coloring_mode == 0) { - c = new Color[width]; + c = new Color[DomainColoring.getDomainColoringPaletteLength(s.ds.domain_coloring_mode)]; for (int i = 0; i < c.length; i++) { double h = ((double) i) / (c.length - 1); @@ -2129,7 +2129,7 @@ public static BufferedImage getOutColoringPalettePreview(Settings s, int color_c } isSmooth = true; } else if (s.ds.domain_coloring && s.ds.domain_coloring_mode == 2) { - c = new Color[width]; + c = new Color[DomainColoring.getDomainColoringPaletteLength(s.ds.domain_coloring_mode)]; for (int i = 0; i < c.length; i++) { double h = ((double) i) / (c.length - 1); @@ -2138,7 +2138,7 @@ public static BufferedImage getOutColoringPalettePreview(Settings s, int color_c isSmooth = true; } else if (s.ds.domain_coloring && s.ds.domain_coloring_mode == 5) { - c = new Color[width]; + c = new Color[DomainColoring.getDomainColoringPaletteLength(s.ds.domain_coloring_mode)]; for (int i = 0; i < c.length; i++) { double h = ((double) i) / (c.length - 1); @@ -2147,7 +2147,7 @@ else if (s.ds.domain_coloring && s.ds.domain_coloring_mode == 5) { isSmooth = true; } else if (s.ds.domain_coloring && s.ds.domain_coloring_mode == 3) { - c = new Color[width]; + c = new Color[DomainColoring.getDomainColoringPaletteLength(s.ds.domain_coloring_mode)]; for (int i = 0; i < c.length; i++) { double h = ((double) i) / (c.length - 1); @@ -2155,7 +2155,7 @@ else if (s.ds.domain_coloring && s.ds.domain_coloring_mode == 3) { } isSmooth = true; } else if (s.ds.domain_coloring && s.ds.domain_coloring_mode == 4) { - c = new Color[width]; + c = new Color[DomainColoring.getDomainColoringPaletteLength(s.ds.domain_coloring_mode)]; for (int i = 0; i < c.length; i++) { double h = ((double) i) / (c.length - 1); @@ -2190,6 +2190,110 @@ else if (s.ds.domain_coloring && s.ds.domain_coloring_mode == 3) { return palette_preview; } + public static int getOutPaletteLength(boolean domain_coloring, int domain_coloring_mode) { + + if(!domain_coloring || domain_coloring_mode == 1) { + return TaskDraw.palette_outcoloring.getPaletteLength(); + } + + return DomainColoring.getDomainColoringPaletteLength(domain_coloring_mode); + } + + public static void adjustBumpOffset(BumpMapSettings bms, double adjust) { + bms.lightDirectionDegrees += adjust; + if (adjust > 0) { + bms.lightDirectionDegrees = bms.lightDirectionDegrees % 360.0; + } + else { + if (bms.lightDirectionDegrees <= -360) { + bms.lightDirectionDegrees += 360; + } + } + } + public static void adjustSlopeOffset(SlopeSettings ss, double adjustment) { + ss.SlopeAngle += adjustment; + + if(adjustment> 0) { + ss.SlopeAngle = ss.SlopeAngle % 360.0; + } + else { + if (ss.SlopeAngle < 0) { + ss.SlopeAngle += 360; + } + } + + double lightAngleRadians = Math.toRadians(ss.SlopeAngle); + ss.lightVector[0] = Math.cos(lightAngleRadians); + ss.lightVector[1] = Math.sin(lightAngleRadians); + } + + public static void adjustLightOffset(LightSettings ls, double adjustment) { + ls.light_direction += adjustment; + + if(adjustment > 0) { + ls.light_direction = ls.light_direction % 360.0; + } + else { + if (ls.light_direction < 0) { + ls.light_direction += 360; + } + } + + double lightAngleRadians = Math.toRadians(ls.light_direction); + ls.lightVector[0] = Math.cos(lightAngleRadians) * ls.light_magnitude; + ls.lightVector[1] = Math.sin(lightAngleRadians) * ls.light_magnitude; + } + + public static void adjustRotationOffset(Settings s, double adjustment) { + s.fns.rotation += adjustment; + if (adjustment > 0) { + s.fns.rotation = s.fns.rotation % 360.0; + } else if (adjustment < 0) { + if (s.fns.rotation <= -360) { + s.fns.rotation += 360; + } + } + + Apfloat tempRadians = MyApfloat.fp.toRadians(new MyApfloat(s.fns.rotation)); + s.fns.rotation_vals[0] = MyApfloat.cos(tempRadians); + s.fns.rotation_vals[1] = MyApfloat.sin(tempRadians); + } + + public static int adjustPaletteOffset(int originalValue, int adjustment, int length) { + if(length <= 0) { + return originalValue; + } + + long newValue = (long)originalValue + adjustment; + + if(newValue > Integer.MAX_VALUE) { + return (int)newValue % length; + } + else if(newValue < 0) { + while (newValue < 0) { + newValue += length; + } + int targetValue = (int)newValue % length; + int currentValue = Integer.MAX_VALUE; + while (currentValue % length != targetValue) { + currentValue--; + } + return currentValue; + } + else { + return (int)newValue; + } + } + + public static int getInPaletteLength(boolean domain_coloring) { + + if(!domain_coloring) { + return TaskDraw.palette_incoloring.getPaletteLength(); + } + + return -1; + } + public static BufferedImage getInColoringPalettePreview(Settings s, int color_cycling_location, int width, int height) { Color[] c = null; diff --git a/src/fractalzoomer/main/Constants.java b/src/fractalzoomer/main/Constants.java index ad6c2eaf4..ff8c15166 100644 --- a/src/fractalzoomer/main/Constants.java +++ b/src/fractalzoomer/main/Constants.java @@ -25,7 +25,7 @@ * @author hrkalona2 */ public interface Constants { - public static final int VERSION = 1089; + public static final int VERSION = 1090; public static final boolean beta = false; public static final int TOTAL_PALETTES = 45; public static final int TOTAL_INCOLORING_ALGORITHMS = 11; @@ -33,7 +33,7 @@ public interface Constants { public static final int TOTAL_BAILOUT_CONDITIONS = 13; public static final int TOTAL_CONVERGENT_BAILOUT_CONDITIONS = 6; public static final int TOTAL_PLANES = 66; - public static final int TOTAL_FUNCTIONS = 513; + public static final int TOTAL_FUNCTIONS = 514; public static final int TOTAL_FILTERS = 35; public static final int TOTAL_COLOR_TRANSFER_FILTERS = 8; public static final int TOTAL_COLOR_BLENDING = 30; @@ -663,6 +663,7 @@ public interface Constants { public static final int PERPENDICULAR_CELTIC_MANDELBROT = 511; public static final int PERPENDICULAR_BUFFALO_MANDELBROT = 512; + public static final int FORMULA48 = 513; /** * *************** */ @@ -1370,12 +1371,14 @@ public interface Constants { public static final String FZL4j = "# Launch4j runtime config\n" + "# This file must be named as the executable. If the executable is AAA.exe, then this file must be named AAA.l4j.ini\n" + "# Configure the JVM Heap size.\n" + - "-Xmx2200m"; + "-Xmx2200m\n" + + "-XX:+UseG1GC"; public static final String IEL4j = "# Launch4j runtime config\n" + "# This file must be named as the executable. If the executable is AAA.exe, then this file must be named AAA.l4j.ini\n" + "# Configure the JVM Heap size.\n" + - "-Xmx4000m"; + "-Xmx4000m\n" + + "-XX:+UseG1GC"; public static final long MAX_PROGRESS_VALUE = Integer.MAX_VALUE; diff --git a/src/fractalzoomer/main/ImageExpanderWindow.java b/src/fractalzoomer/main/ImageExpanderWindow.java index 89878163e..c3de8f19b 100644 --- a/src/fractalzoomer/main/ImageExpanderWindow.java +++ b/src/fractalzoomer/main/ImageExpanderWindow.java @@ -16,6 +16,7 @@ */ package fractalzoomer.main; +import com.fasterxml.jackson.databind.ObjectMapper; import com.sun.jna.Platform; import fractalzoomer.core.*; import fractalzoomer.core.drawing_algorithms.*; @@ -23,11 +24,9 @@ import fractalzoomer.core.la.impl.LAInfoDeep; import fractalzoomer.core.la.LAReference; import fractalzoomer.core.location.Location; +import fractalzoomer.functions.Fractal; import fractalzoomer.gui.*; -import fractalzoomer.main.app_settings.BumpMapSettings; -import fractalzoomer.main.app_settings.LightSettings; -import fractalzoomer.main.app_settings.Settings; -import fractalzoomer.main.app_settings.SlopeSettings; +import fractalzoomer.main.app_settings.*; import fractalzoomer.parser.ParserException; import fractalzoomer.utils.*; import org.apfloat.Apfloat; @@ -62,6 +61,7 @@ public class ImageExpanderWindow extends JFrame implements Constants { private ArrayList> futures = new ArrayList<>(); private Settings s; + private ZoomSequenceSettings zss; private int n; private int m; @@ -105,7 +105,8 @@ public class ImageExpanderWindow extends JFrame implements Constants { private CommonFunctions common; private boolean runsOnBatchingMode; private boolean runsOnSequenceMode; - private boolean flipSequenceIndexing; + + private double aspectRatio; private boolean runsOnLargePolarImageMode; @@ -113,24 +114,9 @@ public class ImageExpanderWindow extends JFrame implements Constants { private int batchIndex; private long sequenceIndex; - private long startAtSequenceIndex; - private long numberOfSequenceSteps; - private String outputDirectory = "."; - - private double zoom_factor = 2.0; - private int zooming_mode = 0; - private double rotation_adjusting_value = 0; - private int color_cycling_adjusting_value = 0; - - private int gradient_color_cycling_adjusting_value = 0; - - private double light_light_direction_adjusting_value = 0; - private double slopes_light_direction_adjusting_value = 0; - private double bump_light_direction_adjusting_value = 0; - - private int zoom_every_n_frame = 1; + public static String outputDirectory = "."; private int number_of_polar_images = 5; private int polar_orientation = 0; @@ -140,10 +126,10 @@ public class ImageExpanderWindow extends JFrame implements Constants { private int gridI; private int gridJ; - private Apfloat size = Constants.DEFAULT_MAGNIFICATION; - private String settingsName; + private static boolean USE_LESS_INITIAL_ITERATIONS_ON_SEQUENCE_RENDER = true; + public ImageExpanderWindow() { super(); @@ -153,8 +139,11 @@ public ImageExpanderWindow() { ptr = this; + aspectRatio = 1; + s = new Settings(); s.applyStaticSettings(); + zss = new ZoomSequenceSettings(); TaskDraw.ALWAYS_SAVE_EXTRA_PIXEL_DATA_ON_AA = false; @@ -168,6 +157,7 @@ public ImageExpanderWindow() { TaskDraw.thread_calculation_executor = (ThreadPoolExecutor)Executors.newFixedThreadPool(m * n); TaskDraw.single_thread_executor = Executors.newSingleThreadExecutor(); + TaskDraw.la_thread_executor = (ThreadPoolExecutor)Executors.newFixedThreadPool(procs); thread_grouping = 3; @@ -176,9 +166,9 @@ public ImageExpanderWindow() { Locale.setDefault(Locale.US); image_size = 1000; - setSize(540, 550); + setSize(565, 565); setTitle("Fractal Zoomer Image Expander"); - + loadPreferences(); if(Platform.isWindows()) { @@ -515,7 +505,7 @@ public void batchRender() { } public void sequenceRender() { - new SequenceRenderDialog(ptr, s, zoom_factor, zooming_mode, size, rotation_adjusting_value, color_cycling_adjusting_value, light_light_direction_adjusting_value, bump_light_direction_adjusting_value, zoom_every_n_frame, gradient_color_cycling_adjusting_value, flipSequenceIndexing, startAtSequenceIndex, slopes_light_direction_adjusting_value); + new SequenceRenderDialog(ptr, s, zss); } public void loadSettings() { @@ -664,24 +654,51 @@ else if(thread_grouping == 3 || thread_grouping == 4 || thread_grouping == 5) { } } else if(TaskDraw.GREEDY_ALGORITHM_SELECTION == DIVIDE_AND_CONQUER) { - if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { - tasks[i][j] = new MarianiSilverColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); - } else { - tasks[i][j] = new MarianiSilverDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + if (TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new MarianiSilver3ColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } else { + tasks[i][j] = new MarianiSilver3Draw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } + } + else { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new MarianiSilverColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } else { + tasks[i][j] = new MarianiSilverDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } } } else if(TaskDraw.GREEDY_ALGORITHM_SELECTION == SUCCESSIVE_REFINEMENT) { - if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { - tasks[i][j] = new SuccessiveRefinementGuessingColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); - } else { - tasks[i][j] = new SuccessiveRefinementGuessingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new SuccessiveRefinementGuessing2ColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } else { + tasks[i][j] = new SuccessiveRefinementGuessing2Draw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } + } + else { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new SuccessiveRefinementGuessingColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } else { + tasks[i][j] = new SuccessiveRefinementGuessingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } } } else if(TaskDraw.GREEDY_ALGORITHM_SELECTION == CIRCULAR_SUCCESSIVE_REFINEMENT) { - if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { - tasks[i][j] = new CircularSuccessiveRefinementGuessingColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); - } else { - tasks[i][j] = new CircularSuccessiveRefinementGuessingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new CircularSuccessiveRefinementGuessing2ColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } else { + tasks[i][j] = new CircularSuccessiveRefinementGuessing2Draw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } + } + else { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new CircularSuccessiveRefinementGuessingColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } else { + tasks[i][j] = new CircularSuccessiveRefinementGuessingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } } } } @@ -692,9 +709,12 @@ else if(TaskDraw.GREEDY_ALGORITHM_SELECTION == CIRCULAR_SUCCESSIVE_REFINEMENT) { else if (TaskDraw.BRUTE_FORCE_ALG == 1) { tasks[i][j] = new BruteForce2Draw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); } - else { + else if (TaskDraw.BRUTE_FORCE_ALG == 2) { tasks[i][j] = new CircularBruteForceDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); } + else { + tasks[i][j] = new BruteForceInterleavedDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } } } else { @@ -707,24 +727,51 @@ else if (TaskDraw.BRUTE_FORCE_ALG == 1) { } } else if(TaskDraw.GREEDY_ALGORITHM_SELECTION == DIVIDE_AND_CONQUER) { - if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { - tasks[i][j] = new MarianiSilverColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); - } else { - tasks[i][j] = new MarianiSilverDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + if (TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new MarianiSilver3ColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } else { + tasks[i][j] = new MarianiSilver3Draw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } + } + else { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new MarianiSilverColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } else { + tasks[i][j] = new MarianiSilverDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } } } else if(TaskDraw.GREEDY_ALGORITHM_SELECTION == SUCCESSIVE_REFINEMENT) { - if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { - tasks[i][j] = new SuccessiveRefinementGuessingColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); - } else { - tasks[i][j] = new SuccessiveRefinementGuessingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new SuccessiveRefinementGuessing2ColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } else { + tasks[i][j] = new SuccessiveRefinementGuessing2Draw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } + } + else { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new SuccessiveRefinementGuessingColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } else { + tasks[i][j] = new SuccessiveRefinementGuessingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } } } else if(TaskDraw.GREEDY_ALGORITHM_SELECTION == CIRCULAR_SUCCESSIVE_REFINEMENT) { - if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { - tasks[i][j] = new CircularSuccessiveRefinementGuessingColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); - } else { - tasks[i][j] = new CircularSuccessiveRefinementGuessingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new CircularSuccessiveRefinementGuessing2ColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } else { + tasks[i][j] = new CircularSuccessiveRefinementGuessing2Draw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } + } + else { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new CircularSuccessiveRefinementGuessingColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } else { + tasks[i][j] = new CircularSuccessiveRefinementGuessingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } } } } @@ -735,9 +782,12 @@ else if(TaskDraw.GREEDY_ALGORITHM_SELECTION == CIRCULAR_SUCCESSIVE_REFINEMENT) { else if (TaskDraw.BRUTE_FORCE_ALG == 1) { tasks[i][j] = new BruteForce2Draw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); } - else { + else if (TaskDraw.BRUTE_FORCE_ALG == 2) { tasks[i][j] = new CircularBruteForceDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); } + else { + tasks[i][j] = new BruteForceInterleavedDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, image, s.fs, periodicity_checking, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } } } tasks[i][j].setTaskId(i * tasks.length + j); @@ -748,7 +798,12 @@ else if (TaskDraw.BRUTE_FORCE_ALG == 1) { if(tasks[0][0].hasCircularLogic()) { CircularBruteForceDraw.initCoordinates(image_size, false, true, tasks[0][0].usesSuccessiveRefinement()); if(tasks[0][0].usesSuccessiveRefinement()) { - CircularSuccessiveRefinementGuessingDraw.initCoordinates(image_size, false); + if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + CircularSuccessiveRefinementGuessing2Draw.initCoordinates(image_size, false); + } + else { + CircularSuccessiveRefinementGuessingDraw.initCoordinates(image_size, false); + } } } else { @@ -830,6 +885,8 @@ public void writeImageToDisk() { return; } + boolean runsOnSimpleMode = false; + try { String name; if (runsOnSequenceMode) { @@ -853,6 +910,7 @@ else if(runsOnSplitImageMode) { } } else { + runsOnSimpleMode = true; Path path = Paths.get(outputDirectory); if (Files.exists(path) && Files.isDirectory(path)) { name = path.resolve(settingsName + ".png").toString(); @@ -868,16 +926,51 @@ else if(runsOnSplitImageMode) { } } - File file = new File(name); - ImageIO.write(image, "png", file); + + double aspect_ratio = 1; + if(runsOnSequenceMode) { + aspect_ratio = zss.aspect_ratio; + } + else if(runsOnSimpleMode) { + aspect_ratio = aspectRatio; + } + writeImage(image, name, aspect_ratio); } catch(IOException ex) { } + if(!runsOnBatchingMode && !runsOnSequenceMode && !runsOnSplitImageMode) { cleanUp(); } } + private void writeImage(BufferedImage image, String name, double aspect_ratio) throws IOException { + if(aspect_ratio == 1) { + File file = new File(name); + ImageIO.write(image, "png", file); + } + else if(aspect_ratio > 1) { + int width = image.getWidth(); + + int height = (int)(width / aspect_ratio + 0.5); + + BufferedImage subImage = image.getSubimage(0, (image.getHeight() - height) / 2, width, height); + + File file = new File(name); + ImageIO.write(subImage, "png", file); + } + else { + int height = image.getHeight(); + + int width = (int)(height * aspect_ratio + 0.5); + + BufferedImage subImage = image.getSubimage((image.getWidth() - width) / 2, 0, width, height); + + File file = new File(name); + ImageIO.write(subImage, "png", file); + } + } + public void setThreadsNumberPost(int grouping, int val, int val2) { if(grouping == 3 || grouping == 4) { ArrayList factors = CommonFunctions.getAllFactors(val); @@ -899,7 +992,7 @@ else if (grouping == 5) { TaskDraw.thread_calculation_executor.shutdown(); TaskDraw.thread_calculation_executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(getNumberOfThreads()); } - + public void setThreadsNumber() { new ThreadsDialog(ptr, n, m, thread_grouping); @@ -927,7 +1020,7 @@ private void overview() { } } - + public void setSizeOfImagePost(int image_size) { this.image_size = image_size; } @@ -1003,7 +1096,7 @@ private void displayHelp() { + "If you are using the *.exe version of the application please edit
    " + "FZImageExpander.l4j.ini and add -Xmx4000m or any other memory size
    " + "value into the *.ini file. The *.ini file name must match the name of the executable.

    " - + + "If you do not set the maximum heap, the JVM's default will be used,
    " + "which scales based on your memory."; @@ -1022,14 +1115,14 @@ public CommonFunctions getCommonFunctions() { return common; } - + public void savePreferences() { PrintWriter writer; try { - writer = new PrintWriter(new File("IEpreferences.ini")); + writer = new PrintWriter("IEpreferences.ini"); - writer.println("#Fractal Zoomer Image Expander preferences."); + writer.println("#Fractal Zoomer Image Expander " + VERSION + " preferences."); writer.println("#This file contains all the preferences of the user and it is updated,"); writer.println("#every time the application terminates. Settings that wont have the"); writer.println("#correct name/number of arguments/argument value, will be ignored"); @@ -1042,6 +1135,7 @@ public void savePreferences() { writer.println("save_settings_path \"" + MainWindow.SaveSettingsPath + "\""); writer.println("output_directory \"" + outputDirectory + "\""); writer.println("use_smoothing_for_processing_algs " + TaskDraw.USE_SMOOTHING_FOR_PROCESSING_ALGS); + writer.println("aspect_ratio " + aspectRatio); writer.println(); @@ -1057,6 +1151,9 @@ public void savePreferences() { writer.println("skipped_pixels_coloring " + TaskDraw.SKIPPED_PIXELS_ALG); writer.println("mariani_silver_use_dfs " + MarianiSilverDraw.RENDER_USING_DFS); writer.println("guess_blocks_selection " + TaskDraw.GUESS_BLOCKS_SELECTION); + writer.println("greedy_successive_refinement_squares_and_rectangles_algorithm " + TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM); + writer.println("two_pass_successive_refinement " + TaskDraw.TWO_PASS_SUCCESSIVE_REFINEMENT); + writer.println("square_rect_chunk_aggregation " + TaskDraw.SQUARE_RECT_CHUNK_AGGERAGATION); int color = TaskDraw.SKIPPED_PIXELS_COLOR; writer.println("skipped_pixels_user_color " + ((color >> 16) & 0xff) + " " + ((color >> 8) & 0xff) + " " + (color & 0xff)); writer.println("perturbation_theory " + TaskDraw.PERTURBATION_THEORY); @@ -1070,12 +1167,14 @@ public void savePreferences() { writer.println("automatic_bignum_precision " + TaskDraw.BIGNUM_AUTOMATIC_PRECISION); writer.println("bignum_precision_bits " + TaskDraw.BIGNUM_PRECISION); writer.println("bignum_precision_factor " + TaskDraw.BIGNUM_PRECISION_FACTOR); + writer.println("bignum_initialization_algorithm " + TaskDraw.BIGNUM_INITIALIZATION_ALGORITHM); writer.println("use_threads_for_sa " + TaskDraw.USE_THREADS_FOR_SA); writer.println("bla_precision_bits " + TaskDraw.BLA_BITS); writer.println("use_threads_for_bla " + TaskDraw.USE_THREADS_FOR_BLA); writer.println("bla_starting_level " + TaskDraw.BLA_STARTING_LEVEL); writer.println("detect_period " + TaskDraw.DETECT_PERIOD); writer.println("brute_force_alg " + TaskDraw.BRUTE_FORCE_ALG); + writer.println("one_chunk_per_row " + TaskDraw.CHUNK_SIZE_PER_ROW); writer.println("exponent_diff_ignored " + MantExp.EXPONENT_DIFF_IGNORED); writer.println("bignum_library " + TaskDraw.BIGNUM_LIBRARY); writer.println("automatic_precision " + MyApfloat.setAutomaticPrecision); @@ -1086,6 +1185,7 @@ public void savePreferences() { writer.println("check_bailout_during_deep_not_full_floatexp_mode " + TaskDraw.CHECK_BAILOUT_DURING_DEEP_NOT_FULL_FLOATEXP_MODE); writer.println("gather_tiny_ref_indexes " + TaskDraw.GATHER_TINY_REF_INDEXES); writer.println("bignum_sqrt_max_iterations " + BigNum.SQRT_MAX_ITERATIONS); + writer.println("built_in_bignum_implementation " + TaskDraw.BUILT_IT_BIGNUM_IMPLEMENTATION); writer.println("stop_reference_calculation_after_detected_period " + TaskDraw.STOP_REFERENCE_CALCULATION_AFTER_DETECTED_PERIOD); writer.println("use_custom_floatexp_requirement " + TaskDraw.USE_CUSTOM_FLOATEXP_REQUIREMENT); writer.println("load_mpfr " + TaskDraw.LOAD_MPFR); @@ -1108,14 +1208,21 @@ public void savePreferences() { writer.println("bla2_la_threshold_c_scale " + LAInfo.LAThresholdCScale); writer.println("bla2_double_threshold_limit " + LAReference.doubleThresholdLimit.toDouble()); writer.println("bla2_convert_to_double_when_possible " + LAReference.CONVERT_TO_DOUBLE_WHEN_POSSIBLE); + writer.println("bla2_period_divisor " + LAReference.periodDivisor); + writer.println("use_threads_for_bla2 " + TaskDraw.USE_THREADS_FOR_BLA2); + writer.println("use_ref_index_on_bla2 " + TaskDraw.USE_RI_ON_BLA2); + writer.println("disable_ref_index_on_bla2 " + TaskDraw.DISABLE_RI_ON_BLA2); writer.println("always_check_for_precision_decrease " + MyApfloat.alwaysCheckForDecrease); writer.println("use_threads_in_bignum_libs " + TaskDraw.USE_THREADS_IN_BIGNUM_LIBS); writer.println("calculate_period_every_time_from_start " + TaskDraw.CALCULATE_PERIOD_EVERY_TIME_FROM_START); writer.println("mantexpcomplex_format " + TaskDraw.MANTEXPCOMPLEX_FORMAT); writer.println("use_fast_delta_location " + TaskDraw.USE_FAST_DELTA_LOCATION); + writer.println("always_save_extra_pixel_data_on_aa_with_pp " + TaskDraw.ALWAYS_SAVE_EXTRA_PIXEL_DATA_ON_AA_WITH_PP); + writer.println("reference_compression " + TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE); + writer.println("reference_compression_error " + ReferenceCompressor.CompressionError); writer.println(); - + writer.println("[Window]"); writer.println("image_size " + image_size); writer.println("window_location " + (int) getLocation().getX() + " " + (int) getLocation().getY()); @@ -1126,6 +1233,11 @@ public void savePreferences() { writer.println("aa_jitter_size " + Location.AA_JITTER_SIZE); writer.println("aa_number_of_jitter_kernels " + Location.NUMBER_OF_AA_JITTER_KERNELS); writer.println("whitepoint " + ColorSpaceConverter.whitePointId); + writer.println("include_aa_data_on_rank_order " + TaskDraw.INCLUDE_AA_DATA_ON_RANK_ORDER); + + writer.println(); + writer.println("[Sequence Render]"); + writer.println("use_less_initial_iterations " + USE_LESS_INITIAL_ITERATIONS_ON_SEQUENCE_RENDER); writer.close(); } @@ -1193,6 +1305,34 @@ else if(token.equals("true")) { TaskDraw.USE_THREADS_IN_BIGNUM_LIBS = true; } } + else if(token.equals("bignum_initialization_algorithm") && tokenizer.countTokens() == 1) { + + token = tokenizer.nextToken(); + + try { + int val = Integer.parseInt(token); + if(val >= 0 && val <= 2) { + TaskDraw.BIGNUM_INITIALIZATION_ALGORITHM = val; + } + } + catch (Exception ex) { + + } + } + else if(token.equals("built_in_bignum_implementation") && tokenizer.countTokens() == 1) { + + token = tokenizer.nextToken(); + + try { + int val = Integer.parseInt(token); + if(val >= 0 && val <= 4) { + TaskDraw.BUILT_IT_BIGNUM_IMPLEMENTATION = val; + } + } + catch (Exception ex) { + + } + } else if(token.equals("mpir_lib") && tokenizer.countTokens() == 1) { token = tokenizer.nextToken(); @@ -1211,6 +1351,17 @@ else if (token.equals("thread_grouping") && tokenizer.countTokens() == 1) { } catch (Exception ex) { } } + else if (token.equals("greedy_successive_refinement_squares_and_rectangles_algorithm") && tokenizer.countTokens() == 1) { + try { + int temp = Integer.parseInt(tokenizer.nextToken()); + + if (temp >= 0 && temp <= 4) { + TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM = temp; + TaskDraw.setSuccessiveRefinementChunks(); + } + } catch (Exception ex) { + } + } else { continue; } @@ -1224,7 +1375,7 @@ else if (token.equals("thread_grouping") && tokenizer.countTokens() == 1) { } } - + private void loadPreferences() { BufferedReader br; @@ -1267,6 +1418,16 @@ else if (token.equals("mantexpcomplex_format") && tokenizer.countTokens() == 1) } catch (Exception ex) { } } + else if (token.equals("aspect_ratio") && tokenizer.countTokens() == 1) { + try { + double temp = Integer.parseInt(tokenizer.nextToken()); + + if (temp > 0) { + aspectRatio = temp; + } + } catch (Exception ex) { + } + } else if (token.equals("window_location") && tokenizer.countTokens() == 2) { try { int x = Integer.parseInt(tokenizer.nextToken()); @@ -1314,7 +1475,7 @@ else if (token.equals("circular_compare_alg") && tokenizer.countTokens() == 1) { try { int temp = Integer.parseInt(tokenizer.nextToken()); - if (temp >= 0 && temp <= 15) { + if (temp >= 0 && temp <= 16) { TaskDraw.CIRCULAR_COMPARE_ALG = temp; } } catch (Exception ex) { @@ -1342,6 +1503,17 @@ else if (token.equals("circular_repeat_spacing") && tokenizer.countTokens() == 1 } catch (Exception ex) { } } + else if (token.equals("bla2_period_divisor") && tokenizer.countTokens() == 1) { + + try { + double temp = Double.parseDouble(tokenizer.nextToken()); + + if (temp > 0) { + LAReference.periodDivisor = temp; + } + } catch (Exception ex) { + } + } else if (token.equals("period_detection_algorithm") && tokenizer.countTokens() == 1) { try { @@ -1374,6 +1546,126 @@ else if(token.equals("true")) { TaskDraw.STOP_REFERENCE_CALCULATION_AFTER_DETECTED_PERIOD = true; } } + else if(token.equals("include_aa_data_on_rank_order") && tokenizer.countTokens() == 1) { + + token = tokenizer.nextToken(); + + if(token.equals("false")) { + TaskDraw.INCLUDE_AA_DATA_ON_RANK_ORDER = false; + } + else if(token.equals("true")) { + TaskDraw.INCLUDE_AA_DATA_ON_RANK_ORDER = true; + } + } + else if(token.equals("use_less_initial_iterations") && tokenizer.countTokens() == 1) { + + token = tokenizer.nextToken(); + + if(token.equals("false")) { + USE_LESS_INITIAL_ITERATIONS_ON_SEQUENCE_RENDER = false; + } + else if(token.equals("true")) { + USE_LESS_INITIAL_ITERATIONS_ON_SEQUENCE_RENDER = true; + } + } + else if(token.equals("use_threads_for_bla2") && tokenizer.countTokens() == 1) { + + token = tokenizer.nextToken(); + + if(token.equals("false")) { + TaskDraw.USE_THREADS_FOR_BLA2 = false; + } + else if(token.equals("true")) { + TaskDraw.USE_THREADS_FOR_BLA2 = true; + } + } + else if(token.equals("reference_compression") && tokenizer.countTokens() == 1) { + + token = tokenizer.nextToken(); + + if(token.equals("false")) { + TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE = false; + } + else if(token.equals("true")) { + TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE = true; + } + } + else if (token.equals("reference_compression_error") && tokenizer.countTokens() == 1) { + try { + double temp = Double.parseDouble(tokenizer.nextToken()); + + if (temp > 0) { + ReferenceCompressor.CompressionError = temp; + ReferenceCompressor.setCompressionError(); + } + } catch (Exception ex) { + } + } + else if(token.equals("use_ref_index_on_bla2") && tokenizer.countTokens() == 1) { + + token = tokenizer.nextToken(); + + if(token.equals("false")) { + TaskDraw.USE_RI_ON_BLA2 = false; + } + else if(token.equals("true")) { + TaskDraw.USE_RI_ON_BLA2 = true; + } + } + else if(token.equals("disable_ref_index_on_bla2") && tokenizer.countTokens() == 1) { + + token = tokenizer.nextToken(); + + if(token.equals("false")) { + TaskDraw.DISABLE_RI_ON_BLA2 = false; + } + else if(token.equals("true")) { + TaskDraw.DISABLE_RI_ON_BLA2 = true; + } + } + else if(token.equals("two_pass_successive_refinement") && tokenizer.countTokens() == 1) { + + token = tokenizer.nextToken(); + + if(token.equals("false")) { + TaskDraw.TWO_PASS_SUCCESSIVE_REFINEMENT = false; + } + else if(token.equals("true")) { + TaskDraw.TWO_PASS_SUCCESSIVE_REFINEMENT = true; + } + } + else if (token.equals("square_rect_chunk_aggregation") && tokenizer.countTokens() == 1) { + try { + int temp = Integer.parseInt(tokenizer.nextToken()); + + if (temp >= 0 && temp <= 1) { + TaskDraw.SQUARE_RECT_CHUNK_AGGERAGATION = temp; + } + } catch (Exception ex) { + } + } + else if(token.equals("one_chunk_per_row") && tokenizer.countTokens() == 1) { + + token = tokenizer.nextToken(); + + if(token.equals("false")) { + TaskDraw.CHUNK_SIZE_PER_ROW = false; + } + else if(token.equals("true")) { + TaskDraw.CHUNK_SIZE_PER_ROW = true; + } + } + else if(token.equals("always_save_extra_pixel_data_on_aa_with_pp") && tokenizer.countTokens() == 1) { + + token = tokenizer.nextToken(); + + if(token.equals("false")) { + TaskDraw.ALWAYS_SAVE_EXTRA_PIXEL_DATA_ON_AA_WITH_PP = false; + } + else if(token.equals("true")) { + TaskDraw.ALWAYS_SAVE_EXTRA_PIXEL_DATA_ON_AA_WITH_PP = true; + } + } else if(token.equals("use_fast_delta_location") && tokenizer.countTokens() == 1) { token = tokenizer.nextToken(); @@ -1643,7 +1935,7 @@ else if (token.equals("brute_force_alg") && tokenizer.countTokens() == 1) { try { int temp = Integer.parseInt(tokenizer.nextToken()); - if (temp >= 0 && temp <= 2) { + if (temp >= 0 && temp <= 3) { TaskDraw.BRUTE_FORCE_ALG = temp; } } catch (Exception ex) { @@ -2251,39 +2543,47 @@ public void startBatchRender(ArrayList files, DefaultListModel f } - public void startSequenceRender(Apfloat size, double zoom_factor, int zooming_mode, double rotation_adjusting_value, int color_cycling_adjusting_value, double light_light_direction_adjusting_value, double bump_light_direction_adjusting_value, int zoom_every_n_frame, int gradient_color_cycling_adjusting_value, boolean flipSequenceIndexing, long startAtSequenceIndex, double slope_light_direction_adjusting_value) { + public void startSequenceRender() { Location.offset = new PixelOffset(); numberOfSequenceSteps = 0; - Apfloat temp = zooming_mode == 0 ? size : s.size; - while ((zooming_mode == 0 && temp.compareTo(s.size) > 0) || (zooming_mode == 1 && temp.compareTo(size) < 0)) { - if(zooming_mode == 0) { - temp = MyApfloat.fp.divide(temp, new MyApfloat(zoom_factor)); + Apfloat temp = zss.zooming_mode == 0 ? zss.size : s.size; + while ((zss.zooming_mode == 0 && temp.compareTo(s.size) > 0) || (zss.zooming_mode == 1 && temp.compareTo(zss.size) < 0)) { + if(zss.zooming_mode == 0) { + temp = MyApfloat.fp.divide(temp, new MyApfloat(zss.zoom_factor)); } else { - temp = MyApfloat.fp.multiply(temp, new MyApfloat(zoom_factor)); + temp = MyApfloat.fp.multiply(temp, new MyApfloat(zss.zoom_factor)); } numberOfSequenceSteps++; } numberOfSequenceSteps++; - this.zoom_factor = zoom_factor; - this.zooming_mode = zooming_mode; - this.size = size; - this.rotation_adjusting_value = rotation_adjusting_value; - this.color_cycling_adjusting_value = color_cycling_adjusting_value; - this.light_light_direction_adjusting_value = light_light_direction_adjusting_value; - this.bump_light_direction_adjusting_value = bump_light_direction_adjusting_value; - this.slopes_light_direction_adjusting_value = slope_light_direction_adjusting_value; - this.zoom_every_n_frame = zoom_every_n_frame; - this.gradient_color_cycling_adjusting_value = gradient_color_cycling_adjusting_value; - this.flipSequenceIndexing = flipSequenceIndexing; - this.startAtSequenceIndex = startAtSequenceIndex; - - numberOfSequenceSteps *= zoom_every_n_frame; + numberOfSequenceSteps *= zss.zoom_every_n_frame; + + Path path = Paths.get(outputDirectory); + + String name; + if (Files.exists(path) && Files.isDirectory(path)) { + name = path.resolve(settingsName + " - zoom sequence.json").toString(); + } + else { + name = settingsName + " - zoom sequence.json"; + } + + File file = new File(name); + ObjectMapper objectMapper = new ObjectMapper(); + try { + objectMapper.writeValue(file, zss); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + + int outPaletteLength = CommonFunctions.getOutPaletteLength(s.ds.domain_coloring, s.ds.domain_coloring_mode); + int inPaletteLength = CommonFunctions.getInPaletteLength(s.ds.domain_coloring); TaskDraw.single_thread_executor.submit(() -> { @@ -2305,7 +2605,7 @@ public void startSequenceRender(Apfloat size, double zoom_factor, int zooming_mo overviewButton.setEnabled(false); setOptions(false); runsOnSequenceMode = true; - sequenceIndex = flipSequenceIndexing ? numberOfSequenceSteps : 1; + sequenceIndex = zss.flipSequenceIndexing ? numberOfSequenceSteps : 1; Apfloat originalSize = s.size; Apfloat[] originalRotCenter = new Apfloat[2]; @@ -2324,16 +2624,24 @@ public void startSequenceRender(Apfloat size, double zoom_factor, int zooming_mo int originalGradientColorCyclingLocation = s.gs.gradient_offset; - if(rotation_adjusting_value != 0) { + int originalMaxIterations = s.max_iterations; + + if(zss.rotation_adjusting_value != 0) { s.fns.rotation_center[0] = s.xCenter; s.fns.rotation_center[1] = s.yCenter; } - s.size = zooming_mode == 0 ? size : s.size; + Fractal.clearStatistics(); + + s.size = zss.zooming_mode == 0 ? zss.size : s.size; + + int renderCount = 0; + for(int k = 1; k <= numberOfSequenceSteps; k++) { - if(startAtSequenceIndex == 0 || (!flipSequenceIndexing && sequenceIndex >= startAtSequenceIndex) || (flipSequenceIndexing && sequenceIndex <= startAtSequenceIndex) ) { + if(zss.startAtSequenceIndex == 0 || (!zss.flipSequenceIndexing && sequenceIndex >= zss.startAtSequenceIndex) || (zss.flipSequenceIndexing && sequenceIndex <= zss.startAtSequenceIndex) ) { render(); + try { for(Future future : futures) { future.get(); @@ -2342,9 +2650,43 @@ public void startSequenceRender(Apfloat size, double zoom_factor, int zooming_mo } catch (ExecutionException ex) { } + + if(USE_LESS_INITIAL_ITERATIONS_ON_SEQUENCE_RENDER && Fractal.total_min_iterations != null && Fractal.total_min_iterations.get() != Long.MAX_VALUE) { + long minStat = Fractal.total_min_iterations.get(); + + int iterLimit = 500000; + double limit = 1000; + double limit2 = 10000; + if(minStat < limit && originalMaxIterations > iterLimit) { + s.max_iterations = iterLimit; + } + else if(minStat >= limit && minStat <= limit2 && originalMaxIterations > iterLimit) { + s.max_iterations = (int)(iterLimit + (originalMaxIterations - iterLimit) * ((minStat - limit) / (limit2 - limit)) + 0.5); + } + else { + s.max_iterations = originalMaxIterations; + } + + if(renderCount == 0 && s.max_iterations != originalMaxIterations) { + render(); + + try { + for(Future future : futures) { + future.get(); + } + } catch (InterruptedException ex) { + } + catch (ExecutionException ex) { + } + } + } + + writeInfo(path); + + renderCount++; } - if(flipSequenceIndexing) { + if(zss.flipSequenceIndexing) { sequenceIndex--; } else { @@ -2359,89 +2701,37 @@ public void startSequenceRender(Apfloat size, double zoom_factor, int zooming_mo totalprogress.setString("Zoom Sequence: " + String.format("%3d", (int) ((double) (totalprogress.getValue()) / totalprogress.getMaximum() * 100)) + "%"); } - if(k >= zoom_every_n_frame && k % zoom_every_n_frame == 0) { - if (zooming_mode == 0) { - s.size = MyApfloat.fp.divide(s.size, new MyApfloat(zoom_factor)); + if(k >= zss.zoom_every_n_frame && k % zss.zoom_every_n_frame == 0) { + if (zss.zooming_mode == 0) { + s.size = MyApfloat.fp.divide(s.size, new MyApfloat(zss.zoom_factor)); } else { - s.size = MyApfloat.fp.multiply(s.size, new MyApfloat(zoom_factor)); + s.size = MyApfloat.fp.multiply(s.size, new MyApfloat(zss.zoom_factor)); } } - if(rotation_adjusting_value != 0) { - s.fns.rotation += rotation_adjusting_value; - if (rotation_adjusting_value > 0) { - s.fns.rotation = s.fns.rotation % 360.0; - } else if (rotation_adjusting_value < 0) { - if (s.fns.rotation <= -360) { - s.fns.rotation += 360; - } - } - - Apfloat tempRadians = MyApfloat.fp.toRadians(new MyApfloat(s.fns.rotation)); - s.fns.rotation_vals[0] = MyApfloat.cos(tempRadians); - s.fns.rotation_vals[1] = MyApfloat.sin(tempRadians); + if(zss.rotation_adjusting_value != 0) { + CommonFunctions.adjustRotationOffset(s,zss.rotation_adjusting_value); } - if(color_cycling_adjusting_value != 0) { - s.ps.color_cycling_location += color_cycling_adjusting_value; - - s.ps.color_cycling_location = s.ps.color_cycling_location > Integer.MAX_VALUE - 40000 ? 0 : s.ps.color_cycling_location; - - s.ps2.color_cycling_location += color_cycling_adjusting_value; - - s.ps2.color_cycling_location = s.ps2.color_cycling_location > Integer.MAX_VALUE - 40000 ? 0 : s.ps2.color_cycling_location; - + if(zss.color_cycling_adjusting_value != 0) { + s.ps.color_cycling_location = CommonFunctions.adjustPaletteOffset(s.ps.color_cycling_location, zss.color_cycling_adjusting_value, outPaletteLength); + s.ps2.color_cycling_location = CommonFunctions.adjustPaletteOffset(s.ps2.color_cycling_location, zss.color_cycling_adjusting_value, inPaletteLength); } - if(gradient_color_cycling_adjusting_value != 0) { - s.gs.gradient_offset += gradient_color_cycling_adjusting_value; - s.gs.gradient_offset = s.gs.gradient_offset > Integer.MAX_VALUE - 40000 ? 0 : s.gs.gradient_offset; + if(zss.gradient_color_cycling_adjusting_value != 0) { + s.gs.gradient_offset = CommonFunctions.adjustPaletteOffset(s.gs.gradient_offset, zss.gradient_color_cycling_adjusting_value, GRADIENT_LENGTH); } - if (s.pps.bms.bump_map && bump_light_direction_adjusting_value != 0) { - s.pps.bms.lightDirectionDegrees += bump_light_direction_adjusting_value; - if (bump_light_direction_adjusting_value > 0) { - s.pps.bms.lightDirectionDegrees = s.pps.bms.lightDirectionDegrees % 360.0; - } - else { - if (s.pps.bms.lightDirectionDegrees <= -360) { - s.pps.bms.lightDirectionDegrees += 360; - } - } + if (s.pps.bms.bump_map && zss.bump_direction_adjusting_value != 0) { + CommonFunctions.adjustBumpOffset(s.pps.bms, zss.bump_direction_adjusting_value); } - if (s.pps.ls.lighting && light_light_direction_adjusting_value != 0) { - s.pps.ls.light_direction += light_light_direction_adjusting_value; - - if(light_light_direction_adjusting_value > 0) { - s.pps.ls.light_direction = s.pps.ls.light_direction % 360.0; - } - else { - if (s.pps.ls.light_direction < 0) { - s.pps.ls.light_direction += 360; - } - } - - double lightAngleRadians = Math.toRadians(s.pps.ls.light_direction); - s.pps.ls.lightVector[0] = Math.cos(lightAngleRadians) * s.pps.ls.light_magnitude; - s.pps.ls.lightVector[1] = Math.sin(lightAngleRadians) * s.pps.ls.light_magnitude; + if (s.pps.ls.lighting && zss.light_direction_adjusting_value != 0) { + CommonFunctions.adjustLightOffset(s.pps.ls, zss.light_direction_adjusting_value); } - if (s.pps.ss.slopes && slope_light_direction_adjusting_value != 0) { - s.pps.ss.SlopeAngle += slope_light_direction_adjusting_value; - - if(slope_light_direction_adjusting_value > 0) { - s.pps.ss.SlopeAngle = s.pps.ss.SlopeAngle % 360.0; - } - else { - if (s.pps.ss.SlopeAngle < 0) { - s.pps.ss.SlopeAngle += 360; - } - } - - double lightAngleRadians = Math.toRadians(s.pps.ss.SlopeAngle); - s.pps.ss.lightVector[0] = Math.cos(lightAngleRadians); - s.pps.ss.lightVector[1] = Math.sin(lightAngleRadians); + if (s.pps.ss.slopes && zss.slopes_direction_adjusting_value != 0) { + CommonFunctions.adjustSlopeOffset(s.pps.ss, zss.slopes_direction_adjusting_value); } } @@ -2462,6 +2752,8 @@ public void startSequenceRender(Apfloat size, double zoom_factor, int zooming_mo s.pps.ls = lightBack; s.pps.ss = slopeBack; + s.max_iterations = originalMaxIterations; + s.gs.gradient_offset = originalGradientColorCyclingLocation; setOptions(true); @@ -2472,6 +2764,43 @@ public void startSequenceRender(Apfloat size, double zoom_factor, int zooming_mo } + private String normalizeValue(String val, int digits) { + val = val.toLowerCase(); + int indexOfE = val.indexOf("e"); + + String mantissa = indexOfE != -1 ? val.substring(0, indexOfE) : val; + String exponent = indexOfE != -1 ? val.substring(indexOfE, val.length()) : ""; + int indexofDot = mantissa.indexOf("."); + if(indexofDot != -1) { + int length = mantissa.length() - (indexofDot + 1); + if(length > digits) { + length = digits; + } + return mantissa.substring(0, indexofDot) + mantissa.substring(indexofDot, indexofDot + 1 + length) + exponent; + } + else { + return val; + } + } + + private void writeInfo(Path path) { + String infoName; + if (Files.exists(path) && Files.isDirectory(path)) { + infoName = path.resolve(settingsName + " - zoom sequence - " + " (" + sequenceIndex + ")" + ".info").toString(); + } + else { + infoName = settingsName + " - zoom sequence - " + " (" + sequenceIndex + ")" + ".info"; + } + + String info = "Size: " + normalizeValue(s.size.toString(), 4) + "\n" + + "Magnification: " + normalizeValue(MyApfloat.fp.divide(Constants.DEFAULT_MAGNIFICATION, s.size).toString(), 6); + + try { + Files.write(Paths.get(infoName), info.getBytes()); + } + catch (Exception ex) {} + } + public void setOutputDirectory() { file_chooser = new JFileChooser(outputDirectory); @@ -2490,21 +2819,23 @@ public void setOutputDirectory() { public static void main(String[] args) throws Exception { - if(args.length > 0 && args[0].equals("l4jini")) { - CommonFunctions.exportL4jIni("FZImageExpander", Constants.IEL4j); - } + // SwingUtilities.invokeLater(() -> { + if(args.length > 0 && args[0].equals("l4jini")) { + CommonFunctions.exportL4jIni("FZImageExpander", Constants.IEL4j); + } - ImageExpanderWindow mw = new ImageExpanderWindow(); - mw.setVisible(true); + ImageExpanderWindow mw = new ImageExpanderWindow(); + mw.setVisible(true); - boolean actionOk = mw.getCommonFunctions().copyLib(); - mw.getCommonFunctions().exportCodeFilesNoUi(); - - if(actionOk) { - mw.getCommonFunctions().compileCode(false); - } - - mw.getCommonFunctions().checkForUpdate(false); + boolean actionOk = mw.getCommonFunctions().copyLib(); + mw.getCommonFunctions().exportCodeFilesNoUi(); + + if(actionOk) { + mw.getCommonFunctions().compileCode(false); + } + + mw.getCommonFunctions().checkForUpdate(false); + //}); } } diff --git a/src/fractalzoomer/main/MainWindow.java b/src/fractalzoomer/main/MainWindow.java index 1b79f4313..dc80fb79d 100644 --- a/src/fractalzoomer/main/MainWindow.java +++ b/src/fractalzoomer/main/MainWindow.java @@ -156,6 +156,7 @@ public class MainWindow extends JFrame implements Constants { public static String SaveImagesPath = ""; private static final long serialVersionUID = -6314723558420412681L; private Settings s; + private ColorCyclingSettings ccs; private boolean first_paint; private boolean orbit; public static boolean show_orbit_converging_point = true; @@ -165,14 +166,6 @@ public class MainWindow extends JFrame implements Constants { public static boolean FAST_JULIA_FILTERS = false; public static boolean PERIODICITY_CHECKING = false; private boolean color_cycling; - private int color_cycling_speed; - private boolean cycle_colors; - private boolean cycle_lights; - private boolean cycle_gradient; - - private ImageRepainter ir; - - private int color_cycling_adjusting_value; public static boolean runsOnWindows; private boolean grid; @@ -184,7 +177,6 @@ public class MainWindow extends JFrame implements Constants { private boolean old_d3; private TaskDraw[][] tasks; private ArrayList> futures = new ArrayList<>(); - private Future image_repainter_future; private Future orbit_future; private DrawOrbit pixels_orbit; private Apfloat old_xCenter; @@ -277,6 +269,7 @@ public MainWindow() { s = new Settings(); s.applyStaticSettings(); + ccs = new ColorCyclingSettings(); TaskDraw.ALWAYS_SAVE_EXTRA_PIXEL_DATA_ON_AA = true; @@ -301,6 +294,7 @@ public MainWindow() { TaskDraw.thread_calculation_executor = (ThreadPoolExecutor)Executors.newFixedThreadPool(m * n); TaskDraw.single_thread_executor = Executors.newSingleThreadExecutor(); TaskDraw.action_thread_executor = (ThreadPoolExecutor)Executors.newFixedThreadPool(4); + TaskDraw.la_thread_executor = (ThreadPoolExecutor)Executors.newFixedThreadPool(procs); thread_grouping = 3; julia_grid_first_dimension = 2; @@ -318,12 +312,6 @@ public MainWindow() { boundaries_spacing_method = 0; boundaries_type = 0; - color_cycling_speed = 140; - cycle_colors = true; - cycle_lights = false; - cycle_gradient = false; - color_cycling_adjusting_value = 1; - old_rotation_vals = new Apfloat[2]; old_rotation_vals[0] = s.fns.rotation_vals[0]; @@ -863,6 +851,15 @@ public void mouseMoved(MouseEvent e) { loadPreferences(); loadAutoSave(); + if(MyApfloat.setAutomaticPrecision) { + long precision = MyApfloat.getAutomaticPrecision(new String[]{s.size.toString()}, new boolean[] {true}, s.fns.function); + + // if (MyApfloat.shouldSetPrecision(precision, true, s.fns.function)) { + Fractal.clearReferences(true, true); + MyApfloat.setPrecision(precision, s); + //} + } + if(!Settings.hasFunctionParameterization(s.fns.function)) { toolbar.getCurrentFunction().setEnabled(false); } @@ -1135,6 +1132,9 @@ public void reloadTitle() { case FORMULA2: temp += " z = c(z + z^-1)"; break; + case FORMULA48: + temp += " z = c(z^2 + z^-2)"; + break; case FORMULA3: temp += " z = c(z^3 + z^-3)"; break; @@ -1469,24 +1469,51 @@ else if(thread_grouping == 3 || thread_grouping == 4 || thread_grouping == 5) { tasks[i][j] = new BoundaryTracingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); } } else if (TaskDraw.GREEDY_ALGORITHM_SELECTION == DIVIDE_AND_CONQUER) { - if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { - tasks[i][j] = new MarianiSilverColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); - } else { - tasks[i][j] = new MarianiSilverDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new MarianiSilver3ColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } else { + tasks[i][j] = new MarianiSilver3Draw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } + } + else { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new MarianiSilverColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } else { + tasks[i][j] = new MarianiSilverDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } } } else if (TaskDraw.GREEDY_ALGORITHM_SELECTION == SUCCESSIVE_REFINEMENT) { - if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { - tasks[i][j] = new SuccessiveRefinementGuessingColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); - } else { - tasks[i][j] = new SuccessiveRefinementGuessingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new SuccessiveRefinementGuessing2ColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } else { + tasks[i][j] = new SuccessiveRefinementGuessing2Draw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } + } + else { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new SuccessiveRefinementGuessingColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } else { + tasks[i][j] = new SuccessiveRefinementGuessingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } } } else if (TaskDraw.GREEDY_ALGORITHM_SELECTION == CIRCULAR_SUCCESSIVE_REFINEMENT) { - if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { - tasks[i][j] = new CircularSuccessiveRefinementGuessingColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); - } else { - tasks[i][j] = new CircularSuccessiveRefinementGuessingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new CircularSuccessiveRefinementGuessing2ColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } else { + tasks[i][j] = new CircularSuccessiveRefinementGuessing2Draw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } + } + else { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new CircularSuccessiveRefinementGuessingColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } else { + tasks[i][j] = new CircularSuccessiveRefinementGuessingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } } } } else { @@ -1495,9 +1522,12 @@ else if (TaskDraw.GREEDY_ALGORITHM_SELECTION == CIRCULAR_SUCCESSIVE_REFINEMENT) } else if (TaskDraw.BRUTE_FORCE_ALG == 1){ tasks[i][j] = new BruteForce2Draw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); } - else { + else if (TaskDraw.BRUTE_FORCE_ALG == 2){ tasks[i][j] = new CircularBruteForceDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); } + else { + tasks[i][j] = new BruteForceInterleavedDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, s.xJuliaCenter, s.yJuliaCenter); + } } } else if (TaskDraw.GREEDY_ALGORITHM) { if (TaskDraw.GREEDY_ALGORITHM_SELECTION == BOUNDARY_TRACING) { @@ -1507,24 +1537,51 @@ else if (TaskDraw.GREEDY_ALGORITHM_SELECTION == CIRCULAR_SUCCESSIVE_REFINEMENT) tasks[i][j] = new BoundaryTracingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); } } else if (TaskDraw.GREEDY_ALGORITHM_SELECTION == DIVIDE_AND_CONQUER) { - if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { - tasks[i][j] = new MarianiSilverColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); - } else { - tasks[i][j] = new MarianiSilverDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new MarianiSilver3ColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } else { + tasks[i][j] = new MarianiSilver3Draw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } + } + else { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new MarianiSilverColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } else { + tasks[i][j] = new MarianiSilverDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } } } else if (TaskDraw.GREEDY_ALGORITHM_SELECTION == SUCCESSIVE_REFINEMENT) { - if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { - tasks[i][j] = new SuccessiveRefinementGuessingColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); - } else { - tasks[i][j] = new SuccessiveRefinementGuessingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new SuccessiveRefinementGuessing2ColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } else { + tasks[i][j] = new SuccessiveRefinementGuessing2Draw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } + } + else { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new SuccessiveRefinementGuessingColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } else { + tasks[i][j] = new SuccessiveRefinementGuessingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } } } else if(TaskDraw.GREEDY_ALGORITHM_SELECTION == CIRCULAR_SUCCESSIVE_REFINEMENT) { - if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { - tasks[i][j] = new CircularSuccessiveRefinementGuessingColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); - } else { - tasks[i][j] = new CircularSuccessiveRefinementGuessingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new CircularSuccessiveRefinementGuessing2ColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } else { + tasks[i][j] = new CircularSuccessiveRefinementGuessing2Draw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } + } + else { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new CircularSuccessiveRefinementGuessingColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } else { + tasks[i][j] = new CircularSuccessiveRefinementGuessingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } } } } else { @@ -1533,9 +1590,12 @@ else if(TaskDraw.GREEDY_ALGORITHM_SELECTION == CIRCULAR_SUCCESSIVE_REFINEMENT) { } else if (TaskDraw.BRUTE_FORCE_ALG == 1) { tasks[i][j] = new BruteForce2Draw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); } - else { + else if (TaskDraw.BRUTE_FORCE_ALG == 2) { tasks[i][j] = new CircularBruteForceDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); } + else { + tasks[i][j] = new BruteForceInterleavedDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.xCenter, s.yCenter, s.size, s.max_iterations, s.fns, s.d3s, ptr, s.fractal_color, s.dem_color, image, s.fs, PERIODICITY_CHECKING, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.ds, s.inverse_dem, doQuickDraw, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps); + } } tasks[i][j].setTaskId(taskId); tasks[i][j].setCreatePreview(createPreview); @@ -1548,7 +1608,12 @@ else if(TaskDraw.GREEDY_ALGORITHM_SELECTION == CIRCULAR_SUCCESSIVE_REFINEMENT) { if(tasks[0][0].hasCircularLogic()) { CircularBruteForceDraw.initCoordinates(image_size, zoom_to_cursor && CIRCULAR_DRAW_FOLLOWS_ZOOM_TO_CURSOR, !doQuickDraw || TaskDraw.QUICKDRAW_SUCCESSIVE_REFINEMENT, tasks[0][0].usesSuccessiveRefinement()); if(tasks[0][0].usesSuccessiveRefinement()) { - CircularSuccessiveRefinementGuessingDraw.initCoordinates(image_size, false); + if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + CircularSuccessiveRefinementGuessing2Draw.initCoordinates(image_size, false); + } + else { + CircularSuccessiveRefinementGuessingDraw.initCoordinates(image_size, false); + } } } else { @@ -1602,17 +1667,7 @@ private void startTasks() { } if (initialized && (AUTO_REPAINT_IMAGE && (!isQuickDraw || TaskDraw.QUICKDRAW_SUCCESSIVE_REFINEMENT)) && !s.d3s.d3 && !isFastJulia && !color_cycling) { - if(ir == null) { - ir = new ImageRepainter(ptr, tasks); - ir.init((isQuickDraw && TaskDraw.QUICKDRAW_SUCCESSIVE_REFINEMENT) || tasks[0][0].usesSuccessiveRefinement()); - image_repainter_future = TaskDraw.single_thread_executor.submit(ir); - } - else { - ir.stopIt(); - ir = new ImageRepainter(ptr, tasks); - ir.init((isQuickDraw && TaskDraw.QUICKDRAW_SUCCESSIVE_REFINEMENT) || tasks[0][0].usesSuccessiveRefinement()); - image_repainter_future = TaskDraw.single_thread_executor.submit(ir); - } + main_panel.setTimer((isQuickDraw && TaskDraw.QUICKDRAW_SUCCESSIVE_REFINEMENT) || tasks[0][0].usesSuccessiveRefinement(), tasks); } } @@ -1720,6 +1775,14 @@ public void prepareUI() { tools_menu.getBoundaries().setSelected(false); } + if(s.size.compareTo(MyApfloat.MIN_DOUBLE_SIZE) < 0) { + tools_menu.getOrbit().setSelected(false); + tools_menu.getOrbit().setEnabled(false); + orbit = false; + toolbar.getOrbitButton().setSelected(false); + toolbar.getOrbitButton().setEnabled(false); + } + if (s.fns.rotation != 0 && s.fns.rotation != 360 && s.fns.rotation != -360) { tools_menu.getGrid().setEnabled(false); grid = false; @@ -1737,8 +1800,7 @@ public void prepareUI() { options_menu.getInColoringMenu().setEnabledAllButMaxIterations(true); } - if (s.pps.ots.useTraps || s.fns.tcs.trueColorIn || (s.pps.sts.statistic && s.pps.sts.statisticGroup == 2 && s.pps.sts.equicontinuityOverrideColoring) - || (s.pps.sts.statistic && (s.pps.sts.statisticGroup == 3 || s.pps.sts.normalMapCombineWithOtherStatistics)) || (s.pps.sts.statistic && s.pps.sts.statisticGroup == 4)) { + if (s.requiresRecalculation(true)) { PERIODICITY_CHECKING = false; options_menu.getPeriodicityChecking().setSelected(false); options_menu.getPeriodicityChecking().setEnabled(false); @@ -1935,6 +1997,7 @@ public void prepareUI() { options_menu.getBailout().setEnabled(false); options_menu.getBailoutConditionMenu().setEnabled(false); options_menu.getConvergentBailoutConditionMenu().setEnabled(false); + options_menu.getConvergentBailout().setEnabled(false); infobar.getMaxIterationsColorPreview().setVisible(false); infobar.getMaxIterationsColorPreviewLabel().setVisible(false); @@ -1994,9 +2057,7 @@ public void prepareUI() { toolbar.getDomainColoringButton().setSelected(s.ds.domain_coloring); - if (s.pps.ots.useTraps || s.fns.tcs.trueColorIn || (s.pps.sts.statistic && s.pps.sts.statisticGroup == 2 && s.pps.sts.equicontinuityOverrideColoring) - || (s.pps.sts.statistic && (s.pps.sts.statisticGroup == 3 || s.pps.sts.normalMapCombineWithOtherStatistics)) || (s.pps.sts.statistic && s.pps.sts.statisticGroup == 4) - ) { + if (s.requiresRecalculation(true)) { tools_menu.getColorCycling().setEnabled(false); toolbar.getColorCyclingButton().setEnabled(false); options_menu.getPeriodicityChecking().setEnabled(false); @@ -2024,6 +2085,7 @@ public void prepareUI() { options_menu.getBailout().setEnabled(false); options_menu.getBailoutConditionMenu().setEnabled(false); options_menu.getConvergentBailoutConditionMenu().setEnabled(true); + options_menu.getConvergentBailout().setEnabled(true); optionsEnableShortcut(); break; case KLEINIAN: @@ -2039,6 +2101,7 @@ public void prepareUI() { options_menu.getBailout().setEnabled(false); options_menu.getBailoutConditionMenu().setEnabled(false); options_menu.getConvergentBailoutConditionMenu().setEnabled(false); + options_menu.getConvergentBailout().setEnabled(false); break; case SIERPINSKI_GASKET: case INERTIA_GRAVITY: @@ -2052,6 +2115,7 @@ public void prepareUI() { options_menu.getInitialValue().setEnabled(false); options_menu.getPlaneInfluenceMenu().setEnabled(false); options_menu.getConvergentBailoutConditionMenu().setEnabled(false); + options_menu.getConvergentBailout().setEnabled(false); break; case MANDELBROT: if (!s.ds.domain_coloring && !s.isPertubationTheoryInUse() && !s.isHighPrecisionInUse()) { @@ -2109,6 +2173,7 @@ public void prepareUI() { out_coloring_modes[ESCAPE_TIME_FIELD_LINES2].setEnabled(true); } options_menu.getConvergentBailoutConditionMenu().setEnabled(false); + options_menu.getConvergentBailout().setEnabled(false); break; case USER_FORMULA: @@ -2132,9 +2197,11 @@ public void prepareUI() { options_menu.getBailoutConditionMenu().setEnabled(false); options_menu.getPeriodicityChecking().setEnabled(false); options_menu.getConvergentBailoutConditionMenu().setEnabled(true); + options_menu.getConvergentBailout().setEnabled(true); } else { options_menu.getConvergentBailoutConditionMenu().setEnabled(false); + options_menu.getConvergentBailout().setEnabled(false); } optionsEnableShortcut(); @@ -2143,6 +2210,7 @@ public void prepareUI() { if(Settings.isPolynomialFunction(s.fns.function)) { if (s.fns.function == MANDELPOLY) { options_menu.getConvergentBailoutConditionMenu().setEnabled(false); + options_menu.getConvergentBailout().setEnabled(false); optionsEnableShortcut(); } else { optionsEnableShortcut2(); @@ -2153,6 +2221,7 @@ else if(Settings.isRootSolvingMethod(s.fns.function)) { } else { options_menu.getConvergentBailoutConditionMenu().setEnabled(false); + options_menu.getConvergentBailout().setEnabled(false); optionsEnableShortcut(); } break; @@ -2160,6 +2229,7 @@ else if(Settings.isRootSolvingMethod(s.fns.function)) { if(s.isMagnetType() || s.isEscapingOrConvergingType()) { options_menu.getConvergentBailoutConditionMenu().setEnabled(true); + options_menu.getConvergentBailout().setEnabled(true); } options_menu.getOutColoringPalette()[s.ps.color_choice].setSelected(true); @@ -2426,6 +2496,14 @@ public void defaultFractalSettings(boolean resetImage) { tools_menu.getBoundaries().setSelected(false); } + if(s.size.compareTo(MyApfloat.MIN_DOUBLE_SIZE) < 0) { + tools_menu.getOrbit().setSelected(false); + tools_menu.getOrbit().setEnabled(false); + orbit = false; + toolbar.getOrbitButton().setSelected(false); + toolbar.getOrbitButton().setEnabled(false); + } + progress.setValue(0); scroll_pane.getHorizontalScrollBar().setValue((int) (scroll_pane.getHorizontalScrollBar().getMaximum() / 2.0 - scroll_pane.getHorizontalScrollBar().getSize().getWidth() / 2.0)); @@ -2465,6 +2543,14 @@ public void setCenterSizePost() { tools_menu.getBoundaries().setSelected(false); } + if(s.size.compareTo(MyApfloat.MIN_DOUBLE_SIZE) < 0) { + tools_menu.getOrbit().setSelected(false); + tools_menu.getOrbit().setEnabled(false); + orbit = false; + toolbar.getOrbitButton().setSelected(false); + toolbar.getOrbitButton().setEnabled(false); + } + setOptions(false); progress.setValue(0); @@ -2593,10 +2679,10 @@ public void fractalColorsChanged(Color max_it_color, Color dem_color, Color spec updateMaxIterColorPreview(); if(!recalculate) { - updateColors(false); + updateColors(false, false); } else { - redraw(); + redraw(false); } } @@ -2619,8 +2705,28 @@ public void setSkipBailoutIterationsPost() { SkipBailoutCondition.SKIPPED_ITERATION_COUNT = s.fns.skip_bailout_iterations; SkipConvergentBailoutCondition.SKIPPED_ITERATION_COUNT = s.fns.skip_convergent_bailout_iterations; - redraw(); + redraw(false); + + } + + public void onIterationsChange() { + + if(s.canSkipCalculatedAreas() && s.old_max_iterations != s.max_iterations) { + redraw(true); + } + else if(s.old_max_iterations != s.max_iterations) { + redraw(false); + } + } + + public void onPeriodChange() { + if(s.canSkipCalculatedAreas() && s.old_max_iterations != s.max_iterations) { + redraw(true); + } + else { + redraw(false); + } } public void setIterations() { @@ -2808,7 +2914,7 @@ public void setPalette(int temp2, int[] palette, int mode) { updateColorPalettesMenu(); updateMaxIterColorPreview(); - updateColors(false); + updateColors(false, false); } @@ -2834,8 +2940,7 @@ public void setFilter(int temp) { resetImageAndCopy(s.d3s.d3, false); - if ((TaskDraw.GREEDY_ALGORITHM && TaskDraw.GREEDY_ALGORITHM_SELECTION == DIVIDE_AND_CONQUER) || s.pps.ots.useTraps || s.fns.tcs.trueColorOut || s.fns.tcs.trueColorIn || (s.pps.sts.statistic && s.pps.sts.statisticGroup == 2 && s.pps.sts.equicontinuityOverrideColoring) - || (s.pps.sts.statistic && (s.pps.sts.statisticGroup == 3 || s.pps.sts.normalMapCombineWithOtherStatistics)) || (s.pps.sts.statistic && s.pps.sts.statisticGroup == 4)) { + if ((TaskDraw.GREEDY_ALGORITHM && TaskDraw.GREEDY_ALGORITHM_SELECTION == DIVIDE_AND_CONQUER) || s.requiresRecalculation(false)) { if (s.d3s.d3) { createTasksPaletteAndFilter3DModel(); } else { @@ -2899,10 +3004,12 @@ public void setFilter(int temp) { resetImageAndCopy(s.d3s.d3, false); - if (s.fs.filters[ANTIALIASING] || s.pps.ots.useTraps || s.ds.domain_coloring || s.fns.tcs.trueColorOut || s.fns.tcs.trueColorIn || (s.pps.sts.statistic && s.pps.sts.statisticGroup == 2 && s.pps.sts.equicontinuityOverrideColoring) - || (s.pps.sts.statistic && (s.pps.sts.statisticGroup == 3 || s.pps.sts.normalMapCombineWithOtherStatistics)) || (s.pps.sts.statistic && s.pps.sts.statisticGroup == 4)) { + if (s.fs.filters[ANTIALIASING] || s.requiresRecalculation(false)) { - if(!TaskDraw.hasExtraData(image_size) || s.d3s.d3) { + if(s.fs.filters[ANTIALIASING] && TaskDraw.hasExtraData(image_size) && !s.d3s.d3 && !s.ds.domain_coloring) { + createTasksPalettePostProcessAndFilterWithAAData(TaskDraw.POST_PROCESSING_WITH_AA_AND_FILTER); + } + else { if(s.julia_map) { createTasksJuliaMap(); } @@ -2913,9 +3020,6 @@ else if (s.d3s.d3) { createTasks(false, false, false, false); } } - else { - createTasksPalettePostProcessAndFilterWithAAData(TaskDraw.POST_PROCESSING_WITH_AA_AND_FILTER); - } calculation_time = System.currentTimeMillis(); @@ -3118,6 +3222,14 @@ private void selectPointFractalInternal(MouseEvent e, double curX, double curY) tools_menu.getBoundaries().setSelected(false); } + if(s.size.compareTo(MyApfloat.MIN_DOUBLE_SIZE) < 0) { + tools_menu.getOrbit().setSelected(false); + tools_menu.getOrbit().setEnabled(false); + orbit = false; + toolbar.getOrbitButton().setSelected(false); + toolbar.getOrbitButton().setEnabled(false); + } + setOptions(false); progress.setValue(0); @@ -3241,6 +3353,14 @@ private void scrollPointInternal(MouseWheelEvent e, boolean doQuickDraw, double tools_menu.getBoundaries().setSelected(false); } + if(s.size.compareTo(MyApfloat.MIN_DOUBLE_SIZE) < 0) { + tools_menu.getOrbit().setSelected(false); + tools_menu.getOrbit().setEnabled(false); + orbit = false; + toolbar.getOrbitButton().setSelected(false); + toolbar.getOrbitButton().setEnabled(false); + } + setOptions(false); if(!doQuickDraw) { @@ -3612,6 +3732,14 @@ private void scrollPointPolarInternal(MouseWheelEvent e, boolean doQuickDraw, do tools_menu.getBoundaries().setSelected(false); } + if(s.size.compareTo(MyApfloat.MIN_DOUBLE_SIZE) < 0) { + tools_menu.getOrbit().setSelected(false); + tools_menu.getOrbit().setEnabled(false); + orbit = false; + toolbar.getOrbitButton().setSelected(false); + toolbar.getOrbitButton().setEnabled(false); + } + setOptions(false); if(!doQuickDraw) { @@ -3767,6 +3895,14 @@ private void selectPointJuliaInternal(MouseEvent e, double curX, double curY) { tools_menu.getBoundaries().setSelected(false); } + if(s.size.compareTo(MyApfloat.MIN_DOUBLE_SIZE) < 0) { + tools_menu.getOrbit().setSelected(false); + tools_menu.getOrbit().setEnabled(false); + orbit = false; + toolbar.getOrbitButton().setSelected(false); + toolbar.getOrbitButton().setEnabled(false); + } + progress.setValue(0); if(!ZOOM_ON_THE_CURSOR) { @@ -3858,6 +3994,14 @@ private void selectPointPolarInternal(MouseEvent e, double curX, double curY) { tools_menu.getBoundaries().setSelected(false); } + if(s.size.compareTo(MyApfloat.MIN_DOUBLE_SIZE) < 0) { + tools_menu.getOrbit().setSelected(false); + tools_menu.getOrbit().setEnabled(false); + orbit = false; + toolbar.getOrbitButton().setSelected(false); + toolbar.getOrbitButton().setEnabled(false); + } + setOptions(false); progress.setValue(0); @@ -3893,19 +4037,6 @@ private void stopSuccessiveRefinement() { catch (ExecutionException ex) { } //} - - if(ir != null && image_repainter_future != null) { - ir.stopIt(); - try { - image_repainter_future.get(); - } - catch (InterruptedException ex) { - - } - catch (ExecutionException ex) { - - } - } } private void selectPointPolar(MouseEvent e) { @@ -4209,6 +4340,14 @@ private void zoomInInternal() { tools_menu.getBoundaries().setSelected(false); } + if(s.size.compareTo(MyApfloat.MIN_DOUBLE_SIZE) < 0) { + tools_menu.getOrbit().setSelected(false); + tools_menu.getOrbit().setEnabled(false); + orbit = false; + toolbar.getOrbitButton().setSelected(false); + toolbar.getOrbitButton().setEnabled(false); + } + setOptions(false); progress.setValue(0); @@ -4287,6 +4426,14 @@ private void zoomOutInternal() { tools_menu.getBoundaries().setSelected(false); } + if(s.size.compareTo(MyApfloat.MIN_DOUBLE_SIZE) < 0) { + tools_menu.getOrbit().setSelected(false); + tools_menu.getOrbit().setEnabled(false); + orbit = false; + toolbar.getOrbitButton().setSelected(false); + toolbar.getOrbitButton().setEnabled(false); + } + setOptions(false); progress.setValue(0); @@ -4363,6 +4510,14 @@ private void moveToInternal(int where) { tools_menu.getBoundaries().setSelected(false); } + if(s.size.compareTo(MyApfloat.MIN_DOUBLE_SIZE) < 0) { + tools_menu.getOrbit().setSelected(false); + tools_menu.getOrbit().setEnabled(false); + orbit = false; + toolbar.getOrbitButton().setSelected(false); + toolbar.getOrbitButton().setEnabled(false); + } + setOptions(false); progress.setValue(0); @@ -4524,8 +4679,9 @@ public void setOptions(boolean option) { options_menu.getBailoutConditionMenu().setEnabled(option); } - if (!s.ds.domain_coloring && s.hasConvergentBailoutCondition()) { + if (!s.ds.domain_coloring && s.hasConvergentBailout()) { options_menu.getConvergentBailoutConditionMenu().setEnabled(option); + options_menu.getConvergentBailout().setEnabled(option); } options_menu.getOptimizationsMenu().setEnabled(option); @@ -4536,7 +4692,7 @@ public void setOptions(boolean option) { options_menu.getDirectColor().setEnabled(option); } - if (!s.ds.domain_coloring && !s.isConvergingType() && s.fns.function != KLEINIAN && s.fns.function != SIERPINSKI_GASKET && s.fns.function != INERTIA_GRAVITY && !s.pps.ots.useTraps && !s.fns.tcs.trueColorIn && !(s.pps.sts.statistic && s.pps.sts.statisticGroup == 2 && s.pps.sts.equicontinuityOverrideColoring) && !(s.pps.sts.statistic && (s.pps.sts.statisticGroup == 3 || s.pps.sts.normalMapCombineWithOtherStatistics)) && !(s.pps.sts.statistic && s.pps.sts.statisticGroup == 4) && !TaskDraw.PERTURBATION_THEORY && !TaskDraw.HIGH_PRECISION_CALCULATION) { + if (!s.ds.domain_coloring && !s.isConvergingType() && s.fns.function != KLEINIAN && s.fns.function != SIERPINSKI_GASKET && s.fns.function != INERTIA_GRAVITY && !s.requiresRecalculation(true) && !TaskDraw.PERTURBATION_THEORY && !TaskDraw.HIGH_PRECISION_CALCULATION) { options_menu.getPeriodicityChecking().setEnabled(option); } @@ -4549,8 +4705,7 @@ public void setOptions(boolean option) { toolbar.getJuliaButton().setEnabled(option); } - if (!zoom_window && !orbit && !color_cycling && !s.d3s.d3 && !s.pps.ots.useTraps && !s.useDirectColor && !s.fns.tcs.trueColorOut && !s.fns.tcs.trueColorIn && !(s.pps.sts.statistic && s.pps.sts.statisticGroup == 2 && s.pps.sts.equicontinuityOverrideColoring) - && !(s.pps.sts.statistic && (s.pps.sts.statisticGroup == 3 || s.pps.sts.normalMapCombineWithOtherStatistics)) && !(s.pps.sts.statistic && s.pps.sts.statisticGroup == 4)) { + if (!zoom_window && !orbit && !color_cycling && !s.d3s.d3 && !s.useDirectColor && !s.requiresRecalculation(false)) { tools_menu.getColorCycling().setEnabled(option); toolbar.getColorCyclingButton().setEnabled(option); } @@ -4655,7 +4810,7 @@ public void setOptions(boolean option) { tools_menu.getZoomWindow().setEnabled(option); } - if (!s.julia_map && !s.d3s.d3 && !zoom_window) { + if (!s.julia_map && !s.d3s.d3 && !zoom_window && s.size.compareTo(MyApfloat.MIN_DOUBLE_SIZE) >= 0) { tools_menu.getOrbit().setEnabled(option); toolbar.getOrbitButton().setEnabled(option); } @@ -4706,17 +4861,10 @@ public void setOptions(boolean option) { } - public void setLine() { - - resetOrbit(); - orbit_style = 0; - - } - - public void setDot() { + public void setOrbitStyle(int style) { resetOrbit(); - orbit_style = 1; + orbit_style = style; } @@ -4920,6 +5068,7 @@ public void setFunction(int temp) { } options_menu.getConvergentBailoutConditionMenu().setEnabled(false); + options_menu.getConvergentBailout().setEnabled(false); break; case USER_FORMULA: new UserFormulaDialog(ptr, s, oldSelected, fractal_functions, wasMagnetType, wasConvergingType, wasSimpleType, wasMagneticPendulumType, wasEscapingOrConvergingType, wasMagnetPatakiType); @@ -4956,6 +5105,7 @@ else if(Settings.isRootSolvingMethod(s.fns.function)) { } else { options_menu.getConvergentBailoutConditionMenu().setEnabled(false); + options_menu.getConvergentBailout().setEnabled(false); optionsEnableShortcut(); } break; @@ -4963,6 +5113,7 @@ else if(Settings.isRootSolvingMethod(s.fns.function)) { if(s.isMagnetType() || s.isEscapingOrConvergingType()) { options_menu.getConvergentBailoutConditionMenu().setEnabled(true); + options_menu.getConvergentBailout().setEnabled(true); } setFunctionPost(oldSelected, wasMagnetType, wasConvergingType, wasSimpleType, wasMagneticPendulumType, wasEscapingOrConvergingType, wasMagnetPatakiType); @@ -5029,7 +5180,15 @@ public void setBailoutPost() { Fractal.clearReferences(true, true); - redraw(); + redraw(false); + } + + public void setConvergentBailoutPost() { + + Fractal.clearReferences(true, true); + TaskDraw.USER_CONVERGENT_BAILOUT = s.fns.convergent_bailout * s.fns.convergent_bailout; + redraw(false); + } public void setBailout() { @@ -5039,6 +5198,13 @@ public void setBailout() { } + public void setConvergentBailout() { + + resetOrbit(); + new ConvergentBailoutDialog(ptr, s); + + } + public void setRotation() { resetOrbit(); @@ -5204,22 +5370,31 @@ private void startingPositionInternal() { resetOrbit(); setOptions(false); + s.startingPosition(); + if(MyApfloat.setAutomaticPrecision) { - long precision = MyApfloat.getAutomaticPrecision(new String[]{s.size.toString(true)}, new boolean[] {true}); + long precision = MyApfloat.getAutomaticPrecision(new String[]{s.size.toString()}, new boolean[] {true}, s.fns.function); - if (MyApfloat.shouldSetPrecision(precision, true)) { + //if (MyApfloat.shouldSetPrecision(precision, true, s.fns.function)) { + Fractal.clearReferences(true, true); MyApfloat.setPrecision(precision, s); - } + //} } - s.startingPosition(); - if (s.size.compareTo(new MyApfloat(0.05)) < 0) { tools_menu.getBoundaries().setEnabled(false); boundaries = false; tools_menu.getBoundaries().setSelected(false); } + if(s.size.compareTo(MyApfloat.MIN_DOUBLE_SIZE) < 0) { + tools_menu.getOrbit().setSelected(false); + tools_menu.getOrbit().setEnabled(false); + orbit = false; + toolbar.getOrbitButton().setSelected(false); + toolbar.getOrbitButton().setEnabled(false); + } + progress.setValue(0); scroll_pane.getHorizontalScrollBar().setValue((int) (scroll_pane.getHorizontalScrollBar().getMaximum() / 2.0 - scroll_pane.getHorizontalScrollBar().getSize().getWidth() / 2.0)); @@ -5281,14 +5456,14 @@ public void setSizeOfImagePost(int image_size) { this.image_size = image_size; + setOptions(false); + if (!s.d3s.d3) { TaskDraw.setArrays(image_size, s.ds.domain_coloring, s.needsExtraData()); } main_panel.setPreferredSize(new Dimension(image_size, image_size)); - setOptions(false); - if (!s.d3s.d3) { progress.setMaximum(image_size * image_size + 1); } @@ -5551,24 +5726,51 @@ else if(thread_grouping == 3 || thread_grouping == 4 || thread_grouping == 5) { tasks[i][j] = new BoundaryTracingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, temp_xCenter, temp_yCenter, temp_size, temp_max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, FAST_JULIA_FILTERS, fast_julia_image, PERIODICITY_CHECKING, s.fs, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, temp_xJuliaCenter, temp_yJuliaCenter); } } else if (TaskDraw.GREEDY_ALGORITHM_SELECTION == DIVIDE_AND_CONQUER) { - if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { - tasks[i][j] = new MarianiSilverColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, temp_xCenter, temp_yCenter, temp_size, temp_max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, FAST_JULIA_FILTERS, fast_julia_image, PERIODICITY_CHECKING, s.fs, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, temp_xJuliaCenter, temp_yJuliaCenter); - } else { - tasks[i][j] = new MarianiSilverDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, temp_xCenter, temp_yCenter, temp_size, temp_max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, FAST_JULIA_FILTERS, fast_julia_image, PERIODICITY_CHECKING, s.fs, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, temp_xJuliaCenter, temp_yJuliaCenter); + if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new MarianiSilver3ColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, temp_xCenter, temp_yCenter, temp_size, temp_max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, FAST_JULIA_FILTERS, fast_julia_image, PERIODICITY_CHECKING, s.fs, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, temp_xJuliaCenter, temp_yJuliaCenter); + } else { + tasks[i][j] = new MarianiSilver3Draw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, temp_xCenter, temp_yCenter, temp_size, temp_max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, FAST_JULIA_FILTERS, fast_julia_image, PERIODICITY_CHECKING, s.fs, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, temp_xJuliaCenter, temp_yJuliaCenter); + } + } + else { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new MarianiSilverColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, temp_xCenter, temp_yCenter, temp_size, temp_max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, FAST_JULIA_FILTERS, fast_julia_image, PERIODICITY_CHECKING, s.fs, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, temp_xJuliaCenter, temp_yJuliaCenter); + } else { + tasks[i][j] = new MarianiSilverDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, temp_xCenter, temp_yCenter, temp_size, temp_max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, FAST_JULIA_FILTERS, fast_julia_image, PERIODICITY_CHECKING, s.fs, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, temp_xJuliaCenter, temp_yJuliaCenter); + } } } else if (TaskDraw.GREEDY_ALGORITHM_SELECTION == SUCCESSIVE_REFINEMENT) { - if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { - tasks[i][j] = new SuccessiveRefinementGuessingColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, temp_xCenter, temp_yCenter, temp_size, temp_max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, FAST_JULIA_FILTERS, fast_julia_image, PERIODICITY_CHECKING, s.fs, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, temp_xJuliaCenter, temp_yJuliaCenter); - } else { - tasks[i][j] = new SuccessiveRefinementGuessingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, temp_xCenter, temp_yCenter, temp_size, temp_max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, FAST_JULIA_FILTERS, fast_julia_image, PERIODICITY_CHECKING, s.fs, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, temp_xJuliaCenter, temp_yJuliaCenter); + if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new SuccessiveRefinementGuessing2ColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, temp_xCenter, temp_yCenter, temp_size, temp_max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, FAST_JULIA_FILTERS, fast_julia_image, PERIODICITY_CHECKING, s.fs, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, temp_xJuliaCenter, temp_yJuliaCenter); + } else { + tasks[i][j] = new SuccessiveRefinementGuessing2Draw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, temp_xCenter, temp_yCenter, temp_size, temp_max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, FAST_JULIA_FILTERS, fast_julia_image, PERIODICITY_CHECKING, s.fs, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, temp_xJuliaCenter, temp_yJuliaCenter); + } + } + else { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new SuccessiveRefinementGuessingColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, temp_xCenter, temp_yCenter, temp_size, temp_max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, FAST_JULIA_FILTERS, fast_julia_image, PERIODICITY_CHECKING, s.fs, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, temp_xJuliaCenter, temp_yJuliaCenter); + } else { + tasks[i][j] = new SuccessiveRefinementGuessingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, temp_xCenter, temp_yCenter, temp_size, temp_max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, FAST_JULIA_FILTERS, fast_julia_image, PERIODICITY_CHECKING, s.fs, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, temp_xJuliaCenter, temp_yJuliaCenter); + } } } else if (TaskDraw.GREEDY_ALGORITHM_SELECTION == CIRCULAR_SUCCESSIVE_REFINEMENT) { - if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { - tasks[i][j] = new CircularSuccessiveRefinementGuessingColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, temp_xCenter, temp_yCenter, temp_size, temp_max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, FAST_JULIA_FILTERS, fast_julia_image, PERIODICITY_CHECKING, s.fs, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, temp_xJuliaCenter, temp_yJuliaCenter); - } else { - tasks[i][j] = new CircularSuccessiveRefinementGuessingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, temp_xCenter, temp_yCenter, temp_size, temp_max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, FAST_JULIA_FILTERS, fast_julia_image, PERIODICITY_CHECKING, s.fs, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, temp_xJuliaCenter, temp_yJuliaCenter); + if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new CircularSuccessiveRefinementGuessing2ColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, temp_xCenter, temp_yCenter, temp_size, temp_max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, FAST_JULIA_FILTERS, fast_julia_image, PERIODICITY_CHECKING, s.fs, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, temp_xJuliaCenter, temp_yJuliaCenter); + } else { + tasks[i][j] = new CircularSuccessiveRefinementGuessing2Draw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, temp_xCenter, temp_yCenter, temp_size, temp_max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, FAST_JULIA_FILTERS, fast_julia_image, PERIODICITY_CHECKING, s.fs, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, temp_xJuliaCenter, temp_yJuliaCenter); + } + } + else { + if (TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA) { + tasks[i][j] = new CircularSuccessiveRefinementGuessingColorsAndIterationDataDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, temp_xCenter, temp_yCenter, temp_size, temp_max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, FAST_JULIA_FILTERS, fast_julia_image, PERIODICITY_CHECKING, s.fs, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, temp_xJuliaCenter, temp_yJuliaCenter); + } else { + tasks[i][j] = new CircularSuccessiveRefinementGuessingDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, temp_xCenter, temp_yCenter, temp_size, temp_max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, FAST_JULIA_FILTERS, fast_julia_image, PERIODICITY_CHECKING, s.fs, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, temp_xJuliaCenter, temp_yJuliaCenter); + } } } } else { @@ -5577,9 +5779,12 @@ else if (TaskDraw.GREEDY_ALGORITHM_SELECTION == CIRCULAR_SUCCESSIVE_REFINEMENT) } else if (TaskDraw.BRUTE_FORCE_ALG == 1) { tasks[i][j] = new BruteForce2Draw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, temp_xCenter, temp_yCenter, temp_size, temp_max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, FAST_JULIA_FILTERS, fast_julia_image, PERIODICITY_CHECKING, s.fs, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, temp_xJuliaCenter, temp_yJuliaCenter); } - else { + else if (TaskDraw.BRUTE_FORCE_ALG == 2) { tasks[i][j] = new CircularBruteForceDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, temp_xCenter, temp_yCenter, temp_size, temp_max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, FAST_JULIA_FILTERS, fast_julia_image, PERIODICITY_CHECKING, s.fs, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, temp_xJuliaCenter, temp_yJuliaCenter); } + else { + tasks[i][j] = new BruteForceInterleavedDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, temp_xCenter, temp_yCenter, temp_size, temp_max_iterations, s.fns, ptr, s.fractal_color, s.dem_color, FAST_JULIA_FILTERS, fast_julia_image, PERIODICITY_CHECKING, s.fs, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.exterior_de, s.exterior_de_factor, s.height_ratio, s.polar_projection, s.circle_period, s.inverse_dem, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.js, s.pps, temp_xJuliaCenter, temp_yJuliaCenter); + } } tasks[i][j].setTaskId(taskId); tasks[i][j].setUsesSquareChunks(thread_grouping == 0 || ((thread_grouping == 3 || thread_grouping == 4 || thread_grouping == 5) && m == n)); @@ -5589,7 +5794,11 @@ else if (TaskDraw.GREEDY_ALGORITHM_SELECTION == CIRCULAR_SUCCESSIVE_REFINEMENT) if(tasks[0][0].hasCircularLogic()) { CircularBruteForceDraw.initCoordinatesFastJulia(TaskDraw.FAST_JULIA_IMAGE_SIZE, tasks[0][0].usesSuccessiveRefinement()); if(tasks[0][0].usesSuccessiveRefinement()) { - CircularSuccessiveRefinementGuessingDraw.initCoordinatesFastJulia(TaskDraw.FAST_JULIA_IMAGE_SIZE, false); + if (TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + CircularSuccessiveRefinementGuessing2Draw.initCoordinatesFastJulia(TaskDraw.FAST_JULIA_IMAGE_SIZE, false); + } else { + CircularSuccessiveRefinementGuessingDraw.initCoordinatesFastJulia(TaskDraw.FAST_JULIA_IMAGE_SIZE, false); + } } } else { @@ -5665,16 +5874,16 @@ public void setColorCycling() { resetImageAndCopy(s.d3s.d3, false); - if(!TaskDraw.hasExtraData(image_size) || s.ds.domain_coloring) { + if(TaskDraw.hasExtraData(image_size) && !s.ds.domain_coloring && !s.requiresRecalculation(false)) { + createTasksPalettePostProcessAndFilterWithAAData(TaskDraw.APPLY_PALETTE_AND_POST_PROCESSING_WITH_AA_AND_FILTER); + } + else { if (s.julia_map) { createTasksJuliaMap(); }else { createTasks(false, false, false, false); } } - else { - createTasksPalettePostProcessAndFilterWithAAData(TaskDraw.APPLY_PALETTE_AND_POST_PROCESSING_WITH_AA_AND_FILTER); - } calculation_time = System.currentTimeMillis(); @@ -5730,6 +5939,9 @@ else if (!TaskDraw.GREEDY_ALGORITHM && TaskDraw.BRUTE_FORCE_ALG == 2) { else if (!TaskDraw.GREEDY_ALGORITHM && TaskDraw.BRUTE_FORCE_ALG == 0) { tasks[i][j] = new BruteForceDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.max_iterations, ptr, image, s.fractal_color, s.dem_color, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.fs, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.ds, s.gs.gradient_offset, s.contourFactor, s.fns.smoothing, s.gps, s.pps); } + else if (!TaskDraw.GREEDY_ALGORITHM && TaskDraw.BRUTE_FORCE_ALG == 3) { + tasks[i][j] = new BruteForceInterleavedDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.max_iterations, ptr, image, s.fractal_color, s.dem_color, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.fs, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.ds, s.gs.gradient_offset, s.contourFactor, s.fns.smoothing, s.gps, s.pps); + } else { tasks[i][j] = new BruteForce2Draw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.max_iterations, ptr, image, s.fractal_color, s.dem_color, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.fs, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.ds, s.gs.gradient_offset, s.contourFactor, s.fns.smoothing, s.gps, s.pps); } @@ -5741,7 +5953,12 @@ else if (!TaskDraw.GREEDY_ALGORITHM && TaskDraw.BRUTE_FORCE_ALG == 0) { if(tasks[0][0].hasCircularLogic()) { CircularBruteForceDraw.initCoordinates(image_size, false, true, tasks[0][0].usesSuccessiveRefinement()); if(tasks[0][0].usesSuccessiveRefinement()) { - CircularSuccessiveRefinementGuessingDraw.initCoordinates(image_size, false); + if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + CircularSuccessiveRefinementGuessing2Draw.initCoordinates(image_size, false); + } + else { + CircularSuccessiveRefinementGuessingDraw.initCoordinates(image_size, false); + } } } else { @@ -5779,6 +5996,9 @@ else if (!TaskDraw.GREEDY_ALGORITHM && TaskDraw.BRUTE_FORCE_ALG == 2) { else if (!TaskDraw.GREEDY_ALGORITHM && TaskDraw.BRUTE_FORCE_ALG == 0) { tasks[i][j] = new BruteForceDraw(action, tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.max_iterations, ptr, image, s.fractal_color, s.dem_color, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.fs, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.pps, s.ds); } + else if (!TaskDraw.GREEDY_ALGORITHM && TaskDraw.BRUTE_FORCE_ALG == 3) { + tasks[i][j] = new BruteForceInterleavedDraw(action, tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.max_iterations, ptr, image, s.fractal_color, s.dem_color, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.fs, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.pps, s.ds); + } else { tasks[i][j] = new BruteForce2Draw(action, tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.max_iterations, ptr, image, s.fractal_color, s.dem_color, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.fs, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.color_blending, s.post_processing_order, s.pbs, s.gs.gradient_offset, s.contourFactor, s.gps, s.pps, s.ds); } @@ -5790,7 +6010,12 @@ else if (!TaskDraw.GREEDY_ALGORITHM && TaskDraw.BRUTE_FORCE_ALG == 0) { if(tasks[0][0].hasCircularLogic()) { CircularBruteForceDraw.initCoordinates(image_size, false, true, tasks[0][0].usesSuccessiveRefinement()); if(tasks[0][0].usesSuccessiveRefinement()) { - CircularSuccessiveRefinementGuessingDraw.initCoordinates(image_size, false); + if(TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM > 0) { + CircularSuccessiveRefinementGuessing2Draw.initCoordinates(image_size, false); + } + else { + CircularSuccessiveRefinementGuessingDraw.initCoordinates(image_size, false); + } } } else { @@ -5818,7 +6043,7 @@ else if(thread_grouping == 3 || thread_grouping == 4 || thread_grouping == 5) { for (int i = 0; i < tasks.length; i++) { for (int j = 0; j < tasks[i].length; j++, taskId++) { TaskSplitCoordinates tsc = TaskSplitCoordinates.get(j, i, thread_grouping, n, m, image_size); - tasks[i][j] = new BruteForceDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.max_iterations, ptr, s.fractal_color, s.dem_color, image, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, color_cycling_speed, s.fs, s.color_blending, s.post_processing_order, s.pbs, cycle_colors, cycle_lights, cycle_gradient, color_cycling_adjusting_value, s.ds, s.gs.gradient_offset, s.contourFactor, s.fns.smoothing, s.gps, s.pps); + tasks[i][j] = new BruteForceDraw(tsc.FROMx, tsc.TOx, tsc.FROMy, tsc.TOy, s.max_iterations, ptr, s.fractal_color, s.dem_color, image, s.ps.color_cycling_location, s.ps2.color_cycling_location, s.ps.color_intensity, s.ps.transfer_function, s.ps.color_density, s.ps2.color_intensity, s.ps2.transfer_function, s.ps2.color_density, s.usePaletteForInColoring, s.fs, s.color_blending, s.post_processing_order, s.pbs, s.ds, s.gs.gradient_offset, s.contourFactor, s.gps, s.pps, ccs); tasks[i][j].setTaskId(taskId); } } @@ -5887,7 +6112,7 @@ else if(thread_grouping == 3 || thread_grouping == 4 || thread_grouping == 5) { public void shiftPalettePost() { updateColorPalettesMenu(); - updateColors(false); + updateColors(false, false); } public void shiftPalette(boolean outcoloring) { @@ -5984,7 +6209,7 @@ public void setBailoutTestPost() { Fractal.clearReferences(true, true); - redraw(); + redraw(false); } @@ -6056,7 +6281,7 @@ public void setOutColoringModePost() { infobar.getGradientPreview().setVisible(true); } - redraw(); + redraw(false); } public void setInColoringMode(int temp) { @@ -6095,7 +6320,7 @@ public void setInColoringModePost() { infobar.getGradientPreview().setVisible(true); } - redraw(); + redraw(false); } public void setSmoothingPost(boolean recalculate) { @@ -6120,10 +6345,16 @@ public void setSmoothingPost(boolean recalculate) { options_menu.getProcessing().updateIcons(s); if(s.needsChangeOfSmoothing() || recalculate) { - redraw(); + if(s.canSkipCalculatedAreas()) { + s.old_max_iterations = s.max_iterations + 1; + redraw(true); + } + else { + redraw(false); + } } else { - updateColors(false); + updateColors(false, false); } } @@ -6199,7 +6430,7 @@ public void setExteriorDistanceEstimationPost() { options_menu.getProcessing().updateIcons(s); - redraw(); + redraw(false); } public void setJuliaMapPost(boolean julia_map, int julia_grid_first_dimension) { @@ -6844,6 +7075,7 @@ public void increaseIterations() { if (s.max_iterations == MAX_ITERATIONS_NUMBER) { return; } + s.old_max_iterations = s.max_iterations; s.max_iterations++; setOptions(false); @@ -6852,7 +7084,13 @@ public void increaseIterations() { whole_image_done = false; - resetImage(); + if(s.canSkipCalculatedAreas()) { + resetImageAndCopyOnChangedIterations(); + } + else { + resetImage(); + } + if (s.d3s.d3) { ArraysFillColor(image, Color.BLACK.getRGB()); @@ -6876,6 +7114,7 @@ public void doubleIterations() { if (s.max_iterations * 2 <= 0) { return; } + s.old_max_iterations = s.max_iterations; s.max_iterations *= 2; setOptions(false); @@ -6884,7 +7123,12 @@ public void doubleIterations() { whole_image_done = false; - resetImage(); + if(s.canSkipCalculatedAreas()) { + resetImageAndCopyOnChangedIterations(); + } + else { + resetImage(); + } if (s.d3s.d3) { ArraysFillColor(image, Color.BLACK.getRGB()); @@ -6906,6 +7150,7 @@ public void decreaseIterations() { resetOrbit(); if (s.max_iterations > 1) { + s.old_max_iterations = s.max_iterations; s.max_iterations--; } else { return; @@ -6917,7 +7162,12 @@ public void decreaseIterations() { whole_image_done = false; - resetImage(); + if(s.canSkipCalculatedAreas()) { + resetImageAndCopyOnChangedIterations(); + } + else { + resetImage(); + } if (s.d3s.d3) { ArraysFillColor(image, Color.BLACK.getRGB()); @@ -6940,17 +7190,13 @@ public void shiftPaletteForward(boolean outcoloring) { resetOrbit(); if (outcoloring) { - s.ps.color_cycling_location++; - - s.ps.color_cycling_location = s.ps.color_cycling_location > Integer.MAX_VALUE - 1 ? 0 : s.ps.color_cycling_location; + s.ps.color_cycling_location = CommonFunctions.adjustPaletteOffset(s.ps.color_cycling_location, 1, CommonFunctions.getOutPaletteLength(s.ds.domain_coloring, s.ds.domain_coloring_mode)); if (s.ps.color_choice == CUSTOM_PALETTE_ID) { s.temp_color_cycling_location = s.ps.color_cycling_location; } } else { - s.ps2.color_cycling_location++; - - s.ps2.color_cycling_location = s.ps2.color_cycling_location > Integer.MAX_VALUE - 1 ? 0 : s.ps2.color_cycling_location; + s.ps2.color_cycling_location = CommonFunctions.adjustPaletteOffset(s.ps2.color_cycling_location, 1, CommonFunctions.getInPaletteLength(s.ds.domain_coloring)); if (s.ps2.color_choice == CUSTOM_PALETTE_ID) { s.temp_color_cycling_location_second_palette = s.ps2.color_cycling_location; @@ -6959,35 +7205,29 @@ public void shiftPaletteForward(boolean outcoloring) { updateColorPalettesMenu(); - updateColors(false); + updateColors(false, false); } public void shiftPaletteBackward(boolean outcoloring) { resetOrbit(); if (outcoloring) { - if (s.ps.color_cycling_location > 0) { - s.ps.color_cycling_location--; + s.ps.color_cycling_location = CommonFunctions.adjustPaletteOffset(s.ps.color_cycling_location, -1, CommonFunctions.getOutPaletteLength(s.ds.domain_coloring, s.ds.domain_coloring_mode)); - if (s.ps.color_choice == CUSTOM_PALETTE_ID) { - s.temp_color_cycling_location = s.ps.color_cycling_location; - } - } else { - return; + if (s.ps.color_choice == CUSTOM_PALETTE_ID) { + s.temp_color_cycling_location = s.ps.color_cycling_location; } - } else if (s.ps2.color_cycling_location > 0) { - s.ps2.color_cycling_location--; + } else { + s.ps2.color_cycling_location = CommonFunctions.adjustPaletteOffset(s.ps2.color_cycling_location, -1, CommonFunctions.getInPaletteLength(s.ds.domain_coloring)); if (s.ps2.color_choice == CUSTOM_PALETTE_ID) { s.temp_color_cycling_location_second_palette = s.ps2.color_cycling_location; } - } else { - return; } updateColorPalettesMenu(); - updateColors(false); + updateColors(false, false); } public void setUsePaletteForInColoring() { @@ -7019,7 +7259,7 @@ public void setUsePaletteForInColoring() { } } - updateColors(false); + updateColors(false, false); } public void setPerturbation() { @@ -7299,6 +7539,20 @@ public void setPolarProjectionPost(boolean polar) { s.polar_projection = polar; + if (s.size.compareTo(new MyApfloat(0.05)) < 0) { + tools_menu.getBoundaries().setEnabled(false); + boundaries = false; + tools_menu.getBoundaries().setSelected(false); + } + + if(s.size.compareTo(MyApfloat.MIN_DOUBLE_SIZE) < 0) { + tools_menu.getOrbit().setSelected(false); + tools_menu.getOrbit().setEnabled(false); + orbit = false; + toolbar.getOrbitButton().setSelected(false); + toolbar.getOrbitButton().setEnabled(false); + } + if(s.polar_projection) { if(!oldPolar) { tools_menu.getPolarProjection().setIcon(getIcon("polar_projection_enabled.png")); @@ -7454,6 +7708,7 @@ public void setDomainColoringSettings(boolean domain_coloring) { options_menu.getBailout().setEnabled(false); options_menu.getBailoutConditionMenu().setEnabled(false); options_menu.getConvergentBailoutConditionMenu().setEnabled(false); + options_menu.getConvergentBailout().setEnabled(false); infobar.getMaxIterationsColorPreview().setVisible(false); infobar.getMaxIterationsColorPreviewLabel().setVisible(false); @@ -7568,7 +7823,12 @@ public void setDomainColoringSettings(boolean domain_coloring) { whole_image_done = false; - resetImage(); + if(s.canSkipCalculatedAreas() && s.old_max_iterations != s.max_iterations) { + resetImageAndCopyOnChangedIterations(); + } + else { + resetImage(); + } if (s.d3s.d3) { ArraysFillColor(image, Color.BLACK.getRGB()); @@ -7865,6 +8125,7 @@ public void optionsEnableShortcut2() { options_menu.getBailout().setEnabled(false); options_menu.getBailoutConditionMenu().setEnabled(false); options_menu.getConvergentBailoutConditionMenu().setEnabled(s.fns.function != MAGNETIC_PENDULUM); + options_menu.getConvergentBailout().setEnabled(s.fns.function != MAGNETIC_PENDULUM); options_menu.getPerturbation().setEnabled(false); options_menu.getInitialValue().setEnabled(false); options_menu.getPlaneInfluenceMenu().setEnabled(false); @@ -7891,18 +8152,10 @@ public void updateValues(String mode) { } - public void setColorCyclingOptionsPost(boolean cycle_colors, boolean cycle_gradient, boolean cycle_lights, int color_cycling_speed, int color_cycling_adjusting_value) { - this.cycle_colors = cycle_colors; - this.cycle_gradient = cycle_gradient; - this.cycle_lights = cycle_lights; - this.color_cycling_speed = color_cycling_speed; - this.color_cycling_adjusting_value = color_cycling_adjusting_value; - } - public void setColorCyclingOptions() { resetOrbit(); - new ColorCyclingDialog(ptr, cycle_colors, cycle_gradient, cycle_lights, color_cycling_speed, color_cycling_adjusting_value); + new ColorCyclingDialog(ptr, ccs); } @@ -8014,16 +8267,31 @@ public void ThreadStats() { JScrollPane scroll_pane_2 = new JScrollPane(textArea); scroll_pane_2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + long totalPixelsCompleted = -1; ArrayList taskStatistics = new ArrayList<>(); for (int i = 0; i < tasks.length; i++) { for (int j = 0; j < tasks[i].length; j++) { TaskStatistic t = tasks[i][j].getTaskStatistic(); if(t != null) { taskStatistics.add(t); + if(t.getPixelsCompleted() >= 0) { + if(totalPixelsCompleted < 0) { + totalPixelsCompleted = t.getPixelsCompleted(); + } + else { + totalPixelsCompleted += t.getPixelsCompleted(); + } + } } } } + if(totalPixelsCompleted == -1) { + for(TaskStatistic stat : taskStatistics) { + stat.setSortMode(1); + } + } + Collections.sort(taskStatistics); long maxTime = TaskDraw.max_pixel_calculation_time.get(); @@ -8073,7 +8341,7 @@ public void ThreadStats() { if (stat.getExtraPixelsCalculated() > 0) { data += "

  • Extra Pixels Calculated: " + stat.getExtraPixelsCalculated() + "
  • "; } - data += ""; + data += "
    "; } data += ""; } @@ -8253,9 +8521,9 @@ public void savePreferences() { PrintWriter writer; try { - writer = new PrintWriter(new File("FZpreferences.ini")); + writer = new PrintWriter("FZpreferences.ini"); - writer.println("#Fractal Zoomer preferences."); + writer.println("#Fractal Zoomer " + VERSION + " preferences."); writer.println("#This file contains all the preferences of the user and it is updated,"); writer.println("#every time the application terminates. Settings that wont have the"); writer.println("#correct name/number of arguments/argument value, will be ignored"); @@ -8276,6 +8544,9 @@ public void savePreferences() { writer.println("skipped_pixels_coloring " + TaskDraw.SKIPPED_PIXELS_ALG); writer.println("mariani_silver_use_dfs " + MarianiSilverDraw.RENDER_USING_DFS); writer.println("guess_blocks_selection " + TaskDraw.GUESS_BLOCKS_SELECTION); + writer.println("greedy_successive_refinement_squares_and_rectangles_algorithm " + TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM); + writer.println("two_pass_successive_refinement " + TaskDraw.TWO_PASS_SUCCESSIVE_REFINEMENT); + writer.println("square_rect_chunk_aggregation " + TaskDraw.SQUARE_RECT_CHUNK_AGGERAGATION); int color = TaskDraw.SKIPPED_PIXELS_COLOR; writer.println("skipped_pixels_user_color " + ((color >> 16) & 0xff) + " " + ((color >> 8) & 0xff) + " " + (color & 0xff)); writer.println("periodicity_checking " + PERIODICITY_CHECKING); @@ -8290,12 +8561,14 @@ public void savePreferences() { writer.println("automatic_bignum_precision " + TaskDraw.BIGNUM_AUTOMATIC_PRECISION); writer.println("bignum_precision_bits " + TaskDraw.BIGNUM_PRECISION); writer.println("bignum_precision_factor " + TaskDraw.BIGNUM_PRECISION_FACTOR); + writer.println("bignum_initialization_algorithm " + TaskDraw.BIGNUM_INITIALIZATION_ALGORITHM); writer.println("use_threads_for_sa " + TaskDraw.USE_THREADS_FOR_SA); writer.println("bla_precision_bits " + TaskDraw.BLA_BITS); writer.println("bla_starting_level " + TaskDraw.BLA_STARTING_LEVEL); writer.println("use_threads_for_bla " + TaskDraw.USE_THREADS_FOR_BLA); writer.println("detect_period " + TaskDraw.DETECT_PERIOD); writer.println("brute_force_alg " + TaskDraw.BRUTE_FORCE_ALG); + writer.println("one_chunk_per_row " + TaskDraw.CHUNK_SIZE_PER_ROW); writer.println("exponent_diff_ignored " + MantExp.EXPONENT_DIFF_IGNORED); writer.println("bignum_library " + TaskDraw.BIGNUM_LIBRARY); writer.println("automatic_precision " + MyApfloat.setAutomaticPrecision); @@ -8303,11 +8576,13 @@ public void savePreferences() { writer.println("nanomb1_m " + TaskDraw.NANOMB1_M); writer.println("perturbation_pixel_algorithm " + TaskDraw.PERTUBATION_PIXEL_ALGORITHM); writer.println("gather_perturbation_statistics " + TaskDraw.GATHER_PERTURBATION_STATISTICS); + writer.println("gather_highprecision_statistics " + TaskDraw.GATHER_HIGHPRECISION_STATISTICS); writer.println("check_bailout_during_deep_not_full_floatexp_mode " + TaskDraw.CHECK_BAILOUT_DURING_DEEP_NOT_FULL_FLOATEXP_MODE); writer.println("gather_tiny_ref_indexes " + TaskDraw.GATHER_TINY_REF_INDEXES); //writer.println("high_precision " + ThreadDraw.HIGH_PRECISION_CALCULATION); writer.println("high_precision_lib " + TaskDraw.HIGH_PRECISION_LIB); writer.println("bignum_sqrt_max_iterations " + BigNum.SQRT_MAX_ITERATIONS); + writer.println("built_in_bignum_implementation " + TaskDraw.BUILT_IT_BIGNUM_IMPLEMENTATION); writer.println("stop_reference_calculation_after_detected_period " + TaskDraw.STOP_REFERENCE_CALCULATION_AFTER_DETECTED_PERIOD); writer.println("use_custom_floatexp_requirement " + TaskDraw.USE_CUSTOM_FLOATEXP_REQUIREMENT); writer.println("load_mpfr " + TaskDraw.LOAD_MPFR); @@ -8329,19 +8604,26 @@ public void savePreferences() { writer.println("bla2_la_threshold_c_scale " + LAInfo.LAThresholdCScale); writer.println("bla2_double_threshold_limit " + LAReference.doubleThresholdLimit.toDouble()); writer.println("bla2_convert_to_double_when_possible " + LAReference.CONVERT_TO_DOUBLE_WHEN_POSSIBLE); + writer.println("bla2_period_divisor " + LAReference.periodDivisor); + writer.println("use_threads_for_bla2 " + TaskDraw.USE_THREADS_FOR_BLA2); + writer.println("use_ref_index_on_bla2 " + TaskDraw.USE_RI_ON_BLA2); + writer.println("disable_ref_index_on_bla2 " + TaskDraw.DISABLE_RI_ON_BLA2); writer.println("always_check_for_precision_decrease " + MyApfloat.alwaysCheckForDecrease); writer.println("use_threads_in_bignum_libs " + TaskDraw.USE_THREADS_IN_BIGNUM_LIBS); writer.println("calculate_period_every_time_from_start " + TaskDraw.CALCULATE_PERIOD_EVERY_TIME_FROM_START); writer.println("mantexpcomplex_format " + TaskDraw.MANTEXPCOMPLEX_FORMAT); writer.println("use_fast_delta_location " + TaskDraw.USE_FAST_DELTA_LOCATION); writer.println("always_save_extra_pixel_data_on_aa " + TaskDraw.ALWAYS_SAVE_EXTRA_PIXEL_DATA_ON_AA); + writer.println("always_save_extra_pixel_data_on_aa_with_pp " + TaskDraw.ALWAYS_SAVE_EXTRA_PIXEL_DATA_ON_AA_WITH_PP); + writer.println("reference_compression " + TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE); + writer.println("reference_compression_error " + ReferenceCompressor.CompressionError); writer.println(); writer.println("[General]"); writer.println("save_settings_path \"" + SaveSettingsPath + "\""); writer.println("save_image_path \"" + SaveImagesPath + "\""); writer.println("auto_repaint_image " + AUTO_REPAINT_IMAGE); - writer.println("auto_repaint_image_delay " + ImageRepainter.REPAINT_SLEEP_TIME); + writer.println("auto_repaint_image_delay " + MainPanel.REPAINT_SLEEP_TIME); writer.println("use_smoothing_for_processing_algs " + TaskDraw.USE_SMOOTHING_FOR_PROCESSING_ALGS); writer.println("zoom_on_cursor " + ZOOM_ON_THE_CURSOR); writer.println("circular_draw_follows_zoom_to_cursor " + CIRCULAR_DRAW_FOLLOWS_ZOOM_TO_CURSOR); @@ -8351,6 +8633,7 @@ public void savePreferences() { writer.println("p3d_aa " + P3D_AA); writer.println("p3d_aa_samples " + P3D_AA_SAMPLES); writer.println("neon_percentage " + ColorComponent.NEON_PERCENTAGE); + writer.println("include_aa_data_on_rank_order " + TaskDraw.INCLUDE_AA_DATA_ON_RANK_ORDER); writer.println(); writer.println("[Window]"); @@ -8394,11 +8677,12 @@ public void savePreferences() { writer.println(); writer.println("[Color Cycling]"); - writer.println("color_cycling_speed " + color_cycling_speed); - writer.println("cycle_colors " + cycle_colors); - writer.println("cycle_lights " + cycle_lights); - writer.println("cycle_gradient " + cycle_gradient); - writer.println("color_cycling_adjusting_value " + color_cycling_adjusting_value); + writer.println("color_cycling_speed " + ccs.color_cycling_speed); + writer.println("color_cycling_adjusting_value " + ccs.color_cycling_adjusting_value); + writer.println("gradient_cycling_adjusting_value " + ccs.gradient_cycling_adjusting_value); + writer.println("light_cycling_adjusting_value " + ccs.light_cycling_adjusting_value); + writer.println("bump_cycling_adjusting_value " + ccs.bump_cycling_adjusting_value); + writer.println("slope_cycling_adjusting_value " + ccs.slope_cycling_adjusting_value); writer.println(); @@ -8472,7 +8756,7 @@ else if(Files.exists(Paths.get("FZpreferences.ini"))) { int temp = Integer.parseInt(tokenizer.nextToken()); if (temp > 0 && temp <= 5000) { - ImageRepainter.REPAINT_SLEEP_TIME = temp; + MainPanel.REPAINT_SLEEP_TIME = temp; } } catch (Exception ex) { } @@ -8498,6 +8782,17 @@ else if (token.equals("guess_blocks_selection") && tokenizer.countTokens() == 1) } catch (Exception ex) { } } + else if (token.equals("bla2_period_divisor") && tokenizer.countTokens() == 1) { + + try { + double temp = Double.parseDouble(tokenizer.nextToken()); + + if (temp > 0) { + LAReference.periodDivisor = temp; + } + } catch (Exception ex) { + } + } else if (token.equals("seed") && tokenizer.countTokens() == 1) { try { @@ -8539,6 +8834,104 @@ else if(token.equals("true")) { TaskDraw.STOP_REFERENCE_CALCULATION_AFTER_DETECTED_PERIOD = true; } } + else if(token.equals("include_aa_data_on_rank_order") && tokenizer.countTokens() == 1) { + + token = tokenizer.nextToken(); + + if(token.equals("false")) { + TaskDraw.INCLUDE_AA_DATA_ON_RANK_ORDER = false; + } + else if(token.equals("true")) { + TaskDraw.INCLUDE_AA_DATA_ON_RANK_ORDER = true; + } + } + else if(token.equals("use_threads_for_bla2") && tokenizer.countTokens() == 1) { + + token = tokenizer.nextToken(); + + if(token.equals("false")) { + TaskDraw.USE_THREADS_FOR_BLA2 = false; + } + else if(token.equals("true")) { + TaskDraw.USE_THREADS_FOR_BLA2 = true; + } + } + else if(token.equals("use_ref_index_on_bla2") && tokenizer.countTokens() == 1) { + + token = tokenizer.nextToken(); + + if(token.equals("false")) { + TaskDraw.USE_RI_ON_BLA2 = false; + } + else if(token.equals("true")) { + TaskDraw.USE_RI_ON_BLA2 = true; + } + } + else if(token.equals("disable_ref_index_on_bla2") && tokenizer.countTokens() == 1) { + + token = tokenizer.nextToken(); + + if(token.equals("false")) { + TaskDraw.DISABLE_RI_ON_BLA2 = false; + } + else if(token.equals("true")) { + TaskDraw.DISABLE_RI_ON_BLA2 = true; + } + } + else if(token.equals("two_pass_successive_refinement") && tokenizer.countTokens() == 1) { + + token = tokenizer.nextToken(); + + if(token.equals("false")) { + TaskDraw.TWO_PASS_SUCCESSIVE_REFINEMENT = false; + } + else if(token.equals("true")) { + TaskDraw.TWO_PASS_SUCCESSIVE_REFINEMENT = true; + } + } + else if (token.equals("square_rect_chunk_aggregation") && tokenizer.countTokens() == 1) { + try { + int temp = Integer.parseInt(tokenizer.nextToken()); + + if (temp >= 0 && temp <= 1) { + TaskDraw.SQUARE_RECT_CHUNK_AGGERAGATION = temp; + } + } catch (Exception ex) { + } + } + else if(token.equals("one_chunk_per_row") && tokenizer.countTokens() == 1) { + + token = tokenizer.nextToken(); + + if(token.equals("false")) { + TaskDraw.CHUNK_SIZE_PER_ROW = false; + } + else if(token.equals("true")) { + TaskDraw.CHUNK_SIZE_PER_ROW = true; + } + } + else if(token.equals("reference_compression") && tokenizer.countTokens() == 1) { + + token = tokenizer.nextToken(); + + if(token.equals("false")) { + TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE = false; + } + else if(token.equals("true")) { + TaskDraw.COMPRESS_REFERENCE_IF_POSSIBLE = true; + } + } + else if (token.equals("reference_compression_error") && tokenizer.countTokens() == 1) { + try { + double temp = Double.parseDouble(tokenizer.nextToken()); + + if (temp > 0) { + ReferenceCompressor.CompressionError = temp; + ReferenceCompressor.setCompressionError(); + } + } catch (Exception ex) { + } + } else if(token.equals("always_save_extra_pixel_data_on_aa") && tokenizer.countTokens() == 1) { token = tokenizer.nextToken(); @@ -8550,6 +8943,17 @@ else if(token.equals("true")) { TaskDraw.ALWAYS_SAVE_EXTRA_PIXEL_DATA_ON_AA = true; } } + else if(token.equals("always_save_extra_pixel_data_on_aa_with_pp") && tokenizer.countTokens() == 1) { + + token = tokenizer.nextToken(); + + if(token.equals("false")) { + TaskDraw.ALWAYS_SAVE_EXTRA_PIXEL_DATA_ON_AA_WITH_PP = false; + } + else if(token.equals("true")) { + TaskDraw.ALWAYS_SAVE_EXTRA_PIXEL_DATA_ON_AA_WITH_PP = true; + } + } else if(token.equals("use_fast_delta_location") && tokenizer.countTokens() == 1) { token = tokenizer.nextToken(); @@ -8792,7 +9196,7 @@ else if (token.equals("circular_compare_alg") && tokenizer.countTokens() == 1) { try { int temp = Integer.parseInt(tokenizer.nextToken()); - if (temp >= 0 && temp <= 15) { + if (temp >= 0 && temp <= 16) { TaskDraw.CIRCULAR_COMPARE_ALG = temp; } } catch (Exception ex) { @@ -9096,6 +9500,17 @@ else if(token.equals("true")) { TaskDraw.GATHER_PERTURBATION_STATISTICS = true; } } + else if(token.equals("gather_highprecision_statistics") && tokenizer.countTokens() == 1) { + + token = tokenizer.nextToken(); + + if(token.equals("false")) { + TaskDraw.GATHER_HIGHPRECISION_STATISTICS = false; + } + else if(token.equals("true")) { + TaskDraw.GATHER_HIGHPRECISION_STATISTICS = true; + } + } // else if(token.equals("high_precision") && tokenizer.countTokens() == 1) { // // token = tokenizer.nextToken(); @@ -9145,7 +9560,7 @@ else if (token.equals("brute_force_alg") && tokenizer.countTokens() == 1) { try { int temp = Integer.parseInt(tokenizer.nextToken()); - if (temp >= 0 && temp <= 2) { + if (temp >= 0 && temp <= 3) { TaskDraw.BRUTE_FORCE_ALG = temp; } } catch (Exception ex) { @@ -9496,6 +9911,9 @@ else if (token.equals("orbit_style") && tokenizer.countTokens() == 1) { } else if (token.equals("1")) { options_menu.getDot().doClick(); } + else if (token.equals("2")) { + options_menu.getLine2().doClick(); + } } else if (token.equals("orbit_show_root") && tokenizer.countTokens() == 1) { token = tokenizer.nextToken(); @@ -9634,7 +10052,7 @@ else if (token.equals("zoom_window_style") && tokenizer.countTokens() == 1) { try { double temp = Double.parseDouble(tokenizer.nextToken()); - if (temp >= 1.05 && temp <= 32) { + if (temp >= 1.001 && temp <= 32) { zoom_factor = temp; } @@ -9645,7 +10063,7 @@ else if (token.equals("zoom_window_style") && tokenizer.countTokens() == 1) { int temp = Integer.parseInt(tokenizer.nextToken()); if (temp >= 0 && temp <= 1000) { - color_cycling_speed = temp; + ccs.color_cycling_speed = temp; } } catch (Exception ex) { } @@ -9653,7 +10071,7 @@ else if (token.equals("zoom_window_style") && tokenizer.countTokens() == 1) { try { int temp = Integer.parseInt(tokenizer.nextToken()); - if (temp >= 0 && temp <= 14) { + if (temp >= 0 && temp <= 15) { CustomPaletteEditorFrame.random_palette_algorithm = temp; } } catch (Exception ex) { @@ -9678,41 +10096,61 @@ else if (token.equals("pastel") && tokenizer.countTokens() == 1) { CustomPaletteEditorFrame.pastel = false; } } - else if (token.equals("cycle_colors") && tokenizer.countTokens() == 1) { + else if (token.equals("color_cycling_adjusting_value") && tokenizer.countTokens() == 1) { - token = tokenizer.nextToken(); + try { + int temp = Integer.parseInt(tokenizer.nextToken()); - if (token.equals("false")) { - cycle_colors = false; - } else if (token.equals("true")) { - cycle_colors = true; + if (temp >= -50 && temp <= 50) { + ccs.color_cycling_adjusting_value = temp; + } + + } catch (Exception ex) { } - } else if (token.equals("cycle_lights") && tokenizer.countTokens() == 1) { + } + else if (token.equals("gradient_cycling_adjusting_value") && tokenizer.countTokens() == 1) { - token = tokenizer.nextToken(); + try { + int temp = Integer.parseInt(tokenizer.nextToken()); - if (token.equals("false")) { - cycle_lights = false; - } else if (token.equals("true")) { - cycle_lights = true; + if (temp >= -50 && temp <= 50) { + ccs.gradient_cycling_adjusting_value = temp; + } + + } catch (Exception ex) { } - } else if (token.equals("cycle_gradient") && tokenizer.countTokens() == 1) { + } + else if (token.equals("light_cycling_adjusting_value") && tokenizer.countTokens() == 1) { - token = tokenizer.nextToken(); + try { + int temp = Integer.parseInt(tokenizer.nextToken()); - if (token.equals("false")) { - cycle_gradient = false; - } else if (token.equals("true")) { - cycle_gradient = true; + if (temp >= -50 && temp <= 50) { + ccs.light_cycling_adjusting_value = temp; + } + + } catch (Exception ex) { } } - else if (token.equals("color_cycling_adjusting_value") && tokenizer.countTokens() == 1) { + else if (token.equals("bump_cycling_adjusting_value") && tokenizer.countTokens() == 1) { try { int temp = Integer.parseInt(tokenizer.nextToken()); - if (temp >= 1 && color_cycling_adjusting_value <= 50) { - color_cycling_adjusting_value = temp; + if (temp >= -50 && temp <= 50) { + ccs.bump_cycling_adjusting_value = temp; + } + + } catch (Exception ex) { + } + } + else if (token.equals("slope_cycling_adjusting_value") && tokenizer.countTokens() == 1) { + + try { + int temp = Integer.parseInt(tokenizer.nextToken()); + + if (temp >= -50 && temp <= 50) { + ccs.slope_cycling_adjusting_value = temp; } } catch (Exception ex) { @@ -9834,6 +10272,34 @@ else if(token.equals("mpir_lib") && tokenizer.countTokens() == 1) { TaskDraw.MPIR_LIB = token; } } + else if(token.equals("bignum_initialization_algorithm") && tokenizer.countTokens() == 1) { + + token = tokenizer.nextToken(); + + try { + int val = Integer.parseInt(token); + if(val >= 0 && val <= 2) { + TaskDraw.BIGNUM_INITIALIZATION_ALGORITHM = val; + } + } + catch (Exception ex) { + + } + } + else if(token.equals("built_in_bignum_implementation") && tokenizer.countTokens() == 1) { + + token = tokenizer.nextToken(); + + try { + int val = Integer.parseInt(token); + if(val >= 0 && val <= 4) { + TaskDraw.BUILT_IT_BIGNUM_IMPLEMENTATION = val; + } + } + catch (Exception ex) { + + } + } else if (token.equals("thread_grouping") && tokenizer.countTokens() == 1) { try { int temp = Integer.parseInt(tokenizer.nextToken()); @@ -9844,6 +10310,17 @@ else if (token.equals("thread_grouping") && tokenizer.countTokens() == 1) { } catch (Exception ex) { } } + else if (token.equals("greedy_successive_refinement_squares_and_rectangles_algorithm") && tokenizer.countTokens() == 1) { + try { + int temp = Integer.parseInt(tokenizer.nextToken()); + + if (temp >= 0 && temp <= 4) { + TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM = temp; + TaskDraw.setSuccessiveRefinementChunks(); + } + } catch (Exception ex) { + } + } else { continue; } @@ -9896,10 +10373,13 @@ public void filtersOptionsChanged(int[] filters_options_vals, int[][] filters_op resetImageAndCopy(s.d3s.d3, false); - if ((oldAAValue && TaskDraw.GREEDY_ALGORITHM && TaskDraw.GREEDY_ALGORITHM_SELECTION == DIVIDE_AND_CONQUER) || s.fs.filters[ANTIALIASING] || s.ds.domain_coloring || s.pps.ots.useTraps || s.fns.tcs.trueColorOut || s.fns.tcs.trueColorIn || (s.pps.sts.statistic && s.pps.sts.statisticGroup == 2 && s.pps.sts.equicontinuityOverrideColoring) - || (s.pps.sts.statistic && (s.pps.sts.statisticGroup == 3 || s.pps.sts.normalMapCombineWithOtherStatistics)) || (s.pps.sts.statistic && s.pps.sts.statisticGroup == 4)) { + if ((oldAAValue && TaskDraw.GREEDY_ALGORITHM && TaskDraw.GREEDY_ALGORITHM_SELECTION == DIVIDE_AND_CONQUER) || s.fs.filters[ANTIALIASING] || s.requiresRecalculation(false)) { - if(!TaskDraw.hasExtraData(image_size) || s.d3s.d3 || samplesChanged || jitterChanged) { + if(s.fs.filters[ANTIALIASING] && TaskDraw.hasExtraData(image_size) && !s.d3s.d3 && !s.ds.domain_coloring + && !samplesChanged && !jitterChanged) { + createTasksPalettePostProcessAndFilterWithAAData(TaskDraw.POST_PROCESSING_WITH_AA_AND_FILTER); + } + else { if(s.julia_map) { createTasksJuliaMap(); } @@ -9907,9 +10387,6 @@ public void filtersOptionsChanged(int[] filters_options_vals, int[][] filters_op createTasks(false, false, false, false); } } - else { - createTasksPalettePostProcessAndFilterWithAAData(TaskDraw.POST_PROCESSING_WITH_AA_AND_FILTER); - } calculation_time = System.currentTimeMillis(); @@ -10040,9 +10517,11 @@ public void setUserFormulaOptions(boolean mode) { options_menu.getBailoutConditionMenu().setEnabled(false); options_menu.getPeriodicityChecking().setEnabled(false); options_menu.getConvergentBailoutConditionMenu().setEnabled(true); + options_menu.getConvergentBailout().setEnabled(true); } else { options_menu.getConvergentBailoutConditionMenu().setEnabled(false); + options_menu.getConvergentBailout().setEnabled(false); } } @@ -10393,13 +10872,12 @@ public void setHighPrecisionPost() { } else { if (s.fns.in_coloring_algorithm == MAX_ITERATIONS) { - if (!s.ds.domain_coloring && !s.isConvergingType() && s.fns.function != KLEINIAN && s.fns.function != SIERPINSKI_GASKET && s.fns.function != INERTIA_GRAVITY && !s.pps.ots.useTraps && !s.fns.tcs.trueColorIn && !(s.pps.sts.statistic && s.pps.sts.statisticGroup == 2 && s.pps.sts.equicontinuityOverrideColoring) - && !(s.pps.sts.statistic && (s.pps.sts.statisticGroup == 3 || s.pps.sts.normalMapCombineWithOtherStatistics)) && !(s.pps.sts.statistic && s.pps.sts.statisticGroup == 4) && !TaskDraw.PERTURBATION_THEORY && !TaskDraw.HIGH_PRECISION_CALCULATION) { + if (!s.ds.domain_coloring && !s.isConvergingType() && s.fns.function != KLEINIAN && s.fns.function != SIERPINSKI_GASKET && s.fns.function != INERTIA_GRAVITY && !s.requiresRecalculation(true) && !TaskDraw.PERTURBATION_THEORY && !TaskDraw.HIGH_PRECISION_CALCULATION) { options_menu.getPeriodicityChecking().setEnabled(true); } } } - redraw(); + redraw(false); } public void setPerturbationTheoryPost() { @@ -10411,13 +10889,12 @@ public void setPerturbationTheoryPost() { } else { if (s.fns.in_coloring_algorithm == MAX_ITERATIONS) { - if (!s.ds.domain_coloring && !s.isConvergingType() && s.fns.function != KLEINIAN && s.fns.function != SIERPINSKI_GASKET && s.fns.function != INERTIA_GRAVITY && !s.pps.ots.useTraps && !s.fns.tcs.trueColorIn && !(s.pps.sts.statistic && s.pps.sts.statisticGroup == 2 && s.pps.sts.equicontinuityOverrideColoring) - && !(s.pps.sts.statistic && (s.pps.sts.statisticGroup == 3 || s.pps.sts.normalMapCombineWithOtherStatistics)) && !(s.pps.sts.statistic && s.pps.sts.statisticGroup == 4) && !TaskDraw.PERTURBATION_THEORY && !TaskDraw.HIGH_PRECISION_CALCULATION) { + if (!s.ds.domain_coloring && !s.isConvergingType() && s.fns.function != KLEINIAN && s.fns.function != SIERPINSKI_GASKET && s.fns.function != INERTIA_GRAVITY && !s.requiresRecalculation(true) && !TaskDraw.PERTURBATION_THEORY && !TaskDraw.HIGH_PRECISION_CALCULATION) { options_menu.getPeriodicityChecking().setEnabled(true); } } } - redraw(); + redraw(false); } @@ -10480,12 +10957,46 @@ else if (d3) { } } + private void resetImageAndCopyOnChangedIterations() { + + BufferedImage temp = image; + image = last_used; + last_used = temp; + + int[] dataDest = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); + int[] dataSrc = ((DataBufferInt) last_used.getRaster().getDataBuffer()).getData(); + int total = dataDest.length; + + for(int p = 0; p < total; p++) { + if(s.max_iterations > s.old_max_iterations) { + if (TaskDraw.image_iterations[p] != ColorAlgorithm.MAXIMUM_ITERATIONS) { + dataDest[p] = (dataSrc[p] & 0x00FFFFFF) | NORMAL_ALPHA_OFFSETED; + } else { + dataDest[p] = (dataSrc[p] & 0x00FFFFFF) | EMPTY_ALPHA_OFFSETED; + } + } + else if(s.max_iterations < s.old_max_iterations) { + if (TaskDraw.image_iterations[p] == ColorAlgorithm.MAXIMUM_ITERATIONS) { + dataDest[p] = (dataSrc[p] & 0x00FFFFFF) | NORMAL_ALPHA_OFFSETED; + } else { + dataDest[p] = (dataSrc[p] & 0x00FFFFFF) | EMPTY_ALPHA_OFFSETED; + } + } + else { + dataDest[p] = (dataSrc[p] & 0x00FFFFFF) | NORMAL_ALPHA_OFFSETED; + } + } + } + public void drawOrbit(Graphics2D g) { if (orbit_style == 0) { - pixels_orbit.drawLine(g); - } else { + pixels_orbit.drawLine(g, true); + } else if (orbit_style == 1){ pixels_orbit.drawDot(g); } + else { + pixels_orbit.drawLine(g, false); + } } public boolean getOrbit() { @@ -10534,7 +11045,7 @@ public void setColorBlending(int val) { s.color_blending.color_blending = val; - updateColors(false); + updateColors(false, false); } public void setColorBlendingRevertColors(boolean val) { @@ -10542,7 +11053,7 @@ public void setColorBlendingRevertColors(boolean val) { s.color_blending.blending_reversed_colors = val; - updateColors(false); + updateColors(false, false); } public void setColorTransfer(int val, boolean outcoloring) { @@ -10554,7 +11065,7 @@ public void setColorTransfer(int val, boolean outcoloring) { s.ps2.transfer_function = val; } - updateColors(false); + updateColors(false, false); } @@ -10600,7 +11111,7 @@ public void gradientChanged(Color colorA, Color colorB, int interpolation, int c updateGradientPreview(s.gs.gradient_offset); - updateColors(false); + updateColors(false, false); } public void setOrbitTraps() { @@ -10764,11 +11275,12 @@ public void resetSettings() { Fractal.clearReferences(true, true); if(MyApfloat.setAutomaticPrecision) { - long precision = MyApfloat.getAutomaticPrecision(new String[]{s.size.toString(true)}, new boolean[] {true}); + long precision = MyApfloat.getAutomaticPrecision(new String[]{s.size.toString()}, new boolean[] {true}, s.fns.function); - if (MyApfloat.shouldSetPrecision(precision, true)) { + //if (MyApfloat.shouldSetPrecision(precision, true, s.fns.function)) { + Fractal.clearReferences(true, true); MyApfloat.setPrecision(precision, s); - } + //} } if (!s.d3s.d3) { @@ -10825,7 +11337,7 @@ public void setProcessingOrder() { public void setProcessingOrder(int[] processing_order) { s.post_processing_order = processing_order; - updateColorsAfterPostProcessing(true); + updateColors(true, true); } public static void ArraysFillColor(BufferedImage img, int color) { @@ -10833,7 +11345,7 @@ public static void ArraysFillColor(BufferedImage img, int color) { Arrays.fill(data, color); } - public void redraw() { + public void redraw(boolean modifiedIterations) { resetOrbit(); setOptions(false); @@ -10842,7 +11354,12 @@ public void redraw() { whole_image_done = false; - resetImageAndCopy(s.d3s.d3, false); + if(modifiedIterations) { + resetImageAndCopyOnChangedIterations(); + } + else { + resetImageAndCopy(s.d3s.d3, false); + } if(s.julia_map) { createTasksJuliaMap(); @@ -10885,12 +11402,12 @@ public void setPostProcessingPost() { TaskDraw.setExtraDataArrays(s.needsExtraData(), image_size); } options_menu.getProcessing().updateIcons(s); - updateColorsAfterPostProcessing(true); + updateColors(true, true); } public void setPaletteGradientMergingPost() { options_menu.getColorsMenu().updateIcons(s); - updateColors(false); + updateColors(false, false); } public void setGeneratedPalettePost() { @@ -10921,7 +11438,7 @@ public void setGeneratedPalettePost() { options_menu.getColorsMenu().getOutColoringPaletteMenu().updateIcons(s); options_menu.getColorsMenu().getInColoringPaletteMenu().updateIcons(s); - updateColors(false); + updateColors(false, false); } public void setPaletteGradientMerging() { @@ -10931,7 +11448,7 @@ public void setPaletteGradientMerging() { } - public void updateColors(boolean skipPreview) { + public void updateColors(boolean skipPreview, boolean afterPostProcessing) { setOptions(false); @@ -10941,59 +11458,23 @@ public void updateColors(boolean skipPreview) { resetImageAndCopy(s.d3s.d3, false); - if (s.fs.filters[ANTIALIASING] || s.needsChangeOfSmoothing() || s.pps.ots.useTraps || s.fns.tcs.trueColorOut || s.fns.tcs.trueColorIn || (s.pps.sts.statistic && s.pps.sts.statisticGroup == 2 && s.pps.sts.equicontinuityOverrideColoring) - || (s.pps.sts.statistic && (s.pps.sts.statisticGroup == 3 || s.pps.sts.normalMapCombineWithOtherStatistics)) || (s.pps.sts.statistic && s.pps.sts.statisticGroup == 4)) { + if (s.fs.filters[ANTIALIASING] || s.needsChangeOfSmoothing() || s.requiresRecalculation(false)) { - - if(!TaskDraw.hasExtraData(image_size) || s.d3s.d3 || s.ds.domain_coloring || s.needsChangeOfSmoothing() || s.pps.ots.useTraps || s.pps.sts.statistic || s.fns.tcs.trueColorOut || s.fns.tcs.trueColorIn) { - if(s.julia_map) { - createTasksJuliaMap(); - } else { - createTasks(false, !skipPreview, false, false); + if(s.fs.filters[ANTIALIASING] && TaskDraw.hasExtraData(image_size) && !s.d3s.d3 && !s.ds.domain_coloring && !s.needsChangeOfSmoothing() && (afterPostProcessing || !s.requiresRecalculation(false))) { + if(afterPostProcessing) { + createTasksPalettePostProcessAndFilterWithAAData(TaskDraw.POST_PROCESSING_WITH_AA_AND_FILTER); + } + else { + createTasksPalettePostProcessAndFilterWithAAData(TaskDraw.APPLY_PALETTE_AND_POST_PROCESSING_WITH_AA_AND_FILTER); } } else { - createTasksPalettePostProcessAndFilterWithAAData(TaskDraw.APPLY_PALETTE_AND_POST_PROCESSING_WITH_AA_AND_FILTER); - } - - calculation_time = System.currentTimeMillis(); - - startTasks(); - } else { - if (s.d3s.d3) { - createTasks(false, true, false, false); - } else { - createTasksPaletteAndFilter(); - } - - calculation_time = System.currentTimeMillis(); - - startTasks(); - } - } - - public void updateColorsAfterPostProcessing(boolean skipPreview) { - - setOptions(false); - - progress.setValue(0); - - whole_image_done = false; - - resetImageAndCopy(s.d3s.d3, false); - - if (s.fs.filters[ANTIALIASING] || s.needsChangeOfSmoothing()) { - - if(!TaskDraw.hasExtraData(image_size) || s.d3s.d3 || s.needsChangeOfSmoothing()) { if(s.julia_map) { createTasksJuliaMap(); } else { createTasks(false, !skipPreview, false, false); } } - else { - createTasksPalettePostProcessAndFilterWithAAData(TaskDraw.POST_PROCESSING_WITH_AA_AND_FILTER); - } calculation_time = System.currentTimeMillis(); @@ -11111,6 +11592,7 @@ public void setFunctionPostNova() { options_menu.getBailout().setEnabled(false); options_menu.getBailoutConditionMenu().setEnabled(false); options_menu.getConvergentBailoutConditionMenu().setEnabled(true); + options_menu.getConvergentBailout().setEnabled(true); } public void setFunctionPostKleinian() { @@ -11125,6 +11607,7 @@ public void setFunctionPostKleinian() { options_menu.getBailout().setEnabled(false); options_menu.getBailoutConditionMenu().setEnabled(false); options_menu.getConvergentBailoutConditionMenu().setEnabled(false); + options_menu.getConvergentBailout().setEnabled(false); } public void setOutTrueColor() { @@ -11144,7 +11627,7 @@ public void setOutTrueColorModePost() { tools_menu.getColorCycling().setEnabled(false); toolbar.getColorCyclingButton().setEnabled(false); - redraw(); + redraw(false); } public void setInTrueColorModePost() { @@ -11257,7 +11740,7 @@ public void setJitterPost() { options_menu.updateIcons(s); - redraw(); + redraw(false); } public void setJitter() { @@ -11306,24 +11789,23 @@ public static void main(String[] args) throws Exception { SplashFrame sf = new SplashFrame(VERSION); sf.setVisible(true); - - while (sf.isAnimating()) { - } - sf.dispose(); - if(args.length > 0 && args[0].equals("l4jini")) { - CommonFunctions.exportL4jIni("Fractal Zoomer", Constants.FZL4j); - } + //SwingUtilities.invokeLater(() -> { + if(args.length > 0 && args[0].equals("l4jini")) { + CommonFunctions.exportL4jIni("Fractal Zoomer", Constants.FZL4j); + } - MainWindow mw = new MainWindow(); - try { - mw.setVisible(true); - } - catch (Exception ex) {} + MainWindow mw = new MainWindow(); + try { + mw.setVisible(true); + } + catch (Exception ex) {} + + mw.checkCompilationStatus(); + mw.getCommonFunctions().checkForUpdate(false); - mw.checkCompilationStatus(); - mw.getCommonFunctions().checkForUpdate(false); + //}); } } diff --git a/src/fractalzoomer/main/app_settings/ApproximationDefaultSettings.java b/src/fractalzoomer/main/app_settings/ApproximationDefaultSettings.java index d57dd3027..8589a8d74 100644 --- a/src/fractalzoomer/main/app_settings/ApproximationDefaultSettings.java +++ b/src/fractalzoomer/main/app_settings/ApproximationDefaultSettings.java @@ -2,13 +2,16 @@ public class ApproximationDefaultSettings { public static int DETECTION_METHOD = 1; - public static double Stage0PeriodDetectionThreshold = 0.1;//0x1.0p-10; - public static double PeriodDetectionThreshold = 0.1;//0x1.0p-10; - public static double Stage0PeriodDetectionThreshold2 = 0.5; + public static double Stage0PeriodDetectionThreshold = 0x1.0p-5;//Imagina: 0x1.0p-10; + public static double PeriodDetectionThreshold = 0x1.0p-10; + public static double Stage0PeriodDetectionThreshold2 = 0x1.0p-3; //Imagina: 0x1.0p-6 public static double PeriodDetectionThreshold2 = 0x1.0p-3; public static double LAThresholdScale = 0x1.0p-24; public static double LAThresholdCScale = 0x1.0p-24; public static double DoubleThresholdLimit = 0x1.0p-768; + public static double PeriodDivisor = 4; + public static int NthRootOption = 1; + public static int lowBound = 64; public static int SERIES_APPROXIMATION_TERMS = 5; public static long SERIES_APPROXIMATION_OOM_DIFFERENCE = 2; diff --git a/src/fractalzoomer/main/app_settings/ColorCyclingSettings.java b/src/fractalzoomer/main/app_settings/ColorCyclingSettings.java new file mode 100644 index 000000000..2ab3738a8 --- /dev/null +++ b/src/fractalzoomer/main/app_settings/ColorCyclingSettings.java @@ -0,0 +1,19 @@ +package fractalzoomer.main.app_settings; + +public class ColorCyclingSettings { + public int color_cycling_speed; + public int color_cycling_adjusting_value; + public int gradient_cycling_adjusting_value; + public int slope_cycling_adjusting_value; + public int light_cycling_adjusting_value; + public int bump_cycling_adjusting_value; + + public ColorCyclingSettings() { + color_cycling_adjusting_value = 1; + gradient_cycling_adjusting_value = 0; + slope_cycling_adjusting_value = 0; + light_cycling_adjusting_value = 0; + bump_cycling_adjusting_value = 0; + color_cycling_speed = 140; + } +} diff --git a/src/fractalzoomer/main/app_settings/D3Settings.java b/src/fractalzoomer/main/app_settings/D3Settings.java index 3409eb599..fc89a2c00 100644 --- a/src/fractalzoomer/main/app_settings/D3Settings.java +++ b/src/fractalzoomer/main/app_settings/D3Settings.java @@ -45,9 +45,6 @@ public class D3Settings { public int shade_choice; public int shade_algorithm; public boolean shade_invert; - public boolean histogram_equalization; - public int histogram_granularity; - public double histogram_density; public boolean preHeightScaling; public int fractionalTransfer; public int fractionalSmoothing; @@ -89,10 +86,6 @@ public D3Settings() { remove_outliers_pre = true; remove_outliers_post = false; - histogram_equalization = false; - histogram_granularity = 10; - histogram_density = 3; - preHeightScaling = false; outliers_method = 0; diff --git a/src/fractalzoomer/main/app_settings/FunctionSettings.java b/src/fractalzoomer/main/app_settings/FunctionSettings.java index 3c4424f6f..d0b2e162b 100644 --- a/src/fractalzoomer/main/app_settings/FunctionSettings.java +++ b/src/fractalzoomer/main/app_settings/FunctionSettings.java @@ -99,6 +99,7 @@ public class FunctionSettings implements Constants { public boolean julia; public int bailout_test_algorithm; public double bailout; + public double convergent_bailout; public String bailout_test_user_formula; public String bailout_test_user_formula2; public int bailout_test_comparison; @@ -161,6 +162,7 @@ public FunctionSettings() { nova_method = NOVA_NEWTON; bailout = 2; + convergent_bailout = 0; bailout_test_algorithm = 0; skip_bailout_iterations = 0; skip_convergent_bailout_iterations = 0; diff --git a/src/fractalzoomer/main/app_settings/HistogramColoringSettings.java b/src/fractalzoomer/main/app_settings/HistogramColoringSettings.java index 4961047ad..ec6a9def8 100644 --- a/src/fractalzoomer/main/app_settings/HistogramColoringSettings.java +++ b/src/fractalzoomer/main/app_settings/HistogramColoringSettings.java @@ -32,6 +32,7 @@ public class HistogramColoringSettings { public int hmapping; public boolean hs_remove_outliers; public int hs_outliers_method; + public int rank_order_digits_grouping; public HistogramColoringSettings() { histogramColoring = false; @@ -44,5 +45,6 @@ public HistogramColoringSettings() { histogramScaleMax = 1; hmapping = 0; hs_outliers_method= 0; + rank_order_digits_grouping = 2; } } diff --git a/src/fractalzoomer/main/app_settings/Settings.java b/src/fractalzoomer/main/app_settings/Settings.java index 4fcf8b02b..3da1dabe7 100644 --- a/src/fractalzoomer/main/app_settings/Settings.java +++ b/src/fractalzoomer/main/app_settings/Settings.java @@ -64,6 +64,7 @@ public class Settings implements Constants { public Apfloat size; public double height_ratio; public int max_iterations; + public long old_max_iterations; public double circle_period; public int color_smoothing_method; public Color fractal_color; @@ -356,12 +357,12 @@ else if (version >= 1085) { if(MyApfloat.setAutomaticPrecision) { - long precision = MyApfloat.getAutomaticPrecision(new String[]{sizeStr, xCenterStr, yCenterStr, xJuliaCenterStr, yJuliaCenterStr}, new boolean[] {true, false, false, false, false}); + long precision = MyApfloat.getAutomaticPrecision(new String[]{sizeStr, xCenterStr, yCenterStr, xJuliaCenterStr, yJuliaCenterStr}, new boolean[] {true, false, false, false, false}, settings.getFunction()); - if (MyApfloat.shouldSetPrecision(precision, true)) { + //if (MyApfloat.shouldSetPrecision(precision, true, settings.getFunction())) { Fractal.clearReferences(true, true); MyApfloat.setPrecision(precision, this); - } + //} } if(version < 1084) { @@ -438,12 +439,12 @@ else if (version >= 1085) { if(MyApfloat.setAutomaticPrecision) { - long precision = MyApfloat.getAutomaticPrecision(new String[]{sizeStr, xCenterStr, yCenterStr}, new boolean[] {true, false, false}); + long precision = MyApfloat.getAutomaticPrecision(new String[]{sizeStr, xCenterStr, yCenterStr}, new boolean[] {true, false, false}, settings.getFunction()); - if (MyApfloat.shouldSetPrecision(precision, true)) { + //if (MyApfloat.shouldSetPrecision(precision, true, settings.getFunction())) { Fractal.clearReferences(true, true); MyApfloat.setPrecision(precision, this); - } + //} } } @@ -1675,6 +1676,21 @@ else if (version >= 1085) { fs.blurringKernelSelection = ((SettingsFractals1089) settings).getBlurringKernelSelection(); } + if(version < 1090) { + fns.convergent_bailout = defaults.fns.convergent_bailout; + pps.hss.rank_order_digits_grouping = defaults.pps.hss.rank_order_digits_grouping; + } + else { + if(TaskDraw.LOAD_DRAWING_ALGORITHM_FROM_SAVES) { + TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM = ((SettingsFractals1090) settings).getBlocksFormat(); + TaskDraw.TWO_PASS_SUCCESSIVE_REFINEMENT = ((SettingsFractals1090) settings).getTwoStepRefinement(); + TaskDraw.CHUNK_SIZE_PER_ROW = ((SettingsFractals1090) settings).getOneChunkPerRow(); + } + + fns.convergent_bailout = ((SettingsFractals1090) settings).getConvergentBailout(); + pps.hss.rank_order_digits_grouping = ((SettingsFractals1090) settings).getRankOrderDigitsGrouping(); + } + if (fns.plane_type == USER_PLANE) { if (version < 1058) { fns.user_plane_algorithm = defaults.fns.user_plane_algorithm; @@ -2156,7 +2172,7 @@ public void save(String filename) { userCode = userCode.replaceAll("\\b" + Parser.DEFAULT_USER_CODE_CLASS + "\\b", Parser.SAVED_USER_CODE_CLASS); } - SettingsFractals settings = new SettingsFractals1089(this, TaskDraw.PERTURBATION_THEORY, TaskDraw.GREEDY_ALGORITHM, TaskDraw.BRUTE_FORCE_ALG, TaskDraw.GREEDY_ALGORITHM_SELECTION, TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA, userCode, TaskDraw.GUESS_BLOCKS_SELECTION); + SettingsFractals settings = new SettingsFractals1090(this, TaskDraw.PERTURBATION_THEORY, TaskDraw.GREEDY_ALGORITHM, TaskDraw.BRUTE_FORCE_ALG, TaskDraw.GREEDY_ALGORITHM_SELECTION, TaskDraw.GREEDY_ALGORITHM_CHECK_ITER_DATA, userCode, TaskDraw.GUESS_BLOCKS_SELECTION, TaskDraw.SUCCESSIVE_REFINEMENT_SQUARE_RECT_SPLIT_ALGORITHM, TaskDraw.TWO_PASS_SUCCESSIVE_REFINEMENT, TaskDraw.CHUNK_SIZE_PER_ROW); file_temp.writeObject(settings); file_temp.flush(); } catch (IOException ex) { @@ -2595,6 +2611,7 @@ public void defaultFractalSettings() { case MAGNET_PATAKI4: case MAGNET_PATAKI5: case MAGNET_PATAKIK: + case FORMULA48: xCenter = new MyApfloat(0.0); yCenter = new MyApfloat(0.0); size = new MyApfloat(6); @@ -2625,6 +2642,8 @@ public void defaultFractalSettings() { } fns.period = 0; + fns.convergent_bailout = 0; + TaskDraw.USER_CONVERGENT_BAILOUT = 0; } public void createPoly() { @@ -2662,7 +2681,7 @@ public void createPoly() { } } - public boolean hasConvergentBailoutCondition() { + public boolean hasConvergentBailout() { return (isConvergingType() || isMagnetType() || isEscapingOrConvergingType()) && fns.function != MAGNETIC_PENDULUM; } @@ -2905,7 +2924,6 @@ public static boolean isThreeFunctionsNovaFormula(int nova_method) { return nova_method == NOVA_HALLEY || nova_method == NOVA_PARHALLEY || nova_method == NOVA_SCHRODER - ||nova_method == NOVA_HOUSEHOLDER || nova_method == NOVA_HOUSEHOLDER || nova_method == NOVA_LAGUERRE || nova_method == NOVA_WHITTAKER @@ -2980,7 +2998,7 @@ public static boolean isRootFormulaFunction(int function) { public static boolean isMagnetPataki(int function) { return function == MAGNET_PATAKI2 || function == MAGNET_PATAKI3 - || function == MAGNET_PATAKI4 || function == MAGNET_PATAKI4 + || function == MAGNET_PATAKI4 || function == MAGNET_PATAKI5 || function == MAGNET_PATAKIK; } @@ -3016,6 +3034,7 @@ public void applyStaticSettings() { TaskDraw.palette_incoloring = new PresetPalette(ps2.color_choice, ps2.direct_palette, fns.smoothing, special_color, color_smoothing_method, special_use_palette_color, fns.smoothing_fractional_transfer_method).getRawPalette(); } + TaskDraw.USER_CONVERGENT_BAILOUT = fns.convergent_bailout * fns.convergent_bailout; TaskDraw.palette_outcoloring.setGeneratedPaletteSettings(true, gps); TaskDraw.palette_incoloring.setGeneratedPaletteSettings(false, gps); @@ -3089,7 +3108,15 @@ public boolean supportsPerturbationTheory() { || fns.function == MAGNET_PATAKI2 || fns.function == MAGNET_PATAKI3 || fns.function == MAGNET_PATAKI4 || fns.function == MAGNET_PATAKI5 || fns.function == FORMULA47 || fns.function == PERPENDICULAR_MANDELBROT || fns.function == BUFFALO_MANDELBROT || fns.function == CELTIC_MANDELBROT - || fns.function == PERPENDICULAR_BURNING_SHIP || fns.function == PERPENDICULAR_CELTIC_MANDELBROT || fns.function == PERPENDICULAR_BUFFALO_MANDELBROT); + || fns.function == PERPENDICULAR_BURNING_SHIP || fns.function == PERPENDICULAR_CELTIC_MANDELBROT || fns.function == PERPENDICULAR_BUFFALO_MANDELBROT + || fns.function == FORMULA48); + } + + public static boolean usesPerturbationWithDivision(int function) { + return function == MAGNET1 || function == NEWTON_THIRD_DEGREE_PARAMETER_SPACE + || function == NEWTON3 || function == NOVA || + function == MAGNET_PATAKI2 || function == MAGNET_PATAKI3 + || function == MAGNET_PATAKI4 || function == MAGNET_PATAKI5 || function == FORMULA48; } public boolean isPertubationTheoryInUse() { @@ -3130,10 +3157,29 @@ public boolean needsChangeOfSmoothing() { return requiresSmoothingCalculation() || requiresUnSmoothingCalculation(); } + public boolean canSkipCalculatedAreas() { + return !d3s.d3 && !ds.domain_coloring && !julia_map && !fs.filters[ANTIALIASING]; + } + public boolean supportsBilinearApproximation() { return (fns.function == MANDELBROT || fns.function == MANDELBROTCUBED || fns.function == MANDELBROTFOURTH || fns.function == MANDELBROTFIFTH) && !fns.burning_ship && !fns.julia; } + public boolean requiresRecalculation(boolean ignoreTrueColorOut) { + + if(ignoreTrueColorOut) { + return pps.ots.useTraps || fns.tcs.trueColorIn + || (pps.sts.statistic && pps.sts.statisticGroup == 2 && pps.sts.equicontinuityOverrideColoring) + || (pps.sts.statistic && (pps.sts.statisticGroup == 3 || pps.sts.normalMapCombineWithOtherStatistics)) + || (pps.sts.statistic && pps.sts.statisticGroup == 4); + } + + return pps.ots.useTraps || fns.tcs.trueColorOut || fns.tcs.trueColorIn + || (pps.sts.statistic && pps.sts.statisticGroup == 2 && pps.sts.equicontinuityOverrideColoring) + || (pps.sts.statistic && (pps.sts.statisticGroup == 3 || pps.sts.normalMapCombineWithOtherStatistics)) + || (pps.sts.statistic && pps.sts.statisticGroup == 4); + } + public boolean supportsBilinearApproximation2() { return fns.function == MANDELBROT && !fns.burning_ship && !fns.julia; } @@ -3186,7 +3232,7 @@ public boolean needsPostProcessing() { ) && !useDirectColor; } public boolean needsExtraData() { - return fs.filters[Constants.ANTIALIASING] && (needsPostProcessing() || TaskDraw.ALWAYS_SAVE_EXTRA_PIXEL_DATA_ON_AA); + return fs.filters[Constants.ANTIALIASING] && ((TaskDraw.ALWAYS_SAVE_EXTRA_PIXEL_DATA_ON_AA_WITH_PP && needsPostProcessing()) || TaskDraw.ALWAYS_SAVE_EXTRA_PIXEL_DATA_ON_AA); } } diff --git a/src/fractalzoomer/main/app_settings/ZoomSequenceSettings.java b/src/fractalzoomer/main/app_settings/ZoomSequenceSettings.java new file mode 100644 index 000000000..4616cb65e --- /dev/null +++ b/src/fractalzoomer/main/app_settings/ZoomSequenceSettings.java @@ -0,0 +1,55 @@ +package fractalzoomer.main.app_settings; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import fractalzoomer.main.Constants; +import org.apfloat.Apfloat; + +public class ZoomSequenceSettings { + public double rotation_adjusting_value; + public int color_cycling_adjusting_value; + + public int gradient_color_cycling_adjusting_value; + + public double light_direction_adjusting_value; + public double slopes_direction_adjusting_value; + public double bump_direction_adjusting_value; + public int zooming_mode; + + public int zoom_every_n_frame; + + public double zoom_factor; + + public boolean flipSequenceIndexing; + public long startAtSequenceIndex; + public String sizeStr; + + @JsonIgnore + public Apfloat size; + + public double aspect_ratio; + + + public ZoomSequenceSettings() { + size = Constants.DEFAULT_MAGNIFICATION; + sizeStr = size.toString(); + + aspect_ratio = 1; + + zoom_factor = 2.0; + flipSequenceIndexing = false; + startAtSequenceIndex = 0; + + rotation_adjusting_value = 0; + color_cycling_adjusting_value = 0; + + gradient_color_cycling_adjusting_value = 0; + + light_direction_adjusting_value = 0; + slopes_direction_adjusting_value = 0; + bump_direction_adjusting_value = 0; + + zooming_mode = 0; + + zoom_every_n_frame = 1; + } +} diff --git a/src/fractalzoomer/native/linux-x86-64/libmpfr.so b/src/fractalzoomer/native/linux-x86-64/libmpfr.so index 04c6559d2f9c14f2ffb57046e8b97d46af19eca4..e33e64c831fefa53653f08046358da024df1834f 100644 GIT binary patch delta 286222 zcmZsE30zjy^Zvc4i3^D*TvS}wSyE%uV8fkdKLJ!X<< zS!PjGnoDZ0W{R49skBI?$QEBRi%QED_4mx3xpCtEKOcvC-+AWD%$YOi+;dk8pC3`Q zbwqBYpTGaw_C0D9&NK}wg==SZs-3ku!2Xf7dhPb;+QxN;jO%O9{~qSPR?o(&Znw0s z*~S*@7jsRcf}!^vd8OUy)00m8vmtlSv4eZ-{PV-x>-{Rs>cxqf?X1k|*Zc}Y-+sKt z_kPxF|GFNk`Vwdt=v7bw$SJR5r%-;piS1jU-Jm_7cR>3=?}Dft0v!fW85^OJkz66zlE`h!QeFwS>qT&Nx z1yz841v%w6*}0DG@1Q^A_n&0{Z~5VD{*j%V*xquO*xm-2=#Ofk>e4SYu=SVyI@kt) z?v&qw*wzO%1T_H#fr3F)La+@5HTB?63s6f?7>G(M*|w2w1h#EKk)V#CXb_bcY`cQG zfx3fwfMP+tK)peIKz%_};$+)Twr*?(fb94W5@w=ohhaM$lmr?jJW?_m`*(rHfyRR- zf+m5Sau4=XLHB~vKvO}}Kzf;u-!nk7Ko6L({~&f|gXV$KK?^_&L5o0C7Gt|q_8-Rf z5!qjc?GvEopcSAeK`TL2R$==TC=-+=JmTlbelE6a?R~W0!p?foMvww+0zC_&vKiaw zK>46;pdFxHpaM`KXg7$;JF?v;+x^%c1RVk$7T$Z<9+7>ja}@jUQ~w_WeE>QEIte-j z`Vd6r47UFReGK|kc*H-4{m($3gGz+|1-9p9pJXm#zZCQ(s0{QS=rYJDKJ0tS@#ja- zPXhdmZH4Urg6%cX@1Q?He}Qg-Zi7reM~z|lVZS=42B;>eHmD9L0Hl{Y@w+~#0jMFU zk)P4pXpEgEpkRwk`dv`hKCFFzmJhwE;zd+Jf4F^wJ)`JAk4=F`&*Mr*y%7 zH&Ay_4^U4~ET|W#4~R-X+4jda9yAb?z&v}L7=!U65i|@m9Fzn~28{;Y1sVrR0a2MG z+k3H{3`zq{0Zj!_xnH(3u$={ZKzz1zOl-42+4B2oY;!=*fYt~v7u$6pOMa7{4cLE{6h8;rq5*l>-zLAe zWBa0py@dUjK|3|xF6_Um{U+rF^80n!zNz7FV}Cd39gt@){u~4y0UZUs4>|@q0itpe z+cTj5fr>#NgQ$Fh?OD({&}YK?T()0edl6Iyx&-=RkR&=Rx_P?VuMxPT7I|mq9y0 zuYh)eobnp>-vGS@+6~$R;)4F)iy!+y`$6x54uYKWp6nly?J;aW03Da#C$K#U`cQsT zy))P^27RjWi2s@V{v6v9+5dvVbslsP^rbMr!uFEvQ$;G@;`eu;%OD@<3g{|`%FozV zfPMk}D!gmhUI+aSx&itNq?fNvDC@ifJ53y=%c8q@~V7Ss;Z9^{k`*zX965?(a6ok3mXcUNq?fqKaAp4j%5 zeMd(ee)kuio3~b-MzuTxs>lt*@4*@`5&OeHBSFcaF`%&^D&w#nFZ&a)y&E)9eow;o z9?)d@Jyo{%VLJ^p12nTbmSMB7GY2#eJkW&h< z{|4wy&|4bc!FPkVNBHkxyB~BAbO_`H@iJJXkAQI$^gieq=mdz$N!flVTjHI;{{KK9 zgFXR$2BPwXY|mqR0dx^m2Kol{9mpx)WB)S9ZvT(i`4#jV=y%YcAS!=h`#0z&=$7z| z8aS$esQAgY8n)FzH9&WOYJzHkYJ=*4>VobB1%eua8i5*vPbrhV81VKzk<E#5 z_7wh8)Ar_G@hP_#P@}Hlnp?-_(1M#vjY#HK;vQuFdHv^7q$beqjLG zgz}Q`+e9-zKdCmcJ;n*zpfu>iK-%kU*k39<-dYr8-(kyz*nhD)i(-Dv5L=N^B>ZQ3 zGCzGZ>!EXFDi8HwzV{%@ceC{)Pj19Bkk-fF7GxL)yl%{|2x3Kax=Cf)K;{R=v3vlt zjhcg)pT8STN0~4Dhuxw_v38f-dh|x&+;8iqpe-#pAHNpf6kGhbtske zzRWkaTdO-qc=||gX5?~xnuVzN_hT{dQ|zCUv#W!dpSzKcb65e|f3XG{&HR{eIA6J3Ks^OtZNCkgskb2}PF@CNIx zt`VLY6Gi!_ciI9-F1z>(zv4LaR|@}4>C+5JnqGG>@N5k0DK@zY+-10`6VCknqb%qI zJcK)_WDXky5}?BxdQdAb+TJ0&#-o^ z#6@S0D9P-k5h2RUOg8GA`)!mE2bM6ObsENWxN8rQo9s7w-7X7-pXOt}b3yGp7=nB? zqvC}1NcV`|Tf1<5qmcEUmA?DCz3>|`zo&%DC#jwMl6Ag&MA$6(8TbWfI$C9y&MvN= zZ-w<}>p9})U;k8@p=vi}epwMa>Ep^qLzx-#+j27pAYZ6NhO&Ij3ih%Cvki{~E%^bS z(CG39mB)~FG_Fqc2r*-UyW{MT#|5x%GghTg~K^s3|zG0V@G+4*K?>wN=EFK z8N~RA-KQ&WROU7lch2u99&3+K7A`?!AfP)-g^pkKvMOZlD;r zCda(O3v8fV_@7BUl0!Kj7?O5b;;i3RvpijJrSgo7jIvqWtuvWztRKM+xyO(^mO~E; z&{QJfl{^a+{_tU3!8?={Wnhw^(oH6d!hxJ;n0D=wDMKu`7dsR$4$XA3`zlBJ8cD;x zu{T@{e8Drdv*7y>T~1w)ah<#10a0{EGV{|;utQJSX0gggb&@ZWOJ?t}I-{;LAm}U$ zjRALawfv5pOBf+`@%S@8kgorr zgp0a%DKbV^@fbx4*=2Y~mM=VwP@;Tl|HY|~xK+5@cFU^SuUDPd6UEi)wXNa(+W3Xu zZ7t{*?O7yC#QZloTON>3+bijt+lu3rE~AD_8{^&bQ>8c8&8$=_-HWm(;wk(eMv&_>S*R?{A9607I5ymTqlx2l=@cSqI$rhL*KrFSd%-L18Qu^O@BpzF(`JgZQVn5qIRBBGy7i zxA&a2F1}yyoFoi;??cJEms6FoYIAG2>?oVRW$Yecq8-~h^4lHl9V|kqC*yYLLHs51Z zyw8Bh8~+U93dyf=gb@q7bVA5%!+&$^oU?*B%m>6z?#l-~j9I(wW!5buC?4$ znYxXIZJD2Tjoo#Le2km<-&S#VI}!vbmVJ6B(OzhHg`C;z)eh)MI*RE{%~u| zpa@TI1dPtv-SLar}!(*ODEl4k+jX-j3%J$5HnX~^^yB4 zcQ+0TcIhM|D^NxjMu}a#&T;7kH(4(OV1mqlG5fgzbitEKDiW0XrK}DLJfD7YcVrr0g@pLkZ4wGeAbPtyXvqXuM2;X%nSLCvmbN=gvvabGY?i7P%m)4 zPc+=)*<+VD{#YwEV7NH*(pirY(U|#Z*Emv*B#^(kn4cjABrlCU){(@Z+6$az@cY)K z#OS-dwK*DV#aQRjT-hz>zt3}W8i^B`A9#|dpC#hN0#v8q6<0a0eA}8ev}Kp{4(!@a zG=a+5P?q-oz)6?LY$IIy#=X)yFf@8<@=9*0lVby9N-3*ifVbN2KeOxVvrHpF{3p>#6&Fzr8o2*3ijGESoOpk{n;$59!E!??ATMLp-N@A$DF|;LxB0 z?6SzJpVTR=FGe(>=_9$;7(sW)0U*Pgk~GBQmHTm*#ovLFx`mfGnI05d2P6k$wsBNn zX4uGWE57~4$%J09OPI*J+Oqt^!p|JU@~-oCQZ_WkiJ}WKQoUJL?~xInr5z-m?{hre zQops#w;5Bo7bggRzNA}BUyj;9@%u$*5KQJlaDYQ)WW=x^Y1LVt9_gWS9C<{Sq`n$i z-_zHb^FL;p9EnjD8cC5&u9A9N+A%+OF1Hyj*<}}oKgrv->cB}BTdU=eR&g))(A~nH zz&+tTMx4&jD zoU?@UqSTN%d#~s@9mU2nhOr(etta!yHVS!Qdkm-fbtGqF6xkooy9P(=qehnCQ&9_dC9_(>R zB67U2RCCsNa^*fn>iyl8_2oasevRPnH{OH$WT%jx?Lom|%`R)>neVEy7TYPTwL1`N3r`?xqnlM*?ac7+{HxB2La z7o_X#2S>m}K<#qEB^AoK#f8G(gTo6c%7|l!oHM{9l1drtI5f^sy&}0Sx++}`aY`fY?(sdPmtV?jI%MdmlNLSHN=pimDEhH7wd-GV^#ccZ# zCUP}>F$<0teqLMFlfQsFY`z5g0Sr=-kNF>u8D8$<2?-uL!;JhZ+yTzm*^|H(Dni+z zbq(0UDCqz?xi>m6@(g4sw`(>{4oN8{g8; zIAa|h9}$v}%qm=md6fMr5#M8(6MELljpODmv*IW8?-Kaof1`F*63DQ)dC_9v6Nr&p z?l|kM3H@3flXH?B@t(VcpM9}o^^nydCBn0|J=ZEc$^y;+QOxE6%p&t7&Ht?L&*+%Fwa?vYS`Cqqd zV4^@%?G}z<+h>G7Pnzm|h&wh!Y|N5_(ec47pDOZ$M~F|cw)|a2YXP=mon;&Tj8njQ z<|JM6uJ94=ij^`q?!-}yb}lA@*N9b|rn5-`BQlEtwSN zNgc$p?iw8bMUsOVa(Z3yGWVDB%)@5MZ1*OXcOC_p6v=whcd-JwrDnX;iuw6*oLeJh z4AT8n_}IV*mRsr0NMB;LyJwWgEe}gwktP|#SWTJS1A}*VnIP)Rs*Lb~U0B}zB)jR{ zuV2`m`DvdqU#?Ocy@xVC_W?U?JjRFIY$IFpxj30Cq>Dp+WeUlcM<4DHhZ07KfrmK% z+?e*LTn}S@V116mMoEe5j{G^6=f#@`53x$;mgTeLbTRyr5@EUa*tsm z+ckP%nMujuZqCW@lil~Y7AuFmvLUR;Y1s1ikf*0+lK$r(_3l~bwp16hA^<>sPKvK> zvpBJlxi97%M}poYp|TDsLh>0cI9Hr?FP@XM`CfV<1Lakbe@JrZl$RS2V54}(St4EN zk*jkt0t7c>MQ(XmGLG#Smu2FH6F2+>Us=Tc*HCvd-B5g%KJiS8qu4y7{Ftd(9&m+N89 z!TyN^mN#m$;AMvnnS7mh(CP&KR+3cM&Zrq3r1=f%&+TBFYFERzX$J?FL%6?Oduy@CC zg&28c0G)1^)7Ji}E&Xz{t@Bd{cga7)-84+VW@rmp3H+4#-^c{He6;YdT4U}T+$Cl; z^Xcs#DkFz8oV$%PL;`NSC(f-LYn{3;!rX8Da$iu`tJ3nad3Ef{_lT0$5Kyx1wc1T< z+bRj!O~2fCu+;M+^+^Nf7k^?cm=-;yu*!2$g&_>*H)apl*d}oI5Ah;($&Fc^b7dzG zVIjWjNA{c^IH$5m#!jGRPVeMNzsTvGZ)13T7Rsqs+5w&v1_-}fOXgR|y-4Q->O?j5F`CITlm3JA>#zkJqv`t zQuyw(*00keJduvxA{JXEVq@iu(l`96dR0be zvaI5rd&!TAo(ehLOG14rDe<Mf1V-Iw+1)!i zPmCrKvf|&Y)ia`}mdP#iL7XVY2jaE&4o;{IGW^OV$aD8_$zv#;E!>r=zrKT6^oj%od@6 z)7e%$Plv|at=N`PZ2dYj!ZQ_WC@$W2rO8secNp_yHgi%a8SUMr3CX#vR+iVsNr|sZ zo*=`VV3$xA>v73>p7fLP530ki$H;h+dz@Zsr1Dg6u8=F&QJfy9celvVz-*3ne-=09 z3}Ajtl?z0T6PTa>6L)EbwEv}E%&#b=IRZy{=V6^2&ZI)GnxM#RU^I1eg|aG3iiur? z-x1bvb%D63t zD>|^@ODt|YEDdne3pyyy^@D`*)?W{_@Z>(jS?Ekxd6GBAEY6!`QQuxpy30;uYC<{6 z+Kd%#*&SDvwc9PppyJ`|PE*lSA(O7L%5Ij&eovMZ4wXO@PUQAFft&1R13y*?G`*@$ zame-K92_c{GSnpw-Oqe_S(3_|l8O~IIBpnRDCp^#GAz?&;%;ICxHcTlipnl=gd&jR zR4&LGEnS{VV>5_|=!qG_V`G9uXa^=ey4F-C4@*TxvYx~6pg|I~U>>`Oh}oreJR7cC zWwJUtjQN4%I6^Xg81y6^MWT4Ib!m1)$ahE~J23KmoXkE(mK8RqlV^{lNnua!m)FH; zSrpfD-Nnl9m2h5@D`*)LIBd=fkAcHQUQRa=UAs(_baT-=VJJ?z{nFi*uV%PDus)d+ zQTv)iG2?>eH#d4%x=aufV*0BwS`~i{N+5N-6Bu#M38(2z2S>8 zMEFDGNE1k}sG`)BrfubAxwSXF^VAr+`-Sq7U^RQOF82n`wzt@nkvf9;#d418jG;j? zNYl1gxAiz+foRA}Z_YHnN=8ye6ZYy?@v5!x^IJ3DIcI7&hRwU>VRUCfw?Z-_w}ahk zkFj1lhC0aZcKQwh$}KVQFmlJ{r*f(nOPJ~oWWKjb`{qcPD&)X4Nv4wXGF!#$<#31D z`Z2^8O3zok!vGS*E;l7p3iol#rU`$k7B_6p1u@pFrENXI6KGBf zF}(6>l{0duONSK7d8T8nmbh&M^C5Pwc=4(FxB8 z944LFYXZjxkDg6uMg3)V*dW1l=lnOA5z?mO*=!NBs9iRTf&8PKOOAn4R@Nh(JS7Mf zHKVW@N4i{U6*$`DF_8VjUkNX4d5QGH;#Ct_TUN+9Ess%rcqNME-2++w!=fjS`2+B_ z0t3$TK%K{Og$#L40dt;Ro*2h`<4Yd3KVpeapRQCFzz4$iv2CE_1<;2LT5 ztW%Fh^iGW9pI#Z8KS+ly=Rg~Qxg2NbU7ep1UTP^G0B`?T#OTY2C;d!+g~i^k$Mz>l zc)jvKIbHvta<`0~!bLnqIJ4+j$%8U$+hakYfgf_GJj9iZPwy5dFIb;E7VVe*q~*6P zqRY`<%q=_2Rmk-yWQJY3kFzE&YcVXQ2B(_y7||4&B#e7F~4Hv3EX3vkF~Aeh2<+{q=Z6?`cCxZDS*?${hcGH&GkN&5M?F+lx%4>KVJNiJpkw zBa--Mqx~!C;i1?g4;m`k(Rjgz9koR_U#4fj-*#Bj9BelhHob*L%H zlO)I5~FX2gxVZWT4AkT(N`-)l5 zG>K;+!a(h=SZurNF?#XzV0@k+1`cyNJS+~al4P&2ScAmRxR%KB#ogI3;$W9Jml%+E zIBUIIl64vLxq~uoY3uM4wFekgE>!IwD6S0P2`W}X_kCODr^&)KjA0`f56CQU;Ypvt zO?7U?MfYHFua}4KY*CZZS@;*3@7(MAa{%)Tt1PpQj$pp~LC(yM+)yL1JM)d-Y<_zq zT7UsEV3I%MlyIK<{{XS0*ymawFAusq?GmH#(k|`}G=ACCGsa_W^<!cdh~FXrGpZgpUm&B z(W;nBxy+M+by<-!BTW`}E94c+;JPe74_!nC-0~1Wmgw0i({jeo+!rmROHN4WGydcN z{bV}?W!de-qq){6D_;`poLaJCNtYGNLt@V#>c|i03u$R0pN9S+e&AA$ zY@YbhK)O1)26y%AJl`14bhPCM;${!0AlhM<4g*+GewAw&sWP0>ZnL7*VmNucbzoI= z?eAs%g5mb-s%VdkzBYv-bB1wi7;BA@`zTn*+vOu^PP$CAa_Vbrmi{l}_ul^fT+ulR zOJFJYa}h_^_z?X{%}?jG{Q%=lG2kc1J=X$mW-m$gGUO*!$heRBKZ~M^;*iVw`lzi;Srql;?lg*h)+d?$Jbr^&EI)w#ZYHh!yA|^dd5qUt zZC7i}{6OJ5-SfU=r!kWqNS9835$8g7wxzLRCp+nhFU+denyk*Az;8J=_wmN4Crb|R zldKCXQ@czb&#_6H%(3x`jZ3m-aLLWoHX?ubU2MCo%IiZPK*08iFAX*P_YvEUG6@&P zSz}iBtKCBS)D>=RULE22syA2j9+NH;^F0SLzoN?VsmloF-z!TQiL6m1?v{0AJtsNx zMju(?IG-`QQ<|}TsI8}|k<8B<890R4WuqKR%3iW2W=D8_5kGRHc;r4UaceJK>6LY< z<42UFX5ku+`vcOREkmT8t67g+1Twyp5#?ISDd>E=;~SUwmtJKeXy}Y6+$?-LqE)Q{ ztT&^ISW8TJ)E({t*3_pXJOgFEb%k(voX2jPN_dKK&47v%o?1Obtt=;C)Gl8PV*a3p z9Nz=NFGF?PoVX#=oY9%b`9!1eZm#f`RM;wU%9kPRr2OH#Sy9FJ?8<5Z8ptvuP+oJs zB6`+ZQ*v51t=PlSUdJ2biBQpE_*>8Av@t!_k(`!zHTLVAppfD>xUV9)#r6ln$n|`y z{xd;C^AEF%7e#;9Hmu3pkmud)QmeBBuA)ldiX;#**8FFJJh}21x--zqkYMhisMVc%sqNUb)X{7f6XZPF&3@nkOciAlt7A=gZ zOp-xv6mzqk4|fE~>2Vt09rhR)40gFNkljt2$SsSIe*LW#^J7NCZ2tVm zdyD){WDoUihP+qiq~%O!kjvv&9qe|%-Q}oH6^gT114gY~Qf2&j{s#V97T@acPN}@oyv_cS6aX1cB;Lz153w*SnbzF z56yprom#@ZWE>7-*d_11(MSEL+>o5jkgN15%rwX}D(CLoq`~4- zsMX4f_T*OM=+k$0snnDF%s9a6`pcyKhxB6FSIl>Y<;&9a3VA}Oj_4_sgHygdSc!<* z#Y$lFuHklfPcpj5fEhJb{E`R0I!gt5F3j$!hgdT@)Gm1u%ukbVEjjnYwvH16O|16o zBgXs{#Xr5nxGSAYs&!+SKTei=&T713IP*W14^ug3SK%`K#H_crua9W8LXKg9i#coG zlx8=Q#i#cL>xcCbA;02aLC$B$GbQ+G7d-Q|p_6B{99fLR>|1?_b-lZ|R+-E-aMdoO zC7tqn@SGy|-i(?u#b?kbKvCogY~y}$GXF_-QjX8YS^T86(dQfL_X;1xw({j;1lL)$ zahLR~S5jIM(fCBtD#Hrf*mme`nG1{n&I;$I-pxj=weVMtOEYQNHR+sUxlixJV~MqP zV@pp)mErRil7^xevypT3?|OFgjLh!LPdmqPGer9-i9=!6>b77KZ;UUIGqxU?1e~@^ z?8W@R9NT-3{Uuzg83TJ%A=k?RZ7sd)ley9**Q%T=c7c&1zlNjNj)$BPAxFltDo4g8 zGG^T)Ic$7|!g^hWwrVKDz>v$j2(Vq!Bo^)<>j#DBQ0XhNC^GpQV`X;FJ;$!XuwB+q z6wl=T?LgtjI(&IDZi(=Jk(N|E$a+eJKLQ~%a;Xldz^XXHAxBMMb__( z0B>7c9=){GI`wRHJ68)%jXSyDjAsY1zO*X#i>$ECE&W`ZtpS@OJok;UU%@iu+1P)V zFf(NGa#v%c&YjIqMQLsorBfu|y!W#_ALH=}R0*#8c@A!j45W=bX?lzpxhmv5$y6N1 zUZ=~Ytw(ufYJZuC22634FS-@Wj8!2whMh^huQ*y*WvPBuW+QI{iZT`u=>i8)xKzo_{}gf4WrLVZE|ti06{D z>TH!()pE1ai&gma5-b^W%Oix&8gaTz%C4K$ZT)q5WAwvv#~wUSasN8+Sl#a=XW%t! zL0)vIOTIl?B;Ms?ERmg3}(J-Hcv01GJK~?x4W~f zFm_x9w6A%eBko zI*GI98;iWN(@-S7o$}M_XL@lD`e`&%xsr-G8G4o<(Yhrs5>fY zlhKVE1u?sP*pBrV&*LbgEp}38mEnO@>-(}YYV(> z9e5$4wkcU$c*^?W1>8HJ516B5urg!v0FjoX6n7Q`WZ9c5pJ{ntoZ2t*LjGAEEN|P| za0Py-w4odGotJxmmXYs%&gOfJonp9$(`b1WQRZl4Vj?TbILQ{}D;CB{S;H7FvWw+n z_@E?sWR=NcHxAeKxR7-_WrKYbdn1Mc;}2HkT#=(ssZxa)`hRLr#>=#^MUGPW|6_UQ z`*8o0<3(|mSKF!NVmU{KEB@q!aGvvR(w_Nc z@}Lk07N0Gb4mRppmv%(dZXyjey1(7vrOzU*(;qczG%^h z^y%qp*>4S+2UkVr&RfLj*VP&}QaL9Y)PKAB|C;nwZqwv1*_&9RX1u12Q=Ro|H=@VyFnl7@$gW@A_)UH<4xNQ?R5NbM??oZ>+s~*q z$>>D-jKccdbvz##hFk7t?W@8!7N}Eo%$K^vwB&wDmRsOXy=37#x5gcQpi6D9YqmF| z)tS0xP{;`B6*9e4Oi)6Y>L$TqG9MBg+?YKhc&UmC0Q{vS4Z$fIyiBDM{Jo}plLl{8 zIe^WpYDa+CDTMwL38w@%skE_KT_q*II~cYp8vLSaekb4>TJ25$fs+Wn6XVV)B^ta} zEhD&r)_~xkO51m-0)h`{4M@@8G*t@NJgTnWi3WV6xlp1>rK`AlQ1XFeAKT#IN*fE* z9D?Pn$reh{;KeGB;IA|nHfeB&F8r*y5FAozW37q`gpyx17g97hPo)xk zON+uL4Zf*z2p+B}FVWyz>QJEB$u!kflA5e3NeQiVVS;L2AMibTJ2d!Sl|=CS8eF2m z7{`FkkJN_xXl9A#NlMd78;__`Qc|onbCU)?rUDuOmRm8lP>BYwP;mtRtho@}tWx=x zYEA<*^Cy)@Qt?_dH)&E=)fs{ZX-Y~o_#btXVCPF)MFtWdA_%!kfOmEs(B+sxCs;fMDn82@*)r;47+>;Qm@OH)-%sDxfi%`MZj145=ionZd5g zcKo5{5Ik0EW{L*iq4Efxq&0Js1_!D$1kcc1DAC}C>L$4`Lq#=#)O*}Q`)^8Er3*7u zD#0IV9&Xa$*(!(NPc;uqG2pPHjk;5!Dy!Q7AR>+*Q5&68Ir20z9XqmwB{_0V1H=^6{4a-V5)~^ zDpP}xsnifOXP(L-sVuGQcWP37)FHs;9(4}FAs=f}MVeG=)jSkR$~3q{g9}trC`@%# z%SfuD=FkmIYN{$A*k6PF+g3IwUzL)QohqOy912uznwmq*Hfl~&Fz-=$V20#tRa3O8 zt<@QVozGBEIA>~bpt?!0EPDwxmTK^R71azjf>dfVNd2hU*rZAIQaL2GOC2Jq$F!lc zPm|iAt`cl&aFGVzRLz?Mc0Qy}o|I_tWt9Zjyjx9gj?QrIERoa=O)69skdp424gbi> zIMz_51k>yNP6^iFH&s9jw8O39T0qLV(@2uBn$$EkhhTrrMxqASRe1zY)@-C`@HTaZ zVCRz~qmQQ)xnl#-GHSU|5X*$64j29yp&9Vsd-0LD#6aVIZ15NYQLdyAGMSD zt2#tdKF#xen$&W2m0-C6WLqiH;FnZ$mpLRvE-KluPlL~>WiHfSr;W%P8hk(%5FDVv z{_QGz=Bz4p!9zb45C*9PEqIZd)Ik+T@O%x9)!>b44#7RO_9bfY?HZT;)YiHx+);}3(a%? z_Lcqdu_^^@maFTn5hUkH7}64{Nu5-2;fTTnH76Xp{?v3OYEqL_9^imX&CwL~W*ek= zNw`@z0i^0c~%YN6*fc&VlpryS93%qAfj8lI`)w^S-jglyBC+N8l)8xj1L z9T@(zQ-g!mA%a_IwfAZ8Jfv_XteL|EOj3YpyDYKvj99%vSB+fg?+Q zm#R{NU)3}R3rt5Y%<*lZ6iUk%RG;Oi=t;MX+en>6@6l|yj0);l{jc!WAc@F^_{ z`!u+*x*CZn{H2<=!v<^qb`W+R${~wBO*mLBBREoX^o9n1s|pD2t)-uT$I48cv#OoL-J_;oc0u(?95Y>#f-quEH&q)w?bq-3wAWTpl` zr*0Dbh1P(j8thV09RSM{Id*qsYVgY{6|lKoE$(1;QWx9dz_L?=cc??)oBPyNQu3SD zA4QtfXR3Kez!$UzlxT2WmDCYRiq$fbD%PZKXj1J}0l^tsJN%<6JK_yh3fTNxU5Bm^ z=Y4T%PoyT*Ma4xy$t}B`{3lj}F%=P&2qG;4< zjxN=d+*VQ1Q1YqfLZ-mfnom_K!K1V&Y|?74QaJ?wPjg|X2LG%M5&WnI@6+HSb(P?= zn(ZPDj#16AS_`o>&r3A8gGwSeL4$n)ljjL)8Nu?rif!VCR$Hk8f;VWc`A1jwpIem@ z?0l4sst0TEM=Br&@SmFPNP$VmpDK=E=W}vYJ65Z`Rm~wdR2w3R8oWp45iD=BP-P?K zKkylXH*2+LYVcfjli=xEk1f^UJ}Rm+vf{WJ)EQZER#UP`lj^K;AQf`ZHqL)`YVZwp zh~T%h=I_(s_tjN`{WRr88jOjs3t;C34N_mC!7Wr0V6%pr-US}MqqXCPNKtnGqY6j~ zeZ<2l{+%lOudgcYVy-cZ)SRx6nyD#C)TF*vc?2)kk|0Hc7pgM^J0BP!J2N%-H+8cs zCW_iBsvD$^Xu-%7De~utN(F3oRExWzIbUm@?9_A}REJ2(+nOi)H25oZm0&NqAf-ry zi&XROu(3gP?+zQOnkQxbIVQyVRxJZ;j!^{=4tYiM#Bf(i;k1}w`j2a!5~#s1tAHMW zcWbaqgX2^j!RIyQF&ex_%^~;`%|o{a4_0{u%R^YU`D6|LK%MD<1{_y6N$O?IM!F`| zSVi>&9H80A(BQo)wI`JLs~kv~oz)Kf3i-xqDz=51a3^(@bcJZTyc&E&HID`StQL%7 z4PK>^2)>{xFVo-@wT$3bH02c;|tuoYHUclN@H zvauGWVEP_93f=ztPQ~?t_P4b06RE*H)Et6aYjCUvw^DfoU)Gc-YVa9#hTso1-%>Pq zzq$z+BfN2Mb8<*~O)6898mDr4LrFai-lV};)B-jG)VbbR3XJH3rNBN7PE^hNp!Qm= zc98}TR!M-(wQ71FbpJI?%BM-?sRF>}6je&Pp3pkVzjI|MUr+&kA$3B<^@Y^)T1+A} zscu1(gt~fJ1q@`wUsV2BsrN%+e zs~ViC!Lw8j!TmHdn>4tgIz;d%wtM_%rv^__SL4u>XH@fkkjl|)6lqeaDybi&nyY0b zYYmRo;OZ)m;Fem_CTcLQ zQUf+$P~Y{3#fMd6H@d#5CcIP=o~KgX(A7-Kj7$ygp>hD54b=`PFFTZN+NTNo zRP%V~l9$o#cou2!Qk6t-N3B&Q8thZc;$fqYDxl4DRZ7D0^*>vef7i+gRj7agfa_>( z2WxPEiX(WvW-3yHtE)K!U?WlGk<=raRH7!eM4cgczt-9m4K7hP3I0^8JyV0HtEhp1 zmut0`YVbQM6|nh*T09UDZKWyMq)C0C4v~^5P03CTuBNV{Htw-CPk_{DEf__bR6mtO z@I6}omS}L8T1K!>gMAvDrV0pNsCjrpgBz++f)8l6{kv86(_s}b2+bU*+6;oD+tfI0 zLRxFOVm0CCR33ywqBS^CgFjYh2yUdoDH{B?x=C=P2G7*sWh!bg;A5JjOEq}EN+o!d z24`yUH!6qVj#`j5X)q>ffOtsD1g@CMa<2;j#x+eI4ux=JGW3$1pE z2KQ9U2p+A$J`Jv|3J5OK;2Rp;UzGwjd#dY0&@&h9fyRG=yH|GOOcj?1CG;|aQzA8Z zkeWmARIT~38hk+I5j;$T6E(PnIs@38rM^pq3(o&bN_J*yQpZ))P)PZyK|>*xr+Jd8 zN!_7xAQj?#D~XhB(qLTMLv6FZx=Ok}S2cz~*PB{siZtQBRnjo%`bRTWqQOVhGJ-u? zO87K*uqq%}z9CDF7&kQdm?|Z>lcwCiM`gf2Qvt&PAJ;+_tieC3xZ!BWay5sfe$W~a zt4VoP9$@oTwFkl>k7~M7G^sn(O;Ylj=E+PAuA`zx0PdnSbEyV5QKs=Sf7rr1?|2jP%m zTDQ#9q;gf%D8yvA8Z-)0-893Qn$%k=2T~!2wMK8!;NR6Df^TUyc4}~@x(emy{i=B~ zq~v=*cJCBvQm0f>GNkTP%Sh@U8|ObhP3mJ+KvLUODM_u?Ec(Y*25O567!9dYDsD8S z$~9e)np872hv3edl2{G?NaYb+SBr0=1}{=)2tKL7DH=RU-6R*jR#9Uh6{baQsV1dV zD!~KvxNGpkDu>_|8oWt^aXSXExkjBEgU*|$+1RH^#jECbLCJ$!GmA8MvPvTOPt8V& z2Ir||1k0Bq>`3}FxUniAc)u3n8ycLVN(qkFZ2R}B?59yGU@YLLG&op;kE=L>KiA+$ z4K7o22!2-cJXVAEsXT&fYaNuR!6E7l!BaIjMT7gQn*?vtf;v-!Jt}G(;MX+UOEtKK zN+r0t=6R+Dk5D-TZ_(gQ8eFUn5j;?HZKnqRpstQXYSmWF$3yB@&4nUOYMn|N52?4+ zGLm{zYllyhnxzT|UZa`1p}{!e1#C`N*P$ziSyt*;++~Cr>+9VmGK&P!!~^d$tgve)CrXY*zBv8 z-3?t$v`G6jsfSeo!J9NCH#GRVDkZp$*4h4jDtq9H3YZ93UjMhf2-e`vDh_a{^Itm> z9;v}b4K;V78Ew{6d8Fk_&Ba7b><4v*VCRdUq$NdzKU6mfen{)6nHv1LikgIAWvfAx z5UjD9jZ95yvC4r|i1Rcv+1RAP*VQ3XvP7LDCHn}LvQLx3lPve(FgjbaQKG>ws%7`U z#(AeIwmuEMTNMy|O$+r64GvPJq`W{=9^ALGCswMsRMe*L7CR+UgU_is1mD)WIaY%& zsXT(|f2(myq6TkKX9#YuDNoVhNOhCoSDdQY&eY(ZD(YUq&T9Z9wN!&It5kx=YW@-mTRx(%`cyiQqyuNmW}59_4W6Uo2oBWXNDV%$<^VRktCja57!hg@HX-vh;S^2y zGj)@6m1>^M)Zp$aY8qg-R(q)iA5y6V57ppI4Zfsu2p*{gX_E%`QilkhtHC=p_%3yo z;QKY@`!u*hHJ=VRLi4;xgTGNpfYrt6X5BkWG`>+yJw6>*oG)uueHy-16--CizE`EF z9#E=D`Kz_}Lu2s$cz~jbcCHgFH!tXV_2()MG9kk>pCdK+88wICE1J)-8jPdK{jlw) z&XCk>O-YI-)kxhWxI}|zYVc_lH3RUw8oX44i&W|i*mzFmkknQ!K{shq6VxG+!ZQJo z@|#+HZ~d9(#G3DgBjxYPl77nV2;A+a<7eMbDTO&*l7OZr|PL;$_({8AE@qEW(&Vb z_4ck(<|(tr5k(87ODNunoaxs`5n8rX_jG} zSV=O}bLG#a8-`Qmv{ZR)-#)?;kCgRK>~&)CZq;eC*(~tN#(%j(dmUSxsj5F`hBr-v zBB@_*$S9vy@;rE4sm%WGVC1xK=#wH=_FJEXWJF|Z#%;Yp4zC6G<9FP1= z%!zv%`@Yq`Xj;FzrD-j~kAMA0?Dc-VmEK!w?`E@k^=&{@*|TONkGja(dq8_a)~ST7 zpGIW;;d?^3WishK%(!^q|@6)=<2*jxeraf}J@*Af2<@O@){w84{jSNSj< z1ppq$zV9Hw>_y@J_BSyob(&th?YW(};<4};BR=a`y(h=KXc~#x3E?p-{A-sF!Vf_H z#-gbIRJx4B((1IRtW&GJK7O1?2=}KRxpFezJ_}FC`kibQNCZ-=kd}$n`{wB)A?xu2;ukW%l=z=A{~PQdPGJ5A z#D5oj+svSqzt>wi6`kcC1s#NLP7pvKYC%&q5Er5L6_A~>t)ag94 zS*;Jh=7x_@6?tZp9tB_AzFnSt0ZEe6cnY;1uk%t@yg(*gFaiFH#P>2koA~~!@AGD` zXEN%hBxLStt+ z+bL7?>z|Y0iSoG(Ay7FrD`8Ind(g^n7vI5^HHpRO7pmAD5}1MzvP2A_$*8x|TQ93C z9tn>B<6?OSY@yZT90+W+$I9p9a(kt*4#Isfid20sZT;ETQ26(CviTU2G)ixNMuv}- zr^fhE1TOAC1R^+S7qIV}bH$GGdEyUZ{#R}S#sTmZe{Z83W&p)ogB0pt35*438-@ea zkWH|%VnlddKZ@clw@Tk;Ho9{$GyTClUcOSz+h#VtbBxZLYV$mubYB0#eugiK&Bl^b zcmN%G#{6>Pp9J5R@EuLqIgOXS40J1_%dzi!jnKAiDs4W%_Zd7+ z;2Kt0cPIGtmL}r!!!GcbP^DkLwf(3=;JXZ-A#fsBT0#5?%wI^#JOdbbj)18QOd_B? zY1_ftwu5nafPmzE09Sg6D$z5VaN$er`>y+L-==wILl)0F=P=5%5ADR!k>|?BE17?Y zCW-7r`)=J%xGmG@g;fl_KvnkarYh%=!XvU`eSv2=i+y;p8qvym0#?_s)p=w!Lmhj; z?BUt}DLkHrKak0q1{u0G2xnT8Oh001eW;hm^)^twC8&o3a9#TV`~h4c?%~cXkxLTe*y7_m13bpzwhXMJhQ%@PB?U|7 z$w!FaM)-5VPh!X!NDySO)702&C6%0S+Osgoo-{QZ`@+ zYwJXSmw{na0c%pK5Jdc)q^&h;n@Her2Ja>?TkYRrw(*?%m}kp(qN-u}G9o;9MUk0h zVrE^`n2x)&Q1-oPA3jc$uY(Lvw^zP_gRj2`mGs&^>|Lhtgs>kQiBEUl!2cidP4LkZ z)$MMlIV=rEv)(UXHmF)ZgEBZv((xpwr|hxeF@Idh3M785<(#H(f}aQ=Hj()suVDVO z>baN9W}bg==z+SBLDdYOfuk;b8$n&SmVGGv20qNh_(tbew>$T^?+aQ#}C6K#Lb@I z?|Z;L8lEU`^)wdYjFvBcUQK@4Y}PCxJaF;hq4x4{@jIQpLs#?-H|nkTW(|7n%F8PK zWi!aL#x{^82I{R@j05ezYvG~2ut;3=PWcQl(S*R+@RB|`gLo|>FH?9LvC{`{0~7xq z;=7sO4*T>OKH?`3KN9@k>b3YQeq3VKpF^|G#gFyem6+Xp*HiV-pgxH!PcG`6(aTuW zJwEGNXD^>v1$^ra_4sn1J0DP@Z z+U~zu2yOHz5!~5`ec$G9Zg-`2c0!2bLy*| zW}C1#kSKHr4mxb`ViTtXlyK@J=HFIrUNOUB=ZIL%cdHpAvM#Yu;*r1luQ+A;l126h zJYW!SUlYDkWN*rS>hV|1$m#(QP-|Z?8;`t(W1Da58SV%2S4QREZ@}LfJn(uDe=x_p z7PVs(^J9rGlgkz2_f!G9%;>I5p_7`h`b;$=d(UI&WVF;CIlfd_B4{3<6DtX#ZYbZZ z=I+9IZ?bxRmpQdTAJU6;3B~PE(%VHfc-36exH|FWV10}Hdj*NCj=gF|)%9T(CcXK% zB&?o))eKENdYUw%I}7`XuQ4BToj&26GpIamDEkc zf3=3X?H)$mmE8Up@V^ZDepe%3Gn>{PCPu@5Q43!)BRrw@Z*Tc}eDSOD?4i1?%v(P8 zcUxJ|W+)3rtKmo(DO>av9IX^TcZ&S>mXCrGJ7!n*!iD)uQHwrog<5u~`=J)RuN$9b z(lj&g(RxO6I@<^;re@s}9+;RFOhC_NJkQ)#-3!ciDdRq2?K`eJ+P{bP{32+_2`FiQ z8vDM(U)l-r9PuAx{vzVP#Qe#`pThimi2sawr@-v%If6+MGZeMXK#~XlyNL3=Y|qih z%ipL~oz4(#i7U_h+&qH5m=1l-xpkXJpFixxV-gy)^6H`vG61I8Dvp(>;R!DIyqbJ? zo_&}`bHks3+ECLe{UeRz8PF(;|HwUg1Ke^Uu){Rca+ttwD6*;6198Km+s^ zjpA)~rDNrt6YWYbJy&U|5!IXa3uPAL|nws#&x{a^QD z#l6hQ)s3oNG!uXs7p@FuJNvirsx>o6(oXh)e+mQ zMI%HGz8~hn>@BQ%;LfAOmxJ|g;(yQlbm%%f7h#?X#k0xJj~K`%poIJJDdN8aJ`IZT zkMW?`_#p<-mhcRS@Mt-=gn?xMXcVQ$D9U@7`P0?^3eB#bH)Vc(_GLSM50f3ae6W=4 zgu#w)3ub5@!0-KW{>r<^`UJ{_EBnxtYM-En%$$DM_x+6Xc<}#04jjIN2f`1O51)fS z^aRy2%8%YrgA#2^Ne2jJgM*g*SpuQAx$=kO!GDJNUlad1@YUmA-4R;->Icr=|D3%# zZ(iYePUN z0N(~2$$Yu^gEqDs3z0v#>dz!`1D6iKuTT6U=6_E7GUoqz7x=Q~e2@4=%zt7s_;hIy zO?;X7h2Z--z(_K*HT-fIV7Z`F5C2P!Zyi^wgZ;yqY^Emh9|0c=>7_WpG@`?GjIRWT zObpf$BeHI1VPWa>sULTnF3*W$Jla2(K^;_tHMV_FOkK#sxdu3-B3aHU+bm}ORm@w& zPf36we}Lun-mihl4L@l5SS1RNLyQ&H6@|N{A}REc=-EZAam)Xs@$gZ5H1C;*=FvL< z5S~fRTTUkmIgRs(e}MUE#D4&Mcth7AB6*ckggFz zM0+}w<-mvNJ38*{!+$@AS^-o`61+3j>g)OcR@*4m=6_Q|4vV7HK0GhA(c|U2f2`pw zzU?c(XM3c>|mca*ecc5y=KjRZNy$1d;(c4*%|{_ zV|83NI98tUm#y(!GBnO$je|+!Qnhxk*|`2E=r0mm4l&;c`!SW**=IhCcX3zlGdtdq zjbl~4mTFX_UprN{&m2(ek_5e#>agF;z!PY%?Z-{pSJburW`g;o>UF@JYfj(0^MILa z;$}{-gXUdkg~~aIn>fX)^q~1=t*;;8tjJQw4w=!l8qDLLW7OY=%;C7jGvu&&pw^=g zGI!wK+V7c7%%-cU^|d~)xAOn!`V#P%uJ`}BXM$|ph$Lc5f*`Rb1c^06!W||pwHGZ_ zOD(NxVk;(0hKw<&;^;ytZB@0^DzOv^6-$+r*1iNS_ljLBu_gb{d+tp_zrTN;Co}h+ z^*!%-_p{7ogkp%=#*NVnRNKYdXGa)DO2S9m|#);h0Wgw)6@%{q)F@8U#Kj zv(!;il3EqELvrk2>JUCVM+(9Q+vPdZC(^IHin*GTmLS7P9 z)?6Zi+8s1n2fQw|>rUIIB*e%WgL%R}=^ggRCZ2Ops-BgzPiiJf3$yP0B7G-GpJlDe zmD)>EeSY?UR1+7){ChxZ%4&Vf>mQWbv#^bP*g@%aX;)VELFuv-a_)7#{k18_lfw9!{kjQfglkjIP== zf{U-}wdW$s<_@*G4%l392`Fpr5It)gzw(0_9F+#*49mu&po;sv)-fr$#>UNr zlth!_>MrUmHGuhpPdg?>OK17oW4I=3QP$C87_3iiqs1Xv_wu9-659IoxKzt${{X!s z56?a>Mb_!I7lusqd7Eow02%ew2o`?>OdFR@fHbpsw-ZuH=m7vNho{rbQ6Z(T-p*Y< z^baXfo&&y7JV`Z6Yzg`DqEx=|4=L0f`gsZeN@bC};1B7os_Qq9!+9eXd{&YidrKX| zNB#-C|CQDKq||~*{rQyBSjJ4@n@&r8SdA@N70yVXN)6AwtoO6_bAj>IH0ul6?$l}d zVv3$QmmfGQ#rpWaqQ3(0bJF1|KQyjvvby#vt{j`E&bq8K=cI3>Rz)_wO!jBg-put% zLcF|S{WiV5Cq0bLM5akeNM0{5=*_b(NHcujGV-c^#yeh=>iN_$8v2`exG2@+bMV0e zzUQkhO5uI>^wis#w~8h@!sb4=^1Lh3 z@PO&y2FJ|xC8<#AGqo&%Op3(=F@NH7Sgk>EU(hbLq{jk5s9mgspe0HGpxO%QvLutkMVk zs~eDgllYSx7~qAhhyrPjROi(X36;y@AsuY4$2Qlg*oR8=StaL+S(O*^JvXJ+HN8

    VgaQNXD+||NE%<`<>q?-g>wYFibnw<+>;kQ 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

    )0!DET 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 QV6*%wUyE$ks`}vn2bOlua{vGU delta 285104 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﷪lFJWat*DoocGstN< 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 r`;1iN>=`UGm`{$@F>p{4V_yAL} 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%0DrOY3h}khW<%a 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

    ))9svI_YoiZ!AAS9&N1s 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 delta 93 zcmX?l%Jb+c&j}qY2mNlROziPtx_P}-ix0qXRv9#V|ZN0_TdW*gF7RT0G noLcQH2Y@QuIXXCjmLpzU1%1MDWz diff --git a/src/fractalzoomer/native/win32-x86-64/libmpfr-6.dll b/src/fractalzoomer/native/win32-x86-64/libmpfr-6.dll index e83f6ca652935be499045a6c79681d5092299318..2965e6ecb2b1a949ddbaf4486c7b72baee666df4 100644 GIT binary patch delta 185581 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

    1@&qJPI)Ode=xn%QU;1Qe|>7apn0;T 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ⅇq_==an_ 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 diff --git a/src/fractalzoomer/native/win32-x86-64/mpir_haswell_avx2.dll b/src/fractalzoomer/native/win32-x86-64/mpir_haswell_avx2.dll index 10ecad9ef63299ad1e97d7ff2d19a906e15e859a..82f4aa4d13b02abd21fcdefc58a48603010e3220 100644 GIT binary patch delta 98656 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≶R`^ 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
    *Ln)=qpo8? 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 G_kRFM=8i-F diff --git a/src/fractalzoomer/native/win32-x86-64/mpir_skylake_avx2.dll b/src/fractalzoomer/native/win32-x86-64/mpir_skylake_avx2.dll index 5548b88f7453d76bb93f81f0896d2e87782e7527..28ef5f720194c62bf32a37b05701f149a47b476c 100644 GIT binary patch delta 99636 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 DGHsI;!h?e`ZpYYymhXAF61cPOzY{0eSD2Ez$E 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�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 diff --git a/src/fractalzoomer/native/win32-x86/libgmp-10.dll b/src/fractalzoomer/native/win32-x86/libgmp-10.dll index b75af672dcae0a00bc6ee233f859a789fcbffcf3..906007ab2abfbf413597bfd2c84e04ead00e5aa0 100644 GIT binary patch delta 84 zcmZ4S&t}Cxn+Y8(-#0a-PVDhv=Ft~uyxn@6vGq1n>uu)N+bpfOSzB+jZN1H|xfHCZ donsk05OV-AClGT1F*gwN05R`&j%9obGXYm+BDVkl delta 84 zcmZ4S&t}Cxn+Y8(ivn(^OziPt7Rlsqyxn@6vGq1n>uu)N+bpfOSzB+jZN1H|xfHCZ donsk05OV-AClGT1F*gwN05R`&j%9obGXXuPB02y7 diff --git a/src/fractalzoomer/native/win32-x86/libmpfr-6.dll b/src/fractalzoomer/native/win32-x86/libmpfr-6.dll index 0742a3f29b5443346955040354b52bc38a02b944..53bb55b26d4107a12e9f9bf82ad4f063dc2276dc 100644 GIT binary patch delta 149854 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�$LQhJ2K=_oe_e{&0v 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 jV*h^ya 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 !XY?jm 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 diff --git a/src/fractalzoomer/palettes/PaletteColorNormal.java b/src/fractalzoomer/palettes/PaletteColorNormal.java index 4cda6e838..c401afdf0 100644 --- a/src/fractalzoomer/palettes/PaletteColorNormal.java +++ b/src/fractalzoomer/palettes/PaletteColorNormal.java @@ -33,14 +33,14 @@ public int getPaletteColor(double result) { if(result < 0) { if(!special_use_palette_color) { - return special_colors[((int)(result * (-1))) % special_colors.length]; + return special_colors[(int)(((long)(result * (-1))) % special_colors.length)]; } else { - return palette[((int)(result * (-1))) % palette.length]; + return palette[(int)(((long)(result * (-1))) % palette.length)]; } } else { - return palette[((int)result) % palette.length]; + return palette[(int)(((long)result) % palette.length)]; } } diff --git a/src/fractalzoomer/palettes/PaletteColorSmooth.java b/src/fractalzoomer/palettes/PaletteColorSmooth.java index bb296b4eb..ec7209751 100644 --- a/src/fractalzoomer/palettes/PaletteColorSmooth.java +++ b/src/fractalzoomer/palettes/PaletteColorSmooth.java @@ -40,7 +40,7 @@ public int getPaletteColor(double result) { if(result < 0) { if(!special_use_palette_color) { - return special_colors[((int)(result * (-1))) % special_colors.length]; + return special_colors[(int)(((long)(result * (-1))) % special_colors.length)]; } else { return calculateSmoothColor(-result); @@ -57,83 +57,83 @@ private double fractional_transfer(double result, int transfer_method) { case 0: return result; case 1: - double fract_part = result - (int)result; + double fract_part = result - (long)result; fract_part = 1 - fract_part; - return (int)result + fract_part; + return (long)result + fract_part; case 2: - fract_part = result - (int)result; + fract_part = result - (long)result; double temp = 2*fract_part-1; fract_part = 1 - temp * temp; - return (int)result + fract_part; + return (long)result + fract_part; case 3: - fract_part = result - (int)result; + fract_part = result - (long)result; temp = 2*fract_part-1; fract_part = temp * temp; - return (int)result + fract_part; + return (long)result + fract_part; case 4: - fract_part = result - (int)result; + fract_part = result - (long)result; temp = 2*fract_part-1; temp *= temp; fract_part = 1 - temp * temp; - return (int)result + fract_part; + return (long)result + fract_part; case 5: - fract_part = result - (int)result; + fract_part = result - (long)result; temp = 2*fract_part-1; temp *= temp; fract_part = temp * temp; - return (int)result + fract_part; + return (long)result + fract_part; case 6: - fract_part = result - (int)result; + fract_part = result - (long)result; fract_part = Math.sin(fract_part * Math.PI); - return (int)result + fract_part; + return (long)result + fract_part; case 7: - fract_part = result - (int)result; + fract_part = result - (long)result; fract_part = 1 - Math.sin(fract_part * Math.PI); - return (int)result + fract_part; + return (long)result + fract_part; case 8: - fract_part = result - (int)result; + fract_part = result - (long)result; if(fract_part < 0.5) { fract_part = 2 * fract_part; } else { fract_part = 2 - 2 *fract_part; } - return (int)result + fract_part; + return (long)result + fract_part; case 9: - fract_part = result - (int)result; + fract_part = result - (long)result; if(fract_part < 0.5) { fract_part = 1 - 2 * fract_part; } else { fract_part = 1 - (2 - 2 *fract_part); } - return (int)result + fract_part; + return (long)result + fract_part; case 10: - fract_part = result - (int)result; + fract_part = result - (long)result; fract_part = 0.5 - 0.5 * Math.cos(2 * fract_part * Math.PI); - return (int)result + fract_part; + return (long)result + fract_part; case 11: - fract_part = result - (int)result; + fract_part = result - (long)result; fract_part = 0.5 + 0.5 * Math.cos(2 * fract_part * Math.PI); - return (int)result + fract_part; + return (long)result + fract_part; case 12: - fract_part = result - (int)result; + fract_part = result - (long)result; if(fract_part < 0.5) { fract_part = Math.sqrt(2 * fract_part); } else { fract_part = Math.sqrt(2 - 2 *fract_part); } - return (int)result + fract_part; + return (long)result + fract_part; case 13: - fract_part = result - (int)result; + fract_part = result - (long)result; if(fract_part < 0.5) { fract_part = 1 - Math.sqrt(2 * fract_part); } else { fract_part = 1 - Math.sqrt(2 - 2 *fract_part); } - return (int)result + fract_part; + return (long)result + fract_part; } return result; @@ -144,8 +144,8 @@ private int calculateSmoothColor(double result) { result = fractional_transfer(result, fractional_transfer_method); - int color2 = palette[((int)(result)) % palette.length]; - int color = palette[((int)((result - 1 + palette.length))) % palette.length]; + int color2 = palette[(int)(((long)(result)) % palette.length)]; + int color = palette[(int)(((long)((result - 1 + palette.length))) % palette.length)]; int color_red = (color >> 16) & 0xff; int color_green = (color >> 8) & 0xff; @@ -155,7 +155,7 @@ private int calculateSmoothColor(double result) { int color2_green = (color2 >> 8) & 0xff; int color2_blue = color2 & 0xff; - double coef = result - (int)result; //fractional part + double coef = result - (long)result; //fractional part return interpolator.interpolate(color_red, color_green, color_blue, color2_red, color2_green, color2_blue, coef); @@ -174,11 +174,11 @@ public int calculateColor(double result, int paletteId, int color_cycling_locat int color2; if(result == 0) { - color = color2 = getGeneratedColor(((int)result), paletteId, color_cycling_location, cycle, iqps); + color = color2 = getGeneratedColor(0, paletteId, color_cycling_location, cycle, iqps); } else { - color = getGeneratedColor(((int)result - 1), paletteId, color_cycling_location, cycle, iqps); - color2 = getGeneratedColor(((int)result), paletteId, color_cycling_location, cycle, iqps); + color = getGeneratedColor(((long)result - 1), paletteId, color_cycling_location, cycle, iqps); + color2 = getGeneratedColor(((long)result), paletteId, color_cycling_location, cycle, iqps); } int color_red = (color >> 16) & 0xff; @@ -189,7 +189,7 @@ public int calculateColor(double result, int paletteId, int color_cycling_locat int color2_green = (color2 >> 8) & 0xff; int color2_blue = color2 & 0xff; - double coef = result - (int)result; //fractional part + double coef = result - (long)result; //fractional part return interpolator.interpolate(color_red, color_green, color_blue, color2_red, color2_green, color2_blue, coef); } diff --git a/src/fractalzoomer/palettes/PresetPalette.java b/src/fractalzoomer/palettes/PresetPalette.java index 45e91cc2c..cd2d15d04 100644 --- a/src/fractalzoomer/palettes/PresetPalette.java +++ b/src/fractalzoomer/palettes/PresetPalette.java @@ -356,7 +356,7 @@ public static Color[] getPalette(int[] palette, int color_cycling_location) { Color[] colors = new Color[palette.length]; for (int i = 0; i < colors.length; i++) { - colors[i] = new Color(palette[(i + color_cycling_location) % colors.length]); + colors[i] = new Color(palette[(int)(((long)i + color_cycling_location) % colors.length)]); } return colors; @@ -506,7 +506,7 @@ public static Color[] getPalette(int id, int color_cycling_location) { Color[] colors = new Color[palette.length]; for (int i = 0; i < colors.length; i++) { - colors[i] = new Color(palette[(i + color_cycling_location) % colors.length]); + colors[i] = new Color(palette[(int)(((long)i + color_cycling_location) % colors.length)]); } return colors; diff --git a/src/fractalzoomer/palettes/transfer_functions/AtanTransferFunction.java b/src/fractalzoomer/palettes/transfer_functions/AtanTransferFunction.java index 8f5b1e8eb..f8d08800a 100644 --- a/src/fractalzoomer/palettes/transfer_functions/AtanTransferFunction.java +++ b/src/fractalzoomer/palettes/transfer_functions/AtanTransferFunction.java @@ -42,12 +42,12 @@ public double transfer(double result) { result = -result; // transfer to positive result *= itPaletteDensity; result = Math.atan(result); - result *= paletteLength; + result *= paletteLength * paletteMultiplier; result = -result; // transfer to negative } else { result *= itPaletteDensity; result = Math.atan(result); - result *= paletteLength; + result *= paletteLength * paletteMultiplier; } return result * color_intensity; diff --git a/src/fractalzoomer/palettes/transfer_functions/CbrtTransferFunction.java b/src/fractalzoomer/palettes/transfer_functions/CbrtTransferFunction.java index b97b3685f..83ddef237 100644 --- a/src/fractalzoomer/palettes/transfer_functions/CbrtTransferFunction.java +++ b/src/fractalzoomer/palettes/transfer_functions/CbrtTransferFunction.java @@ -40,13 +40,13 @@ public double transfer(double result) { if (result < 0) { result = -result; // transfer to positive result *= itPaletteDensity; - result = Math.cbrt(result + 1); - result *= paletteLength; + result = Math.cbrt(result); + result *= paletteLength * paletteMultiplier; result = -result; // transfer to negative } else { result *= itPaletteDensity; - result = Math.cbrt(result + 1); - result *= paletteLength; + result = Math.cbrt(result); + result *= paletteLength * paletteMultiplier; } return result * color_intensity; diff --git a/src/fractalzoomer/palettes/transfer_functions/ForthrtTransferFunction.java b/src/fractalzoomer/palettes/transfer_functions/ForthrtTransferFunction.java index 39070047d..ef630e67e 100644 --- a/src/fractalzoomer/palettes/transfer_functions/ForthrtTransferFunction.java +++ b/src/fractalzoomer/palettes/transfer_functions/ForthrtTransferFunction.java @@ -41,13 +41,13 @@ public double transfer(double result) { if (result < 0) { result = -result; // transfer to positive result *= itPaletteDensity; - result = Math.sqrt(Math.sqrt(result + 1)); - result *= paletteLength; + result = Math.sqrt(Math.sqrt(result)); + result *= paletteLength * paletteMultiplier; result = -result; // transfer to negative } else { result *= itPaletteDensity; - result = Math.sqrt(Math.sqrt(result + 1)); - result *= paletteLength; + result = Math.sqrt(Math.sqrt(result)); + result *= paletteLength * paletteMultiplier; } return result * color_intensity; diff --git a/src/fractalzoomer/palettes/transfer_functions/LinearTransferFunction.java b/src/fractalzoomer/palettes/transfer_functions/LinearTransferFunction.java index 4640144c9..5465fa117 100644 --- a/src/fractalzoomer/palettes/transfer_functions/LinearTransferFunction.java +++ b/src/fractalzoomer/palettes/transfer_functions/LinearTransferFunction.java @@ -21,11 +21,11 @@ public double transfer(double result) { if (result < 0) { result = -result; // transfer to positive result *= itPaletteDensity; - result *= paletteLength; + result *= paletteLength * paletteMultiplier; result = -result; // transfer to negative } else { result *= itPaletteDensity; - result *= paletteLength; + result *= paletteLength * paletteMultiplier; } return result * color_intensity; diff --git a/src/fractalzoomer/palettes/transfer_functions/LogLogTransferFunction.java b/src/fractalzoomer/palettes/transfer_functions/LogLogTransferFunction.java index 54c1e5bf1..3d78cb7e0 100644 --- a/src/fractalzoomer/palettes/transfer_functions/LogLogTransferFunction.java +++ b/src/fractalzoomer/palettes/transfer_functions/LogLogTransferFunction.java @@ -42,12 +42,12 @@ public double transfer(double result) { result = -result; // transfer to positive result *= itPaletteDensity; result = Math.log(Math.log(result + 1) + 1); - result *= paletteLength; + result *= paletteLength * paletteMultiplier; result = -result; // transfer to negative } else { result *= itPaletteDensity; result = Math.log(Math.log(result + 1) + 1); - result *= paletteLength; + result *= paletteLength * paletteMultiplier; } return result * color_intensity; diff --git a/src/fractalzoomer/palettes/transfer_functions/LogarithmTransferFunction.java b/src/fractalzoomer/palettes/transfer_functions/LogarithmTransferFunction.java index 103aa9883..16c8234b8 100644 --- a/src/fractalzoomer/palettes/transfer_functions/LogarithmTransferFunction.java +++ b/src/fractalzoomer/palettes/transfer_functions/LogarithmTransferFunction.java @@ -25,6 +25,7 @@ public class LogarithmTransferFunction extends TransferFunction { private double color_intensity; private double itPaletteDensity; + public LogarithmTransferFunction(int paletteLength, double color_intensity, double colorDensity) { super(paletteLength); @@ -42,12 +43,12 @@ public double transfer(double result) { result = -result; // transfer to positive result *= itPaletteDensity; result = Math.log(result + 1); - result *= paletteLength; + result *= paletteLength * paletteMultiplier; result = -result; // transfer to negative } else { result *= itPaletteDensity; result = Math.log(result + 1); - result *= paletteLength; + result *= paletteLength * paletteMultiplier; } return result * color_intensity; diff --git a/src/fractalzoomer/palettes/transfer_functions/SqrtTransferFunction.java b/src/fractalzoomer/palettes/transfer_functions/SqrtTransferFunction.java index 6e47b6ccb..535541236 100644 --- a/src/fractalzoomer/palettes/transfer_functions/SqrtTransferFunction.java +++ b/src/fractalzoomer/palettes/transfer_functions/SqrtTransferFunction.java @@ -45,8 +45,8 @@ public double transfer(double result) { // result *= paletteLength; // rescale to palette length result *= itPaletteDensity; - result = Math.sqrt(result + 1); - result *= paletteLength; + result = Math.sqrt(result); + result *= paletteLength * paletteMultiplier; result = -result; // transfer to negative } else { @@ -55,8 +55,8 @@ public double transfer(double result) { // result *= paletteLength; // rescale to palette length result *= itPaletteDensity; - result = Math.sqrt(result + 1); - result *= paletteLength; + result = Math.sqrt(result); + result *= paletteLength * paletteMultiplier; } return result * color_intensity; diff --git a/src/fractalzoomer/palettes/transfer_functions/TransferFunction.java b/src/fractalzoomer/palettes/transfer_functions/TransferFunction.java index e38f7a177..3b5516cd0 100644 --- a/src/fractalzoomer/palettes/transfer_functions/TransferFunction.java +++ b/src/fractalzoomer/palettes/transfer_functions/TransferFunction.java @@ -23,10 +23,12 @@ public abstract class TransferFunction { protected static double IT_COLOR_DENSITY_MULTIPLIER = 0.05; protected int paletteLength; + protected double paletteMultiplier; public TransferFunction(int paletteLength) { this.paletteLength = paletteLength; + paletteMultiplier = paletteLength <= 2000 ? 1 : 2000.0 / paletteLength; } diff --git a/src/fractalzoomer/planes/general/LambdaPlane.java b/src/fractalzoomer/planes/general/LambdaPlane.java index e81f9f10f..fd8338401 100644 --- a/src/fractalzoomer/planes/general/LambdaPlane.java +++ b/src/fractalzoomer/planes/general/LambdaPlane.java @@ -89,7 +89,7 @@ public BigComplex transform(BigComplex pixel) { @Override public BigNumComplex transform(BigNumComplex pixel) { - return pixel.times(pixel.r_sub(new BigNum(1))); + return pixel.times(pixel.r_sub(BigNum.create(1))); } diff --git a/src/fractalzoomer/settings/SettingsFractals1090.java b/src/fractalzoomer/settings/SettingsFractals1090.java new file mode 100644 index 000000000..a34e9e6f9 --- /dev/null +++ b/src/fractalzoomer/settings/SettingsFractals1090.java @@ -0,0 +1,54 @@ +package fractalzoomer.settings; + +import fractalzoomer.main.app_settings.Settings; + +import java.io.Serializable; + +public class SettingsFractals1090 extends SettingsFractals1089 implements Serializable { + private static final long serialVersionUID = 053203451L; + + private double convergent_bailout; + private int rank_order_digits_grouping; + + private int blocks_format; + private boolean two_step_refinement; + private boolean one_chunk_per_row; + + public SettingsFractals1090(Settings s, boolean perturbation_theory, boolean greedy_drawing_algorithm, int brute_force_alg, int greedy_drawing_algorithm_id, boolean greedy_algorithm_check_iter_data, String userDefinedCode, int guess_blocks, int blocks_format, boolean two_step_refinement, boolean one_chunk_per_row) { + super(s, perturbation_theory, greedy_drawing_algorithm, brute_force_alg, greedy_drawing_algorithm_id, greedy_algorithm_check_iter_data, userDefinedCode, guess_blocks); + + this.blocks_format = blocks_format; + convergent_bailout = s.fns.convergent_bailout; + rank_order_digits_grouping = s.pps.hss.rank_order_digits_grouping; + this.two_step_refinement = two_step_refinement; + this.one_chunk_per_row = one_chunk_per_row; + + } + + public double getConvergentBailout() { + return convergent_bailout; + } + + public int getRankOrderDigitsGrouping() { + return rank_order_digits_grouping; + } + + public int getBlocksFormat() { + return blocks_format; + } + + public boolean getTwoStepRefinement() { + return two_step_refinement; + } + + public boolean getOneChunkPerRow() { + return one_chunk_per_row; + } + + @Override + public int getVersion() { + + return 1090; + + } +} diff --git a/src/fractalzoomer/true_coloring_algorithms/UserTrueColorAlgorithm.java b/src/fractalzoomer/true_coloring_algorithms/UserTrueColorAlgorithm.java index 14e972df2..4d97e3dbc 100644 --- a/src/fractalzoomer/true_coloring_algorithms/UserTrueColorAlgorithm.java +++ b/src/fractalzoomer/true_coloring_algorithms/UserTrueColorAlgorithm.java @@ -352,7 +352,7 @@ private static int getColor(double c1, double c2, double c3, int space, boolean res = ColorSpaceConverter.RYBtoRGB(c1, c2, c3); return 0xFF000000 | res[0] << 16 | res[1] << 8 | res[2]; case ColorSpaceConverter.LAB: - res = ColorSpaceConverter.LABtoRGB(c1 * 100, (2 * c2 - 1) * 100, (2 * c3 - 1) * 100); + res = ColorSpaceConverter.LABtoRGB(c1 * 100, c2 * 184.43 - 86.17, c3 * 202.33 - 107.85); return 0xFF000000 | res[0] << 16 | res[1] << 8 | res[2]; case ColorSpaceConverter.LCH_ab: res = ColorSpaceConverter.LCH_abtoRGB(c1 * 100, c2 * 140, c3 * 360); diff --git a/src/fractalzoomer/utils/ImageRepainter.java b/src/fractalzoomer/utils/ImageRepainter.java deleted file mode 100644 index e9d584f4b..000000000 --- a/src/fractalzoomer/utils/ImageRepainter.java +++ /dev/null @@ -1,58 +0,0 @@ -package fractalzoomer.utils; - -import fractalzoomer.core.TaskDraw; -import fractalzoomer.main.MainWindow; - -public class ImageRepainter implements Runnable { - private MainWindow ptr; - private TaskDraw[][] drawThreads; - public static int REPAINT_SLEEP_TIME = 24; - - private volatile boolean stop; - - public ImageRepainter(MainWindow ptr, TaskDraw[][] drawThreads) { - super(); - this.ptr = ptr; - this.drawThreads = drawThreads; - stop = false; - } - - public void init(boolean quickDrawAndRefinement) { - - ptr.setWholeImageDone(!quickDrawAndRefinement); - if(!quickDrawAndRefinement) { - boolean isJulia = drawThreads[0][0].isJulia(); - boolean isJuliaMap = drawThreads[0][0].isJuliaMap(); - boolean isDomainColoring = drawThreads[0][0].isDomainColoring(); - boolean isNonJulia = drawThreads[0][0].isNonJulia(); - - if(isJulia || isNonJulia || isJuliaMap || isDomainColoring) { - ptr.reloadTitle(); - TaskDraw.updateMode(ptr, false, isJulia, isJuliaMap, isDomainColoring); - } - ptr.getMainPanel().repaint(); - } - stop = false; - } - - public void stopIt() { - stop = true; - } - - @Override - public void run() { - - while (!stop && TaskDraw.number_of_tasks.get() > 0) { - - ptr.repaint(); - - try { - Thread.sleep(REPAINT_SLEEP_TIME); - } catch (Exception ex) { - - } - - } - - } -} diff --git a/src/fractalzoomer/utils/JsonPalettesContainer.java b/src/fractalzoomer/utils/JsonPalettesContainer.java index 7ad837238..1492f595c 100644 --- a/src/fractalzoomer/utils/JsonPalettesContainer.java +++ b/src/fractalzoomer/utils/JsonPalettesContainer.java @@ -19,10 +19,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import java.io.InputStream; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; +import java.util.*; public class JsonPalettesContainer { private ArrayList palettes; @@ -37,6 +34,26 @@ public JsonPalettesContainer() { catch (Exception ex) { } + Collections.sort(palettes, (o1, o2) -> { + Set> set1 = ((LinkedHashMap)o1).entrySet(); + Set> set2 = ((LinkedHashMap)o2).entrySet(); + + String name1 = ""; + for(Map.Entry entry : set1) { + if(entry.getKey().equals("name")) { + name1 = ((String)entry.getValue()).toLowerCase(); + } + } + + String name2 = ""; + for(Map.Entry entry : set2) { + if(entry.getKey().equals("name")) { + name2 = ((String)entry.getValue()).toLowerCase(); + } + } + + return name1.compareTo(name2); + }); } public ArrayList getPalettes() { diff --git a/src/fractalzoomer/utils/MathUtils.java b/src/fractalzoomer/utils/MathUtils.java index d27243bbe..a4178d4b9 100644 --- a/src/fractalzoomer/utils/MathUtils.java +++ b/src/fractalzoomer/utils/MathUtils.java @@ -31,7 +31,7 @@ public class MathUtils { public static double fract(double x) { x = Math.abs(x); - return x - (int)x; + return x - (long)x; } public static double angleBetween2PointsDegrees(double x1, double y1, double x2, double y2) { diff --git a/src/fractalzoomer/utils/TaskStatistic.java b/src/fractalzoomer/utils/TaskStatistic.java index 17c6810c7..cd78585c5 100644 --- a/src/fractalzoomer/utils/TaskStatistic.java +++ b/src/fractalzoomer/utils/TaskStatistic.java @@ -12,6 +12,7 @@ public class TaskStatistic implements Comparable { private long extra_pixels_calculated; private long pixels_post_processed; + private int sort_mode = 0; private long total_pixels; @@ -39,7 +40,14 @@ public TaskStatistic(int taskId, String threadName, long pixelCalculationTime, l @Override public int compareTo(TaskStatistic o) { - return Long.compare(pixelCalculationTime, o.pixelCalculationTime); + if(sort_mode == 0) { + return Long.compare(pixelCalculationTime, o.pixelCalculationTime); + } + return Long.compare(postProcessingCalculationTime, o.postProcessingCalculationTime); + } + + public void setSortMode(int mode) { + sort_mode = mode; } public String getThreadName() { diff --git a/test/Test.java b/test/Test.java index 1974da25f..8ef57b718 100644 --- a/test/Test.java +++ b/test/Test.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ - +package test; import fractalzoomer.core.Complex; import fractalzoomer.parser.EvaluationException; import fractalzoomer.parser.ExpressionNode; diff --git a/test/TestBigNum.java b/test/TestBigNum.java deleted file mode 100644 index ba8a36c1f..000000000 --- a/test/TestBigNum.java +++ /dev/null @@ -1,72 +0,0 @@ -import fractalzoomer.core.BigNum; -import fractalzoomer.core.MyApfloat; -import org.apfloat.Apfloat; - -public class TestBigNum { - - public static void main(String[] args) { - - MyApfloat.precision = 1000000; - BigNum.reinitializeTest(10000); - - Apfloat a = new MyApfloat("1.999999999999999999999999"); - BigNum k = new BigNum(a); - - assert k.multFull(k).compare(k.multFullOLD(k)) == 0; - assert k.multKaratsuba(k).compare(k.multKaratsubaOLD(k)) == 0; - assert k.squareFull().compare(k.squareFullOLD()) == 0; - assert k.squareFull().compare(k.squareFullBackwards()) == 0; - assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; - assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; - - assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; - assert k.multFull(k).compare(k.squareFull()) == 0; - assert k.multFull(k).compare(k.squareKaratsuba()) == 0; - - a = new MyApfloat("11111111.999999999999999999999999"); - k = new BigNum(a); - - assert k.multFull(k).compare(k.multFullOLD(k)) == 0; - assert k.multKaratsuba(k).compare(k.multKaratsubaOLD(k)) == 0; - assert k.squareFull().compare(k.squareFullOLD()) == 0; - assert k.squareFull().compare(k.squareFullBackwards()) == 0; - assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; - assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; - - assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; - assert k.multFull(k).compare(k.squareFull()) == 0; - assert k.multFull(k).compare(k.squareKaratsuba()) == 0; - - - BigNum.reinitializeTest(10000 + 30); - - a = new MyApfloat("1.999999999999999999999999"); - k = new BigNum(a); - - assert k.multFull(k).compare(k.multFullOLD(k)) == 0; - assert k.multKaratsuba(k).compare(k.multKaratsubaOLD(k)) == 0; - assert k.squareFull().compare(k.squareFullOLD()) == 0; - assert k.squareFull().compare(k.squareFullBackwards()) == 0; - assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; - assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; - - assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; - assert k.multFull(k).compare(k.squareFull()) == 0; - assert k.multFull(k).compare(k.squareKaratsuba()) == 0; - - a = new MyApfloat("11111111.999999999999999999999999"); - k = new BigNum(a); - - assert k.multFull(k).compare(k.multFullOLD(k)) == 0; - assert k.multKaratsuba(k).compare(k.multKaratsubaOLD(k)) == 1; - assert k.squareFull().compare(k.squareFullOLD()) == 0; - assert k.squareFull().compare(k.squareFullBackwards()) == 0; - assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 1; - assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; - - assert k.multFull(k).compare(k.multKaratsuba(k)) == -1; - assert k.multFull(k).compare(k.squareFull()) == 0; - assert k.multFull(k).compare(k.squareKaratsuba()) == -1; - - } -} diff --git a/test/TestBigNum30.java b/test/TestBigNum30.java new file mode 100644 index 000000000..e45afaf0e --- /dev/null +++ b/test/TestBigNum30.java @@ -0,0 +1,242 @@ +package test; +import fractalzoomer.core.BigNum; +import fractalzoomer.core.BigNum30; +import fractalzoomer.core.MyApfloat; +import fractalzoomer.core.TaskDraw; +import org.apfloat.Apfloat; + +public class TestBigNum30 { + + public static void main(String[] args) { + + TaskDraw.BUILT_IT_BIGNUM_IMPLEMENTATION = 1; + MyApfloat.precision = 2000000; + BigNum.reinitializeTest(19000); + + Apfloat a = new MyApfloat("1.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + BigNum30 k = (BigNum30) BigNum.create(a); + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaGolden(k)) == 0; + assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + assert k.squareFull().compare(k.squareFullBackwards()) == 0; + assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + a = new MyApfloat("11111111.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = (BigNum30) BigNum.create(a); + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaGolden(k)) == 0; + assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + assert k.squareFull().compare(k.squareFullBackwards()) == 0; + assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + k.digits[0] = 0x7fff; + for(int i = 1; i < k.digits.length; i++) { + k.digits[i] = 0x3fffffff; + } + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaGolden(k)) == 0; + assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + assert k.squareFull().compare(k.squareFullBackwards()) == 0; + assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + BigNum.reinitializeTest(19000 + 30); + + a = new MyApfloat("1.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = (BigNum30) BigNum.create(a); + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaGolden(k)) == 0; + assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + assert k.squareFull().compare(k.squareFullBackwards()) == 0; + assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + a = new MyApfloat("11111111.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = (BigNum30) BigNum.create(a); + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaGolden(k)) == 0; + assert k.squareFull().compare(k.squareWithZeroSkip()) == -1; + assert k.squareFull().compare(k.squareFullGolden()) == -1; + assert k.squareFull().compare(k.squareFullBackwards()) == 0; + assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 1; + assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + assert k.multFull(k).compare(k.squareFullBackwards()) == 1; + assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + k.digits[0] = 0x7fff; + for(int i = 1; i < k.digits.length; i++) { + k.digits[i] = 0x3fffffff; + } + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaGolden(k)) == 0; + assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + assert k.squareFull().compare(k.squareFullBackwards()) == 0; + assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + + BigNum.reinitializeTest(10); + a = new MyApfloat("1.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = (BigNum30) BigNum.create(a); + + k.digits[0] = 0x7fff; + for(int i = 1; i < k.digits.length; i++) { + k.digits[i] = 0x3fffffff; + } + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaGolden(k)) == 0; + assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + assert k.squareFull().compare(k.squareFullBackwards()) == 0; + assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + BigNum.reinitializeTest(30); + a = new MyApfloat("1.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = (BigNum30) BigNum.create(a); + + k.digits[0] = 0x7fff; + for(int i = 1; i < k.digits.length; i++) { + k.digits[i] = 0x3fffffff; + } + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaGolden(k)) == 0; + assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + assert k.squareFull().compare(k.squareFullBackwards()) == 0; + assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + BigNum.reinitializeTest(60); + a = new MyApfloat("1.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = (BigNum30) BigNum.create(a); + + k.digits[0] = 0x7fff; + for(int i = 1; i < k.digits.length; i++) { + k.digits[i] = 0x3fffffff; + } + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaGolden(k)) == 0; + assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + assert k.squareFull().compare(k.squareFullBackwards()) == 0; + assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + /*Random ran = new Random(1); + BigNum.reinitializeTest(19000); + System.out.println(BigNum.fracDigits); + for(int i = 0; i < 100000; i++) { + BigNum r = new BigNum(ran.nextDouble()+0x7fff ); + if(r.multFullOLD(r).compare(r.multKaratsuba(r)) != 0) { + System.out.println(r.doubleValue()); + } + } + + BigNum.reinitializeTest(19000 + 30); + System.out.println(BigNum.fracDigits); + for(int i = 0; i < 100000; i++) { + BigNum r = new BigNum(ran.nextDouble()+0x7fff ); + if(r.multFullOLD(r).compare(r.multKaratsuba(r)) != 0) { + System.out.println(r.doubleValue()); + } + }*/ + + + } +} diff --git a/test/TestBigNum32.java b/test/TestBigNum32.java new file mode 100644 index 000000000..72cccd803 --- /dev/null +++ b/test/TestBigNum32.java @@ -0,0 +1,223 @@ +package test; +import fractalzoomer.core.BigNum; +import fractalzoomer.core.MyApfloat; +import fractalzoomer.core.TaskDraw; +import fractalzoomer.core.BigNum32; +import org.apfloat.Apfloat; + +public class TestBigNum32 { + + public static void main(String[] args) { + + TaskDraw.BUILT_IT_BIGNUM_IMPLEMENTATION = 3; + MyApfloat.precision = 2000000; + BigNum32.reinitializeTest(19000); + + Apfloat a = new MyApfloat("1.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + BigNum32 k = (BigNum32) BigNum.create(a); + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaOLD(k)) == 0; + assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + //assert k.squareFull().compare(k.squareFullBackwards()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + //assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + //assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + //assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + //assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + a = new MyApfloat("11111111.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = (BigNum32) BigNum.create(a); + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaOLD(k)) == 0; + assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + //assert k.squareFull().compare(k.squareFullBackwards()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + //assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + //assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + //assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + //assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + k.digits[0] = 0x7fff; + for(int i = 1; i < k.digits.length; i++) { + k.digits[i] = 0xffffffff; + } + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaOLD(k)) == 0; + assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + //assert k.squareFull().compare(k.squareFullBackwards()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + //assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + //assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + //assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + //assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + BigNum32.reinitializeTest(19000 + 32); + + a = new MyApfloat("1.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = (BigNum32) BigNum.create(a); + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaOLD(k)) == 0; + assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + //assert k.squareFull().compare(k.squareFullBackwards()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + //assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + //assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + //assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + //assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + a = new MyApfloat("11111111.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = (BigNum32) BigNum.create(a); + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaOLD(k)) == 0; + assert k.squareFull().compare(k.squareWithZeroSkip()) == -1; + assert k.squareFull().compare(k.squareFullGolden()) == -1; + //assert k.squareFull().compare(k.squareFullBackwards()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + //assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 1; + //assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + //assert k.multFull(k).compare(k.squareFullBackwards()) == 1; + //assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + k.digits[0] = 0x7fff; + for(int i = 1; i < k.digits.length; i++) { + k.digits[i] = 0xffffffff; + } + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaOLD(k)) == 0; + assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + //assert k.squareFull().compare(k.squareFullBackwards()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + //assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + //assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + //assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + //assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + + BigNum32.reinitializeTest(10); + a = new MyApfloat("1.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = (BigNum32) BigNum.create(a); + + k.digits[0] = 0x7fff; + for(int i = 1; i < k.digits.length; i++) { + k.digits[i] = 0xffffffff; + } + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaOLD(k)) == 0; + assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + //assert k.squareFull().compare(k.squareFullBackwards()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + //assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + //assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + //assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + //assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + BigNum32.reinitializeTest(32); + a = new MyApfloat("1.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = (BigNum32) BigNum.create(a); + + k.digits[0] = 0x7fff; + for(int i = 1; i < k.digits.length; i++) { + k.digits[i] = 0xffffffff; + } + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaOLD(k)) == 0; + assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + //assert k.squareFull().compare(k.squareFullBackwards()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + //assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + //assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + //assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + //assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + BigNum32.reinitializeTest(64); + a = new MyApfloat("1.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = (BigNum32) BigNum.create(a); + + k.digits[0] = 0x7fff; + for(int i = 1; i < k.digits.length; i++) { + k.digits[i] = 0xffffffff; + } + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaOLD(k)) == 0; + assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + //assert k.squareFull().compare(k.squareFullBackwards()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + //assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + //assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + //assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + //assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + + } +} diff --git a/test/TestBigNum60.java b/test/TestBigNum60.java new file mode 100644 index 000000000..3d2878ff8 --- /dev/null +++ b/test/TestBigNum60.java @@ -0,0 +1,158 @@ +package test; +import fractalzoomer.core.BigNum; +import fractalzoomer.core.MyApfloat; +import fractalzoomer.core.BigNum60; +import fractalzoomer.core.TaskDraw; +import org.apfloat.Apfloat; + +public class TestBigNum60 { + + public static void main(String[] args) { + + MyApfloat.precision = 2000000; + BigNum60.reinitializeTest(19000); + TaskDraw.BUILT_IT_BIGNUM_IMPLEMENTATION = 2; + + Apfloat a = new MyApfloat("1.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + BigNum60 k = (BigNum60) BigNum.create(a); + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaGolden(k)) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + + assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + + a = new MyApfloat("1111111111.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = (BigNum60) BigNum.create(a); + + + assert k.multFull(k).compare(k.multFullGolden(k)) == -1; + assert k.multKaratsuba(k).compare(k.multKaratsubaGolden(k)) == 0;//Due to overflow on second unrolled loop + assert k.squareFull().compare(k.squareFullGolden()) == 0; + assert k.multFull(k).compare(k.multKaratsuba(k)) == -1; + assert k.multFull(k).compare(k.squareFull()) == -1; + + k.digits[0] = 0x3fffffff; + for(int i = 1; i < k.digits.length; i++) { + k.digits[i] = 0xfffffffffffffffL; + } + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaGolden(k)) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + + + assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + + BigNum60.reinitializeTest(19000 + 60); + + a = new MyApfloat("1.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = (BigNum60) BigNum.create(a); + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaGolden(k)) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + + assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + + a = new MyApfloat("1111111111.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = (BigNum60) BigNum.create(a); + + assert k.multFull(k).compare(k.multFullGolden(k)) == -1; + assert k.multKaratsuba(k).compare(k.multKaratsubaGolden(k)) == 0; //Due to overflow on second unrolled loop + assert k.squareFull().compare(k.squareFullGolden()) == 0; + + assert k.multFull(k).compare(k.multKaratsuba(k)) == -1; + assert k.multFull(k).compare(k.squareFull()) == -1; + + k.digits[0] = 0x3fffffff; + for(int i = 1; i < k.digits.length; i++) { + k.digits[i] = 0xfffffffffffffffL; + } + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaGolden(k)) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + + + assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + + + BigNum60.reinitializeTest(10); + a = new MyApfloat("1.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = (BigNum60) BigNum.create(a); + + k.digits[0] = 0x3fffffff; + for(int i = 1; i < k.digits.length; i++) { + k.digits[i] = 0xfffffffffffffffL; + } + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaGolden(k)) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + + + assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + + BigNum60.reinitializeTest(60); + a = new MyApfloat("1.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = (BigNum60) BigNum.create(a); + + k.digits[0] = 0x3fffffff; + for(int i = 1; i < k.digits.length; i++) { + k.digits[i] = 0xfffffffffffffffL; + } + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaGolden(k)) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + + + assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + + BigNum60.reinitializeTest(120); + a = new MyApfloat("1.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = (BigNum60) BigNum.create(a); + + k.digits[0] = 0x3fffffff; + for(int i = 1; i < k.digits.length; i++) { + k.digits[i] = 0xfffffffffffffffL; + } + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + assert k.multKaratsuba(k).compare(k.multKaratsubaGolden(k)) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + + + assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + + + + /*Random ran = new Random(1); + BigNum64.reinitializeTest(19000); + System.out.println(BigNum64.fracDigits); + for(int i = 0; i < 100000; i++) { + BigNum64 r = new BigNum64(ran.nextDouble() +0x7fffffff ); + if(r.multFullGolden(r).compare(r.multKaratsuba(r)) != 0) { + System.out.println(r.doubleValue()); + } + } + + BigNum64.reinitializeTest(19000 + 60); + System.out.println(BigNum64.fracDigits); + for(int i = 0; i < 100000; i++) { + BigNum64 r = new BigNum64(ran.nextDouble() +0x7fffffff ); + if(r.multFullGolden(r).compare(r.multKaratsuba(r)) != 0) { + System.out.println(r.doubleValue()); + } + }*/ + + } +} diff --git a/test/TestBigNum64.java b/test/TestBigNum64.java new file mode 100644 index 000000000..958f751f7 --- /dev/null +++ b/test/TestBigNum64.java @@ -0,0 +1,222 @@ +package test; + +import fractalzoomer.core.*; +import org.apfloat.Apfloat; + +public class TestBigNum64 { + + public static void main(String[] args) { + + //TaskDraw.BUILT_IT_BIGNUM_IMPLEMENTATION = 3; + MyApfloat.precision = 2000000; + BigNum64.reinitializeTest(19000); + + Apfloat a = new MyApfloat("1.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + BigNum64 k = new BigNum64(a); + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaOLD(k)) == 0; + //assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + //assert k.squareFull().compare(k.squareFullBackwards()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + //assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + //assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + //assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + //assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + a = new MyApfloat("11111111.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = new BigNum64(a); + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaOLD(k)) == 0; + //assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + //assert k.squareFull().compare(k.squareFullBackwards()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + //assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + //assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + //assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + //assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + k.digits[0] = 0x3fffffff; + for(int i = 1; i < k.digits.length; i++) { + k.digits[i] = 0xffffffffffffffffL; + } + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaOLD(k)) == 0; + //assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + //assert k.squareFull().compare(k.squareFullBackwards()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + //assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + //assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + //assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + //assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + BigNum64.reinitializeTest(19000 + 64); + + a = new MyApfloat("1.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = new BigNum64(a); + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaOLD(k)) == 0; + //assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + //assert k.squareFull().compare(k.squareFullBackwards()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + //assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + //assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + //assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + //assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + a = new MyApfloat("11111111111.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = new BigNum64(a); + + + assert k.multFull(k).compare(k.multFullGolden(k)) == -1; + //assert k.multKaratsuba(k).compare(k.multKaratsubaOLD(k)) == 0; + //assert k.squareFull().compare(k.squareWithZeroSkip()) == -1; + assert k.squareFull().compare(k.squareFullGolden()) == -1; + //assert k.squareFull().compare(k.squareFullBackwards()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + //assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + //assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + //assert k.multFull(k).compare(k.squareFullBackwards()) == 1; + //assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + k.digits[0] = 0x3fffffff; + for(int i = 1; i < k.digits.length; i++) { + k.digits[i] = 0xffffffffffffffffL; + } + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaOLD(k)) == 0; + //assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + //assert k.squareFull().compare(k.squareFullBackwards()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + //assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + //assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + //assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + //assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + + BigNum64.reinitializeTest(10); + a = new MyApfloat("1.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = new BigNum64(a); + + k.digits[0] = 0x3fffffff; + for(int i = 1; i < k.digits.length; i++) { + k.digits[i] = 0xffffffffffffffffL; + } + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaOLD(k)) == 0; + //assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + //assert k.squareFull().compare(k.squareFullBackwards()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + //assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + //assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + //assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + //assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + BigNum64.reinitializeTest(64); + a = new MyApfloat("1.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = new BigNum64(a); + + k.digits[0] = 0x3fffffff; + for(int i = 1; i < k.digits.length; i++) { + k.digits[i] = 0xffffffffffffffffL; + } + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaOLD(k)) == 0; + //assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + //assert k.squareFull().compare(k.squareFullBackwards()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + //assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + //assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + //assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + //assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + BigNum64.reinitializeTest(128); + a = new MyApfloat("1.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"); + k = new BigNum64(a); + + k.digits[0] = 0x3fffffff; + for(int i = 1; i < k.digits.length; i++) { + k.digits[i] = 0xffffffffffffffffL; + } + + assert k.multFull(k).compare(k.multFullGolden(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaOLD(k)) == 0; + //assert k.squareFull().compare(k.squareWithZeroSkip()) == 0; + assert k.squareFull().compare(k.squareFullGolden()) == 0; + //assert k.squareFull().compare(k.squareFullBackwards()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaOLD()) == 0; + //assert k.squareKaratsuba().compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multFullBackwards(k)) == 0; + //assert k.multKaratsuba(k).compare(k.multKaratsubaBackwards(k)) == 0; + + //assert k.multFull(k).compare(k.multKaratsuba(k)) == 0; + assert k.multFull(k).compare(k.squareFull()) == 0; + //assert k.multFull(k).compare(k.squareKaratsuba()) == 0; + //assert k.multFull(k).compare(k.squareFullBackwards()) == 0; + //assert k.multFull(k).compare(k.squareKaratsubaBackwards()) == 0; + //assert k.multFull(k).compare(k.multKaratsubaBackwards(k)) == 0; + + + } +} diff --git a/test/TestComplex.java b/test/TestComplex.java index 04149dd60..0a5150f99 100644 --- a/test/TestComplex.java +++ b/test/TestComplex.java @@ -1,4 +1,4 @@ - +package test; import fractalzoomer.core.Complex; /* diff --git a/test/TestDerivative.java b/test/TestDerivative.java index e61f7f13f..1fd07a052 100644 --- a/test/TestDerivative.java +++ b/test/TestDerivative.java @@ -1,3 +1,4 @@ +package test; import fractalzoomer.core.Complex; import fractalzoomer.core.Derivative; diff --git a/test/TestRootFindingMethodUniquenes.java b/test/TestRootFindingMethodUniquenes.java index addc11d11..ea3cd0b8c 100644 --- a/test/TestRootFindingMethodUniquenes.java +++ b/test/TestRootFindingMethodUniquenes.java @@ -1,3 +1,4 @@ +package test; import fractalzoomer.core.Complex; import fractalzoomer.functions.root_finding_methods.abbasbandy.AbbasbandyRootFindingMethod; import fractalzoomer.functions.root_finding_methods.abbasbandy2.Abbasbandy2RootFindingMethod;