{ "cells": [ { "cell_type": "markdown", "id": "0", "metadata": {}, "source": [ "# Converting Sparse Tensors to Matrices and vice versa\n", "```\n", "Copyright 2022 National Technology & Engineering Solutions of Sandia,\n", "LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the\n", "U.S. Government retains certain rights in this software.\n", "```" ] }, { "cell_type": "markdown", "id": "1", "metadata": {}, "source": [ "We show how to convert an `sptensor` to a matrix stored in _coordinate_ format with extra information so that is can be convertered back to an `sptensor`." ] }, { "cell_type": "code", "execution_count": null, "id": "2", "metadata": {}, "outputs": [], "source": [ "import pyttb as ttb\n", "import numpy as np" ] }, { "cell_type": "markdown", "id": "3", "metadata": {}, "source": [ "## Creating an `sptenmat` (sparse tensor as sparse matrix) object\n", "A sparse tensor can be converted to a sparse matrix, with row and column indices stored explicitly.\n", "\n", "First, we crease a sparse tensor to be converted." ] }, { "cell_type": "code", "execution_count": null, "id": "4", "metadata": {}, "outputs": [], "source": [ "np.random.seed(0) # Random seed for reproducibility\n", "X = ttb.sptenrand((10, 10, 10, 10), nonzeros=10)\n", "X" ] }, { "cell_type": "markdown", "id": "5", "metadata": {}, "source": [ "Similar options as `tenmat` are available for `sptenmat`." ] }, { "cell_type": "code", "execution_count": null, "id": "6", "metadata": {}, "outputs": [], "source": [ "A = X.to_sptenmat(np.array([0])) # Mode-0 matricization\n", "A" ] }, { "cell_type": "code", "execution_count": null, "id": "7", "metadata": {}, "outputs": [], "source": [ "A = X.to_sptenmat(np.array([1, 2])) # Multiple modes mapped to rows.\n", "A" ] }, { "cell_type": "code", "execution_count": null, "id": "8", "metadata": {}, "outputs": [], "source": [ "A = X.to_sptenmat(cdims=np.array([1, 2])) # Specify column dimensions.\n", "A" ] }, { "cell_type": "code", "execution_count": null, "id": "9", "metadata": {}, "outputs": [], "source": [ "A = X.to_sptenmat(np.arange(4)) # All modes mapped to rows, i.e., vectorize.\n", "A" ] }, { "cell_type": "code", "execution_count": null, "id": "10", "metadata": {}, "outputs": [], "source": [ "A = X.to_sptenmat(np.array([1])) # By default, columns are ordered as [0, 2, 3]\n", "A" ] }, { "cell_type": "code", "execution_count": null, "id": "11", "metadata": {}, "outputs": [], "source": [ "A = X.to_sptenmat(np.array([1]), np.array([3, 0, 2])) # Specify explicit ordering\n", "A" ] }, { "cell_type": "code", "execution_count": null, "id": "12", "metadata": {}, "outputs": [], "source": [ "A = X.to_sptenmat(np.array([1]), cdims_cyclic=\"fc\") # Forward cyclic column ordering\n", "A" ] }, { "cell_type": "code", "execution_count": null, "id": "13", "metadata": {}, "outputs": [], "source": [ "A = X.to_sptenmat(np.array([1]), cdims_cyclic=\"bc\") # Backward cyclic column ordering\n", "A" ] }, { "cell_type": "markdown", "id": "14", "metadata": {}, "source": [ "## Constituent parts of an `sptenmat`" ] }, { "cell_type": "code", "execution_count": null, "id": "15", "metadata": {}, "outputs": [], "source": [ "A.subs # Subscripts of the nonzeros." ] }, { "cell_type": "code", "execution_count": null, "id": "16", "metadata": {}, "outputs": [], "source": [ "A.vals # Corresponding nonzero values." ] }, { "cell_type": "code", "execution_count": null, "id": "17", "metadata": {}, "outputs": [], "source": [ "A.tshape # Shape of the original tensor." ] }, { "cell_type": "code", "execution_count": null, "id": "18", "metadata": {}, "outputs": [], "source": [ "A.rdims # Dimensions that were mapped to the rows." ] }, { "cell_type": "code", "execution_count": null, "id": "19", "metadata": {}, "outputs": [], "source": [ "A.cdims # Dimensions that were mapped to the columns." ] }, { "cell_type": "markdown", "id": "20", "metadata": {}, "source": [ "## Creating an `sptenmat` from its constituent parts" ] }, { "cell_type": "code", "execution_count": null, "id": "21", "metadata": {}, "outputs": [], "source": [ "B = ttb.sptenmat(A.subs, A.vals, A.rdims, A.cdims, A.tshape) # Effectively copies A\n", "B" ] }, { "cell_type": "markdown", "id": "22", "metadata": {}, "source": [ "## Creating an `sptenmat` with no nonzeros" ] }, { "cell_type": "code", "execution_count": null, "id": "23", "metadata": {}, "outputs": [], "source": [ "A = ttb.sptenmat(rdims=A.rdims, cdims=A.cdims, tshape=A.tshape) # An empty sptenmat\n", "A" ] }, { "cell_type": "markdown", "id": "24", "metadata": {}, "source": [ "## Creating an empty sptenmat" ] }, { "cell_type": "code", "execution_count": null, "id": "25", "metadata": {}, "outputs": [], "source": [ "A = ttb.sptenmat() # A really empty sptenmat\n", "A" ] }, { "cell_type": "markdown", "id": "26", "metadata": {}, "source": [ "## Use `double` to convert an `sptenmat` to a SciPy COO Matrix" ] }, { "cell_type": "code", "execution_count": null, "id": "27", "metadata": {}, "outputs": [], "source": [ "X = ttb.sptenrand((10, 10, 10, 10), nonzeros=10) # Create sptensor\n", "A = X.to_sptenmat(np.array([0])) # Convert to an sptenmat\n", "A" ] }, { "cell_type": "code", "execution_count": null, "id": "28", "metadata": {}, "outputs": [], "source": [ "B = A.double() # Convert to scipy\n", "B" ] }, { "cell_type": "markdown", "id": "29", "metadata": {}, "source": [ "## Use `full` to convert an `sptenmat` to a `tenmat`" ] }, { "cell_type": "code", "execution_count": null, "id": "30", "metadata": {}, "outputs": [], "source": [ "B = ttb.sptenrand((3, 3, 3), nonzeros=3).to_sptenmat(np.array([0]))\n", "B" ] }, { "cell_type": "code", "execution_count": null, "id": "31", "metadata": {}, "outputs": [], "source": [ "C = B.full()\n", "C" ] }, { "cell_type": "markdown", "id": "32", "metadata": {}, "source": [ "## Use `to_sptensor` to convert an `sptenmat` to an `sptensor`." ] }, { "cell_type": "code", "execution_count": null, "id": "33", "metadata": {}, "outputs": [], "source": [ "Y = B.to_sptensor()\n", "Y" ] }, { "cell_type": "code", "execution_count": null, "id": "34", "metadata": {}, "outputs": [], "source": [ "## Access `shape` and `tshape` for dimensions of an `sptenmat`" ] }, { "cell_type": "code", "execution_count": null, "id": "35", "metadata": {}, "outputs": [], "source": [ "print(f\"Matrix shape: {A.shape}\\n\" f\"Original tensor shape: {A.tshape}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "36", "metadata": {}, "outputs": [], "source": [ "## Subscripted assignment for an `sptenmat`" ] }, { "cell_type": "code", "execution_count": null, "id": "37", "metadata": {}, "outputs": [], "source": [ "A[0:2, 0:2] = 1\n", "A" ] }, { "cell_type": "code", "execution_count": null, "id": "38", "metadata": {}, "outputs": [], "source": [ "## Basic operations for `sptenmat`" ] }, { "cell_type": "code", "execution_count": null, "id": "39", "metadata": {}, "outputs": [], "source": [ "A.norm() # Norm of the matrix." ] }, { "cell_type": "code", "execution_count": null, "id": "40", "metadata": {}, "outputs": [], "source": [ "+A # Positive version of matrix (no change)" ] }, { "cell_type": "code", "execution_count": null, "id": "41", "metadata": {}, "outputs": [], "source": [ "-A # Negative version of matrix" ] } ], "metadata": {}, "nbformat": 4, "nbformat_minor": 5 }