Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
core
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
LibreOffice
core
Commits
83f77ab0
Kaydet (Commit)
83f77ab0
authored
Tem 01, 2013
tarafından
Kohei Yoshida
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Rework SUMPRODUCT to reduce the number of block position lookups.
Change-Id: I22b843142b76df1c51597a8138b1674286f78792
üst
9c1ca6dc
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
223 additions
and
31 deletions
+223
-31
scmatrix.hxx
sc/inc/scmatrix.hxx
+4
-2
interpr5.cxx
sc/source/core/tool/interpr5.cxx
+63
-29
scmatrix.cxx
sc/source/core/tool/scmatrix.cxx
+156
-0
No files found.
sc/inc/scmatrix.hxx
Dosyayı görüntüle @
83f77ab0
...
...
@@ -119,6 +119,8 @@ class SC_DLLPUBLIC ScMatrix
ScMatrix
&
operator
=
(
const
ScMatrix
&
);
public
:
enum
Op
{
Add
,
Sub
,
Mul
,
Div
};
/**
* When adding all numerical matrix elements for a scalar result such as
* summation, the interpreter wants to separate the first non-zero value
...
...
@@ -352,8 +354,8 @@ public:
double
GetMaxValue
(
bool
bTextAsZero
)
const
;
double
GetMinValue
(
bool
bTextAsZero
)
const
;
// All other matrix functions MatMult, MInv, ... are in ScInterpreter
// to be numerically safe.
void
GetDoubleArray
(
std
::
vector
<
double
>&
rArray
)
const
;
void
MergeDoubleArray
(
std
::
vector
<
double
>&
rArray
,
Op
eOp
)
const
;
#if DEBUG_MATRIX
void
Dump
()
const
;
...
...
sc/source/core/tool/interpr5.cxx
Dosyayı görüntüle @
83f77ab0
...
...
@@ -1595,6 +1595,49 @@ void ScInterpreter::ScPow()
PushDouble
(
pow
(
fVal1
,
fVal2
));
}
namespace
{
bool
mergeArray
(
std
::
vector
<
double
>&
rRes
,
const
std
::
vector
<
double
>&
rOther
)
{
if
(
rRes
.
size
()
!=
rOther
.
size
())
return
false
;
double
fNan
;
rtl
::
math
::
setNan
(
&
fNan
);
std
::
vector
<
double
>::
iterator
it
=
rRes
.
begin
(),
itEnd
=
rRes
.
end
();
std
::
vector
<
double
>::
const_iterator
itOther
=
rOther
.
begin
();
for
(;
it
!=
itEnd
;
++
it
,
++
itOther
)
{
if
(
rtl
::
math
::
isNan
(
*
it
)
||
rtl
::
math
::
isNan
(
*
itOther
))
{
*
it
=
fNan
;
continue
;
}
*
it
*=
*
itOther
;
}
return
true
;
}
class
SumValues
:
std
::
unary_function
<
double
,
void
>
{
double
mfSum
;
public
:
SumValues
()
:
mfSum
(
0.0
)
{}
void
operator
()
(
double
f
)
{
if
(
!
rtl
::
math
::
isNan
(
f
))
mfSum
+=
f
;
}
double
getValue
()
const
{
return
mfSum
;
}
};
}
void
ScInterpreter
::
ScSumProduct
()
{
RTL_LOGFILE_CONTEXT_AUTHOR
(
aLogger
,
"sc"
,
"er"
,
"ScInterpreter::ScSumProduct"
);
...
...
@@ -1602,49 +1645,40 @@ void ScInterpreter::ScSumProduct()
if
(
!
MustHaveParamCount
(
nParamCount
,
1
,
30
)
)
return
;
ScMatrixRef
pMat
1
=
NULL
;
ScMatrixRef
pMat
2
=
NULL
;
ScMatrixRef
pMat
=
NULL
;
pMat
2
=
GetMatrix
();
if
(
!
pMat
2
)
ScMatrixRef
pMat
Last
;
ScMatrixRef
pMat
;
pMat
Last
=
GetMatrix
();
if
(
!
pMat
Last
)
{
PushIllegalParameter
();
return
;
}
SCSIZE
nC
,
nC1
;
SCSIZE
nR
,
nR1
;
pMat2
->
GetDimensions
(
nC
,
nR
);
pMat
=
pMat2
;
for
(
sal_uInt16
i
=
1
;
i
<
nParamCount
;
i
++
)
SCSIZE
nC
,
nCLast
,
nR
,
nRLast
;
pMatLast
->
GetDimensions
(
nCLast
,
nRLast
);
std
::
vector
<
double
>
aResArray
;
pMatLast
->
GetDoubleArray
(
aResArray
);
for
(
sal_uInt16
i
=
1
;
i
<
nParamCount
;
++
i
)
{
pMat
1
=
GetMatrix
();
if
(
!
pMat
1
)
pMat
=
GetMatrix
();
if
(
!
pMat
)
{
PushIllegalParameter
();
return
;
}
pMat1
->
GetDimensions
(
nC1
,
nR1
);
if
(
nC1
!=
nC
||
nR1
!=
nR
)
{
PushNoValue
();
return
;
}
ScMatrixRef
pResMat
=
lcl_MatrixCalculation
<
MatrixMul
>
(
*
pMat1
,
*
pMat
,
this
);
if
(
!
pResMat
)
pMat
->
GetDimensions
(
nC
,
nR
);
if
(
nC
!=
nCLast
||
nR
!=
nRLast
)
{
PushNoValue
();
return
;
}
else
pMat
=
pResMat
;
}
double
fSum
=
0.0
;
SCSIZE
nCount
=
pMat
->
GetElementCount
();
for
(
SCSIZE
j
=
0
;
j
<
nCount
;
j
++
)
{
if
(
!
pMat
->
IsString
(
j
))
fSum
+=
pMat
->
GetDouble
(
j
);
pMat
->
MergeDoubleArray
(
aResArray
,
ScMatrix
::
Mul
);
}
double
fSum
=
std
::
for_each
(
aResArray
.
begin
(),
aResArray
.
end
(),
SumValues
()).
getValue
();
PushDouble
(
fSum
);
}
...
...
sc/source/core/tool/scmatrix.cxx
Dosyayı görüntüle @
83f77ab0
...
...
@@ -225,6 +225,8 @@ public:
double
GetMaxValue
(
bool
bTextAsZero
)
const
;
double
GetMinValue
(
bool
bTextAsZero
)
const
;
void
GetDoubleArray
(
std
::
vector
<
double
>&
rArray
)
const
;
void
MergeDoubleArray
(
std
::
vector
<
double
>&
rArray
,
ScMatrix
::
Op
eOp
)
const
;
#if DEBUG_MATRIX
void
Dump
()
const
;
...
...
@@ -1022,6 +1024,121 @@ public:
}
};
class
ToDoubleArray
:
std
::
unary_function
<
MatrixImplType
::
element_block_type
,
void
>
{
std
::
vector
<
double
>
maArray
;
std
::
vector
<
double
>::
iterator
miPos
;
double
mfNaN
;
public
:
ToDoubleArray
(
size_t
nSize
)
:
maArray
(
nSize
,
0.0
),
miPos
(
maArray
.
begin
())
{
rtl
::
math
::
setNan
(
&
mfNaN
);
}
void
operator
()
(
const
MatrixImplType
::
element_block_node_type
&
node
)
{
using
namespace
mdds
::
mtv
;
switch
(
node
.
type
)
{
case
mdds
:
:
mtm
::
element_numeric
:
{
numeric_element_block
::
const_iterator
it
=
numeric_element_block
::
begin
(
*
node
.
data
);
numeric_element_block
::
const_iterator
itEnd
=
numeric_element_block
::
end
(
*
node
.
data
);
for
(;
it
!=
itEnd
;
++
it
,
++
miPos
)
*
miPos
=
*
it
;
}
break
;
case
mdds
:
:
mtm
::
element_boolean
:
{
boolean_element_block
::
const_iterator
it
=
boolean_element_block
::
begin
(
*
node
.
data
);
boolean_element_block
::
const_iterator
itEnd
=
boolean_element_block
::
end
(
*
node
.
data
);
for
(;
it
!=
itEnd
;
++
it
,
++
miPos
)
*
miPos
=
*
it
?
1.0
:
0.0
;
}
break
;
case
mdds
:
:
mtm
::
element_string
:
{
for
(
size_t
i
=
0
;
i
<
node
.
size
;
++
i
,
++
miPos
)
*
miPos
=
mfNaN
;
}
break
;
default
:
;
}
}
void
swap
(
std
::
vector
<
double
>&
rOther
)
{
maArray
.
swap
(
rOther
);
}
};
struct
ArrayMul
:
public
std
::
binary_function
<
double
,
double
,
double
>
{
double
operator
()
(
const
double
&
lhs
,
const
double
&
rhs
)
const
{
return
lhs
*
rhs
;
}
};
template
<
typename
_Op
>
class
MergeDoubleArrayFunc
:
std
::
unary_function
<
MatrixImplType
::
element_block_type
,
void
>
{
std
::
vector
<
double
>&
mrArray
;
std
::
vector
<
double
>::
iterator
miPos
;
double
mfNaN
;
public
:
MergeDoubleArrayFunc
(
std
::
vector
<
double
>&
rArray
)
:
mrArray
(
rArray
),
miPos
(
mrArray
.
begin
())
{
rtl
::
math
::
setNan
(
&
mfNaN
);
}
void
operator
()
(
const
MatrixImplType
::
element_block_node_type
&
node
)
{
using
namespace
mdds
::
mtv
;
static
_Op
op
;
switch
(
node
.
type
)
{
case
mdds
:
:
mtm
::
element_numeric
:
{
numeric_element_block
::
const_iterator
it
=
numeric_element_block
::
begin
(
*
node
.
data
);
numeric_element_block
::
const_iterator
itEnd
=
numeric_element_block
::
end
(
*
node
.
data
);
for
(;
it
!=
itEnd
;
++
it
,
++
miPos
)
{
if
(
rtl
::
math
::
isNan
(
*
miPos
))
continue
;
*
miPos
=
op
(
*
miPos
,
*
it
);
}
}
break
;
case
mdds
:
:
mtm
::
element_boolean
:
{
boolean_element_block
::
const_iterator
it
=
boolean_element_block
::
begin
(
*
node
.
data
);
boolean_element_block
::
const_iterator
itEnd
=
boolean_element_block
::
end
(
*
node
.
data
);
for
(;
it
!=
itEnd
;
++
it
,
++
miPos
)
{
if
(
rtl
::
math
::
isNan
(
*
miPos
))
continue
;
*
miPos
=
op
(
*
miPos
,
*
it
?
1.0
:
0.0
);
}
}
break
;
case
mdds
:
:
mtm
::
element_string
:
{
for
(
size_t
i
=
0
;
i
<
node
.
size
;
++
i
,
++
miPos
)
*
miPos
=
mfNaN
;
}
break
;
default
:
;
}
}
};
}
ScMatrix
::
IterateResult
ScMatrixImpl
::
Sum
(
bool
bTextAsZero
)
const
...
...
@@ -1067,6 +1184,34 @@ double ScMatrixImpl::GetMinValue( bool bTextAsZero ) const
return
aFunc
.
getValue
();
}
void
ScMatrixImpl
::
GetDoubleArray
(
std
::
vector
<
double
>&
rArray
)
const
{
MatrixImplType
::
size_pair_type
aSize
=
maMat
.
size
();
ToDoubleArray
aFunc
(
aSize
.
row
*
aSize
.
column
);
maMat
.
walk
(
aFunc
);
aFunc
.
swap
(
rArray
);
}
void
ScMatrixImpl
::
MergeDoubleArray
(
std
::
vector
<
double
>&
rArray
,
ScMatrix
::
Op
eOp
)
const
{
MatrixImplType
::
size_pair_type
aSize
=
maMat
.
size
();
size_t
nSize
=
aSize
.
row
*
aSize
.
column
;
if
(
nSize
!=
rArray
.
size
())
return
;
switch
(
eOp
)
{
case
ScMatrix
:
:
Mul
:
{
MergeDoubleArrayFunc
<
ArrayMul
>
aFunc
(
rArray
);
maMat
.
walk
(
aFunc
);
}
break
;
default
:
;
}
}
#if DEBUG_MATRIX
void
ScMatrixImpl
::
Dump
()
const
{
...
...
@@ -1419,6 +1564,16 @@ double ScMatrix::GetMinValue( bool bTextAsZero ) const
return
pImpl
->
GetMinValue
(
bTextAsZero
);
}
void
ScMatrix
::
GetDoubleArray
(
std
::
vector
<
double
>&
rArray
)
const
{
pImpl
->
GetDoubleArray
(
rArray
);
}
void
ScMatrix
::
MergeDoubleArray
(
std
::
vector
<
double
>&
rArray
,
Op
eOp
)
const
{
pImpl
->
MergeDoubleArray
(
rArray
,
eOp
);
}
#if DEBUG_MATRIX
void
ScMatrix
::
Dump
()
const
{
...
...
@@ -1427,3 +1582,4 @@ void ScMatrix::Dump() const
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment