Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
tsoc
openmm
Commits
cecc774a
Commit
cecc774a
authored
Oct 05, 2015
by
Peter Eastman
Browse files
Merge branch 'master' into hardwall
parents
1dfa0e59
a20944f6
Changes
206
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1067 additions
and
33 deletions
+1067
-33
CMakeLists.txt
CMakeLists.txt
+4
-3
devtools/forcefield-scripts/processTinkerForceField.py
devtools/forcefield-scripts/processTinkerForceField.py
+0
-1
libraries/sfmt/src/SFMT.cpp
libraries/sfmt/src/SFMT.cpp
+2
-0
libraries/vecmath/include/neon_mathfun.h
libraries/vecmath/include/neon_mathfun.h
+302
-0
libraries/vecmath/include/sse_mathfun.h
libraries/vecmath/include/sse_mathfun.h
+712
-0
libraries/vecmath/src/vecmath.cpp
libraries/vecmath/src/vecmath.cpp
+8
-0
openmmapi/include/openmm/CustomAngleForce.h
openmmapi/include/openmm/CustomAngleForce.h
+2
-2
openmmapi/include/openmm/CustomBondForce.h
openmmapi/include/openmm/CustomBondForce.h
+2
-2
openmmapi/include/openmm/CustomCentroidBondForce.h
openmmapi/include/openmm/CustomCentroidBondForce.h
+4
-4
openmmapi/include/openmm/CustomCompoundBondForce.h
openmmapi/include/openmm/CustomCompoundBondForce.h
+2
-2
openmmapi/include/openmm/CustomExternalForce.h
openmmapi/include/openmm/CustomExternalForce.h
+11
-5
openmmapi/include/openmm/CustomGBForce.h
openmmapi/include/openmm/CustomGBForce.h
+1
-1
openmmapi/include/openmm/CustomHbondForce.h
openmmapi/include/openmm/CustomHbondForce.h
+4
-4
openmmapi/include/openmm/CustomManyParticleForce.h
openmmapi/include/openmm/CustomManyParticleForce.h
+1
-1
openmmapi/include/openmm/CustomNonbondedForce.h
openmmapi/include/openmm/CustomNonbondedForce.h
+1
-1
openmmapi/include/openmm/CustomTorsionForce.h
openmmapi/include/openmm/CustomTorsionForce.h
+2
-2
openmmapi/include/openmm/internal/CustomCentroidBondForceImpl.h
...api/include/openmm/internal/CustomCentroidBondForceImpl.h
+2
-1
openmmapi/include/openmm/internal/CustomCompoundBondForceImpl.h
...api/include/openmm/internal/CustomCompoundBondForceImpl.h
+2
-1
openmmapi/include/openmm/internal/CustomHbondForceImpl.h
openmmapi/include/openmm/internal/CustomHbondForceImpl.h
+3
-2
openmmapi/include/openmm/internal/CustomManyParticleForceImpl.h
...api/include/openmm/internal/CustomManyParticleForceImpl.h
+2
-1
No files found.
Too many changes to show.
To preserve performance only
206 of 206+
files are displayed.
Plain diff
Email patch
CMakeLists.txt
View file @
cecc774a
...
@@ -82,7 +82,7 @@ ENDIF(${CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT})
...
@@ -82,7 +82,7 @@ ENDIF(${CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT})
# The source is organized into subdirectories, but we handle them all from
# The source is organized into subdirectories, but we handle them all from
# this CMakeLists file rather than letting CMake visit them as SUBDIRS.
# this CMakeLists file rather than letting CMake visit them as SUBDIRS.
SET
(
OPENMM_SOURCE_SUBDIRS . openmmapi olla libraries/jama libraries/quern libraries/lepton libraries/sfmt libraries/lbfgs libraries/hilbert libraries/csha1 platforms/reference serialization libraries/validate libraries/irrxml
)
SET
(
OPENMM_SOURCE_SUBDIRS . openmmapi olla libraries/jama libraries/quern libraries/lepton libraries/sfmt libraries/lbfgs libraries/hilbert libraries/csha1 platforms/reference serialization libraries/validate libraries/irrxml
libraries/vecmath
)
IF
(
WIN32
)
IF
(
WIN32
)
SET
(
OPENMM_SOURCE_SUBDIRS
${
OPENMM_SOURCE_SUBDIRS
}
libraries/pthreads
)
SET
(
OPENMM_SOURCE_SUBDIRS
${
OPENMM_SOURCE_SUBDIRS
}
libraries/pthreads
)
ELSE
(
WIN32
)
ELSE
(
WIN32
)
...
@@ -159,8 +159,8 @@ ENDIF (NOT CMAKE_CXX_FLAGS_RELEASE)
...
@@ -159,8 +159,8 @@ ENDIF (NOT CMAKE_CXX_FLAGS_RELEASE)
# and make it available to the code so it can be built into the binaries.
# and make it available to the code so it can be built into the binaries.
SET
(
OPENMM_LIBRARY_NAME OpenMM
)
SET
(
OPENMM_LIBRARY_NAME OpenMM
)
SET
(
OPENMM_MAJOR_VERSION
6
)
SET
(
OPENMM_MAJOR_VERSION
7
)
SET
(
OPENMM_MINOR_VERSION
3
)
SET
(
OPENMM_MINOR_VERSION
0
)
SET
(
OPENMM_BUILD_VERSION 0
)
SET
(
OPENMM_BUILD_VERSION 0
)
SET
(
OPENMM_COPYRIGHT_YEARS
"2008-2015"
)
SET
(
OPENMM_COPYRIGHT_YEARS
"2008-2015"
)
...
@@ -340,6 +340,7 @@ ELSE(DL_LIBRARY)
...
@@ -340,6 +340,7 @@ ELSE(DL_LIBRARY)
ENDIF
(
DL_LIBRARY
)
ENDIF
(
DL_LIBRARY
)
IF
(
BUILD_TESTING
)
IF
(
BUILD_TESTING
)
INCLUDE_DIRECTORIES
(
${
CMAKE_SOURCE_DIR
}
/tests
)
ADD_SUBDIRECTORY
(
platforms/reference/tests
)
ADD_SUBDIRECTORY
(
platforms/reference/tests
)
ENDIF
(
BUILD_TESTING
)
ENDIF
(
BUILD_TESTING
)
...
...
devtools/forcefield-scripts/processTinkerForceField.py
View file @
cecc774a
...
@@ -1017,7 +1017,6 @@ if( isAmoeba ):
...
@@ -1017,7 +1017,6 @@ if( isAmoeba ):
torsionTorsionUnit
=
1.0
torsionTorsionUnit
=
1.0
outputString
=
""" <AmoebaTorsionTorsionForce >"""
outputString
=
""" <AmoebaTorsionTorsionForce >"""
tinkerXmlFile
.
write
(
"%s
\n
"
%
(
outputString
)
)
tinkerXmlFile
.
write
(
"%s
\n
"
%
(
outputString
)
)
conversion
=
41.84
/
radian
torsionTorsions
=
forces
[
'tortors'
]
torsionTorsions
=
forces
[
'tortors'
]
for
(
index
,
torsionTorsion
)
in
enumerate
(
torsionTorsions
):
for
(
index
,
torsionTorsion
)
in
enumerate
(
torsionTorsions
):
torInfo
=
torsionTorsion
[
0
]
torInfo
=
torsionTorsion
[
0
]
...
...
libraries/sfmt/src/SFMT.cpp
View file @
cecc774a
...
@@ -124,11 +124,13 @@ public:
...
@@ -124,11 +124,13 @@ public:
};
};
void
SFMT
::
createCheckpoint
(
std
::
ostream
&
stream
)
{
void
SFMT
::
createCheckpoint
(
std
::
ostream
&
stream
)
{
stream
.
write
((
char
*
)
&
data
->
baseData
,
sizeof
(
data
->
baseData
));
stream
.
write
((
char
*
)
&
data
->
sfmt
,
sizeof
(
data
->
sfmt
));
stream
.
write
((
char
*
)
&
data
->
sfmt
,
sizeof
(
data
->
sfmt
));
stream
.
write
((
char
*
)
&
data
->
idx
,
sizeof
(
data
->
idx
));
stream
.
write
((
char
*
)
&
data
->
idx
,
sizeof
(
data
->
idx
));
}
}
void
SFMT
::
loadCheckpoint
(
std
::
istream
&
stream
)
{
void
SFMT
::
loadCheckpoint
(
std
::
istream
&
stream
)
{
stream
.
read
((
char
*
)
&
data
->
baseData
,
sizeof
(
data
->
baseData
));
stream
.
read
((
char
*
)
&
data
->
sfmt
,
sizeof
(
data
->
sfmt
));
stream
.
read
((
char
*
)
&
data
->
sfmt
,
sizeof
(
data
->
sfmt
));
stream
.
read
((
char
*
)
&
data
->
idx
,
sizeof
(
data
->
idx
));
stream
.
read
((
char
*
)
&
data
->
idx
,
sizeof
(
data
->
idx
));
}
}
...
...
libraries/vecmath/include/neon_mathfun.h
0 → 100644
View file @
cecc774a
/* NEON implementation of sin, cos, exp and log
Inspired by Intel Approximate Math library, and based on the
corresponding algorithms of the cephes math library
*/
/* Copyright (C) 2011 Julien Pommier
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
(this is the zlib license)
*/
#include <arm_neon.h>
#include "openmm/internal/windowsExport.h"
typedef
float32x4_t
v4sf
;
// vector of 4 float
typedef
uint32x4_t
v4su
;
// vector of 4 uint32
typedef
int32x4_t
v4si
;
// vector of 4 uint32
#define c_inv_mant_mask ~0x7f800000u
#define c_cephes_SQRTHF 0.707106781186547524
#define c_cephes_log_p0 7.0376836292E-2
#define c_cephes_log_p1 - 1.1514610310E-1
#define c_cephes_log_p2 1.1676998740E-1
#define c_cephes_log_p3 - 1.2420140846E-1
#define c_cephes_log_p4 + 1.4249322787E-1
#define c_cephes_log_p5 - 1.6668057665E-1
#define c_cephes_log_p6 + 2.0000714765E-1
#define c_cephes_log_p7 - 2.4999993993E-1
#define c_cephes_log_p8 + 3.3333331174E-1
#define c_cephes_log_q1 -2.12194440e-4
#define c_cephes_log_q2 0.693359375
/* natural logarithm computed for 4 simultaneous float
return NaN for x <= 0
*/
OPENMM_EXPORT
v4sf
log_ps
(
v4sf
x
)
{
v4sf
one
=
vdupq_n_f32
(
1
);
x
=
vmaxq_f32
(
x
,
vdupq_n_f32
(
0
));
/* force flush to zero on denormal values */
v4su
invalid_mask
=
vcleq_f32
(
x
,
vdupq_n_f32
(
0
));
v4si
ux
=
vreinterpretq_s32_f32
(
x
);
v4si
emm0
=
vshrq_n_s32
(
ux
,
23
);
/* keep only the fractional part */
ux
=
vandq_s32
(
ux
,
vdupq_n_s32
(
c_inv_mant_mask
));
ux
=
vorrq_s32
(
ux
,
vreinterpretq_s32_f32
(
vdupq_n_f32
(
0
.
5
f
)));
x
=
vreinterpretq_f32_s32
(
ux
);
emm0
=
vsubq_s32
(
emm0
,
vdupq_n_s32
(
0x7f
));
v4sf
e
=
vcvtq_f32_s32
(
emm0
);
e
=
vaddq_f32
(
e
,
one
);
/* part2:
if( x < SQRTHF ) {
e -= 1;
x = x + x - 1.0;
} else { x = x - 1.0; }
*/
v4su
mask
=
vcltq_f32
(
x
,
vdupq_n_f32
(
c_cephes_SQRTHF
));
v4sf
tmp
=
vreinterpretq_f32_u32
(
vandq_u32
(
vreinterpretq_u32_f32
(
x
),
mask
));
x
=
vsubq_f32
(
x
,
one
);
e
=
vsubq_f32
(
e
,
vreinterpretq_f32_u32
(
vandq_u32
(
vreinterpretq_u32_f32
(
one
),
mask
)));
x
=
vaddq_f32
(
x
,
tmp
);
v4sf
z
=
vmulq_f32
(
x
,
x
);
v4sf
y
=
vdupq_n_f32
(
c_cephes_log_p0
);
y
=
vmulq_f32
(
y
,
x
);
y
=
vaddq_f32
(
y
,
vdupq_n_f32
(
c_cephes_log_p1
));
y
=
vmulq_f32
(
y
,
x
);
y
=
vaddq_f32
(
y
,
vdupq_n_f32
(
c_cephes_log_p2
));
y
=
vmulq_f32
(
y
,
x
);
y
=
vaddq_f32
(
y
,
vdupq_n_f32
(
c_cephes_log_p3
));
y
=
vmulq_f32
(
y
,
x
);
y
=
vaddq_f32
(
y
,
vdupq_n_f32
(
c_cephes_log_p4
));
y
=
vmulq_f32
(
y
,
x
);
y
=
vaddq_f32
(
y
,
vdupq_n_f32
(
c_cephes_log_p5
));
y
=
vmulq_f32
(
y
,
x
);
y
=
vaddq_f32
(
y
,
vdupq_n_f32
(
c_cephes_log_p6
));
y
=
vmulq_f32
(
y
,
x
);
y
=
vaddq_f32
(
y
,
vdupq_n_f32
(
c_cephes_log_p7
));
y
=
vmulq_f32
(
y
,
x
);
y
=
vaddq_f32
(
y
,
vdupq_n_f32
(
c_cephes_log_p8
));
y
=
vmulq_f32
(
y
,
x
);
y
=
vmulq_f32
(
y
,
z
);
tmp
=
vmulq_f32
(
e
,
vdupq_n_f32
(
c_cephes_log_q1
));
y
=
vaddq_f32
(
y
,
tmp
);
tmp
=
vmulq_f32
(
z
,
vdupq_n_f32
(
0
.
5
f
));
y
=
vsubq_f32
(
y
,
tmp
);
tmp
=
vmulq_f32
(
e
,
vdupq_n_f32
(
c_cephes_log_q2
));
x
=
vaddq_f32
(
x
,
y
);
x
=
vaddq_f32
(
x
,
tmp
);
x
=
vreinterpretq_f32_u32
(
vorrq_u32
(
vreinterpretq_u32_f32
(
x
),
invalid_mask
));
// negative arg will be NAN
return
x
;
}
#define c_exp_hi 88.3762626647949f
#define c_exp_lo -88.3762626647949f
#define c_cephes_LOG2EF 1.44269504088896341
#define c_cephes_exp_C1 0.693359375
#define c_cephes_exp_C2 -2.12194440e-4
#define c_cephes_exp_p0 1.9875691500E-4
#define c_cephes_exp_p1 1.3981999507E-3
#define c_cephes_exp_p2 8.3334519073E-3
#define c_cephes_exp_p3 4.1665795894E-2
#define c_cephes_exp_p4 1.6666665459E-1
#define c_cephes_exp_p5 5.0000001201E-1
/* exp() computed for 4 float at once */
OPENMM_EXPORT
v4sf
exp_ps
(
v4sf
x
)
{
v4sf
tmp
,
fx
;
v4sf
one
=
vdupq_n_f32
(
1
);
x
=
vminq_f32
(
x
,
vdupq_n_f32
(
c_exp_hi
));
x
=
vmaxq_f32
(
x
,
vdupq_n_f32
(
c_exp_lo
));
/* express exp(x) as exp(g + n*log(2)) */
fx
=
vmlaq_f32
(
vdupq_n_f32
(
0
.
5
f
),
x
,
vdupq_n_f32
(
c_cephes_LOG2EF
));
/* perform a floorf */
tmp
=
vcvtq_f32_s32
(
vcvtq_s32_f32
(
fx
));
/* if greater, substract 1 */
v4su
mask
=
vcgtq_f32
(
tmp
,
fx
);
mask
=
vandq_u32
(
mask
,
vreinterpretq_u32_f32
(
one
));
fx
=
vsubq_f32
(
tmp
,
vreinterpretq_f32_u32
(
mask
));
tmp
=
vmulq_f32
(
fx
,
vdupq_n_f32
(
c_cephes_exp_C1
));
v4sf
z
=
vmulq_f32
(
fx
,
vdupq_n_f32
(
c_cephes_exp_C2
));
x
=
vsubq_f32
(
x
,
tmp
);
x
=
vsubq_f32
(
x
,
z
);
static
const
float
cephes_exp_p
[
6
]
=
{
c_cephes_exp_p0
,
c_cephes_exp_p1
,
c_cephes_exp_p2
,
c_cephes_exp_p3
,
c_cephes_exp_p4
,
c_cephes_exp_p5
};
v4sf
y
=
vld1q_dup_f32
(
cephes_exp_p
+
0
);
v4sf
c1
=
vld1q_dup_f32
(
cephes_exp_p
+
1
);
v4sf
c2
=
vld1q_dup_f32
(
cephes_exp_p
+
2
);
v4sf
c3
=
vld1q_dup_f32
(
cephes_exp_p
+
3
);
v4sf
c4
=
vld1q_dup_f32
(
cephes_exp_p
+
4
);
v4sf
c5
=
vld1q_dup_f32
(
cephes_exp_p
+
5
);
y
=
vmulq_f32
(
y
,
x
);
z
=
vmulq_f32
(
x
,
x
);
y
=
vaddq_f32
(
y
,
c1
);
y
=
vmulq_f32
(
y
,
x
);
y
=
vaddq_f32
(
y
,
c2
);
y
=
vmulq_f32
(
y
,
x
);
y
=
vaddq_f32
(
y
,
c3
);
y
=
vmulq_f32
(
y
,
x
);
y
=
vaddq_f32
(
y
,
c4
);
y
=
vmulq_f32
(
y
,
x
);
y
=
vaddq_f32
(
y
,
c5
);
y
=
vmulq_f32
(
y
,
z
);
y
=
vaddq_f32
(
y
,
x
);
y
=
vaddq_f32
(
y
,
one
);
/* build 2^n */
int32x4_t
mm
;
mm
=
vcvtq_s32_f32
(
fx
);
mm
=
vaddq_s32
(
mm
,
vdupq_n_s32
(
0x7f
));
mm
=
vshlq_n_s32
(
mm
,
23
);
v4sf
pow2n
=
vreinterpretq_f32_s32
(
mm
);
y
=
vmulq_f32
(
y
,
pow2n
);
return
y
;
}
#define c_minus_cephes_DP1 -0.78515625
#define c_minus_cephes_DP2 -2.4187564849853515625e-4
#define c_minus_cephes_DP3 -3.77489497744594108e-8
#define c_sincof_p0 -1.9515295891E-4
#define c_sincof_p1 8.3321608736E-3
#define c_sincof_p2 -1.6666654611E-1
#define c_coscof_p0 2.443315711809948E-005
#define c_coscof_p1 -1.388731625493765E-003
#define c_coscof_p2 4.166664568298827E-002
#define c_cephes_FOPI 1.27323954473516 // 4 / M_PI
/* evaluation of 4 sines & cosines at once.
The code is the exact rewriting of the cephes sinf function.
Precision is excellent as long as x < 8192 (I did not bother to
take into account the special handling they have for greater values
-- it does not return garbage for arguments over 8192, though, but
the extra precision is missing).
Note that it is such that sinf((float)M_PI) = 8.74e-8, which is the
surprising but correct result.
Note also that when you compute sin(x), cos(x) is available at
almost no extra price so both sin_ps and cos_ps make use of
sincos_ps..
*/
OPENMM_EXPORT
void
sincos_ps
(
v4sf
x
,
v4sf
*
ysin
,
v4sf
*
ycos
)
{
// any x
v4sf
xmm1
,
xmm2
,
xmm3
,
y
;
v4su
emm2
;
v4su
sign_mask_sin
,
sign_mask_cos
;
sign_mask_sin
=
vcltq_f32
(
x
,
vdupq_n_f32
(
0
));
x
=
vabsq_f32
(
x
);
/* scale by 4/Pi */
y
=
vmulq_f32
(
x
,
vdupq_n_f32
(
c_cephes_FOPI
));
/* store the integer part of y in mm0 */
emm2
=
vcvtq_u32_f32
(
y
);
/* j=(j+1) & (~1) (see the cephes sources) */
emm2
=
vaddq_u32
(
emm2
,
vdupq_n_u32
(
1
));
emm2
=
vandq_u32
(
emm2
,
vdupq_n_u32
(
~
1
));
y
=
vcvtq_f32_u32
(
emm2
);
/* get the polynom selection mask
there is one polynom for 0 <= x <= Pi/4
and another one for Pi/4<x<=Pi/2
Both branches will be computed.
*/
v4su
poly_mask
=
vtstq_u32
(
emm2
,
vdupq_n_u32
(
2
));
/* The magic pass: "Extended precision modular arithmetic"
x = ((x - y * DP1) - y * DP2) - y * DP3; */
xmm1
=
vmulq_n_f32
(
y
,
c_minus_cephes_DP1
);
xmm2
=
vmulq_n_f32
(
y
,
c_minus_cephes_DP2
);
xmm3
=
vmulq_n_f32
(
y
,
c_minus_cephes_DP3
);
x
=
vaddq_f32
(
x
,
xmm1
);
x
=
vaddq_f32
(
x
,
xmm2
);
x
=
vaddq_f32
(
x
,
xmm3
);
sign_mask_sin
=
veorq_u32
(
sign_mask_sin
,
vtstq_u32
(
emm2
,
vdupq_n_u32
(
4
)));
sign_mask_cos
=
vtstq_u32
(
vsubq_u32
(
emm2
,
vdupq_n_u32
(
2
)),
vdupq_n_u32
(
4
));
/* Evaluate the first polynom (0 <= x <= Pi/4) in y1,
and the second polynom (Pi/4 <= x <= 0) in y2 */
v4sf
z
=
vmulq_f32
(
x
,
x
);
v4sf
y1
,
y2
;
y1
=
vmulq_n_f32
(
z
,
c_coscof_p0
);
y2
=
vmulq_n_f32
(
z
,
c_sincof_p0
);
y1
=
vaddq_f32
(
y1
,
vdupq_n_f32
(
c_coscof_p1
));
y2
=
vaddq_f32
(
y2
,
vdupq_n_f32
(
c_sincof_p1
));
y1
=
vmulq_f32
(
y1
,
z
);
y2
=
vmulq_f32
(
y2
,
z
);
y1
=
vaddq_f32
(
y1
,
vdupq_n_f32
(
c_coscof_p2
));
y2
=
vaddq_f32
(
y2
,
vdupq_n_f32
(
c_sincof_p2
));
y1
=
vmulq_f32
(
y1
,
z
);
y2
=
vmulq_f32
(
y2
,
z
);
y1
=
vmulq_f32
(
y1
,
z
);
y2
=
vmulq_f32
(
y2
,
x
);
y1
=
vsubq_f32
(
y1
,
vmulq_f32
(
z
,
vdupq_n_f32
(
0
.
5
f
)));
y2
=
vaddq_f32
(
y2
,
x
);
y1
=
vaddq_f32
(
y1
,
vdupq_n_f32
(
1
));
/* select the correct result from the two polynoms */
v4sf
ys
=
vbslq_f32
(
poly_mask
,
y1
,
y2
);
v4sf
yc
=
vbslq_f32
(
poly_mask
,
y2
,
y1
);
*
ysin
=
vbslq_f32
(
sign_mask_sin
,
vnegq_f32
(
ys
),
ys
);
*
ycos
=
vbslq_f32
(
sign_mask_cos
,
yc
,
vnegq_f32
(
yc
));
}
OPENMM_EXPORT
v4sf
sin_ps
(
v4sf
x
)
{
v4sf
ysin
,
ycos
;
sincos_ps
(
x
,
&
ysin
,
&
ycos
);
return
ysin
;
}
OPENMM_EXPORT
v4sf
cos_ps
(
v4sf
x
)
{
v4sf
ysin
,
ycos
;
sincos_ps
(
x
,
&
ysin
,
&
ycos
);
return
ycos
;
}
libraries/vecmath/include/sse_mathfun.h
0 → 100644
View file @
cecc774a
/* SIMD (SSE1+MMX or SSE2) implementation of sin, cos, exp and log
Inspired by Intel Approximate Math library, and based on the
corresponding algorithms of the cephes math library
The default is to use the SSE1 version. If you define USE_SSE2 the
the SSE2 intrinsics will be used in place of the MMX intrinsics. Do
not expect any significant performance improvement with SSE2.
*/
/* Copyright (C) 2007 Julien Pommier
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
(this is the zlib license)
*/
#include <xmmintrin.h>
#include "openmm/internal/windowsExport.h"
/* yes I know, the top of this file is quite ugly */
#ifdef _MSC_VER
/* visual c++ */
# define ALIGN16_BEG __declspec(align(16))
# define ALIGN16_END
#else
/* gcc or icc */
# define ALIGN16_BEG
# define ALIGN16_END __attribute__((aligned(16)))
#endif
/* __m128 is ugly to write */
typedef
__m128
v4sf
;
// vector of 4 float (sse1)
#ifdef USE_SSE2
# include <emmintrin.h>
typedef
__m128i
v4si
;
// vector of 4 int (sse2)
#else
typedef
__m64
v2si
;
// vector of 2 int (mmx)
#endif
/* declare some SSE constants -- why can't I figure a better way to do that? */
#define _PS_CONST(Name, Val) \
static const ALIGN16_BEG float _ps_##Name[4] ALIGN16_END = { Val, Val, Val, Val }
#define _PI32_CONST(Name, Val) \
static const ALIGN16_BEG int _pi32_##Name[4] ALIGN16_END = { Val, Val, Val, Val }
#define _PS_CONST_TYPE(Name, Type, Val) \
static const ALIGN16_BEG Type _ps_##Name[4] ALIGN16_END = { Val, Val, Val, Val }
_PS_CONST
(
1
,
1
.
0
f
);
_PS_CONST
(
0
p5
,
0
.
5
f
);
/* the smallest non denormalized float number */
_PS_CONST_TYPE
(
min_norm_pos
,
int
,
0x00800000
);
_PS_CONST_TYPE
(
mant_mask
,
int
,
0x7f800000
);
_PS_CONST_TYPE
(
inv_mant_mask
,
int
,
~
0x7f800000
);
_PS_CONST_TYPE
(
sign_mask
,
int
,
(
int
)
0x80000000
);
_PS_CONST_TYPE
(
inv_sign_mask
,
int
,
~
0x80000000
);
_PI32_CONST
(
1
,
1
);
_PI32_CONST
(
inv1
,
~
1
);
_PI32_CONST
(
2
,
2
);
_PI32_CONST
(
4
,
4
);
_PI32_CONST
(
0x7f
,
0x7f
);
_PS_CONST
(
cephes_SQRTHF
,
0
.
707106781186547524
);
_PS_CONST
(
cephes_log_p0
,
7.0376836292E-2
);
_PS_CONST
(
cephes_log_p1
,
-
1.1514610310E-1
);
_PS_CONST
(
cephes_log_p2
,
1.1676998740E-1
);
_PS_CONST
(
cephes_log_p3
,
-
1.2420140846E-1
);
_PS_CONST
(
cephes_log_p4
,
+
1.4249322787E-1
);
_PS_CONST
(
cephes_log_p5
,
-
1.6668057665E-1
);
_PS_CONST
(
cephes_log_p6
,
+
2.0000714765E-1
);
_PS_CONST
(
cephes_log_p7
,
-
2.4999993993E-1
);
_PS_CONST
(
cephes_log_p8
,
+
3.3333331174E-1
);
_PS_CONST
(
cephes_log_q1
,
-
2.12194440e-4
);
_PS_CONST
(
cephes_log_q2
,
0
.
693359375
);
#ifndef USE_SSE2
typedef
union
xmm_mm_union
{
__m128
xmm
;
__m64
mm
[
2
];
}
xmm_mm_union
;
#define COPY_XMM_TO_MM(xmm_, mm0_, mm1_) { \
xmm_mm_union u; u.xmm = xmm_; \
mm0_ = u.mm[0]; \
mm1_ = u.mm[1]; \
}
#define COPY_MM_TO_XMM(mm0_, mm1_, xmm_) { \
xmm_mm_union u; u.mm[0]=mm0_; u.mm[1]=mm1_; xmm_ = u.xmm; \
}
#endif // USE_SSE2
/* natural logarithm computed for 4 simultaneous float
return NaN for x <= 0
*/
OPENMM_EXPORT
v4sf
log_ps
(
v4sf
x
)
{
#ifdef USE_SSE2
v4si
emm0
;
#else
v2si
mm0
,
mm1
;
#endif
v4sf
one
=
*
(
v4sf
*
)
_ps_1
;
v4sf
invalid_mask
=
_mm_cmple_ps
(
x
,
_mm_setzero_ps
());
x
=
_mm_max_ps
(
x
,
*
(
v4sf
*
)
_ps_min_norm_pos
);
/* cut off denormalized stuff */
#ifndef USE_SSE2
/* part 1: x = frexpf(x, &e); */
COPY_XMM_TO_MM
(
x
,
mm0
,
mm1
);
mm0
=
_mm_srli_pi32
(
mm0
,
23
);
mm1
=
_mm_srli_pi32
(
mm1
,
23
);
#else
emm0
=
_mm_srli_epi32
(
_mm_castps_si128
(
x
),
23
);
#endif
/* keep only the fractional part */
x
=
_mm_and_ps
(
x
,
*
(
v4sf
*
)
_ps_inv_mant_mask
);
x
=
_mm_or_ps
(
x
,
*
(
v4sf
*
)
_ps_0p5
);
#ifndef USE_SSE2
/* now e=mm0:mm1 contain the really base-2 exponent */
mm0
=
_mm_sub_pi32
(
mm0
,
*
(
v2si
*
)
_pi32_0x7f
);
mm1
=
_mm_sub_pi32
(
mm1
,
*
(
v2si
*
)
_pi32_0x7f
);
v4sf
e
=
_mm_cvtpi32x2_ps
(
mm0
,
mm1
);
_mm_empty
();
/* bye bye mmx */
#else
emm0
=
_mm_sub_epi32
(
emm0
,
*
(
v4si
*
)
_pi32_0x7f
);
v4sf
e
=
_mm_cvtepi32_ps
(
emm0
);
#endif
e
=
_mm_add_ps
(
e
,
one
);
/* part2:
if( x < SQRTHF ) {
e -= 1;
x = x + x - 1.0;
} else { x = x - 1.0; }
*/
v4sf
mask
=
_mm_cmplt_ps
(
x
,
*
(
v4sf
*
)
_ps_cephes_SQRTHF
);
v4sf
tmp
=
_mm_and_ps
(
x
,
mask
);
x
=
_mm_sub_ps
(
x
,
one
);
e
=
_mm_sub_ps
(
e
,
_mm_and_ps
(
one
,
mask
));
x
=
_mm_add_ps
(
x
,
tmp
);
v4sf
z
=
_mm_mul_ps
(
x
,
x
);
v4sf
y
=
*
(
v4sf
*
)
_ps_cephes_log_p0
;
y
=
_mm_mul_ps
(
y
,
x
);
y
=
_mm_add_ps
(
y
,
*
(
v4sf
*
)
_ps_cephes_log_p1
);
y
=
_mm_mul_ps
(
y
,
x
);
y
=
_mm_add_ps
(
y
,
*
(
v4sf
*
)
_ps_cephes_log_p2
);
y
=
_mm_mul_ps
(
y
,
x
);
y
=
_mm_add_ps
(
y
,
*
(
v4sf
*
)
_ps_cephes_log_p3
);
y
=
_mm_mul_ps
(
y
,
x
);
y
=
_mm_add_ps
(
y
,
*
(
v4sf
*
)
_ps_cephes_log_p4
);
y
=
_mm_mul_ps
(
y
,
x
);
y
=
_mm_add_ps
(
y
,
*
(
v4sf
*
)
_ps_cephes_log_p5
);
y
=
_mm_mul_ps
(
y
,
x
);
y
=
_mm_add_ps
(
y
,
*
(
v4sf
*
)
_ps_cephes_log_p6
);
y
=
_mm_mul_ps
(
y
,
x
);
y
=
_mm_add_ps
(
y
,
*
(
v4sf
*
)
_ps_cephes_log_p7
);
y
=
_mm_mul_ps
(
y
,
x
);
y
=
_mm_add_ps
(
y
,
*
(
v4sf
*
)
_ps_cephes_log_p8
);
y
=
_mm_mul_ps
(
y
,
x
);
y
=
_mm_mul_ps
(
y
,
z
);
tmp
=
_mm_mul_ps
(
e
,
*
(
v4sf
*
)
_ps_cephes_log_q1
);
y
=
_mm_add_ps
(
y
,
tmp
);
tmp
=
_mm_mul_ps
(
z
,
*
(
v4sf
*
)
_ps_0p5
);
y
=
_mm_sub_ps
(
y
,
tmp
);
tmp
=
_mm_mul_ps
(
e
,
*
(
v4sf
*
)
_ps_cephes_log_q2
);
x
=
_mm_add_ps
(
x
,
y
);
x
=
_mm_add_ps
(
x
,
tmp
);
x
=
_mm_or_ps
(
x
,
invalid_mask
);
// negative arg will be NAN
return
x
;
}
_PS_CONST
(
exp_hi
,
88
.
3762626647949
f
);
_PS_CONST
(
exp_lo
,
-
88
.
3762626647949
f
);
_PS_CONST
(
cephes_LOG2EF
,
1
.
44269504088896341
);
_PS_CONST
(
cephes_exp_C1
,
0
.
693359375
);
_PS_CONST
(
cephes_exp_C2
,
-
2.12194440e-4
);
_PS_CONST
(
cephes_exp_p0
,
1.9875691500E-4
);
_PS_CONST
(
cephes_exp_p1
,
1.3981999507E-3
);
_PS_CONST
(
cephes_exp_p2
,
8.3334519073E-3
);
_PS_CONST
(
cephes_exp_p3
,
4.1665795894E-2
);
_PS_CONST
(
cephes_exp_p4
,
1.6666665459E-1
);
_PS_CONST
(
cephes_exp_p5
,
5.0000001201E-1
);
OPENMM_EXPORT
v4sf
exp_ps
(
v4sf
x
)
{
v4sf
tmp
=
_mm_setzero_ps
(),
fx
;
#ifdef USE_SSE2
v4si
emm0
;
#else
v2si
mm0
,
mm1
;
#endif
v4sf
one
=
*
(
v4sf
*
)
_ps_1
;
x
=
_mm_min_ps
(
x
,
*
(
v4sf
*
)
_ps_exp_hi
);
x
=
_mm_max_ps
(
x
,
*
(
v4sf
*
)
_ps_exp_lo
);
/* express exp(x) as exp(g + n*log(2)) */
fx
=
_mm_mul_ps
(
x
,
*
(
v4sf
*
)
_ps_cephes_LOG2EF
);
fx
=
_mm_add_ps
(
fx
,
*
(
v4sf
*
)
_ps_0p5
);
/* how to perform a floorf with SSE: just below */
#ifndef USE_SSE2
/* step 1 : cast to int */
tmp
=
_mm_movehl_ps
(
tmp
,
fx
);
mm0
=
_mm_cvttps_pi32
(
fx
);
mm1
=
_mm_cvttps_pi32
(
tmp
);
/* step 2 : cast back to float */
tmp
=
_mm_cvtpi32x2_ps
(
mm0
,
mm1
);
#else
emm0
=
_mm_cvttps_epi32
(
fx
);
tmp
=
_mm_cvtepi32_ps
(
emm0
);
#endif
/* if greater, substract 1 */
v4sf
mask
=
_mm_cmpgt_ps
(
tmp
,
fx
);
mask
=
_mm_and_ps
(
mask
,
one
);
fx
=
_mm_sub_ps
(
tmp
,
mask
);
tmp
=
_mm_mul_ps
(
fx
,
*
(
v4sf
*
)
_ps_cephes_exp_C1
);
v4sf
z
=
_mm_mul_ps
(
fx
,
*
(
v4sf
*
)
_ps_cephes_exp_C2
);
x
=
_mm_sub_ps
(
x
,
tmp
);
x
=
_mm_sub_ps
(
x
,
z
);
z
=
_mm_mul_ps
(
x
,
x
);
v4sf
y
=
*
(
v4sf
*
)
_ps_cephes_exp_p0
;
y
=
_mm_mul_ps
(
y
,
x
);
y
=
_mm_add_ps
(
y
,
*
(
v4sf
*
)
_ps_cephes_exp_p1
);
y
=
_mm_mul_ps
(
y
,
x
);
y
=
_mm_add_ps
(
y
,
*
(
v4sf
*
)
_ps_cephes_exp_p2
);
y
=
_mm_mul_ps
(
y
,
x
);
y
=
_mm_add_ps
(
y
,
*
(
v4sf
*
)
_ps_cephes_exp_p3
);
y
=
_mm_mul_ps
(
y
,
x
);
y
=
_mm_add_ps
(
y
,
*
(
v4sf
*
)
_ps_cephes_exp_p4
);
y
=
_mm_mul_ps
(
y
,
x
);
y
=
_mm_add_ps
(
y
,
*
(
v4sf
*
)
_ps_cephes_exp_p5
);
y
=
_mm_mul_ps
(
y
,
z
);
y
=
_mm_add_ps
(
y
,
x
);
y
=
_mm_add_ps
(
y
,
one
);
/* build 2^n */
#ifndef USE_SSE2
z
=
_mm_movehl_ps
(
z
,
fx
);
mm0
=
_mm_cvttps_pi32
(
fx
);
mm1
=
_mm_cvttps_pi32
(
z
);
mm0
=
_mm_add_pi32
(
mm0
,
*
(
v2si
*
)
_pi32_0x7f
);
mm1
=
_mm_add_pi32
(
mm1
,
*
(
v2si
*
)
_pi32_0x7f
);
mm0
=
_mm_slli_pi32
(
mm0
,
23
);
mm1
=
_mm_slli_pi32
(
mm1
,
23
);
v4sf
pow2n
;
COPY_MM_TO_XMM
(
mm0
,
mm1
,
pow2n
);
_mm_empty
();
#else
emm0
=
_mm_cvttps_epi32
(
fx
);
emm0
=
_mm_add_epi32
(
emm0
,
*
(
v4si
*
)
_pi32_0x7f
);
emm0
=
_mm_slli_epi32
(
emm0
,
23
);
v4sf
pow2n
=
_mm_castsi128_ps
(
emm0
);
#endif
y
=
_mm_mul_ps
(
y
,
pow2n
);
return
y
;
}
_PS_CONST
(
minus_cephes_DP1
,
-
0
.
78515625
);
_PS_CONST
(
minus_cephes_DP2
,
-
2.4187564849853515625e-4
);
_PS_CONST
(
minus_cephes_DP3
,
-
3.77489497744594108e-8
);
_PS_CONST
(
sincof_p0
,
-
1.9515295891E-4
);
_PS_CONST
(
sincof_p1
,
8.3321608736E-3
);
_PS_CONST
(
sincof_p2
,
-
1.6666654611E-1
);
_PS_CONST
(
coscof_p0
,
2.443315711809948E-005
);
_PS_CONST
(
coscof_p1
,
-
1.388731625493765E-003
);
_PS_CONST
(
coscof_p2
,
4.166664568298827E-002
);
_PS_CONST
(
cephes_FOPI
,
1
.
27323954473516
);
// 4 / M_PI
/* evaluation of 4 sines at onces, using only SSE1+MMX intrinsics so
it runs also on old athlons XPs and the pentium III of your grand
mother.
The code is the exact rewriting of the cephes sinf function.
Precision is excellent as long as x < 8192 (I did not bother to
take into account the special handling they have for greater values
-- it does not return garbage for arguments over 8192, though, but
the extra precision is missing).
Note that it is such that sinf((float)M_PI) = 8.74e-8, which is the
surprising but correct result.
Performance is also surprisingly good, 1.33 times faster than the
macos vsinf SSE2 function, and 1.5 times faster than the
__vrs4_sinf of amd's ACML (which is only available in 64 bits). Not
too bad for an SSE1 function (with no special tuning) !
However the latter libraries probably have a much better handling of NaN,
Inf, denormalized and other special arguments..
On my core 1 duo, the execution of this function takes approximately 95 cycles.
From what I have observed on the experiments with Intel AMath lib, switching to an
SSE2 version would improve the perf by only 10%.
Since it is based on SSE intrinsics, it has to be compiled at -O2 to
deliver full speed.
*/
OPENMM_EXPORT
v4sf
sin_ps
(
v4sf
x
)
{
// any x
v4sf
xmm1
,
xmm2
=
_mm_setzero_ps
(),
xmm3
,
sign_bit
,
y
;
#ifdef USE_SSE2
v4si
emm0
,
emm2
;
#else
v2si
mm0
,
mm1
,
mm2
,
mm3
;
#endif
sign_bit
=
x
;
/* take the absolute value */
x
=
_mm_and_ps
(
x
,
*
(
v4sf
*
)
_ps_inv_sign_mask
);
/* extract the sign bit (upper one) */
sign_bit
=
_mm_and_ps
(
sign_bit
,
*
(
v4sf
*
)
_ps_sign_mask
);
/* scale by 4/Pi */
y
=
_mm_mul_ps
(
x
,
*
(
v4sf
*
)
_ps_cephes_FOPI
);
#ifdef USE_SSE2
/* store the integer part of y in mm0 */
emm2
=
_mm_cvttps_epi32
(
y
);
/* j=(j+1) & (~1) (see the cephes sources) */
emm2
=
_mm_add_epi32
(
emm2
,
*
(
v4si
*
)
_pi32_1
);
emm2
=
_mm_and_si128
(
emm2
,
*
(
v4si
*
)
_pi32_inv1
);
y
=
_mm_cvtepi32_ps
(
emm2
);
/* get the swap sign flag */
emm0
=
_mm_and_si128
(
emm2
,
*
(
v4si
*
)
_pi32_4
);
emm0
=
_mm_slli_epi32
(
emm0
,
29
);
/* get the polynom selection mask
there is one polynom for 0 <= x <= Pi/4
and another one for Pi/4<x<=Pi/2
Both branches will be computed.
*/
emm2
=
_mm_and_si128
(
emm2
,
*
(
v4si
*
)
_pi32_2
);
emm2
=
_mm_cmpeq_epi32
(
emm2
,
_mm_setzero_si128
());
v4sf
swap_sign_bit
=
_mm_castsi128_ps
(
emm0
);
v4sf
poly_mask
=
_mm_castsi128_ps
(
emm2
);
sign_bit
=
_mm_xor_ps
(
sign_bit
,
swap_sign_bit
);
#else
/* store the integer part of y in mm0:mm1 */
xmm2
=
_mm_movehl_ps
(
xmm2
,
y
);
mm2
=
_mm_cvttps_pi32
(
y
);
mm3
=
_mm_cvttps_pi32
(
xmm2
);
/* j=(j+1) & (~1) (see the cephes sources) */
mm2
=
_mm_add_pi32
(
mm2
,
*
(
v2si
*
)
_pi32_1
);
mm3
=
_mm_add_pi32
(
mm3
,
*
(
v2si
*
)
_pi32_1
);
mm2
=
_mm_and_si64
(
mm2
,
*
(
v2si
*
)
_pi32_inv1
);
mm3
=
_mm_and_si64
(
mm3
,
*
(
v2si
*
)
_pi32_inv1
);
y
=
_mm_cvtpi32x2_ps
(
mm2
,
mm3
);
/* get the swap sign flag */
mm0
=
_mm_and_si64
(
mm2
,
*
(
v2si
*
)
_pi32_4
);
mm1
=
_mm_and_si64
(
mm3
,
*
(
v2si
*
)
_pi32_4
);
mm0
=
_mm_slli_pi32
(
mm0
,
29
);
mm1
=
_mm_slli_pi32
(
mm1
,
29
);
/* get the polynom selection mask */
mm2
=
_mm_and_si64
(
mm2
,
*
(
v2si
*
)
_pi32_2
);
mm3
=
_mm_and_si64
(
mm3
,
*
(
v2si
*
)
_pi32_2
);
mm2
=
_mm_cmpeq_pi32
(
mm2
,
_mm_setzero_si64
());
mm3
=
_mm_cmpeq_pi32
(
mm3
,
_mm_setzero_si64
());
v4sf
swap_sign_bit
,
poly_mask
;
COPY_MM_TO_XMM
(
mm0
,
mm1
,
swap_sign_bit
);
COPY_MM_TO_XMM
(
mm2
,
mm3
,
poly_mask
);
sign_bit
=
_mm_xor_ps
(
sign_bit
,
swap_sign_bit
);
_mm_empty
();
/* good-bye mmx */
#endif
/* The magic pass: "Extended precision modular arithmetic"
x = ((x - y * DP1) - y * DP2) - y * DP3; */
xmm1
=
*
(
v4sf
*
)
_ps_minus_cephes_DP1
;
xmm2
=
*
(
v4sf
*
)
_ps_minus_cephes_DP2
;
xmm3
=
*
(
v4sf
*
)
_ps_minus_cephes_DP3
;
xmm1
=
_mm_mul_ps
(
y
,
xmm1
);
xmm2
=
_mm_mul_ps
(
y
,
xmm2
);
xmm3
=
_mm_mul_ps
(
y
,
xmm3
);
x
=
_mm_add_ps
(
x
,
xmm1
);
x
=
_mm_add_ps
(
x
,
xmm2
);
x
=
_mm_add_ps
(
x
,
xmm3
);
/* Evaluate the first polynom (0 <= x <= Pi/4) */
y
=
*
(
v4sf
*
)
_ps_coscof_p0
;
v4sf
z
=
_mm_mul_ps
(
x
,
x
);
y
=
_mm_mul_ps
(
y
,
z
);
y
=
_mm_add_ps
(
y
,
*
(
v4sf
*
)
_ps_coscof_p1
);
y
=
_mm_mul_ps
(
y
,
z
);
y
=
_mm_add_ps
(
y
,
*
(
v4sf
*
)
_ps_coscof_p2
);
y
=
_mm_mul_ps
(
y
,
z
);
y
=
_mm_mul_ps
(
y
,
z
);
v4sf
tmp
=
_mm_mul_ps
(
z
,
*
(
v4sf
*
)
_ps_0p5
);
y
=
_mm_sub_ps
(
y
,
tmp
);
y
=
_mm_add_ps
(
y
,
*
(
v4sf
*
)
_ps_1
);
/* Evaluate the second polynom (Pi/4 <= x <= 0) */
v4sf
y2
=
*
(
v4sf
*
)
_ps_sincof_p0
;
y2
=
_mm_mul_ps
(
y2
,
z
);
y2
=
_mm_add_ps
(
y2
,
*
(
v4sf
*
)
_ps_sincof_p1
);
y2
=
_mm_mul_ps
(
y2
,
z
);
y2
=
_mm_add_ps
(
y2
,
*
(
v4sf
*
)
_ps_sincof_p2
);
y2
=
_mm_mul_ps
(
y2
,
z
);
y2
=
_mm_mul_ps
(
y2
,
x
);
y2
=
_mm_add_ps
(
y2
,
x
);
/* select the correct result from the two polynoms */
xmm3
=
poly_mask
;
y2
=
_mm_and_ps
(
xmm3
,
y2
);
//, xmm3);
y
=
_mm_andnot_ps
(
xmm3
,
y
);
y
=
_mm_add_ps
(
y
,
y2
);
/* update the sign */
y
=
_mm_xor_ps
(
y
,
sign_bit
);
return
y
;
}
/* almost the same as sin_ps */
OPENMM_EXPORT
v4sf
cos_ps
(
v4sf
x
)
{
// any x
v4sf
xmm1
,
xmm2
=
_mm_setzero_ps
(),
xmm3
,
y
;
#ifdef USE_SSE2
v4si
emm0
,
emm2
;
#else
v2si
mm0
,
mm1
,
mm2
,
mm3
;
#endif
/* take the absolute value */
x
=
_mm_and_ps
(
x
,
*
(
v4sf
*
)
_ps_inv_sign_mask
);
/* scale by 4/Pi */
y
=
_mm_mul_ps
(
x
,
*
(
v4sf
*
)
_ps_cephes_FOPI
);
#ifdef USE_SSE2
/* store the integer part of y in mm0 */
emm2
=
_mm_cvttps_epi32
(
y
);
/* j=(j+1) & (~1) (see the cephes sources) */
emm2
=
_mm_add_epi32
(
emm2
,
*
(
v4si
*
)
_pi32_1
);
emm2
=
_mm_and_si128
(
emm2
,
*
(
v4si
*
)
_pi32_inv1
);
y
=
_mm_cvtepi32_ps
(
emm2
);
emm2
=
_mm_sub_epi32
(
emm2
,
*
(
v4si
*
)
_pi32_2
);
/* get the swap sign flag */
emm0
=
_mm_andnot_si128
(
emm2
,
*
(
v4si
*
)
_pi32_4
);
emm0
=
_mm_slli_epi32
(
emm0
,
29
);
/* get the polynom selection mask */
emm2
=
_mm_and_si128
(
emm2
,
*
(
v4si
*
)
_pi32_2
);
emm2
=
_mm_cmpeq_epi32
(
emm2
,
_mm_setzero_si128
());
v4sf
sign_bit
=
_mm_castsi128_ps
(
emm0
);
v4sf
poly_mask
=
_mm_castsi128_ps
(
emm2
);
#else
/* store the integer part of y in mm0:mm1 */
xmm2
=
_mm_movehl_ps
(
xmm2
,
y
);
mm2
=
_mm_cvttps_pi32
(
y
);
mm3
=
_mm_cvttps_pi32
(
xmm2
);
/* j=(j+1) & (~1) (see the cephes sources) */
mm2
=
_mm_add_pi32
(
mm2
,
*
(
v2si
*
)
_pi32_1
);
mm3
=
_mm_add_pi32
(
mm3
,
*
(
v2si
*
)
_pi32_1
);
mm2
=
_mm_and_si64
(
mm2
,
*
(
v2si
*
)
_pi32_inv1
);
mm3
=
_mm_and_si64
(
mm3
,
*
(
v2si
*
)
_pi32_inv1
);
y
=
_mm_cvtpi32x2_ps
(
mm2
,
mm3
);
mm2
=
_mm_sub_pi32
(
mm2
,
*
(
v2si
*
)
_pi32_2
);
mm3
=
_mm_sub_pi32
(
mm3
,
*
(
v2si
*
)
_pi32_2
);
/* get the swap sign flag in mm0:mm1 and the
polynom selection mask in mm2:mm3 */
mm0
=
_mm_andnot_si64
(
mm2
,
*
(
v2si
*
)
_pi32_4
);
mm1
=
_mm_andnot_si64
(
mm3
,
*
(
v2si
*
)
_pi32_4
);
mm0
=
_mm_slli_pi32
(
mm0
,
29
);
mm1
=
_mm_slli_pi32
(
mm1
,
29
);
mm2
=
_mm_and_si64
(
mm2
,
*
(
v2si
*
)
_pi32_2
);
mm3
=
_mm_and_si64
(
mm3
,
*
(
v2si
*
)
_pi32_2
);
mm2
=
_mm_cmpeq_pi32
(
mm2
,
_mm_setzero_si64
());
mm3
=
_mm_cmpeq_pi32
(
mm3
,
_mm_setzero_si64
());
v4sf
sign_bit
,
poly_mask
;
COPY_MM_TO_XMM
(
mm0
,
mm1
,
sign_bit
);
COPY_MM_TO_XMM
(
mm2
,
mm3
,
poly_mask
);
_mm_empty
();
/* good-bye mmx */
#endif
/* The magic pass: "Extended precision modular arithmetic"
x = ((x - y * DP1) - y * DP2) - y * DP3; */
xmm1
=
*
(
v4sf
*
)
_ps_minus_cephes_DP1
;
xmm2
=
*
(
v4sf
*
)
_ps_minus_cephes_DP2
;
xmm3
=
*
(
v4sf
*
)
_ps_minus_cephes_DP3
;
xmm1
=
_mm_mul_ps
(
y
,
xmm1
);
xmm2
=
_mm_mul_ps
(
y
,
xmm2
);
xmm3
=
_mm_mul_ps
(
y
,
xmm3
);
x
=
_mm_add_ps
(
x
,
xmm1
);
x
=
_mm_add_ps
(
x
,
xmm2
);
x
=
_mm_add_ps
(
x
,
xmm3
);
/* Evaluate the first polynom (0 <= x <= Pi/4) */
y
=
*
(
v4sf
*
)
_ps_coscof_p0
;
v4sf
z
=
_mm_mul_ps
(
x
,
x
);
y
=
_mm_mul_ps
(
y
,
z
);
y
=
_mm_add_ps
(
y
,
*
(
v4sf
*
)
_ps_coscof_p1
);
y
=
_mm_mul_ps
(
y
,
z
);
y
=
_mm_add_ps
(
y
,
*
(
v4sf
*
)
_ps_coscof_p2
);
y
=
_mm_mul_ps
(
y
,
z
);
y
=
_mm_mul_ps
(
y
,
z
);
v4sf
tmp
=
_mm_mul_ps
(
z
,
*
(
v4sf
*
)
_ps_0p5
);
y
=
_mm_sub_ps
(
y
,
tmp
);
y
=
_mm_add_ps
(
y
,
*
(
v4sf
*
)
_ps_1
);
/* Evaluate the second polynom (Pi/4 <= x <= 0) */
v4sf
y2
=
*
(
v4sf
*
)
_ps_sincof_p0
;
y2
=
_mm_mul_ps
(
y2
,
z
);
y2
=
_mm_add_ps
(
y2
,
*
(
v4sf
*
)
_ps_sincof_p1
);
y2
=
_mm_mul_ps
(
y2
,
z
);
y2
=
_mm_add_ps
(
y2
,
*
(
v4sf
*
)
_ps_sincof_p2
);
y2
=
_mm_mul_ps
(
y2
,
z
);
y2
=
_mm_mul_ps
(
y2
,
x
);
y2
=
_mm_add_ps
(
y2
,
x
);
/* select the correct result from the two polynoms */
xmm3
=
poly_mask
;
y2
=
_mm_and_ps
(
xmm3
,
y2
);
//, xmm3);
y
=
_mm_andnot_ps
(
xmm3
,
y
);
y
=
_mm_add_ps
(
y
,
y2
);
/* update the sign */
y
=
_mm_xor_ps
(
y
,
sign_bit
);
return
y
;
}
/* since sin_ps and cos_ps are almost identical, sincos_ps could replace both of them..
it is almost as fast, and gives you a free cosine with your sine */
OPENMM_EXPORT
void
sincos_ps
(
v4sf
x
,
v4sf
*
s
,
v4sf
*
c
)
{
v4sf
xmm1
,
xmm2
,
xmm3
=
_mm_setzero_ps
(),
sign_bit_sin
,
y
;
#ifdef USE_SSE2
v4si
emm0
,
emm2
,
emm4
;
#else
v2si
mm0
,
mm1
,
mm2
,
mm3
,
mm4
,
mm5
;
#endif
sign_bit_sin
=
x
;
/* take the absolute value */
x
=
_mm_and_ps
(
x
,
*
(
v4sf
*
)
_ps_inv_sign_mask
);
/* extract the sign bit (upper one) */
sign_bit_sin
=
_mm_and_ps
(
sign_bit_sin
,
*
(
v4sf
*
)
_ps_sign_mask
);
/* scale by 4/Pi */
y
=
_mm_mul_ps
(
x
,
*
(
v4sf
*
)
_ps_cephes_FOPI
);
#ifdef USE_SSE2
/* store the integer part of y in emm2 */
emm2
=
_mm_cvttps_epi32
(
y
);
/* j=(j+1) & (~1) (see the cephes sources) */
emm2
=
_mm_add_epi32
(
emm2
,
*
(
v4si
*
)
_pi32_1
);
emm2
=
_mm_and_si128
(
emm2
,
*
(
v4si
*
)
_pi32_inv1
);
y
=
_mm_cvtepi32_ps
(
emm2
);
emm4
=
emm2
;
/* get the swap sign flag for the sine */
emm0
=
_mm_and_si128
(
emm2
,
*
(
v4si
*
)
_pi32_4
);
emm0
=
_mm_slli_epi32
(
emm0
,
29
);
v4sf
swap_sign_bit_sin
=
_mm_castsi128_ps
(
emm0
);
/* get the polynom selection mask for the sine*/
emm2
=
_mm_and_si128
(
emm2
,
*
(
v4si
*
)
_pi32_2
);
emm2
=
_mm_cmpeq_epi32
(
emm2
,
_mm_setzero_si128
());
v4sf
poly_mask
=
_mm_castsi128_ps
(
emm2
);
#else
/* store the integer part of y in mm2:mm3 */
xmm3
=
_mm_movehl_ps
(
xmm3
,
y
);
mm2
=
_mm_cvttps_pi32
(
y
);
mm3
=
_mm_cvttps_pi32
(
xmm3
);
/* j=(j+1) & (~1) (see the cephes sources) */
mm2
=
_mm_add_pi32
(
mm2
,
*
(
v2si
*
)
_pi32_1
);
mm3
=
_mm_add_pi32
(
mm3
,
*
(
v2si
*
)
_pi32_1
);
mm2
=
_mm_and_si64
(
mm2
,
*
(
v2si
*
)
_pi32_inv1
);
mm3
=
_mm_and_si64
(
mm3
,
*
(
v2si
*
)
_pi32_inv1
);
y
=
_mm_cvtpi32x2_ps
(
mm2
,
mm3
);
mm4
=
mm2
;
mm5
=
mm3
;
/* get the swap sign flag for the sine */
mm0
=
_mm_and_si64
(
mm2
,
*
(
v2si
*
)
_pi32_4
);
mm1
=
_mm_and_si64
(
mm3
,
*
(
v2si
*
)
_pi32_4
);
mm0
=
_mm_slli_pi32
(
mm0
,
29
);
mm1
=
_mm_slli_pi32
(
mm1
,
29
);
v4sf
swap_sign_bit_sin
;
COPY_MM_TO_XMM
(
mm0
,
mm1
,
swap_sign_bit_sin
);
/* get the polynom selection mask for the sine */
mm2
=
_mm_and_si64
(
mm2
,
*
(
v2si
*
)
_pi32_2
);
mm3
=
_mm_and_si64
(
mm3
,
*
(
v2si
*
)
_pi32_2
);
mm2
=
_mm_cmpeq_pi32
(
mm2
,
_mm_setzero_si64
());
mm3
=
_mm_cmpeq_pi32
(
mm3
,
_mm_setzero_si64
());
v4sf
poly_mask
;
COPY_MM_TO_XMM
(
mm2
,
mm3
,
poly_mask
);
#endif
/* The magic pass: "Extended precision modular arithmetic"
x = ((x - y * DP1) - y * DP2) - y * DP3; */
xmm1
=
*
(
v4sf
*
)
_ps_minus_cephes_DP1
;
xmm2
=
*
(
v4sf
*
)
_ps_minus_cephes_DP2
;
xmm3
=
*
(
v4sf
*
)
_ps_minus_cephes_DP3
;
xmm1
=
_mm_mul_ps
(
y
,
xmm1
);
xmm2
=
_mm_mul_ps
(
y
,
xmm2
);
xmm3
=
_mm_mul_ps
(
y
,
xmm3
);
x
=
_mm_add_ps
(
x
,
xmm1
);
x
=
_mm_add_ps
(
x
,
xmm2
);
x
=
_mm_add_ps
(
x
,
xmm3
);
#ifdef USE_SSE2
emm4
=
_mm_sub_epi32
(
emm4
,
*
(
v4si
*
)
_pi32_2
);
emm4
=
_mm_andnot_si128
(
emm4
,
*
(
v4si
*
)
_pi32_4
);
emm4
=
_mm_slli_epi32
(
emm4
,
29
);
v4sf
sign_bit_cos
=
_mm_castsi128_ps
(
emm4
);
#else
/* get the sign flag for the cosine */
mm4
=
_mm_sub_pi32
(
mm4
,
*
(
v2si
*
)
_pi32_2
);
mm5
=
_mm_sub_pi32
(
mm5
,
*
(
v2si
*
)
_pi32_2
);
mm4
=
_mm_andnot_si64
(
mm4
,
*
(
v2si
*
)
_pi32_4
);
mm5
=
_mm_andnot_si64
(
mm5
,
*
(
v2si
*
)
_pi32_4
);
mm4
=
_mm_slli_pi32
(
mm4
,
29
);
mm5
=
_mm_slli_pi32
(
mm5
,
29
);
v4sf
sign_bit_cos
;
COPY_MM_TO_XMM
(
mm4
,
mm5
,
sign_bit_cos
);
_mm_empty
();
/* good-bye mmx */
#endif
sign_bit_sin
=
_mm_xor_ps
(
sign_bit_sin
,
swap_sign_bit_sin
);
/* Evaluate the first polynom (0 <= x <= Pi/4) */
v4sf
z
=
_mm_mul_ps
(
x
,
x
);
y
=
*
(
v4sf
*
)
_ps_coscof_p0
;
y
=
_mm_mul_ps
(
y
,
z
);
y
=
_mm_add_ps
(
y
,
*
(
v4sf
*
)
_ps_coscof_p1
);
y
=
_mm_mul_ps
(
y
,
z
);
y
=
_mm_add_ps
(
y
,
*
(
v4sf
*
)
_ps_coscof_p2
);
y
=
_mm_mul_ps
(
y
,
z
);
y
=
_mm_mul_ps
(
y
,
z
);
v4sf
tmp
=
_mm_mul_ps
(
z
,
*
(
v4sf
*
)
_ps_0p5
);
y
=
_mm_sub_ps
(
y
,
tmp
);
y
=
_mm_add_ps
(
y
,
*
(
v4sf
*
)
_ps_1
);
/* Evaluate the second polynom (Pi/4 <= x <= 0) */
v4sf
y2
=
*
(
v4sf
*
)
_ps_sincof_p0
;
y2
=
_mm_mul_ps
(
y2
,
z
);
y2
=
_mm_add_ps
(
y2
,
*
(
v4sf
*
)
_ps_sincof_p1
);
y2
=
_mm_mul_ps
(
y2
,
z
);
y2
=
_mm_add_ps
(
y2
,
*
(
v4sf
*
)
_ps_sincof_p2
);
y2
=
_mm_mul_ps
(
y2
,
z
);
y2
=
_mm_mul_ps
(
y2
,
x
);
y2
=
_mm_add_ps
(
y2
,
x
);
/* select the correct result from the two polynoms */
xmm3
=
poly_mask
;
v4sf
ysin2
=
_mm_and_ps
(
xmm3
,
y2
);
v4sf
ysin1
=
_mm_andnot_ps
(
xmm3
,
y
);
y2
=
_mm_sub_ps
(
y2
,
ysin2
);
y
=
_mm_sub_ps
(
y
,
ysin1
);
xmm1
=
_mm_add_ps
(
ysin1
,
ysin2
);
xmm2
=
_mm_add_ps
(
y
,
y2
);
/* update the sign */
*
s
=
_mm_xor_ps
(
xmm1
,
sign_bit_sin
);
*
c
=
_mm_xor_ps
(
xmm2
,
sign_bit_cos
);
}
libraries/vecmath/src/vecmath.cpp
0 → 100644
View file @
cecc774a
#if defined(__ANDROID__)
#include "neon_mathfun.h"
#else
#if !defined(__PNACL__)
#define USE_SSE2
#include "sse_mathfun.h"
#endif
#endif
openmmapi/include/openmm/CustomAngleForce.h
View file @
cecc774a
...
@@ -171,7 +171,7 @@ public:
...
@@ -171,7 +171,7 @@ public:
* @param parameters the list of parameters for the new angle
* @param parameters the list of parameters for the new angle
* @return the index of the angle that was added
* @return the index of the angle that was added
*/
*/
int
addAngle
(
int
particle1
,
int
particle2
,
int
particle3
,
const
std
::
vector
<
double
>&
parameters
);
int
addAngle
(
int
particle1
,
int
particle2
,
int
particle3
,
const
std
::
vector
<
double
>&
parameters
=
std
::
vector
<
double
>
()
);
/**
/**
* Get the force field parameters for an angle term.
* Get the force field parameters for an angle term.
*
*
...
@@ -191,7 +191,7 @@ public:
...
@@ -191,7 +191,7 @@ public:
* @param particle3 the index of the third particle connected by the angle
* @param particle3 the index of the third particle connected by the angle
* @param parameters the list of parameters for the angle
* @param parameters the list of parameters for the angle
*/
*/
void
setAngleParameters
(
int
index
,
int
particle1
,
int
particle2
,
int
particle3
,
const
std
::
vector
<
double
>&
parameters
);
void
setAngleParameters
(
int
index
,
int
particle1
,
int
particle2
,
int
particle3
,
const
std
::
vector
<
double
>&
parameters
=
std
::
vector
<
double
>
()
);
/**
/**
* Update the per-angle parameters in a Context to match those stored in this Force object. This method provides
* Update the per-angle parameters in a Context to match those stored in this Force object. This method provides
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
...
...
openmmapi/include/openmm/CustomBondForce.h
View file @
cecc774a
...
@@ -170,7 +170,7 @@ public:
...
@@ -170,7 +170,7 @@ public:
* @param parameters the list of parameters for the new bond
* @param parameters the list of parameters for the new bond
* @return the index of the bond that was added
* @return the index of the bond that was added
*/
*/
int
addBond
(
int
particle1
,
int
particle2
,
const
std
::
vector
<
double
>&
parameters
);
int
addBond
(
int
particle1
,
int
particle2
,
const
std
::
vector
<
double
>&
parameters
=
std
::
vector
<
double
>
()
);
/**
/**
* Get the force field parameters for a bond term.
* Get the force field parameters for a bond term.
*
*
...
@@ -188,7 +188,7 @@ public:
...
@@ -188,7 +188,7 @@ public:
* @param particle2 the index of the second particle connected by the bond
* @param particle2 the index of the second particle connected by the bond
* @param parameters the list of parameters for the bond
* @param parameters the list of parameters for the bond
*/
*/
void
setBondParameters
(
int
index
,
int
particle1
,
int
particle2
,
const
std
::
vector
<
double
>&
parameters
);
void
setBondParameters
(
int
index
,
int
particle1
,
int
particle2
,
const
std
::
vector
<
double
>&
parameters
=
std
::
vector
<
double
>
()
);
/**
/**
* Update the per-bond parameters in a Context to match those stored in this Force object. This method provides
* Update the per-bond parameters in a Context to match those stored in this Force object. This method provides
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
...
...
openmmapi/include/openmm/CustomCentroidBondForce.h
View file @
cecc774a
...
@@ -237,7 +237,7 @@ public:
...
@@ -237,7 +237,7 @@ public:
* If this is omitted, then particle masses will be used as weights.
* If this is omitted, then particle masses will be used as weights.
* @return the index of the group that was added
* @return the index of the group that was added
*/
*/
int
addGroup
(
const
std
::
vector
<
int
>&
particles
,
const
std
::
vector
<
double
>&
weights
=
std
::
vector
<
double
>
());
int
addGroup
(
const
std
::
vector
<
int
>&
particles
,
const
std
::
vector
<
double
>&
weights
=
std
::
vector
<
double
>
());
/**
/**
* Get the properties of a group.
* Get the properties of a group.
*
*
...
@@ -256,7 +256,7 @@ public:
...
@@ -256,7 +256,7 @@ public:
* @param weights the weight to use for each particle when computing the center position.
* @param weights the weight to use for each particle when computing the center position.
* If this is omitted, then particle masses will be used as weights.
* If this is omitted, then particle masses will be used as weights.
*/
*/
void
setGroupParameters
(
int
index
,
const
std
::
vector
<
int
>&
particles
,
const
std
::
vector
<
double
>&
weights
=
std
::
vector
<
double
>
());
void
setGroupParameters
(
int
index
,
const
std
::
vector
<
int
>&
particles
,
const
std
::
vector
<
double
>&
weights
=
std
::
vector
<
double
>
());
/**
/**
* Add a bond to the force
* Add a bond to the force
*
*
...
@@ -264,7 +264,7 @@ public:
...
@@ -264,7 +264,7 @@ public:
* @param parameters the list of per-bond parameter values for the new bond
* @param parameters the list of per-bond parameter values for the new bond
* @return the index of the bond that was added
* @return the index of the bond that was added
*/
*/
int
addBond
(
const
std
::
vector
<
int
>&
groups
,
const
std
::
vector
<
double
>&
parameters
);
int
addBond
(
const
std
::
vector
<
int
>&
groups
,
const
std
::
vector
<
double
>&
parameters
=
std
::
vector
<
double
>
()
);
/**
/**
* Get the properties of a bond.
* Get the properties of a bond.
*
*
...
@@ -280,7 +280,7 @@ public:
...
@@ -280,7 +280,7 @@ public:
* @param groups the indices of the groups in the bond
* @param groups the indices of the groups in the bond
* @param parameters the list of per-bond parameter values for the bond
* @param parameters the list of per-bond parameter values for the bond
*/
*/
void
setBondParameters
(
int
index
,
const
std
::
vector
<
int
>&
groups
,
const
std
::
vector
<
double
>&
parameters
);
void
setBondParameters
(
int
index
,
const
std
::
vector
<
int
>&
groups
,
const
std
::
vector
<
double
>&
parameters
=
std
::
vector
<
double
>
()
);
/**
/**
* Add a tabulated function that may appear in the energy expression.
* Add a tabulated function that may appear in the energy expression.
*
*
...
...
openmmapi/include/openmm/CustomCompoundBondForce.h
View file @
cecc774a
...
@@ -219,7 +219,7 @@ public:
...
@@ -219,7 +219,7 @@ public:
* @param parameters the list of per-bond parameter values for the new bond
* @param parameters the list of per-bond parameter values for the new bond
* @return the index of the bond that was added
* @return the index of the bond that was added
*/
*/
int
addBond
(
const
std
::
vector
<
int
>&
particles
,
const
std
::
vector
<
double
>&
parameters
);
int
addBond
(
const
std
::
vector
<
int
>&
particles
,
const
std
::
vector
<
double
>&
parameters
=
std
::
vector
<
double
>
()
);
/**
/**
* Get the properties of a bond.
* Get the properties of a bond.
*
*
...
@@ -235,7 +235,7 @@ public:
...
@@ -235,7 +235,7 @@ public:
* @param particles the indices of the particles in the bond
* @param particles the indices of the particles in the bond
* @param parameters the list of per-bond parameter values for the bond
* @param parameters the list of per-bond parameter values for the bond
*/
*/
void
setBondParameters
(
int
index
,
const
std
::
vector
<
int
>&
particles
,
const
std
::
vector
<
double
>&
parameters
);
void
setBondParameters
(
int
index
,
const
std
::
vector
<
int
>&
particles
,
const
std
::
vector
<
double
>&
parameters
=
std
::
vector
<
double
>
()
);
/**
/**
* Add a tabulated function that may appear in the energy expression.
* Add a tabulated function that may appear in the energy expression.
*
*
...
...
openmmapi/include/openmm/CustomExternalForce.h
View file @
cecc774a
...
@@ -67,6 +67,14 @@ namespace OpenMM {
...
@@ -67,6 +67,14 @@ namespace OpenMM {
* force->addPerParticleParameter("z0");
* force->addPerParticleParameter("z0");
* </pre></tt>
* </pre></tt>
*
*
* Special care is needed in systems that use periodic boundary conditions. In that case, each particle really represents
* an infinite set of particles repeating through space. The variables x, y, and z contain the coordinates of one of those
* periodic copies, but there is no guarantee about which. It might even change from one time step to the next. You can handle
* this situation by using the function periodicdistance(x1, y1, z1, x2, y2, z2), which returns the minimum distance between
* periodic copies of the points (x1, y1, z1) and (x2, y2, z2). For example, the force given above would be rewritten as
*
* <tt>CustomExternalForce* force = new CustomExternalForce("k*periodicdistance(x, y, z, x0, y0, z0)^2");</tt>
*
* Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following
* Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following
* functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta, select. All trigonometric functions
* functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta, select. All trigonometric functions
* are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise.
* are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise.
...
@@ -172,7 +180,7 @@ public:
...
@@ -172,7 +180,7 @@ public:
* @param parameters the list of parameters for the new force term
* @param parameters the list of parameters for the new force term
* @return the index of the particle term that was added
* @return the index of the particle term that was added
*/
*/
int
addParticle
(
int
particle
,
const
std
::
vector
<
double
>&
parameters
);
int
addParticle
(
int
particle
,
const
std
::
vector
<
double
>&
parameters
=
std
::
vector
<
double
>
()
);
/**
/**
* Get the force field parameters for a force field term.
* Get the force field parameters for a force field term.
*
*
...
@@ -188,7 +196,7 @@ public:
...
@@ -188,7 +196,7 @@ public:
* @param particle the index of the particle this term is applied to
* @param particle the index of the particle this term is applied to
* @param parameters the list of parameters for the force field term
* @param parameters the list of parameters for the force field term
*/
*/
void
setParticleParameters
(
int
index
,
int
particle
,
const
std
::
vector
<
double
>&
parameters
);
void
setParticleParameters
(
int
index
,
int
particle
,
const
std
::
vector
<
double
>&
parameters
=
std
::
vector
<
double
>
()
);
/**
/**
* Update the per-particle parameters in a Context to match those stored in this Force object. This method provides
* Update the per-particle parameters in a Context to match those stored in this Force object. This method provides
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
...
@@ -206,9 +214,7 @@ public:
...
@@ -206,9 +214,7 @@ public:
*
*
* @returns false
* @returns false
*/
*/
bool
usesPeriodicBoundaryConditions
()
const
{
bool
usesPeriodicBoundaryConditions
()
const
;
return
false
;
}
protected:
protected:
ForceImpl
*
createImpl
()
const
;
ForceImpl
*
createImpl
()
const
;
private:
private:
...
...
openmmapi/include/openmm/CustomGBForce.h
View file @
cecc774a
...
@@ -319,7 +319,7 @@ public:
...
@@ -319,7 +319,7 @@ public:
* @param parameters the list of parameters for the new particle
* @param parameters the list of parameters for the new particle
* @return the index of the particle that was added
* @return the index of the particle that was added
*/
*/
int
addParticle
(
const
std
::
vector
<
double
>&
parameters
);
int
addParticle
(
const
std
::
vector
<
double
>&
parameters
=
std
::
vector
<
double
>
()
);
/**
/**
* Get the nonbonded force parameters for a particle.
* Get the nonbonded force parameters for a particle.
*
*
...
...
openmmapi/include/openmm/CustomHbondForce.h
View file @
cecc774a
...
@@ -296,7 +296,7 @@ public:
...
@@ -296,7 +296,7 @@ public:
* @param parameters the list of per-donor parameter values for the new donor
* @param parameters the list of per-donor parameter values for the new donor
* @return the index of the donor that was added
* @return the index of the donor that was added
*/
*/
int
addDonor
(
int
d1
,
int
d2
,
int
d3
,
const
std
::
vector
<
double
>&
parameters
);
int
addDonor
(
int
d1
,
int
d2
,
int
d3
,
const
std
::
vector
<
double
>&
parameters
=
std
::
vector
<
double
>
()
);
/**
/**
* Get the properties of a donor group.
* Get the properties of a donor group.
*
*
...
@@ -320,7 +320,7 @@ public:
...
@@ -320,7 +320,7 @@ public:
* less than three particles, this must be -1.
* less than three particles, this must be -1.
* @param parameters the list of per-donor parameter values for the donor
* @param parameters the list of per-donor parameter values for the donor
*/
*/
void
setDonorParameters
(
int
index
,
int
d1
,
int
d2
,
int
d3
,
const
std
::
vector
<
double
>&
parameters
);
void
setDonorParameters
(
int
index
,
int
d1
,
int
d2
,
int
d3
,
const
std
::
vector
<
double
>&
parameters
=
std
::
vector
<
double
>
()
);
/**
/**
* Add an acceptor group to the force
* Add an acceptor group to the force
*
*
...
@@ -332,7 +332,7 @@ public:
...
@@ -332,7 +332,7 @@ public:
* @param parameters the list of per-acceptor parameter values for the new acceptor
* @param parameters the list of per-acceptor parameter values for the new acceptor
* @return the index of the acceptor that was added
* @return the index of the acceptor that was added
*/
*/
int
addAcceptor
(
int
a1
,
int
a2
,
int
a3
,
const
std
::
vector
<
double
>&
parameters
);
int
addAcceptor
(
int
a1
,
int
a2
,
int
a3
,
const
std
::
vector
<
double
>&
parameters
=
std
::
vector
<
double
>
()
);
/**
/**
* Get the properties of an acceptor group.
* Get the properties of an acceptor group.
*
*
...
@@ -356,7 +356,7 @@ public:
...
@@ -356,7 +356,7 @@ public:
* less than three particles, this must be -1.
* less than three particles, this must be -1.
* @param parameters the list of per-acceptor parameter values for the acceptor
* @param parameters the list of per-acceptor parameter values for the acceptor
*/
*/
void
setAcceptorParameters
(
int
index
,
int
a1
,
int
a2
,
int
a3
,
const
std
::
vector
<
double
>&
parameters
);
void
setAcceptorParameters
(
int
index
,
int
a1
,
int
a2
,
int
a3
,
const
std
::
vector
<
double
>&
parameters
=
std
::
vector
<
double
>
()
);
/**
/**
* Add a donor-acceptor pair to the list of interactions that should be excluded.
* Add a donor-acceptor pair to the list of interactions that should be excluded.
*
*
...
...
openmmapi/include/openmm/CustomManyParticleForce.h
View file @
cecc774a
...
@@ -348,7 +348,7 @@ public:
...
@@ -348,7 +348,7 @@ public:
* @param type the type of the new particle
* @param type the type of the new particle
* @return the index of the particle that was added
* @return the index of the particle that was added
*/
*/
int
addParticle
(
const
std
::
vector
<
double
>&
parameters
,
int
type
=
0
);
int
addParticle
(
const
std
::
vector
<
double
>&
parameters
=
std
::
vector
<
double
>
()
,
int
type
=
0
);
/**
/**
* Get the nonbonded force parameters for a particle.
* Get the nonbonded force parameters for a particle.
*
*
...
...
openmmapi/include/openmm/CustomNonbondedForce.h
View file @
cecc774a
...
@@ -328,7 +328,7 @@ public:
...
@@ -328,7 +328,7 @@ public:
* @param parameters the list of parameters for the new particle
* @param parameters the list of parameters for the new particle
* @return the index of the particle that was added
* @return the index of the particle that was added
*/
*/
int
addParticle
(
const
std
::
vector
<
double
>&
parameters
);
int
addParticle
(
const
std
::
vector
<
double
>&
parameters
=
std
::
vector
<
double
>
()
);
/**
/**
* Get the nonbonded force parameters for a particle.
* Get the nonbonded force parameters for a particle.
*
*
...
...
openmmapi/include/openmm/CustomTorsionForce.h
View file @
cecc774a
...
@@ -172,7 +172,7 @@ public:
...
@@ -172,7 +172,7 @@ public:
* @param parameters the list of parameters for the new torsion
* @param parameters the list of parameters for the new torsion
* @return the index of the torsion that was added
* @return the index of the torsion that was added
*/
*/
int
addTorsion
(
int
particle1
,
int
particle2
,
int
particle3
,
int
particle4
,
const
std
::
vector
<
double
>&
parameters
);
int
addTorsion
(
int
particle1
,
int
particle2
,
int
particle3
,
int
particle4
,
const
std
::
vector
<
double
>&
parameters
=
std
::
vector
<
double
>
()
);
/**
/**
* Get the force field parameters for a torsion term.
* Get the force field parameters for a torsion term.
*
*
...
@@ -194,7 +194,7 @@ public:
...
@@ -194,7 +194,7 @@ public:
* @param particle4 the index of the fourth particle connected by the torsion
* @param particle4 the index of the fourth particle connected by the torsion
* @param parameters the list of parameters for the torsion
* @param parameters the list of parameters for the torsion
*/
*/
void
setTorsionParameters
(
int
index
,
int
particle1
,
int
particle2
,
int
particle3
,
int
particle4
,
const
std
::
vector
<
double
>&
parameters
);
void
setTorsionParameters
(
int
index
,
int
particle1
,
int
particle2
,
int
particle3
,
int
particle4
,
const
std
::
vector
<
double
>&
parameters
=
std
::
vector
<
double
>
()
);
/**
/**
* Update the per-torsion parameters in a Context to match those stored in this Force object. This method provides
* Update the per-torsion parameters in a Context to match those stored in this Force object. This method provides
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
...
...
openmmapi/include/openmm/internal/CustomCentroidBondForceImpl.h
View file @
cecc774a
...
@@ -41,6 +41,7 @@
...
@@ -41,6 +41,7 @@
#include "lepton/ParsedExpression.h"
#include "lepton/ParsedExpression.h"
#include <utility>
#include <utility>
#include <map>
#include <map>
#include <set>
#include <string>
#include <string>
namespace
OpenMM
{
namespace
OpenMM
{
...
@@ -93,7 +94,7 @@ private:
...
@@ -93,7 +94,7 @@ private:
class
FunctionPlaceholder
;
class
FunctionPlaceholder
;
static
Lepton
::
ExpressionTreeNode
replaceFunctions
(
const
Lepton
::
ExpressionTreeNode
&
node
,
std
::
map
<
std
::
string
,
int
>
atoms
,
static
Lepton
::
ExpressionTreeNode
replaceFunctions
(
const
Lepton
::
ExpressionTreeNode
&
node
,
std
::
map
<
std
::
string
,
int
>
atoms
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
distances
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
angles
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
distances
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
angles
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
dihedrals
);
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
dihedrals
,
std
::
set
<
std
::
string
>&
variables
);
void
addBondsBetweenGroups
(
int
group1
,
int
group2
,
std
::
vector
<
std
::
pair
<
int
,
int
>
>&
bonds
)
const
;
void
addBondsBetweenGroups
(
int
group1
,
int
group2
,
std
::
vector
<
std
::
pair
<
int
,
int
>
>&
bonds
)
const
;
const
CustomCentroidBondForce
&
owner
;
const
CustomCentroidBondForce
&
owner
;
Kernel
kernel
;
Kernel
kernel
;
...
...
openmmapi/include/openmm/internal/CustomCompoundBondForceImpl.h
View file @
cecc774a
...
@@ -40,6 +40,7 @@
...
@@ -40,6 +40,7 @@
#include "lepton/ParsedExpression.h"
#include "lepton/ParsedExpression.h"
#include <utility>
#include <utility>
#include <map>
#include <map>
#include <set>
#include <string>
#include <string>
namespace
OpenMM
{
namespace
OpenMM
{
...
@@ -83,7 +84,7 @@ private:
...
@@ -83,7 +84,7 @@ private:
class
FunctionPlaceholder
;
class
FunctionPlaceholder
;
static
Lepton
::
ExpressionTreeNode
replaceFunctions
(
const
Lepton
::
ExpressionTreeNode
&
node
,
std
::
map
<
std
::
string
,
int
>
atoms
,
static
Lepton
::
ExpressionTreeNode
replaceFunctions
(
const
Lepton
::
ExpressionTreeNode
&
node
,
std
::
map
<
std
::
string
,
int
>
atoms
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
distances
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
angles
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
distances
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
angles
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
dihedrals
);
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
dihedrals
,
std
::
set
<
std
::
string
>&
variables
);
const
CustomCompoundBondForce
&
owner
;
const
CustomCompoundBondForce
&
owner
;
Kernel
kernel
;
Kernel
kernel
;
};
};
...
...
openmmapi/include/openmm/internal/CustomHbondForceImpl.h
View file @
cecc774a
...
@@ -9,7 +9,7 @@
...
@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* *
* Portions copyright (c) 2008-201
0
Stanford University and the Authors. *
* Portions copyright (c) 2008-201
5
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Authors: Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -40,6 +40,7 @@
...
@@ -40,6 +40,7 @@
#include "lepton/ParsedExpression.h"
#include "lepton/ParsedExpression.h"
#include <utility>
#include <utility>
#include <map>
#include <map>
#include <set>
#include <string>
#include <string>
namespace
OpenMM
{
namespace
OpenMM
{
...
@@ -84,7 +85,7 @@ private:
...
@@ -84,7 +85,7 @@ private:
class
FunctionPlaceholder
;
class
FunctionPlaceholder
;
static
Lepton
::
ExpressionTreeNode
replaceFunctions
(
const
Lepton
::
ExpressionTreeNode
&
node
,
std
::
map
<
std
::
string
,
int
>
atoms
,
static
Lepton
::
ExpressionTreeNode
replaceFunctions
(
const
Lepton
::
ExpressionTreeNode
&
node
,
std
::
map
<
std
::
string
,
int
>
atoms
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
distances
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
angles
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
distances
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
angles
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
dihedrals
);
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
dihedrals
,
std
::
set
<
std
::
string
>&
variables
);
const
CustomHbondForce
&
owner
;
const
CustomHbondForce
&
owner
;
Kernel
kernel
;
Kernel
kernel
;
};
};
...
...
openmmapi/include/openmm/internal/CustomManyParticleForceImpl.h
View file @
cecc774a
...
@@ -40,6 +40,7 @@
...
@@ -40,6 +40,7 @@
#include "lepton/ParsedExpression.h"
#include "lepton/ParsedExpression.h"
#include <utility>
#include <utility>
#include <map>
#include <map>
#include <set>
#include <string>
#include <string>
namespace
OpenMM
{
namespace
OpenMM
{
...
@@ -98,7 +99,7 @@ private:
...
@@ -98,7 +99,7 @@ private:
class
FunctionPlaceholder
;
class
FunctionPlaceholder
;
static
Lepton
::
ExpressionTreeNode
replaceFunctions
(
const
Lepton
::
ExpressionTreeNode
&
node
,
std
::
map
<
std
::
string
,
int
>
atoms
,
static
Lepton
::
ExpressionTreeNode
replaceFunctions
(
const
Lepton
::
ExpressionTreeNode
&
node
,
std
::
map
<
std
::
string
,
int
>
atoms
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
distances
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
angles
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
distances
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
angles
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
dihedrals
);
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
dihedrals
,
std
::
set
<
std
::
string
>&
variables
);
static
void
generatePermutations
(
std
::
vector
<
int
>&
values
,
int
numFixed
,
std
::
vector
<
std
::
vector
<
int
>
>&
result
);
static
void
generatePermutations
(
std
::
vector
<
int
>&
values
,
int
numFixed
,
std
::
vector
<
std
::
vector
<
int
>
>&
result
);
const
CustomManyParticleForce
&
owner
;
const
CustomManyParticleForce
&
owner
;
Kernel
kernel
;
Kernel
kernel
;
...
...
Prev
1
2
3
4
5
…
11
Next
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