[Libreoffice-commits] core.git: 4 commits - chart2/source officecfg/registry sc/inc sc/Library_sc.mk sc/sdi sc/source sc/uiconfig

Tomaž Vajngerl quikee at gmail.com
Sun Jul 14 13:27:46 PDT 2013


 chart2/source/inc/PolynomialRegressionCurveCalculator.hxx         |    3 
 chart2/source/tools/MovingAverageRegressionCurveCalculator.cxx    |    1 
 chart2/source/tools/PolynomialRegressionCurveCalculator.cxx       |  149 ++-
 chart2/source/tools/gauss.hxx                                     |  166 ---
 chart2/source/view/charttypes/VSeriesPlotter.cxx                  |    5 
 officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu |    8 
 sc/Library_sc.mk                                                  |    1 
 sc/inc/sc.hrc                                                     |    4 
 sc/sdi/cellsh.sdi                                                 |    2 
 sc/sdi/scalc.sdi                                                  |   26 
 sc/source/ui/StatisticsDialogs/RandomNumberGeneratorDialog.cxx    |  486 ++++++++++
 sc/source/ui/app/scdll.cxx                                        |    2 
 sc/source/ui/inc/RandomNumberGeneratorDialog.hxx                  |   85 +
 sc/source/ui/inc/reffact.hxx                                      |    2 
 sc/source/ui/miscdlgs/solvrdlg.cxx                                |   26 
 sc/source/ui/view/cellsh.cxx                                      |    1 
 sc/source/ui/view/cellsh1.cxx                                     |    8 
 sc/source/ui/view/reffact.cxx                                     |    5 
 sc/source/ui/view/tabvwsh.cxx                                     |    2 
 sc/source/ui/view/tabvwshc.cxx                                    |    9 
 sc/uiconfig/scalc/menubar/menubar.xml                             |    1 
 sc/uiconfig/scalc/ui/randomnumbergenerator.ui                     |  388 +++++++
 22 files changed, 1149 insertions(+), 231 deletions(-)

New commits:
commit 5c05b1cabcf7f6a7f490ae6fc4bc145e75229752
Author: Tomaž Vajngerl <quikee at gmail.com>
Date:   Sun Jul 14 22:18:14 2013 +0200

    fdo#66477 Random Number Generation added to menu>fill.
    
    Added dialog for random number generation to fill menu into calc.
    Initial implementation has uniform, uniform integer, cauchy,
    bernoulli, binomial, negative binomial, chi squared and geometric
    distribution. Others can quickly be added.
    
    Change-Id: Id5c1f27462f1fe87eddedf415b9c149fb943404a

diff --git a/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu b/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu
index bb7cdac..3df5946 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu
@@ -624,6 +624,14 @@
           <value xml:lang="en-US">S~eries...</value>
         </prop>
       </node>
+      <node oor:name=".uno:RandomNumberGeneratorDialog" oor:op="replace">
+        <prop oor:name="Label" oor:type="xs:string">
+          <value xml:lang="en-US">Fill R~andom Number...</value>
+        </prop>
+        <prop oor:name="ContextLabel" oor:type="xs:string">
+          <value xml:lang="en-US">R~andom Number...</value>
+        </prop>
+      </node>
       <node oor:name=".uno:EditHeaderAndFooter" oor:op="replace">
         <prop oor:name="Label" oor:type="xs:string">
           <value xml:lang="en-US">~Headers & Footers...</value>
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index d431c3c..c72a967 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -473,6 +473,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
     sc/source/ui/sidebar/CellBorderStylePopup \
     sc/source/ui/sidebar/NumberFormatPropertyPanel \
 	sc/source/ui/sidebar/ScPanelFactory \
+	sc/source/ui/StatisticsDialogs/RandomNumberGeneratorDialog \
 	sc/source/ui/undo/areasave \
 	sc/source/ui/undo/refundo \
 	sc/source/ui/undo/target \
diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc
index 5bfe313..d163480 100644
--- a/sc/inc/sc.hrc
+++ b/sc/inc/sc.hrc
@@ -29,7 +29,7 @@
 #include "helpids.h"
 
 #define VAR_ARGS                30 // variable Parameter in scfuncs.src
-#define PAIRED_VAR_ARGS			(VAR_ARGS + VAR_ARGS)
+#define PAIRED_VAR_ARGS         (VAR_ARGS + VAR_ARGS)
 
 // areas
 
@@ -252,6 +252,8 @@
 #define SID_OPENDLG_ICONSET         (SC_MESSAGE_START + 68)
 #define SID_OPENDLG_CONDDATE        (SC_MESSAGE_START + 69)
 
+#define SID_OPENDLG_RANDOM_NUMBER_GENERATOR (SC_MESSAGE_START + 70)
+
 // functions
 
 
diff --git a/sc/sdi/cellsh.sdi b/sc/sdi/cellsh.sdi
index b889801..683ddc8 100644
--- a/sc/sdi/cellsh.sdi
+++ b/sc/sdi/cellsh.sdi
@@ -147,6 +147,7 @@ interface CellSelection
     FID_FILL_TAB        [ ExecMethod = ExecuteEdit; StateMethod = GetState; ]
     FID_FILL_SERIES     [ ExecMethod = ExecuteEdit; StateMethod = GetBlockState; ]
     FID_FILL_AUTO       [ ExecMethod = ExecuteEdit; StateMethod = GetState; ]
+    SID_OPENDLG_RANDOM_NUMBER_GENERATOR     [ ExecMethod = ExecuteEdit; StateMethod = GetBlockState; ]
     SID_MARKDATAAREA    [ ExecMethod = ExecuteMove; StateMethod = GetStateCursor; ]
     SID_MARKARRAYFORMULA [ ExecMethod = ExecuteMove; StateMethod = GetStateCursor; ]
     SID_SETINPUTMODE    [ ExecMethod = ExecuteMove; StateMethod = GetStateCursor; ]
@@ -434,4 +435,3 @@ shell ScCellShell : ScFormatShell
 {
     import Cell[Automation];
 }
-
diff --git a/sc/sdi/scalc.sdi b/sc/sdi/scalc.sdi
index ddcf8d4..9520604 100644
--- a/sc/sdi/scalc.sdi
+++ b/sc/sdi/scalc.sdi
@@ -2942,6 +2942,32 @@ SfxVoidItem GoalSeekDialog SID_OPENDLG_SOLVE
     GroupId = GID_OPTIONS;
 ]
 
+SfxVoidItem RandomNumberGeneratorDialog SID_OPENDLG_RANDOM_NUMBER_GENERATOR
+()
+[
+    /* flags: */
+    AutoUpdate = FALSE,
+    Cachable = Cachable,
+    FastCall = FALSE,
+    HasCoreId = FALSE,
+    HasDialog = TRUE,
+    ReadOnlyDoc = TRUE,
+    Toggle = FALSE,
+    Container = FALSE,
+    RecordAbsolute = FALSE,
+    RecordPerSet;
+    Synchron;
+
+    /* config: */
+    AccelConfig = TRUE,
+    MenuConfig = TRUE,
+    StatusBarConfig = FALSE,
+    ToolBoxConfig = TRUE,
+    GroupId = GID_OPTIONS;
+]
+
+
+
 //--------------------------------------------------------------------------
 SfxVoidItem SolverDialog SID_OPENDLG_OPTSOLVER
 ()
diff --git a/sc/source/ui/StatisticsDialogs/RandomNumberGeneratorDialog.cxx b/sc/source/ui/StatisticsDialogs/RandomNumberGeneratorDialog.cxx
new file mode 100644
index 0000000..80a2da7
--- /dev/null
+++ b/sc/source/ui/StatisticsDialogs/RandomNumberGeneratorDialog.cxx
@@ -0,0 +1,486 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#include <sfx2/dispatch.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/undo.hxx>
+
+#include "rangelst.hxx"
+#include "scitems.hxx"
+#include "docsh.hxx"
+#include "document.hxx"
+#include "uiitems.hxx"
+#include "reffact.hxx"
+#include "scresid.hxx"
+#include "random.hxx"
+#include "docfunc.hxx"
+#include "globstr.hrc"
+#include "sc.hrc"
+
+#include <boost/random.hpp>
+#include <boost/random/uniform_real_distribution.hpp>
+#include <boost/random/uniform_int_distribution.hpp>
+#include <boost/random/binomial_distribution.hpp>
+#include <boost/random/normal_distribution.hpp>
+#include <boost/random/cauchy_distribution.hpp>
+#include <boost/random/bernoulli_distribution.hpp>
+#include <boost/random/binomial_distribution.hpp>
+#include <boost/random/chi_squared_distribution.hpp>
+#include <boost/random/geometric_distribution.hpp>
+#include <boost/random/negative_binomial_distribution.hpp>
+
+#include "RandomNumberGeneratorDialog.hxx"
+
+#define ABS_DREF3D SCA_VALID | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE | SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE | SCA_TAB2_ABSOLUTE | SCA_TAB_3D
+
+namespace
+{
+
+static const sal_Int64 DIST_UNIFORM             = 0;
+static const sal_Int64 DIST_NORMAL              = 1;
+static const sal_Int64 DIST_CAUCHY              = 2;
+static const sal_Int64 DIST_BERNOULLI           = 3;
+static const sal_Int64 DIST_BINOMIAL            = 4;
+static const sal_Int64 DIST_CHI_SQUARED         = 5;
+static const sal_Int64 DIST_GEOMETRIC           = 6;
+static const sal_Int64 DIST_NEGATIVE_BINOMIAL   = 7;
+static const sal_Int64 DIST_UNIFORM_INTEGER     = 8;
+
+static const sal_Int64 PERCISION   = 10000;
+static const sal_Int64 DIGITS      = 4;
+}
+
+ScRandomNumberGeneratorDialog::ScRandomNumberGeneratorDialog(
+        SfxBindings* pB, SfxChildWindow* pCW, Window* pParent, ScViewData* pViewData ) :
+    ScAnyRefDlg     ( pB, pCW, pParent, "RandomNumberGeneratorDialog", "modules/scalc/ui/randomnumbergenerator.ui" ),
+    mViewData       ( pViewData ),
+    mDocument       ( pViewData->GetDocument() ),
+    mAddressDetails ( mDocument->GetAddressConvention(), 0, 0 ),
+    mDialogLostFocus( false )
+{
+    get(mpFtVariableCell, "cell-range-label");
+    get(mpEdVariableCell, "cell-range-edit");
+    mpEdVariableCell->SetReferences(this, mpFtVariableCell);
+    get(mpRBVariableCell, "cell-range-button");
+    mpRBVariableCell->SetReferences(this, mpEdVariableCell);
+
+    get(mpButtonOk,     "ok");
+    get(mpButtonApply,  "apply");
+    get(mpButtonCancel, "cancel");
+
+    get(mpParameter1Value, "parameter1-spin");
+    get(mpParameter1Text,  "parameter1-label");
+    get(mpParameter2Value, "parameter2-spin");
+    get(mpParameter2Text,  "parameter2-label");
+
+    get(mpEnableSeed, "enable-seed-check");
+    get(mpSeed, "seed-spin");
+
+    get(mpDistributionCombo, "distribution-combo");
+
+    Init();
+    GetRangeFromSelection();
+}
+
+void ScRandomNumberGeneratorDialog::Init()
+{
+    mpButtonOk->SetClickHdl( LINK( this, ScRandomNumberGeneratorDialog, OkClicked ) );
+    mpButtonCancel->SetClickHdl( LINK( this, ScRandomNumberGeneratorDialog, CancelClicked ) );
+    mpButtonApply->SetClickHdl( LINK( this, ScRandomNumberGeneratorDialog, ApplyClicked ) );
+
+    Link aLink = LINK( this, ScRandomNumberGeneratorDialog, GetFocusHandler );
+    mpEdVariableCell->SetGetFocusHdl( aLink );
+    mpRBVariableCell->SetGetFocusHdl( aLink );
+
+    aLink = LINK( this, ScRandomNumberGeneratorDialog, LoseFocusHandler );
+    mpEdVariableCell->SetLoseFocusHdl ( aLink );
+    mpRBVariableCell->SetLoseFocusHdl ( aLink );
+
+    mpParameter1Value->SetModifyHdl( LINK( this, ScRandomNumberGeneratorDialog, Parameter1ValueModified ));
+    mpParameter2Value->SetModifyHdl( LINK( this, ScRandomNumberGeneratorDialog, Parameter2ValueModified ));
+
+    mpDistributionCombo->SetSelectHdl( LINK( this, ScRandomNumberGeneratorDialog, DistributionChanged ));
+
+    mpEnableSeed->SetToggleHdl( LINK( this, ScRandomNumberGeneratorDialog, SeedCheckChanged ));
+
+    mpParameter1Value->SetMin( SAL_MIN_INT64 );
+    mpParameter1Value->SetMax( SAL_MAX_INT64 );
+    mpParameter2Value->SetMin( SAL_MIN_INT64 );
+    mpParameter2Value->SetMax( SAL_MAX_INT64 );
+
+    DistributionChanged(NULL);
+    SeedCheckChanged(NULL);
+}
+
+void ScRandomNumberGeneratorDialog::GetRangeFromSelection()
+{
+    String  aCurrentString;
+
+    SCCOL   nStartCol   = 0;
+    SCROW   nStartRow   = 0;
+    SCTAB   nStartTab   = 0;
+    SCCOL   nEndCol     = 0;
+    SCROW   nEndRow     = 0;
+    SCTAB   nEndTab     = 0;
+
+    mViewData->GetSimpleArea( nStartCol, nStartRow, nStartTab,
+                              nEndCol,   nEndRow,  nEndTab );
+
+    mCurrentRange = ScRange( ScAddress( nStartCol, nStartRow, nStartTab ),
+                            ScAddress( nEndCol,   nEndRow,   nEndTab ) );
+
+    mCurrentRange.Format( aCurrentString, ABS_DREF3D, mDocument, mAddressDetails );
+
+    mpEdVariableCell->SetText( aCurrentString );
+}
+
+
+ScRandomNumberGeneratorDialog::~ScRandomNumberGeneratorDialog()
+{
+}
+
+void ScRandomNumberGeneratorDialog::SetActive()
+{
+    if ( mDialogLostFocus )
+    {
+        mDialogLostFocus = false;
+        if( mpEdVariableCell )
+            mpEdVariableCell->GrabFocus();
+    }
+    else
+    {
+        GrabFocus();
+    }
+    RefInputDone();
+}
+
+sal_Bool ScRandomNumberGeneratorDialog::Close()
+{
+    return DoClose( ScRandomNumberGeneratorDialogWrapper::GetChildWindowId() );
+}
+
+void ScRandomNumberGeneratorDialog::SetReference( const ScRange& rReferenceRange, ScDocument* pDocument )
+{
+    if ( mpEdVariableCell->IsEnabled() )
+    {
+        if ( rReferenceRange.aStart != rReferenceRange.aEnd )
+            RefInputStart( mpEdVariableCell );
+
+        mCurrentRange = rReferenceRange;
+
+        String aReferenceString;
+        mCurrentRange.Format( aReferenceString, ABS_DREF3D, pDocument, mAddressDetails );
+        mpEdVariableCell->SetRefString( aReferenceString );
+    }
+}
+
+void ScRandomNumberGeneratorDialog::SelectGeneratorAndGenerateNumbers()
+{
+    sal_Int16 aSelectedIndex = mpDistributionCombo-> GetSelectEntryPos();
+    sal_Int64 aSelectedId = (sal_Int64) mpDistributionCombo->GetEntryData(aSelectedIndex);
+
+    sal_uInt32 seedValue;
+
+    if( mpEnableSeed->IsChecked() )
+    {
+        seedValue = mpSeed->GetValue();
+    }
+    else
+    {
+        TimeValue now;
+        osl_getSystemTime(&now);
+        seedValue = now.Nanosec;
+    }
+
+    boost::mt19937 seed(seedValue);
+
+    sal_Int64 parameterInteger1 = mpParameter1Value->GetValue();
+    sal_Int64 parameterInteger2 = mpParameter2Value->GetValue();
+
+    double parameter1 = parameterInteger1 / static_cast<double>(PERCISION);
+    double parameter2 = parameterInteger2 / static_cast<double>(PERCISION);
+
+    switch(aSelectedId)
+    {
+        case DIST_UNIFORM:
+        {
+            boost::random::uniform_real_distribution<> distribution(parameter1, parameter2);
+            boost::variate_generator<boost::mt19937&, boost::random::uniform_real_distribution<> > rng(seed, distribution);
+            GenerateNumbers(rng, OUString("Uniform Real"));
+            break;
+        }
+        case DIST_UNIFORM_INTEGER:
+        {
+            boost::random::uniform_int_distribution<> distribution(parameterInteger1, parameterInteger2);
+            boost::variate_generator<boost::mt19937&, boost::random::uniform_int_distribution<> > rng(seed, distribution);
+            GenerateNumbers(rng, OUString("Uniform Integer"));
+            break;
+        }
+        case DIST_NORMAL:
+        {
+            boost::random::normal_distribution<> distribution(parameter1, parameter2);
+            boost::variate_generator<boost::mt19937&, boost::random::normal_distribution<> > rng(seed, distribution);
+            GenerateNumbers(rng, OUString("Normal"));
+            break;
+        }
+        case DIST_CAUCHY:
+        {
+            boost::random::cauchy_distribution<> distribution(parameter1);
+            boost::variate_generator<boost::mt19937&, boost::random::cauchy_distribution<> > rng(seed, distribution);
+            GenerateNumbers(rng, OUString("Cauchy"));
+            break;
+        }
+        case DIST_BERNOULLI:
+        {
+            boost::random::bernoulli_distribution<> distribution(parameter1);
+            boost::variate_generator<boost::mt19937&, boost::random::bernoulli_distribution<> > rng(seed, distribution);
+            GenerateNumbers(rng, OUString("Bernoulli"));
+            break;
+        }
+        case DIST_BINOMIAL:
+        {
+            boost::random::binomial_distribution<> distribution(parameterInteger2, parameter1);
+            boost::variate_generator<boost::mt19937&, boost::random::binomial_distribution<> > rng(seed, distribution);
+            GenerateNumbers(rng, OUString("Binomial"));
+            break;
+        }
+        case DIST_NEGATIVE_BINOMIAL:
+        {
+            boost::random::negative_binomial_distribution<> distribution(parameterInteger2, parameter1);
+            boost::variate_generator<boost::mt19937&, boost::random::negative_binomial_distribution<> > rng(seed, distribution);
+            GenerateNumbers(rng, OUString("Negative Binomial"));
+            break;
+        }
+        case DIST_CHI_SQUARED:
+        {
+            boost::random::chi_squared_distribution<> distribution(parameter1);
+            boost::variate_generator<boost::mt19937&, boost::random::chi_squared_distribution<> > rng(seed, distribution);
+            GenerateNumbers(rng, OUString("Chi Squared"));
+            break;
+        }
+        case DIST_GEOMETRIC:
+        {
+            boost::random::geometric_distribution<> distribution(parameter1);
+            boost::variate_generator<boost::mt19937&, boost::random::geometric_distribution<> > rng(seed, distribution);
+            GenerateNumbers(rng, OUString("Geometric"));
+            break;
+        }
+    }
+}
+
+template<class RNG>
+void ScRandomNumberGeneratorDialog::GenerateNumbers(RNG randomGenerator, OUString aDistributionName)
+{
+    OUString aUndo("Random (");
+    aUndo += aDistributionName;
+    aUndo += ")";
+    ScDocShell* pDocShell = mViewData->GetDocShell();
+    svl::IUndoManager* pUndoManager = pDocShell->GetUndoManager();
+    pUndoManager->EnterListAction( aUndo, aUndo );
+
+    SCROW nRowStart = mCurrentRange.aStart.Row();
+    SCROW nRowEnd   = mCurrentRange.aEnd.Row();
+    SCCOL nColStart = mCurrentRange.aStart.Col();
+    SCCOL nColEnd   = mCurrentRange.aEnd.Col();
+    SCTAB nTabStart = mCurrentRange.aStart.Tab();
+    SCTAB nTabEnd   = mCurrentRange.aEnd.Tab();
+
+    for (SCROW nTab = nTabStart; nTab <= nTabEnd; nTab++)
+    {
+        for (SCROW nRow = nRowStart; nRow <= nRowEnd; nRow++)
+        {
+            for (SCCOL nCol = nColStart; nCol <= nColEnd; nCol++)
+            {
+                pDocShell->GetDocFunc().SetValueCell(ScAddress(nCol, nRow, nTab), randomGenerator(), true);
+            }
+        }
+    }
+
+    pUndoManager->LeaveListAction();
+
+    pDocShell->PostPaint( mCurrentRange, PAINT_GRID );
+}
+
+IMPL_LINK( ScRandomNumberGeneratorDialog, OkClicked, PushButton*, /*pButton*/ )
+{
+    SelectGeneratorAndGenerateNumbers();
+    Close();
+    return 0;
+}
+
+
+IMPL_LINK( ScRandomNumberGeneratorDialog, ApplyClicked, PushButton*, /*pButton*/ )
+{
+    SelectGeneratorAndGenerateNumbers();
+    return 0;
+}
+
+IMPL_LINK( ScRandomNumberGeneratorDialog, CancelClicked, PushButton*, /*pButton*/ )
+{
+    Close();
+    return 0;
+}
+
+IMPL_LINK( ScRandomNumberGeneratorDialog, GetFocusHandler, Control*, pCtrl )
+{
+    Edit* pEdit = NULL;
+
+    if( (pCtrl == (Control*)mpEdVariableCell) || (pCtrl == (Control*)mpRBVariableCell) )
+        pEdit = mpEdVariableCell;
+
+    if( pEdit )
+        pEdit->SetSelection( Selection( 0, SELECTION_MAX ) );
+
+    return 0;
+}
+
+IMPL_LINK_NOARG(ScRandomNumberGeneratorDialog, LoseFocusHandler)
+{
+    mDialogLostFocus = !IsActive();
+    return 0;
+}
+
+IMPL_LINK_NOARG(ScRandomNumberGeneratorDialog, Parameter1ValueModified)
+{
+    sal_Int16 aSelectedIndex = mpDistributionCombo-> GetSelectEntryPos();
+    sal_Int64 aSelectedId = (sal_Int64) mpDistributionCombo->GetEntryData(aSelectedIndex);
+    if (aSelectedId == DIST_UNIFORM ||
+        aSelectedId == DIST_UNIFORM_INTEGER)
+    {
+        sal_Int64 min = mpParameter1Value->GetValue();
+        sal_Int64 max = mpParameter2Value->GetValue();
+        if(min > max)
+        {
+            mpParameter2Value->SetValue(min);
+        }
+    }
+    return 0;
+}
+
+IMPL_LINK_NOARG(ScRandomNumberGeneratorDialog, Parameter2ValueModified)
+{
+    sal_Int16 aSelectedIndex = mpDistributionCombo-> GetSelectEntryPos();
+    sal_Int64 aSelectedId = (sal_Int64) mpDistributionCombo->GetEntryData(aSelectedIndex);
+    if (aSelectedId == DIST_UNIFORM ||
+        aSelectedId == DIST_UNIFORM_INTEGER)
+    {
+        sal_Int64 min = mpParameter1Value->GetValue();
+        sal_Int64 max = mpParameter2Value->GetValue();
+        if(min > max)
+        {
+            mpParameter1Value->SetValue(max);
+        }
+    }
+    return 0;
+}
+
+IMPL_LINK_NOARG(ScRandomNumberGeneratorDialog, SeedCheckChanged)
+{
+    mpSeed->Enable(mpEnableSeed->IsChecked());
+    return 0;
+}
+
+IMPL_LINK_NOARG(ScRandomNumberGeneratorDialog, DistributionChanged)
+{
+    sal_Int16 aSelectedIndex = mpDistributionCombo-> GetSelectEntryPos();
+    sal_Int64 aSelectedId = (sal_Int64) mpDistributionCombo->GetEntryData(aSelectedIndex);
+
+    mpParameter1Value->SetMin( SAL_MIN_INT64 );
+    mpParameter1Value->SetMax( SAL_MAX_INT64 );
+    mpParameter2Value->SetMin( SAL_MIN_INT64 );
+    mpParameter2Value->SetMax( SAL_MAX_INT64 );
+
+    mpParameter1Value->SetDecimalDigits(DIGITS);
+    mpParameter1Value->SetSpinSize(PERCISION);
+
+    mpParameter2Value->SetDecimalDigits(DIGITS);
+    mpParameter2Value->SetSpinSize(PERCISION);
+
+    switch(aSelectedId)
+    {
+        case DIST_UNIFORM:
+        {
+            mpParameter1Text->SetText(OUString("Minimum"));
+            mpParameter2Text->SetText(OUString("Maximum"));
+            mpParameter2Text->Show();
+            mpParameter2Value->Show();
+            break;
+        }
+        case DIST_UNIFORM_INTEGER:
+        {
+            mpParameter1Text->SetText(OUString("Minimum"));
+            mpParameter1Value->SetDecimalDigits(0);
+            mpParameter1Value->SetSpinSize(1);
+
+            mpParameter2Text->SetText(OUString("Maximum"));
+            mpParameter2Value->SetDecimalDigits(0);
+            mpParameter2Value->SetSpinSize(1);
+
+            mpParameter2Text->Show();
+            mpParameter2Value->Show();
+            break;
+        }
+        case DIST_NORMAL:
+        {
+            mpParameter1Text->SetText(OUString("Mean"));
+            mpParameter2Text->SetText(OUString("Standard Deviation"));
+            mpParameter2Text->Show();
+            mpParameter2Value->Show();
+            break;
+        }
+        case DIST_CAUCHY:
+        {
+            mpParameter1Text->SetText(OUString("Median"));
+            mpParameter2Text->SetText(OUString("Sigma"));
+            mpParameter2Text->Show();
+            mpParameter2Value->Show();
+            break;
+        }
+        case DIST_BERNOULLI:
+        case DIST_GEOMETRIC:
+        {
+            mpParameter1Text->SetText(OUString("p Value"));
+            mpParameter1Value->SetMin(         0 );
+            mpParameter1Value->SetMax( PERCISION );
+            mpParameter1Value->SetSpinSize(1000);
+
+            mpParameter2Text->Hide();
+            mpParameter2Value->Hide();
+            break;
+        }
+        case DIST_BINOMIAL:
+        case DIST_NEGATIVE_BINOMIAL:
+        {
+            mpParameter1Text->SetText(OUString("p Value"));
+            mpParameter1Value->SetMin(         0 );
+            mpParameter1Value->SetMax( PERCISION );
+            mpParameter1Value->SetSpinSize(1000);
+
+            mpParameter2Text->SetText(OUString("Number Of Trials"));
+            mpParameter2Text->Show();
+            mpParameter2Value->Show();
+            mpParameter2Value->SetDecimalDigits(0);
+            mpParameter2Value->SetSpinSize(1);
+            break;
+        }
+        case DIST_CHI_SQUARED:
+        {
+            mpParameter1Text->SetText(OUString("nu Value"));
+
+            mpParameter2Text->Hide();
+            mpParameter2Value->Hide();
+            break;
+        }
+    }
+    return 0;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/app/scdll.cxx b/sc/source/ui/app/scdll.cxx
index b31a45e..553399f 100644
--- a/sc/source/ui/app/scdll.cxx
+++ b/sc/source/ui/app/scdll.cxx
@@ -270,6 +270,8 @@ void ScDLL::Init()
     ScColRowNameRangesDlgWrapper::RegisterChildWindow(false, pMod);
     ScFormulaDlgWrapper         ::RegisterChildWindow(false, pMod);
 
+    ScRandomNumberGeneratorDialogWrapper::RegisterChildWindow(false, pMod);
+
     // First docking Window for Calc
     ScFunctionChildWindow       ::RegisterChildWindow(false, pMod);
 
diff --git a/sc/source/ui/inc/RandomNumberGeneratorDialog.hxx b/sc/source/ui/inc/RandomNumberGeneratorDialog.hxx
new file mode 100644
index 0000000..1f5ea80
--- /dev/null
+++ b/sc/source/ui/inc/RandomNumberGeneratorDialog.hxx
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#ifndef RANDOM_NUMBER_GENERATION_HXX
+#define RANDOM_NUMBER_GENERATION_HXX
+
+#include "global.hxx"
+#include "address.hxx"
+#include "anyrefdg.hxx"
+
+
+#include <vcl/fixed.hxx>
+#include <vcl/group.hxx>
+#include <vcl/lstbox.hxx>
+
+class ScRandomNumberGeneratorDialog : public ScAnyRefDlg
+{
+public:
+    ScRandomNumberGeneratorDialog(
+        SfxBindings* pB, SfxChildWindow* pCW,
+        Window* pParent, ScViewData* pViewData );
+
+    virtual ~ScRandomNumberGeneratorDialog();
+
+    virtual void        SetReference( const ScRange& rRef, ScDocument* pDoc );
+    virtual void        SetActive();
+    virtual sal_Bool    Close();
+
+private:
+    // Widgets
+    FixedText*          mpFtVariableCell;
+    formula::RefEdit*   mpEdVariableCell;
+    formula::RefButton* mpRBVariableCell;
+    ListBox*            mpDistributionCombo;
+    FixedText*          mpParameter1Text;
+    NumericField*       mpParameter1Value;
+    FixedText*          mpParameter2Text;
+    NumericField*       mpParameter2Value;
+    NumericField*       mpSeed;
+    CheckBox*           mpEnableSeed;
+    PushButton*         mpButtonApply;
+    OKButton*           mpButtonOk;
+    CancelButton*       mpButtonCancel;
+
+    // Data
+    ScViewData*         mViewData;
+    ScDocument*         mDocument;
+
+    ScRange             mCurrentRange;
+    ScAddress::Details  mAddressDetails;
+
+    bool                mDialogLostFocus;
+
+    void Init();
+    void GetRangeFromSelection();
+
+    template<class RNG>
+    void GenerateNumbers(RNG randomGenerator, OUString aDistributionName);
+
+    void SelectGeneratorAndGenerateNumbers();
+
+    DECL_LINK( OkClicked,        PushButton* );
+    DECL_LINK( CancelClicked,    PushButton* );
+    DECL_LINK( ApplyClicked,     PushButton* );
+    DECL_LINK( GetFocusHandler,  Control* );
+    DECL_LINK( LoseFocusHandler, void* );
+
+    DECL_LINK( Parameter1ValueModified, void* );
+    DECL_LINK( Parameter2ValueModified, void* );
+    DECL_LINK( DistributionChanged, void* );
+    DECL_LINK( SeedCheckChanged, void* );
+
+};
+
+#endif // SC_SOLVRDLG_HXX
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/inc/reffact.hxx b/sc/source/ui/inc/reffact.hxx
index 215836c..aa94ff1 100644
--- a/sc/source/ui/inc/reffact.hxx
+++ b/sc/source/ui/inc/reffact.hxx
@@ -50,6 +50,8 @@ DECL_WRAPPER_WITHID(ScColRowNameRangesDlgWrapper)
 DECL_WRAPPER_WITHID(ScFormulaDlgWrapper)
 DECL_WRAPPER_WITHID(ScHighlightChgDlgWrapper)
 
+DECL_WRAPPER_WITHID(ScRandomNumberGeneratorDialogWrapper)
+
 class ScAcceptChgDlgWrapper: public SfxChildWindow
 {
     public:
diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx
index 9431b90..05d55f4 100644
--- a/sc/source/ui/view/cellsh.cxx
+++ b/sc/source/ui/view/cellsh.cxx
@@ -171,6 +171,7 @@ void ScCellShell::GetBlockState( SfxItemSet& rSet )
             }
             break;
             case FID_FILL_SERIES:       // fill block
+            case SID_OPENDLG_RANDOM_NUMBER_GENERATOR:
             case SID_OPENDLG_TABOP:     // multiple-cell operations, are at least 2 cells marked?
                 if (pDoc->GetChangeTrack()!=NULL &&nWhich ==SID_OPENDLG_TABOP)
                     bDisable = sal_True;
diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx
index 23bbec0..daac7ec 100644
--- a/sc/source/ui/view/cellsh1.cxx
+++ b/sc/source/ui/view/cellsh1.cxx
@@ -903,7 +903,15 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq )
                 }
             }
             break;
+        case SID_OPENDLG_RANDOM_NUMBER_GENERATOR:
+            {
+                sal_uInt16          nId  = ScRandomNumberGeneratorDialogWrapper::GetChildWindowId();
+                SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+                SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
 
+                pScMod->SetRefDialog( nId, pWnd ? false : sal_True );
+            }
+            break;
         //
         //  disposal (Outlines)
         //  SID_AUTO_OUTLINE, SID_OUTLINE_DELETEALL in Execute (in docsh.idl)
diff --git a/sc/source/ui/view/reffact.cxx b/sc/source/ui/view/reffact.cxx
index 687b527..cf7e796 100644
--- a/sc/source/ui/view/reffact.cxx
+++ b/sc/source/ui/view/reffact.cxx
@@ -50,6 +50,9 @@ SFX_IMPL_MODELESSDIALOG_WITHID(ScFormulaDlgWrapper, SID_OPENDLG_FUNCTION )
 SFX_IMPL_MODELESSDIALOG_WITHID(ScAcceptChgDlgWrapper, FID_CHG_ACCEPT )
 SFX_IMPL_MODELESSDIALOG_WITHID(ScHighlightChgDlgWrapper, FID_CHG_SHOW )
 SFX_IMPL_MODELESSDIALOG_WITHID(ScSimpleRefDlgWrapper, WID_SIMPLE_REF )
+
+SFX_IMPL_MODELESSDIALOG_WITHID(ScRandomNumberGeneratorDialogWrapper, SID_OPENDLG_RANDOM_NUMBER_GENERATOR )
+
 SFX_IMPL_CHILDWINDOW_WITHID(ScValidityRefChildWin, SID_VALIDITY_REFERENCE)
 
 SfxChildWinInfo ScValidityRefChildWin::GetInfo() const
@@ -177,6 +180,8 @@ IMPL_CHILD_CTOR( ScPrintAreasDlgWrapper, SID_OPENDLG_EDIT_PRINTAREA )
 IMPL_CHILD_CTOR( ScFormulaDlgWrapper, SID_OPENDLG_FUNCTION )
 
 
+IMPL_CHILD_CTOR( ScRandomNumberGeneratorDialogWrapper, SID_OPENDLG_RANDOM_NUMBER_GENERATOR )
+
 //-------------------------------------------------------------------------
 // ScSimpleRefDlgWrapper
 //-------------------------------------------------------------------------
diff --git a/sc/source/ui/view/tabvwsh.cxx b/sc/source/ui/view/tabvwsh.cxx
index 7949e17..c53bf66 100644
--- a/sc/source/ui/view/tabvwsh.cxx
+++ b/sc/source/ui/view/tabvwsh.cxx
@@ -80,6 +80,8 @@ SFX_IMPL_INTERFACE(ScTabViewShell,SfxViewShell,ScResId(SCSTR_TABVIEWSHELL))
     SFX_CHILDWINDOW_REGISTRATION(GalleryChildWindow::GetChildWindowId());
     SFX_CHILDWINDOW_REGISTRATION(ScSpellDialogChildWindow::GetChildWindowId());
     SFX_CHILDWINDOW_REGISTRATION(ScValidityRefChildWin::GetChildWindowId());
+
+    SFX_CHILDWINDOW_REGISTRATION(ScRandomNumberGeneratorDialogWrapper::GetChildWindowId());
 }
 
 SFX_IMPL_NAMED_VIEWFACTORY( ScTabViewShell, "Default" )
diff --git a/sc/source/ui/view/tabvwshc.cxx b/sc/source/ui/view/tabvwshc.cxx
index f8e7763..a613c77b 100644
--- a/sc/source/ui/view/tabvwshc.cxx
+++ b/sc/source/ui/view/tabvwshc.cxx
@@ -61,6 +61,8 @@
 #include "condformatdlg.hxx"
 #include "xmlsourcedlg.hxx"
 
+#include "RandomNumberGeneratorDialog.hxx"
+
 //------------------------------------------------------------------
 
 void ScTabViewShell::SetCurRefDlgId( sal_uInt16 nNew )
@@ -311,6 +313,13 @@ SfxModelessDialog* ScTabViewShell::CreateRefDialog(
         }
         break;
 
+        case SID_OPENDLG_RANDOM_NUMBER_GENERATOR:
+        {
+            ScViewData*  pViewData  = GetViewData();
+            pResult = new ScRandomNumberGeneratorDialog( pB, pCW, pParent, pViewData );
+        }
+        break;
+
         case SID_OPENDLG_OPTSOLVER:
         {
             ScViewData* pViewData = GetViewData();
diff --git a/sc/uiconfig/scalc/menubar/menubar.xml b/sc/uiconfig/scalc/menubar/menubar.xml
index 6b29652..428b52c 100644
--- a/sc/uiconfig/scalc/menubar/menubar.xml
+++ b/sc/uiconfig/scalc/menubar/menubar.xml
@@ -99,6 +99,7 @@
                     <menu:menuitem menu:id=".uno:FillLeft"/>
                     <menu:menuitem menu:id=".uno:FillTable"/>
                     <menu:menuitem menu:id=".uno:FillSeries"/>
+                    <menu:menuitem menu:id=".uno:RandomNumberGeneratorDialog"/>
                 </menu:menupopup>
             </menu:menu>
             <menu:menuitem menu:id=".uno:Delete"/>
diff --git a/sc/uiconfig/scalc/ui/randomnumbergenerator.ui b/sc/uiconfig/scalc/ui/randomnumbergenerator.ui
new file mode 100644
index 0000000..fa05540
--- /dev/null
+++ b/sc/uiconfig/scalc/ui/randomnumbergenerator.ui
@@ -0,0 +1,388 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <!-- interface-requires LibreOffice 1.0 -->
+  <object class="GtkAdjustment" id="parameter1-adjustment">
+    <property name="upper">100</property>
+    <property name="value">1</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+  <object class="GtkListStore" id="distribution-liststore">
+    <columns>
+      <!-- column-name value -->
+      <column type="gchararray"/>
+      <!-- column-name id -->
+      <column type="gint"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">Uniform</col>
+        <col id="1">0</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Uniform Integer</col>
+        <col id="1">8</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Normal</col>
+        <col id="1">1</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Cauchy</col>
+        <col id="1">2</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Bernoulli</col>
+        <col id="1">3</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Binomial</col>
+        <col id="1">4</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Chi Squared</col>
+        <col id="1">5</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Geometric</col>
+        <col id="1">6</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Negative Binomial</col>
+        <col id="1">7</col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkAdjustment" id="parameter2-adjustment">
+    <property name="upper">100</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+  <object class="GtkDialog" id="RandomNumberGeneratorDialog">
+    <property name="can_focus">False</property>
+    <property name="border_width">5</property>
+    <property name="type_hint">dialog</property>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="dialog-vbox1">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area1">
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="apply">
+                <property name="label">gtk-apply</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="has_default">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="ok">
+                <property name="label">gtk-ok</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="has_default">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="cancel">
+                <property name="label">gtk-cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkFrame" id="frame1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label_xalign">0</property>
+            <property name="shadow_type">none</property>
+            <child>
+              <object class="GtkAlignment" id="alignment1">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="left_padding">12</property>
+                <child>
+                  <object class="GtkGrid" id="grid1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="row_spacing">6</property>
+                    <property name="column_spacing">12</property>
+                    <child>
+                      <object class="GtkLabel" id="cell-range-label">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Cell Range</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">0</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="foruilo-RefEdit" id="cell-range-edit">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="valign">center</property>
+                        <property name="hexpand">True</property>
+                        <property name="invisible_char">•</property>
+                        <property name="invisible_char_set">True</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">0</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="foruilo-RefButton" id="cell-range-button">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="receives_default">True</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">2</property>
+                        <property name="top_attach">0</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="distribution-label">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Distribution</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">1</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkComboBox" id="distribution-combo">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="hexpand">True</property>
+                        <property name="model">distribution-liststore</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">1</property>
+                        <property name="width">2</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSpinButton" id="seed-spin">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="hexpand">True</property>
+                        <property name="invisible_char">•</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">3</property>
+                        <property name="width">2</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="seed-label">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Seed</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">3</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkFrame" id="frame2">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label_xalign">0</property>
+                        <property name="shadow_type">in</property>
+                        <child>
+                          <object class="GtkAlignment" id="alignment2">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="top_padding">6</property>
+                            <property name="bottom_padding">6</property>
+                            <property name="left_padding">12</property>
+                            <property name="right_padding">12</property>
+                            <child>
+                              <object class="GtkGrid" id="grid2">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="row_spacing">6</property>
+                                <property name="column_spacing">12</property>
+                                <child>
+                                  <object class="GtkLabel" id="parameter1-label">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="hexpand">True</property>
+                                    <property name="xalign">0</property>
+                                    <property name="label" translatable="yes">...</property>
+                                  </object>
+                                  <packing>
+                                    <property name="left_attach">0</property>
+                                    <property name="top_attach">0</property>
+                                    <property name="width">1</property>
+                                    <property name="height">1</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkLabel" id="parameter2-label">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="hexpand">True</property>
+                                    <property name="xalign">0</property>
+                                    <property name="label" translatable="yes">...</property>
+                                  </object>
+                                  <packing>
+                                    <property name="left_attach">0</property>
+                                    <property name="top_attach">1</property>
+                                    <property name="width">1</property>
+                                    <property name="height">1</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkSpinButton" id="parameter1-spin">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="invisible_char">•</property>
+                                    <property name="invisible_char_set">True</property>
+                                    <property name="adjustment">parameter2-adjustment</property>
+                                    <property name="digits">4</property>
+                                  </object>
+                                  <packing>
+                                    <property name="left_attach">1</property>
+                                    <property name="top_attach">0</property>
+                                    <property name="width">1</property>
+                                    <property name="height">1</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkSpinButton" id="parameter2-spin">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="invisible_char">•</property>
+                                    <property name="invisible_char_set">True</property>
+                                    <property name="adjustment">parameter1-adjustment</property>
+                                    <property name="digits">4</property>
+                                  </object>
+                                  <packing>
+                                    <property name="left_attach">1</property>
+                                    <property name="top_attach">1</property>
+                                    <property name="width">1</property>
+                                    <property name="height">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                            </child>
+                          </object>
+                        </child>
+                        <child type="label">
+                          <object class="GtkLabel" id="label1">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="label" translatable="yes">Parameters</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">4</property>
+                        <property name="width">3</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkCheckButton" id="enable-seed-check">
+                        <property name="label" translatable="yes">Enable Custom Seed</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="receives_default">False</property>
+                        <property name="xalign">0</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">2</property>
+                        <property name="width">3</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child type="label">
+              <object class="GtkLabel" id="rng-label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Random Number Generator</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="0">apply</action-widget>
+      <action-widget response="0">ok</action-widget>
+      <action-widget response="0">cancel</action-widget>
+    </action-widgets>
+  </object>
+</interface>
commit bdb0619d6f28a2b0a9636077f576265d1305ca20
Author: Tomaž Vajngerl <quikee at gmail.com>
Date:   Sat Jul 13 11:05:17 2013 +0200

    Remove gauss.hxx from MovingAverageRegressionCurveCalculator.
    
    Change-Id: Ib1a781b7bf848a092dd000d5999fef00a409d92d

diff --git a/chart2/source/tools/MovingAverageRegressionCurveCalculator.cxx b/chart2/source/tools/MovingAverageRegressionCurveCalculator.cxx
index 22d72e4..6ec2757 100644
--- a/chart2/source/tools/MovingAverageRegressionCurveCalculator.cxx
+++ b/chart2/source/tools/MovingAverageRegressionCurveCalculator.cxx
@@ -23,7 +23,6 @@
 
 #include <rtl/math.hxx>
 #include <rtl/ustrbuf.hxx>
-#include "gauss.hxx"
 
 using namespace ::com::sun::star;
 
commit f879676b3b48477eb0d7de96efd67209e9ec74fa
Author: Tomaž Vajngerl <quikee at gmail.com>
Date:   Wed Jul 10 20:54:33 2013 +0200

    If you do DRY don't do it with a MACRO.
    
    Change-Id: I02f5d3c0540afeb3d925e605f1233f40d4e26370

diff --git a/sc/source/ui/miscdlgs/solvrdlg.cxx b/sc/source/ui/miscdlgs/solvrdlg.cxx
index 80395f1..b7eae47 100644
--- a/sc/source/ui/miscdlgs/solvrdlg.cxx
+++ b/sc/source/ui/miscdlgs/solvrdlg.cxx
@@ -32,15 +32,15 @@
 
 #define _SOLVRDLG_CXX
 #include "solvrdlg.hxx"
-#undef _SOLVERDLG_CXX
+#undef  _SOLVRDLG_CXX
 
-
-#define ERRORBOX(s) ErrorBox( this, WinBits( WB_OK | WB_DEF_OK), s ).Execute()
-
-
-//============================================================================
-//  class ScSolverDlg
-//----------------------------------------------------------------------------
+namespace
+{
+    void lclErrorDialog( Window* pParent, OUString aString )
+    {
+        ErrorBox( pParent, WinBits( WB_OK | WB_DEF_OK), aString ).Execute();
+    }
+}
 
 ScSolverDlg::ScSolverDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
                           ScDocument* pDocument,
@@ -165,22 +165,22 @@ void ScSolverDlg::RaiseError( ScSolverErr eError )
     switch ( eError )
     {
         case SOLVERR_NOFORMULA:
-            ERRORBOX( errMsgNoFormula );
+            lclErrorDialog( this, errMsgNoFormula );
             m_pEdFormulaCell->GrabFocus();
             break;
 
         case SOLVERR_INVALID_FORMULA:
-            ERRORBOX( errMsgInvalidForm );
+            lclErrorDialog( this, errMsgInvalidForm );
             m_pEdFormulaCell->GrabFocus();
             break;
 
         case SOLVERR_INVALID_VARIABLE:
-            ERRORBOX( errMsgInvalidVar );
+            lclErrorDialog( this, errMsgInvalidVar );
             m_pEdVariableCell->GrabFocus();
             break;
 
         case SOLVERR_INVALID_TARGETVALUE:
-            ERRORBOX( errMsgInvalidVal );
+            lclErrorDialog( this, errMsgInvalidVal );
             m_pEdTargetVal->GrabFocus();
             break;
     }
@@ -293,6 +293,4 @@ IMPL_LINK_NOARG(ScSolverDlg, LoseFocusHdl)
 }
 
 
-
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit c06ddaa0d7b97ef4a6738b5a5ce192e31d6e0d0d
Author: Tomaž Vajngerl <quikee at gmail.com>
Date:   Wed Jul 10 20:32:40 2013 +0200

    Use QR decomposition instead of gauss elimination for polynomial reg.
    
    Gauss elimination is not a stable algorithm so use QR decomposition
    (with other methods). Also use horner's method to evaluate a polynomial
    which is the prefered and more stable method of polynomial evaluation.
    Still this is not quite enough as you still have to multiply very large
    number with very small and you lose percision on high-degree polynomials
    or big X values. Some methods evaluate the polynomial in barycentric form
    but how to get the polynomial into the barycentric form is now the
    question.
    
    Change-Id: If0d93bc1f08253f015e814e187b5a2cb7f78ec49

diff --git a/chart2/source/inc/PolynomialRegressionCurveCalculator.hxx b/chart2/source/inc/PolynomialRegressionCurveCalculator.hxx
index e3b43a2..6c1d990 100644
--- a/chart2/source/inc/PolynomialRegressionCurveCalculator.hxx
+++ b/chart2/source/inc/PolynomialRegressionCurveCalculator.hxx
@@ -25,6 +25,7 @@
 namespace chart
 {
 
+
 class PolynomialRegressionCurveCalculator : public RegressionCurveCalculator
 {
 public:
@@ -57,7 +58,7 @@ private:
         throw (com::sun::star::lang::IllegalArgumentException,
                com::sun::star::uno::RuntimeException);
 
-    std::vector<double> mResult;
+    std::vector<double> mCoefficients;
 };
 
 } //  namespace chart
diff --git a/chart2/source/tools/PolynomialRegressionCurveCalculator.cxx b/chart2/source/tools/PolynomialRegressionCurveCalculator.cxx
index 19d224d..1c84731 100644
--- a/chart2/source/tools/PolynomialRegressionCurveCalculator.cxx
+++ b/chart2/source/tools/PolynomialRegressionCurveCalculator.cxx
@@ -24,11 +24,9 @@
 #include <cmath>
 #include <rtl/math.hxx>
 #include <rtl/ustrbuf.hxx>
-#include "gauss.hxx"
 
 using namespace com::sun::star;
 
-
 namespace chart
 {
 
@@ -49,80 +47,138 @@ void SAL_CALL PolynomialRegressionCurveCalculator::recalculateRegression(
     RegressionCalculationHelper::tDoubleVectorPair aValues(
         RegressionCalculationHelper::cleanup( aXValues, aYValues, RegressionCalculationHelper::isValid()));
 
-    sal_Int32 aNoElements = mForceIntercept ? mDegree : mDegree + 1;
-    sal_Int32 aNumberOfPowers = 2 * aNoElements - 1;
+    const sal_Int32 aNoValues = aValues.first.size();
 
-    std::vector<double> aPowers;
-    aPowers.resize(aNumberOfPowers, 0.0);
+    const sal_Int32 aNoPowers = mForceIntercept ? mDegree : mDegree + 1;
 
-    sal_Int32 aNoColumns = aNoElements;
-    sal_Int32 aNoRows    = aNoElements + 1;
+    mCoefficients.clear();
+    mCoefficients.resize(aNoPowers, 0.0);
 
-    std::vector<double> aMatrix;
-    aMatrix.resize(aNoColumns * aNoRows, 0.0);
+    double yAverage = 0.0;
 
-    const size_t aNoValues = aValues.first.size();
+    std::vector<double> aQRTransposed;
+    aQRTransposed.resize(aNoValues * aNoPowers, 0.0);
 
-    double yAverage = 0.0;
+    std::vector<double> yVector;
+    yVector.resize(aNoValues, 0.0);
 
-    for( size_t i = 0; i < aNoValues; ++i )
+    for(sal_Int32 i = 0; i < aNoValues; i++)
     {
-        double x = aValues.first[i];
-        double y = aValues.second[i];
+        double yValue = aValues.second[i];
+        if (mForceIntercept)
+            yValue -= mInterceptValue;
+        yVector[i] = yValue;
+        yAverage += yValue;
+    }
+    yAverage /= aNoValues;
 
-        for (sal_Int32 j = 0; j < aNumberOfPowers; j++)
+    for(sal_Int32 j = 0; j < aNoPowers; j++)
+    {
+        sal_Int32 aPower = mForceIntercept ? j+1 : j;
+        sal_Int32 aColumnIndex = j * aNoValues;
+        for(sal_Int32 i = 0; i < aNoValues; i++)
         {
-            if (mForceIntercept)
-                aPowers[j] += std::pow(x, (int) j + 2);
-            else
-                aPowers[j] += std::pow(x, (int) j);
+            double xValue = aValues.first[i];
+            aQRTransposed[i + aColumnIndex] = std::pow(xValue, aPower);
         }
+    }
+
+    // QR decomposition - based on org.apache.commons.math.linear.QRDecomposition from apache commons math (ASF)
+    sal_Int32 aMinorSize = std::min(aNoValues, aNoPowers);
+
+    std::vector<double> aDiagonal;
+    aDiagonal.resize(aMinorSize, 0.0);
 
-        for (sal_Int32 j = 0; j < aNoElements; j++)
+    // Calculate Householder reflectors
+    for (sal_Int32 aMinor = 0; aMinor < aMinorSize; aMinor++)
+    {
+        double aNormSqr = 0.0;
+        for (sal_Int32 x = aMinor; x < aNoValues; x++)
         {
-            if (mForceIntercept)
-                aMatrix[j * aNoRows + aNoElements] += std::pow(x, (int) j + 1) * ( y - mInterceptValue );
-            else
-                aMatrix[j * aNoRows + aNoElements] += std::pow(x, (int) j) * y;
+            double c = aQRTransposed[x + aMinor * aNoValues];
+            aNormSqr += c * c;
         }
 
-        yAverage += y;
-    }
+        double a;
+
+        if (aQRTransposed[aMinor + aMinor * aNoValues] > 0.0)
+            a = -std::sqrt(aNormSqr);
+        else
+            a = std::sqrt(aNormSqr);
+
+        aDiagonal[aMinor] = a;
 
-    yAverage = yAverage / aNoValues;
+        if (a != 0.0)
+        {
+            aQRTransposed[aMinor + aMinor * aNoValues] -= a;
 
-    for (sal_Int32 y = 0; y < aNoElements; y++)
+            for (sal_Int32 aColumn = aMinor + 1; aColumn < aNoPowers; aColumn++)
+            {
+                double alpha = 0.0;
+                for (sal_Int32 aRow = aMinor; aRow < aNoValues; aRow++)
+                {
+                    alpha -= aQRTransposed[aRow + aColumn * aNoValues] * aQRTransposed[aRow + aMinor * aNoValues];
+                }
+                alpha /= a * aQRTransposed[aMinor + aMinor * aNoValues];
+
+                for (sal_Int32 aRow = aMinor; aRow < aNoValues; aRow++)
+                {
+                    aQRTransposed[aRow + aColumn * aNoValues] -= alpha * aQRTransposed[aRow + aMinor * aNoValues];
+                }
+            }
+        }
+    }
+
+    // Solve the linear equation
+    for (sal_Int32 aMinor = 0; aMinor < aMinorSize; aMinor++)
     {
-        for (sal_Int32 x = 0; x < aNoElements; x++)
+        double aDotProduct = 0;
+
+        for (sal_Int32 aRow = aMinor; aRow < aNoValues; aRow++)
+        {
+            aDotProduct += yVector[aRow] * aQRTransposed[aRow + aMinor * aNoValues];
+        }
+        aDotProduct /= aDiagonal[aMinor] * aQRTransposed[aMinor + aMinor * aNoValues];
+
+        for (sal_Int32 aRow = aMinor; aRow < aNoValues; aRow++)
         {
-            aMatrix[y * aNoRows + x] = aPowers[y + x];
+            yVector[aRow] += aDotProduct * aQRTransposed[aRow + aMinor * aNoValues];
         }
+
     }
 
-    mResult.clear();
-    mResult.resize(aNoElements, 0.0);
+    for (sal_Int32 aRow = aDiagonal.size() - 1; aRow >= 0; aRow--)
+    {
+        yVector[aRow] /= aDiagonal[aRow];
+        double yRow = yVector[aRow];
+        mCoefficients[aRow] = yRow;
 
-    solve(aMatrix, aNoColumns, aNoRows, mResult, 1.0e-20);
+        for (sal_Int32 i = 0; i < aRow; i++)
+        {
+            yVector[i] -= yRow * aQRTransposed[i + aRow * aNoValues];
+        }
+    }
 
-    // Set intercept value if force intercept is enabled
-    if (mForceIntercept) {
-        mResult.insert( mResult.begin(), mInterceptValue );
+    if(mForceIntercept)
+    {
+        mCoefficients.insert(mCoefficients.begin(), mInterceptValue);
     }
 
     // Calculate correlation coeffitient
     double aSumError = 0.0;
     double aSumTotal = 0.0;
 
-    for( size_t i = 0; i < aNoValues; ++i )
+    for( sal_Int32 i = 0; i < aNoValues; i++ )
     {
-        double x = aValues.first[i];
+        double xValue = aValues.first[i];
         double yActual = aValues.second[i];
-        double yPredicted = getCurveValue( x );
+        double yPredicted = getCurveValue( xValue );
         aSumTotal += (yActual - yAverage) * (yActual - yAverage);
         aSumError += (yActual - yPredicted) * (yActual - yPredicted);
     }
 
     double aRSquared = 1.0 - (aSumError / aSumTotal);
+
     if (aRSquared > 0.0)
         m_fCorrelationCoeffitient = std::sqrt(aRSquared);
     else
@@ -136,15 +192,18 @@ double SAL_CALL PolynomialRegressionCurveCalculator::getCurveValue( double x )
     double fResult;
     rtl::math::setNan(&fResult);
 
-    if (mResult.empty())
+    if (mCoefficients.empty())
     {
         return fResult;
     }
 
+    sal_Int32 aNoCoefficients = (sal_Int32) mCoefficients.size();
+
+    // Horner's method
     fResult = 0.0;
-    for (size_t i = 0; i<mResult.size(); i++)
+    for (sal_Int32 i = aNoCoefficients - 1; i >= 0; i--)
     {
-        fResult += mResult[i] * std::pow(x, (int) i);
+        fResult = mCoefficients[i] + (x * fResult);
     }
     return fResult;
 }
@@ -167,10 +226,10 @@ OUString PolynomialRegressionCurveCalculator::ImplGetRepresentation(
 {
     OUStringBuffer aBuf( "f(x) = ");
 
-    sal_Int32 aLastIndex = mResult.size() - 1;
+    sal_Int32 aLastIndex = mCoefficients.size() - 1;
     for (sal_Int32 i = aLastIndex; i >= 0; i--)
     {
-        double aValue = mResult[i];
+        double aValue = mCoefficients[i];
         if (aValue == 0.0)
         {
             continue;
diff --git a/chart2/source/tools/gauss.hxx b/chart2/source/tools/gauss.hxx
deleted file mode 100644
index 6cd63ce..0000000
--- a/chart2/source/tools/gauss.hxx
+++ /dev/null
@@ -1,166 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-/** This method eliminates elements below main diagonal in the given
-    matrix by gaussian elimination.
-
-    @param matrix
-    The matrix to operate on. Last column is the result vector (right
-    hand side of the linear equation). After successful termination,
-    the matrix is upper triangular. The matrix is expected to be in
-    row major order.
-
-    @param rows
-    Number of rows in matrix
-
-    @param cols
-    Number of columns in matrix
-
-    @param minPivot
-    If the pivot element gets lesser than minPivot, this method fails,
-    otherwise, elimination succeeds and true is returned.
-
-    @return true, if elimination succeeded.
- */
-template <class Matrix, typename BaseType>
-bool eliminate(     Matrix&         matrix,
-                    int             rows,
-                    int             cols,
-                    const BaseType& minPivot    )
-{
-    BaseType    temp;
-    int         max, i, j, k;   /* *must* be signed, when looping like: j>=0 ! */
-
-    /* eliminate below main diagonal */
-    for(i=0; i<cols-1; ++i)
-    {
-        /* find best pivot */
-        max = i;
-        for(j=i+1; j<rows; ++j)
-            if( fabs(matrix[ j*cols + i ]) > fabs(matrix[ max*cols + i ]) )
-                max = j;
-
-        /* check pivot value */
-        if( fabs(matrix[ max*cols + i ]) < minPivot )
-            return false;   /* pivot too small! */
-
-        /* interchange rows 'max' and 'i' */
-        for(k=0; k<cols; ++k)
-        {
-            temp = matrix[ i*cols + k ];
-            matrix[ i*cols + k ] = matrix[ max*cols + k ];
-            matrix[ max*cols + k ] = temp;
-        }
-
-        /* eliminate column */
-        for(j=i+1; j<rows; ++j)
-            for(k=cols-1; k>=i; --k)
-                matrix[ j*cols + k ] -= matrix[ i*cols + k ] *
-                    matrix[ j*cols + i ] / matrix[ i*cols + i ];
-    }
-
-    /* everything went well */
-    return true;
-}
-
-
-/** Retrieve solution vector of linear system by substituting backwards.
-
-    This operation _relies_ on the previous successful
-    application of eliminate()!
-
-    @param matrix
-    Matrix in upper diagonal form, as e.g. generated by eliminate()
-
-    @param rows
-    Number of rows in matrix
-
-    @param cols
-    Number of columns in matrix
-
-    @param result
-    Result vector. Given matrix must have space for one column (rows entries).
-
-    @return true, if back substitution was possible (i.e. no division
-    by zero occurred).
- */
-template <class Matrix, class Vector, typename BaseType>
-bool substitute(    const Matrix&   matrix,
-                    int             rows,
-                    int             cols,
-                    Vector&         result  )
-{
-    BaseType    temp;
-    int         j,k;    /* *must* be signed, when looping like: j>=0 ! */
-
-    /* substitute backwards */
-    for(j=rows-1; j>=0; --j)
-    {
-        temp = 0.0;
-        for(k=j+1; k<cols-1; ++k)
-            temp += matrix[ j*cols + k ] * result[k];
-
-        if( matrix[ j*cols + j ] == 0.0 )
-            return false;   /* imminent division by zero! */
-
-        result[j] = (matrix[ j*cols + cols-1 ] - temp) / matrix[ j*cols + j ];
-    }
-
-    /* everything went well */
-    return true;
-}
-
-
-/** This method determines solution of given linear system, if any
-
-    This is a wrapper for eliminate and substitute, given matrix must
-    contain right side of equation as the last column.
-
-    @param matrix
-    The matrix to operate on. Last column is the result vector (right
-    hand side of the linear equation). After successful termination,
-    the matrix is upper triangular. The matrix is expected to be in
-    row major order.
-
-    @param rows
-    Number of rows in matrix
-
-    @param cols
-    Number of columns in matrix
-
-    @param minPivot
-    If the pivot element gets lesser than minPivot, this method fails,
-    otherwise, elimination succeeds and true is returned.
-
-    @return true, if elimination succeeded.
- */
-template <class Matrix, class Vector, typename BaseType>
-bool solve( Matrix&     matrix,
-            int         rows,
-            int         cols,
-            Vector&     result,
-            BaseType    minPivot    )
-{
-    if( eliminate<Matrix,BaseType>(matrix, rows, cols, minPivot) )
-        return substitute<Matrix,Vector,BaseType>(matrix, rows, cols, result);
-
-    return false;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/view/charttypes/VSeriesPlotter.cxx b/chart2/source/view/charttypes/VSeriesPlotter.cxx
index 6a9a62a..40bf94c 100644
--- a/chart2/source/view/charttypes/VSeriesPlotter.cxx
+++ b/chart2/source/view/charttypes/VSeriesPlotter.cxx
@@ -1025,12 +1025,13 @@ void VSeriesPlotter::createRegressionCurvesShapes( VDataSeries& rVDataSeries,
 
             fPointScale = (fMaxX - fMinX) / (fChartMaxX - fChartMinX);
         }
-
         xCalculator->setRegressionProperties(aDegree, aForceIntercept, aInterceptValue, aPeriod);
         xCalculator->recalculateRegression( rVDataSeries.getAllX(), rVDataSeries.getAllY() );
-
         sal_Int32 nPointCount = 100 * fPointScale;
 
+        if ( nPointCount < 2 )
+            nPointCount = 2;
+
         drawing::PolyPolygonShape3D aRegressionPoly;
         aRegressionPoly.SequenceX.realloc(1);
         aRegressionPoly.SequenceY.realloc(1);


More information about the Libreoffice-commits mailing list