{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "2eccae4a",
   "metadata": {},
   "source": [
    "# Ising-Lenz Ergodicity: Generate Distributional Power-laws in Gamma Distribution\n",
    "Fields \n",
    "    \n",
    "     (c) 2013, 2014, 2015, 2016, 2025 Süzen\n",
    "     GPL v3 \n",
    "\n",
    "This notebook generates power-laws in the form, $P(\\Gamma_{G}(t)) \\sim \\Gamma_{G}(t)^{-\\alpha}$. Using outputs from generate gamma. power-laws are fitted and results are repored with the bias corrected bootstrap confidence intervals. \n",
    "\n",
    "The resulting dataset is called `ising1DrateErgodicityPowerlawsDistFields.rds`. \n",
    "\n",
    "$\\Omega_{G}(t)$ : Modified TM G-metric, ergodic convergence.  \n",
    "$\\Gamma_{G}(t)$ : Rate of ergodic convergence.  \n",
    "$\\Kappa_{G}(t)$ : Inverse rate of ergodic convergence.  \n",
    "\n",
    "\n",
    "* Workhorse of the data generation is method `dist_power_law`. The RDS file is simply \n",
    " a data frame for each parameters and their power-law fit information.\n",
    "* Parameters are hardcoded in paralell method below.\n",
    "     * Sizes at Metropolis (`transP=1`) and Glauber (`transP=2`) Dynamics `N=512, 1024, 1536`.\n",
    "     * Fields ranges `seq(from = 0.5, by = 0.06, length.out = 16)`.\n",
    "     * `J=1.0 ikBT=1.0`.\n",
    "     * MC steps up-to `2e6`. \n",
    "       Each `by_ = 1000` point is used for fitting (This is important).\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "8d683416",
   "metadata": {
    "vscode": {
     "languageId": "r"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Loading required package: isingLenzMC\n",
      "\n",
      "\n",
      "Attaching package: ‘igraph’\n",
      "\n",
      "\n",
      "The following objects are masked from ‘package:stats’:\n",
      "\n",
      "    decompose, spectrum\n",
      "\n",
      "\n",
      "The following object is masked from ‘package:base’:\n",
      "\n",
      "    union\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "rm(list=ls()) \n",
    "require(\"isingLenzMC\"); # Developed and tested on v0.2.5 and R v4.5.1\n",
    "library(\"igraph\")\n",
    "library(parallel)       # Core package\n",
    "\n",
    "source(\"../src/power_utilities.R\");\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "fff6ca12",
   "metadata": {
    "vscode": {
     "languageId": "r"
    }
   },
   "outputs": [],
   "source": [
    "  library(boot)\n",
    "\n",
    "  get_mean_boot95_bca <- function(data) {\n",
    "    # Bias-corrected bootstraped means and 95$ CI.\n",
    "    mean_boot <- function(data, indices) {\n",
    "      return(mean(data[indices]))\n",
    "    }\n",
    "    boot_result <- boot(data = as.numeric(data), statistic = mean_boot, R = 1000)\n",
    "    boot_means <- boot_result$t\n",
    "    ci <- boot::boot.ci(boot_result, type = \"bca\")$bca[4:5]\n",
    "    list(\"mean\" = boot_result$t0, \"lower\" = ci[1], \"upper\" = ci[2], \"ci\" = ci)\n",
    "  }\n",
    "\n",
    "dist_power_law <- function(accept_time, gamma_, by_ = 1000) {\n",
    "  # fit power-law given RunSim's result\n",
    "  # P(Gamma) ~ Gamma^alpha\n",
    "  ll <- length(gamma_)\n",
    "  ix <- seq(1, ll, by = by_)\n",
    "  accept_time <- accept_time[ix]\n",
    "  gamma_ <- gamma_[ix]\n",
    "  pf <- igraph::fit_power_law(gamma_)\n",
    "  alpha <- pf$alpha\n",
    "  ix <- which(gamma_ == pf$xmin)[1]\n",
    "  tmin <- accept_time[ix]\n",
    "  D <- pf$KS.stat\n",
    "  pairlist(\n",
    "    \"alpha\" = alpha,\n",
    "    \"tmin\" = tmin,\n",
    "    \"D\" = D\n",
    "  )\n",
    "}\n",
    "\n",
    "dist_power_law_ci <- function(result, by_=1000) {\n",
    "    nrepeat <- length(result$accept_times_repeats)\n",
    "    alphas <- vector(\"numeric\", nrepeat)\n",
    "    optDs <- vector(\"numeric\", nrepeat)\n",
    "    opt_tmins <- vector(\"numeric\", nrepeat)\n",
    "    for(i in 1:nrepeat) {\n",
    "        gamma_ <- result$gamma_repeats[[i]]\n",
    "        accept_time <- result$accept_times_repeats[[i]]\n",
    "        ixx <- which(accept_time < 2e6)\n",
    "        pf <- dist_power_law(accept_time[ixx], gamma_[ixx], by_)\n",
    "        alphas[i] <- pf$alpha\n",
    "        optDs[i] <- pf$D\n",
    "        opt_tmins[i] <- pf$tmin\n",
    "    }\n",
    "    # alpha\n",
    "    alpha_s <- get_mean_boot95_bca(as.numeric(alphas))\n",
    "    alpha_mean <- alpha_s$mean\n",
    "    alpha_boot95ci <- c(alpha_s$lower, alpha_s$upper)\n",
    "    # Ds\n",
    "    D_s <- get_mean_boot95_bca(as.numeric(optDs))\n",
    "    D_mean <- D_s$mean\n",
    "    D_boot95ci <- c(D_s$lower, D_s$upper)\n",
    "    # tmins\n",
    "    tmin_s <- get_mean_boot95_bca(as.numeric(opt_tmins))\n",
    "    tmin_mean <- tmin_s$mean\n",
    "    tmin_boot95ci <- c(tmin_s$lower, tmin_s$upper)\n",
    "    pl_info = list(\n",
    "        \"N\"=result$N,\n",
    "        \"ikBT\"=result$ikBT,\n",
    "        \"dynamics\"=result$dynamics,\n",
    "        \"H\"=result$H,\n",
    "        \"J\"=result$J,\n",
    "        \"alpha_mean\"=alpha_mean,\n",
    "        \"alpha_upper\"=alpha_s$upper,\n",
    "        \"alpha_lower\"=alpha_s$lower,\n",
    "        \"D_mean\"=D_mean,\n",
    "        \"D_upper\"=D_s$upper,\n",
    "        \"D_lower\"=D_s$lower,\n",
    "        \"tmin_mean\"=as.integer(tmin_mean),\n",
    "        \"tmin_upper\"=as.integer(tmin_s$upper),\n",
    "        \"tmin_lower\"=as.integer(tmin_s$lower)\n",
    "    )\n",
    "    pl_info\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "5d055eab",
   "metadata": {
    "vscode": {
     "languageId": "r"
    }
   },
   "outputs": [],
   "source": [
    "ergoRates <- readRDS(\"../datasets/ising1DrateErgodicityFields.rds\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "20ddc4ab",
   "metadata": {
    "vscode": {
     "languageId": "r"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Warning message in norm.inter(t, adj.alpha):\n",
      "“extreme order statistics used as endpoints”\n"
     ]
    }
   ],
   "source": [
    "nresults <- length(ergoRates)\n",
    "for(j in 1:nresults){\n",
    "    result <- ergoRates[[j]]\n",
    "    to_null <- function(x) { \n",
    "        if (is.null(x)) NA else x \n",
    "    }\n",
    "    df_pl <- as.data.frame(lapply(dist_power_law_ci(result), to_null))\n",
    "    if(j == 1) {\n",
    "        df_pl_gamma = df_pl\n",
    "    } else {\n",
    "        df_pl_gamma <- rbind.data.frame(df_pl_gamma, df_pl)\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "c28db963",
   "metadata": {
    "vscode": {
     "languageId": "r"
    }
   },
   "outputs": [],
   "source": [
    "saveRDS(df_pl_gamma, \"../datasets/ising1DrateErgodicityPowerlawsDistributionFields.rds\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "R",
   "language": "R",
   "name": "ir"
  },
  "language_info": {
   "codemirror_mode": "r",
   "file_extension": ".r",
   "mimetype": "text/x-r-source",
   "name": "R",
   "pygments_lexer": "r",
   "version": "4.5.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
