View | Details | Raw Unified | Return to issue 19991
Collapse All | Expand All

(-)scaddins/source/analysis/analysishelper.cxx (-13 / +95 lines)
Lines 838-851 Link Here
838
838
839
	return aRet;
839
	return aRet;
840
}
840
}
841
841
/** Calculates erf(x) by using Maclaurin expansion.  Accurate up to
842
842
	x = 4.
843
double Erf( double x )
843
 */
844
void ErfMaclaurin( double x, double& fErf )
844
{
845
{
845
	if( x == 0.0 )
846
	if( x == 0.0 )
846
		return 0.0;
847
	{
848
		fErf = 0.0;
849
		return;
850
	}
847
851
848
	double		f, fZm, fN2, fn1, fOld, fT;
852
	double		fZm, fN2, fn1, fOld, fT;
849
	sal_Bool	bAdd = sal_True;
853
	sal_Bool	bAdd = sal_True;
850
	sal_Int32	nMaxIter = 1000;
854
	sal_Int32	nMaxIter = 1000;
851
855
Lines 857-869 Link Here
857
861
858
	fT = x * fZm;
862
	fT = x * fZm;
859
863
860
	f = x - fT / fN2;
864
	fErf = x - fT / fN2;
861
865
862
	fOld = f * 0.9;
866
	fOld = fErf * 0.9;
863
867
864
	while( f != fOld && nMaxIter )
868
	while( fErf != fOld && nMaxIter-- )
865
	{
869
	{
866
		fOld = f;
870
		fOld = fErf;
867
871
868
		fN2 += 2.0;
872
		fN2 += 2.0;
869
873
Lines 873-890 Link Here
873
		fn1++;
877
		fn1++;
874
878
875
		if( bAdd )
879
		if( bAdd )
876
			f += fT / fN2;
880
			fErf += fT / fN2;
877
		else
881
		else
878
			f -= fT / fN2;
882
			fErf -= fT / fN2;
879
883
880
		bAdd = !bAdd;
884
		bAdd = !bAdd;
885
	}
886
887
	fErf *= 1.1283791670955125738961589031215452;
888
}
889
890
/** Calculates erf(x) by using Asymptotic expansion.  Accurate for x > 4
891
	but converges more quickly than octave/gnumeric.  Calculated values
892
	are almost identical to Excel's.
893
894
	@author Kohei Yoshida <kohei@openoffice.org>
895
896
	@see #i19991#
897
 */
898
void ErfAsymptotic( double x, double& fErf )
899
{
900
	if( x == 0.0 )
901
	{
902
		fErf = 0.0;
903
		return;
904
	}
905
906
	long nMaxIter = 1000;
907
908
	double fFct2 = 1.0, fDenom = 1.0, fX = x, fn = 0.0;
909
	double fXCnt = 1.0;
910
	double f = 1.0 / fX;
911
	double fOld = f * 0.9;
881
912
882
		nMaxIter--;
913
	bool bAdd = false;
914
	double fDiff = 0.0, fDiffOld = 1000.0;
915
	while( f != fOld && nMaxIter-- )
916
	{
917
		fOld = f;
918
919
		fFct2 *= 2.0*++fn - 1.0;
920
		fDenom *= 2.0;
921
		fX *= x*x;
922
		fXCnt += 2.0;
923
924
		if ( bAdd )
925
			f += fFct2 / ( fDenom * fX );
926
		else
927
			f -= fFct2 / ( fDenom * fX );
928
929
		bAdd = !bAdd;
930
		
931
		fDiff = fabs( f - fOld );
932
		if ( fDiffOld < fDiff )
933
		{
934
			f = fOld;
935
			break;
936
		}
937
		fDiffOld = fDiff;
883
	}
938
	}
884
939
885
	return f * 1.128379167095512573896;	// * 2/sqrt(PI)
940
	fErf = 1.0 - f*exp( -1.0*x*x )*0.5641895835477562869480794515607726;
886
}
941
}
887
942
943
/** Parent erf function that calls two different algorithms based on value
944
	of x.  It takes care of cases where x is negative ( erf is an odd function
945
	i.e. f(-x) = -f(x) ).
946
947
	@author Kohei Yoshida <kohei@openoffice.org>
948
949
	@see #i19991#
950
 */
951
double Erf( double x )
952
{
953
	bool bNegative = false;
954
	if ( x < 0.0 )
955
	{
956
		x = fabs( x );
957
		bNegative = true;
958
	}
959
	
960
	double fErf;
961
	if ( x > 4.0 )
962
		ErfAsymptotic( x, fErf );
963
	else
964
		ErfMaclaurin( x, fErf );
965
966
	if ( bNegative )
967
		fErf *= -1.0;
968
	return fErf;
969
}
888
970
889
inline sal_Bool IsNum( sal_Unicode c )
971
inline sal_Bool IsNum( sal_Unicode c )
890
{
972
{

Return to issue 19991