Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • nomad-lab/analytics
1 result
Select Git revision
Show changes
Commits on Source (435)
Showing
with 463 additions and 19180 deletions
...@@ -3,4 +3,4 @@ ...@@ -3,4 +3,4 @@
**/.gitmodules **/.gitmodules
**/.dockerignore **/.dockerignore
.gitlab-ci .gitlab-ci.yml
\ No newline at end of file \ No newline at end of file
.vscode/
.idea/
.ipython/
.keras/
.local/
.DS_Store
# https://github.com/github/gitignore/blob/main/Python.gitignore
# Byte-compiled / optimized / DLL files # Byte-compiled / optimized / DLL files
__pycache__/ __pycache__/
...@@ -29,6 +23,7 @@ parts/ ...@@ -29,6 +23,7 @@ parts/
sdist/ sdist/
var/ var/
wheels/ wheels/
share/python-wheels/
*.egg-info/ *.egg-info/
.installed.cfg .installed.cfg
*.egg *.egg
...@@ -47,14 +42,17 @@ pip-delete-this-directory.txt ...@@ -47,14 +42,17 @@ pip-delete-this-directory.txt
# Unit test / coverage reports # Unit test / coverage reports
htmlcov/ htmlcov/
.tox/ .tox/
.nox/
.coverage .coverage
.coverage.* .coverage.*
.cache .cache
nosetests.xml nosetests.xml
coverage.xml coverage.xml
*.cover *.cover
*.py,cover
.hypothesis/ .hypothesis/
.pytest_cache/ .pytest_cache/
cover/
# Translations # Translations
*.mo *.mo
...@@ -64,6 +62,7 @@ coverage.xml ...@@ -64,6 +62,7 @@ coverage.xml
*.log *.log
local_settings.py local_settings.py
db.sqlite3 db.sqlite3
db.sqlite3-journal
# Flask stuff: # Flask stuff:
instance/ instance/
...@@ -76,16 +75,49 @@ instance/ ...@@ -76,16 +75,49 @@ instance/
docs/_build/ docs/_build/
# PyBuilder # PyBuilder
.pybuilder/
target/ target/
# Jupyter Notebook # Jupyter Notebook
.ipynb_checkpoints .ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv # pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
.python-version .python-version
# celery beat schedule file # pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule celerybeat-schedule
celerybeat.pid
# SageMath parsed files # SageMath parsed files
*.sage.py *.sage.py
...@@ -111,3 +143,252 @@ venv.bak/ ...@@ -111,3 +143,252 @@ venv.bak/
# mypy # mypy
.mypy_cache/ .mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/
# https://github.com/github/gitignore/blob/main/Node.gitignore
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
.cache
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
# https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore/
.vscode/*
!.vscode/settings.json
# !.vscode/tasks.json
# !.vscode/launch.json
# !.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
# https://github.com/github/gitignore/blob/main/Global/macOS.gitignore
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# https://github.com/github/gitignore/blob/main/Global/Windows.gitignore
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# https://github.com/github/gitignore/blob/main/Global/Linux.gitignore
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
# Analitics
deployments
.keras/
# default installed image for docker executor is: python:3.6 image: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-fair/ci-runner
# using an image that can do git, docker, docker-compose
# https://docs.gitlab.com/ee/ci/docker/using_docker_build.html
image: docker:dind
variables: # variables:
GIT_SUBMODULE_STRATEGY: recursive # IMAGE_NAME: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}
stages: stages:
- build - build
- deploy - deploy
- release
build to develop:
build to staging:
stage: build stage: build
variables:
GIT_SUBMODULE_STRATEGY: recursive
GIT_SUBMODULE_UPDATE_FLAGS: --jobs 4
before_script: before_script:
- echo "Building the single user notebook image" - echo "Building the single user notebook image"
- echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER $CI_REGISTRY --password-stdin - echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER $CI_REGISTRY --password-stdin
- docker info - docker info
script: script:
# Using cache to speed up the build process --cache-from ${CI_REGISTRY_IMAGE}:${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} - docker build -t ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG} .
- docker pull ${CI_REGISTRY_IMAGE}:${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} || true - docker push ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}
- docker build --tag ${CI_REGISTRY_IMAGE}:${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}${CI_COMMIT_SHORT_SHA} --tag ${CI_REGISTRY_IMAGE}:${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} .
- docker push ${CI_REGISTRY_IMAGE}:${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}${CI_COMMIT_SHORT_SHA}
- docker push ${CI_REGISTRY_IMAGE}:${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}
rules: rules:
# Execute jobs when a new commit is pushed to master branch # Execute jobs when a new commit is pushed to master branch
- if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop"
build to production: # build to staging:
stage: build # stage: build
before_script: # variables:
- echo "Building the single user notebook image" # GIT_SUBMODULE_STRATEGY: recursive
- echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER $CI_REGISTRY --password-stdin # GIT_SUBMODULE_UPDATE_FLAGS: --jobs 4
- docker info # before_script:
script: # - echo "Building the single user notebook image"
# Using cache to speed up the build process # - echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER $CI_REGISTRY --password-stdin
- docker pull ${CI_REGISTRY_IMAGE}:latest || true # script:
- docker build --cache-from ${CI_REGISTRY_IMAGE}:latest --tag ${CI_REGISTRY_IMAGE}:production${CI_COMMIT_SHORT_SHA} --tag ${CI_REGISTRY_IMAGE}:latest . # - docker build -t ${STAGING_IMAGE} .
- docker push ${CI_REGISTRY_IMAGE}:production${CI_COMMIT_SHORT_SHA} # - docker push ${STAGING_IMAGE}
- docker push ${CI_REGISTRY_IMAGE}:latest # rules:
rules: # # Execute jobs when a new commit is pushed to develop branch
# Execute jobs when a new commit is pushed to master branch # - if: $CI_COMMIT_BRANCH == "develop"
- if: $CI_COMMIT_BRANCH == 'master'
# build to production:
# stage: build
# variables:
# GIT_SUBMODULE_STRATEGY: recursive
# GIT_SUBMODULE_UPDATE_FLAGS: --jobs 4
# before_script:
# - echo "Building the single user notebook image"
# - echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER $CI_REGISTRY --password-stdin
# script:
# - docker build -t ${STAGING_IMAGE} .
# - docker push ${STAGING_IMAGE}
# rules:
# # Execute jobs when a new commit is pushed to master branch
# - if: $CI_COMMIT_BRANCH == 'master'
deploy to staging: deploy to develop:
image: python:3.6
stage: deploy stage: deploy
environment:
name: dev/$CI_COMMIT_REF_NAME
deployment_tier: development
url: https://analytics-toolkit.nomad-coe.eu/dev/${CI_ENVIRONMENT_SLUG}
auto_stop_in: 7 days
on_stop: stop deploy dev
variables: variables:
GIT_SUBMODULE_STRATEGY: none NAMESPACE: analytics-develop
before_script:
- mkdir ~/.kube/
- echo ${CI_KUBE_CONFIG} | base64 -d > ~/.kube/config
- helm repo add jupyterhub https://jupyterhub.github.io/helm-chart
- helm repo update
- helm version
script: script:
- ./.gitlab-ci/update_tag_staging.sh - helm upgrade ${CI_ENVIRONMENT_SLUG} jupyterhub/jupyterhub
environment: --install
name: staging --namespace ${NAMESPACE}
url: https://nomad-lab.eu/dev/analytics/staging --version=1.2.0
--timeout=40m0s
--cleanup-on-fail
--values deployments/dev-values.yaml
--set hub.baseUrl=/dev/${CI_ENVIRONMENT_SLUG}
--set fullnameOverride=${CI_ENVIRONMENT_SLUG}
--set singleuser.podNameTemplate="${CI_ENVIRONMENT_SLUG}-{username}"
--set hub.config.GenericOAuthenticator.oauth_callback_url=https://analytics-toolkit.nomad-coe.eu/dev/${CI_ENVIRONMENT_SLUG}/hub/oauth_callback
--set singleuser.image.name=${CI_REGISTRY_IMAGE}
--set singleuser.image.tag=${CI_COMMIT_REF_SLUG}
--set roll=true
--wait
rules: rules:
# Execute jobs when a new commit is pushed to master branch # Execute jobs when a new commit is pushed to master branch
- if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop"
stop deploy dev:
deploy to production:
image: python:3.6
stage: deploy stage: deploy
script:
- ./.gitlab-ci/update_tag_production.sh
environment: environment:
name: production name: dev/$CI_COMMIT_REF_NAME
url: https://nomad-lab.eu/prod/analytics/hub action: stop
rules: before_script:
# Execute jobs when a new commit is pushed to master branch - mkdir ~/.kube/
- if: $CI_COMMIT_BRANCH == 'master' - echo ${CI_K8S_CONFIG} | base64 -d > ~/.kube/config
script:
- helm uninstall ${CI_ENVIRONMENT_SLUG} --namespace analytics
when: manual
needs: ["build to develop"]
# deploy to staging:
# stage: deploy
# environment:
# name: staging
# url: https://nomad-lab.eu/dev/analytics/staging
# script:
# - ./.gitlab-ci/update_tag_staging.sh
# rules:
# # Execute jobs when a new commit is pushed to master branch
# - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop"
# deploy to production:
# stage: deploy
# environment:
# name: production
# url: https://nomad-lab.eu/prod/analytics/hub
# script:
# - ./.gitlab-ci/update_tag_production.sh
# rules:
# # Execute jobs when a new commit is pushed to master branch
# - if: $CI_COMMIT_BRANCH == 'develop'
# !/bin/bash
# Based on: https://docs.gitlab.com/ee/ci/ssh_keys/README.html
# Install ssh-agent if not already installed, it is required by Docker.
# (change apt-get to yum if you use an RPM-based image)
# - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
# Run ssh-agent (inside the build environment)
eval $(ssh-agent -s)
# Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
# We're using tr to fix line endings which makes ed25519 keys work
# without extra base64 encoding.
# https://gitlab.com/gitlab-examples/ssh-private-key/issues/1#note_48526556
echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
# Create the SSH directory and give it the right permissions
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# Use ssh-keyscan to scan the keys of your private server.
ssh-keyscan gitlab.mpcdf.mpg.de >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
# Set the user name and email.
git config --global user.name $GITLAB_USER_NAME
git config --global user.email $GITLAB_USER_EMAIL
# Clone the private repository
git clone git@gitlab.mpcdf.mpg.de:nomad-lab/analytics-deployment.git /tmp/analytics-deployment
cd /tmp/analytics-deployment
# Update the tag of the docker image
sed -i "s/^ tag\:.*/ tag\: production$CI_COMMIT_SHORT_SHA/g" deployments/hub/config.yaml
sed -i "s/^ tag\:.*/ tag\: production$CI_COMMIT_SHORT_SHA/g" deployments/hub/public.yaml
# Finally, commit and push the changes
git add deployments/hub/config.yaml
git add deployments/hub/public.yaml
git commit -m "CI: Update the hub image for production ($CI_PIPELINE_URL)"
git push
rm -rf /tmp/analytics-deployment
# !/bin/bash
# Based on: https://docs.gitlab.com/ee/ci/ssh_keys/README.html
# Install ssh-agent if not already installed, it is required by Docker.
# (change apt-get to yum if you use an RPM-based image)
# - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
# Run ssh-agent (inside the build environment)
eval $(ssh-agent -s)
# Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
# We're using tr to fix line endings which makes ed25519 keys work
# without extra base64 encoding.
# https://gitlab.com/gitlab-examples/ssh-private-key/issues/1#note_48526556
echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
# Create the SSH directory and give it the right permissions
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# Use ssh-keyscan to scan the keys of your private server.
ssh-keyscan gitlab.mpcdf.mpg.de >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
# Set the user name and email.
git config --global user.name $GITLAB_USER_NAME
git config --global user.email $GITLAB_USER_EMAIL
# Clone the private repository
git clone git@gitlab.mpcdf.mpg.de:nomad-lab/analytics-deployment.git /tmp/analytics-deployment
cd /tmp/analytics-deployment
# Update the tag of the docker image
sed -i "s/^ tag\:.*/ tag\: $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME$CI_COMMIT_SHORT_SHA/g" deployments/hub/staging.yaml
# Finally, commit and push the changes
git add deployments/hub/staging.yaml
git commit -m "CI: Update the hub image for staging ($CI_PIPELINE_URL)"
git push
rm -rf /tmp/analytics-deployment
[submodule "3rdparty/atomic-features-package"]
path = 3rdparty/atomic-features-package
url = https://gitlab.mpcdf.mpg.de/nomad-lab/atomic-features-package.git
[submodule "3rdparty/cmlkit"]
path = 3rdparty/cmlkit
url = https://gitlab.mpcdf.mpg.de/nomad-lab/cmlkit.git
[submodule "3rdparty/keras-vis"]
path = 3rdparty/keras-vis
url = https://github.com/raghakot/keras-vis.git
[submodule "3rdparty/qmmlpack"]
path = 3rdparty/qmmlpack
url = https://gitlab.com/qmml/qmmlpack.git
[submodule "3rdparty/quip"] [submodule "3rdparty/quip"]
path = 3rdparty/quip path = 3rdparty/quip
url = https://github.com/libAtoms/QUIP.git url = git@github.com:libAtoms/QUIP.git
[submodule "3rdparty/sissopp"]
path = 3rdparty/sissopp
url = https://gitlab.com/sissopp_developers/sissopp.git
[submodule "tutorials/analytics-compressed-sensing"] [submodule "tutorials/analytics-compressed-sensing"]
path = tutorials/analytics-compressed-sensing path = tutorials/analytics-compressed-sensing
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-compressed-sensing.git url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-compressed-sensing.git
...@@ -22,57 +37,78 @@ ...@@ -22,57 +37,78 @@
[submodule "tutorials/analytics-tcmi"] [submodule "tutorials/analytics-tcmi"]
path = tutorials/analytics-tcmi path = tutorials/analytics-tcmi
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-tcmi.git url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-tcmi.git
[submodule "tutorials/analytics-descriptor-role"]
path = tutorials/analytics-descriptor-role
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-descriptor-role.git
[submodule "tutorials/analytics-error-estimates"]
path = tutorials/analytics-error-estimates
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-error-estimates.git
[submodule "3rdparty/cpp_sisso"]
path = 3rdparty/cpp_sisso
url = https://gitlab.mpcdf.mpg.de/nomad-lab/cpp_sisso.git
[submodule "tutorials/analytics-query-nomad-archive"]
path = tutorials/analytics-query-nomad-archive
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-query-nomad-archive.git
[submodule "tutorials/analytics-cmlkit"] [submodule "tutorials/analytics-cmlkit"]
path = tutorials/analytics-cmlkit path = tutorials/analytics-cmlkit
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-cmlkit.git url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-cmlkit.git
[submodule "3rdparty/qmmlpack"] [submodule "tutorials/analytics-descriptor-role"]
path = 3rdparty/qmmlpack path = tutorials/analytics-descriptor-role
url = https://gitlab.com/qmml/qmmlpack.git url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-descriptor-role.git
[submodule "tutorials/analytics-decision-tree"] [submodule "tutorials/analytics-decision-tree"]
path = tutorials/analytics-decision-tree path = tutorials/analytics-decision-tree
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-decision-tree.git url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-decision-tree.git
[submodule "tutorials/analytics-clustering-tutorial"] [submodule "tutorials/analytics-nn-regression"]
path = tutorials/analytics-clustering-tutorial path = tutorials/analytics-nn-regression
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-clustering-tutorial.git url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-nn-regression.git
[submodule "tutorials/analytics-exploratory-analysis"] [submodule "tutorials/analytics-exploratory-analysis"]
path = tutorials/analytics-exploratory-analysis path = tutorials/analytics-exploratory-analysis
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-exploratory-analysis.git url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-exploratory-analysis.git
[submodule "tutorials/analytics-perovskites-tolerance-factor"]
path = tutorials/analytics-perovskites-tolerance-factor
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-perovskites-tolerance-factor.git
[submodule "tutorials/analytics-krr4mat"]
path = tutorials/analytics-krr4mat
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-krr4mat.git
[submodule "tutorials/analytics-error-estimates"]
path = tutorials/analytics-error-estimates
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-error-estimates.git
[submodule "tutorials/analytics-query-nomad-archive"]
path = tutorials/analytics-query-nomad-archive
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-query-nomad-archive
[submodule "tutorials/analytics-domain-of-applicability"] [submodule "tutorials/analytics-domain-of-applicability"]
path = tutorials/analytics-domain-of-applicability path = tutorials/analytics-domain-of-applicability
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-domain-of-applicability.git url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-domain-of-applicability.git
[submodule "tutorials/analytics-nn-regression"]
path = tutorials/analytics-nn-regression
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-nn-regression.git
[submodule "tutorials/analytics-tetradymite-PRM2020"] [submodule "tutorials/analytics-tetradymite-PRM2020"]
path = tutorials/analytics-tetradymite-PRM2020 path = tutorials/analytics-tetradymite-PRM2020
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-tetradymite-PRM2020.ipynb.git url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-tetradymite-PRM2020.ipynb.git
[submodule "tutorials/analytics-clustering-tutorial"]
path = tutorials/analytics-clustering-tutorial
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-clustering-tutorial.git
[submodule "tutorials/analytics-arise"] [submodule "tutorials/analytics-arise"]
path = tutorials/analytics-arise path = tutorials/analytics-arise
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-arise.git url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-arise.git
[submodule "tutorials/analytics-krr4mat"] [submodule "tutorials/analytics-catalysis-MRS2021"]
path = tutorials/analytics-krr4mat path = tutorials/analytics-catalysis-MRS2021
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-krr4mat.git url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-catalysis-MRS2021.git
[submodule "3rdparty/keras-vis"] [submodule "tutorials/analytics-atomic-features"]
path = 3rdparty/keras-vis path = tutorials/analytics-atomic-features
url = https://github.com/raghakot/keras-vis.git url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-atomic-features.git
[submodule "3rdparty/atomic-features-package"]
path = 3rdparty/atomic-features-package
url = https://gitlab.mpcdf.mpg.de/nomad-lab/atomic-features-package.git
[submodule "tutorials/analytics-co2-sgd-tutorial"]
path = tutorials/analytics-co2-sgd-tutorial
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-co2-sgd-tutorial.git
[submodule "tutorials/analytics-sgd-alloys-oxygen-reduction-evolution"] [submodule "tutorials/analytics-sgd-alloys-oxygen-reduction-evolution"]
path = tutorials/analytics-sgd-alloys-oxygen-reduction-evolution path = tutorials/analytics-sgd-alloys-oxygen-reduction-evolution
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-sgd-alloys-oxygen-reduction-evolution.git url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-sgd-alloys-oxygen-reduction-evolution.git
[submodule "tutorials/analytics-co2-sgd-tutorial"]
path = tutorials/analytics-co2-sgd-tutorial
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-co2-sgd-tutorial.git
[submodule "tutorials/analytics-metalInsulator-PRM2018"]
path = tutorials/analytics-metalInsulator-PRM2018
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-metalinsulator-prm2018.git
[submodule "tutorials/analytics-proto-archetype-clustering-sisso"]
path = tutorials/analytics-proto-archetype-clustering-sisso
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-proto-archetype-clustering-sisso.git
[submodule "tutorials/analytics-svm-classification"]
path = tutorials/analytics-svm-classification
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-svm-classification.git
[submodule "tutorials/analytics-sgd-propylene-oxidation-hte"]
path = tutorials/analytics-sgd-propylene-oxidation-hte
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-sgd-propylene-oxidation-hte.git
[submodule "tutorials/analytics-dos-similarity-search"]
path = tutorials/analytics-dos-similarity-search
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-dos-similarity-search.git
[submodule "tutorials/analytics-dimensionality-reduction"]
path = tutorials/analytics-dimensionality-reduction
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-dimensionality-reduction.git
[submodule "tutorials/analytics-kappa-screening-sisso"]
path = tutorials/analytics-kappa-screening-sisso
url = https://gitlab.mpcdf.mpg.de/nomad-lab/analytics-kappa-screening-sisso.git
[submodule "3rdparty/nomad-FAIR"]
path = 3rdparty/nomad-FAIR
url = git@gitlab.mpcdf.mpg.de:nomad-lab/nomad-FAIR.git
Subproject commit a0c34e8bf4f6cc05bcfa6f5524adbc1806a44b9c Subproject commit 7dda7a911e99b87c4470f01d619664e39f56dd9c
Subproject commit 3ce44fd3933c17d567fbf783fa784b2b6c98ba7c
Subproject commit 0a99e15f54a53f829d1fc7f2cb2d0372319eebbd
*~
### GAP suite — Non-commercial License Agreement
*Last updated: 19th April 2017*
The GAP suite of programs, comprising the GAP-filler and GAP packages
(together “the Software”), written by Dr Gabor Csanyi and Dr Albert
Bartok-Partay of the University of Cambridge (the “Authors”) for
describing the chemical environments of atoms and molecules and
predicting potential energy surfaces, is copyrighted by the University
of Cambridge and the Authors. Users at non-commercial institutions may
obtain a copy for Non-commercial Purposes. "Non-commercial Purposes"
means use of the Software and/or any **Software-derived data (including
interatomic potentials)** for academic research or other not-for-profit
or scholarly purposes which are undertaken at an educational,
non-profit, charitable or governmental institution that does not
involve the production or manufacture of products for sale or the
performance of services for a fee or other non-monetary value.
For commercial use of either or both the Software or any
Software-derived data, please contact Cambridge Enterprise Limited at
<enquiries@enterprise.cam.ac.uk>.
1. This is a legal agreement between you (“USER”), and the Authors. By
accepting, receiving, and using this Software, you are agreeing to
be bound by the terms of this Agreement.
2. The Authors hereby grant to the USER a non-exclusive,
non-transferable personal licence to use the Software.
3. The licence granted under this Agreement shall only entitle the USER
to use the Software for Non-commercial Purposes. The use of the
Software, or any code which is a modification of, enhancement to,
derived from or based upon the Software, or Software-derived data,
either directly or indirectly for any commercial purpose whatsoever
is expressly forbidden. The USER may not sublicense, distribute or
copy (except for archival purposes) the Software or enhancements
thereto.
4. If any academic paper or publication by the USER includes any set of
interatomic potentials or other Software-derived data then the USER
must timeously publish their full GAP model and source data (i.e.
the underlying quantum mechanical data which were used as input to
the GAP-filler). Any publication of any GAP models, interatomic
potentials or other Software-derived data must specifically state
that such data is provided for non-commercial use only.
5. If any academic paper or publication by the USER is based wholly or
partially, directly or indirectly on the Software or any results
derived from the Software then that paper or publication must cite:
- A. P. Bartok et al. *Physical Review Letters* **104**
136403 (2010)
- A. P. Bartok et al. *Physical Review B* **87** 184115 (2013)
- That this Software is available for non-commercial use from
`www.libatoms.org`
6. The Software is the subject of copyright. Unauthorised copying of
the Software is expressly forbidden. The University of Cambridge and
the Authors retain all the rights in and title to the Software.
7. The Software is provided "AS IS" and except as expressly provided in
this Agreement no warranty, condition, undertaking or term, express
or implied, statutory or otherwise, as to the condition,
performance, satisfactory quality or fitness for purpose of the
Software is given or assumed by the Authors or the University of
Cambridge, and all such warranties, conditions, undertakings and
terms are hereby excluded.
8. The limitations and exclusions in this Agreement shall not apply in
respect of claims for personal injury or death caused by negligence
or in respect of fraud or fraudulent misrepresentation.
9. EXCEPT AS PROVIDED BY CLAUSE 8, neither the AUTHORS nor the
University OF CAMBRIDGE or its employees or students shall be liable
for any damages or expenses of whatsoever nature and howsoever
arising (including without limitation in contract, tort, negligence
or for breach of statutory duty or misrepresentation) in connection
with any right or licence granted or use of the Software or
otherwise in connection with this Licence or any relationships
established by it. Without prejudice to the generality of the
foregoing, in the event that the AUTHORS, the University OF
CAMBRIDGE, its employees or students should be found liable, then
their aggregate liability for direct damages shall be limited to
£100; and none of them shall be liable for any indirect, incidental,
consequential or special damages including without limitation loss
of profits, revenue, or business opportunity, loss of goodwill, data
loss, business disruption or computer failure.
10. The USER shall indemnify the Authors, the University of Cambridge,
its employees and students in full against each and every claim made
against any of them by any third party (including without limitation
in contract, tort, negligence or for breach of statutory duty or
misrepresentation) arising out of or in connection with the USER's
use of the Software.
11. The Authors accept no obligation to provide maintenance nor do they
guarantee the expected functionality of the Software or of any part
of the Software.
12. This Agreement is effective until terminated. This Agreement will
terminate automatically on notice from the Authors if the USER fails
to comply with any provision of this Agreement. Upon termination the
USER shall immediately destroy all copies of the Software.
13. This Agreement and any matters relating to it shall be governed and
construed in accordance with the laws of England and Wales and
Authors and the USER hereby irrevocably submit to the exclusive
jurisdiction of the English Courts.
# HND XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# HND X
# HND X libAtoms+QUIP: atomistic simulation library
# HND X
# HND X Portions of this code were written by
# HND X Albert Bartok-Partay, Silvia Cereda, Gabor Csanyi, James Kermode,
# HND X Ivan Solt, Wojciech Szlachta, Csilla Varnai, Steven Winfield.
# HND X
# HND X Copyright 2006-2010.
# HND X
# HND X Not for distribution
# HND X
# HND X Portions of this code were written by Noam Bernstein as part of
# HND X his employment for the U.S. Government, and are not subject
# HND X to copyright in the USA.
# HND X
# HND X When using this software, please cite the following reference:
# HND X
# HND X http://www.libatoms.org
# HND X
# HND X Additional contributions by
# HND X Alessio Comisso, Chiara Gattinoni, and Gianpietro Moras
# HND X
# HND XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ifeq (${QUIP_ARCH},)
include Makefile.arch
else
include Makefile.${QUIP_ARCH}
endif
include Makefile.inc
include Makefile.rules
GAP1_F95_FILES = make_permutations_v2 descriptors gp_predict descriptors_wrapper clustering
GAP1_F95_SOURCES = ${addsuffix .f95, ${GAP1_F95_FILES}}
GAP1_F95_OBJS = ${addsuffix .o, ${GAP1_F95_FILES}}
GAP2_F95_FILES = gp_fit gap_fit_module
GAP2_F95_SOURCES = ${addsuffix .f95, ${GAP2_F95_FILES}}
GAP2_F95_OBJS = ${addsuffix .o, ${GAP2_F95_FILES}}
default: ${GAP_LIBFILE}
ifeq (${USE_MAKEDEP},1)
GAP1_F95_FPP_FILES = ${addsuffix .fpp, ${GAP1_F95_FILES}}
GAP2_F95_FPP_FILES = ${addsuffix .fpp, ${GAP2_F95_FILES}}
GAP1.depend: ${GAP1_F95_FPP_FILES}
${SCRIPT_PATH}/${MAKEDEP} ${MAKEDEP_ARGS} -- ${addprefix ../../src/GAP/,${GAP1_F95_SOURCES}} > GAP1.depend
GAP2.depend: ${GAP2_F95_FPP_FILES} ${GAP1_F95_FPP_FILES}
${SCRIPT_PATH}/${MAKEDEP} ${MAKEDEP_ARGS} -- ${addprefix ../../src/GAP/,${GAP2_F95_SOURCES}} > GAP2.depend
-include GAP1.depend
-include GAP2.depend
endif
PROGRAMS = gap_fit
LIBS = -L. -lquiputils -lquip_core -lgap -latoms
ifeq (${HAVE_THIRDPARTY},1)
LIBS += -lthirdparty
endif
LIBFILES = libatoms.a ${GAP_LIBFILE} libquip_core.a libquiputils.a
.PHONY : clean allclean depend doc install
Programs: ${PROGRAMS}
cp ${QUIP_ROOT}/src/GAP/teach_sparse .
${PROGRAMS}: % : ${LIBFILES} ${GAP2_F95_OBJS} ${GAPFIT_LIBFILE} %.o
$(LINKER) $(LINKFLAGS) -o $@ ${F90OPTS} $@.o ${GAPFIT_LIBFILE} ${LIBS} ${LINKOPTS}
${GAP_LIBFILE}: ${GAP1_F95_OBJS}
ifneq (${LIBTOOL},)
${LIBTOOL} -o ${GAP_LIBFILE} ${GAP1_F95_OBJS}
else
${AR} ${AR_ADD} ${GAP_LIBFILE} $?
endif
${GAPFIT_LIBFILE}: ${GAP2_F95_OBJS}
ifneq (${LIBTOOL},)
${LIBTOOL} -o ${GAPFIT_LIBFILE} ${GAP2_F95_OBJS}
else
${AR} ${AR_ADD} ${GAPFIT_LIBFILE} $?
endif
install:
@if [ ! -d ${QUIP_INSTALLDIR} ]; then \
echo "make install: QUIP_INSTALLDIR '${QUIP_INSTALLDIR}' doesn't exist or isn't a directory"; \
exit 1; \
else \
for f in ${PROGRAMS} ; do \
echo "Copying $$f to ${QUIP_INSTALLDIR}/$${f}${QUIP_MPI_SUFFIX}" ; \
cp $$f ${QUIP_INSTALLDIR}/$${f}${QUIP_MPI_SUFFIX} ; \
done ;\
cp ${QUIP_ROOT}/src/GAP/teach_sparse ${QUIP_INSTALLDIR}; \
fi
clean:
rm -f *.o *.mod *.mod.save ${GAP_LIBFILE} ${GAPFIT_LIBFILE} ${PROGRAMS} GAP1.depend GAP2.depend
! HND XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
! HND X
! HND X libAtoms+QUIP: atomistic simulation library
! HND X
! HND X Portions of this code were written by
! HND X Albert Bartok-Partay, Silvia Cereda, Gabor Csanyi, James Kermode,
! HND X Ivan Solt, Wojciech Szlachta, Csilla Varnai, Steven Winfield.
! HND X
! HND X Copyright 2006-2010.
! HND X
! HND X Not for distribution
! HND X
! HND X Portions of this code were written by Noam Bernstein as part of
! HND X his employment for the U.S. Government, and are not subject
! HND X to copyright in the USA.
! HND X
! HND X When using this software, please cite the following reference:
! HND X
! HND X http://www.libatoms.org
! HND X
! HND X Additional contributions by
! HND X Alessio Comisso, Chiara Gattinoni, and Gianpietro Moras
! HND X
! HND XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include "error.inc"
module clustering_module
! use libatoms_module
use error_module
use system_module ! , only : dp, optional_default, ran_uniform, reallocate
use linearalgebra_module
implicit none
private
public :: pivot, bisect_kmedoids, cluster_kmeans, select_uniform, cluster_fuzzy_cmeans, cur_decomposition
integer, parameter :: n_trial = 10
integer, parameter :: n_trial_k_med = 100
real(dp), parameter :: cluster_jitter = 1.0e-7_dp
real(dp), parameter :: KMEANS_THRESHOLD = 1.0e-6_dp
type lst
integer, dimension(:), allocatable :: object
integer :: medoid
real(dp) :: sse
integer :: N
endtype lst
type clstr
type(lst), dimension(:), allocatable :: cluster
real(dp), dimension(:,:), pointer :: dm
integer :: N
endtype clstr
contains
subroutine distance_matrix(x,dm,theta_fac,theta)
real(dp), dimension(:,:), intent(in) :: x
real(dp), dimension(:,:), intent(out) :: dm
real(dp), intent(in), optional :: theta_fac
real(dp), dimension(:), intent(in), target, optional :: theta
real(dp), dimension(:), pointer :: my_theta => null()
real(dp) :: my_theta_fac
integer :: i, j, d, n
my_theta_fac = optional_default(1.0_dp, theta_fac)
d = size(x,1)
n = size(x,2)
if( present(theta) ) then
if( size(theta) == d) then
my_theta => theta
else
allocate(my_theta(d))
my_theta = theta(1)
endif
else
allocate(my_theta(d))
do i = 1, d
my_theta(i) = ( maxval(x(i,:)) - minval(x(i,:)) )
! theta(i) = sqrt( & !take square root
! & sum( x(i,:)**2 ) / size(x(i,:)) - &
! & (sum( x(i,:) ) / size(x(i,:)))**2 )
if( my_theta(i) .feq. 0.0_dp ) my_theta(i) = 1.0_dp
enddo
my_theta = my_theta * my_theta_fac
endif
do i = 1, n
do j = i + 1, n
dm(j,i) = cluster_jitter*ran_uniform()
enddo
dm(i,i) = 0.0_dp
enddo
!$omp parallel do default(none) shared(dm,n,x,my_theta) private(i,j) schedule(dynamic)
do i = 1, n
do j = i + 1, n
dm(j,i) = dm(j,i) + sqrt( sum( ( (x(:,j) - x(:,i)) / my_theta )**2 ) )
dm(i,j) = dm(j,i)
enddo
enddo
!$omp end parallel do
do i = 1, n
do j = i + 1, n
dm(i,j) = dm(j,i)
enddo
enddo
if( present(theta) ) then
my_theta => null()
else
deallocate(my_theta)
endif
endsubroutine distance_matrix
subroutine pca(x,x_mean,v)
real(dp), dimension(:,:), intent(in) :: x
real(dp), dimension(:), intent(out) :: x_mean
real(dp), dimension(:,:), intent(out) :: v
real(dp), dimension(:), allocatable :: diag_c
real(dp), dimension(:,:), allocatable :: cov
integer :: i, j, d, n
d = size(x,1)
n = size(x,2)
allocate(cov(d,d),diag_c(d))
x_mean = sum(x,dim=2) / n ! empirical mean
do i = 1, d
do j = 1, d
cov(j,i) = dot_product(x(i,:),x(j,:)) / n - x_mean(i)*x_mean(j)
enddo
enddo
call diagonalise(cov,diag_c, evects=v)
deallocate(cov, diag_c)
endsubroutine pca
subroutine pivot(x,pivout,theta_fac,theta)
real(dp), dimension(:,:), intent(in) :: x
integer, dimension(:), intent(out) :: pivout
real(dp), intent(in), optional :: theta_fac
real(dp), dimension(:), intent(in), optional :: theta
real(dp), dimension(:,:), allocatable :: knn
real(dp), dimension(:), allocatable :: ktmp
integer, dimension(:), allocatable :: pivin
integer :: stat, i, j, k, d, m, n, jtmp, jmax
real(dp) :: dmax
d = size(x,1)
n = size(x,2)
m = size(pivout)
if( m > n ) call system_abort('pivot: required number of changes ('//m//') greater than possible number of changes ('//n//')')
allocate(knn(n,n),stat=stat)
if(stat /=0 ) call system_abort('pivot: could not allocate knn matrix.')
allocate(pivin(n),ktmp(n))
call distance_matrix(x,knn,theta_fac=theta_fac,theta=theta)
do i = 1, n
do j = 1, n
knn(j,i) = exp(-0.5_dp*knn(j,i))
enddo
enddo
pivin = (/ (i, i=1,n) /)
do k = 1, m
dmax = 0.0_dp
do j = k, n
if( dmax < knn(j,j) ) then
jmax = j
dmax = knn(j,j)
endif
enddo
if( jmax /= k ) then
jtmp = pivin(jmax)
pivin(jmax) = pivin(k)
pivin(k) = jtmp
ktmp = knn(k,:)
knn(k,:) = knn(jmax,:)
knn(jmax,:) = ktmp
ktmp = knn(:,k)
knn(:,k) = knn(:,jmax)
knn(:,jmax) = ktmp
endif
knn(k,k) = sqrt(knn(k,k))
knn(k+1:n,k) = knn(k+1:n,k)/knn(k,k)
do j = k+1, n
knn(j:n,j) = knn(j:n,j) - knn(j:n,k)*knn(j,k)
enddo
do j = 1, n
do i = j+1,n
knn(j,i) = knn(i,j)
enddo
enddo
enddo
pivout = pivin(1:m)
deallocate(knn,pivin,ktmp)
endsubroutine pivot
subroutine bisect_kmedoids(dat,n_clusters_in, c,med, theta_fac,theta, is_distance_matrix)
real(dp), dimension(:,:), intent(in), target :: dat
integer, intent(in) :: n_clusters_in
integer, dimension(:), intent(out),optional :: c, med
real(dp), intent(in), optional :: theta_fac
real(dp), dimension(:), intent(in), optional :: theta
logical, intent(in), optional :: is_distance_matrix
type(clstr) :: my_cluster, tmp
logical :: must_calculate_distance
real(dp), dimension(:,:), allocatable, target :: dm
real(dp), dimension(:), allocatable :: dv
real(dp) :: max_sse, min_sse, sse
integer, dimension(:), allocatable :: sub_cluster1, sub_cluster2, sub_cluster1_min, sub_cluster2_min
integer, dimension(1) :: ml
integer :: stat, i, j, k, km, m, n, nc, &
lo_med, hi_med, lo_med_new, hi_med_new, lo_med_min, hi_med_min, n1, n2, n1_min, n2_min, iter
must_calculate_distance = .not. optional_default(.true., is_distance_matrix)
n = size(dat,2)
if (.not. must_calculate_distance) then
if (size(dat,1) /= n) call system_abort('is_distance_matrix but not square')
endif
if( n_clusters_in > n ) call system_abort('bisect_kmedoids: required number of cluster greater than total number of data points')
if(present(c) ) c = 0
if (must_calculate_distance) then
allocate(dm(n,n), stat=stat)
if(stat /=0 ) call system_abort('bisect_kmedoids: could not allocate dm matrix.')
call print('Started distance matrix calculation', verbosity=PRINT_NERD)
call distance_matrix(dat, dm, theta_fac=theta_fac,theta=theta)
call print('Finished distance matrix calculation', verbosity=PRINT_NERD)
my_cluster%dm => dm
else
my_cluster%dm => dat
endif
! start clustering
my_cluster%N = 1 ! start with one big cluster
allocate( my_cluster%cluster(1) )
my_cluster%cluster(1)%N = n ! put every object in the initial cluster
allocate( my_cluster%cluster(1)%object(n) )
my_cluster%cluster(1)%object = (/(i,i=1,n)/)
allocate(dv(n)) ! distance vector, the sum of square of distances of points from central object
dv = sum(my_cluster%dm,dim=1)
my_cluster%cluster(1)%sse = minval( dv ) ! determine initial medoid, the object that is the
ml = minloc( dv ) ! closest to any other object in cluster
my_cluster%cluster(1)%medoid = ml(1)
deallocate(dv)
! main loop starts here, bisects initial clusters until desired number of
! clusters are found
iter = 0
do
iter = iter + 1
call print("Starting iteration "//iter,verbosity=PRINT_NERD)
if( my_cluster%N == n_clusters_in ) exit
max_sse = -1.0_dp ! select cluster with greatest sse
do j = 1, my_cluster%N
if( max_sse < my_cluster%cluster(j)%sse ) then
i = j
max_sse = my_cluster%cluster(j)%sse
endif
enddo
nc = my_cluster%cluster(i)%N
if( nc==1 ) cycle
allocate( sub_cluster1(nc), sub_cluster2(nc), sub_cluster1_min(nc),sub_cluster2_min(nc) )
min_sse = huge(1.0_dp)
do j = 1, n_trial
m = ceiling( ran_uniform()*(nc-1) ) ! choose a bisecting point randomly
ml = minloc( sum( my_cluster%dm( my_cluster%cluster(i)%object(:m), my_cluster%cluster(i)%object(:m) ), dim=1) )
lo_med_new = my_cluster%cluster(i)%object(ml(1))
ml = minloc( sum( my_cluster%dm( my_cluster%cluster(i)%object(m+1:), my_cluster%cluster(i)%object(m+1:) ), dim=1) )
hi_med_new = my_cluster%cluster(i)%object(ml(1) + m)
! the median of the 2 subclusters determined
lo_med = 0
hi_med = 0
! perform k-medoid clustering on the two subclusters
do km = 1, n_trial_k_med
if( (lo_med_new == lo_med) .and. (hi_med_new == hi_med) ) exit
lo_med = lo_med_new
hi_med = hi_med_new
n1 = 0
n2 = 0
!n1 = 1
!n2 = 1
!sub_cluster1(n1) = lo_med
!sub_cluster1(n2) = hi_med
do k = 1, my_cluster%cluster(i)%N
if( my_cluster%dm(lo_med,my_cluster%cluster(i)%object(k)) < &
& my_cluster%dm(hi_med,my_cluster%cluster(i)%object(k)) ) then
n1 = n1 + 1
sub_cluster1(n1) = my_cluster%cluster(i)%object(k)
else
n2 = n2 + 1
sub_cluster2(n2) = my_cluster%cluster(i)%object(k)
endif
enddo
ml = minloc( sum( my_cluster%dm( sub_cluster1(:n1), sub_cluster1(:n1) ), dim=1) )
lo_med_new = sub_cluster1(ml(1))
ml = minloc( sum( my_cluster%dm( sub_cluster2(:n2), sub_cluster2(:n2) ), dim=1) )
hi_med_new = sub_cluster2(ml(1))
enddo
sse = sum( my_cluster%dm(lo_med_new,sub_cluster1(:n1)) ) + sum( my_cluster%dm(hi_med_new,sub_cluster2(:n2)) )
! choose the clustering that resulted the smallest sse
if( sse < min_sse ) then
min_sse = sse
sub_cluster1_min = sub_cluster1
sub_cluster2_min = sub_cluster2
n1_min = n1
n2_min = n2
lo_med_min = lo_med_new
hi_med_min = hi_med_new
endif
enddo
! now update the the clusters with the two new subclusters
tmp = my_cluster
do j = 1, my_cluster%N
deallocate( my_cluster%cluster(j)%object )
enddo
deallocate( my_cluster%cluster )
my_cluster%N = my_cluster%N + 1
allocate( my_cluster%cluster( my_cluster%N ) )
do j = 1, my_cluster%N - 1
if( i == j ) then
allocate( my_cluster%cluster(j)%object(n1_min) )
my_cluster%cluster(j)%N = n1_min
my_cluster%cluster(j)%object = sub_cluster1_min(:n1_min)
my_cluster%cluster(j)%sse = sum( my_cluster%dm(lo_med_min,sub_cluster1_min(:n1_min)) )
my_cluster%cluster(j)%medoid = lo_med_min
else
my_cluster%cluster(j) = tmp%cluster(j)
endif
enddo
allocate( my_cluster%cluster(my_cluster%N)%object(n2_min) )
my_cluster%cluster(my_cluster%N)%N = n2_min
my_cluster%cluster(my_cluster%N)%object = sub_cluster2_min(:n2_min)
my_cluster%cluster(my_cluster%N)%sse = sum( my_cluster%dm(hi_med_min,sub_cluster2_min(:n2_min)) )
my_cluster%cluster(my_cluster%N)%medoid = hi_med_min
do j = 1, tmp%N
deallocate( tmp%cluster(j)%object )
enddo
deallocate( tmp%cluster, sub_cluster1, sub_cluster2, sub_cluster1_min, sub_cluster2_min )
call kmedoid(my_cluster)
enddo
if( present(c) ) then
do j = 1, my_cluster%N
do k = 1, my_cluster%cluster(j)%N
i = my_cluster%cluster(j)%object(k)
c(i) = j
enddo
enddo
endif
if( present(med) ) then
do j = 1, my_cluster%N
med(j) = my_cluster%cluster(j)%medoid
enddo
endif
do j = 1, my_cluster%N
deallocate( my_cluster%cluster(j)%object )
enddo
deallocate(my_cluster%cluster)
if (allocated(dm)) deallocate(dm)
endsubroutine bisect_kmedoids
subroutine kmedoid(this)
type(clstr), intent(inout) :: this
type(clstr) :: tmp
integer, dimension(:), allocatable :: medoids
integer, dimension(1) :: ml
integer :: n, j, k
logical :: refined
! k-medoid-refinement
n = size(this%dm,1)
! n: total number of objects
tmp%N = this%N
allocate( tmp%cluster(tmp%N), medoids(tmp%N) )
do j = 1, tmp%N
allocate( tmp%cluster(j)%object(n) )
medoids(j) = this%cluster(j)%medoid
enddo
! main loop starts here, perfom k-medoid clustering until medoids don't
! change anymore
do
do j = 1, tmp%N
tmp%cluster(j)%N = 0
enddo
do j = 1, n
ml = minloc( this%dm(j,medoids) ) ! determine to which medoid each object belongs
k = ml(1)
tmp%cluster(k)%N = tmp%cluster(k)%N + 1
tmp%cluster(k)%object(tmp%cluster(k)%N) = j
enddo
! re-determine the medoid in each cluster
do j = 1, tmp%N
ml = minloc( sum( this%dm( tmp%cluster(j)%object(:tmp%cluster(j)%N), &
& tmp%cluster(j)%object(:tmp%cluster(j)%N) ), dim=1) )
tmp%cluster(j)%medoid = tmp%cluster(j)%object(ml(1))
enddo
refined = .true.
! check whether medoids have changed
do j = 1, tmp%N
refined = refined .and. (tmp%cluster(j)%medoid == medoids(j))
medoids(j) = tmp%cluster(j)%medoid
enddo
if(refined) exit
enddo
! write results
do j = 1, tmp%N
deallocate( this%cluster(j)%object )
allocate( this%cluster(j)%object( tmp%cluster(j)%N ) )
this%cluster(j)%object = tmp%cluster(j)%object(:tmp%cluster(j)%N)
this%cluster(j)%N = tmp%cluster(j)%N
this%cluster(j)%medoid = tmp%cluster(j)%medoid
this%cluster(j)%sse = sum( this%dm(this%cluster(j)%medoid,&
& this%cluster(j)%object ) )
deallocate( tmp%cluster(j)%object )
enddo
deallocate( tmp%cluster, medoids )
endsubroutine kmedoid
subroutine cluster_kmeans(x,cluster_index,theta_fac,theta)
real(dp), dimension(:,:), intent(in) :: x
integer, dimension(:), intent(out) :: cluster_index
real(dp), intent(in), optional :: theta_fac
real(dp), dimension(:), intent(in), target, optional :: theta
real(dp), dimension(:), pointer :: my_theta => null()
real(dp) :: my_theta_fac, d_min, d_ij, d_total, d_total_prev
real(dp), dimension(:,:), allocatable :: cluster_centre
integer, dimension(:), allocatable :: cluster_info
integer :: d, n, m, i, j, k, cluster_info_old, iter, n_points_cluster_j
logical :: cluster_same
d = size(x,1)
n = size(x,2)
m = size(cluster_index)
if( m > n ) call system_abort('cluster_kmeans: required number of clusters ('//m//') greater than total number of points ('//n//')')
my_theta_fac = optional_default(1.0_dp, theta_fac)
if( present(theta) ) then
if( size(theta) == d) then
my_theta => theta
else
allocate(my_theta(d))
my_theta = theta(1)
endif
else
allocate(my_theta(d))
do i = 1, d
my_theta(i) = ( maxval(x(i,:)) - minval(x(i,:)) )
if( my_theta(i) .feq. 0.0_dp ) my_theta(i) = 1.0_dp
enddo
my_theta = my_theta * my_theta_fac
endif
allocate(cluster_centre(d,m),cluster_info(n))
call fill_random_integer(cluster_index, n) !choose random points as cluster centres.
cluster_centre = x(:,cluster_index)
cluster_info = 0
iter = 0
d_total = huge(1.0_dp)
do
iter = iter + 1
call print("iteration: "//iter,verbosity=PRINT_NERD)
cluster_same = .true.
d_total_prev = d_total
d_total = 0.0_dp
!$omp parallel do default(none) shared(n,m,x,cluster_info,cluster_centre,my_theta) &
!$omp reduction(.and.:cluster_same) &
!$omp private(i,j,d_min,d_ij,cluster_info_old) reduction(+:d_total)
do i = 1, n
d_min = huge(0.0_dp)
cluster_info_old = cluster_info(i)
do j = 1, m
d_ij = sum(( (cluster_centre(:,j) - x(:,i))/my_theta )**2)
if( d_ij < d_min ) then
d_min = d_ij
cluster_info(i) = j
endif
enddo
if( cluster_info_old /= cluster_info(i) ) cluster_same = cluster_same .and. .false.
d_total = d_total + d_min
enddo
!$omp end parallel do
call print("cluster_kmeans iteration="//iter//" d_total="//d_total)
!$omp parallel do default(none) shared(x,cluster_centre,cluster_info,m,d,n) private(j,k,n_points_cluster_j)
do j = 1, m
n_points_cluster_j = count(cluster_info==j)
if( n_points_cluster_j == 0 ) then
cluster_centre(:,j) = x(:,ceiling(ran_uniform()*n))
else
do k = 1, d
cluster_centre(k,j) = sum(x(k,:),mask=(cluster_info==j)) / n_points_cluster_j
enddo
endif
enddo
!$omp end parallel do
if( cluster_same ) exit
if( abs(d_total - d_total_prev) < KMEANS_THRESHOLD * d_total ) exit
enddo
do j = 1, m
d_min = huge(0.0_dp)
do i = 1, n
d_ij = sum(( (cluster_centre(:,j) - x(:,i))/my_theta )**2)
if( d_ij < d_min ) then
d_min = d_ij
cluster_index(j) = i
endif
enddo
enddo
deallocate(cluster_centre, cluster_info)
if(present(theta)) then
my_theta => null()
else
deallocate(my_theta)
endif
endsubroutine cluster_kmeans
! https://sites.google.com/site/dataclusteringalgorithms/fuzzy-c-means-clustering-algorithm
subroutine cluster_fuzzy_cmeans(x,cluster_index,theta_fac,theta,fuzziness)
real(dp), dimension(:,:), intent(in) :: x
integer, dimension(:), intent(out) :: cluster_index
real(dp), intent(in), optional :: theta_fac
real(dp), dimension(:), intent(in), target, optional :: theta
real(dp), intent(in), optional :: fuzziness
real(dp), dimension(:), pointer :: my_theta => null()
real(dp) :: my_theta_fac, d_min, d_ij, d_total, d_total_prev
real(dp), dimension(:,:), allocatable :: cluster_centre
real(dp), dimension(:,:), allocatable :: w
real(dp), dimension(:), allocatable, save :: wx_j, d_i
real(dp) :: w_j, w_old, my_fuzziness, alpha
integer :: d, n, m, i, j, iter
logical :: cluster_same
!$omp threadprivate(d_i, wx_j)
d = size(x,1)
n = size(x,2)
m = size(cluster_index)
if( m > n ) call system_abort('cluster_fuzzy_cmeans: required number of clusters ('//m//') greater than total number of points ('//n//')')
my_theta_fac = optional_default(1.0_dp, theta_fac)
my_fuzziness = optional_default(4.0_dp, fuzziness)
if( present(theta) ) then
if( size(theta) == d) then
my_theta => theta
else
allocate(my_theta(d))
my_theta = theta(1)
endif
else
allocate(my_theta(d))
do i = 1, d
my_theta(i) = ( maxval(x(i,:)) - minval(x(i,:)) )
if( my_theta(i) .feq. 0.0_dp ) my_theta(i) = 1.0_dp
enddo
my_theta = my_theta * my_theta_fac
endif
allocate(cluster_centre(d,m), w(n,m))
!$omp parallel
allocate(d_i(m), wx_j(d))
!$omp end parallel
call fill_random_integer(cluster_index, n) !choose random points as cluster centres.
cluster_centre = x(:,cluster_index)
do i = 1, m
do j = 1, d
cluster_centre(j,i) = cluster_centre(j,i) + ( ran_uniform() - 0.5_dp ) * cluster_jitter
enddo
enddo
w = 0.0_dp
iter = 0
d_total = huge(1.0_dp)
do
iter = iter + 1
call print("iteration: "//iter,verbosity=PRINT_NERD)
cluster_same = .true.
d_total_prev = d_total
d_total = 0.0_dp
! Calculate fuzzy membership
!$omp parallel do default(none) shared(n,m,my_theta,my_fuzziness,w,x,cluster_centre) &
!$omp private(i,j,alpha,w_old) reduction(.and.:cluster_same) reduction(+:d_total)
do i = 1, n
alpha = 0.0_dp
do j = 1, m
d_i(j) = sqrt(sum(( (cluster_centre(:,j) - x(:,i))/my_theta )**2))
alpha = alpha + 1.0_dp / d_i(j)**(2.0_dp / (my_fuzziness - 1.0_dp))
enddo
do j = 1, m
w_old = w(i,j)
w(i,j) = 0.0_dp
w(i,j) = 1.0_dp / d_i(j)**(2.0_dp / (my_fuzziness - 1.0_dp)) / alpha
if( w_old .fne. w(i,j) ) cluster_same = cluster_same .and. .false.
d_total = d_total + d_i(j)**2 * w(i,j)**my_fuzziness
enddo
enddo
!$omp end parallel do
call print("cluster_fuzzy_cmeans iteration="//iter//" d_total="//d_total)
! Calculate fuzzy centres
!$omp parallel do default(none) shared(m,n,w,x,my_fuzziness,cluster_centre) &
!$omp private(i,j,w_j)
do j = 1, m
w_j = 0.0_dp
wx_j = 0.0_dp
do i = 1, n
w_j = w_j + w(i,j)**my_fuzziness
wx_j = wx_j + x(:,i) * w(i,j)**my_fuzziness
enddo
cluster_centre(:,j) = wx_j / w_j
enddo
!$omp end parallel do
call print("cluster_same: "//cluster_same,verbosity=PRINT_NERD)
call print("d_total: "//d_total,verbosity=PRINT_NERD)
call print("d_total_prev: "//d_total_prev,verbosity=PRINT_NERD)
call print("d_total-d_total_prev: "//(d_total-d_total_prev),verbosity=PRINT_NERD)
if( cluster_same ) exit
if( abs(d_total - d_total_prev) < KMEANS_THRESHOLD * d_total ) exit
enddo
! Allocate cluster centres to nearest points
do j = 1, m
d_min = huge(0.0_dp)
do i = 1, n
d_ij = sum(( (cluster_centre(:,j) - x(:,i))/my_theta )**2)
if( d_ij < d_min ) then
d_min = d_ij
cluster_index(j) = i
endif
enddo
enddo
deallocate(cluster_centre, w)
!$omp parallel
if(allocated(d_i)) deallocate(d_i)
if(allocated(wx_j)) deallocate(wx_j)
!$omp end parallel
if(present(theta)) then
my_theta => null()
else
deallocate(my_theta)
endif
endsubroutine cluster_fuzzy_cmeans
subroutine select_uniform(x,index_out)
real(dp), dimension(:,:), intent(in) :: x
integer, dimension(:), intent(out) :: index_out
integer :: i, j, d, n, m, n_grid, i_global, i_index_out
integer, dimension(:), allocatable :: p_grid, i_hist, histogram, x_histogram, index_out_histogram
real(dp), dimension(:), allocatable :: lower_bound, upper_bound, x_range
d = size(x,1)
n = size(x,2)
m = size(index_out)
if( n < m ) call system_abort('select_uniform: n = '//n//' < m = '//m)
allocate(lower_bound(d), upper_bound(d), x_range(d), p_grid(d), i_hist(d))
lower_bound = minval(x,dim=2)
upper_bound = maxval(x,dim=2)
x_range = upper_bound - lower_bound
n_grid = ceiling( real(m,kind=dp)**(1.0_dp/real(d,kind=dp)) )
p_grid = (/ ( n_grid**(i-1), i = 1, d ) /)
allocate(histogram(n_grid**d))
allocate(x_histogram(n),index_out_histogram(m))
histogram = 0
do i = 1, n
! for each datapoint x(:,i) compute the bin index in each d direction
i_hist = nint( ( x(:,i) - lower_bound ) / x_range * (n_grid-1) ) + 1
! map the bin index to a flat histogram bin index
i_global = sum((i_hist-1)*p_grid)+1
histogram(i_global) = histogram(i_global) + 1
! the i-th datapoint belongs to the i_global-th index in the histogram
x_histogram(i) = i_global
enddo
index_out = 0
i_index_out = 0
! To monitor which bins the sparse points belong to.
index_out_histogram = 0
do i = 1, n
! That's the exit condition if all sparse points are assigned before we
! finish with the data points
if( all(index_out /= 0) ) exit
if( all(x_histogram(i) /= index_out_histogram) ) then
! We have just found a point which belongs to a bin that we haven't
! selected yet in the sparse points
i_index_out = i_index_out + 1
index_out(i_index_out) = i
index_out_histogram(i_index_out) = x_histogram(i)
endif
enddo
do while ( any(index_out == 0) )
! We haven't yet assigned all sparse points.
! Select a bin randomly
i_global = ceiling( ran_uniform() * size(histogram) )
! cycle if the bin is empty
if( histogram(i_global) == 0 ) cycle
! check if there are points belonging to this bin which we haven't
! selected yet
if( count(x_histogram == i_global) == count(index_out_histogram == i_global) ) cycle
do while (.true.)
! select a point from x which belongs to that bin and add it to
! the output.
i = ceiling( ran_uniform() * n )
if( x_histogram(i) /= i_global .or. any(index_out == i) ) then
cycle
else
i_index_out = i_index_out + 1
index_out(i_index_out) = i
index_out_histogram(i_index_out) = x_histogram(i)
exit
endif
enddo
enddo
deallocate(lower_bound, upper_bound, x_range, p_grid, i_hist, histogram, x_histogram,index_out_histogram)
if (.not. all(index_out /= 0)) call system_abort('select_uniform: could not assign all sparse points')
endsubroutine select_uniform
subroutine cur_decomposition(this, index_out, rank, n_iter)
! based on 10.1073/pnas.0803205106
real(dp), intent(in), dimension(:,:) :: this
integer, dimension(:), intent(out) :: index_out
integer, intent(in), optional :: rank, n_iter
integer :: n
integer :: expected_columns
integer :: my_n_iter, my_rank
type(LA_Matrix) :: LA_this
real(dp), allocatable, dimension(:) :: p, s, p_minus_ran_uniform
real(dp), allocatable, dimension(:,:) :: v
integer :: j, l
integer, allocatable, dimension(:), target :: p_index
integer, pointer, dimension(:) :: tmp_index_out => null()
real(dp), allocatable, dimension(:,:) :: C, Cp
real(dp) :: err, min_err
integer :: error
expected_columns = size(index_out)
if( expected_columns <= 0 ) then
call print_warning("cur_decomposition: called with expected_columns "//expected_columns//", can't be zero or less")
return
endif
call initialise(LA_this,this)
my_n_iter = optional_default(1, n_iter)
if (present(rank)) then
call LA_Matrix_SVD_Allocate(LA_this,v=v,error=error)
HANDLE_ERROR(error)
call LA_Matrix_SVD(LA_this,v=v,error=error)
HANDLE_ERROR(error)
my_rank = rank
else
call LA_Matrix_SVD_Allocate(LA_this,s=s,v=v,error=error)
HANDLE_ERROR(error)
call LA_Matrix_SVD(LA_this,s=s,v=v,error=error)
HANDLE_ERROR(error)
my_rank = count(s > TOL_SVD) / 2
endif
n = size(v,1)
allocate(p(n), p_minus_ran_uniform(n), p_index(n))
allocate( C(size(this,1),expected_columns), Cp(expected_columns,size(this,1)) )
p = sum(v(:,1:my_rank)**2, dim=2)
p = p * expected_columns
p = p / my_rank
p = min(p,1.0_dp)
if(my_n_iter <= 0) then ! do not do probabilistic selection of columns
p_index = (/(j, j=1,n )/)
p_minus_ran_uniform = -p
call heap_sort(p_minus_ran_uniform,i_data=p_index)
index_out = p_index(1:expected_columns)
else
min_err = huge(1.0_dp)
do l = 1, my_n_iter
! randomly select columns according to the probabilities
do j = 1, n
p_minus_ran_uniform(j) = ran_uniform() - p(j)
p_index(j) = j ! initialise index array
end do
call heap_sort(p_minus_ran_uniform,i_data=p_index)
tmp_index_out => p_index(1:expected_columns)
C = this(:,tmp_index_out)
! pinv: Moore-Penrose pseudo-inverse
call pseudo_inverse(C,Cp)
err = sum( (this - ( C .mult. Cp .mult. this))**2 )
call print("cur_decomposition: iteration: "//l//", error: "//err)
if(err < min_err) then ! this happens at least once
index_out = tmp_index_out
min_err = err
endif
end do
endif
call finalise(LA_this)
tmp_index_out => null()
if(allocated(s)) deallocate(s)
if(allocated(v)) deallocate(v)
if(allocated(p)) deallocate(p)
if(allocated(p_minus_ran_uniform)) deallocate(p_minus_ran_uniform)
if(allocated(p_index)) deallocate(p_index)
if(allocated(C)) deallocate(C)
if(allocated(Cp)) deallocate(Cp)
end subroutine cur_decomposition
endmodule clustering_module
Source diff could not be displayed: it is too large. Options to address this: view the blob.
! HND XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
! HND X
! HND X libAtoms+QUIP: atomistic simulation library
! HND X
! HND X Portions of this code were written by
! HND X Albert Bartok-Partay, Silvia Cereda, Gabor Csanyi, James Kermode,
! HND X Ivan Solt, Wojciech Szlachta, Csilla Varnai, Steven Winfield.
! HND X
! HND X Copyright 2006-2010.
! HND X
! HND X Not for distribution
! HND X
! HND X Portions of this code were written by Noam Bernstein as part of
! HND X his employment for the U.S. Government, and are not subject
! HND X to copyright in the USA.
! HND X
! HND X When using this software, please cite the following reference:
! HND X
! HND X http://www.libatoms.org
! HND X
! HND X Additional contributions by
! HND X Alessio Comisso, Chiara Gattinoni, and Gianpietro Moras
! HND X
! HND XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
!XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
!X
!X descriptors_wrapper subroutine
!X
!XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
!XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
subroutine descriptors_wrapper_distances(N,lattice,symbol,coord,descriptor_str,descriptor_str_len, &
calc_args_str,calc_args_str_len,i,fractional,previous_accepted,distances)
use system_module
use linearalgebra_module
use dictionary_module
use periodictable_module
use atoms_types_module
use connection_module
use atoms_module
use descriptors_module
implicit none
integer, intent(in) :: N
real(dp), dimension(3,3), intent(inout) :: lattice
character(len=3), dimension(N), intent(in) :: symbol
integer, intent(in) :: descriptor_str_len
character(len=descriptor_str_len) :: descriptor_str
integer, intent(in) :: calc_args_str_len
character(len=calc_args_str_len) :: calc_args_str
real(dp), dimension(3,N), intent(in) :: coord
integer, intent(in) :: i
logical, intent(in) :: fractional, previous_accepted
real(dp), dimension(N,N), intent(out) :: distances
type(atoms), save :: at
type(Connection), save :: at_connect_last_accepted, at_connect_previous
type(descriptor), save :: desc
type(descriptor_data) :: desc_data
real(dp), dimension(:,:), allocatable, save :: desc_array_last_accepted, distances_in_last_accepted, desc_array_previous, distances_in_previous
logical, dimension(:), pointer :: desc_mask
integer, save :: d
integer :: j, k, l, n_i
logical, save :: first_run = .true.
logical :: recalculate
recalculate = .false.
if( first_run ) then
call system_initialise(verbosity=PRINT_SILENT)
call initialise(desc,trim(descriptor_str))
call initialise(at,N,lattice)
call add_property(at,'desc_mask',.true.,ptr=desc_mask)
d = descriptor_dimensions(desc)
allocate(desc_array_previous(d,N), desc_array_last_accepted(d,N))
allocate(distances_in_previous(N,N), distances_in_last_accepted(N,N))
recalculate = .true.
endif
if( .not. first_run .and. (N /= at%N) ) then
call finalise(at)
call initialise(at,N,lattice)
call add_property(at,'desc_mask',.true.,ptr=desc_mask)
if(allocated(desc_array_previous)) deallocate(desc_array_previous)
allocate(desc_array_previous(d,N))
if(allocated(desc_array_last_accepted)) deallocate(desc_array_last_accepted)
allocate(desc_array_last_accepted(d,N))
if(allocated(distances_in_previous)) deallocate(distances_in_previous)
allocate(distances_in_previous(N,N))
if(allocated(distances_in_last_accepted)) deallocate(distances_in_last_accepted)
allocate(distances_in_last_accepted(N,N))
recalculate = .true.
endif
if( .not. first_run ) then
if( previous_accepted ) then
at_connect_last_accepted = at_connect_previous
desc_array_last_accepted = desc_array_previous
distances_in_last_accepted = distances_in_previous
else
at_connect_previous = at_connect_last_accepted
desc_array_previous = desc_array_last_accepted
distances_in_previous = distances_in_last_accepted
endif
endif
if( at%lattice .fne. lattice ) then
call set_lattice(at,lattice, scale_positions=.false.)
recalculate = .true.
endif
do k = 1, at%N
at%Z(k) = atomic_number_from_symbol(symbol(k))
enddo
if( i > 0 .and. previous_accepted .and. .not. recalculate ) then
if( fractional ) then
at%pos(:,i) = matmul(at%lattice,coord(:,i))
else
at%pos(:,i) = coord(:,i)
endif
else
if( fractional ) then
at%pos = matmul(at%lattice,coord)
else
at%pos = coord
endif
endif
call set_cutoff(at,cutoff(desc)+0.5_dp)
call calc_connect(at)
if( .not. assign_pointer(at,'desc_mask',desc_mask) ) call system_abort("descriptors_wrapper: could not assign pointer desc_mask")
if( i > 0 .and. .not. recalculate ) then
if( i > at%N ) call system_abort("descriptors_wrapper: argument i = "//i//" greater than number of atoms "//at%N)
desc_mask = .false.
desc_mask(i) = .true.
if( at_connect_previous%initialised ) then
do n_i = 1, n_neighbours(at,i,alt_connect=at_connect_previous)
desc_mask(neighbour(at,i,n_i,alt_connect=at_connect_previous)) = .true.
enddo
endif
do n_i = 1, n_neighbours(at,i)
desc_mask(neighbour(at,i,n_i)) = .true.
enddo
call calc(desc,at,desc_data,do_descriptor=.true.,do_grad_descriptor=.false.,args_str="atom_mask_name=desc_mask "//trim(calc_args_str))
do k = 1, count(desc_mask)
j = desc_data%x(k)%ci(1)
desc_array_previous(:,j) = desc_data%x(k)%data(:)
enddo
do k = 1, count(desc_mask)
j = desc_data%x(k)%ci(1)
do l = 1, at%N
distances_in_previous(l,j) = sum( desc_array_previous(:,l) * desc_array_previous(:,j) )
distances_in_previous(j,l) = distances_in_previous(l,j)
enddo
enddo
desc_mask = .true.
at_connect_previous = at%connect
else
call calc(desc,at,desc_data,do_descriptor=.true.,do_grad_descriptor=.false.,args_str=trim(calc_args_str))
do j = 1, at%N
desc_array_previous(:,j) = desc_data%x(j)%data
enddo
distances_in_previous = matmul(transpose(desc_array_previous),desc_array_previous)
at_connect_previous = at%connect
endif
distances = -log(distances_in_previous)
call finalise(desc_data)
if( first_run ) then
at_connect_last_accepted = at_connect_previous
desc_array_last_accepted = desc_array_previous
distances_in_last_accepted = distances_in_previous
endif
first_run = .false.
endsubroutine descriptors_wrapper_distances
module descriptors_wrapper_module
use system_module
use periodictable_module, only : atomic_number_from_symbol
use atoms_module
use linearalgebra_module
use descriptors_module, only : descriptor, initialise, finalise, cutoff, calc, descriptor_sizes, descriptor_dimensions
implicit none
#ifdef HAVE_GAP
type(descriptor), save :: desc
#endif
logical :: first_run = .true.
contains
subroutine descriptors_wrapper_initialise(descriptor_str)
character(len=*) :: descriptor_str
#ifdef HAVE_GAP
if( first_run ) then
call system_initialise(verbosity=PRINT_SILENT)
call initialise(desc,trim(descriptor_str))
else
call finalise(desc)
call initialise(desc,trim(descriptor_str))
endif
first_run = .false.
#endif
endsubroutine descriptors_wrapper_initialise
subroutine descriptors_wrapper_initialise_C(descriptor_str,n_descriptor_str) bind(c)
use iso_c_binding, only: c_int, c_char
character(kind=c_char), intent(in) :: descriptor_str(n_descriptor_str)
integer(kind=c_int), intent(in) :: n_descriptor_str
call descriptors_wrapper_initialise(trim(a2s(descriptor_str)))
endsubroutine descriptors_wrapper_initialise_C
function descriptors_wrapper_dimensions()
integer :: descriptors_wrapper_dimensions
if(.not. first_run) then
descriptors_wrapper_dimensions = descriptor_dimensions(desc)
else
call system_abort("descriptors_wrapper_dimensions: initialise with calling descriptors_wrapper_initialise() first.")
endif
endfunction descriptors_wrapper_dimensions
function descriptors_wrapper_dimensions_C() bind(c)
use iso_c_binding, only: c_int
integer(kind=c_int) :: descriptors_wrapper_dimensions_C
descriptors_wrapper_dimensions_C = descriptors_wrapper_dimensions()
endfunction descriptors_wrapper_dimensions_C
function descriptors_wrapper_size(N,lattice,symbol,coord,fractional)
integer, intent(in) :: N
real(dp), dimension(3,3), intent(inout) :: lattice
character(len=3), dimension(N), intent(in) :: symbol
real(dp), dimension(3,N), intent(in) :: coord
logical, intent(in) :: fractional
integer :: descriptors_wrapper_size
type(atoms), save :: at
integer :: n_descriptors,n_cross
call copy_data_to_atoms(at,N,lattice,symbol,coord,fractional)
call descriptor_sizes(desc,at,n_descriptors,n_cross)
descriptors_wrapper_size = n_descriptors
endfunction descriptors_wrapper_size
function descriptors_wrapper_size_C(N,lattice,symbol,coord,fractional) bind(c)
use iso_c_binding, only: c_double, c_int, c_bool, c_char
integer(kind=c_int), intent(in) :: N
real(kind=c_double), dimension(3,3), intent(inout) :: lattice
character(kind=c_char), dimension(3,N), intent(in) :: symbol
real(kind=c_double), dimension(3,N), intent(in) :: coord
logical(kind=c_bool), intent(in) :: fractional
integer(kind=c_int) :: descriptors_wrapper_size_C
character(len=3), dimension(N) :: my_symbol
integer :: i
logical :: my_fractional
do i = 1, N
my_symbol(i) = a2s(symbol(:,i))
enddo
my_fractional = logical(fractional,kind=kind(my_fractional))
descriptors_wrapper_size_C = descriptors_wrapper_size(N,lattice,my_symbol,coord,my_fractional)
endfunction descriptors_wrapper_size_C
function descriptors_wrapper_gradient_size(N,lattice,symbol,coord,fractional)
integer, intent(in) :: N
real(dp), dimension(3,3), intent(inout) :: lattice
character(len=3), dimension(N), intent(in) :: symbol
real(dp), dimension(3,N), intent(in) :: coord
logical, intent(in) :: fractional
integer :: descriptors_wrapper_gradient_size
type(atoms), save :: at
integer :: n_descriptors,n_cross
call copy_data_to_atoms(at,N,lattice,symbol,coord,fractional)
call descriptor_sizes(desc,at,n_descriptors,n_cross)
descriptors_wrapper_gradient_size = n_cross
endfunction descriptors_wrapper_gradient_size
function descriptors_wrapper_gradient_size_C(N,lattice,symbol,coord,fractional) bind(c)
use iso_c_binding, only: c_double, c_int, c_bool, c_char
integer(kind=c_int), intent(in) :: N
real(kind=c_double), dimension(3,3), intent(inout) :: lattice
character(kind=c_char), dimension(3,N), intent(in) :: symbol
real(kind=c_double), dimension(3,N), intent(in) :: coord
logical(kind=c_bool), intent(in) :: fractional
integer(kind=c_int) :: descriptors_wrapper_gradient_size_C
character(len=3), dimension(N) :: my_symbol
integer :: i
logical :: my_fractional
do i = 1, N
my_symbol(i) = a2s(symbol(:,i))
enddo
my_fractional = logical(fractional,kind=kind(my_fractional))
descriptors_wrapper_gradient_size_C = descriptors_wrapper_gradient_size(N,lattice,my_symbol,coord,my_fractional)
endfunction descriptors_wrapper_gradient_size_C
subroutine descriptors_wrapper_both_sizes(N,lattice,symbol,coord,fractional,n_descriptors,n_cross)
integer, intent(in) :: N
real(dp), dimension(3,3), intent(inout) :: lattice
character(len=3), dimension(N), intent(in) :: symbol
real(dp), dimension(3,N), intent(in) :: coord
logical, intent(in) :: fractional
integer, intent(out) :: n_descriptors, n_cross
type(atoms), save :: at
call copy_data_to_atoms(at,N,lattice,symbol,coord,fractional)
call descriptor_sizes(desc,at,n_descriptors,n_cross)
endsubroutine descriptors_wrapper_both_sizes
subroutine descriptors_wrapper_both_sizes_C(N,lattice,symbol,coord,fractional,n_descriptors,n_cross) bind(c)
use iso_c_binding, only: c_double, c_int, c_bool, c_char
integer(kind=c_int), intent(in) :: N
real(kind=c_double), dimension(3,3), intent(inout) :: lattice
character(kind=c_char), dimension(3,N), intent(in) :: symbol
real(kind=c_double), dimension(3,N), intent(in) :: coord
logical(kind=c_bool), intent(in) :: fractional
integer(kind=c_int), intent(out) :: n_descriptors, n_cross
character(len=3), dimension(N) :: my_symbol
integer :: i
logical :: my_fractional
do i = 1, N
my_symbol(i) = a2s(symbol(:,i))
enddo
my_fractional = logical(fractional,kind=kind(my_fractional))
call descriptors_wrapper_both_sizes(N,lattice,my_symbol,coord,my_fractional,n_descriptors,n_cross)
endsubroutine descriptors_wrapper_both_sizes_C
subroutine descriptors_wrapper_array(N,lattice,symbol,coord,fractional,descriptor_array,d_descriptor, n_descriptor)
integer, intent(in) :: N
real(dp), dimension(3,3), intent(inout) :: lattice
character(len=3), dimension(N), intent(in) :: symbol
real(dp), dimension(3,N), intent(in) :: coord
logical, intent(in) :: fractional
integer, intent(in) :: d_descriptor, n_descriptor
real(dp), dimension(d_descriptor,n_descriptor), intent(out):: descriptor_array
type(atoms), save :: at
if( first_run ) then
call system_abort("descriptors_wrapper_array: initialise with calling descriptors_wrapper_initialise() first.")
endif
call copy_data_to_atoms(at,N,lattice,symbol,coord,fractional)
call calc(desc,at,descriptor_array)
endsubroutine descriptors_wrapper_array
subroutine descriptors_wrapper_array_C(N,lattice,symbol,coord,fractional,descriptor_array,d_descriptor, n_descriptor) bind(c)
use iso_c_binding, only: c_double, c_int, c_bool, c_char
integer(kind=c_int), intent(in) :: N
real(kind=c_double), dimension(3,3), intent(inout) :: lattice
character(kind=c_char), dimension(3,N), intent(in) :: symbol
real(kind=c_double), dimension(3,N), intent(in) :: coord
logical(kind=c_bool), intent(in) :: fractional
integer(kind=c_int), intent(in) :: d_descriptor, n_descriptor
real(kind=c_double), dimension(d_descriptor,n_descriptor), intent(out):: descriptor_array
character(len=3), dimension(N) :: my_symbol
integer :: i
logical :: my_fractional
do i = 1, N
my_symbol(i) = a2s(symbol(:,i))
enddo
my_fractional = logical(fractional,kind=kind(my_fractional))
call descriptors_wrapper_array(N,lattice,my_symbol,coord,my_fractional,descriptor_array,d_descriptor,n_descriptor)
endsubroutine descriptors_wrapper_array_C
subroutine descriptors_wrapper_gradient_array(N,lattice,symbol,coord,fractional,grad_descriptor_array,grad_descriptor_index,grad_descriptor_pos,d_descriptor,n_cross)
integer, intent(in) :: N
real(dp), dimension(3,3), intent(inout) :: lattice
character(len=3), dimension(N), intent(in) :: symbol
real(dp), dimension(3,N), intent(in) :: coord
logical, intent(in) :: fractional
integer, intent(in) :: d_descriptor, n_cross
real(dp), dimension(d_descriptor,3,n_cross), intent(out):: grad_descriptor_array
integer, dimension(2,n_cross), intent(out):: grad_descriptor_index
real(dp), dimension(3,n_cross), intent(out):: grad_descriptor_pos
type(atoms), save :: at
if( first_run ) then
call system_abort("descriptors_wrapper_gradient_array: initialise with calling descriptors_wrapper_initialise() first.")
endif
call copy_data_to_atoms(at,N,lattice,symbol,coord,fractional)
call calc(desc,at,grad_descriptor_out=grad_descriptor_array,grad_descriptor_index=grad_descriptor_index,grad_descriptor_pos=grad_descriptor_pos)
endsubroutine descriptors_wrapper_gradient_array
subroutine descriptors_wrapper_gradient_array_C(N,lattice,symbol,coord,fractional,grad_descriptor_array,grad_descriptor_index,grad_descriptor_pos,d_descriptor,n_cross) bind(c)
use iso_c_binding, only: c_double, c_int, c_bool, c_char
integer(kind=c_int), intent(in) :: N
real(kind=c_double), dimension(3,3), intent(inout) :: lattice
character(kind=c_char), dimension(3,N), intent(in) :: symbol
real(kind=c_double), dimension(3,N), intent(in) :: coord
logical(kind=c_bool), intent(in) :: fractional
integer(kind=c_int), intent(in) :: d_descriptor, n_cross
real(kind=c_double), dimension(d_descriptor,3,n_cross), intent(out):: grad_descriptor_array
integer(kind=c_int), dimension(2,n_cross), intent(out):: grad_descriptor_index
real(kind=c_double), dimension(3,n_cross), intent(out):: grad_descriptor_pos
character(len=3), dimension(N) :: my_symbol
integer :: i
logical :: my_fractional
do i = 1, N
my_symbol(i) = a2s(symbol(:,i))
enddo
my_fractional = logical(fractional,kind=kind(my_fractional))
call descriptors_wrapper_gradient_array(N,lattice,my_symbol,coord,my_fractional,grad_descriptor_array,grad_descriptor_index,grad_descriptor_pos,d_descriptor,n_cross)
endsubroutine descriptors_wrapper_gradient_array_C
subroutine descriptors_wrapper_both_arrays(N,lattice,symbol,coord,fractional,descriptor_array,grad_descriptor_array,grad_descriptor_index,grad_descriptor_pos,d_descriptor,n_descriptor,n_cross)
integer, intent(in) :: N
real(dp), dimension(3,3), intent(inout) :: lattice
character(len=3), dimension(N), intent(in) :: symbol
real(dp), dimension(3,N), intent(in) :: coord
logical, intent(in) :: fractional
integer, intent(in) :: d_descriptor, n_descriptor, n_cross
real(dp), dimension(d_descriptor,n_descriptor), intent(out):: descriptor_array
real(dp), dimension(d_descriptor,3,n_cross), intent(out):: grad_descriptor_array
integer, dimension(2,n_cross), intent(out):: grad_descriptor_index
real(dp), dimension(3,n_cross), intent(out):: grad_descriptor_pos
type(atoms), save :: at
if( first_run ) then
call system_abort("descriptors_wrapper_both_arrays: initialise with calling descriptors_wrapper_initialise() first.")
endif
call copy_data_to_atoms(at,N,lattice,symbol,coord,fractional)
call calc(desc,at,descriptor_out=descriptor_array,grad_descriptor_out=grad_descriptor_array,grad_descriptor_index=grad_descriptor_index,grad_descriptor_pos=grad_descriptor_pos)
endsubroutine descriptors_wrapper_both_arrays
subroutine descriptors_wrapper_both_arrays_C(N,lattice,symbol,coord,fractional,descriptor_array,grad_descriptor_array,grad_descriptor_index,grad_descriptor_pos,d_descriptor,n_descriptor,n_cross) bind(c)
use iso_c_binding, only: c_double, c_int, c_bool, c_char
integer(kind=c_int), intent(in) :: N
real(kind=c_double), dimension(3,3), intent(inout) :: lattice
character(kind=c_char), dimension(3,N), intent(in) :: symbol
real(kind=c_double), dimension(3,N), intent(in) :: coord
logical(kind=c_bool), intent(in) :: fractional
integer(kind=c_int), intent(in) :: d_descriptor, n_descriptor, n_cross
real(kind=c_double), dimension(d_descriptor,n_descriptor), intent(out):: descriptor_array
real(kind=c_double), dimension(d_descriptor,3,n_cross), intent(out):: grad_descriptor_array
integer(kind=c_int), dimension(2,n_cross), intent(out):: grad_descriptor_index
real(kind=c_double), dimension(3,n_cross), intent(out):: grad_descriptor_pos
character(len=3), dimension(N) :: my_symbol
integer :: i
logical :: my_fractional
do i = 1, N
my_symbol(i) = a2s(symbol(:,i))
enddo
my_fractional = logical(fractional,kind=kind(my_fractional))
call descriptors_wrapper_both_arrays(N,lattice,my_symbol,coord,my_fractional,descriptor_array,grad_descriptor_array,grad_descriptor_index,grad_descriptor_pos,d_descriptor,n_descriptor,n_cross)
endsubroutine descriptors_wrapper_both_arrays_C
subroutine copy_data_to_atoms(at,N,lattice,symbol,coord,fractional)
type(atoms), intent(inout) :: at
integer, intent(in) :: N
real(dp), dimension(3,3), intent(inout) :: lattice
character(len=3), dimension(N), intent(in) :: symbol
real(dp), dimension(3,N), intent(in) :: coord
logical, intent(in) :: fractional
integer :: k
if( N /= at%N ) then
call finalise(at)
call initialise(at,N,lattice)
endif
if( at%lattice .fne. lattice ) then
call set_lattice(at,lattice, scale_positions=.false.)
endif
do k = 1, at%N
at%Z(k) = atomic_number_from_symbol(symbol(k))
enddo
if( fractional ) then
at%pos = matmul(at%lattice,coord)
else
at%pos = coord
endif
call set_cutoff(at,cutoff(desc)+0.5_dp)
call calc_connect(at)
endsubroutine copy_data_to_atoms
endmodule descriptors_wrapper_module
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SPHINXPROJ = gap
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
# -*- coding: utf-8 -*-
# HQ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# HQ X
# HQ X quippy: Python interface to QUIP atomistic simulation library
# HQ X
# HQ X Copyright James Kermode 2010
# HQ X
# HQ X These portions of the source code are released under the GNU General
# HQ X Public License, version 2, http://www.gnu.org/copyleft/gpl.html
# HQ X
# HQ X If you would like to license the source code under different terms,
# HQ X please contact James Kermode, james.kermode@gmail.com
# HQ X
# HQ X When using this software, please cite the following reference:
# HQ X
# HQ X http://www.jrkermode.co.uk/quippy
# HQ X
# HQ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#
# quippy documentation build configuration file, created by
# sphinx-quickstart on Wed Sep 2 14:17:01 2009.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import glob
import os
import sys
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(1, os.path.abspath('..'))
sys.path.insert(1, os.path.abspath('.'))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
needs_sphinx = '1.4'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.mathjax',
'sphinx.ext.autosummary',
'sphinx.ext.intersphinx',
'sphinx.ext.viewcode',
'sphinx.ext.githubpages',
'nbsphinx',
'modcontents',
'numpydoc']
# This list was generated by grep as a workaround to
# https://github.com/sphinx-doc/sphinx/issues/2485
autosummary_generate = [
'gap_fit.rst',
]
nbsphinx_allow_errors = True
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = ['.rst', '.ipynb']
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'gap'
copyright = u'20010-2019, Gabor Csanyi'
author= u'Gabor Csanyi'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
import os
version=os.popen('cat ../GIT_VERSON 2> /dev/null|| '
'git describe --always --tags --dirty=+ 2> /dev/null || '
'echo ').read().strip()
# The full version, including alpha/beta/rc tags.
release = version
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '**.ipynb_checkpoints']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
modindex_common_prefix = ['quippy.']
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
html_theme_options = {
}
html_logo = 'hybrid.png'
html_favicon = 'favicon.ico'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Fix for RTD tables
html_context = {
'css_files': [
'_static/theme_overrides.css',
],
}
# -- Options for HTMLHelp output ------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'gapdoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'gap.tex', u'GAP Documentation',
u'Gabor Csanyi', 'manual'),
]
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'gap', u'GAP Documentation',
[author], 1)
]
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'gap', u'GAP Documentation',
author, 'gap', 'One line description of project.',
'Miscellaneous'),
]
intersphinx_mapping = {'python': ('https://docs.python.org/2.7', None),
'ase': ('https://wiki.fysik.dtu.dk/ase/', None),
'numpy': ('https://docs.scipy.org/doc/numpy/', None),
'matplotlib': ('https://matplotlib.org/', None)}
###
### sphinx-quickstart output ends here
###
from quippy.oo_fortran import FortranDerivedType, FortranDerivedTypes
import re
# classnames = [v.__name__ for v in FortranDerivedTypes.values()]
# classname_re = re.compile('(^|\s+)((``)?)('+'|'.join([v.__name__ for v in FortranDerivedTypes.values()])+r')\2(?=[\s\W]+)')
# method_or_attr_re = re.compile('(^|\s+)((``)?)('+'|'.join([v.__name__+'\.([a-zA-Z][a-zA-Z0-9_]*)' for v in FortranDerivedTypes.values()])+r')\2(?=[\s\W]+)')
# doc_subs = [(classname_re, r'\1:class:`~.\4`'),
# (method_or_attr_re, r'\1:meth:`.\4`')]
global_options = None
def process_docstring(app, what, name, obj, options, lines):
global global_options
global_options = options
def process_signature(app, what, name, obj, options, signature, return_annotation):
return (signature, return_annotation)
def maybe_skip_member(app, what, name, obj, skip, options):
if hasattr(FortranDerivedType, name) and options.inherited_members:
return True
return skip
from docutils import nodes, utils
from docutils.parsers.rst.roles import set_classes
def get_github_url(view, path):
return 'https://github.com/{project}/{view}/{branch}/{path}'.format(
project='libAtoms/GAP',
view=view,
branch='public',
path=path)
def github_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
if text[-1] == '>':
i = text.index('<')
name = text[:i - 1]
text = text[i + 1:-1]
else:
name = text
ref = get_github_url('blob', name)
set_classes(options)
node = nodes.reference(rawtext, name, refuri=ref, **options)
return [node], []
def mol_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
n = []
t = ''
while text:
if text[0] == '_':
n.append(nodes.Text(t))
t = ''
n.append(nodes.subscript(text=text[1]))
text = text[2:]
else:
t += text[0]
text = text[1:]
n.append(nodes.Text(t))
return n, []
def setup(app):
app.connect('autodoc-process-docstring', process_docstring)
app.connect('autodoc-process-signature', process_signature)
app.connect('autodoc-skip-member', maybe_skip_member)
app.add_role('git', github_role)
app.add_role('mol', mol_role)
autodoc_member_order = 'groupwise'
#autoclass_content = 'both'
def add_line(self, line, source, *lineno):
"""Append one line of generated reST to the output."""
sys.stdout.write(self.indent + line + '\n')
self.directive.result.append(self.indent + line, source, *lineno)
# Uncomment two lines below to debug autodoc rst output
#import sphinx.ext.autodoc
#sphinx.ext.autodoc.Documenter.add_line = add_line
# Monkey patch numpydoc to exclude methods and attributes inherited
# from base classes, and to include attributes wrapped by Python
# properties
numpydoc_show_class_members = True
import inspect
import pydoc
import numpydoc
import numpydoc.docscrape
@property
def methods(self):
if self._cls is None:
return []
do_inherited = False
if global_options is not None and hasattr(global_options, 'inherited_members'):
do_inherited = global_options.inherited_members
return [name for name,func in inspect.getmembers(self._cls)
if not name.startswith('_') and callable(func) and
(do_inherited or not any(hasattr(base, name) for base in self._cls.__bases__)) and
pydoc.getdoc(getattr(self._cls, name))]
@property
def properties(self):
if self._cls is None:
return []
do_inherited = False
if global_options is not None and hasattr(global_options, 'inherited_members'):
do_inherited = global_options.inherited_members
return [name for name,func in inspect.getmembers(self._cls) if not name.startswith('_') and
(do_inherited or not any(hasattr(base, name) for base in self._cls.__bases__)) and
(func is None or isinstance(getattr(self._cls, name), property)) and
pydoc.getdoc(getattr(self._cls, name))]
numpydoc.docscrape.ClassDoc.methods = methods
numpydoc.docscrape.ClassDoc.properties = properties
# generate .rst versions of any .ipynb notebooks under Examples/
# Superseded by nbsphinx extension
# for notebook in glob.glob(os.path.join('Examples/*.ipynb')):
# cmd = 'jupyter nbconvert --to rst {0}'.format(notebook)
# print cmd
# os.system(cmd)
.. HQ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
.. HQ X
.. HQ X quippy: Python interface to QUIP atomistic simulation library
.. HQ X
.. HQ X Copyright James Kermode 2010
.. HQ X
.. HQ X These portions of the source code are released under the GNU General
.. HQ X Public License, version 2, http://www.gnu.org/copyleft/gpl.html
.. HQ X
.. HQ X If you would like to license the source code under different terms,
.. HQ X please contact James Kermode, james.kermode@gmail.com
.. HQ X
.. HQ X When using this software, please cite the following reference:
.. HQ X
.. HQ X http://www.jrkermode.co.uk/quippy
.. HQ X
.. HQ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
The gap_fit program
=====================================================
Main options
------------
.. autofunction:: quippy.gap_fit_parse_command_line
GAP options
-----------
.. autofunction:: quippy.gap_fit_parse_gap_str
`sparse_method` options are:
- RANDOM: default, chooses n_sparse random datapoints
- PIVOT: based on the full covariance matrix finds the n_sparse "pivoting" points
- CLUSTER: based on the full covariance matrix performs a k-medoid clustering into n_sparse clusters, returning the medoids
- UNIFORM: makes a histogram of the data based on n_sparse and returns a data point from each bin
- KMEANS: k-means clustering based on the data points
- COVARIANCE: greedy data point selection based on the sparse covariance matrix, to minimise the GP variance of all datapoints
- UNIQ: selects unique datapoints from the dataset
- FUZZY: fuzzy k-means clustering
- FILE: reads sparse points from a file
- INDEX_FILE: reads indices of sparse points from a file
- CUR_COVARIANCE: CUR, based on the full covariance matrix
- CUR_POINTS: CUR, based on the datapoints
Source diff could not be displayed: it is too large. Options to address this: view the blob.
.. HQ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
.. HQ X
.. HQ X GAP: Gaussian Approximation Potential
.. HQ X
.. HQ X Copyright Albert Bartok-Partay, Gabor Csanyi 2010-2019
.. HQ X
.. HQ X gc121@cam.ac.uk
.. HQ X
.. HQ X
.. HQ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
.. gap documentation master file
GAP and SOAP documentation
=============================
.. module:: gap
These are the documentation pages for Gaussian Approximation Potential
(GAP) code. GAP is a plugin for QUIP, which itself can be used as a
plugin to LAMMPS or called from ASE. For installation, see the QUIP
documentation pages. The information below is on the usage of GAP.
The purpose of the GAP code is to fit interatomic potentials and then
use them for molecular simulation.
Contents
========
.. toctree::
:maxdepth: 1
gap_fit.rst
tutorials.rst
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
* `Module Source Code <_modules/index.html>`_