Source code for memtorch.bh.memristor.VTEAM

import math

import numpy as np
import torch

import memtorch
from memtorch.utils import clip, convert_range

from .Memristor import Memristor as Memristor


[docs]class VTEAM(Memristor): """VTEAM memristor model (https://asic2.group/tools/memristor-models/). Parameters ---------- time_series_resolution : float Time series resolution (s). r_off : float Off (maximum) resistance of the device (ohms). r_on : float On (minimum) resistance of the device (ohms). d : float Device length (m). k_on : float k_on model parameter. k_off: float k_off model parameter. alpha_on : float alpha_on model parameter. alpha_off : float alpha_off model parameter. v_on : float Positive write threshold voltage (V). v_off : float Negative write threshold voltage (V). x_on : float x_on model parameter. x_off : float x_off model parameter. """ def __init__( self, time_series_resolution=1e-10, r_off=1000, r_on=50, d=3e-9, k_on=-10, k_off=5e-4, alpha_on=3, alpha_off=1, v_on=-0.2, v_off=0.02, x_on=0, x_off=3e-9, **kwargs ): args = memtorch.bh.unpack_parameters(locals()) super(VTEAM, self).__init__( args.r_off, args.r_on, args.time_series_resolution, args.v_off, args.v_on ) self.d = args.d self.k_on = args.k_on self.k_off = args.k_off self.alpha_on = args.alpha_on self.alpha_off = args.alpha_off self.v_on = args.v_on self.v_off = args.v_off self.x_on = args.x_on self.x_off = args.x_off self.g = 1 / self.r_on self.x = self.x_on self.lamda = np.log(self.r_off / self.r_on)
[docs] def dxdt(self, voltage): """Method to determine the derivative of the state variable. Parameters ---------- voltage : float The current applied voltage (V). Returns ------- float The derivative of the state variable. """ if voltage >= self.v_off: return self.k_off * (((voltage / self.v_off) - 1) ** self.alpha_off) elif voltage <= self.v_on: return self.k_on * (((voltage / self.v_on) - 1) ** self.alpha_on) else: return 0
[docs] def current(self, voltage): """Method to determine the current of the model given an applied voltage. Parameters ---------- voltage : float The current applied voltage (V). Returns ------- float The observed current (A). """ return voltage / ( self.r_off * self.x / self.d + self.r_on * (1 - self.x / self.d) )
[docs] def simulate(self, voltage_signal, return_current=False): len_voltage_signal = 1 try: len_voltage_signal = len(voltage_signal) except: voltage_signal = [voltage_signal] if return_current: current = np.zeros(len_voltage_signal) np.seterr(all="raise") for t in range(0, len_voltage_signal): self.x = self.x + ( self.dxdt(voltage_signal[t]) * self.time_series_resolution ) if self.x >= self.d or self.x <= 0: if self.x >= self.d: self.x = self.d else: self.x = 0 current_ = self.current(voltage_signal[t]) if voltage_signal[t] != 0: self.g = current_ / voltage_signal[t] if return_current: current[t] = current_ if return_current: return current
[docs] def set_conductance(self, conductance): conductance = clip(conductance, 1 / self.r_off, 1 / self.r_on) self.x = self.d * ((1 / conductance) - self.r_on) / (self.r_off - self.r_on) self.g = conductance
[docs] def plot_hysteresis_loop( self, duration=200e-9, voltage_signal_amplitude=1, voltage_signal_frequency=50e6, return_result=False, ): return super(VTEAM, self).plot_hysteresis_loop( self, duration=duration, voltage_signal_amplitude=voltage_signal_amplitude, voltage_signal_frequency=voltage_signal_frequency, return_result=return_result, )
[docs] def plot_bipolar_switching_behaviour( self, voltage_signal_amplitude=1.5, voltage_signal_frequency=50e6, log_scale=True, return_result=False, ): return super().plot_bipolar_switching_behaviour( self, voltage_signal_amplitude=voltage_signal_amplitude, voltage_signal_frequency=voltage_signal_frequency, log_scale=log_scale, return_result=return_result, )