Source code for bayesflow.simulators.benchmark_simulators.inverse_kinematics

import numpy as np

from .benchmark_simulator import BenchmarkSimulator


[docs] class InverseKinematics(BenchmarkSimulator): def __init__( self, scales: np.ndarray = None, l1: float = 0.5, l2: float = 0.5, l3: float = 1.0, rng: np.random.Generator = None, ): """Inverse Kinematics simulated benchmark See: https://arxiv.org/pdf/2101.10763.pdf Parameters ---------- scales: np.ndarray of shape (4, ) or None, optional, default: None The four scales of the Gaussian prior. If ``None`` provided, the scales from https://arxiv.org/pdf/2101.10763.pdf will be used: [0.25, 0.5, 0.5, 0.5]. l1: float, optional, default: 0.5 The length of the first segment. l2: float, optional, default: 0.5 The length of the second segment. l3: float, optional, default: 1.0 The length of the third segment. rng: np.random.Generator or None, optional, default: None An optional random number generator to use. """ self.scales = scales if self.scales is None: self.scales = np.array([0.25, 0.5, 0.5, 0.5]) self.l1 = l1 self.l2 = l2 self.l3 = l3 self.rng = rng if self.rng is None: self.rng = np.random.default_rng()
[docs] def prior(self): """Generates a random draw from a 4-dimensional Gaussian prior distribution with a spherical convariance matrix. The parameters represent a robot's arm configuration, with the first parameter indicating the arm's height and the remaining three are angles. Returns ------- params : np.ndarray of shape (4, ) A single draw from the 4-dimensional Gaussian prior. """ return self.rng.normal(loc=0, scale=self.scales)
[docs] def observation_model(self, params: np.ndarray): """Returns the 2D coordinates of a robot arm given parameter vector. The first parameter represents the arm's height and the remaining three correspond to angles. Parameters ---------- params : np.ndarray of shape (params, ) The four model parameters which will determine the coordinates Returns ------- x : np.ndarray of shape (2, ) The 2D coordinates of the arm """ # Determine 2D position x1 = self.l1 * np.sin(params[1]) x1 += self.l2 * np.sin(params[1] + params[2]) x1 += self.l3 * np.sin(params[1] + params[2] + params[3]) + params[0] x2 = self.l1 * np.cos(params[1]) x2 += self.l2 * np.cos(params[1] + params[2]) x2 += self.l3 * np.cos(params[1] + params[2] + params[3]) return np.array([x1, x2])